@tagadapay/plugin-sdk 3.0.12 → 3.0.15

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 (31) hide show
  1. package/dist/external-tracker.js +3645 -115
  2. package/dist/external-tracker.min.js +25 -2
  3. package/dist/external-tracker.min.js.map +4 -4
  4. package/dist/react/types.d.ts +2 -0
  5. package/dist/v2/core/client.d.ts +5 -0
  6. package/dist/v2/core/client.js +135 -26
  7. package/dist/v2/core/config/environment.js +6 -0
  8. package/dist/v2/core/funnelClient.d.ts +27 -1
  9. package/dist/v2/core/funnelClient.js +124 -23
  10. package/dist/v2/core/resources/checkout.d.ts +76 -1
  11. package/dist/v2/core/resources/checkout.js +86 -1
  12. package/dist/v2/core/resources/funnel.d.ts +45 -4
  13. package/dist/v2/core/resources/offers.d.ts +26 -0
  14. package/dist/v2/core/resources/offers.js +37 -0
  15. package/dist/v2/core/types.d.ts +3 -1
  16. package/dist/v2/core/utils/authHandoff.d.ts +60 -0
  17. package/dist/v2/core/utils/authHandoff.js +154 -0
  18. package/dist/v2/core/utils/deviceInfo.d.ts +20 -3
  19. package/dist/v2/core/utils/deviceInfo.js +62 -94
  20. package/dist/v2/core/utils/previewMode.d.ts +4 -0
  21. package/dist/v2/core/utils/previewMode.js +4 -0
  22. package/dist/v2/react/hooks/useCheckoutQuery.d.ts +0 -1
  23. package/dist/v2/react/hooks/useCheckoutQuery.js +12 -4
  24. package/dist/v2/react/hooks/useFunnelLegacy.js +39 -11
  25. package/dist/v2/react/hooks/usePreviewOffer.d.ts +3 -3
  26. package/dist/v2/react/hooks/usePreviewOffer.js +20 -15
  27. package/dist/v2/react/hooks/useTranslation.js +12 -4
  28. package/dist/v2/react/providers/TagadaProvider.js +61 -1
  29. package/dist/v2/standalone/index.d.ts +2 -1
  30. package/dist/v2/standalone/index.js +2 -1
  31. package/package.json +3 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * TagadaPay External Tracker v3.0.12
2
+ * TagadaPay External Tracker v3.0.15
3
3
  * CDN Bundle - Standalone tracking for external pages (Debug Build)
4
4
  * @license MIT
5
5
  */
@@ -110,7 +110,9 @@ var TagadaTrackerBundle = (() => {
110
110
  endpoints: {
111
111
  checkout: {
112
112
  sessionInit: "/api/v1/checkout/session/init",
113
- sessionStatus: "/api/v1/checkout/session/status"
113
+ sessionInitAsync: "/api/v1/checkout/session/init-async",
114
+ sessionStatus: "/api/v1/checkout/session/status",
115
+ asyncStatus: "/api/public/v1/checkout/async-status"
114
116
  },
115
117
  customer: {
116
118
  profile: "/api/v1/customer/profile",
@@ -126,7 +128,9 @@ var TagadaTrackerBundle = (() => {
126
128
  endpoints: {
127
129
  checkout: {
128
130
  sessionInit: "/api/v1/checkout/session/init",
129
- sessionStatus: "/api/v1/checkout/session/status"
131
+ sessionInitAsync: "/api/v1/checkout/session/init-async",
132
+ sessionStatus: "/api/v1/checkout/session/status",
133
+ asyncStatus: "/api/public/v1/checkout/async-status"
130
134
  },
131
135
  customer: {
132
136
  profile: "/api/v1/customer/profile",
@@ -142,7 +146,9 @@ var TagadaTrackerBundle = (() => {
142
146
  endpoints: {
143
147
  checkout: {
144
148
  sessionInit: "/api/v1/checkout/session/init",
145
- sessionStatus: "/api/v1/checkout/session/status"
149
+ sessionInitAsync: "/api/v1/checkout/session/init-async",
150
+ sessionStatus: "/api/v1/checkout/session/status",
151
+ asyncStatus: "/api/public/v1/checkout/async-status"
146
152
  },
147
153
  customer: {
148
154
  profile: "/api/v1/customer/profile",
@@ -629,6 +635,32 @@ var TagadaTrackerBundle = (() => {
629
635
  getState() {
630
636
  return this.state;
631
637
  }
638
+ /**
639
+ * Get the session ID that would be used for initialization (URL params or cookie)
640
+ * This allows getting the session ID even before the client is fully initialized.
641
+ */
642
+ getDetectedSessionId() {
643
+ var _a;
644
+ if ((_a = this.state.context) == null ? void 0 : _a.sessionId) {
645
+ return this.state.context.sessionId;
646
+ }
647
+ if (typeof window === "undefined") return null;
648
+ const params = new URLSearchParams(window.location.search);
649
+ const urlSessionId = params.get("funnelSessionId");
650
+ if (urlSessionId) return urlSessionId;
651
+ return getFunnelSessionCookie() || null;
652
+ }
653
+ /**
654
+ * Reset initialization state (used for back-button restores)
655
+ */
656
+ resetInitialization() {
657
+ this.initializationAttempted = false;
658
+ this.isInitializing = false;
659
+ this.updateState({
660
+ context: null,
661
+ isInitialized: false
662
+ });
663
+ }
632
664
  /**
633
665
  * Initialize session with automatic detection (cookies, URL, etc.)
634
666
  */
@@ -640,30 +672,32 @@ var TagadaTrackerBundle = (() => {
640
672
  this.isInitializing = true;
641
673
  this.updateState({ isLoading: true, error: null });
642
674
  try {
675
+ const existingSessionId = this.getDetectedSessionId();
643
676
  const params = new URLSearchParams(typeof window !== "undefined" ? window.location.search : "");
644
677
  const urlFunnelId = params.get("funnelId");
645
678
  const effectiveFunnelId = urlFunnelId || funnelId;
646
- let existingSessionId = params.get("funnelSessionId");
647
- if (!existingSessionId) {
648
- existingSessionId = getFunnelSessionCookie() || null;
649
- }
650
679
  const injectedFunnelId = getAssignedFunnelId();
651
680
  const funnelVariantId = getAssignedFunnelVariant();
652
- const funnelStepId = getAssignedFunnelStep();
681
+ const injectedStepId = getAssignedFunnelStep();
653
682
  const sdkParams = getSDKParams();
654
- const finalFunnelId = injectedFunnelId || effectiveFunnelId;
683
+ const finalFunnelId = this.config.funnelId || injectedFunnelId || effectiveFunnelId;
684
+ const finalStepId = this.config.stepId || injectedStepId;
655
685
  if (this.config.debugMode) {
656
686
  console.log("\u{1F680} [FunnelClient] Auto-initializing...", {
657
687
  existingSessionId,
658
688
  effectiveFunnelId: finalFunnelId,
659
689
  funnelVariantId,
660
690
  // 🎯 Log variant ID for debugging
661
- funnelStepId,
691
+ funnelStepId: finalStepId,
662
692
  // 🎯 Log step ID for debugging
663
693
  draft: sdkParams.draft,
664
694
  // 🎯 Log draft mode
665
- funnelTracking: sdkParams.funnelTracking
695
+ funnelTracking: sdkParams.funnelTracking,
666
696
  // 🎯 Log tracking flag
697
+ source: {
698
+ funnelId: this.config.funnelId ? "config" : injectedFunnelId ? "injected" : effectiveFunnelId ? "url/prop" : "none",
699
+ stepId: this.config.stepId ? "config" : injectedStepId ? "injected" : "none"
700
+ }
667
701
  });
668
702
  }
669
703
  const response = await this.resource.initialize({
@@ -678,8 +712,8 @@ var TagadaTrackerBundle = (() => {
678
712
  currentUrl: typeof window !== "undefined" ? window.location.href : void 0,
679
713
  funnelVariantId,
680
714
  // 🎯 Pass A/B test variant ID to backend
681
- funnelStepId,
682
- // 🎯 Pass step ID to backend
715
+ funnelStepId: finalStepId,
716
+ // 🎯 Pass step ID to backend (with config override)
683
717
  draft: sdkParams.draft,
684
718
  // 🎯 Pass draft mode explicitly (more robust than URL parsing)
685
719
  funnelTracking: sdkParams.funnelTracking
@@ -745,30 +779,90 @@ var TagadaTrackerBundle = (() => {
745
779
  }
746
780
  /**
747
781
  * Navigate
782
+ * @param event - Navigation event/action
783
+ * @param options - Navigation options
784
+ * @param options.fireAndForget - If true, queues navigation to QStash and returns immediately without waiting for result
785
+ * @param options.customerTags - Customer tags to set (merged with existing customer tags)
786
+ * @param options.deviceId - Device ID for geo/device tag enrichment (optional, rarely needed)
748
787
  */
749
- async navigate(event) {
750
- var _a;
788
+ async navigate(event, options) {
789
+ var _a, _b, _c;
751
790
  if (!((_a = this.state.context) == null ? void 0 : _a.sessionId)) throw new Error("No active session");
752
791
  this.updateState({ isNavigating: true, isLoading: true });
753
792
  try {
793
+ let funnelVariantId = getAssignedFunnelVariant();
794
+ let funnelStepId = getAssignedFunnelStep();
795
+ const currentUrl = typeof window !== "undefined" ? window.location.href : void 0;
796
+ if (!funnelStepId && this.config.stepId) {
797
+ funnelStepId = this.config.stepId;
798
+ if (this.config.debugMode) {
799
+ console.log("\u{1F50D} [FunnelClient.navigate] Using stepId from config (no injection):", funnelStepId);
800
+ }
801
+ }
802
+ if (!funnelVariantId && this.config.variantId) {
803
+ funnelVariantId = this.config.variantId;
804
+ if (this.config.debugMode) {
805
+ console.log("\u{1F50D} [FunnelClient.navigate] Using variantId from config (no injection):", funnelVariantId);
806
+ }
807
+ }
808
+ if (this.config.debugMode) {
809
+ console.log("\u{1F50D} [FunnelClient.navigate] Sending to backend:", {
810
+ sessionId: this.state.context.sessionId,
811
+ currentUrl,
812
+ funnelStepId: funnelStepId || "(not found)",
813
+ funnelVariantId: funnelVariantId || "(not found)",
814
+ hasInjectedStepId: !!getAssignedFunnelStep(),
815
+ hasInjectedVariantId: !!getAssignedFunnelVariant(),
816
+ usedConfigFallback: !getAssignedFunnelStep() && !!this.config.stepId,
817
+ customerTags: (options == null ? void 0 : options.customerTags) || "(none)",
818
+ deviceId: (options == null ? void 0 : options.deviceId) || "(none)"
819
+ });
820
+ }
821
+ const fireAndForget = (options == null ? void 0 : options.fireAndForget) || false;
754
822
  const response = await this.resource.navigate({
755
823
  sessionId: this.state.context.sessionId,
756
- event
824
+ event,
825
+ currentUrl,
826
+ funnelStepId,
827
+ funnelVariantId,
828
+ fireAndForget,
829
+ customerTags: options == null ? void 0 : options.customerTags,
830
+ deviceId: options == null ? void 0 : options.deviceId
757
831
  });
758
- if (response.success && response.result) {
759
- await this.refreshSession();
832
+ if (!response.success || !response.result) {
833
+ throw new Error(response.error || "Navigation failed");
834
+ }
835
+ const result = response.result;
836
+ if (result.queued) {
760
837
  this.updateState({ isNavigating: false, isLoading: false });
761
- const result = response.result;
762
- const shouldAutoRedirect = this.config.autoRedirect !== false;
763
- if (shouldAutoRedirect && (result == null ? void 0 : result.url) && typeof window !== "undefined") {
838
+ if (result.sessionId && result.sessionId !== ((_b = this.state.context) == null ? void 0 : _b.sessionId)) {
764
839
  if (this.config.debugMode) {
765
- console.log("\u{1F680} [FunnelClient] Auto-redirecting to:", result.url);
840
+ console.log("\u{1F525} [FunnelClient] Session ID updated: ".concat((_c = this.state.context) == null ? void 0 : _c.sessionId, " \u2192 ").concat(result.sessionId));
766
841
  }
767
- window.location.href = result.url;
842
+ if (this.state.context) {
843
+ this.state.context.sessionId = result.sessionId;
844
+ }
845
+ }
846
+ if (this.config.debugMode) {
847
+ console.log("\u{1F525} [FunnelClient] Navigation queued (fire-and-forget mode)");
768
848
  }
769
849
  return result;
770
850
  }
771
- throw new Error(response.error || "Navigation failed");
851
+ const shouldAutoRedirect = this.config.autoRedirect !== false;
852
+ if (!shouldAutoRedirect) {
853
+ if (this.config.debugMode) {
854
+ console.log("\u{1F504} [FunnelClient] Refreshing session (no auto-redirect)");
855
+ }
856
+ await this.refreshSession();
857
+ }
858
+ this.updateState({ isNavigating: false, isLoading: false });
859
+ if (shouldAutoRedirect && (result == null ? void 0 : result.url) && typeof window !== "undefined") {
860
+ if (this.config.debugMode) {
861
+ console.log("\u{1F680} [FunnelClient] Auto-redirecting to:", result.url, "(skipped session refresh - next page will initialize)");
862
+ }
863
+ window.location.href = result.url;
864
+ }
865
+ return result;
772
866
  } catch (error) {
773
867
  const err = error instanceof Error ? error : new Error(String(error));
774
868
  this.updateState({ error: err, isNavigating: false, isLoading: false });
@@ -3638,70 +3732,3240 @@ var TagadaTrackerBundle = (() => {
3638
3732
  }
3639
3733
  };
3640
3734
 
3641
- // src/v2/core/utils/deviceInfo.ts
3642
- function getBrowserInfo() {
3643
- const userAgent = navigator.userAgent;
3644
- if (userAgent.includes("Chrome")) {
3645
- const match = /Chrome\/(\d+)/.exec(userAgent);
3646
- return { name: "Chrome", version: match ? match[1] : "unknown" };
3735
+ // ../../node_modules/.pnpm/@ua-parser-js+pro-enterprise@2.0.6/node_modules/@ua-parser-js/pro-enterprise/src/main/ua-parser.mjs
3736
+ var LIBVERSION = "2.0.6";
3737
+ var UA_MAX_LENGTH = 500;
3738
+ var USER_AGENT = "user-agent";
3739
+ var EMPTY = "";
3740
+ var UNKNOWN = "?";
3741
+ var TYPEOF = {
3742
+ FUNCTION: "function",
3743
+ OBJECT: "object",
3744
+ STRING: "string",
3745
+ UNDEFINED: "undefined"
3746
+ };
3747
+ var BROWSER = "browser";
3748
+ var CPU = "cpu";
3749
+ var DEVICE = "device";
3750
+ var ENGINE = "engine";
3751
+ var OS = "os";
3752
+ var RESULT = "result";
3753
+ var NAME = "name";
3754
+ var TYPE = "type";
3755
+ var VENDOR = "vendor";
3756
+ var VERSION3 = "version";
3757
+ var ARCHITECTURE = "architecture";
3758
+ var MAJOR = "major";
3759
+ var MODEL = "model";
3760
+ var CONSOLE = "console";
3761
+ var MOBILE = "mobile";
3762
+ var TABLET = "tablet";
3763
+ var SMARTTV = "smarttv";
3764
+ var WEARABLE = "wearable";
3765
+ var XR = "xr";
3766
+ var EMBEDDED = "embedded";
3767
+ var INAPP = "inapp";
3768
+ var BRANDS = "brands";
3769
+ var FORMFACTORS = "formFactors";
3770
+ var FULLVERLIST = "fullVersionList";
3771
+ var PLATFORM = "platform";
3772
+ var PLATFORMVER = "platformVersion";
3773
+ var BITNESS = "bitness";
3774
+ var CH = "sec-ch-ua";
3775
+ var CH_FULL_VER_LIST = CH + "-full-version-list";
3776
+ var CH_ARCH = CH + "-arch";
3777
+ var CH_BITNESS = CH + "-" + BITNESS;
3778
+ var CH_FORM_FACTORS = CH + "-form-factors";
3779
+ var CH_MOBILE = CH + "-" + MOBILE;
3780
+ var CH_MODEL = CH + "-" + MODEL;
3781
+ var CH_PLATFORM = CH + "-" + PLATFORM;
3782
+ var CH_PLATFORM_VER = CH_PLATFORM + "-version";
3783
+ var CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS];
3784
+ var AMAZON = "Amazon";
3785
+ var APPLE = "Apple";
3786
+ var ASUS = "ASUS";
3787
+ var BLACKBERRY = "BlackBerry";
3788
+ var GOOGLE = "Google";
3789
+ var HUAWEI = "Huawei";
3790
+ var LENOVO = "Lenovo";
3791
+ var HONOR = "Honor";
3792
+ var LG = "LG";
3793
+ var MICROSOFT = "Microsoft";
3794
+ var MOTOROLA = "Motorola";
3795
+ var NVIDIA = "Nvidia";
3796
+ var ONEPLUS = "OnePlus";
3797
+ var OPPO = "OPPO";
3798
+ var SAMSUNG = "Samsung";
3799
+ var SHARP = "Sharp";
3800
+ var SONY = "Sony";
3801
+ var XIAOMI = "Xiaomi";
3802
+ var ZEBRA = "Zebra";
3803
+ var CHROME = "Chrome";
3804
+ var CHROMIUM = "Chromium";
3805
+ var CHROMECAST = "Chromecast";
3806
+ var EDGE = "Edge";
3807
+ var FIREFOX = "Firefox";
3808
+ var OPERA = "Opera";
3809
+ var FACEBOOK = "Facebook";
3810
+ var SOGOU = "Sogou";
3811
+ var PREFIX_MOBILE = "Mobile ";
3812
+ var SUFFIX_BROWSER = " Browser";
3813
+ var WINDOWS = "Windows";
3814
+ var isWindow = typeof window !== TYPEOF.UNDEFINED;
3815
+ var NAVIGATOR = isWindow && window.navigator ? window.navigator : void 0;
3816
+ var NAVIGATOR_UADATA = NAVIGATOR && NAVIGATOR.userAgentData ? NAVIGATOR.userAgentData : void 0;
3817
+ var extend2 = function(defaultRgx, extensions) {
3818
+ var mergedRgx = {};
3819
+ var extraRgx = extensions;
3820
+ if (!isExtensions(extensions)) {
3821
+ extraRgx = {};
3822
+ for (var i in extensions) {
3823
+ for (var j in extensions[i]) {
3824
+ extraRgx[j] = extensions[i][j].concat(extraRgx[j] ? extraRgx[j] : []);
3825
+ }
3826
+ }
3647
3827
  }
3648
- if (userAgent.includes("Firefox")) {
3649
- const match = /Firefox\/(\d+)/.exec(userAgent);
3650
- return { name: "Firefox", version: match ? match[1] : "unknown" };
3828
+ for (var k in defaultRgx) {
3829
+ mergedRgx[k] = extraRgx[k] && extraRgx[k].length % 2 === 0 ? extraRgx[k].concat(defaultRgx[k]) : defaultRgx[k];
3651
3830
  }
3652
- if (userAgent.includes("Safari") && !userAgent.includes("Chrome")) {
3653
- const match = /Version\/(\d+)/.exec(userAgent);
3654
- return { name: "Safari", version: match ? match[1] : "unknown" };
3831
+ return mergedRgx;
3832
+ };
3833
+ var enumerize = function(arr) {
3834
+ var enums = {};
3835
+ for (var i = 0; i < arr.length; i++) {
3836
+ enums[arr[i].toUpperCase()] = arr[i];
3655
3837
  }
3656
- if (userAgent.includes("Edge")) {
3657
- const match = /Edge\/(\d+)/.exec(userAgent);
3658
- return { name: "Edge", version: match ? match[1] : "unknown" };
3838
+ return enums;
3839
+ };
3840
+ var has = function(str1, str2) {
3841
+ if (typeof str1 === TYPEOF.OBJECT && str1.length > 0) {
3842
+ for (var i in str1) {
3843
+ if (lowerize(str2) == lowerize(str1[i])) return true;
3844
+ }
3845
+ return false;
3659
3846
  }
3660
- return { name: "unknown", version: "unknown" };
3661
- }
3662
- function getOSInfo() {
3663
- const userAgent = navigator.userAgent;
3664
- if (userAgent.includes("Windows")) {
3665
- if (userAgent.includes("Windows NT 10.0")) return { name: "Windows", version: "10" };
3666
- if (userAgent.includes("Windows NT 6.3")) return { name: "Windows", version: "8.1" };
3667
- if (userAgent.includes("Windows NT 6.2")) return { name: "Windows", version: "8" };
3668
- if (userAgent.includes("Windows NT 6.1")) return { name: "Windows", version: "7" };
3669
- return { name: "Windows", version: "unknown" };
3670
- }
3671
- if (userAgent.includes("Mac OS X")) {
3672
- const match = /Mac OS X (\d+[._]\d+)/.exec(userAgent);
3673
- return { name: "macOS", version: match ? match[1].replace("_", ".") : "unknown" };
3674
- }
3675
- if (userAgent.includes("iPhone") || userAgent.includes("iPad")) {
3676
- const match = /OS (\d+[._]\d+)/.exec(userAgent);
3677
- return { name: "iOS", version: match ? match[1].replace("_", ".") : "unknown" };
3678
- }
3679
- if (userAgent.includes("Android")) {
3680
- const match = /Android (\d+[.\d]*)/.exec(userAgent);
3681
- return { name: "Android", version: match ? match[1] : "unknown" };
3682
- }
3683
- if (userAgent.includes("Linux")) {
3684
- return { name: "Linux", version: "unknown" };
3685
- }
3686
- return { name: "unknown", version: "unknown" };
3687
- }
3688
- function getDeviceInfo() {
3689
- const userAgent = navigator.userAgent;
3690
- if (userAgent.includes("iPhone")) {
3691
- return { type: "mobile", model: "iPhone" };
3847
+ return isString2(str1) ? lowerize(str2) == lowerize(str1) : false;
3848
+ };
3849
+ var isExtensions = function(obj, deep) {
3850
+ for (var prop in obj) {
3851
+ return /^(browser|cpu|device|engine|os)$/.test(prop) || (deep ? isExtensions(obj[prop]) : false);
3692
3852
  }
3693
- if (userAgent.includes("iPad")) {
3694
- return { type: "tablet", model: "iPad" };
3853
+ };
3854
+ var isString2 = function(val) {
3855
+ return typeof val === TYPEOF.STRING;
3856
+ };
3857
+ var itemListToArray = function(header) {
3858
+ if (!header) return void 0;
3859
+ var arr = [];
3860
+ var tokens = strip(/\\?\"/g, header).split(",");
3861
+ for (var i = 0; i < tokens.length; i++) {
3862
+ if (tokens[i].indexOf(";") > -1) {
3863
+ var token = trim2(tokens[i]).split(";v=");
3864
+ arr[i] = { brand: token[0], version: token[1] };
3865
+ } else {
3866
+ arr[i] = trim2(tokens[i]);
3867
+ }
3695
3868
  }
3696
- if (userAgent.includes("Android")) {
3697
- if (userAgent.includes("Mobile")) {
3698
- return { type: "mobile", model: "Android" };
3869
+ return arr;
3870
+ };
3871
+ var lowerize = function(str) {
3872
+ return isString2(str) ? str.toLowerCase() : str;
3873
+ };
3874
+ var majorize = function(version) {
3875
+ return isString2(version) ? strip(/[^\d\.]/g, version).split(".")[0] : void 0;
3876
+ };
3877
+ var setProps = function(arr) {
3878
+ for (var i in arr) {
3879
+ if (!arr.hasOwnProperty(i)) continue;
3880
+ var propName = arr[i];
3881
+ if (typeof propName == TYPEOF.OBJECT && propName.length == 2) {
3882
+ this[propName[0]] = propName[1];
3699
3883
  } else {
3700
- return { type: "tablet", model: "Android" };
3884
+ this[propName] = void 0;
3701
3885
  }
3702
3886
  }
3703
- return void 0;
3887
+ return this;
3888
+ };
3889
+ var strip = function(pattern, str) {
3890
+ return isString2(str) ? str.replace(pattern, EMPTY) : str;
3891
+ };
3892
+ var stripQuotes = function(str) {
3893
+ return strip(/\\?\"/g, str);
3894
+ };
3895
+ var trim2 = function(str, len) {
3896
+ str = strip(/^\s\s*/, String(str));
3897
+ return typeof len === TYPEOF.UNDEFINED ? str : str.substring(0, len);
3898
+ };
3899
+ var rgxMapper = function(ua, arrays) {
3900
+ if (!ua || !arrays) return;
3901
+ var i = 0, j, k, p, q, matches, match;
3902
+ while (i < arrays.length && !matches) {
3903
+ var regex = arrays[i], props = arrays[i + 1];
3904
+ j = k = 0;
3905
+ while (j < regex.length && !matches) {
3906
+ if (!regex[j]) {
3907
+ break;
3908
+ }
3909
+ matches = regex[j++].exec(ua);
3910
+ if (!!matches) {
3911
+ for (p = 0; p < props.length; p++) {
3912
+ match = matches[++k];
3913
+ q = props[p];
3914
+ if (typeof q === TYPEOF.OBJECT && q.length > 0) {
3915
+ if (q.length === 2) {
3916
+ if (typeof q[1] == TYPEOF.FUNCTION) {
3917
+ this[q[0]] = q[1].call(this, match);
3918
+ } else {
3919
+ this[q[0]] = q[1];
3920
+ }
3921
+ } else if (q.length >= 3) {
3922
+ if (typeof q[1] === TYPEOF.FUNCTION && !(q[1].exec && q[1].test)) {
3923
+ if (q.length > 3) {
3924
+ this[q[0]] = match ? q[1].apply(this, q.slice(2)) : void 0;
3925
+ } else {
3926
+ this[q[0]] = match ? q[1].call(this, match, q[2]) : void 0;
3927
+ }
3928
+ } else {
3929
+ if (q.length == 3) {
3930
+ this[q[0]] = match ? match.replace(q[1], q[2]) : void 0;
3931
+ } else if (q.length == 4) {
3932
+ this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : void 0;
3933
+ } else if (q.length > 4) {
3934
+ this[q[0]] = match ? q[3].apply(this, [match.replace(q[1], q[2])].concat(q.slice(4))) : void 0;
3935
+ }
3936
+ }
3937
+ }
3938
+ } else {
3939
+ this[q] = match ? match : void 0;
3940
+ }
3941
+ }
3942
+ }
3943
+ }
3944
+ i += 2;
3945
+ }
3946
+ };
3947
+ var strMapper = function(str, map) {
3948
+ for (var i in map) {
3949
+ if (typeof map[i] === TYPEOF.OBJECT && map[i].length > 0) {
3950
+ for (var j = 0; j < map[i].length; j++) {
3951
+ if (has(map[i][j], str)) {
3952
+ return i === UNKNOWN ? void 0 : i;
3953
+ }
3954
+ }
3955
+ } else if (has(map[i], str)) {
3956
+ return i === UNKNOWN ? void 0 : i;
3957
+ }
3958
+ }
3959
+ return map.hasOwnProperty("*") ? map["*"] : str;
3960
+ };
3961
+ var windowsVersionMap = {
3962
+ "ME": "4.90",
3963
+ "NT 3.51": "3.51",
3964
+ "NT 4.0": "4.0",
3965
+ "2000": ["5.0", "5.01"],
3966
+ "XP": ["5.1", "5.2"],
3967
+ "Vista": "6.0",
3968
+ "7": "6.1",
3969
+ "8": "6.2",
3970
+ "8.1": "6.3",
3971
+ "10": ["6.4", "10.0"],
3972
+ "NT": ""
3973
+ };
3974
+ var formFactorsMap = {
3975
+ "embedded": "Automotive",
3976
+ "mobile": "Mobile",
3977
+ "tablet": ["Tablet", "EInk"],
3978
+ "smarttv": "TV",
3979
+ "wearable": "Watch",
3980
+ "xr": ["VR", "XR"],
3981
+ "?": ["Desktop", "Unknown"],
3982
+ "*": void 0
3983
+ };
3984
+ var browserHintsMap = {
3985
+ "Chrome": "Google Chrome",
3986
+ "Edge": "Microsoft Edge",
3987
+ "Edge WebView2": "Microsoft Edge WebView2",
3988
+ "Chrome WebView": "Android WebView",
3989
+ "Chrome Headless": "HeadlessChrome",
3990
+ "Huawei Browser": "HuaweiBrowser",
3991
+ "MIUI Browser": "Miui Browser",
3992
+ "Opera Mobi": "OperaMobile",
3993
+ "Yandex": "YaBrowser"
3994
+ };
3995
+ var defaultRegexes = {
3996
+ browser: [
3997
+ [
3998
+ // Most common regardless engine
3999
+ /\b(?:crmo|crios)\/([\w\.]+)/i
4000
+ // Chrome for Android/iOS
4001
+ ],
4002
+ [VERSION3, [NAME, PREFIX_MOBILE + "Chrome"]],
4003
+ [
4004
+ /webview.+edge\/([\w\.]+)/i
4005
+ // Microsoft Edge
4006
+ ],
4007
+ [VERSION3, [NAME, EDGE + " WebView"]],
4008
+ [
4009
+ /edg(?:e|ios|a)?\/([\w\.]+)/i
4010
+ ],
4011
+ [VERSION3, [NAME, "Edge"]],
4012
+ [
4013
+ // Presto based
4014
+ /(opera mini)\/([-\w\.]+)/i,
4015
+ // Opera Mini
4016
+ /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,
4017
+ // Opera Mobi/Tablet
4018
+ /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i
4019
+ // Opera
4020
+ ],
4021
+ [NAME, VERSION3],
4022
+ [
4023
+ /opios[\/ ]+([\w\.]+)/i
4024
+ // Opera mini on iphone >= 8.0
4025
+ ],
4026
+ [VERSION3, [NAME, OPERA + " Mini"]],
4027
+ [
4028
+ /\bop(?:rg)?x\/([\w\.]+)/i
4029
+ // Opera GX
4030
+ ],
4031
+ [VERSION3, [NAME, OPERA + " GX"]],
4032
+ [
4033
+ /\bopr\/([\w\.]+)/i
4034
+ // Opera Webkit
4035
+ ],
4036
+ [VERSION3, [NAME, OPERA]],
4037
+ [
4038
+ // Mixed
4039
+ /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i
4040
+ // Baidu
4041
+ ],
4042
+ [VERSION3, [NAME, "Baidu"]],
4043
+ [
4044
+ /\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i
4045
+ // Maxthon
4046
+ ],
4047
+ [VERSION3, [NAME, "Maxthon"]],
4048
+ [
4049
+ /(kindle)\/([\w\.]+)/i,
4050
+ // Kindle
4051
+ /(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
4052
+ // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
4053
+ // Trident based
4054
+ /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i,
4055
+ // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet
4056
+ /(?:ms|\()(ie) ([\w\.]+)/i,
4057
+ // Internet Explorer
4058
+ // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser/Otter/qutebrowser/Dooble/Palemoon
4059
+ /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:lg |qute)browser|palemoon)\/([-\w\.]+)/i,
4060
+ // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
4061
+ /(heytap|ovi|115|surf|qwant)browser\/([\d\.]+)/i,
4062
+ // HeyTap/Ovi/115/Surf
4063
+ /(qwant)(?:ios|mobile)\/([\d\.]+)/i,
4064
+ // Qwant
4065
+ /(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i
4066
+ // Ecosia/Weibo
4067
+ ],
4068
+ [NAME, VERSION3],
4069
+ [
4070
+ /quark(?:pc)?\/([-\w\.]+)/i
4071
+ // Quark
4072
+ ],
4073
+ [VERSION3, [NAME, "Quark"]],
4074
+ [
4075
+ /\bddg\/([\w\.]+)/i
4076
+ // DuckDuckGo
4077
+ ],
4078
+ [VERSION3, [NAME, "DuckDuckGo"]],
4079
+ [
4080
+ /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i
4081
+ // UCBrowser
4082
+ ],
4083
+ [VERSION3, [NAME, "UCBrowser"]],
4084
+ [
4085
+ /microm.+\bqbcore\/([\w\.]+)/i,
4086
+ // WeChat Desktop for Windows Built-in Browser
4087
+ /\bqbcore\/([\w\.]+).+microm/i,
4088
+ /micromessenger\/([\w\.]+)/i
4089
+ // WeChat
4090
+ ],
4091
+ [VERSION3, [NAME, "WeChat"]],
4092
+ [
4093
+ /konqueror\/([\w\.]+)/i
4094
+ // Konqueror
4095
+ ],
4096
+ [VERSION3, [NAME, "Konqueror"]],
4097
+ [
4098
+ /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i
4099
+ // IE11
4100
+ ],
4101
+ [VERSION3, [NAME, "IE"]],
4102
+ [
4103
+ /ya(?:search)?browser\/([\w\.]+)/i
4104
+ // Yandex
4105
+ ],
4106
+ [VERSION3, [NAME, "Yandex"]],
4107
+ [
4108
+ /slbrowser\/([\w\.]+)/i
4109
+ // Smart Lenovo Browser
4110
+ ],
4111
+ [VERSION3, [NAME, "Smart " + LENOVO + SUFFIX_BROWSER]],
4112
+ [
4113
+ /(avast|avg)\/([\w\.]+)/i
4114
+ // Avast/AVG Secure Browser
4115
+ ],
4116
+ [[NAME, /(.+)/, "$1 Secure" + SUFFIX_BROWSER], VERSION3],
4117
+ [
4118
+ /\bfocus\/([\w\.]+)/i
4119
+ // Firefox Focus
4120
+ ],
4121
+ [VERSION3, [NAME, FIREFOX + " Focus"]],
4122
+ [
4123
+ /\bopt\/([\w\.]+)/i
4124
+ // Opera Touch
4125
+ ],
4126
+ [VERSION3, [NAME, OPERA + " Touch"]],
4127
+ [
4128
+ /coc_coc\w+\/([\w\.]+)/i
4129
+ // Coc Coc Browser
4130
+ ],
4131
+ [VERSION3, [NAME, "Coc Coc"]],
4132
+ [
4133
+ /dolfin\/([\w\.]+)/i
4134
+ // Dolphin
4135
+ ],
4136
+ [VERSION3, [NAME, "Dolphin"]],
4137
+ [
4138
+ /coast\/([\w\.]+)/i
4139
+ // Opera Coast
4140
+ ],
4141
+ [VERSION3, [NAME, OPERA + " Coast"]],
4142
+ [
4143
+ /miuibrowser\/([\w\.]+)/i
4144
+ // MIUI Browser
4145
+ ],
4146
+ [VERSION3, [NAME, "MIUI" + SUFFIX_BROWSER]],
4147
+ [
4148
+ /fxios\/([\w\.-]+)/i
4149
+ // Firefox for iOS
4150
+ ],
4151
+ [VERSION3, [NAME, PREFIX_MOBILE + FIREFOX]],
4152
+ [
4153
+ /\bqihoobrowser\/?([\w\.]*)/i
4154
+ // 360
4155
+ ],
4156
+ [VERSION3, [NAME, "360"]],
4157
+ [
4158
+ /\b(qq)\/([\w\.]+)/i
4159
+ // QQ
4160
+ ],
4161
+ [[NAME, /(.+)/, "$1Browser"], VERSION3],
4162
+ [
4163
+ /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
4164
+ ],
4165
+ [[NAME, /(.+)/, "$1" + SUFFIX_BROWSER], VERSION3],
4166
+ [
4167
+ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
4168
+ /samsungbrowser\/([\w\.]+)/i
4169
+ // Samsung Internet
4170
+ ],
4171
+ [VERSION3, [NAME, SAMSUNG + " Internet"]],
4172
+ [
4173
+ /metasr[\/ ]?([\d\.]+)/i
4174
+ // Sogou Explorer
4175
+ ],
4176
+ [VERSION3, [NAME, SOGOU + " Explorer"]],
4177
+ [
4178
+ /(sogou)mo\w+\/([\d\.]+)/i
4179
+ // Sogou Mobile
4180
+ ],
4181
+ [[NAME, SOGOU + " Mobile"], VERSION3],
4182
+ [
4183
+ /(electron)\/([\w\.]+) safari/i,
4184
+ // Electron-based App
4185
+ /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,
4186
+ // Tesla
4187
+ /m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i
4188
+ // QQ/2345
4189
+ ],
4190
+ [NAME, VERSION3],
4191
+ [
4192
+ /(lbbrowser|rekonq)/i
4193
+ // LieBao Browser/Rekonq
4194
+ ],
4195
+ [NAME],
4196
+ [
4197
+ /ome\/([\w\.]+) \w* ?(iron) saf/i,
4198
+ // Iron
4199
+ /ome\/([\w\.]+).+qihu (360)[es]e/i
4200
+ // 360
4201
+ ],
4202
+ [VERSION3, NAME],
4203
+ [
4204
+ // WebView
4205
+ /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i
4206
+ // Facebook App for iOS & Android
4207
+ ],
4208
+ [[NAME, FACEBOOK], VERSION3, [TYPE, INAPP]],
4209
+ [
4210
+ /(kakao(?:talk|story))[\/ ]([\w\.]+)/i,
4211
+ // Kakao App
4212
+ /(naver)\(.*?(\d+\.[\w\.]+).*\)/i,
4213
+ // Naver InApp
4214
+ /(daum)apps[\/ ]([\w\.]+)/i,
4215
+ // Daum App
4216
+ /safari (line)\/([\w\.]+)/i,
4217
+ // Line App for iOS
4218
+ /\b(line)\/([\w\.]+)\/iab/i,
4219
+ // Line App for Android
4220
+ /(alipay)client\/([\w\.]+)/i,
4221
+ // Alipay
4222
+ /(twitter)(?:and| f.+e\/([\w\.]+))/i,
4223
+ // Twitter
4224
+ /(bing)(?:web|sapphire)\/([\w\.]+)/i,
4225
+ // Bing
4226
+ /(instagram|snapchat|klarna)[\/ ]([-\w\.]+)/i
4227
+ // Instagram/Snapchat/Klarna
4228
+ ],
4229
+ [NAME, VERSION3, [TYPE, INAPP]],
4230
+ [
4231
+ /\bgsa\/([\w\.]+) .*safari\//i
4232
+ // Google Search Appliance on iOS
4233
+ ],
4234
+ [VERSION3, [NAME, "GSA"], [TYPE, INAPP]],
4235
+ [
4236
+ /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i
4237
+ // TikTok
4238
+ ],
4239
+ [VERSION3, [NAME, "TikTok"], [TYPE, INAPP]],
4240
+ [
4241
+ /\[(linkedin)app\]/i
4242
+ // LinkedIn App for iOS & Android
4243
+ ],
4244
+ [NAME, [TYPE, INAPP]],
4245
+ [
4246
+ /(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i
4247
+ // Zalo
4248
+ ],
4249
+ [[NAME, /(.+)/, "Zalo"], VERSION3, [TYPE, INAPP]],
4250
+ [
4251
+ /(chromium)[\/ ]([-\w\.]+)/i
4252
+ // Chromium
4253
+ ],
4254
+ [NAME, VERSION3],
4255
+ [
4256
+ /headlesschrome(?:\/([\w\.]+)| )/i
4257
+ // Chrome Headless
4258
+ ],
4259
+ [VERSION3, [NAME, CHROME + " Headless"]],
4260
+ [
4261
+ /wv\).+chrome\/([\w\.]+).+edgw\//i
4262
+ // Edge WebView2
4263
+ ],
4264
+ [VERSION3, [NAME, EDGE + " WebView2"]],
4265
+ [
4266
+ / wv\).+(chrome)\/([\w\.]+)/i
4267
+ // Chrome WebView
4268
+ ],
4269
+ [[NAME, CHROME + " WebView"], VERSION3],
4270
+ [
4271
+ /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i
4272
+ // Android Browser
4273
+ ],
4274
+ [VERSION3, [NAME, "Android" + SUFFIX_BROWSER]],
4275
+ [
4276
+ /chrome\/([\w\.]+) mobile/i
4277
+ // Chrome Mobile
4278
+ ],
4279
+ [VERSION3, [NAME, PREFIX_MOBILE + "Chrome"]],
4280
+ [
4281
+ /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i
4282
+ // Chrome/OmniWeb/Arora/Tizen/Nokia
4283
+ ],
4284
+ [NAME, VERSION3],
4285
+ [
4286
+ /version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i
4287
+ // Safari Mobile
4288
+ ],
4289
+ [VERSION3, [NAME, PREFIX_MOBILE + "Safari"]],
4290
+ [
4291
+ /iphone .*mobile(?:\/\w+ | ?)safari/i
4292
+ ],
4293
+ [[NAME, PREFIX_MOBILE + "Safari"]],
4294
+ [
4295
+ /version\/([\w\.\,]+) .*(safari)/i
4296
+ // Safari
4297
+ ],
4298
+ [VERSION3, NAME],
4299
+ [
4300
+ /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i
4301
+ // Safari < 3.0
4302
+ ],
4303
+ [NAME, [VERSION3, "1"]],
4304
+ [
4305
+ /(webkit|khtml)\/([\w\.]+)/i
4306
+ ],
4307
+ [NAME, VERSION3],
4308
+ [
4309
+ // Gecko based
4310
+ /(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i
4311
+ // Firefox Mobile
4312
+ ],
4313
+ [[NAME, PREFIX_MOBILE + FIREFOX], VERSION3],
4314
+ [
4315
+ /(navigator|netscape\d?)\/([-\w\.]+)/i
4316
+ // Netscape
4317
+ ],
4318
+ [[NAME, "Netscape"], VERSION3],
4319
+ [
4320
+ /(wolvic|librewolf)\/([\w\.]+)/i
4321
+ // Wolvic/LibreWolf
4322
+ ],
4323
+ [NAME, VERSION3],
4324
+ [
4325
+ /mobile vr; rv:([\w\.]+)\).+firefox/i
4326
+ // Firefox Reality
4327
+ ],
4328
+ [VERSION3, [NAME, FIREFOX + " Reality"]],
4329
+ [
4330
+ /ekiohf.+(flow)\/([\w\.]+)/i,
4331
+ // Flow
4332
+ /(swiftfox)/i,
4333
+ // Swiftfox
4334
+ /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,
4335
+ // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
4336
+ /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|basilisk|waterfox)\/([-\w\.]+)$/i,
4337
+ // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
4338
+ /(firefox)\/([\w\.]+)/i,
4339
+ // Other Firefox-based
4340
+ /(mozilla)\/([\w\.]+(?= .+rv\:.+gecko\/\d+)|[0-4][\w\.]+(?!.+compatible))/i,
4341
+ // Mozilla
4342
+ // Other
4343
+ /(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
4344
+ // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser/Ladybird
4345
+ /\b(links) \(([\w\.]+)/i
4346
+ // Links
4347
+ ],
4348
+ [NAME, [VERSION3, /_/g, "."]],
4349
+ [
4350
+ /(cobalt)\/([\w\.]+)/i
4351
+ // Cobalt
4352
+ ],
4353
+ [NAME, [VERSION3, /[^\d\.]+./, EMPTY]]
4354
+ ],
4355
+ cpu: [
4356
+ [
4357
+ /\b((amd|x|x86[-_]?|wow|win)64)\b/i
4358
+ // AMD64 (x64)
4359
+ ],
4360
+ [[ARCHITECTURE, "amd64"]],
4361
+ [
4362
+ /(ia32(?=;))/i,
4363
+ // IA32 (quicktime)
4364
+ /\b((i[346]|x)86)(pc)?\b/i
4365
+ // IA32 (x86)
4366
+ ],
4367
+ [[ARCHITECTURE, "ia32"]],
4368
+ [
4369
+ /\b(aarch64|arm(v?[89]e?l?|_?64))\b/i
4370
+ // ARM64
4371
+ ],
4372
+ [[ARCHITECTURE, "arm64"]],
4373
+ [
4374
+ /\b(arm(v[67])?ht?n?[fl]p?)\b/i
4375
+ // ARMHF
4376
+ ],
4377
+ [[ARCHITECTURE, "armhf"]],
4378
+ [
4379
+ // PocketPC mistakenly identified as PowerPC
4380
+ /( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i
4381
+ ],
4382
+ [[ARCHITECTURE, "arm"]],
4383
+ [
4384
+ / sun4\w[;\)]/i
4385
+ // SPARC
4386
+ ],
4387
+ [[ARCHITECTURE, "sparc"]],
4388
+ [
4389
+ // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
4390
+ /\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,
4391
+ /((ppc|powerpc)(64)?)( mac|;|\))/i,
4392
+ // PowerPC
4393
+ /(?:osf1|[freopnt]{3,4}bsd) (alpha)/i
4394
+ // Alpha
4395
+ ],
4396
+ [[ARCHITECTURE, /ower/, EMPTY, lowerize]],
4397
+ [
4398
+ /mc680.0/i
4399
+ ],
4400
+ [[ARCHITECTURE, "68k"]],
4401
+ [
4402
+ /winnt.+\[axp/i
4403
+ ],
4404
+ [[ARCHITECTURE, "alpha"]]
4405
+ ],
4406
+ device: [
4407
+ [
4408
+ //////////////////////////
4409
+ // MOBILES & TABLETS
4410
+ /////////////////////////
4411
+ // Samsung
4412
+ /\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i
4413
+ ],
4414
+ [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]],
4415
+ [
4416
+ /\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
4417
+ /samsung[- ]((?!sm-[lr]|browser)[-\w]+)/i,
4418
+ /sec-(sgh\w+)/i
4419
+ ],
4420
+ [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]],
4421
+ [
4422
+ // Apple
4423
+ /(?:\/|\()(ip(?:hone|od)[\w, ]*)[\/\);]/i
4424
+ // iPod/iPhone
4425
+ ],
4426
+ [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]],
4427
+ [
4428
+ /\b(?:ios|apple\w+)\/.+[\(\/](ipad)/i,
4429
+ // iPad
4430
+ /\b(ipad)[\d,]*[;\] ].+(mac |i(pad)?)os/i
4431
+ ],
4432
+ [MODEL, [VENDOR, APPLE], [TYPE, TABLET]],
4433
+ [
4434
+ /(macintosh);/i
4435
+ ],
4436
+ [MODEL, [VENDOR, APPLE]],
4437
+ [
4438
+ // Sharp
4439
+ /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
4440
+ ],
4441
+ [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]],
4442
+ [
4443
+ // Honor
4444
+ /\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i
4445
+ ],
4446
+ [MODEL, [VENDOR, HONOR], [TYPE, TABLET]],
4447
+ [
4448
+ /honor([-\w ]+)[;\)]/i
4449
+ ],
4450
+ [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]],
4451
+ [
4452
+ // Huawei
4453
+ /\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i
4454
+ ],
4455
+ [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]],
4456
+ [
4457
+ /(?:huawei) ?([-\w ]+)[;\)]/i,
4458
+ /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][\dc][adnt]?)\b(?!.+d\/s)/i
4459
+ ],
4460
+ [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]],
4461
+ [
4462
+ // Xiaomi
4463
+ /oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,
4464
+ /\b(?:xiao)?((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i
4465
+ // Mi Pad tablets
4466
+ ],
4467
+ [[MODEL, /_/g, " "], [VENDOR, XIAOMI], [TYPE, TABLET]],
4468
+ [
4469
+ /\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i,
4470
+ // Xiaomi POCO
4471
+ /\b; (\w+) build\/hm\1/i,
4472
+ // Xiaomi Hongmi 'numeric' models
4473
+ /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,
4474
+ // Xiaomi Hongmi
4475
+ /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i,
4476
+ // Xiaomi Redmi
4477
+ /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i,
4478
+ // Xiaomi Redmi 'numeric' models
4479
+ /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,
4480
+ // Xiaomi Mi
4481
+ / ([\w ]+) miui\/v?\d/i
4482
+ ],
4483
+ [[MODEL, /_/g, " "], [VENDOR, XIAOMI], [TYPE, MOBILE]],
4484
+ [
4485
+ // OnePlus
4486
+ /droid.+; (cph2[3-6]\d[13579]|((gm|hd)19|(ac|be|in|kb)20|(d[en]|eb|le|mt)21|ne22)[0-2]\d|p[g-k]\w[1m]10)\b/i,
4487
+ /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
4488
+ ],
4489
+ [MODEL, [VENDOR, ONEPLUS], [TYPE, MOBILE]],
4490
+ [
4491
+ // OPPO
4492
+ /; (\w+) bui.+ oppo/i,
4493
+ /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
4494
+ ],
4495
+ [MODEL, [VENDOR, OPPO], [TYPE, MOBILE]],
4496
+ [
4497
+ /\b(opd2(\d{3}a?))(?: bui|\))/i
4498
+ ],
4499
+ [MODEL, [VENDOR, strMapper, { "OnePlus": ["203", "304", "403", "404", "413", "415"], "*": OPPO }], [TYPE, TABLET]],
4500
+ [
4501
+ // BLU
4502
+ /(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i
4503
+ // Vivo series
4504
+ ],
4505
+ [MODEL, [VENDOR, "BLU"], [TYPE, MOBILE]],
4506
+ [
4507
+ // Vivo
4508
+ /; vivo (\w+)(?: bui|\))/i,
4509
+ /\b(v[12]\d{3}\w?[at])(?: bui|;)/i
4510
+ ],
4511
+ [MODEL, [VENDOR, "Vivo"], [TYPE, MOBILE]],
4512
+ [
4513
+ // Realme
4514
+ /\b(rmx[1-3]\d{3})(?: bui|;|\))/i
4515
+ ],
4516
+ [MODEL, [VENDOR, "Realme"], [TYPE, MOBILE]],
4517
+ [
4518
+ // Lenovo
4519
+ /(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,
4520
+ /lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i
4521
+ ],
4522
+ [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]],
4523
+ [
4524
+ /lenovo[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i
4525
+ ],
4526
+ [MODEL, [VENDOR, LENOVO], [TYPE, MOBILE]],
4527
+ [
4528
+ // Motorola
4529
+ /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
4530
+ /\bmot(?:orola)?[- ]([\w\s]+)(\)| bui)/i,
4531
+ /((?:moto(?! 360)[-\w\(\) ]+|xt\d{3,4}[cgkosw\+]?[-\d]*|nexus 6)(?= bui|\)))/i
4532
+ ],
4533
+ [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]],
4534
+ [
4535
+ /\b(mz60\d|xoom[2 ]{0,2}) build\//i
4536
+ ],
4537
+ [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]],
4538
+ [
4539
+ // LG
4540
+ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
4541
+ ],
4542
+ [MODEL, [VENDOR, LG], [TYPE, TABLET]],
4543
+ [
4544
+ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
4545
+ /\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch|webos))(\w+)/i,
4546
+ /\blg-?([\d\w]+) bui/i
4547
+ ],
4548
+ [MODEL, [VENDOR, LG], [TYPE, MOBILE]],
4549
+ [
4550
+ // Nokia
4551
+ /(nokia) (t[12][01])/i
4552
+ ],
4553
+ [VENDOR, MODEL, [TYPE, TABLET]],
4554
+ [
4555
+ /(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,
4556
+ /nokia[-_ ]?(([-\w\. ]*?))( bui|\)|;|\/)/i
4557
+ ],
4558
+ [[MODEL, /_/g, " "], [TYPE, MOBILE], [VENDOR, "Nokia"]],
4559
+ [
4560
+ // Google
4561
+ /(pixel (c|tablet))\b/i
4562
+ // Google Pixel C/Tablet
4563
+ ],
4564
+ [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]],
4565
+ [
4566
+ // Google Pixel
4567
+ /droid.+;(?: google)? (g(01[13]a|020[aem]|025[jn]|1b60|1f8f|2ybb|4s1m|576d|5nz6|8hhn|8vou|a02099|c15s|d1yq|e2ae|ec77|gh2x|kv4x|p4bc|pj41|r83y|tt9q|ur25|wvk6)|pixel[\d ]*a?( pro)?( xl)?( fold)?( \(5g\))?)( bui|\))/i
4568
+ ],
4569
+ [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]],
4570
+ [
4571
+ /(google) (pixelbook( go)?)/i
4572
+ ],
4573
+ [VENDOR, MODEL],
4574
+ [
4575
+ // Sony
4576
+ /droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-\w\w\d\d)(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i
4577
+ ],
4578
+ [MODEL, [VENDOR, SONY], [TYPE, MOBILE]],
4579
+ [
4580
+ /sony tablet [ps]/i,
4581
+ /\b(?:sony)?sgp\w+(?: bui|\))/i
4582
+ ],
4583
+ [[MODEL, "Xperia Tablet"], [VENDOR, SONY], [TYPE, TABLET]],
4584
+ [
4585
+ // Amazon
4586
+ /(alexa)webm/i,
4587
+ /(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i,
4588
+ // Kindle Fire without Silk / Echo Show
4589
+ /(kf[a-z]+)( bui|\)).+silk\//i
4590
+ // Kindle Fire HD
4591
+ ],
4592
+ [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]],
4593
+ [
4594
+ /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i
4595
+ // Fire Phone
4596
+ ],
4597
+ [[MODEL, /(.+)/g, "Fire Phone $1"], [VENDOR, AMAZON], [TYPE, MOBILE]],
4598
+ [
4599
+ // BlackBerry
4600
+ /(playbook);[-\w\),; ]+(rim)/i
4601
+ // BlackBerry PlayBook
4602
+ ],
4603
+ [MODEL, VENDOR, [TYPE, TABLET]],
4604
+ [
4605
+ /\b((?:bb[a-f]|st[hv])100-\d)/i,
4606
+ /(?:blackberry|\(bb10;) (\w+)/i
4607
+ ],
4608
+ [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]],
4609
+ [
4610
+ // Asus
4611
+ /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i
4612
+ ],
4613
+ [MODEL, [VENDOR, ASUS], [TYPE, TABLET]],
4614
+ [
4615
+ / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i
4616
+ ],
4617
+ [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]],
4618
+ [
4619
+ // HTC
4620
+ /(nexus 9)/i
4621
+ // HTC Nexus 9
4622
+ ],
4623
+ [MODEL, [VENDOR, "HTC"], [TYPE, TABLET]],
4624
+ [
4625
+ /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,
4626
+ // HTC
4627
+ // ZTE
4628
+ /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,
4629
+ /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i
4630
+ // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
4631
+ ],
4632
+ [VENDOR, [MODEL, /_/g, " "], [TYPE, MOBILE]],
4633
+ [
4634
+ // TCL
4635
+ /tcl (xess p17aa)/i,
4636
+ /droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i
4637
+ ],
4638
+ [MODEL, [VENDOR, "TCL"], [TYPE, TABLET]],
4639
+ [
4640
+ /droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i
4641
+ ],
4642
+ [MODEL, [VENDOR, "TCL"], [TYPE, MOBILE]],
4643
+ [
4644
+ // itel
4645
+ /(itel) ((\w+))/i
4646
+ ],
4647
+ [[VENDOR, lowerize], MODEL, [TYPE, strMapper, { "tablet": ["p10001l", "w7001"], "*": "mobile" }]],
4648
+ [
4649
+ // Acer
4650
+ /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
4651
+ ],
4652
+ [MODEL, [VENDOR, "Acer"], [TYPE, TABLET]],
4653
+ [
4654
+ // Meizu
4655
+ /droid.+; (m[1-5] note) bui/i,
4656
+ /\bmz-([-\w]{2,})/i
4657
+ ],
4658
+ [MODEL, [VENDOR, "Meizu"], [TYPE, MOBILE]],
4659
+ [
4660
+ // Ulefone
4661
+ /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
4662
+ ],
4663
+ [MODEL, [VENDOR, "Ulefone"], [TYPE, MOBILE]],
4664
+ [
4665
+ // Energizer
4666
+ /; (energy ?\w+)(?: bui|\))/i,
4667
+ /; energizer ([\w ]+)(?: bui|\))/i
4668
+ ],
4669
+ [MODEL, [VENDOR, "Energizer"], [TYPE, MOBILE]],
4670
+ [
4671
+ // Cat
4672
+ /; cat (b35);/i,
4673
+ /; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i
4674
+ ],
4675
+ [MODEL, [VENDOR, "Cat"], [TYPE, MOBILE]],
4676
+ [
4677
+ // Smartfren
4678
+ /((?:new )?andromax[\w- ]+)(?: bui|\))/i
4679
+ ],
4680
+ [MODEL, [VENDOR, "Smartfren"], [TYPE, MOBILE]],
4681
+ [
4682
+ // Nothing
4683
+ /droid.+; (a(in)?(0(15|59|6[35])|142)p?)/i
4684
+ ],
4685
+ [MODEL, [VENDOR, "Nothing"], [TYPE, MOBILE]],
4686
+ [
4687
+ // Archos
4688
+ /; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,
4689
+ /archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i
4690
+ ],
4691
+ [MODEL, [VENDOR, "Archos"], [TYPE, TABLET]],
4692
+ [
4693
+ /archos ([\w ]+)( b|\))/i,
4694
+ /; (ac[3-6]\d\w{2,8})( b|\))/i
4695
+ ],
4696
+ [MODEL, [VENDOR, "Archos"], [TYPE, MOBILE]],
4697
+ [
4698
+ // HMD
4699
+ /; (n159v)/i
4700
+ ],
4701
+ [MODEL, [VENDOR, "HMD"], [TYPE, MOBILE]],
4702
+ [
4703
+ // MIXED
4704
+ /(imo) (tab \w+)/i,
4705
+ // IMO
4706
+ /(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i
4707
+ // Infinix XPad / Tecno
4708
+ ],
4709
+ [VENDOR, MODEL, [TYPE, TABLET]],
4710
+ [
4711
+ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
4712
+ // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Tecno/Micromax/Advan
4713
+ // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko
4714
+ /; (blu|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,
4715
+ /(hp) ([\w ]+\w)/i,
4716
+ // HP iPAQ
4717
+ /(microsoft); (lumia[\w ]+)/i,
4718
+ // Microsoft Lumia
4719
+ /(oppo) ?([\w ]+) bui/i,
4720
+ // OPPO
4721
+ /(hisense) ([ehv][\w ]+)\)/i,
4722
+ // Hisense
4723
+ /droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i
4724
+ // Philips
4725
+ ],
4726
+ [VENDOR, MODEL, [TYPE, MOBILE]],
4727
+ [
4728
+ /(kobo)\s(ereader|touch)/i,
4729
+ // Kobo
4730
+ /(hp).+(touchpad(?!.+tablet)|tablet)/i,
4731
+ // HP TouchPad
4732
+ /(kindle)\/([\w\.]+)/i
4733
+ // Kindle
4734
+ ],
4735
+ [VENDOR, MODEL, [TYPE, TABLET]],
4736
+ [
4737
+ /(surface duo)/i
4738
+ // Surface Duo
4739
+ ],
4740
+ [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]],
4741
+ [
4742
+ /droid [\d\.]+; (fp\du?)(?: b|\))/i
4743
+ // Fairphone
4744
+ ],
4745
+ [MODEL, [VENDOR, "Fairphone"], [TYPE, MOBILE]],
4746
+ [
4747
+ /((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i
4748
+ // Nvidia Tablets
4749
+ ],
4750
+ [MODEL, [VENDOR, NVIDIA], [TYPE, TABLET]],
4751
+ [
4752
+ /(sprint) (\w+)/i
4753
+ // Sprint Phones
4754
+ ],
4755
+ [VENDOR, MODEL, [TYPE, MOBILE]],
4756
+ [
4757
+ /(kin\.[onetw]{3})/i
4758
+ // Microsoft Kin
4759
+ ],
4760
+ [[MODEL, /\./g, " "], [VENDOR, MICROSOFT], [TYPE, MOBILE]],
4761
+ [
4762
+ /droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i
4763
+ // Zebra
4764
+ ],
4765
+ [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]],
4766
+ [
4767
+ /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i
4768
+ ],
4769
+ [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]],
4770
+ [
4771
+ ///////////////////
4772
+ // SMARTTVS
4773
+ ///////////////////
4774
+ /(philips)[\w ]+tv/i,
4775
+ // Philips
4776
+ /smart-tv.+(samsung)/i
4777
+ // Samsung
4778
+ ],
4779
+ [VENDOR, [TYPE, SMARTTV]],
4780
+ [
4781
+ /hbbtv.+maple;(\d+)/i
4782
+ ],
4783
+ [[MODEL, /^/, "SmartTV"], [VENDOR, SAMSUNG], [TYPE, SMARTTV]],
4784
+ [
4785
+ /(vizio)(?: |.+model\/)(\w+-\w+)/i,
4786
+ // Vizio
4787
+ /tcast.+(lg)e?. ([-\w]+)/i
4788
+ // LG SmartTV
4789
+ ],
4790
+ [VENDOR, MODEL, [TYPE, SMARTTV]],
4791
+ [
4792
+ /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i
4793
+ ],
4794
+ [[VENDOR, LG], [TYPE, SMARTTV]],
4795
+ [
4796
+ /(apple) ?tv/i
4797
+ // Apple TV
4798
+ ],
4799
+ [VENDOR, [MODEL, APPLE + " TV"], [TYPE, SMARTTV]],
4800
+ [
4801
+ /crkey.*devicetype\/chromecast/i
4802
+ // Google Chromecast Third Generation
4803
+ ],
4804
+ [[MODEL, CHROMECAST + " Third Generation"], [VENDOR, GOOGLE], [TYPE, SMARTTV]],
4805
+ [
4806
+ /crkey.*devicetype\/([^/]*)/i
4807
+ // Google Chromecast with specific device type
4808
+ ],
4809
+ [[MODEL, /^/, "Chromecast "], [VENDOR, GOOGLE], [TYPE, SMARTTV]],
4810
+ [
4811
+ /fuchsia.*crkey/i
4812
+ // Google Chromecast Nest Hub
4813
+ ],
4814
+ [[MODEL, CHROMECAST + " Nest Hub"], [VENDOR, GOOGLE], [TYPE, SMARTTV]],
4815
+ [
4816
+ /crkey/i
4817
+ // Google Chromecast, Linux-based or unknown
4818
+ ],
4819
+ [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]],
4820
+ [
4821
+ /(portaltv)/i
4822
+ // Facebook Portal TV
4823
+ ],
4824
+ [MODEL, [VENDOR, FACEBOOK], [TYPE, SMARTTV]],
4825
+ [
4826
+ /droid.+aft(\w+)( bui|\))/i
4827
+ // Fire TV
4828
+ ],
4829
+ [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]],
4830
+ [
4831
+ /(shield \w+ tv)/i
4832
+ // Nvidia Shield TV
4833
+ ],
4834
+ [MODEL, [VENDOR, NVIDIA], [TYPE, SMARTTV]],
4835
+ [
4836
+ /\(dtv[\);].+(aquos)/i,
4837
+ /(aquos-tv[\w ]+)\)/i
4838
+ // Sharp
4839
+ ],
4840
+ [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],
4841
+ [
4842
+ /(bravia[\w ]+)( bui|\))/i
4843
+ // Sony
4844
+ ],
4845
+ [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]],
4846
+ [
4847
+ /(mi(tv|box)-?\w+) bui/i
4848
+ // Xiaomi
4849
+ ],
4850
+ [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]],
4851
+ [
4852
+ /Hbbtv.*(technisat) (.*);/i
4853
+ // TechniSAT
4854
+ ],
4855
+ [VENDOR, MODEL, [TYPE, SMARTTV]],
4856
+ [
4857
+ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,
4858
+ // Roku
4859
+ /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i
4860
+ // HbbTV devices
4861
+ ],
4862
+ [[VENDOR, /.+\/(\w+)/, "$1", strMapper, { "LG": "lge" }], [MODEL, trim2], [TYPE, SMARTTV]],
4863
+ [
4864
+ ///////////////////
4865
+ // CONSOLES
4866
+ ///////////////////
4867
+ /(playstation \w+)/i
4868
+ // Playstation
4869
+ ],
4870
+ [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]],
4871
+ [
4872
+ /\b(xbox(?: one)?(?!; xbox))[\); ]/i
4873
+ // Microsoft Xbox
4874
+ ],
4875
+ [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]],
4876
+ [
4877
+ /(ouya)/i,
4878
+ // Ouya
4879
+ /(nintendo) (\w+)/i,
4880
+ // Nintendo
4881
+ /(retroid) (pocket ([^\)]+))/i
4882
+ // Retroid Pocket
4883
+ ],
4884
+ [VENDOR, MODEL, [TYPE, CONSOLE]],
4885
+ [
4886
+ /droid.+; (shield)( bui|\))/i
4887
+ // Nvidia Portable
4888
+ ],
4889
+ [MODEL, [VENDOR, NVIDIA], [TYPE, CONSOLE]],
4890
+ [
4891
+ ///////////////////
4892
+ // WEARABLES
4893
+ ///////////////////
4894
+ /\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i
4895
+ // Samsung Galaxy Watch
4896
+ ],
4897
+ [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]],
4898
+ [
4899
+ /((pebble))app/i,
4900
+ // Pebble
4901
+ /(asus|google|lg|oppo) ((pixel |zen)?watch[\w ]*)( bui|\))/i
4902
+ // Asus ZenWatch / LG Watch / Pixel Watch
4903
+ ],
4904
+ [VENDOR, MODEL, [TYPE, WEARABLE]],
4905
+ [
4906
+ /(ow(?:19|20)?we?[1-3]{1,3})/i
4907
+ // Oppo Watch
4908
+ ],
4909
+ [MODEL, [VENDOR, OPPO], [TYPE, WEARABLE]],
4910
+ [
4911
+ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i
4912
+ // Apple Watch
4913
+ ],
4914
+ [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]],
4915
+ [
4916
+ /(opwwe\d{3})/i
4917
+ // OnePlus Watch
4918
+ ],
4919
+ [MODEL, [VENDOR, ONEPLUS], [TYPE, WEARABLE]],
4920
+ [
4921
+ /(moto 360)/i
4922
+ // Motorola 360
4923
+ ],
4924
+ [MODEL, [VENDOR, MOTOROLA], [TYPE, WEARABLE]],
4925
+ [
4926
+ /(smartwatch 3)/i
4927
+ // Sony SmartWatch
4928
+ ],
4929
+ [MODEL, [VENDOR, SONY], [TYPE, WEARABLE]],
4930
+ [
4931
+ /(g watch r)/i
4932
+ // LG G Watch R
4933
+ ],
4934
+ [MODEL, [VENDOR, LG], [TYPE, WEARABLE]],
4935
+ [
4936
+ /droid.+; (wt63?0{2,3})\)/i
4937
+ ],
4938
+ [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]],
4939
+ [
4940
+ ///////////////////
4941
+ // XR
4942
+ ///////////////////
4943
+ /droid.+; (glass) \d/i
4944
+ // Google Glass
4945
+ ],
4946
+ [MODEL, [VENDOR, GOOGLE], [TYPE, XR]],
4947
+ [
4948
+ /(pico) ([\w ]+) os\d/i
4949
+ // Pico
4950
+ ],
4951
+ [VENDOR, MODEL, [TYPE, XR]],
4952
+ [
4953
+ /(quest( \d| pro)?s?).+vr/i
4954
+ // Meta Quest
4955
+ ],
4956
+ [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]],
4957
+ [
4958
+ /mobile vr; rv.+firefox/i
4959
+ // Unidentifiable VR device using Firefox Reality / Wolvic
4960
+ ],
4961
+ [[TYPE, XR]],
4962
+ [
4963
+ ///////////////////
4964
+ // EMBEDDED
4965
+ ///////////////////
4966
+ /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i
4967
+ // Tesla
4968
+ ],
4969
+ [VENDOR, [TYPE, EMBEDDED]],
4970
+ [
4971
+ /(aeobc)\b/i
4972
+ // Echo Dot
4973
+ ],
4974
+ [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]],
4975
+ [
4976
+ /(homepod).+mac os/i
4977
+ // Apple HomePod
4978
+ ],
4979
+ [MODEL, [VENDOR, APPLE], [TYPE, EMBEDDED]],
4980
+ [
4981
+ /windows iot/i
4982
+ // Unidentifiable embedded device using Windows IoT
4983
+ ],
4984
+ [[TYPE, EMBEDDED]],
4985
+ [
4986
+ ////////////////////
4987
+ // MIXED (GENERIC)
4988
+ ///////////////////
4989
+ /droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i
4990
+ // Unidentifiable SmartTV
4991
+ ],
4992
+ [MODEL, [TYPE, SMARTTV]],
4993
+ [
4994
+ /\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i
4995
+ ],
4996
+ [[TYPE, SMARTTV]],
4997
+ [
4998
+ /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew|; hmsc).+?(mobile|vr|\d) safari/i
4999
+ ],
5000
+ [MODEL, [TYPE, strMapper, { "mobile": "Mobile", "xr": "VR", "*": TABLET }]],
5001
+ [
5002
+ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i
5003
+ // Unidentifiable Tablet
5004
+ ],
5005
+ [[TYPE, TABLET]],
5006
+ [
5007
+ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i
5008
+ // Unidentifiable Mobile
5009
+ ],
5010
+ [[TYPE, MOBILE]],
5011
+ [
5012
+ /droid .+?; ([\w\. -]+)( bui|\))/i
5013
+ // Generic Android Device
5014
+ ],
5015
+ [MODEL, [VENDOR, "Generic"]]
5016
+ ],
5017
+ engine: [
5018
+ [
5019
+ /windows.+ edge\/([\w\.]+)/i
5020
+ // EdgeHTML
5021
+ ],
5022
+ [VERSION3, [NAME, EDGE + "HTML"]],
5023
+ [
5024
+ /(arkweb)\/([\w\.]+)/i
5025
+ // ArkWeb
5026
+ ],
5027
+ [NAME, VERSION3],
5028
+ [
5029
+ /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i
5030
+ // Blink
5031
+ ],
5032
+ [VERSION3, [NAME, "Blink"]],
5033
+ [
5034
+ /(presto)\/([\w\.]+)/i,
5035
+ // Presto
5036
+ /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i,
5037
+ // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo
5038
+ /ekioh(flow)\/([\w\.]+)/i,
5039
+ // Flow
5040
+ /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i,
5041
+ // KHTML/Tasman/Links
5042
+ /(icab)[\/ ]([23]\.[\d\.]+)/i,
5043
+ // iCab
5044
+ /\b(libweb)/i
5045
+ // LibWeb
5046
+ ],
5047
+ [NAME, VERSION3],
5048
+ [
5049
+ /ladybird\//i
5050
+ ],
5051
+ [[NAME, "LibWeb"]],
5052
+ [
5053
+ /rv\:([\w\.]{1,9})\b.+(gecko)/i
5054
+ // Gecko
5055
+ ],
5056
+ [VERSION3, NAME]
5057
+ ],
5058
+ os: [
5059
+ [
5060
+ // Windows
5061
+ /(windows nt) (6\.[23]); arm/i
5062
+ // Windows RT
5063
+ ],
5064
+ [[NAME, /N/, "R"], [VERSION3, strMapper, windowsVersionMap]],
5065
+ [
5066
+ /(windows (?:phone|mobile|iot))(?: os)?[\/ ]?([\d\.]*( se)?)/i,
5067
+ // Windows IoT/Mobile/Phone
5068
+ // Windows NT/3.1/95/98/ME/2000/XP/Vista/7/8/8.1/10/11
5069
+ /(windows)[\/ ](1[01]|2000|3\.1|7|8(\.1)?|9[58]|me|server 20\d\d( r2)?|vista|xp)/i
5070
+ ],
5071
+ [NAME, VERSION3],
5072
+ [
5073
+ /windows nt ?([\d\.\)]*)(?!.+xbox)/i,
5074
+ /\bwin(?=3| ?9|n)(?:nt| 9x )?([\d\.;]*)/i
5075
+ ],
5076
+ [[VERSION3, /(;|\))/g, "", strMapper, windowsVersionMap], [NAME, WINDOWS]],
5077
+ [
5078
+ /(windows ce)\/?([\d\.]*)/i
5079
+ // Windows CE
5080
+ ],
5081
+ [NAME, VERSION3],
5082
+ [
5083
+ // iOS/macOS
5084
+ /[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i,
5085
+ // iOS
5086
+ /(?:ios;fbsv|ios(?=.+ip(?:ad|hone))|ip(?:ad|hone)(?: |.+i(?:pad)?)os)[\/ ]([\w\.]+)/i,
5087
+ /cfnetwork\/.+darwin/i
5088
+ ],
5089
+ [[VERSION3, /_/g, "."], [NAME, "iOS"]],
5090
+ [
5091
+ /(mac os x) ?([\w\. ]*)/i,
5092
+ /(macintosh|mac_powerpc\b)(?!.+(haiku|morphos))/i
5093
+ // Mac OS
5094
+ ],
5095
+ [[NAME, "macOS"], [VERSION3, /_/g, "."]],
5096
+ [
5097
+ // Google Chromecast
5098
+ /android ([\d\.]+).*crkey/i
5099
+ // Google Chromecast, Android-based
5100
+ ],
5101
+ [VERSION3, [NAME, CHROMECAST + " Android"]],
5102
+ [
5103
+ /fuchsia.*crkey\/([\d\.]+)/i
5104
+ // Google Chromecast, Fuchsia-based
5105
+ ],
5106
+ [VERSION3, [NAME, CHROMECAST + " Fuchsia"]],
5107
+ [
5108
+ /crkey\/([\d\.]+).*devicetype\/smartspeaker/i
5109
+ // Google Chromecast, Linux-based Smart Speaker
5110
+ ],
5111
+ [VERSION3, [NAME, CHROMECAST + " SmartSpeaker"]],
5112
+ [
5113
+ /linux.*crkey\/([\d\.]+)/i
5114
+ // Google Chromecast, Legacy Linux-based
5115
+ ],
5116
+ [VERSION3, [NAME, CHROMECAST + " Linux"]],
5117
+ [
5118
+ /crkey\/([\d\.]+)/i
5119
+ // Google Chromecast, unknown
5120
+ ],
5121
+ [VERSION3, [NAME, CHROMECAST]],
5122
+ [
5123
+ // Mobile OSes
5124
+ /droid ([\w\.]+)\b.+(android[- ]x86)/i
5125
+ // Android-x86
5126
+ ],
5127
+ [VERSION3, NAME],
5128
+ [
5129
+ /(ubuntu) ([\w\.]+) like android/i
5130
+ // Ubuntu Touch
5131
+ ],
5132
+ [[NAME, /(.+)/, "$1 Touch"], VERSION3],
5133
+ [
5134
+ /(harmonyos)[\/ ]?([\d\.]*)/i,
5135
+ // HarmonyOS
5136
+ // Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen
5137
+ /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen)\w*[-\/\.; ]?([\d\.]*)/i
5138
+ ],
5139
+ [NAME, VERSION3],
5140
+ [
5141
+ /\(bb(10);/i
5142
+ // BlackBerry 10
5143
+ ],
5144
+ [VERSION3, [NAME, BLACKBERRY]],
5145
+ [
5146
+ /(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i
5147
+ // Symbian
5148
+ ],
5149
+ [VERSION3, [NAME, "Symbian"]],
5150
+ [
5151
+ /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i
5152
+ // Firefox OS
5153
+ ],
5154
+ [VERSION3, [NAME, FIREFOX + " OS"]],
5155
+ [
5156
+ /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i,
5157
+ // WebOS
5158
+ /webos(?:[ \/]?|\.tv-20(?=2[2-9]))(\d[\d\.]*)/i
5159
+ ],
5160
+ [VERSION3, [NAME, "webOS"]],
5161
+ [
5162
+ /web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i
5163
+ // https://webostv.developer.lge.com/develop/specifications/web-api-and-web-engine
5164
+ ],
5165
+ [[VERSION3, strMapper, { "25": "120", "24": "108", "23": "94", "22": "87", "6": "79", "5": "68", "4": "53", "3": "38", "2": "538", "1": "537", "*": "TV" }], [NAME, "webOS"]],
5166
+ [
5167
+ /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i
5168
+ // watchOS
5169
+ ],
5170
+ [VERSION3, [NAME, "watchOS"]],
5171
+ [
5172
+ // Google ChromeOS
5173
+ /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i
5174
+ // Chromium OS
5175
+ ],
5176
+ [[NAME, "Chrome OS"], VERSION3],
5177
+ [
5178
+ // Smart TVs
5179
+ /panasonic;(viera)/i,
5180
+ // Panasonic Viera
5181
+ /(netrange)mmh/i,
5182
+ // Netrange
5183
+ /(nettv)\/(\d+\.[\w\.]+)/i,
5184
+ // NetTV
5185
+ // Console
5186
+ /(nintendo|playstation) (\w+)/i,
5187
+ // Nintendo/Playstation
5188
+ /(xbox); +xbox ([^\);]+)/i,
5189
+ // Microsoft Xbox (360, One, X, S, Series X, Series S)
5190
+ /(pico) .+os([\w\.]+)/i,
5191
+ // Pico
5192
+ // Other
5193
+ /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,
5194
+ // Joli/Palm
5195
+ /linux.+(mint)[\/\(\) ]?([\w\.]*)/i,
5196
+ // Mint
5197
+ /(mageia|vectorlinux|fuchsia|arcaos|arch(?= ?linux))[;l ]([\d\.]*)/i,
5198
+ // Mageia/VectorLinux/Fuchsia/ArcaOS/Arch
5199
+ /([kxln]?ubuntu|debian|suse|opensuse|gentoo|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire|knoppix)(?: gnu[\/ ]linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,
5200
+ // Ubuntu/Debian/SUSE/Gentoo/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire/Knoppix
5201
+ /((?:open)?solaris)[-\/ ]?([\w\.]*)/i,
5202
+ // Solaris
5203
+ /\b(aix)[; ]([1-9\.]{0,4})/i,
5204
+ // AIX
5205
+ /(hurd|linux|morphos)(?: (?:arm|x86|ppc)\w*| ?)([\w\.]*)/i,
5206
+ // Hurd/Linux/MorphOS
5207
+ /(gnu) ?([\w\.]*)/i,
5208
+ // GNU
5209
+ /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,
5210
+ // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly
5211
+ /(haiku) ?(r\d)?/i
5212
+ // Haiku
5213
+ ],
5214
+ [NAME, VERSION3],
5215
+ [
5216
+ /(sunos) ?([\d\.]*)/i
5217
+ // Solaris
5218
+ ],
5219
+ [[NAME, "Solaris"], VERSION3],
5220
+ [
5221
+ /\b(beos|os\/2|amigaos|openvms|hp-ux|serenityos)/i,
5222
+ // BeOS/OS2/AmigaOS/OpenVMS/HP-UX/SerenityOS
5223
+ /(unix) ?([\w\.]*)/i
5224
+ // UNIX
5225
+ ],
5226
+ [NAME, VERSION3]
5227
+ ]
5228
+ };
5229
+ var defaultProps = function() {
5230
+ var props = { init: {}, isIgnore: {}, isIgnoreRgx: {}, toString: {} };
5231
+ setProps.call(props.init, [
5232
+ [BROWSER, [NAME, VERSION3, MAJOR, TYPE]],
5233
+ [CPU, [ARCHITECTURE]],
5234
+ [DEVICE, [TYPE, MODEL, VENDOR]],
5235
+ [ENGINE, [NAME, VERSION3]],
5236
+ [OS, [NAME, VERSION3]]
5237
+ ]);
5238
+ setProps.call(props.isIgnore, [
5239
+ [BROWSER, [VERSION3, MAJOR]],
5240
+ [ENGINE, [VERSION3]],
5241
+ [OS, [VERSION3]]
5242
+ ]);
5243
+ setProps.call(props.isIgnoreRgx, [
5244
+ [BROWSER, / ?browser$/i],
5245
+ [OS, / ?os$/i]
5246
+ ]);
5247
+ setProps.call(props.toString, [
5248
+ [BROWSER, [NAME, VERSION3]],
5249
+ [CPU, [ARCHITECTURE]],
5250
+ [DEVICE, [VENDOR, MODEL]],
5251
+ [ENGINE, [NAME, VERSION3]],
5252
+ [OS, [NAME, VERSION3]]
5253
+ ]);
5254
+ return props;
5255
+ }();
5256
+ var createIData = function(item, itemType) {
5257
+ var init_props = defaultProps.init[itemType], is_ignoreProps = defaultProps.isIgnore[itemType] || 0, is_ignoreRgx = defaultProps.isIgnoreRgx[itemType] || 0, toString_props = defaultProps.toString[itemType] || 0;
5258
+ function IData() {
5259
+ setProps.call(this, init_props);
5260
+ }
5261
+ IData.prototype.getItem = function() {
5262
+ return item;
5263
+ };
5264
+ IData.prototype.withClientHints = function() {
5265
+ if (!NAVIGATOR_UADATA) {
5266
+ return item.parseCH().get();
5267
+ }
5268
+ return NAVIGATOR_UADATA.getHighEntropyValues(CH_ALL_VALUES).then(function(res) {
5269
+ return item.setCH(new UACHData(res, false)).parseCH().get();
5270
+ });
5271
+ };
5272
+ IData.prototype.withFeatureCheck = function() {
5273
+ return item.detectFeature().get();
5274
+ };
5275
+ if (itemType != RESULT) {
5276
+ IData.prototype.is = function(strToCheck) {
5277
+ var is = false;
5278
+ for (var i in this) {
5279
+ if (this.hasOwnProperty(i) && !has(is_ignoreProps, i) && lowerize(is_ignoreRgx ? strip(is_ignoreRgx, this[i]) : this[i]) == lowerize(is_ignoreRgx ? strip(is_ignoreRgx, strToCheck) : strToCheck)) {
5280
+ is = true;
5281
+ if (strToCheck != TYPEOF.UNDEFINED) break;
5282
+ } else if (strToCheck == TYPEOF.UNDEFINED && is) {
5283
+ is = !is;
5284
+ break;
5285
+ }
5286
+ }
5287
+ return is;
5288
+ };
5289
+ IData.prototype.toString = function() {
5290
+ var str = EMPTY;
5291
+ for (var i in toString_props) {
5292
+ if (typeof this[toString_props[i]] !== TYPEOF.UNDEFINED) {
5293
+ str += (str ? " " : EMPTY) + this[toString_props[i]];
5294
+ }
5295
+ }
5296
+ return str || TYPEOF.UNDEFINED;
5297
+ };
5298
+ }
5299
+ if (!NAVIGATOR_UADATA) {
5300
+ IData.prototype.then = function(cb) {
5301
+ var that = this;
5302
+ var IDataResolve = function() {
5303
+ for (var prop in that) {
5304
+ if (that.hasOwnProperty(prop)) {
5305
+ this[prop] = that[prop];
5306
+ }
5307
+ }
5308
+ };
5309
+ IDataResolve.prototype = {
5310
+ is: IData.prototype.is,
5311
+ toString: IData.prototype.toString
5312
+ };
5313
+ var resolveData = new IDataResolve();
5314
+ cb(resolveData);
5315
+ return resolveData;
5316
+ };
5317
+ }
5318
+ return new IData();
5319
+ };
5320
+ function UACHData(uach, isHttpUACH) {
5321
+ uach = uach || {};
5322
+ setProps.call(this, CH_ALL_VALUES);
5323
+ if (isHttpUACH) {
5324
+ setProps.call(this, [
5325
+ [BRANDS, itemListToArray(uach[CH])],
5326
+ [FULLVERLIST, itemListToArray(uach[CH_FULL_VER_LIST])],
5327
+ [MOBILE, /\?1/.test(uach[CH_MOBILE])],
5328
+ [MODEL, stripQuotes(uach[CH_MODEL])],
5329
+ [PLATFORM, stripQuotes(uach[CH_PLATFORM])],
5330
+ [PLATFORMVER, stripQuotes(uach[CH_PLATFORM_VER])],
5331
+ [ARCHITECTURE, stripQuotes(uach[CH_ARCH])],
5332
+ [FORMFACTORS, itemListToArray(uach[CH_FORM_FACTORS])],
5333
+ [BITNESS, stripQuotes(uach[CH_BITNESS])]
5334
+ ]);
5335
+ } else {
5336
+ for (var prop in uach) {
5337
+ if (this.hasOwnProperty(prop) && typeof uach[prop] !== TYPEOF.UNDEFINED) this[prop] = uach[prop];
5338
+ }
5339
+ }
5340
+ }
5341
+ function UAItem(itemType, ua, rgxMap, uaCH) {
5342
+ this.get = function(prop) {
5343
+ if (!prop) return this.data;
5344
+ return this.data.hasOwnProperty(prop) ? this.data[prop] : void 0;
5345
+ };
5346
+ this.set = function(prop, val) {
5347
+ this.data[prop] = val;
5348
+ return this;
5349
+ };
5350
+ this.setCH = function(ch) {
5351
+ this.uaCH = ch;
5352
+ return this;
5353
+ };
5354
+ this.detectFeature = function() {
5355
+ if (NAVIGATOR && NAVIGATOR.userAgent == this.ua) {
5356
+ switch (this.itemType) {
5357
+ case BROWSER:
5358
+ if (NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave == TYPEOF.FUNCTION) {
5359
+ this.set(NAME, "Brave");
5360
+ }
5361
+ break;
5362
+ case DEVICE:
5363
+ if (!this.get(TYPE) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[MOBILE]) {
5364
+ this.set(TYPE, MOBILE);
5365
+ }
5366
+ if (this.get(MODEL) == "Macintosh" && NAVIGATOR && typeof NAVIGATOR.standalone !== TYPEOF.UNDEFINED && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 2) {
5367
+ this.set(MODEL, "iPad").set(TYPE, TABLET);
5368
+ }
5369
+ break;
5370
+ case OS:
5371
+ if (!this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM]) {
5372
+ this.set(NAME, NAVIGATOR_UADATA[PLATFORM]);
5373
+ }
5374
+ break;
5375
+ case RESULT:
5376
+ var data = this.data;
5377
+ var detect = function(itemType2) {
5378
+ return data[itemType2].getItem().detectFeature().get();
5379
+ };
5380
+ this.set(BROWSER, detect(BROWSER)).set(CPU, detect(CPU)).set(DEVICE, detect(DEVICE)).set(ENGINE, detect(ENGINE)).set(OS, detect(OS));
5381
+ }
5382
+ }
5383
+ return this;
5384
+ };
5385
+ this.parseUA = function() {
5386
+ if (this.itemType != RESULT) {
5387
+ rgxMapper.call(this.data, this.ua, this.rgxMap);
5388
+ }
5389
+ switch (this.itemType) {
5390
+ case BROWSER:
5391
+ this.set(MAJOR, majorize(this.get(VERSION3)));
5392
+ break;
5393
+ case OS:
5394
+ if (this.get(NAME) == "iOS" && this.get(VERSION3) == "18.6") {
5395
+ var realVersion = /\) Version\/([\d\.]+)/.exec(this.ua);
5396
+ if (realVersion && parseInt(realVersion[1].substring(0, 2), 10) >= 26) {
5397
+ this.set(VERSION3, realVersion[1]);
5398
+ }
5399
+ }
5400
+ break;
5401
+ }
5402
+ return this;
5403
+ };
5404
+ this.parseCH = function() {
5405
+ var uaCH2 = this.uaCH, rgxMap2 = this.rgxMap;
5406
+ switch (this.itemType) {
5407
+ case BROWSER:
5408
+ case ENGINE:
5409
+ var brands = uaCH2[FULLVERLIST] || uaCH2[BRANDS], prevName;
5410
+ if (brands) {
5411
+ for (var i = 0; i < brands.length; i++) {
5412
+ var brandName = brands[i].brand || brands[i], brandVersion = brands[i].version;
5413
+ if (this.itemType == BROWSER && !/not.a.brand/i.test(brandName) && (!prevName || /Chrom/.test(prevName) && brandName != CHROMIUM || prevName == EDGE && /WebView2/.test(brandName))) {
5414
+ brandName = strMapper(brandName, browserHintsMap);
5415
+ prevName = this.get(NAME);
5416
+ if (!(prevName && !/Chrom/.test(prevName) && /Chrom/.test(brandName))) {
5417
+ this.set(NAME, brandName).set(VERSION3, brandVersion).set(MAJOR, majorize(brandVersion));
5418
+ }
5419
+ prevName = brandName;
5420
+ }
5421
+ if (this.itemType == ENGINE && brandName == CHROMIUM) {
5422
+ this.set(VERSION3, brandVersion);
5423
+ }
5424
+ }
5425
+ }
5426
+ break;
5427
+ case CPU:
5428
+ var archName = uaCH2[ARCHITECTURE];
5429
+ if (archName) {
5430
+ if (archName && uaCH2[BITNESS] == "64") archName += "64";
5431
+ rgxMapper.call(this.data, archName + ";", rgxMap2);
5432
+ }
5433
+ break;
5434
+ case DEVICE:
5435
+ if (uaCH2[MOBILE]) {
5436
+ this.set(TYPE, MOBILE);
5437
+ }
5438
+ if (uaCH2[MODEL]) {
5439
+ this.set(MODEL, uaCH2[MODEL]);
5440
+ if (!this.get(TYPE) || !this.get(VENDOR)) {
5441
+ var reParse = {};
5442
+ rgxMapper.call(reParse, "droid 9; " + uaCH2[MODEL] + ")", rgxMap2);
5443
+ if (!this.get(TYPE) && !!reParse.type) {
5444
+ this.set(TYPE, reParse.type);
5445
+ }
5446
+ if (!this.get(VENDOR) && !!reParse.vendor) {
5447
+ this.set(VENDOR, reParse.vendor);
5448
+ }
5449
+ }
5450
+ }
5451
+ if (uaCH2[FORMFACTORS]) {
5452
+ var ff;
5453
+ if (typeof uaCH2[FORMFACTORS] !== "string") {
5454
+ var idx = 0;
5455
+ while (!ff && idx < uaCH2[FORMFACTORS].length) {
5456
+ ff = strMapper(uaCH2[FORMFACTORS][idx++], formFactorsMap);
5457
+ }
5458
+ } else {
5459
+ ff = strMapper(uaCH2[FORMFACTORS], formFactorsMap);
5460
+ }
5461
+ this.set(TYPE, ff);
5462
+ }
5463
+ break;
5464
+ case OS:
5465
+ var osName = uaCH2[PLATFORM];
5466
+ if (osName) {
5467
+ var osVersion = uaCH2[PLATFORMVER];
5468
+ if (osName == WINDOWS) osVersion = parseInt(majorize(osVersion), 10) >= 13 ? "11" : "10";
5469
+ this.set(NAME, osName).set(VERSION3, osVersion);
5470
+ }
5471
+ if (this.get(NAME) == WINDOWS && uaCH2[MODEL] == "Xbox") {
5472
+ this.set(NAME, "Xbox").set(VERSION3, void 0);
5473
+ }
5474
+ break;
5475
+ case RESULT:
5476
+ var data = this.data;
5477
+ var parse = function(itemType2) {
5478
+ return data[itemType2].getItem().setCH(uaCH2).parseCH().get();
5479
+ };
5480
+ this.set(BROWSER, parse(BROWSER)).set(CPU, parse(CPU)).set(DEVICE, parse(DEVICE)).set(ENGINE, parse(ENGINE)).set(OS, parse(OS));
5481
+ }
5482
+ return this;
5483
+ };
5484
+ setProps.call(this, [
5485
+ ["itemType", itemType],
5486
+ ["ua", ua],
5487
+ ["uaCH", uaCH],
5488
+ ["rgxMap", rgxMap],
5489
+ ["data", createIData(this, itemType)]
5490
+ ]);
5491
+ return this;
5492
+ }
5493
+ function UAParser(ua, extensions, headers) {
5494
+ if (typeof ua === TYPEOF.OBJECT) {
5495
+ if (isExtensions(ua, true)) {
5496
+ if (typeof extensions === TYPEOF.OBJECT) {
5497
+ headers = extensions;
5498
+ }
5499
+ extensions = ua;
5500
+ } else {
5501
+ headers = ua;
5502
+ extensions = void 0;
5503
+ }
5504
+ ua = void 0;
5505
+ } else if (typeof ua === TYPEOF.STRING && !isExtensions(extensions, true)) {
5506
+ headers = extensions;
5507
+ extensions = void 0;
5508
+ }
5509
+ if (headers) {
5510
+ if (typeof headers.append === TYPEOF.FUNCTION) {
5511
+ var kv = {};
5512
+ headers.forEach(function(v, k) {
5513
+ kv[String(k).toLowerCase()] = v;
5514
+ });
5515
+ headers = kv;
5516
+ } else {
5517
+ var normalized = {};
5518
+ for (var header in headers) {
5519
+ if (headers.hasOwnProperty(header)) {
5520
+ normalized[String(header).toLowerCase()] = headers[header];
5521
+ }
5522
+ }
5523
+ headers = normalized;
5524
+ }
5525
+ }
5526
+ if (!(this instanceof UAParser)) {
5527
+ return new UAParser(ua, extensions, headers).getResult();
5528
+ }
5529
+ var userAgent = typeof ua === TYPEOF.STRING ? ua : (
5530
+ // Passed user-agent string
5531
+ headers && headers[USER_AGENT] ? headers[USER_AGENT] : (
5532
+ // User-Agent from passed headers
5533
+ NAVIGATOR && NAVIGATOR.userAgent ? NAVIGATOR.userAgent : (
5534
+ // navigator.userAgent
5535
+ EMPTY
5536
+ )
5537
+ )
5538
+ ), httpUACH = new UACHData(headers, true), regexMap = extensions ? extend2(defaultRegexes, extensions) : defaultRegexes, createItemFunc = function(itemType) {
5539
+ if (itemType == RESULT) {
5540
+ return function() {
5541
+ return new UAItem(itemType, userAgent, regexMap, httpUACH).set("ua", userAgent).set(BROWSER, this.getBrowser()).set(CPU, this.getCPU()).set(DEVICE, this.getDevice()).set(ENGINE, this.getEngine()).set(OS, this.getOS()).get();
5542
+ };
5543
+ } else {
5544
+ return function() {
5545
+ return new UAItem(itemType, userAgent, regexMap[itemType], httpUACH).parseUA().get();
5546
+ };
5547
+ }
5548
+ };
5549
+ setProps.call(this, [
5550
+ ["getBrowser", createItemFunc(BROWSER)],
5551
+ ["getCPU", createItemFunc(CPU)],
5552
+ ["getDevice", createItemFunc(DEVICE)],
5553
+ ["getEngine", createItemFunc(ENGINE)],
5554
+ ["getOS", createItemFunc(OS)],
5555
+ ["getResult", createItemFunc(RESULT)],
5556
+ ["getUA", function() {
5557
+ return userAgent;
5558
+ }],
5559
+ ["setUA", function(ua2) {
5560
+ if (isString2(ua2)) userAgent = trim2(ua2, UA_MAX_LENGTH);
5561
+ return this;
5562
+ }]
5563
+ ]).setUA(userAgent);
5564
+ return this;
3704
5565
  }
5566
+ UAParser.VERSION = LIBVERSION;
5567
+ UAParser.BROWSER = enumerize([NAME, VERSION3, MAJOR, TYPE]);
5568
+ UAParser.CPU = enumerize([ARCHITECTURE]);
5569
+ UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
5570
+ UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION3]);
5571
+
5572
+ // ../../node_modules/.pnpm/@ua-parser-js+pro-enterprise@2.0.6/node_modules/@ua-parser-js/pro-enterprise/src/enums/ua-parser-enums.mjs
5573
+ var BrowserName = Object.freeze({
5574
+ "115": "115",
5575
+ "2345": "2345",
5576
+ "360": "360",
5577
+ ALIPAY: "Alipay",
5578
+ AMAYA: "Amaya",
5579
+ ANDROID: "Android Browser",
5580
+ ARORA: "Arora",
5581
+ AVANT: "Avant",
5582
+ AVAST: "Avast Secure Browser",
5583
+ AVG: "AVG Secure Browser",
5584
+ BAIDU: "Baidu Browser",
5585
+ BASILISK: "Basilisk",
5586
+ BING: "Bing",
5587
+ BLAZER: "Blazer",
5588
+ BOLT: "Bolt",
5589
+ BOWSER: "Bowser",
5590
+ BRAVE: "Brave",
5591
+ CAMINO: "Camino",
5592
+ CHIMERA: "Chimera",
5593
+ CHROME: "Chrome",
5594
+ CHROME_HEADLESS: "Chrome Headless",
5595
+ CHROME_MOBILE: "Mobile Chrome",
5596
+ CHROME_WEBVIEW: "Chrome WebView",
5597
+ CHROMIUM: "Chromium",
5598
+ COBALT: "Cobalt",
5599
+ COC_COC: "Coc Coc",
5600
+ CONKEROR: "Conkeror",
5601
+ DAUM: "Daum",
5602
+ DILLO: "Dillo",
5603
+ DOLPHIN: "Dolphin",
5604
+ DOOBLE: "Dooble",
5605
+ DORIS: "Doris",
5606
+ DRAGON: "Dragon",
5607
+ DUCKDUCKGO: "DuckDuckGo",
5608
+ ECOSIA: "Ecosia",
5609
+ EDGE: "Edge",
5610
+ EDGE_WEBVIEW: "Edge WebView",
5611
+ EDGE_WEBVIEW2: "Edge WebView2",
5612
+ EPIPHANY: "Epiphany",
5613
+ FACEBOOK: "Facebook",
5614
+ FALKON: "Falkon",
5615
+ FIREBIRD: "Firebird",
5616
+ FIREFOX: "Firefox",
5617
+ FIREFOX_FOCUS: "Firefox Focus",
5618
+ FIREFOX_MOBILE: "Mobile Firefox",
5619
+ FIREFOX_REALITY: "Firefox Reality",
5620
+ FENNEC: "Fennec",
5621
+ FLOCK: "Flock",
5622
+ FLOW: "Flow",
5623
+ GO: "GoBrowser",
5624
+ GOOGLE_SEARCH: "GSA",
5625
+ HELIO: "Helio",
5626
+ HEYTAP: "HeyTap",
5627
+ HONOR: "Honor",
5628
+ HUAWEI: "Huawei Browser",
5629
+ ICAB: "iCab",
5630
+ ICE: "ICE Browser",
5631
+ ICEAPE: "IceApe",
5632
+ ICECAT: "IceCat",
5633
+ ICEDRAGON: "IceDragon",
5634
+ ICEWEASEL: "IceWeasel",
5635
+ IE: "IE",
5636
+ INSTAGRAM: "Instagram",
5637
+ IRIDIUM: "Iridium",
5638
+ IRON: "Iron",
5639
+ JASMINE: "Jasmine",
5640
+ KONQUEROR: "Konqueror",
5641
+ KAKAO: "KakaoTalk",
5642
+ KHTML: "KHTML",
5643
+ K_MELEON: "K-Meleon",
5644
+ KLAR: "Klar",
5645
+ KLARNA: "Klarna",
5646
+ KINDLE: "Kindle",
5647
+ LENOVO: "Smart Lenovo Browser",
5648
+ LADYBIRD: "Ladybird",
5649
+ LG: "LG Browser",
5650
+ LIBREWOLF: "LibreWolf",
5651
+ LIEBAO: "LBBROWSER",
5652
+ LINE: "Line",
5653
+ LINKEDIN: "LinkedIn",
5654
+ LINKS: "Links",
5655
+ LUNASCAPE: "Lunascape",
5656
+ LYNX: "Lynx",
5657
+ MAEMO: "Maemo Browser",
5658
+ MAXTHON: "Maxthon",
5659
+ MIDORI: "Midori",
5660
+ MINIMO: "Minimo",
5661
+ MIUI: "MIUI Browser",
5662
+ MOZILLA: "Mozilla",
5663
+ MOSAIC: "Mosaic",
5664
+ NAVER: "Naver",
5665
+ NETFRONT: "NetFront",
5666
+ NETSCAPE: "Netscape",
5667
+ NETSURF: "Netsurf",
5668
+ NOKIA: "Nokia Browser",
5669
+ OBIGO: "Obigo",
5670
+ OCULUS: "Oculus Browser",
5671
+ OMNIWEB: "OmniWeb",
5672
+ OPERA: "Opera",
5673
+ OPERA_COAST: "Opera Coast",
5674
+ OPERA_GX: "Opera GX",
5675
+ OPERA_MINI: "Opera Mini",
5676
+ OPERA_MOBI: "Opera Mobi",
5677
+ OPERA_TABLET: "Opera Tablet",
5678
+ OPERA_TOUCH: "Opera Touch",
5679
+ OTTER: "Otter",
5680
+ OVI: "OviBrowser",
5681
+ PALEMOON: "PaleMoon",
5682
+ PHANTOMJS: "PhantomJS",
5683
+ PHOENIX: "Phoenix",
5684
+ PICOBROWSER: "Pico Browser",
5685
+ POLARIS: "Polaris",
5686
+ PUFFIN: "Puffin",
5687
+ QQ: "QQBrowser",
5688
+ QQ_LITE: "QQBrowserLite",
5689
+ QUARK: "Quark",
5690
+ QUPZILLA: "QupZilla",
5691
+ QUTEBROWSER: "qutebrowser",
5692
+ QWANT: "Qwant",
5693
+ REKONQ: "rekonq",
5694
+ ROCKMELT: "Rockmelt",
5695
+ SAFARI: "Safari",
5696
+ SAFARI_MOBILE: "Mobile Safari",
5697
+ SAILFISH: "Sailfish Browser",
5698
+ SAMSUNG: "Samsung Internet",
5699
+ SEAMONKEY: "SeaMonkey",
5700
+ SILK: "Silk",
5701
+ SKYFIRE: "Skyfire",
5702
+ SLEIPNIR: "Sleipnir",
5703
+ SLIMBOAT: "SlimBoat",
5704
+ SLIMBROWSER: "SlimBrowser",
5705
+ SLIMJET: "Slimjet",
5706
+ SNAPCHAT: "Snapchat",
5707
+ SOGOU_EXPLORER: "Sogou Explorer",
5708
+ SOGOU_MOBILE: "Sogou Mobile",
5709
+ SURF: "Surf",
5710
+ SWIFTFOX: "Swiftfox",
5711
+ TESLA: "Tesla",
5712
+ TIKTOK: "TikTok",
5713
+ TIZEN: "Tizen Browser",
5714
+ TWITTER: "Twitter",
5715
+ UC: "UCBrowser",
5716
+ UP: "UP.Browser",
5717
+ VIVALDI: "Vivaldi",
5718
+ VIVO: "Vivo Browser",
5719
+ W3M: "w3m",
5720
+ WATERFOX: "Waterfox",
5721
+ WEBKIT: "WebKit",
5722
+ WECHAT: "WeChat",
5723
+ WEIBO: "Weibo",
5724
+ WHALE: "Whale",
5725
+ WOLVIC: "Wolvic",
5726
+ YANDEX: "Yandex",
5727
+ ZALO: "Zalo"
5728
+ // TODO : test!
5729
+ });
5730
+ var BrowserType = Object.freeze({
5731
+ CRAWLER: "crawler",
5732
+ CLI: "cli",
5733
+ EMAIL: "email",
5734
+ FETCHER: "fetcher",
5735
+ INAPP: "inapp",
5736
+ MEDIAPLAYER: "mediaplayer",
5737
+ LIBRARY: "library"
5738
+ });
5739
+ var CPUArch = Object.freeze({
5740
+ "68K": "68k",
5741
+ ALPHA: "alpha",
5742
+ ARM: "arm",
5743
+ ARM_64: "arm64",
5744
+ ARM_HF: "armhf",
5745
+ AVR: "avr",
5746
+ AVR_32: "avr32",
5747
+ IA64: "ia64",
5748
+ IRIX: "irix",
5749
+ IRIX_64: "irix64",
5750
+ MIPS: "mips",
5751
+ MIPS_64: "mips64",
5752
+ PA_RISC: "pa-risc",
5753
+ PPC: "ppc",
5754
+ SPARC: "sparc",
5755
+ SPARC_64: "sparc64",
5756
+ X86: "ia32",
5757
+ X86_64: "amd64"
5758
+ });
5759
+ var DeviceType = Object.freeze({
5760
+ CONSOLE: "console",
5761
+ DESKTOP: "desktop",
5762
+ EMBEDDED: "embedded",
5763
+ MOBILE: "mobile",
5764
+ SMARTTV: "smarttv",
5765
+ TABLET: "tablet",
5766
+ WEARABLE: "wearable",
5767
+ XR: "xr"
5768
+ });
5769
+ var DeviceVendor = Object.freeze({
5770
+ ACER: "Acer",
5771
+ ADVAN: "Advan",
5772
+ ALCATEL: "Alcatel",
5773
+ APPLE: "Apple",
5774
+ AMAZON: "Amazon",
5775
+ ARCHOS: "Archos",
5776
+ ASUS: "ASUS",
5777
+ ATT: "AT&T",
5778
+ BENQ: "BenQ",
5779
+ BLACKBERRY: "BlackBerry",
5780
+ BLU: "BLU",
5781
+ CAT: "Cat",
5782
+ DELL: "Dell",
5783
+ ENERGIZER: "Energizer",
5784
+ ESSENTIAL: "Essential",
5785
+ FACEBOOK: "Facebook",
5786
+ FAIRPHONE: "Fairphone",
5787
+ GEEKSPHONE: "GeeksPhone",
5788
+ GENERIC: "Generic",
5789
+ GOOGLE: "Google",
5790
+ HISENSE: "Hisense",
5791
+ HMD: "HMD",
5792
+ HP: "HP",
5793
+ HTC: "HTC",
5794
+ HUAWEI: "Huawei",
5795
+ IMO: "IMO",
5796
+ INFINIX: "Infinix",
5797
+ ITEL: "itel",
5798
+ JOLLA: "Jolla",
5799
+ KOBO: "Kobo",
5800
+ LAVA: "Lava",
5801
+ LENOVO: "Lenovo",
5802
+ LG: "LG",
5803
+ MEIZU: "Meizu",
5804
+ MICROMAX: "Micromax",
5805
+ MICROSOFT: "Microsoft",
5806
+ MOTOROLA: "Motorola",
5807
+ NEXIAN: "Nexian",
5808
+ NINTENDO: "Nintendo",
5809
+ NOKIA: "Nokia",
5810
+ NOTHING: "Nothing",
5811
+ NVIDIA: "Nvidia",
5812
+ ONEPLUS: "OnePlus",
5813
+ OPPO: "OPPO",
5814
+ OUYA: "Ouya",
5815
+ PALM: "Palm",
5816
+ PANASONIC: "Panasonic",
5817
+ PEBBLE: "Pebble",
5818
+ PHILIPS: "Philips",
5819
+ PICO: "Pico",
5820
+ POLYTRON: "Polytron",
5821
+ REALME: "Realme",
5822
+ RETROID: "Retroid",
5823
+ RIM: "RIM",
5824
+ ROKU: "Roku",
5825
+ SAMSUNG: "Samsung",
5826
+ SHARP: "Sharp",
5827
+ SIEMENS: "Siemens",
5828
+ SMARTFREN: "Smartfren",
5829
+ SONY: "Sony",
5830
+ SPRINT: "Sprint",
5831
+ TCL: "TCL",
5832
+ TECHNISAT: "TechniSAT",
5833
+ TECNO: "TECNO",
5834
+ TESLA: "Tesla",
5835
+ ULEFONE: "Ulefone",
5836
+ VIVO: "Vivo",
5837
+ VIZIO: "Vizio",
5838
+ VODAFONE: "Vodafone",
5839
+ WIKO: "Wiko",
5840
+ XBOX: "Xbox",
5841
+ XIAOMI: "Xiaomi",
5842
+ ZEBRA: "Zebra",
5843
+ ZTE: "ZTE"
5844
+ // TODO : test!
5845
+ });
5846
+ var EngineName = Object.freeze({
5847
+ AMAYA: "Amaya",
5848
+ ARKWEB: "ArkWeb",
5849
+ BLINK: "Blink",
5850
+ EDGEHTML: "EdgeHTML",
5851
+ FLOW: "Flow",
5852
+ GECKO: "Gecko",
5853
+ GOANNA: "Goanna",
5854
+ ICAB: "iCab",
5855
+ KHTML: "KHTML",
5856
+ LIBWEB: "LibWeb",
5857
+ LINKS: "Links",
5858
+ LYNX: "Lynx",
5859
+ NETFRONT: "NetFront",
5860
+ NETSURF: "NetSurf",
5861
+ PRESTO: "Presto",
5862
+ SERVO: "Servo",
5863
+ TASMAN: "Tasman",
5864
+ TRIDENT: "Trident",
5865
+ W3M: "w3m",
5866
+ WEBKIT: "WebKit"
5867
+ });
5868
+ var OSName = Object.freeze({
5869
+ AIX: "AIX",
5870
+ AMIGA_OS: "Amiga OS",
5871
+ ANDROID: "Android",
5872
+ ANDROID_X86: "Android-x86",
5873
+ ARCAOS: "ArcaOS",
5874
+ ARCH: "Arch",
5875
+ BADA: "Bada",
5876
+ BEOS: "BeOS",
5877
+ BLACKBERRY: "BlackBerry",
5878
+ CENTOS: "CentOS",
5879
+ CHROME_OS: "Chrome OS",
5880
+ CHROMECAST: "Chromecast",
5881
+ CHROMECAST_ANDROID: "Chromecast Android",
5882
+ CHROMECAST_FUCHSIA: "Chromecast Fuchsia",
5883
+ CHROMECAST_LINUX: "Chromecast Linux",
5884
+ CHROMECAST_SMARTSPEAKER: "Chromecast SmartSpeaker",
5885
+ CONTIKI: "Contiki",
5886
+ DEBIAN: "Debian",
5887
+ DEEPIN: "Deepin",
5888
+ DRAGONFLY: "DragonFly",
5889
+ ELEMENTARY_OS: "elementary OS",
5890
+ FEDORA: "Fedora",
5891
+ FIREFOX_OS: "Firefox OS",
5892
+ FREEBSD: "FreeBSD",
5893
+ FUCHSIA: "Fuchsia",
5894
+ GENTOO: "Gentoo",
5895
+ GHOSTBSD: "GhostBSD",
5896
+ GNU: "GNU",
5897
+ HAIKU: "Haiku",
5898
+ HARMONYOS: "HarmonyOS",
5899
+ HP_UX: "HP-UX",
5900
+ HURD: "Hurd",
5901
+ IOS: "iOS",
5902
+ JOLI: "Joli",
5903
+ KAIOS: "KaiOS",
5904
+ KNOPPIX: "Knoppix",
5905
+ KUBUNTU: "Kubuntu",
5906
+ LINPUS: "Linpus",
5907
+ LINSPIRE: "Linspire",
5908
+ LINUX: "Linux",
5909
+ MACOS: "macOS",
5910
+ MAEMO: "Maemo",
5911
+ MAGEIA: "Mageia",
5912
+ MANDRIVA: "Mandriva",
5913
+ MANJARO: "Manjaro",
5914
+ MEEGO: "MeeGo",
5915
+ MINIX: "Minix",
5916
+ MINT: "Mint",
5917
+ MORPH_OS: "Morph OS",
5918
+ NETBSD: "NetBSD",
5919
+ NETRANGE: "NetRange",
5920
+ NETTV: "NetTV",
5921
+ NINTENDO: "Nintendo",
5922
+ OPENHARMONY: "OpenHarmony",
5923
+ OPENBSD: "OpenBSD",
5924
+ OPENVMS: "OpenVMS",
5925
+ OS2: "OS/2",
5926
+ PALM: "Palm",
5927
+ PC_BSD: "PC-BSD",
5928
+ PCLINUXOS: "PCLinuxOS",
5929
+ PICO: "Pico",
5930
+ PLAN9: "Plan9",
5931
+ PLAYSTATION: "PlayStation",
5932
+ QNX: "QNX",
5933
+ RASPBIAN: "Raspbian",
5934
+ REDHAT: "RedHat",
5935
+ RIM_TABLET_OS: "RIM Tablet OS",
5936
+ RISC_OS: "RISC OS",
5937
+ SABAYON: "Sabayon",
5938
+ SAILFISH: "Sailfish",
5939
+ SERENITYOS: "SerenityOS",
5940
+ SERIES40: "Series40",
5941
+ SLACKWARE: "Slackware",
5942
+ SOLARIS: "Solaris",
5943
+ SUSE: "SUSE",
5944
+ SYMBIAN: "Symbian",
5945
+ TIZEN: "Tizen",
5946
+ UBUNTU: "Ubuntu",
5947
+ UBUNTU_TOUCH: "Ubuntu Touch",
5948
+ UNIX: "Unix",
5949
+ VECTORLINUX: "VectorLinux",
5950
+ WATCHOS: "watchOS",
5951
+ WEBOS: "WebOS",
5952
+ WINDOWS: "Windows",
5953
+ WINDOWS_CE: "Windows CE",
5954
+ WINDOWS_IOT: "Windows IoT",
5955
+ WINDOWS_MOBILE: "Windows Mobile",
5956
+ WINDOWS_PHONE: "Windows Phone",
5957
+ WINDOWS_RT: "Windows RT",
5958
+ XBOX: "Xbox",
5959
+ XUBUNTU: "Xubuntu",
5960
+ ZENWALK: "Zenwalk"
5961
+ // TODO : test!
5962
+ });
5963
+ var Extension = Object.freeze({
5964
+ BrowserName: {
5965
+ CLI: {
5966
+ CURL: "curl",
5967
+ ELINKS: "ELinks",
5968
+ HTTPIE: "HTTPie",
5969
+ LYNX: "Lynx",
5970
+ WGET: "Wget"
5971
+ },
5972
+ Crawler: {
5973
+ AHREFS_BOT: "AhrefsBot",
5974
+ AI2_BOT: "AI2Bot",
5975
+ AIHIT_BOT: "aiHitBot",
5976
+ ALGOLIA_CRAWLER: "Algolia Crawler",
5977
+ APPLE_BOT: "Applebot",
5978
+ APPLE_BOT_EXTENDED: "Applebot-Extended",
5979
+ ASK_TEOMA: "Teoma",
5980
+ AMAZON_BOT: "Amazonbot",
5981
+ AMAZON_CONTXBOT: "contxbot",
5982
+ ANTHROPIC_AI: "anthropic-ai",
5983
+ ANTHROPIC_CLAUDE_BOT: "ClaudeBot",
5984
+ ANTHROPIC_CLAUDE_SEARCHBOT: "Claude-SearchBot",
5985
+ ANTHROPIC_CLAUDE_WEB: "Claude-Web",
5986
+ ARCHIVEORG_BOT: "archive.org_bot",
5987
+ BAIDU_ADS: "Baidu-ADS",
5988
+ BAIDU_SPIDER: "Baiduspider",
5989
+ BAIDU_SPIDER_ADS: "Baiduspider-ads",
5990
+ BAIDU_SPIDER_CPRO: "Baiduspider-cpro",
5991
+ BAIDU_SPIDER_FAVO: "Baiduspider-favo",
5992
+ BAIDU_SPIDER_IMAGE: "Baiduspider-image",
5993
+ BAIDU_SPIDER_NEWS: "Baiduspider-news",
5994
+ BAIDU_SPIDER_RENDER: "Baiduspider-render",
5995
+ BAIDU_SPIDER_VIDEO: "Baiduspider-video",
5996
+ BLEX_BOT: "BLEXBot",
5997
+ BOTIFY: "botify",
5998
+ BRAVE_BOT: "Bravebot",
5999
+ BYTEDANCE_BYTESPIDER: "Bytespider",
6000
+ BYTEDANCE_TIKTOKSPIDER: "TikTokSpider",
6001
+ COMMON_CRAWL_CCBOT: "CCBot",
6002
+ COCCOC_BOT_WEB: "coccocbot-web",
6003
+ COCCOC_BOT_IMAGE: "coccocbot-image",
6004
+ COHERE_TRAINING_DATA_CRAWLER: "cohere-training-data-crawler",
6005
+ COTOYOGI: "Cotoyogi",
6006
+ COVEO_BOT: "Coveobot",
6007
+ CRITEO_BOT: "CriteoBot",
6008
+ DATAFORSEO_BOT: "DataForSeoBot",
6009
+ DAUM: "Daum",
6010
+ DAUM_DAUMOA: "Daumoa",
6011
+ DAUM_DAUMOA_IMAGE: "Daumoa-image",
6012
+ DEEPSEEK_BOT: "DeepSeekBot",
6013
+ DIFFBOT: "Diffbot",
6014
+ DUCKDUCKGO_BOT: "DuckDuckBot",
6015
+ DUCKDUCKGO_FAVICONS_BOT: "DuckDuckGo-Favicons-Bot",
6016
+ ELASTIC: "Elastic",
6017
+ ELASTIC_SWIFTYPE_BOT: "Swiftbot",
6018
+ EXALEAD_EXABOT: "Exabot",
6019
+ FIRECRAWL_AGENT: "FirecrawlAgent",
6020
+ FREESPOKE: "Freespoke",
6021
+ GOOGLE_ADSBOT: "AdsBot-Google",
6022
+ GOOGLE_ADSBOT_MOBILE: "Adsbot-Google-Mobile",
6023
+ GOOGLE_ADSENSE: "AdSense",
6024
+ GOOGLE_APIS: "APIs-Google",
6025
+ GOOGLE_BOT: "Googlebot",
6026
+ GOOGLE_BOT_IMAGE: "Googlebot-Image",
6027
+ GOOGLE_BOT_NEWS: "Googlebot-News",
6028
+ GOOGLE_BOT_VIDEO: "Googlebot-Video",
6029
+ GOOGLE_CLOUDVERTEXBOT: "Google-CloudVertexBot",
6030
+ GOOGLE_EXTENDED: "Google-Extended",
6031
+ GOOGLE_INSPECTIONTOOL: "Google-InspectionTool",
6032
+ GOOGLE_OTHER: "GoogleOther",
6033
+ GOOGLE_OTHER_IMAGE: "GoogleOther-Image",
6034
+ GOOGLE_OTHER_VIDEO: "GoogleOther-Video",
6035
+ GOOGLE_SAFETY: "Google-Safety",
6036
+ GOOGLE_STOREBOT: "Storebot-Google",
6037
+ HIVE_IMAGESIFTBOT: "ImagesiftBot",
6038
+ HUAWEI_PANGUBOT: "PanguBot",
6039
+ HUAWEI_PETALBOT: "PetalBot",
6040
+ HUGGINGFACE_BOT: "HuggingFace-Bot",
6041
+ HUNTER_VELENPUBLICWEBCRAWLER: "VelenPublicWebCrawler",
6042
+ IA_ARCHIVER: "ia_archiver",
6043
+ IASK_BOT: "iAskBot",
6044
+ KAGI_BOT: "Kagibot",
6045
+ KANGAROO_BOT: "Kangaroo Bot",
6046
+ LINE_SPIDER: "Linespider",
6047
+ LINKEDIN_BOT: "LinkedInBot",
6048
+ MAGPIE_CRAWLER: "magpie-crawler",
6049
+ MARGINALIA: "marginalia",
6050
+ META_EXTERNALAGENT: "meta-externalagent",
6051
+ META_FACEBOOKBOT: "FacebookBot",
6052
+ META_FACEBOOKCATALOG: "facebookcatalog",
6053
+ META_FACEBOOKEXTERNALHIT: "facebookexternalhit",
6054
+ MAJESTIC_MJ12BOT: "MJ12bot",
6055
+ MICROSOFT_BINGBOT: "Bingbot",
6056
+ MICROSOFT_MSNBOT: "msnbot",
6057
+ MICROSOFT_ADIDXBOT: "adidxbot",
6058
+ MOJEEK_BOT: "MojeekBot",
6059
+ MOZ_DOTBOT: "DotBot",
6060
+ ONCRAWL: "OnCrawl",
6061
+ ONESPOT_SCRAPERBOT: "Onespot-ScraperBot",
6062
+ OPENAI_GPTBOT: "GPTBot",
6063
+ OPENAI_SEARCH_BOT: "OAI-SearchBot",
6064
+ PERPLEXITY_BOT: "PerplexityBot",
6065
+ QIHOO_360_SPIDER: "360Spider",
6066
+ QWANT_BOT: "Qwantbot",
6067
+ QWANT_BOT_NEWS: "Qwantbot-news",
6068
+ REPLICATE_BOT: "Replicate-Bot",
6069
+ RUNPOD_BOT: "RunPod-Bot",
6070
+ SB_INTUITIONS_BOT: "SBIntuitionsBot",
6071
+ SEEKPORT_BOT: "SeekportBot",
6072
+ SEMRUSH_BOT: "SemrushBot",
6073
+ SEMRUSH_BOT_BACKLINK: "SemrushBot-BA",
6074
+ SEMRUSH_BOT_CONTENTSHAKE: "SemrushBot-OCOB",
6075
+ SEMRUSH_BOT_SEO_CHECKER: "SemrushBot-SI",
6076
+ SEZNAM_BOT: "SeznamBot",
6077
+ SITEIMPROVE: "Siteimprove",
6078
+ SOGOU_PIC_SPIDER: "Sogou Pic Spider",
6079
+ SOGOU_WEB_SPIDER: "Sogou web spider",
6080
+ STARTPAGE: "Startpage",
6081
+ SURLY_BOT: "SurdotlyBot",
6082
+ TIMPI_BOT: "Timpibot",
6083
+ TOGETHER_BOT: "Together-Bot",
6084
+ TURNITIN_BOT: "TurnitinBot",
6085
+ TWIN_AGENT: "TwinAgent",
6086
+ VERCEL_V0BOT: "v0bot",
6087
+ WEBZIO: "webzio",
6088
+ WEBZIO_EXTENDED: "Webzio-Extended",
6089
+ WEBZIO_OMGILI: "omgili",
6090
+ WEBZIO_OMGILI_BOT: "omgilibot",
6091
+ XAI_BOT: "xAI-Bot",
6092
+ YAHOO_JAPAN: "Y!J-BRW",
6093
+ YAHOO_SLURP: "Yahoo! Slurp",
6094
+ YANDEX_ACCESSIBILITY_BOT: "YandexAccessibilityBot",
6095
+ YANDEX_ADDITIONAL_BOT: "YandexAdditionalBot",
6096
+ YANDEX_ADNET: "YandexAdNet",
6097
+ YANDEX_BLOGS: "YandexBlogs",
6098
+ YANDEX_BOT: "YandexBot",
6099
+ YANDEX_BOT_MIRRORDETECTOR: "YandexBot MirrorDetector",
6100
+ YANDEX_COMBOT: "YandexComBot",
6101
+ YANDEX_FAVICONS: "YandexFavicons",
6102
+ YANDEX_IMAGE_RESIZER: "YandexImageResizer",
6103
+ YANDEX_IMAGES: "YandexImages",
6104
+ YANDEX_MARKET: "YandexMarket",
6105
+ YANDEX_MEDIA: "YandexMedia",
6106
+ YANDEX_METRIKA: "YandexMetrika",
6107
+ YANDEX_MOBILE_BOT: "YandexMobileBot",
6108
+ YANDEX_MOBILE_SCREENSHOT_BOT: "YandexMobileScreenShotBot",
6109
+ YANDEX_NEWS: "YandexNews",
6110
+ YANDEX_ONTODB: "YandexOntoDB",
6111
+ YANDEX_ONTODB_API: "YandexOntoDBAPI",
6112
+ YANDEX_PARTNER: "YandexPartner",
6113
+ YANDEX_RCA: "YandexRCA",
6114
+ YANDEX_RENDERRESOURCES_BOT: "YandexRenderResourcesBot",
6115
+ YANDEX_SCREENSHOT_BOT: "YandexScreenshotBot",
6116
+ YANDEX_SPRAV_BOT: "YandexSpravBot",
6117
+ YANDEX_TRACKER: "YandexTracker",
6118
+ YANDEX_VERTICALS: "YandexVerticals",
6119
+ YANDEX_VERTIS: "YandexVertis",
6120
+ YANDEX_VIDEO: "YandexVideo",
6121
+ YANDEX_VIDEO_PARSER: "YandexVideoParser",
6122
+ YANDEX_WEBMASTER: "YandexWebmaster",
6123
+ YEP_BOT: "YepBot",
6124
+ YETI: "Yeti",
6125
+ YISOU_SPIDER: "YisouSpider",
6126
+ YOU_BOT: "YouBot",
6127
+ ZHIPU_CHATGLM_SPIDER: "ChatGLM-Spider",
6128
+ ZUM_BOT: "ZumBot"
6129
+ },
6130
+ Email: {
6131
+ AIRMAIL: "Airmail",
6132
+ APPLE_MAIL: "Mail",
6133
+ BLUEMAIL: "BlueMail",
6134
+ DAUM_MAIL: "DaumMail",
6135
+ EVOLUTION: "Evolution",
6136
+ EM_CLIENT: "eM Client",
6137
+ FOXMAIL: "Foxmail",
6138
+ KMAIL: "KMail",
6139
+ KMAIL2: "kmail2",
6140
+ KONTACT: "Kontact",
6141
+ MICROSOFT_OUTLOOK: "Microsoft Outlook",
6142
+ MICROSOFT_OUTLOOK_MAC: "MacOutlook",
6143
+ NAVER_MAILAPP: "NaverMailApp",
6144
+ POLYMAIL: "Polymail",
6145
+ PROTON_MAIL: "ProtonMail",
6146
+ SPARK_MAIL: "SparkDesktop",
6147
+ SPARROW: "Sparrow",
6148
+ THUNDERBIRD: "Thunderbird",
6149
+ YAHOO_MAIL: "Yahoo",
6150
+ ZIMBRA: "Zimbra",
6151
+ ZOHO_MAIL: "ZohoMail-Desktop"
6152
+ },
6153
+ Fetcher: {
6154
+ AHREFS_SITEAUDIT: "AhrefsSiteAudit",
6155
+ ANTHROPIC_CLAUDE_USER: "Claude-User",
6156
+ ASANA: "Asana",
6157
+ BETTER_UPTIME_BOT: "Better Uptime Bot",
6158
+ BITLY_BOT: "bitlybot",
6159
+ BLUESKY: "Bluesky",
6160
+ BUFFER_LINKPREVIEWBOT: "BufferLinkPreviewBot",
6161
+ COHERE_AI: "Cohere-AI",
6162
+ DISCORD_BOT: "Discordbot",
6163
+ DUCKDUCKGO_ASSISTBOT: "DuckAssistBot",
6164
+ GOOGLE_CHROME_LIGHTHOUSE: "Chrome-Lighthouse",
6165
+ GOOGLE_FEEDFETCHER: "FeedFetcher-Google",
6166
+ GOOGLE_GEMINI_DEEP_RESEARCH: "Gemini-Deep-Research",
6167
+ GOOGLE_IMAGEPROXY: "GoogleImageProxy",
6168
+ GOOGLE_PAGERENDERER: "Google-PageRenderer",
6169
+ GOOGLE_READ_ALOUD: "Google-Read-Aloud",
6170
+ GOOGLE_PRODUCER: "GoogleProducer",
6171
+ GOOGLE_SITE_VERIFICATION: "Google-Site-Verification",
6172
+ HUBSPOT_PAGE_FETCHER: "HubSpot Page Fetcher",
6173
+ IFRAMELY: "Iframely",
6174
+ KAKAOTALK_SCRAP: "kakaotalk-scrap",
6175
+ KEYBASE_BOT: "KeybaseBot",
6176
+ META_EXTERNALFETCHER: "meta-externalfetcher",
6177
+ META_WHATSAPP: "WhatsApp",
6178
+ MICROSOFT_BINGPREVIEW: "BingPreview",
6179
+ MICROSOFT_PREVIEW: "MicrosoftPreview",
6180
+ MISTRALAI_USER: "MistralAI-User",
6181
+ NAVER_BLUENO: "Blueno",
6182
+ ONCRAWL_ROGERBOT: "rogerbot",
6183
+ OPENAI_CHATGPT_USER: "ChatGPT-User",
6184
+ PERPLEXITY_USER: "Perplexity-User",
6185
+ PINTEREST_BOT: "Pinterestbot",
6186
+ SEMRUSH_SITEAUDITBOT: "SiteAuditBot",
6187
+ SLACK_BOT: "Slackbot",
6188
+ SLACK_BOT_LINKEXPANDING: "Slackbot-LinkExpanding",
6189
+ SLACK_IMGPROXY: "Slack-ImgProxy",
6190
+ SNAP_URL_PREVIEW: "Snap URL Preview",
6191
+ SKYPE_URIPREVIEW: "SkypeUriPreview",
6192
+ TELEGRAM_BOT: "TelegramBot",
6193
+ UPTIMEROBOT: "UptimeRobot",
6194
+ VERCEL_FAVICON_BOT: "vercel-favicon-bot",
6195
+ VERCEL_SCREENSHOT_BOT: "vercel-screenshot-bot",
6196
+ VERCEL_BOT: "Vercelbot",
6197
+ VERCEL_FLAGS: "vercelflags",
6198
+ VERCEL_TRACING: "verceltracing",
6199
+ X_TWITTERBOT: "Twitterbot",
6200
+ YANDEX_CALENDAR: "YandexCalendar",
6201
+ YANDEX_DIRECT: "YandexDirect",
6202
+ YANDEX_DIRECTDYN: "YandexDirectDyn",
6203
+ YANDEX_DIRECTFETCHER: "YaDirectFetcher",
6204
+ YANDEX_FORDOMAIN: "YandexForDomain",
6205
+ YANDEX_PAGECHECKER: "YandexPagechecker",
6206
+ YANDEX_SEARCHSHOP: "YandexSearchShop",
6207
+ YANDEX_SITELINKS: "YandexSitelinks",
6208
+ YANDEX_USERPROXY: "YandexUserproxy",
6209
+ ZOOMINFO_BOT: "Zoombot"
6210
+ },
6211
+ InApp: {
6212
+ DISCORD: "Discord",
6213
+ EVERNOTE: "Evernote",
6214
+ FIGMA: "Figma",
6215
+ FLIPBOARD: "Flipboard",
6216
+ MATTERMOST: "Mattermost",
6217
+ TEAMS: "Teams",
6218
+ NOTION: "Notion",
6219
+ POSTMAN: "Postman",
6220
+ RAMBOX: "Rambox",
6221
+ ROCKETCHAT: "Rocket.Chat",
6222
+ SLACK: "Slack",
6223
+ TIKTOK_LITE: "TikTok Lite",
6224
+ VSCODE: "VS Code",
6225
+ YAHOO_JAPAN: "Yahoo! Japan"
6226
+ },
6227
+ Library: {
6228
+ ADOBE_AIR: "AdobeAIR",
6229
+ AIOHTTP: "aiohttp",
6230
+ APACHE_HTTPCLIENT: "Apache-HttpClient",
6231
+ AXIOS: "axios",
6232
+ GO_HTTP_CLIENT: "go-http-client",
6233
+ GOT: "got",
6234
+ GUZZLEHTTP: "GuzzleHttp",
6235
+ JAVA: "Java",
6236
+ JAVA_HTTPCLIENT: "Java-http-client",
6237
+ JSDOM: "jsdom",
6238
+ LIBWWW_PERL: "libwww-perl",
6239
+ LUA_RESTY_HTTP: "lua-resty-http",
6240
+ NEEDLE: "Needle",
6241
+ NUTCH: "Nutch",
6242
+ OKHTTP: "OkHttp",
6243
+ NODE_FETCH: "node-fetch",
6244
+ NODE_SUPERAGENT: "node-superagent",
6245
+ PHP_SOAP: "PHP-SOAP",
6246
+ POSTMAN_RUNTIME: "PostmanRuntime",
6247
+ PYTHON_HTTPX: "python-httpx",
6248
+ PYTHON_URLLIB: "python-urllib",
6249
+ PYTHON_URLLIB3: "python-urllib3",
6250
+ PYTHON_REQUESTS: "python-requests",
6251
+ SCRAPY: "Scrapy"
6252
+ }
6253
+ },
6254
+ DeviceVendor: {
6255
+ Vehicle: {
6256
+ BMW: "BMW",
6257
+ BYD: "BYD",
6258
+ JEEP: "Jeep",
6259
+ RIVIAN: "Rivian",
6260
+ TESLA: "Tesla",
6261
+ VOLVO: "Volvo"
6262
+ }
6263
+ }
6264
+ });
6265
+
6266
+ // ../../node_modules/.pnpm/@ua-parser-js+pro-enterprise@2.0.6/node_modules/@ua-parser-js/pro-enterprise/src/extensions/ua-parser-extensions.mjs
6267
+ var MODEL2 = "model";
6268
+ var NAME2 = "name";
6269
+ var TYPE2 = "type";
6270
+ var VENDOR2 = "vendor";
6271
+ var VERSION4 = "version";
6272
+ var MOBILE2 = "mobile";
6273
+ var TABLET2 = "tablet";
6274
+ var CRAWLER = "crawler";
6275
+ var CLI = "cli";
6276
+ var EMAIL = "email";
6277
+ var FETCHER = "fetcher";
6278
+ var INAPP2 = "inapp";
6279
+ var MEDIAPLAYER = "mediaplayer";
6280
+ var LIBRARY = "library";
6281
+ var CLIs = Object.freeze({
6282
+ browser: [
6283
+ // wget / curl / Lynx / ELinks / HTTPie
6284
+ [/(wget|curl|lynx|elinks|httpie)[\/ ]\(?([\w\.-]+)/i],
6285
+ [NAME2, VERSION4, [TYPE2, CLI]]
6286
+ ]
6287
+ });
6288
+ var Crawlers = Object.freeze({
6289
+ browser: [
6290
+ [
6291
+ // AhrefsBot - https://ahrefs.com/robot
6292
+ // Amazonbot - https://developer.amazon.com/amazonbot
6293
+ // Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0
6294
+ // Bravebot - https://search.brave.com/help/brave-search-crawler
6295
+ // CCBot - https://commoncrawl.org/faq
6296
+ // contxbot - https://affiliate-program.amazon.com/help/node/topic/GT98G5PPRERNVZ2C
6297
+ // Coveobot - https://connect.coveo.com/s/article/19648
6298
+ // CriteoBot - https://www.criteo.com/criteo-crawler/
6299
+ // Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot
6300
+ // DuckDuckBot - http://duckduckgo.com/duckduckbot.html
6301
+ // FacebookBot - https://developers.facebook.com/docs/sharing/bot/
6302
+ // GPTBot - https://platform.openai.com/docs/gptbot
6303
+ // iAskBot - https://iask.ai
6304
+ // Kagibot - https://kagi.com/bot
6305
+ // Kangaroo Bot - https://kangaroollm.com.au/kangaroo-bot/
6306
+ // LinkedInBot - http://www.linkedin.com
6307
+ // MJ12bot - https://mj12bot.com/
6308
+ // MojeekBot - https://www.mojeek.com/bot.html
6309
+ // Onespot - https://www.onespot.com/identifying-traffic.html
6310
+ // OpenAI's SearchGPT - https://platform.openai.com/docs/bots
6311
+ // PerplexityBot - https://perplexity.ai/perplexitybot
6312
+ // SBIntuitionsBot - https://www.sbintuitions.co.jp/bot/
6313
+ // SeznamBot - http://napoveda.seznam.cz/seznambot-intro
6314
+ // SurdotlyBot - http://sur.ly/bot.html
6315
+ // Swiftbot - https://swiftype.com/swiftbot
6316
+ // YepBot - https://yep.com/yepbot/
6317
+ /((?:adidx|ahrefs|amazon|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|sbintuitions|semrush|seznam|surdotly|swift|yep)bot)\/([\w\.-]+)/i,
6318
+ // Algolia Crawler
6319
+ /(algolia crawler(?: renderscript)?)\/?([\w\.]*)/i,
6320
+ // Applebot - http://apple.com/go/applebot
6321
+ /(applebot(?:-extended)?)\/?([\w\.]*)/i,
6322
+ // Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001
6323
+ /(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i,
6324
+ // ClaudeBot (Anthropic)
6325
+ /(claude(?:bot|-searchbot|-web)|anthropic-ai)\/?([\w\.]*)/i,
6326
+ // Coc Coc Bot - https://help.coccoc.com/en/search-engine
6327
+ /(coccocbot-(?:image|web))\/([\w\.]+)/i,
6328
+ // Daum
6329
+ /(daum(?:oa)?(?:-image)?)[ \/]([\w\.]+)/i,
6330
+ // Facebook / Meta
6331
+ // https://developers.facebook.com/docs/sharing/webmasters/web-crawlers
6332
+ /(facebook(?:externalhit|catalog)|meta-externalagent)\/([\w\.]+)/i,
6333
+ // Googlebot - http://www.google.com/bot.html
6334
+ /(google(?:bot|other|-inspectiontool)(?:-image|-video|-news)?|storebot-google)\/?([\w\.]*)/i,
6335
+ // Internet Archive (archive.org)
6336
+ /(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i,
6337
+ // OnCrawl
6338
+ /(oncrawl) mobile\/([\w\.]+)/i,
6339
+ // Qwantbot - https://help.qwant.com/bot
6340
+ /(qwantbot(?:-news)?)[-\w]*\/?([\w\.]*)/i,
6341
+ // SemrushBot - http://www.semrush.com/bot.html
6342
+ /((?:semrush|splitsignal)bot[-abcfimostw]*)\/?([\w\.-]*)/i,
6343
+ // Sogou Spider
6344
+ /(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i,
6345
+ // Yahoo! Japan - https://support.yahoo-net.jp/PccSearch/s/article/H000007955
6346
+ /(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i,
6347
+ // Yandex Bots - https://yandex.com/bots
6348
+ /(yandex(?:(?:mobile)?(?:accessibility|additional|com|renderresources|screenshot|sprav)?bot(?!.+mirror)|image(?:s|resizer)|adnet|blogs|favicons|market|media|metrika|news|ontodb(?:api)?|partner|rca|tracker|turbo|verti(?:cal)?s|webmaster|video(?:parser)?))\/([\w\.]+)/i,
6349
+ // Yeti (Naver)
6350
+ /(yeti)\/([\w\.]+)/i,
6351
+ // aiHitBot / Algolia Crawler / BLEXBot / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot
6352
+ // Cotoyogi - https://ds.rois.ac.jp/en_center8/en_crawler/
6353
+ // Freespoke - https://docs.freespoke.com/search/bot/
6354
+ /((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cotoyogi|firecrawlagent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|twinagent|webzio-extended)\/?([\w\.]*)/i
6355
+ ],
6356
+ [NAME2, VERSION4, [TYPE2, CRAWLER]],
6357
+ [
6358
+ // YandexBot MirrorDetector
6359
+ /(yandexbot\/([\w\.]+); mirrordetector)/i
6360
+ ],
6361
+ [[NAME2, /\/.+;/ig, ""], VERSION4, [TYPE2, CRAWLER]],
6362
+ [
6363
+ // Google Bots
6364
+ /((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
6365
+ // AI2Bot - https://allenai.org/crawler
6366
+ // DataForSeoBot - https://dataforseo.com/dataforseo-bot
6367
+ // Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot
6368
+ // ImagesiftBot - https://imagesift.com/about
6369
+ // Siteimprove - https://help.siteimprove.com/support/solutions/articles/80000448553
6370
+ // TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html
6371
+ // v0bot - https://vercel.com/docs/bot-management
6372
+ // Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
6373
+ // Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider
6374
+ /\b((ai2|aspiegel|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i
6375
+ ],
6376
+ [NAME2, [TYPE2, CRAWLER]]
6377
+ ]
6378
+ });
6379
+ var ExtraDevices = Object.freeze({
6380
+ device: [
6381
+ [
6382
+ /(nook)[\w ]+build\/(\w+)/i,
6383
+ // Nook
6384
+ /(dell) (strea[kpr\d ]*[\dko])/i,
6385
+ // Dell Streak
6386
+ /(le[- ]+pan)[- ]+(\w{1,9}) bui/i,
6387
+ // Le Pan Tablets
6388
+ /(trinity)[- ]*(t\d{3}) bui/i,
6389
+ // Trinity Tablets
6390
+ /(gigaset)[- ]+(q\w{1,9}) bui/i,
6391
+ // Gigaset Tablets
6392
+ /(vodafone) ([\w ]+)(?:\)| bui)/i
6393
+ // Vodafone
6394
+ ],
6395
+ [VENDOR2, MODEL2, [TYPE2, TABLET2]],
6396
+ [
6397
+ /(u304aa)/i
6398
+ // AT&T
6399
+ ],
6400
+ [MODEL2, [VENDOR2, "AT&T"], [TYPE2, MOBILE2]],
6401
+ [
6402
+ /\bsie-(\w*)/i
6403
+ // Siemens
6404
+ ],
6405
+ [MODEL2, [VENDOR2, "Siemens"], [TYPE2, MOBILE2]],
6406
+ [
6407
+ /\b(rct\w+) b/i
6408
+ // RCA Tablets
6409
+ ],
6410
+ [MODEL2, [VENDOR2, "RCA"], [TYPE2, TABLET2]],
6411
+ [
6412
+ /\b(venue[\d ]{2,7}) b/i
6413
+ // Dell Venue Tablets
6414
+ ],
6415
+ [MODEL2, [VENDOR2, "Dell"], [TYPE2, TABLET2]],
6416
+ [
6417
+ /\b(q(?:mv|ta)\w+) b/i
6418
+ // Verizon Tablet
6419
+ ],
6420
+ [MODEL2, [VENDOR2, "Verizon"], [TYPE2, TABLET2]],
6421
+ [
6422
+ /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i
6423
+ // Barnes & Noble Tablet
6424
+ ],
6425
+ [MODEL2, [VENDOR2, "Barnes & Noble"], [TYPE2, TABLET2]],
6426
+ [
6427
+ /\b(tm\d{3}\w+) b/i
6428
+ ],
6429
+ [MODEL2, [VENDOR2, "NuVision"], [TYPE2, TABLET2]],
6430
+ [
6431
+ /\b(k88) b/i
6432
+ // ZTE K Series Tablet
6433
+ ],
6434
+ [MODEL2, [VENDOR2, "ZTE"], [TYPE2, TABLET2]],
6435
+ [
6436
+ /\b(nx\d{3}j) b/i
6437
+ // ZTE Nubia
6438
+ ],
6439
+ [MODEL2, [VENDOR2, "ZTE"], [TYPE2, MOBILE2]],
6440
+ [
6441
+ /\b(gen\d{3}) b.+49h/i
6442
+ // Swiss GEN Mobile
6443
+ ],
6444
+ [MODEL2, [VENDOR2, "Swiss"], [TYPE2, MOBILE2]],
6445
+ [
6446
+ /\b(zur\d{3}) b/i
6447
+ // Swiss ZUR Tablet
6448
+ ],
6449
+ [MODEL2, [VENDOR2, "Swiss"], [TYPE2, TABLET2]],
6450
+ [
6451
+ /^((zeki)?tb.*\b) b/i
6452
+ // Zeki Tablets
6453
+ ],
6454
+ [MODEL2, [VENDOR2, "Zeki"], [TYPE2, TABLET2]],
6455
+ [
6456
+ /\b([yr]\d{2}) b/i,
6457
+ /\b(?:dragon[- ]+touch |dt)(\w{5}) b/i
6458
+ // Dragon Touch Tablet
6459
+ ],
6460
+ [MODEL2, [VENDOR2, "Dragon Touch"], [TYPE2, TABLET2]],
6461
+ [
6462
+ /\b(ns-?\w{0,9}) b/i
6463
+ // Insignia Tablets
6464
+ ],
6465
+ [MODEL2, [VENDOR2, "Insignia"], [TYPE2, TABLET2]],
6466
+ [
6467
+ /\b((nxa|next)-?\w{0,9}) b/i
6468
+ // NextBook Tablets
6469
+ ],
6470
+ [MODEL2, [VENDOR2, "NextBook"], [TYPE2, TABLET2]],
6471
+ [
6472
+ /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i
6473
+ // Voice Xtreme Phones
6474
+ ],
6475
+ [[VENDOR2, "Voice"], MODEL2, [TYPE2, MOBILE2]],
6476
+ [
6477
+ /\b(lvtel\-)?(v1[12]) b/i
6478
+ // LvTel Phones
6479
+ ],
6480
+ [[VENDOR2, "LvTel"], MODEL2, [TYPE2, MOBILE2]],
6481
+ [
6482
+ /\b(ph-1) /i
6483
+ // Essential PH-1
6484
+ ],
6485
+ [MODEL2, [VENDOR2, "Essential"], [TYPE2, MOBILE2]],
6486
+ [
6487
+ /\b(v(100md|700na|7011|917g).*\b) b/i
6488
+ // Envizen Tablets
6489
+ ],
6490
+ [MODEL2, [VENDOR2, "Envizen"], [TYPE2, TABLET2]],
6491
+ [
6492
+ /\b(trio[-\w\. ]+) b/i
6493
+ // MachSpeed Tablets
6494
+ ],
6495
+ [MODEL2, [VENDOR2, "MachSpeed"], [TYPE2, TABLET2]],
6496
+ [
6497
+ /\btu_(1491) b/i
6498
+ // Rotor Tablets
6499
+ ],
6500
+ [MODEL2, [VENDOR2, "Rotor"], [TYPE2, TABLET2]]
6501
+ ]
6502
+ });
6503
+ var Emails = Object.freeze({
6504
+ browser: [
6505
+ [
6506
+ // Evolution / Kontact/KMail[2] / [Microsoft/Mac] Outlook / Thunderbird
6507
+ // Airmail / BlueMail / DaumMail / eMClient / Foxmail / NaverMailApp / Polymail
6508
+ // ProtonMail / SparkDesktop / Sparrow / Yahoo! Mail / Zimbra / ZohoMail-Desktop
6509
+ /((?:air|blue|daum|fox|poly|proton)mail|emclient|evolution|kmail2?|kontact|(?:microsoft |mac)?outlook(?:-express)?|navermailapp|(?!chrom.+)sparrow|sparkdesktop|thunderbird|yahoo|zohomail-desktop)(?:m.+ail; |[\/ ])([\w\.]+)/i,
6510
+ // Apple's Mail
6511
+ /(mail)\/([\w\.]+) cf/i
6512
+ ],
6513
+ [NAME2, VERSION4, [TYPE2, EMAIL]],
6514
+ [
6515
+ // Zimbra
6516
+ /zdesktop\/([\w\.]+)/i
6517
+ ],
6518
+ [VERSION4, [NAME2, "Zimbra"], [TYPE2, EMAIL]]
6519
+ ]
6520
+ });
6521
+ var Fetchers = Object.freeze({
6522
+ browser: [
6523
+ [
6524
+ // Asana / Bitlybot / Better Uptime / BingPreview / Blueno / Cohere-AI / HubSpot Page Fetcher / kakaotalk-scrap / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
6525
+ // AhrefsSiteAudit - https://ahrefs.com/robot/site-audit
6526
+ // Buffer Link Preview Bot - https://scraper.buffer.com/about/bots/link-preview-bot
6527
+ // ChatGPT-User - https://platform.openai.com/docs/plugins/bot
6528
+ // DuckAssistBot - https://duckduckgo.com/duckassistbot/
6529
+ // Google Site Verifier / Meta / Yahoo! Japan
6530
+ // Iframely - https://iframely.com/docs/about
6531
+ // Perplexity-User - https://docs.perplexity.ai/guides/bots
6532
+ // MistralAI-User - https://docs.mistral.ai/robots/
6533
+ // Yandex Bots - https://yandex.com/bots
6534
+ /(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|cohere-ai|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
6535
+ // Bluesky
6536
+ /(bluesky) cardyb\/([\w\.]+)/i,
6537
+ // Skype
6538
+ /(skypeuripreview) preview\/([\w\.]+)/i,
6539
+ // Slackbot - https://api.slack.com/robots
6540
+ /(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i,
6541
+ // WhatsApp
6542
+ /(whatsapp)\/([\w\.]+)/i
6543
+ ],
6544
+ [NAME2, VERSION4, [TYPE2, FETCHER]],
6545
+ [
6546
+ // Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / KeybaseBot / Snapchat / Vercelbot / Yandex Bots
6547
+ /((?:better uptime |keybase|telegram|vercel)bot|chrome-lighthouse|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i
6548
+ ],
6549
+ [NAME2, [TYPE2, FETCHER]]
6550
+ ],
6551
+ os: [
6552
+ [/whatsapp\/[\d\.]+ (a|i)/i],
6553
+ [[NAME2, (os) => os == "A" ? "Android" : "iOS"]]
6554
+ ]
6555
+ });
6556
+ var InApps = Object.freeze({
6557
+ browser: [
6558
+ [
6559
+ // Discord/Figma/Flipboard/Mattermost/Notion/Postman/Rambox/Rocket.Chat/Slack/Teams
6560
+ /\b(discord|figma|mattermost|notion|postman|rambox|rocket.chat|slack|teams)\/([\w\.]+).+(electron\/|; ios)/i,
6561
+ /(flipboard)\/([\w\.]+)/i
6562
+ ],
6563
+ [NAME2, VERSION4, [TYPE2, INAPP2]],
6564
+ [
6565
+ // Evernote/Teams on mobile
6566
+ /(evernote) win/i,
6567
+ /(teams)mobile-(ios|and)/i
6568
+ ],
6569
+ [NAME2, [TYPE2, INAPP2]],
6570
+ [
6571
+ // Slack
6572
+ /chatlyio\/([\d\.]+)/i
6573
+ ],
6574
+ [VERSION4, [NAME2, "Slack"], [TYPE2, INAPP2]],
6575
+ [
6576
+ // TikTok Lite
6577
+ /ultralite app_version\/([\w\.]+)/i
6578
+ ],
6579
+ [VERSION4, [NAME2, "TikTok Lite"], [TYPE2, INAPP2]],
6580
+ [
6581
+ // VS Code
6582
+ /\) code\/([\d\.]+).+electron\//i
6583
+ ],
6584
+ [VERSION4, [NAME2, "VS Code"], [TYPE2, INAPP2]],
6585
+ [
6586
+ // Yahoo! Japan
6587
+ /jp\.co\.yahoo\.(?:android\.yjtop|ipn\.appli)\/([\d\.]+)/i
6588
+ ],
6589
+ [VERSION4, [NAME2, "Yahoo! Japan"], [TYPE2, INAPP2]]
6590
+ ]
6591
+ });
6592
+ var MediaPlayers = Object.freeze({
6593
+ browser: [
6594
+ [
6595
+ /(apple(?:coremedia|tv))\/([\w\._]+)/i,
6596
+ // Generic Apple CoreMedia
6597
+ /(coremedia) v([\w\._]+)/i,
6598
+ // Ares/Nexplayer/OSSProxy
6599
+ /(ares|clementine|music player daemon|nexplayer|ossproxy) ([\w\.-]+)/i,
6600
+ // Aqualung/Lyssna/BSPlayer/Clementine/MPD
6601
+ // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/GnomeMplayer/MoC
6602
+ // NSPlayer/PSP-InternetRadioPlayer/Videos
6603
+ // Nero Home/Nero Scout/Nokia
6604
+ // QuickTime/RealMedia/RadioApp/RadioClientApplication/
6605
+ // SoundTap/Totem/Stagefright/Streamium
6606
+ // XBMC/gvfs/Xine/XMMS/irapp
6607
+ /^(aqualung|audacious|audimusicstream|amarok|bass|bsplayer|core|gnomemplayer|gvfs|irapp|lyssna|music on console|nero (?:home|scout)|nokia\d+|nsplayer|psp-internetradioplayer|quicktime|rma|radioapp|radioclientapplication|soundtap|stagefright|streamium|totem|videos|xbmc|xine|xmms)\/([\w\.-]+)/i,
6608
+ /(lg player|nexplayer) ([\d\.]+)/i,
6609
+ /player\/(nexplayer|lg player) ([\w\.-]+)/i,
6610
+ // NexPlayer/LG Player
6611
+ /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i,
6612
+ // Gstreamer
6613
+ /(htc streaming player) [\w_]+ \/ ([\d\.]+)/i,
6614
+ // HTC Streaming Player
6615
+ /(lavf)([\d\.]+)/i,
6616
+ // Lavf (FFMPEG)
6617
+ // MPlayer SVN
6618
+ /(mplayer)(?: |\/)(?:(?:sherpya-){0,1}svn)(?:-| )(r\d+(?:-\d+[\w\.-]+))/i,
6619
+ / (songbird)\/([\w\.-]+)/i,
6620
+ // Songbird/Philips-Songbird
6621
+ /(winamp)(?:3 version|mpeg| ) ([\w\.-]+)/i,
6622
+ // Winamp
6623
+ /(vlc)(?:\/| media player - version )([\w\.-]+)/i,
6624
+ // VLC Videolan
6625
+ /^(foobar2000|itunes|smp)\/([\d\.]+)/i,
6626
+ // Foobar2000/iTunes/SMP
6627
+ /com\.(riseupradioalarm)\/([\d\.]*)/i,
6628
+ // RiseUP Radio Alarm
6629
+ /(mplayer)(?:\s|\/| unknown-)([\w\.\-]+)/i,
6630
+ // MPlayer
6631
+ // Windows Media Server
6632
+ /(windows)\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ home media server/i
6633
+ ],
6634
+ [NAME2, VERSION4, [TYPE2, MEDIAPLAYER]],
6635
+ [
6636
+ /(flrp)\/([\w\.-]+)/i
6637
+ // Flip Player
6638
+ ],
6639
+ [[NAME2, "Flip Player"], VERSION4, [TYPE2, MEDIAPLAYER]],
6640
+ [
6641
+ // FStream/NativeHost/QuerySeekSpider
6642
+ // MPlayer (no other info)/Media Player Classic/Nero ShowTime
6643
+ // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info)
6644
+ // inlight radio / YourMuze
6645
+ /(fstream|media player classic|inlight radio|mplayer|nativehost|nero showtime|ocms-bot|queryseekspider|tapinradio|tunein radio|winamp|yourmuze)/i
6646
+ ],
6647
+ [NAME2, [TYPE2, MEDIAPLAYER]],
6648
+ [
6649
+ /(htc_one_s|windows-media-player|wmplayer)\/([\w\.-]+)/i
6650
+ // HTC One S / Windows Media Player
6651
+ ],
6652
+ [[NAME2, /[_-]/g, " "], VERSION4, [TYPE2, MEDIAPLAYER]],
6653
+ [
6654
+ /(rad.io|radio.(?:de|at|fr)) ([\d\.]+)/i
6655
+ // Rad.io
6656
+ ],
6657
+ [[NAME2, "rad.io"], VERSION4, [TYPE2, MEDIAPLAYER]]
6658
+ ]
6659
+ });
6660
+ var Libraries = Object.freeze({
6661
+ browser: [
6662
+ // Apache-HttpClient/Axios/go-http-client/got/GuzzleHttp/Java[-HttpClient]/jsdom/libwww-perl/lua-resty-http/Needle/node-fetch/OkHttp/PHP-SOAP/PostmanRuntime/python-urllib/python-requests/Scrapy/superagent
6663
+ [
6664
+ /^(apache-httpclient|axios|(?:go|java)-http-client|got|guzzlehttp|java|libwww-perl|lua-resty-http|needle|node-(?:fetch|superagent)|okhttp|php-soap|postmanruntime|python-(?:httpx|urllib[23]?|requests)|scrapy)\/([\w\.]+)/i,
6665
+ /(adobeair|aiohttp|jsdom)\/([\w\.]+)/i,
6666
+ /(nutch)-([\w\.-]+)(\(|$)/i,
6667
+ /\((java)\/([\w\.]+)/i
6668
+ ],
6669
+ [NAME2, VERSION4, [TYPE2, LIBRARY]]
6670
+ ]
6671
+ });
6672
+ var Vehicles = Object.freeze({
6673
+ device: [
6674
+ [/aftlbt962e2/i],
6675
+ // BMW
6676
+ [[VENDOR2, "BMW"]],
6677
+ [/dilink.+(byd) auto/i],
6678
+ // BYD
6679
+ [VENDOR2],
6680
+ [/aftlft962x3/i],
6681
+ // Jeep
6682
+ [[VENDOR2, "Jeep"], [MODEL2, "Wagooner"]],
6683
+ [/(rivian) (r1t)/i],
6684
+ // Rivian
6685
+ [VENDOR2, MODEL2],
6686
+ [/vcc.+netfront/i],
6687
+ // Volvo
6688
+ [[VENDOR2, "Volvo"]]
6689
+ ]
6690
+ });
6691
+ var Bots = Object.freeze({
6692
+ browser: [
6693
+ ...CLIs.browser,
6694
+ ...Fetchers.browser,
6695
+ ...Crawlers.browser,
6696
+ ...Libraries.browser
6697
+ ],
6698
+ os: [
6699
+ ...Fetchers.os
6700
+ ]
6701
+ });
6702
+
6703
+ // ../../node_modules/.pnpm/detect-europe-js@0.1.2/node_modules/detect-europe-js/dist/esm/index.js
6704
+ var TIMEZONE = {
6705
+ ANDORRA: {
6706
+ ANDORRA: "Europe/Andorra"
6707
+ },
6708
+ AUSTRIA: {
6709
+ VIENNA: "Europe/Vienna"
6710
+ },
6711
+ BELGIUM: {
6712
+ BRUSSELS: "Europe/Brussels"
6713
+ },
6714
+ BULGARIA: {
6715
+ SOFIA: "Europe/Sofia"
6716
+ },
6717
+ CROATIA: {
6718
+ ZAGREB: "Europe/Zagreb"
6719
+ },
6720
+ CYPRUS: {
6721
+ NICOSIA_EUROPE: "Europe/Nicosia",
6722
+ NICOSIA_ASIA: "Asia/Nicosia",
6723
+ FAMAGUSTA: "Asia/Famagusta"
6724
+ },
6725
+ CZECHIA: {
6726
+ PRAGUE: "Europe/Prague"
6727
+ },
6728
+ DENMARK: {
6729
+ COPENHAGEN: "Europe/Copenhagen",
6730
+ FAROE: "Atlantic/Faroe"
6731
+ },
6732
+ ESTONIA: {
6733
+ TALLINN: "Europe/Tallinn"
6734
+ },
6735
+ FINLAND: {
6736
+ HELSINKI: "Europe/Helsinki",
6737
+ MARIEHAMN: "Europe/Mariehamn"
6738
+ },
6739
+ FRANCE: {
6740
+ PARIS: "Europe/Paris",
6741
+ CAYENNE: "America/Cayenne",
6742
+ GUADELOUPE: "America/Guadeloupe",
6743
+ MARIGOT: "America/Marigot",
6744
+ MARTINIQUE: "America/Martinique",
6745
+ MAYOTTE: "Indian/Mayotte",
6746
+ REUNION: "Indian/Reunion"
6747
+ },
6748
+ GERMANY: {
6749
+ BERLIN: "Europe/Berlin",
6750
+ BUSINGEN: "Europe/Busingen"
6751
+ },
6752
+ GREECE: {
6753
+ ATHENS: "Europe/Athens"
6754
+ },
6755
+ HUNGARY: {
6756
+ BUDAPEST: "Europe/Budapest"
6757
+ },
6758
+ ICELAND: {
6759
+ REYKJAVIK: "Atlantic/Reykjavik"
6760
+ },
6761
+ IRELAND: {
6762
+ DUBLIN: "Europe/Dublin"
6763
+ },
6764
+ ITALY: {
6765
+ ROME: "Europe/Rome"
6766
+ },
6767
+ LATVIA: {
6768
+ RIGA: "Europe/Riga"
6769
+ },
6770
+ LIECHTENSTEIN: {
6771
+ VADUZ: "Europe/Vaduz"
6772
+ },
6773
+ LITHUANIA: {
6774
+ VILNIUS: "Europe/Vilnius"
6775
+ },
6776
+ LUXEMBOURG: {
6777
+ LUXEMBOURG: "Europe/Luxembourg"
6778
+ },
6779
+ MALTA: {
6780
+ MALTA: "Europe/Malta"
6781
+ },
6782
+ MONACO: {
6783
+ MONACO: "Europe/Monaco"
6784
+ },
6785
+ NETHERLANDS: {
6786
+ AMSTERDAM: "Europe/Amsterdam",
6787
+ ARUBA: "America/Aruba",
6788
+ CURACAO: "America/Curacao",
6789
+ KRALENDIJK: "America/Kralendijk",
6790
+ LOWER_PRINCES: "America/Lower_Princes"
6791
+ },
6792
+ NORWAY: {
6793
+ OSLO: "Europe/Oslo",
6794
+ JAN_MAYEN: "Atlantic/Jan_Mayen",
6795
+ LONGYEARBYEN: "Arctic/Longyearbyen"
6796
+ },
6797
+ POLAND: {
6798
+ WARSAW: "Europe/Warsaw"
6799
+ },
6800
+ PORTUGAL: {
6801
+ LISBON: "Europe/Lisbon",
6802
+ AZORES: "Atlantic/Azores",
6803
+ MADEIRA: "Atlantic/Madeira"
6804
+ },
6805
+ ROMANIA: {
6806
+ BUCHAREST: "Europe/Bucharest"
6807
+ },
6808
+ SAN_MARINO: {
6809
+ SAN_MARINO: "Europe/San_Marino"
6810
+ },
6811
+ SLOVAKIA: {
6812
+ BRATISLAVA: "Europe/Bratislava"
6813
+ },
6814
+ SLOVENIA: {
6815
+ LJUBLJANA: "Europe/Ljubljana"
6816
+ },
6817
+ SPAIN: {
6818
+ MADRID: "Europe/Madrid",
6819
+ CANARY: "Atlantic/Canary",
6820
+ CEUTA: "Africa/Ceuta"
6821
+ },
6822
+ SWEDEN: {
6823
+ STOCKHOLM: "Europe/Stockholm"
6824
+ },
6825
+ SWITZERLAND: {
6826
+ ZURICH: "Europe/Zurich"
6827
+ },
6828
+ VATICAN: {
6829
+ VATICAN: "Europe/Vatican"
6830
+ }
6831
+ };
6832
+ var EU_TIMEZONE = [
6833
+ TIMEZONE.AUSTRIA.VIENNA,
6834
+ TIMEZONE.BELGIUM.BRUSSELS,
6835
+ TIMEZONE.BULGARIA.SOFIA,
6836
+ TIMEZONE.CROATIA.ZAGREB,
6837
+ TIMEZONE.CYPRUS.NICOSIA_EUROPE,
6838
+ TIMEZONE.CYPRUS.NICOSIA_ASIA,
6839
+ TIMEZONE.CYPRUS.FAMAGUSTA,
6840
+ TIMEZONE.CZECHIA.PRAGUE,
6841
+ TIMEZONE.DENMARK.COPENHAGEN,
6842
+ TIMEZONE.ESTONIA.TALLINN,
6843
+ TIMEZONE.FINLAND.HELSINKI,
6844
+ TIMEZONE.FINLAND.MARIEHAMN,
6845
+ TIMEZONE.FRANCE.PARIS,
6846
+ TIMEZONE.GERMANY.BERLIN,
6847
+ TIMEZONE.GREECE.ATHENS,
6848
+ TIMEZONE.HUNGARY.BUDAPEST,
6849
+ TIMEZONE.IRELAND.DUBLIN,
6850
+ TIMEZONE.ITALY.ROME,
6851
+ TIMEZONE.LATVIA.RIGA,
6852
+ TIMEZONE.LITHUANIA.VILNIUS,
6853
+ TIMEZONE.LUXEMBOURG.LUXEMBOURG,
6854
+ TIMEZONE.MALTA.MALTA,
6855
+ TIMEZONE.NETHERLANDS.AMSTERDAM,
6856
+ TIMEZONE.POLAND.WARSAW,
6857
+ TIMEZONE.PORTUGAL.LISBON,
6858
+ TIMEZONE.ROMANIA.BUCHAREST,
6859
+ TIMEZONE.SLOVAKIA.BRATISLAVA,
6860
+ TIMEZONE.SLOVENIA.LJUBLJANA,
6861
+ TIMEZONE.SPAIN.MADRID,
6862
+ TIMEZONE.SWEDEN.STOCKHOLM,
6863
+ TIMEZONE.FRANCE.CAYENNE,
6864
+ TIMEZONE.FRANCE.GUADELOUPE,
6865
+ TIMEZONE.FRANCE.MARIGOT,
6866
+ TIMEZONE.FRANCE.MARTINIQUE,
6867
+ TIMEZONE.FRANCE.MAYOTTE,
6868
+ TIMEZONE.FRANCE.REUNION,
6869
+ TIMEZONE.PORTUGAL.AZORES,
6870
+ TIMEZONE.PORTUGAL.MADEIRA,
6871
+ TIMEZONE.SPAIN.CANARY
6872
+ ];
6873
+ var EEA_EFTA_TIMEZONE = [
6874
+ TIMEZONE.ICELAND.REYKJAVIK,
6875
+ TIMEZONE.LIECHTENSTEIN.VADUZ,
6876
+ TIMEZONE.NORWAY.OSLO,
6877
+ TIMEZONE.NORWAY.JAN_MAYEN
6878
+ ];
6879
+ var EEA_TIMEZONE = [
6880
+ ...EU_TIMEZONE,
6881
+ ...EEA_EFTA_TIMEZONE
6882
+ ];
6883
+ var EFTA_TIMEZONE = [
6884
+ TIMEZONE.SWITZERLAND.ZURICH,
6885
+ ...EEA_EFTA_TIMEZONE
6886
+ ];
6887
+ var SCHENGEN_TIMEZONE = [
6888
+ TIMEZONE.AUSTRIA.VIENNA,
6889
+ TIMEZONE.BELGIUM.BRUSSELS,
6890
+ TIMEZONE.BULGARIA.SOFIA,
6891
+ TIMEZONE.CROATIA.ZAGREB,
6892
+ TIMEZONE.CZECHIA.PRAGUE,
6893
+ TIMEZONE.DENMARK.COPENHAGEN,
6894
+ TIMEZONE.ESTONIA.TALLINN,
6895
+ TIMEZONE.FINLAND.HELSINKI,
6896
+ TIMEZONE.FINLAND.MARIEHAMN,
6897
+ TIMEZONE.FRANCE.PARIS,
6898
+ TIMEZONE.GERMANY.BERLIN,
6899
+ TIMEZONE.GREECE.ATHENS,
6900
+ TIMEZONE.HUNGARY.BUDAPEST,
6901
+ TIMEZONE.ITALY.ROME,
6902
+ TIMEZONE.LATVIA.RIGA,
6903
+ TIMEZONE.LITHUANIA.VILNIUS,
6904
+ TIMEZONE.LUXEMBOURG.LUXEMBOURG,
6905
+ TIMEZONE.MALTA.MALTA,
6906
+ TIMEZONE.NETHERLANDS.AMSTERDAM,
6907
+ TIMEZONE.POLAND.WARSAW,
6908
+ TIMEZONE.PORTUGAL.LISBON,
6909
+ TIMEZONE.PORTUGAL.AZORES,
6910
+ TIMEZONE.PORTUGAL.MADEIRA,
6911
+ TIMEZONE.ROMANIA.BUCHAREST,
6912
+ TIMEZONE.SLOVAKIA.BRATISLAVA,
6913
+ TIMEZONE.SLOVENIA.LJUBLJANA,
6914
+ TIMEZONE.SPAIN.MADRID,
6915
+ TIMEZONE.SPAIN.CANARY,
6916
+ TIMEZONE.SWEDEN.STOCKHOLM,
6917
+ TIMEZONE.ANDORRA.ANDORRA,
6918
+ TIMEZONE.GERMANY.BUSINGEN,
6919
+ TIMEZONE.ICELAND.REYKJAVIK,
6920
+ TIMEZONE.LIECHTENSTEIN.VADUZ,
6921
+ TIMEZONE.MONACO.MONACO,
6922
+ TIMEZONE.NORWAY.OSLO,
6923
+ TIMEZONE.SAN_MARINO.SAN_MARINO,
6924
+ TIMEZONE.SPAIN.CEUTA,
6925
+ TIMEZONE.SWITZERLAND.ZURICH,
6926
+ TIMEZONE.VATICAN.VATICAN
6927
+ ];
6928
+
6929
+ // ../../node_modules/.pnpm/is-standalone-pwa@0.1.1/node_modules/is-standalone-pwa/dist/esm/index.js
6930
+ function isStandalonePWA() {
6931
+ var _a;
6932
+ return typeof window !== "undefined" && ((window === null || window === void 0 ? void 0 : window.matchMedia("(display-mode: standalone)").matches) || ((_a = window.navigator) === null || _a === void 0 ? void 0 : _a.standalone) || document.referrer.startsWith("android-app://") || (window === null || window === void 0 ? void 0 : window.Windows) || /trident.+(msapphost|webview)\//i.test(navigator.userAgent) || document.referrer.startsWith("app-info://platform/microsoft-store"));
6933
+ }
6934
+
6935
+ // ../../node_modules/.pnpm/@ua-parser-js+pro-enterprise@2.0.6/node_modules/@ua-parser-js/pro-enterprise/src/helpers/ua-parser-helpers.mjs
6936
+ var { Crawler } = Extension.BrowserName;
6937
+ var toResult = (value, head, ext) => typeof value === "string" ? UAParser(value, head, ext) : value;
6938
+ var isAppleSilicon = (resultOrUA) => {
6939
+ const res = toResult(resultOrUA);
6940
+ if (res.os.is(OSName.MACOS)) {
6941
+ if (res.cpu.is(CPUArch.ARM)) {
6942
+ return true;
6943
+ }
6944
+ if (typeof resultOrUA !== "string" && typeof window !== "undefined") {
6945
+ try {
6946
+ const canvas = document.createElement("canvas");
6947
+ const webgl = canvas.getContext("webgl2") || canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
6948
+ const debug = webgl.getExtension("WEBGL_debug_renderer_info");
6949
+ const renderer = webgl.getParameter(debug.UNMASKED_RENDERER_WEBGL);
6950
+ if (renderer.match(/apple m\d/i)) {
6951
+ return true;
6952
+ }
6953
+ } catch (e) {
6954
+ return false;
6955
+ }
6956
+ }
6957
+ }
6958
+ return false;
6959
+ };
6960
+ var isBot = (resultOrUA) => [
6961
+ BrowserType.CLI,
6962
+ BrowserType.CRAWLER,
6963
+ BrowserType.FETCHER,
6964
+ BrowserType.LIBRARY
6965
+ ].includes(toResult(resultOrUA, Bots).browser.type);
6966
+ var isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(EngineName.BLINK);
6967
+
6968
+ // src/v2/core/utils/deviceInfo.ts
3705
6969
  function getScreenResolution() {
3706
6970
  return {
3707
6971
  width: window.screen.width,
@@ -3728,21 +6992,71 @@ var TagadaTrackerBundle = (() => {
3728
6992
  if (typeof window === "undefined") {
3729
6993
  return {
3730
6994
  userAgent: {
3731
- browser: { name: "unknown", version: "unknown" },
3732
- os: { name: "unknown", version: "unknown" }
6995
+ name: "",
6996
+ browser: { major: "", name: "", version: "" },
6997
+ os: { name: "", version: "" },
6998
+ device: void 0,
6999
+ engine: { name: "", version: "" },
7000
+ cpu: { architecture: "" }
3733
7001
  },
3734
7002
  screenResolution: { width: 0, height: 0 },
3735
- timeZone: "UTC"
7003
+ timeZone: "UTC",
7004
+ flags: {
7005
+ isBot: false,
7006
+ isChromeFamily: false,
7007
+ isStandalonePWA: false,
7008
+ isAppleSilicon: false
7009
+ }
7010
+ };
7011
+ }
7012
+ const parser = new UAParser();
7013
+ const result = parser.getResult();
7014
+ let flags;
7015
+ try {
7016
+ flags = {
7017
+ isBot: isBot(result),
7018
+ isChromeFamily: isChromeFamily(result),
7019
+ isStandalonePWA: isStandalonePWA(),
7020
+ isAppleSilicon: isAppleSilicon(result)
7021
+ };
7022
+ } catch (error) {
7023
+ console.error("Failed to compute device flags:", error);
7024
+ flags = {
7025
+ isBot: false,
7026
+ isChromeFamily: false,
7027
+ isStandalonePWA: false,
7028
+ isAppleSilicon: false
3736
7029
  };
3737
7030
  }
3738
7031
  return {
3739
7032
  userAgent: {
3740
- browser: getBrowserInfo(),
3741
- os: getOSInfo(),
3742
- device: getDeviceInfo()
7033
+ name: result.ua,
7034
+ browser: {
7035
+ major: result.browser.major || "",
7036
+ name: result.browser.name || "",
7037
+ version: result.browser.version || "",
7038
+ type: result.browser.type
7039
+ },
7040
+ os: {
7041
+ name: result.os.name || "",
7042
+ version: result.os.version || ""
7043
+ },
7044
+ device: result.device.model || result.device.type || result.device.vendor ? {
7045
+ model: result.device.model,
7046
+ type: result.device.type,
7047
+ vendor: result.device.vendor
7048
+ } : void 0,
7049
+ engine: {
7050
+ name: result.engine.name || "",
7051
+ version: result.engine.version || ""
7052
+ },
7053
+ cpu: {
7054
+ architecture: result.cpu.architecture || ""
7055
+ }
3743
7056
  },
3744
7057
  screenResolution: getScreenResolution(),
3745
- timeZone: getTimeZone()
7058
+ timeZone: getTimeZone(),
7059
+ flags
3746
7060
  };
3747
7061
  }
3748
7062
  function getUrlParams() {
@@ -4104,6 +7418,94 @@ var TagadaTrackerBundle = (() => {
4104
7418
  }
4105
7419
  }
4106
7420
 
7421
+ // src/v2/core/utils/authHandoff.ts
7422
+ var resolutionCache = /* @__PURE__ */ new Map();
7423
+ var resolvedCodes = /* @__PURE__ */ new Set();
7424
+ function getAuthCode() {
7425
+ if (typeof window === "undefined") return null;
7426
+ const urlParams = new URLSearchParams(window.location.search);
7427
+ return urlParams.get("authCode");
7428
+ }
7429
+ async function resolveAuthHandoff(authCode, storeId, apiBaseUrl, debugMode = false) {
7430
+ if (resolvedCodes.has(authCode)) {
7431
+ if (debugMode) {
7432
+ console.log("[AuthHandoff] Code already resolved, skipping duplicate request");
7433
+ }
7434
+ throw new Error("Auth code already resolved");
7435
+ }
7436
+ const inFlightResolution = resolutionCache.get(authCode);
7437
+ if (inFlightResolution) {
7438
+ if (debugMode) {
7439
+ console.log("[AuthHandoff] Resolution already in progress, waiting for existing request");
7440
+ }
7441
+ return inFlightResolution;
7442
+ }
7443
+ if (debugMode) {
7444
+ console.log("[AuthHandoff] Resolving authCode:", authCode.substring(0, 15) + "...");
7445
+ }
7446
+ const resolutionPromise = (async () => {
7447
+ try {
7448
+ const response = await fetch("".concat(apiBaseUrl, "/api/v1/cms/auth/resolve-handoff"), {
7449
+ method: "POST",
7450
+ headers: {
7451
+ "Content-Type": "application/json"
7452
+ },
7453
+ body: JSON.stringify({
7454
+ code: authCode,
7455
+ storeId
7456
+ })
7457
+ });
7458
+ if (!response.ok) {
7459
+ const errorData = await response.json().catch(() => ({ message: "Unknown error" }));
7460
+ throw new Error(errorData.message || "Failed to resolve auth handoff: ".concat(response.status));
7461
+ }
7462
+ const data = await response.json();
7463
+ if (debugMode) {
7464
+ console.log("[AuthHandoff] \u2705 Resolved successfully:", {
7465
+ customerId: data.customer.id,
7466
+ role: data.customer.role,
7467
+ hasContext: Object.keys(data.context).length > 0
7468
+ });
7469
+ }
7470
+ if (debugMode) {
7471
+ console.log("[AuthHandoff] Storing new token (overriding existing)");
7472
+ }
7473
+ setClientToken(data.token);
7474
+ cleanAuthCodeFromUrl(debugMode);
7475
+ resolvedCodes.add(authCode);
7476
+ return data;
7477
+ } catch (error) {
7478
+ console.error("[AuthHandoff] \u274C Failed to resolve:", error);
7479
+ throw error;
7480
+ } finally {
7481
+ resolutionCache.delete(authCode);
7482
+ }
7483
+ })();
7484
+ resolutionCache.set(authCode, resolutionPromise);
7485
+ return resolutionPromise;
7486
+ }
7487
+ function cleanAuthCodeFromUrl(debugMode = false) {
7488
+ if (typeof window === "undefined") return;
7489
+ const url = new URL(window.location.href);
7490
+ if (url.searchParams.has("authCode")) {
7491
+ url.searchParams.delete("authCode");
7492
+ window.history.replaceState({}, "", url.pathname + url.search + url.hash);
7493
+ if (debugMode) {
7494
+ console.log("[AuthHandoff] Cleaned authCode from URL");
7495
+ }
7496
+ }
7497
+ }
7498
+ function shouldResolveAuthCode() {
7499
+ const authCode = getAuthCode();
7500
+ if (!authCode || !authCode.startsWith("ah_")) {
7501
+ return false;
7502
+ }
7503
+ if (resolvedCodes.has(authCode)) {
7504
+ return false;
7505
+ }
7506
+ return true;
7507
+ }
7508
+
4107
7509
  // src/v2/core/client.ts
4108
7510
  var TagadaClient = class {
4109
7511
  constructor(config = {}) {
@@ -4119,13 +7521,40 @@ var TagadaTrackerBundle = (() => {
4119
7521
  this.lastSessionInitError = null;
4120
7522
  this.sessionInitRetryCount = 0;
4121
7523
  this.MAX_SESSION_INIT_RETRIES = 3;
4122
- var _a, _b;
7524
+ var _a, _b, _c, _d;
4123
7525
  this.config = config;
4124
7526
  this.instanceId = Math.random().toString(36).substr(2, 9);
4125
7527
  this.boundHandleStorageChange = this.handleStorageChange.bind(this);
4126
- if (this.config.debugMode) {
4127
- console.log("[TagadaClient ".concat(this.instanceId, "] Initializing..."));
4128
- }
7528
+ this.boundHandlePageshow = (event) => {
7529
+ if (event.persisted) {
7530
+ if (this.state.debugMode) {
7531
+ console.log("[TagadaClient ".concat(this.instanceId, "] Page restored from BFcache (back button), re-initializing funnel..."));
7532
+ }
7533
+ if (this.funnel && this.state.session && this.state.store) {
7534
+ this.funnel.resetInitialization();
7535
+ const accountId = this.getAccountId();
7536
+ const urlParams = new URLSearchParams(typeof window !== "undefined" ? window.location.search : "");
7537
+ const funnelId = urlParams.get("funnelId") || void 0;
7538
+ this.funnel.autoInitialize(
7539
+ { customerId: this.state.session.customerId, sessionId: this.state.session.sessionId },
7540
+ { id: this.state.store.id, accountId },
7541
+ funnelId
7542
+ ).catch((err) => {
7543
+ console.error("[TagadaClient] Funnel re-initialization failed:", err);
7544
+ });
7545
+ } else {
7546
+ this.sessionInitRetryCount = 0;
7547
+ this.initialize();
7548
+ }
7549
+ }
7550
+ };
7551
+ console.log("[TagadaClient ".concat(this.instanceId, "] Initializing..."));
7552
+ console.log("[TagadaClient ".concat(this.instanceId, "] Config:"), {
7553
+ debugMode: config.debugMode,
7554
+ hasRawPluginConfig: !!config.rawPluginConfig,
7555
+ rawPluginConfig: config.rawPluginConfig,
7556
+ features: config.features
7557
+ });
4129
7558
  const previewModeActive = handlePreviewMode(this.config.debugMode);
4130
7559
  if (previewModeActive && this.config.debugMode) {
4131
7560
  console.log("[TagadaClient ".concat(this.instanceId, "] Preview mode active - state cleared"));
@@ -4166,10 +7595,15 @@ var TagadaTrackerBundle = (() => {
4166
7595
  isInitialized: false,
4167
7596
  isSessionInitialized: false,
4168
7597
  pluginConfig: { basePath: "/", config: {} },
4169
- pluginConfigLoading: !config.rawPluginConfig,
7598
+ pluginConfigLoading: true,
7599
+ // Always true - loadPluginConfig will process rawPluginConfig
4170
7600
  debugMode: (_a = config.debugMode) != null ? _a : env !== "production",
4171
7601
  token: null
4172
7602
  };
7603
+ console.log("[TagadaClient ".concat(this.instanceId, "] Initial state:"), {
7604
+ pluginConfigLoading: this.state.pluginConfigLoading,
7605
+ hasRawPluginConfig: !!config.rawPluginConfig
7606
+ });
4173
7607
  this.apiClient = new ApiClient({
4174
7608
  baseURL: envConfig.apiConfig.baseUrl
4175
7609
  });
@@ -4182,12 +7616,16 @@ var TagadaTrackerBundle = (() => {
4182
7616
  debugMode: this.state.debugMode,
4183
7617
  pluginConfig: this.state.pluginConfig,
4184
7618
  environment: this.state.environment,
4185
- autoRedirect: funnelConfig.autoRedirect
7619
+ autoRedirect: funnelConfig.autoRedirect,
7620
+ // Pass funnelId and stepId from rawPluginConfig to enable config-based initialization
7621
+ funnelId: (_c = config.rawPluginConfig) == null ? void 0 : _c.funnelId,
7622
+ stepId: (_d = config.rawPluginConfig) == null ? void 0 : _d.stepId
4186
7623
  });
4187
7624
  }
4188
7625
  this.apiClient.setTokenProvider(this.waitForToken.bind(this));
4189
7626
  if (typeof window !== "undefined") {
4190
7627
  window.addEventListener("storage", this.boundHandleStorageChange);
7628
+ window.addEventListener("pageshow", this.boundHandlePageshow);
4191
7629
  }
4192
7630
  this.setupConfigHotReload();
4193
7631
  this.initialize();
@@ -4198,6 +7636,7 @@ var TagadaTrackerBundle = (() => {
4198
7636
  destroy() {
4199
7637
  if (typeof window !== "undefined") {
4200
7638
  window.removeEventListener("storage", this.boundHandleStorageChange);
7639
+ window.removeEventListener("pageshow", this.boundHandlePageshow);
4201
7640
  }
4202
7641
  if (this.state.debugMode) {
4203
7642
  console.log("[TagadaClient ".concat(this.instanceId, "] Destroyed"));
@@ -4280,10 +7719,19 @@ var TagadaTrackerBundle = (() => {
4280
7719
  * Load plugin configuration
4281
7720
  */
4282
7721
  async initializePluginConfig() {
4283
- if (!this.state.pluginConfigLoading) return;
7722
+ console.log("[TagadaClient ".concat(this.instanceId, "] initializePluginConfig called"), {
7723
+ pluginConfigLoading: this.state.pluginConfigLoading,
7724
+ hasRawPluginConfig: !!this.config.rawPluginConfig
7725
+ });
7726
+ if (!this.state.pluginConfigLoading) {
7727
+ console.log("[TagadaClient ".concat(this.instanceId, "] Plugin config already loading or loaded, skipping..."));
7728
+ return;
7729
+ }
4284
7730
  try {
4285
7731
  const configVariant = this.config.localConfig || "default";
7732
+ console.log("[TagadaClient ".concat(this.instanceId, "] Loading plugin config with variant: ").concat(configVariant));
4286
7733
  const config = await loadPluginConfig(configVariant, this.config.rawPluginConfig);
7734
+ console.log("[TagadaClient ".concat(this.instanceId, "] Plugin config loaded:"), config);
4287
7735
  this.updateState({
4288
7736
  pluginConfig: config,
4289
7737
  pluginConfigLoading: false
@@ -4294,9 +7742,6 @@ var TagadaTrackerBundle = (() => {
4294
7742
  environment: this.state.environment
4295
7743
  });
4296
7744
  }
4297
- if (this.state.debugMode) {
4298
- console.log("[TagadaClient] Plugin config loaded:", config);
4299
- }
4300
7745
  } catch (error) {
4301
7746
  console.error("[TagadaClient] Failed to load plugin config:", error);
4302
7747
  this.updateState({
@@ -4309,15 +7754,63 @@ var TagadaTrackerBundle = (() => {
4309
7754
  * Initialize token and session
4310
7755
  */
4311
7756
  async initializeToken() {
7757
+ var _a;
7758
+ if (shouldResolveAuthCode()) {
7759
+ const storeId = this.state.pluginConfig.storeId;
7760
+ if (!storeId) {
7761
+ console.error("[TagadaClient] Cannot resolve authCode: storeId not found in config");
7762
+ return this.fallbackToNormalFlow();
7763
+ }
7764
+ console.log("[TagadaClient ".concat(this.instanceId, "] \u{1F510} Cross-domain auth detected, resolving..."));
7765
+ try {
7766
+ const authCode = new URLSearchParams(window.location.search).get("authCode");
7767
+ if (!authCode) {
7768
+ return this.fallbackToNormalFlow();
7769
+ }
7770
+ const handoffData = await resolveAuthHandoff(
7771
+ authCode,
7772
+ storeId,
7773
+ this.state.environment.apiConfig.baseUrl,
7774
+ this.state.debugMode
7775
+ );
7776
+ console.log("[TagadaClient ".concat(this.instanceId, "] \u2705 Auth handoff resolved:"), {
7777
+ customerId: handoffData.customer.id,
7778
+ role: handoffData.customer.role,
7779
+ hasContext: Object.keys(handoffData.context).length > 0
7780
+ });
7781
+ this.setToken(handoffData.token);
7782
+ const decodedSession = decodeJWTClient(handoffData.token);
7783
+ if (decodedSession) {
7784
+ this.updateState({ session: decodedSession });
7785
+ await this.initializeSession(decodedSession);
7786
+ if (((_a = handoffData.context) == null ? void 0 : _a.funnelSessionId) && this.funnel) {
7787
+ if (this.state.debugMode) {
7788
+ console.log("[TagadaClient ".concat(this.instanceId, "] Restoring funnel session from handoff context:"), handoffData.context.funnelSessionId);
7789
+ }
7790
+ }
7791
+ } else {
7792
+ console.error("[TagadaClient] Failed to decode token from handoff");
7793
+ this.updateState({ isInitialized: true, isLoading: false });
7794
+ }
7795
+ return;
7796
+ } catch (error) {
7797
+ console.error("[TagadaClient ".concat(this.instanceId, "] \u274C Auth handoff failed, falling back to normal flow:"), error);
7798
+ }
7799
+ }
7800
+ await this.fallbackToNormalFlow();
7801
+ }
7802
+ /**
7803
+ * Normal token initialization flow (no cross-domain handoff)
7804
+ */
7805
+ async fallbackToNormalFlow() {
4312
7806
  const existingToken = getClientToken();
4313
7807
  const urlParams = new URLSearchParams(typeof window !== "undefined" ? window.location.search : "");
4314
7808
  const queryToken = urlParams.get("token");
4315
- if (this.state.debugMode) {
4316
- console.log("[TagadaClient ".concat(this.instanceId, "] Initializing token..."), {
4317
- hasExistingToken: !!existingToken,
4318
- hasQueryToken: !!queryToken
4319
- });
4320
- }
7809
+ console.log("[TagadaClient ".concat(this.instanceId, "] Initializing token (normal flow)..."), {
7810
+ hasExistingToken: !!existingToken,
7811
+ hasQueryToken: !!queryToken,
7812
+ storeId: this.state.pluginConfig.storeId
7813
+ });
4321
7814
  let tokenToUse = null;
4322
7815
  let shouldPersist = false;
4323
7816
  if (queryToken) {
@@ -4344,12 +7837,14 @@ var TagadaTrackerBundle = (() => {
4344
7837
  }
4345
7838
  } else {
4346
7839
  const storeId = this.state.pluginConfig.storeId;
7840
+ console.log("[TagadaClient ".concat(this.instanceId, "] No existing token, creating anonymous token..."), {
7841
+ hasStoreId: !!storeId,
7842
+ storeId
7843
+ });
4347
7844
  if (storeId) {
4348
- if (this.state.debugMode) {
4349
- console.log("[TagadaClient ".concat(this.instanceId, "] Creating anonymous token for store:"), storeId);
4350
- }
4351
7845
  await this.createAnonymousToken(storeId);
4352
7846
  } else {
7847
+ console.warn("[TagadaClient ".concat(this.instanceId, "] No storeId in plugin config, skipping anonymous token creation"));
4353
7848
  this.updateState({ isInitialized: true, isLoading: false });
4354
7849
  }
4355
7850
  }
@@ -4423,7 +7918,7 @@ var TagadaTrackerBundle = (() => {
4423
7918
  * Initialize session
4424
7919
  */
4425
7920
  async initializeSession(sessionData) {
4426
- var _a, _b;
7921
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
4427
7922
  if (this.isInitializingSession) {
4428
7923
  if (this.state.debugMode) {
4429
7924
  console.log("[TagadaClient ".concat(this.instanceId, "] Session initialization already in progress, skipping"));
@@ -4460,14 +7955,24 @@ var TagadaTrackerBundle = (() => {
4460
7955
  osVersion: deviceInfo.userAgent.os.version,
4461
7956
  deviceType: (_a = deviceInfo.userAgent.device) == null ? void 0 : _a.type,
4462
7957
  deviceModel: (_b = deviceInfo.userAgent.device) == null ? void 0 : _b.model,
7958
+ deviceVendor: (_c = deviceInfo.userAgent.device) == null ? void 0 : _c.vendor,
7959
+ userAgent: deviceInfo.userAgent.name,
7960
+ engineName: deviceInfo.userAgent.engine.name,
7961
+ engineVersion: deviceInfo.userAgent.engine.version,
7962
+ cpuArchitecture: deviceInfo.userAgent.cpu.architecture,
7963
+ isBot: (_e = (_d = deviceInfo.flags) == null ? void 0 : _d.isBot) != null ? _e : false,
7964
+ isChromeFamily: (_g = (_f = deviceInfo.flags) == null ? void 0 : _f.isChromeFamily) != null ? _g : false,
7965
+ isStandalonePWA: (_i = (_h = deviceInfo.flags) == null ? void 0 : _h.isStandalonePWA) != null ? _i : false,
7966
+ isAppleSilicon: (_k = (_j = deviceInfo.flags) == null ? void 0 : _j.isAppleSilicon) != null ? _k : false,
4463
7967
  screenWidth: deviceInfo.screenResolution.width,
4464
7968
  screenHeight: deviceInfo.screenResolution.height,
4465
7969
  timeZone: deviceInfo.timeZone,
4466
- draft
7970
+ draft,
4467
7971
  // 🎯 Pass draft mode to session init
7972
+ fetchMessages: false
4468
7973
  };
4469
7974
  const response = await this.apiClient.post(
4470
- "/api/v1/cms/session/init",
7975
+ "/api/v1/cms/session/v2/init",
4471
7976
  sessionInitData
4472
7977
  );
4473
7978
  this.lastSessionInitError = null;
@@ -4503,13 +8008,15 @@ var TagadaTrackerBundle = (() => {
4503
8008
  });
4504
8009
  this.updateState({ store: storeConfig });
4505
8010
  }
4506
- const localeConfig = {
4507
- locale: response.locale,
4508
- language: response.locale.split("-")[0],
4509
- region: (_b = response.locale.split("-")[1]) != null ? _b : "US",
4510
- messages: (_c = response.messages) != null ? _c : {}
4511
- };
4512
- this.updateState({ locale: localeConfig });
8011
+ if (response.locale) {
8012
+ const localeConfig = {
8013
+ locale: response.locale,
8014
+ language: response.locale.split("-")[0],
8015
+ region: (_b = response.locale.split("-")[1]) != null ? _b : "US",
8016
+ messages: (_c = response.messages) != null ? _c : {}
8017
+ };
8018
+ this.updateState({ locale: localeConfig });
8019
+ }
4513
8020
  if (response.store) {
4514
8021
  const currencyConfig = {
4515
8022
  code: response.store.currency,
@@ -5066,6 +8573,29 @@ var TagadaTrackerBundle = (() => {
5066
8573
  }
5067
8574
  return __toCommonJS(external_tracker_exports);
5068
8575
  })();
8576
+ /*! Bundled license information:
8577
+
8578
+ detect-europe-js/dist/esm/index.js:
8579
+ (*! detectEurope.js v0.1.2
8580
+ Determine whether a user is from the European Union (EU) area
8581
+ https://github.com/faisalman/detect-europe-js
8582
+ Author: Faisal Salman <f@faisalman.com>
8583
+ MIT License *)
8584
+
8585
+ ua-is-frozen/dist/esm/index.js:
8586
+ (*! isFrozenUA
8587
+ A freeze-test for your user-agent string
8588
+ https://github.com/faisalman/ua-is-frozen
8589
+ Author: Faisal Salman <f@faisalman.com>
8590
+ MIT License *)
8591
+
8592
+ is-standalone-pwa/dist/esm/index.js:
8593
+ (*! isStandalonePWA 0.1.1
8594
+ Detect if PWA is running in standalone mode
8595
+ https://github.com/faisalman/is-standalone-pwa
8596
+ Author: Faisal Salman <f@faisalman.com>
8597
+ MIT License *)
8598
+ */
5069
8599
  // Expose TagadaTracker globally
5070
8600
  if (typeof window !== 'undefined' && TagadaTrackerBundle && TagadaTrackerBundle.TagadaTracker) {
5071
8601
  window.TagadaTracker = TagadaTrackerBundle.TagadaTracker;