@vidinfra/analytics 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/README.md +67 -0
  2. package/dist/cjs/actions.d.ts +7 -0
  3. package/dist/cjs/actions.js +19 -0
  4. package/dist/cjs/actions.js.map +1 -0
  5. package/dist/cjs/auto.d.ts +1 -0
  6. package/dist/cjs/auto.js +25 -0
  7. package/dist/cjs/auto.js.map +1 -0
  8. package/dist/cjs/build +0 -0
  9. package/dist/cjs/config.d.ts +2 -0
  10. package/dist/cjs/config.js +6 -0
  11. package/dist/cjs/config.js.map +1 -0
  12. package/dist/cjs/global.d.ts +2 -0
  13. package/dist/cjs/global.js +11 -0
  14. package/dist/cjs/global.js.map +1 -0
  15. package/dist/cjs/index.d.ts +18 -0
  16. package/dist/cjs/index.js +71 -0
  17. package/dist/cjs/index.js.map +1 -0
  18. package/dist/cjs/lib/event-handler.d.ts +18 -0
  19. package/dist/cjs/lib/event-handler.js +50 -0
  20. package/dist/cjs/lib/event-handler.js.map +1 -0
  21. package/dist/cjs/lib/event.d.ts +25 -0
  22. package/dist/cjs/lib/event.js +3 -0
  23. package/dist/cjs/lib/event.js.map +1 -0
  24. package/dist/cjs/lib/internal-events.d.ts +17 -0
  25. package/dist/cjs/lib/internal-events.js +30 -0
  26. package/dist/cjs/lib/internal-events.js.map +1 -0
  27. package/dist/cjs/lib/ping.d.ts +2 -0
  28. package/dist/cjs/lib/ping.js +25 -0
  29. package/dist/cjs/lib/ping.js.map +1 -0
  30. package/dist/cjs/lib/request.d.ts +11 -0
  31. package/dist/cjs/lib/request.js +74 -0
  32. package/dist/cjs/lib/request.js.map +1 -0
  33. package/dist/cjs/lib/session.d.ts +11 -0
  34. package/dist/cjs/lib/session.js +66 -0
  35. package/dist/cjs/lib/session.js.map +1 -0
  36. package/dist/cjs/lib/types.d.ts +30 -0
  37. package/dist/cjs/lib/types.js +3 -0
  38. package/dist/cjs/lib/types.js.map +1 -0
  39. package/dist/cjs/lib/utils.d.ts +8 -0
  40. package/dist/cjs/lib/utils.js +33 -0
  41. package/dist/cjs/lib/utils.js.map +1 -0
  42. package/dist/cjs/media/analytics.d.ts +35 -0
  43. package/dist/cjs/media/analytics.js +320 -0
  44. package/dist/cjs/media/analytics.js.map +1 -0
  45. package/dist/cjs/media/events.d.ts +24 -0
  46. package/dist/cjs/media/events.js +28 -0
  47. package/dist/cjs/media/events.js.map +1 -0
  48. package/dist/cjs/media/index.d.ts +5 -0
  49. package/dist/cjs/media/index.js +28 -0
  50. package/dist/cjs/media/index.js.map +1 -0
  51. package/dist/cjs/media/player.d.ts +36 -0
  52. package/dist/cjs/media/player.js +3 -0
  53. package/dist/cjs/media/player.js.map +1 -0
  54. package/dist/cjs/media/players/helpers/bitrate-calculator.d.ts +10 -0
  55. package/dist/cjs/media/players/helpers/bitrate-calculator.js +57 -0
  56. package/dist/cjs/media/players/helpers/bitrate-calculator.js.map +1 -0
  57. package/dist/cjs/media/players/helpers/frame-rate-calculator.d.ts +14 -0
  58. package/dist/cjs/media/players/helpers/frame-rate-calculator.js +53 -0
  59. package/dist/cjs/media/players/helpers/frame-rate-calculator.js.map +1 -0
  60. package/dist/cjs/media/players/helpers/loaded-time-calculator.d.ts +11 -0
  61. package/dist/cjs/media/players/helpers/loaded-time-calculator.js +42 -0
  62. package/dist/cjs/media/players/helpers/loaded-time-calculator.js.map +1 -0
  63. package/dist/cjs/media/players/html.d.ts +43 -0
  64. package/dist/cjs/media/players/html.js +232 -0
  65. package/dist/cjs/media/players/html.js.map +1 -0
  66. package/dist/cjs/media/players/index.d.ts +2 -0
  67. package/dist/cjs/media/players/index.js +8 -0
  68. package/dist/cjs/media/players/index.js.map +1 -0
  69. package/dist/cjs/media/players/videojs.d.ts +72 -0
  70. package/dist/cjs/media/players/videojs.js +102 -0
  71. package/dist/cjs/media/players/videojs.js.map +1 -0
  72. package/dist/cjs/media/types.d.ts +63 -0
  73. package/dist/cjs/media/types.js +32 -0
  74. package/dist/cjs/media/types.js.map +1 -0
  75. package/dist/cjs/media/utils.d.ts +2 -0
  76. package/dist/cjs/media/utils.js +15 -0
  77. package/dist/cjs/media/utils.js.map +1 -0
  78. package/dist/cjs/package.json +1 -0
  79. package/dist/cjs/page/analytics.d.ts +25 -0
  80. package/dist/cjs/page/analytics.js +102 -0
  81. package/dist/cjs/page/analytics.js.map +1 -0
  82. package/dist/cjs/page/index.d.ts +0 -0
  83. package/dist/cjs/page/index.js +2 -0
  84. package/dist/cjs/page/index.js.map +1 -0
  85. package/dist/cjs/page/performance.d.ts +10 -0
  86. package/dist/cjs/page/performance.js +49 -0
  87. package/dist/cjs/page/performance.js.map +1 -0
  88. package/dist/cjs/page/types.d.ts +30 -0
  89. package/dist/cjs/page/types.js +17 -0
  90. package/dist/cjs/page/types.js.map +1 -0
  91. package/dist/cjs/page/utils.d.ts +2 -0
  92. package/dist/cjs/page/utils.js +27 -0
  93. package/dist/cjs/page/utils.js.map +1 -0
  94. package/dist/esm/actions.d.ts +7 -0
  95. package/dist/esm/actions.js +15 -0
  96. package/dist/esm/actions.js.map +1 -0
  97. package/dist/esm/auto.d.ts +1 -0
  98. package/dist/esm/auto.js +23 -0
  99. package/dist/esm/auto.js.map +1 -0
  100. package/dist/esm/build +0 -0
  101. package/dist/esm/config.d.ts +2 -0
  102. package/dist/esm/config.js +3 -0
  103. package/dist/esm/config.js.map +1 -0
  104. package/dist/esm/global.d.ts +2 -0
  105. package/dist/esm/global.js +3 -0
  106. package/dist/esm/global.js.map +1 -0
  107. package/dist/esm/index.d.ts +18 -0
  108. package/dist/esm/index.js +65 -0
  109. package/dist/esm/index.js.map +1 -0
  110. package/dist/esm/lib/event-handler.d.ts +18 -0
  111. package/dist/esm/lib/event-handler.js +46 -0
  112. package/dist/esm/lib/event-handler.js.map +1 -0
  113. package/dist/esm/lib/event.d.ts +25 -0
  114. package/dist/esm/lib/event.js +2 -0
  115. package/dist/esm/lib/event.js.map +1 -0
  116. package/dist/esm/lib/internal-events.d.ts +17 -0
  117. package/dist/esm/lib/internal-events.js +26 -0
  118. package/dist/esm/lib/internal-events.js.map +1 -0
  119. package/dist/esm/lib/ping.d.ts +2 -0
  120. package/dist/esm/lib/ping.js +20 -0
  121. package/dist/esm/lib/ping.js.map +1 -0
  122. package/dist/esm/lib/request.d.ts +11 -0
  123. package/dist/esm/lib/request.js +69 -0
  124. package/dist/esm/lib/request.js.map +1 -0
  125. package/dist/esm/lib/session.d.ts +11 -0
  126. package/dist/esm/lib/session.js +58 -0
  127. package/dist/esm/lib/session.js.map +1 -0
  128. package/dist/esm/lib/types.d.ts +30 -0
  129. package/dist/esm/lib/types.js +2 -0
  130. package/dist/esm/lib/types.js.map +1 -0
  131. package/dist/esm/lib/utils.d.ts +8 -0
  132. package/dist/esm/lib/utils.js +27 -0
  133. package/dist/esm/lib/utils.js.map +1 -0
  134. package/dist/esm/media/analytics.d.ts +35 -0
  135. package/dist/esm/media/analytics.js +316 -0
  136. package/dist/esm/media/analytics.js.map +1 -0
  137. package/dist/esm/media/events.d.ts +24 -0
  138. package/dist/esm/media/events.js +25 -0
  139. package/dist/esm/media/events.js.map +1 -0
  140. package/dist/esm/media/index.d.ts +5 -0
  141. package/dist/esm/media/index.js +22 -0
  142. package/dist/esm/media/index.js.map +1 -0
  143. package/dist/esm/media/player.d.ts +36 -0
  144. package/dist/esm/media/player.js +2 -0
  145. package/dist/esm/media/player.js.map +1 -0
  146. package/dist/esm/media/players/helpers/bitrate-calculator.d.ts +10 -0
  147. package/dist/esm/media/players/helpers/bitrate-calculator.js +53 -0
  148. package/dist/esm/media/players/helpers/bitrate-calculator.js.map +1 -0
  149. package/dist/esm/media/players/helpers/frame-rate-calculator.d.ts +14 -0
  150. package/dist/esm/media/players/helpers/frame-rate-calculator.js +49 -0
  151. package/dist/esm/media/players/helpers/frame-rate-calculator.js.map +1 -0
  152. package/dist/esm/media/players/helpers/loaded-time-calculator.d.ts +11 -0
  153. package/dist/esm/media/players/helpers/loaded-time-calculator.js +38 -0
  154. package/dist/esm/media/players/helpers/loaded-time-calculator.js.map +1 -0
  155. package/dist/esm/media/players/html.d.ts +43 -0
  156. package/dist/esm/media/players/html.js +228 -0
  157. package/dist/esm/media/players/html.js.map +1 -0
  158. package/dist/esm/media/players/index.d.ts +2 -0
  159. package/dist/esm/media/players/index.js +3 -0
  160. package/dist/esm/media/players/index.js.map +1 -0
  161. package/dist/esm/media/players/videojs.d.ts +72 -0
  162. package/dist/esm/media/players/videojs.js +98 -0
  163. package/dist/esm/media/players/videojs.js.map +1 -0
  164. package/dist/esm/media/types.d.ts +63 -0
  165. package/dist/esm/media/types.js +29 -0
  166. package/dist/esm/media/types.js.map +1 -0
  167. package/dist/esm/media/utils.d.ts +2 -0
  168. package/dist/esm/media/utils.js +11 -0
  169. package/dist/esm/media/utils.js.map +1 -0
  170. package/dist/esm/package.json +1 -0
  171. package/dist/esm/page/analytics.d.ts +25 -0
  172. package/dist/esm/page/analytics.js +98 -0
  173. package/dist/esm/page/analytics.js.map +1 -0
  174. package/dist/esm/page/index.d.ts +0 -0
  175. package/dist/esm/page/index.js +2 -0
  176. package/dist/esm/page/index.js.map +1 -0
  177. package/dist/esm/page/performance.d.ts +10 -0
  178. package/dist/esm/page/performance.js +45 -0
  179. package/dist/esm/page/performance.js.map +1 -0
  180. package/dist/esm/page/types.d.ts +30 -0
  181. package/dist/esm/page/types.js +14 -0
  182. package/dist/esm/page/types.js.map +1 -0
  183. package/dist/esm/page/utils.d.ts +2 -0
  184. package/dist/esm/page/utils.js +23 -0
  185. package/dist/esm/page/utils.js.map +1 -0
  186. package/dist/index.global.dev.js +2588 -0
  187. package/dist/index.global.js +1 -0
  188. package/package.json +79 -0
@@ -0,0 +1,2588 @@
1
+ "use strict";
2
+ var TenbyteAnalytics = (() => {
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJS = (cb, mod) => function __require() {
10
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
+ };
12
+ var __export = (target, all) => {
13
+ for (var name in all)
14
+ __defProp(target, name, { get: all[name], enumerable: true });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
+ // If the importer is in node compatibility mode or this is not an ESM
26
+ // file that has been converted to a CommonJS file using a Babel-
27
+ // compatible transform (i.e. "__esModule" has not been set), then set
28
+ // "default" to the CommonJS "module.exports" for node compatibility.
29
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
+ mod
31
+ ));
32
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
+
34
+ // node_modules/ua-parser-js/src/ua-parser.js
35
+ var require_ua_parser = __commonJS({
36
+ "node_modules/ua-parser-js/src/ua-parser.js"(exports, module) {
37
+ (function(window2, undefined2) {
38
+ "use strict";
39
+ var LIBVERSION = "1.0.37", EMPTY = "", UNKNOWN = "?", FUNC_TYPE = "function", UNDEF_TYPE = "undefined", OBJ_TYPE = "object", STR_TYPE = "string", MAJOR = "major", MODEL = "model", NAME = "name", TYPE = "type", VENDOR = "vendor", VERSION = "version", ARCHITECTURE = "architecture", CONSOLE = "console", MOBILE = "mobile", TABLET = "tablet", SMARTTV = "smarttv", WEARABLE = "wearable", EMBEDDED = "embedded", UA_MAX_LENGTH = 500;
40
+ var AMAZON = "Amazon", APPLE = "Apple", ASUS = "ASUS", BLACKBERRY = "BlackBerry", BROWSER = "Browser", CHROME = "Chrome", EDGE = "Edge", FIREFOX = "Firefox", GOOGLE = "Google", HUAWEI = "Huawei", LG = "LG", MICROSOFT = "Microsoft", MOTOROLA = "Motorola", OPERA = "Opera", SAMSUNG = "Samsung", SHARP = "Sharp", SONY = "Sony", XIAOMI = "Xiaomi", ZEBRA = "Zebra", FACEBOOK = "Facebook", CHROMIUM_OS = "Chromium OS", MAC_OS = "Mac OS";
41
+ var extend = function(regexes2, extensions) {
42
+ var mergedRegexes = {};
43
+ for (var i in regexes2) {
44
+ if (extensions[i] && extensions[i].length % 2 === 0) {
45
+ mergedRegexes[i] = extensions[i].concat(regexes2[i]);
46
+ } else {
47
+ mergedRegexes[i] = regexes2[i];
48
+ }
49
+ }
50
+ return mergedRegexes;
51
+ }, enumerize = function(arr) {
52
+ var enums = {};
53
+ for (var i = 0; i < arr.length; i++) {
54
+ enums[arr[i].toUpperCase()] = arr[i];
55
+ }
56
+ return enums;
57
+ }, has = function(str1, str2) {
58
+ return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
59
+ }, lowerize = function(str) {
60
+ return str.toLowerCase();
61
+ }, majorize = function(version) {
62
+ return typeof version === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split(".")[0] : undefined2;
63
+ }, trim = function(str, len) {
64
+ if (typeof str === STR_TYPE) {
65
+ str = str.replace(/^\s\s*/, EMPTY);
66
+ return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
67
+ }
68
+ };
69
+ var rgxMapper = function(ua, arrays) {
70
+ var i = 0, j, k, p, q, matches, match;
71
+ while (i < arrays.length && !matches) {
72
+ var regex = arrays[i], props = arrays[i + 1];
73
+ j = k = 0;
74
+ while (j < regex.length && !matches) {
75
+ if (!regex[j]) {
76
+ break;
77
+ }
78
+ matches = regex[j++].exec(ua);
79
+ if (!!matches) {
80
+ for (p = 0; p < props.length; p++) {
81
+ match = matches[++k];
82
+ q = props[p];
83
+ if (typeof q === OBJ_TYPE && q.length > 0) {
84
+ if (q.length === 2) {
85
+ if (typeof q[1] == FUNC_TYPE) {
86
+ this[q[0]] = q[1].call(this, match);
87
+ } else {
88
+ this[q[0]] = q[1];
89
+ }
90
+ } else if (q.length === 3) {
91
+ if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
92
+ this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined2;
93
+ } else {
94
+ this[q[0]] = match ? match.replace(q[1], q[2]) : undefined2;
95
+ }
96
+ } else if (q.length === 4) {
97
+ this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined2;
98
+ }
99
+ } else {
100
+ this[q] = match ? match : undefined2;
101
+ }
102
+ }
103
+ }
104
+ }
105
+ i += 2;
106
+ }
107
+ }, strMapper = function(str, map) {
108
+ for (var i in map) {
109
+ if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
110
+ for (var j = 0; j < map[i].length; j++) {
111
+ if (has(map[i][j], str)) {
112
+ return i === UNKNOWN ? undefined2 : i;
113
+ }
114
+ }
115
+ } else if (has(map[i], str)) {
116
+ return i === UNKNOWN ? undefined2 : i;
117
+ }
118
+ }
119
+ return str;
120
+ };
121
+ var oldSafariMap = {
122
+ "1.0": "/8",
123
+ "1.2": "/1",
124
+ "1.3": "/3",
125
+ "2.0": "/412",
126
+ "2.0.2": "/416",
127
+ "2.0.3": "/417",
128
+ "2.0.4": "/419",
129
+ "?": "/"
130
+ }, windowsVersionMap = {
131
+ "ME": "4.90",
132
+ "NT 3.11": "NT3.51",
133
+ "NT 4.0": "NT4.0",
134
+ "2000": "NT 5.0",
135
+ "XP": ["NT 5.1", "NT 5.2"],
136
+ "Vista": "NT 6.0",
137
+ "7": "NT 6.1",
138
+ "8": "NT 6.2",
139
+ "8.1": "NT 6.3",
140
+ "10": ["NT 6.4", "NT 10.0"],
141
+ "RT": "ARM"
142
+ };
143
+ var regexes = {
144
+ browser: [
145
+ [
146
+ /\b(?:crmo|crios)\/([\w\.]+)/i
147
+ // Chrome for Android/iOS
148
+ ],
149
+ [VERSION, [NAME, "Chrome"]],
150
+ [
151
+ /edg(?:e|ios|a)?\/([\w\.]+)/i
152
+ // Microsoft Edge
153
+ ],
154
+ [VERSION, [NAME, "Edge"]],
155
+ [
156
+ // Presto based
157
+ /(opera mini)\/([-\w\.]+)/i,
158
+ // Opera Mini
159
+ /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,
160
+ // Opera Mobi/Tablet
161
+ /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i
162
+ // Opera
163
+ ],
164
+ [NAME, VERSION],
165
+ [
166
+ /opios[\/ ]+([\w\.]+)/i
167
+ // Opera mini on iphone >= 8.0
168
+ ],
169
+ [VERSION, [NAME, OPERA + " Mini"]],
170
+ [
171
+ /\bopr\/([\w\.]+)/i
172
+ // Opera Webkit
173
+ ],
174
+ [VERSION, [NAME, OPERA]],
175
+ [
176
+ // Mixed
177
+ /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i
178
+ // Baidu
179
+ ],
180
+ [VERSION, [NAME, "Baidu"]],
181
+ [
182
+ /(kindle)\/([\w\.]+)/i,
183
+ // Kindle
184
+ /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i,
185
+ // Lunascape/Maxthon/Netfront/Jasmine/Blazer
186
+ // Trident based
187
+ /(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i,
188
+ // Avant/IEMobile/SlimBrowser
189
+ /(?:ms|\()(ie) ([\w\.]+)/i,
190
+ // Internet Explorer
191
+ // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
192
+ /(flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i,
193
+ // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ
194
+ /(heytap|ovi)browser\/([\d\.]+)/i,
195
+ // Heytap/Ovi
196
+ /(weibo)__([\d\.]+)/i
197
+ // Weibo
198
+ ],
199
+ [NAME, VERSION],
200
+ [
201
+ /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i
202
+ // UCBrowser
203
+ ],
204
+ [VERSION, [NAME, "UC" + BROWSER]],
205
+ [
206
+ /microm.+\bqbcore\/([\w\.]+)/i,
207
+ // WeChat Desktop for Windows Built-in Browser
208
+ /\bqbcore\/([\w\.]+).+microm/i,
209
+ /micromessenger\/([\w\.]+)/i
210
+ // WeChat
211
+ ],
212
+ [VERSION, [NAME, "WeChat"]],
213
+ [
214
+ /konqueror\/([\w\.]+)/i
215
+ // Konqueror
216
+ ],
217
+ [VERSION, [NAME, "Konqueror"]],
218
+ [
219
+ /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i
220
+ // IE11
221
+ ],
222
+ [VERSION, [NAME, "IE"]],
223
+ [
224
+ /ya(?:search)?browser\/([\w\.]+)/i
225
+ // Yandex
226
+ ],
227
+ [VERSION, [NAME, "Yandex"]],
228
+ [
229
+ /slbrowser\/([\w\.]+)/i
230
+ // Smart Lenovo Browser
231
+ ],
232
+ [VERSION, [NAME, "Smart Lenovo " + BROWSER]],
233
+ [
234
+ /(avast|avg)\/([\w\.]+)/i
235
+ // Avast/AVG Secure Browser
236
+ ],
237
+ [[NAME, /(.+)/, "$1 Secure " + BROWSER], VERSION],
238
+ [
239
+ /\bfocus\/([\w\.]+)/i
240
+ // Firefox Focus
241
+ ],
242
+ [VERSION, [NAME, FIREFOX + " Focus"]],
243
+ [
244
+ /\bopt\/([\w\.]+)/i
245
+ // Opera Touch
246
+ ],
247
+ [VERSION, [NAME, OPERA + " Touch"]],
248
+ [
249
+ /coc_coc\w+\/([\w\.]+)/i
250
+ // Coc Coc Browser
251
+ ],
252
+ [VERSION, [NAME, "Coc Coc"]],
253
+ [
254
+ /dolfin\/([\w\.]+)/i
255
+ // Dolphin
256
+ ],
257
+ [VERSION, [NAME, "Dolphin"]],
258
+ [
259
+ /coast\/([\w\.]+)/i
260
+ // Opera Coast
261
+ ],
262
+ [VERSION, [NAME, OPERA + " Coast"]],
263
+ [
264
+ /miuibrowser\/([\w\.]+)/i
265
+ // MIUI Browser
266
+ ],
267
+ [VERSION, [NAME, "MIUI " + BROWSER]],
268
+ [
269
+ /fxios\/([-\w\.]+)/i
270
+ // Firefox for iOS
271
+ ],
272
+ [VERSION, [NAME, FIREFOX]],
273
+ [
274
+ /\bqihu|(qi?ho?o?|360)browser/i
275
+ // 360
276
+ ],
277
+ [[NAME, "360 " + BROWSER]],
278
+ [
279
+ /(oculus|sailfish|huawei|vivo)browser\/([\w\.]+)/i
280
+ ],
281
+ [[NAME, /(.+)/, "$1 " + BROWSER], VERSION],
282
+ [
283
+ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser
284
+ /samsungbrowser\/([\w\.]+)/i
285
+ // Samsung Internet
286
+ ],
287
+ [VERSION, [NAME, SAMSUNG + " Internet"]],
288
+ [
289
+ /(comodo_dragon)\/([\w\.]+)/i
290
+ // Comodo Dragon
291
+ ],
292
+ [[NAME, /_/g, " "], VERSION],
293
+ [
294
+ /metasr[\/ ]?([\d\.]+)/i
295
+ // Sogou Explorer
296
+ ],
297
+ [VERSION, [NAME, "Sogou Explorer"]],
298
+ [
299
+ /(sogou)mo\w+\/([\d\.]+)/i
300
+ // Sogou Mobile
301
+ ],
302
+ [[NAME, "Sogou Mobile"], VERSION],
303
+ [
304
+ /(electron)\/([\w\.]+) safari/i,
305
+ // Electron-based App
306
+ /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,
307
+ // Tesla
308
+ /m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i
309
+ // QQBrowser/2345 Browser
310
+ ],
311
+ [NAME, VERSION],
312
+ [
313
+ /(lbbrowser)/i,
314
+ // LieBao Browser
315
+ /\[(linkedin)app\]/i
316
+ // LinkedIn App for iOS & Android
317
+ ],
318
+ [NAME],
319
+ [
320
+ // WebView
321
+ /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i
322
+ // Facebook App for iOS & Android
323
+ ],
324
+ [[NAME, FACEBOOK], VERSION],
325
+ [
326
+ /(Klarna)\/([\w\.]+)/i,
327
+ // Klarna Shopping Browser for iOS & Android
328
+ /(kakao(?:talk|story))[\/ ]([\w\.]+)/i,
329
+ // Kakao App
330
+ /(naver)\(.*?(\d+\.[\w\.]+).*\)/i,
331
+ // Naver InApp
332
+ /safari (line)\/([\w\.]+)/i,
333
+ // Line App for iOS
334
+ /\b(line)\/([\w\.]+)\/iab/i,
335
+ // Line App for Android
336
+ /(alipay)client\/([\w\.]+)/i,
337
+ // Alipay
338
+ /(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i
339
+ // Chromium/Instagram/Snapchat
340
+ ],
341
+ [NAME, VERSION],
342
+ [
343
+ /\bgsa\/([\w\.]+) .*safari\//i
344
+ // Google Search Appliance on iOS
345
+ ],
346
+ [VERSION, [NAME, "GSA"]],
347
+ [
348
+ /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i
349
+ // TikTok
350
+ ],
351
+ [VERSION, [NAME, "TikTok"]],
352
+ [
353
+ /headlesschrome(?:\/([\w\.]+)| )/i
354
+ // Chrome Headless
355
+ ],
356
+ [VERSION, [NAME, CHROME + " Headless"]],
357
+ [
358
+ / wv\).+(chrome)\/([\w\.]+)/i
359
+ // Chrome WebView
360
+ ],
361
+ [[NAME, CHROME + " WebView"], VERSION],
362
+ [
363
+ /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i
364
+ // Android Browser
365
+ ],
366
+ [VERSION, [NAME, "Android " + BROWSER]],
367
+ [
368
+ /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i
369
+ // Chrome/OmniWeb/Arora/Tizen/Nokia
370
+ ],
371
+ [NAME, VERSION],
372
+ [
373
+ /version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i
374
+ // Mobile Safari
375
+ ],
376
+ [VERSION, [NAME, "Mobile Safari"]],
377
+ [
378
+ /version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i
379
+ // Safari & Safari Mobile
380
+ ],
381
+ [VERSION, NAME],
382
+ [
383
+ /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i
384
+ // Safari < 3.0
385
+ ],
386
+ [NAME, [VERSION, strMapper, oldSafariMap]],
387
+ [
388
+ /(webkit|khtml)\/([\w\.]+)/i
389
+ ],
390
+ [NAME, VERSION],
391
+ [
392
+ // Gecko based
393
+ /(navigator|netscape\d?)\/([-\w\.]+)/i
394
+ // Netscape
395
+ ],
396
+ [[NAME, "Netscape"], VERSION],
397
+ [
398
+ /mobile vr; rv:([\w\.]+)\).+firefox/i
399
+ // Firefox Reality
400
+ ],
401
+ [VERSION, [NAME, FIREFOX + " Reality"]],
402
+ [
403
+ /ekiohf.+(flow)\/([\w\.]+)/i,
404
+ // Flow
405
+ /(swiftfox)/i,
406
+ // Swiftfox
407
+ /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
408
+ // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar
409
+ /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
410
+ // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
411
+ /(firefox)\/([\w\.]+)/i,
412
+ // Other Firefox-based
413
+ /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i,
414
+ // Mozilla
415
+ // Other
416
+ /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
417
+ // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser
418
+ /(links) \(([\w\.]+)/i,
419
+ // Links
420
+ /panasonic;(viera)/i
421
+ // Panasonic Viera
422
+ ],
423
+ [NAME, VERSION],
424
+ [
425
+ /(cobalt)\/([\w\.]+)/i
426
+ // Cobalt
427
+ ],
428
+ [NAME, [VERSION, /master.|lts./, ""]]
429
+ ],
430
+ cpu: [
431
+ [
432
+ /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i
433
+ // AMD64 (x64)
434
+ ],
435
+ [[ARCHITECTURE, "amd64"]],
436
+ [
437
+ /(ia32(?=;))/i
438
+ // IA32 (quicktime)
439
+ ],
440
+ [[ARCHITECTURE, lowerize]],
441
+ [
442
+ /((?:i[346]|x)86)[;\)]/i
443
+ // IA32 (x86)
444
+ ],
445
+ [[ARCHITECTURE, "ia32"]],
446
+ [
447
+ /\b(aarch64|arm(v?8e?l?|_?64))\b/i
448
+ // ARM64
449
+ ],
450
+ [[ARCHITECTURE, "arm64"]],
451
+ [
452
+ /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i
453
+ // ARMHF
454
+ ],
455
+ [[ARCHITECTURE, "armhf"]],
456
+ [
457
+ // PocketPC mistakenly identified as PowerPC
458
+ /windows (ce|mobile); ppc;/i
459
+ ],
460
+ [[ARCHITECTURE, "arm"]],
461
+ [
462
+ /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i
463
+ // PowerPC
464
+ ],
465
+ [[ARCHITECTURE, /ower/, EMPTY, lowerize]],
466
+ [
467
+ /(sun4\w)[;\)]/i
468
+ // SPARC
469
+ ],
470
+ [[ARCHITECTURE, "sparc"]],
471
+ [
472
+ /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i
473
+ // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
474
+ ],
475
+ [[ARCHITECTURE, lowerize]]
476
+ ],
477
+ device: [
478
+ [
479
+ //////////////////////////
480
+ // MOBILES & TABLETS
481
+ /////////////////////////
482
+ // Samsung
483
+ /\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
484
+ ],
485
+ [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]],
486
+ [
487
+ /\b((?:s[cgp]h|gt|sm)-\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
488
+ /samsung[- ]([-\w]+)/i,
489
+ /sec-(sgh\w+)/i
490
+ ],
491
+ [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]],
492
+ [
493
+ // Apple
494
+ /(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i
495
+ // iPod/iPhone
496
+ ],
497
+ [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]],
498
+ [
499
+ /\((ipad);[-\w\),; ]+apple/i,
500
+ // iPad
501
+ /applecoremedia\/[\w\.]+ \((ipad)/i,
502
+ /\b(ipad)\d\d?,\d\d?[;\]].+ios/i
503
+ ],
504
+ [MODEL, [VENDOR, APPLE], [TYPE, TABLET]],
505
+ [
506
+ /(macintosh);/i
507
+ ],
508
+ [MODEL, [VENDOR, APPLE]],
509
+ [
510
+ // Sharp
511
+ /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
512
+ ],
513
+ [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]],
514
+ [
515
+ // Huawei
516
+ /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
517
+ ],
518
+ [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]],
519
+ [
520
+ /(?:huawei|honor)([-\w ]+)[;\)]/i,
521
+ /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
522
+ ],
523
+ [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]],
524
+ [
525
+ // Xiaomi
526
+ /\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i,
527
+ // Xiaomi POCO
528
+ /\b; (\w+) build\/hm\1/i,
529
+ // Xiaomi Hongmi 'numeric' models
530
+ /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,
531
+ // Xiaomi Hongmi
532
+ /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i,
533
+ // Xiaomi Redmi
534
+ /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i,
535
+ // Xiaomi Redmi 'numeric' models
536
+ /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i
537
+ // Xiaomi Mi
538
+ ],
539
+ [[MODEL, /_/g, " "], [VENDOR, XIAOMI], [TYPE, MOBILE]],
540
+ [
541
+ /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i,
542
+ // Redmi Pad
543
+ /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i
544
+ // Mi Pad tablets
545
+ ],
546
+ [[MODEL, /_/g, " "], [VENDOR, XIAOMI], [TYPE, TABLET]],
547
+ [
548
+ // OPPO
549
+ /; (\w+) bui.+ oppo/i,
550
+ /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
551
+ ],
552
+ [MODEL, [VENDOR, "OPPO"], [TYPE, MOBILE]],
553
+ [
554
+ // Vivo
555
+ /vivo (\w+)(?: bui|\))/i,
556
+ /\b(v[12]\d{3}\w?[at])(?: bui|;)/i
557
+ ],
558
+ [MODEL, [VENDOR, "Vivo"], [TYPE, MOBILE]],
559
+ [
560
+ // Realme
561
+ /\b(rmx[1-3]\d{3})(?: bui|;|\))/i
562
+ ],
563
+ [MODEL, [VENDOR, "Realme"], [TYPE, MOBILE]],
564
+ [
565
+ // Motorola
566
+ /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
567
+ /\bmot(?:orola)?[- ](\w*)/i,
568
+ /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i
569
+ ],
570
+ [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]],
571
+ [
572
+ /\b(mz60\d|xoom[2 ]{0,2}) build\//i
573
+ ],
574
+ [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]],
575
+ [
576
+ // LG
577
+ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
578
+ ],
579
+ [MODEL, [VENDOR, LG], [TYPE, TABLET]],
580
+ [
581
+ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
582
+ /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i,
583
+ /\blg-?([\d\w]+) bui/i
584
+ ],
585
+ [MODEL, [VENDOR, LG], [TYPE, MOBILE]],
586
+ [
587
+ // Lenovo
588
+ /(ideatab[-\w ]+)/i,
589
+ /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
590
+ ],
591
+ [MODEL, [VENDOR, "Lenovo"], [TYPE, TABLET]],
592
+ [
593
+ // Nokia
594
+ /(?:maemo|nokia).*(n900|lumia \d+)/i,
595
+ /nokia[-_ ]?([-\w\.]*)/i
596
+ ],
597
+ [[MODEL, /_/g, " "], [VENDOR, "Nokia"], [TYPE, MOBILE]],
598
+ [
599
+ // Google
600
+ /(pixel c)\b/i
601
+ // Google Pixel C
602
+ ],
603
+ [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]],
604
+ [
605
+ /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i
606
+ // Google Pixel
607
+ ],
608
+ [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]],
609
+ [
610
+ // Sony
611
+ /droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i
612
+ ],
613
+ [MODEL, [VENDOR, SONY], [TYPE, MOBILE]],
614
+ [
615
+ /sony tablet [ps]/i,
616
+ /\b(?:sony)?sgp\w+(?: bui|\))/i
617
+ ],
618
+ [[MODEL, "Xperia Tablet"], [VENDOR, SONY], [TYPE, TABLET]],
619
+ [
620
+ // OnePlus
621
+ / (kb2005|in20[12]5|be20[12][59])\b/i,
622
+ /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
623
+ ],
624
+ [MODEL, [VENDOR, "OnePlus"], [TYPE, MOBILE]],
625
+ [
626
+ // Amazon
627
+ /(alexa)webm/i,
628
+ /(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i,
629
+ // Kindle Fire without Silk / Echo Show
630
+ /(kf[a-z]+)( bui|\)).+silk\//i
631
+ // Kindle Fire HD
632
+ ],
633
+ [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]],
634
+ [
635
+ /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i
636
+ // Fire Phone
637
+ ],
638
+ [[MODEL, /(.+)/g, "Fire Phone $1"], [VENDOR, AMAZON], [TYPE, MOBILE]],
639
+ [
640
+ // BlackBerry
641
+ /(playbook);[-\w\),; ]+(rim)/i
642
+ // BlackBerry PlayBook
643
+ ],
644
+ [MODEL, VENDOR, [TYPE, TABLET]],
645
+ [
646
+ /\b((?:bb[a-f]|st[hv])100-\d)/i,
647
+ /\(bb10; (\w+)/i
648
+ // BlackBerry 10
649
+ ],
650
+ [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]],
651
+ [
652
+ // Asus
653
+ /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i
654
+ ],
655
+ [MODEL, [VENDOR, ASUS], [TYPE, TABLET]],
656
+ [
657
+ / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i
658
+ ],
659
+ [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]],
660
+ [
661
+ // HTC
662
+ /(nexus 9)/i
663
+ // HTC Nexus 9
664
+ ],
665
+ [MODEL, [VENDOR, "HTC"], [TYPE, TABLET]],
666
+ [
667
+ /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,
668
+ // HTC
669
+ // ZTE
670
+ /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,
671
+ /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i
672
+ // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
673
+ ],
674
+ [VENDOR, [MODEL, /_/g, " "], [TYPE, MOBILE]],
675
+ [
676
+ // Acer
677
+ /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
678
+ ],
679
+ [MODEL, [VENDOR, "Acer"], [TYPE, TABLET]],
680
+ [
681
+ // Meizu
682
+ /droid.+; (m[1-5] note) bui/i,
683
+ /\bmz-([-\w]{2,})/i
684
+ ],
685
+ [MODEL, [VENDOR, "Meizu"], [TYPE, MOBILE]],
686
+ [
687
+ // Ulefone
688
+ /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
689
+ ],
690
+ [MODEL, [VENDOR, "Ulefone"], [TYPE, MOBILE]],
691
+ [
692
+ // MIXED
693
+ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i,
694
+ // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
695
+ /(hp) ([\w ]+\w)/i,
696
+ // HP iPAQ
697
+ /(asus)-?(\w+)/i,
698
+ // Asus
699
+ /(microsoft); (lumia[\w ]+)/i,
700
+ // Microsoft Lumia
701
+ /(lenovo)[-_ ]?([-\w]+)/i,
702
+ // Lenovo
703
+ /(jolla)/i,
704
+ // Jolla
705
+ /(oppo) ?([\w ]+) bui/i
706
+ // OPPO
707
+ ],
708
+ [VENDOR, MODEL, [TYPE, MOBILE]],
709
+ [
710
+ /(kobo)\s(ereader|touch)/i,
711
+ // Kobo
712
+ /(archos) (gamepad2?)/i,
713
+ // Archos
714
+ /(hp).+(touchpad(?!.+tablet)|tablet)/i,
715
+ // HP TouchPad
716
+ /(kindle)\/([\w\.]+)/i,
717
+ // Kindle
718
+ /(nook)[\w ]+build\/(\w+)/i,
719
+ // Nook
720
+ /(dell) (strea[kpr\d ]*[\dko])/i,
721
+ // Dell Streak
722
+ /(le[- ]+pan)[- ]+(\w{1,9}) bui/i,
723
+ // Le Pan Tablets
724
+ /(trinity)[- ]*(t\d{3}) bui/i,
725
+ // Trinity Tablets
726
+ /(gigaset)[- ]+(q\w{1,9}) bui/i,
727
+ // Gigaset Tablets
728
+ /(vodafone) ([\w ]+)(?:\)| bui)/i
729
+ // Vodafone
730
+ ],
731
+ [VENDOR, MODEL, [TYPE, TABLET]],
732
+ [
733
+ /(surface duo)/i
734
+ // Surface Duo
735
+ ],
736
+ [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]],
737
+ [
738
+ /droid [\d\.]+; (fp\du?)(?: b|\))/i
739
+ // Fairphone
740
+ ],
741
+ [MODEL, [VENDOR, "Fairphone"], [TYPE, MOBILE]],
742
+ [
743
+ /(u304aa)/i
744
+ // AT&T
745
+ ],
746
+ [MODEL, [VENDOR, "AT&T"], [TYPE, MOBILE]],
747
+ [
748
+ /\bsie-(\w*)/i
749
+ // Siemens
750
+ ],
751
+ [MODEL, [VENDOR, "Siemens"], [TYPE, MOBILE]],
752
+ [
753
+ /\b(rct\w+) b/i
754
+ // RCA Tablets
755
+ ],
756
+ [MODEL, [VENDOR, "RCA"], [TYPE, TABLET]],
757
+ [
758
+ /\b(venue[\d ]{2,7}) b/i
759
+ // Dell Venue Tablets
760
+ ],
761
+ [MODEL, [VENDOR, "Dell"], [TYPE, TABLET]],
762
+ [
763
+ /\b(q(?:mv|ta)\w+) b/i
764
+ // Verizon Tablet
765
+ ],
766
+ [MODEL, [VENDOR, "Verizon"], [TYPE, TABLET]],
767
+ [
768
+ /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i
769
+ // Barnes & Noble Tablet
770
+ ],
771
+ [MODEL, [VENDOR, "Barnes & Noble"], [TYPE, TABLET]],
772
+ [
773
+ /\b(tm\d{3}\w+) b/i
774
+ ],
775
+ [MODEL, [VENDOR, "NuVision"], [TYPE, TABLET]],
776
+ [
777
+ /\b(k88) b/i
778
+ // ZTE K Series Tablet
779
+ ],
780
+ [MODEL, [VENDOR, "ZTE"], [TYPE, TABLET]],
781
+ [
782
+ /\b(nx\d{3}j) b/i
783
+ // ZTE Nubia
784
+ ],
785
+ [MODEL, [VENDOR, "ZTE"], [TYPE, MOBILE]],
786
+ [
787
+ /\b(gen\d{3}) b.+49h/i
788
+ // Swiss GEN Mobile
789
+ ],
790
+ [MODEL, [VENDOR, "Swiss"], [TYPE, MOBILE]],
791
+ [
792
+ /\b(zur\d{3}) b/i
793
+ // Swiss ZUR Tablet
794
+ ],
795
+ [MODEL, [VENDOR, "Swiss"], [TYPE, TABLET]],
796
+ [
797
+ /\b((zeki)?tb.*\b) b/i
798
+ // Zeki Tablets
799
+ ],
800
+ [MODEL, [VENDOR, "Zeki"], [TYPE, TABLET]],
801
+ [
802
+ /\b([yr]\d{2}) b/i,
803
+ /\b(dragon[- ]+touch |dt)(\w{5}) b/i
804
+ // Dragon Touch Tablet
805
+ ],
806
+ [[VENDOR, "Dragon Touch"], MODEL, [TYPE, TABLET]],
807
+ [
808
+ /\b(ns-?\w{0,9}) b/i
809
+ // Insignia Tablets
810
+ ],
811
+ [MODEL, [VENDOR, "Insignia"], [TYPE, TABLET]],
812
+ [
813
+ /\b((nxa|next)-?\w{0,9}) b/i
814
+ // NextBook Tablets
815
+ ],
816
+ [MODEL, [VENDOR, "NextBook"], [TYPE, TABLET]],
817
+ [
818
+ /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i
819
+ // Voice Xtreme Phones
820
+ ],
821
+ [[VENDOR, "Voice"], MODEL, [TYPE, MOBILE]],
822
+ [
823
+ /\b(lvtel\-)?(v1[12]) b/i
824
+ // LvTel Phones
825
+ ],
826
+ [[VENDOR, "LvTel"], MODEL, [TYPE, MOBILE]],
827
+ [
828
+ /\b(ph-1) /i
829
+ // Essential PH-1
830
+ ],
831
+ [MODEL, [VENDOR, "Essential"], [TYPE, MOBILE]],
832
+ [
833
+ /\b(v(100md|700na|7011|917g).*\b) b/i
834
+ // Envizen Tablets
835
+ ],
836
+ [MODEL, [VENDOR, "Envizen"], [TYPE, TABLET]],
837
+ [
838
+ /\b(trio[-\w\. ]+) b/i
839
+ // MachSpeed Tablets
840
+ ],
841
+ [MODEL, [VENDOR, "MachSpeed"], [TYPE, TABLET]],
842
+ [
843
+ /\btu_(1491) b/i
844
+ // Rotor Tablets
845
+ ],
846
+ [MODEL, [VENDOR, "Rotor"], [TYPE, TABLET]],
847
+ [
848
+ /(shield[\w ]+) b/i
849
+ // Nvidia Shield Tablets
850
+ ],
851
+ [MODEL, [VENDOR, "Nvidia"], [TYPE, TABLET]],
852
+ [
853
+ /(sprint) (\w+)/i
854
+ // Sprint Phones
855
+ ],
856
+ [VENDOR, MODEL, [TYPE, MOBILE]],
857
+ [
858
+ /(kin\.[onetw]{3})/i
859
+ // Microsoft Kin
860
+ ],
861
+ [[MODEL, /\./g, " "], [VENDOR, MICROSOFT], [TYPE, MOBILE]],
862
+ [
863
+ /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i
864
+ // Zebra
865
+ ],
866
+ [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]],
867
+ [
868
+ /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i
869
+ ],
870
+ [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]],
871
+ [
872
+ ///////////////////
873
+ // SMARTTVS
874
+ ///////////////////
875
+ /smart-tv.+(samsung)/i
876
+ // Samsung
877
+ ],
878
+ [VENDOR, [TYPE, SMARTTV]],
879
+ [
880
+ /hbbtv.+maple;(\d+)/i
881
+ ],
882
+ [[MODEL, /^/, "SmartTV"], [VENDOR, SAMSUNG], [TYPE, SMARTTV]],
883
+ [
884
+ /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i
885
+ // LG SmartTV
886
+ ],
887
+ [[VENDOR, LG], [TYPE, SMARTTV]],
888
+ [
889
+ /(apple) ?tv/i
890
+ // Apple TV
891
+ ],
892
+ [VENDOR, [MODEL, APPLE + " TV"], [TYPE, SMARTTV]],
893
+ [
894
+ /crkey/i
895
+ // Google Chromecast
896
+ ],
897
+ [[MODEL, CHROME + "cast"], [VENDOR, GOOGLE], [TYPE, SMARTTV]],
898
+ [
899
+ /droid.+aft(\w+)( bui|\))/i
900
+ // Fire TV
901
+ ],
902
+ [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]],
903
+ [
904
+ /\(dtv[\);].+(aquos)/i,
905
+ /(aquos-tv[\w ]+)\)/i
906
+ // Sharp
907
+ ],
908
+ [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],
909
+ [
910
+ /(bravia[\w ]+)( bui|\))/i
911
+ // Sony
912
+ ],
913
+ [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]],
914
+ [
915
+ /(mitv-\w{5}) bui/i
916
+ // Xiaomi
917
+ ],
918
+ [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]],
919
+ [
920
+ /Hbbtv.*(technisat) (.*);/i
921
+ // TechniSAT
922
+ ],
923
+ [VENDOR, MODEL, [TYPE, SMARTTV]],
924
+ [
925
+ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,
926
+ // Roku
927
+ /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i
928
+ // HbbTV devices
929
+ ],
930
+ [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]],
931
+ [
932
+ /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i
933
+ // SmartTV from Unidentified Vendors
934
+ ],
935
+ [[TYPE, SMARTTV]],
936
+ [
937
+ ///////////////////
938
+ // CONSOLES
939
+ ///////////////////
940
+ /(ouya)/i,
941
+ // Ouya
942
+ /(nintendo) ([wids3utch]+)/i
943
+ // Nintendo
944
+ ],
945
+ [VENDOR, MODEL, [TYPE, CONSOLE]],
946
+ [
947
+ /droid.+; (shield) bui/i
948
+ // Nvidia
949
+ ],
950
+ [MODEL, [VENDOR, "Nvidia"], [TYPE, CONSOLE]],
951
+ [
952
+ /(playstation [345portablevi]+)/i
953
+ // Playstation
954
+ ],
955
+ [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]],
956
+ [
957
+ /\b(xbox(?: one)?(?!; xbox))[\); ]/i
958
+ // Microsoft Xbox
959
+ ],
960
+ [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]],
961
+ [
962
+ ///////////////////
963
+ // WEARABLES
964
+ ///////////////////
965
+ /((pebble))app/i
966
+ // Pebble
967
+ ],
968
+ [VENDOR, MODEL, [TYPE, WEARABLE]],
969
+ [
970
+ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i
971
+ // Apple Watch
972
+ ],
973
+ [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]],
974
+ [
975
+ /droid.+; (glass) \d/i
976
+ // Google Glass
977
+ ],
978
+ [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]],
979
+ [
980
+ /droid.+; (wt63?0{2,3})\)/i
981
+ ],
982
+ [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]],
983
+ [
984
+ /(quest( 2| pro)?)/i
985
+ // Oculus Quest
986
+ ],
987
+ [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]],
988
+ [
989
+ ///////////////////
990
+ // EMBEDDED
991
+ ///////////////////
992
+ /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i
993
+ // Tesla
994
+ ],
995
+ [VENDOR, [TYPE, EMBEDDED]],
996
+ [
997
+ /(aeobc)\b/i
998
+ // Echo Dot
999
+ ],
1000
+ [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]],
1001
+ [
1002
+ ////////////////////
1003
+ // MIXED (GENERIC)
1004
+ ///////////////////
1005
+ /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i
1006
+ // Android Phones from Unidentified Vendors
1007
+ ],
1008
+ [MODEL, [TYPE, MOBILE]],
1009
+ [
1010
+ /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i
1011
+ // Android Tablets from Unidentified Vendors
1012
+ ],
1013
+ [MODEL, [TYPE, TABLET]],
1014
+ [
1015
+ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i
1016
+ // Unidentifiable Tablet
1017
+ ],
1018
+ [[TYPE, TABLET]],
1019
+ [
1020
+ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i
1021
+ // Unidentifiable Mobile
1022
+ ],
1023
+ [[TYPE, MOBILE]],
1024
+ [
1025
+ /(android[-\w\. ]{0,9});.+buil/i
1026
+ // Generic Android Device
1027
+ ],
1028
+ [MODEL, [VENDOR, "Generic"]]
1029
+ ],
1030
+ engine: [
1031
+ [
1032
+ /windows.+ edge\/([\w\.]+)/i
1033
+ // EdgeHTML
1034
+ ],
1035
+ [VERSION, [NAME, EDGE + "HTML"]],
1036
+ [
1037
+ /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i
1038
+ // Blink
1039
+ ],
1040
+ [VERSION, [NAME, "Blink"]],
1041
+ [
1042
+ /(presto)\/([\w\.]+)/i,
1043
+ // Presto
1044
+ /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i,
1045
+ // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna
1046
+ /ekioh(flow)\/([\w\.]+)/i,
1047
+ // Flow
1048
+ /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i,
1049
+ // KHTML/Tasman/Links
1050
+ /(icab)[\/ ]([23]\.[\d\.]+)/i,
1051
+ // iCab
1052
+ /\b(libweb)/i
1053
+ ],
1054
+ [NAME, VERSION],
1055
+ [
1056
+ /rv\:([\w\.]{1,9})\b.+(gecko)/i
1057
+ // Gecko
1058
+ ],
1059
+ [VERSION, NAME]
1060
+ ],
1061
+ os: [
1062
+ [
1063
+ // Windows
1064
+ /microsoft (windows) (vista|xp)/i
1065
+ // Windows (iTunes)
1066
+ ],
1067
+ [NAME, VERSION],
1068
+ [
1069
+ /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i
1070
+ // Windows Phone
1071
+ ],
1072
+ [NAME, [VERSION, strMapper, windowsVersionMap]],
1073
+ [
1074
+ /windows nt 6\.2; (arm)/i,
1075
+ // Windows RT
1076
+ /windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i,
1077
+ /(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i
1078
+ ],
1079
+ [[VERSION, strMapper, windowsVersionMap], [NAME, "Windows"]],
1080
+ [
1081
+ // iOS/macOS
1082
+ /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i,
1083
+ // iOS
1084
+ /(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i,
1085
+ /cfnetwork\/.+darwin/i
1086
+ ],
1087
+ [[VERSION, /_/g, "."], [NAME, "iOS"]],
1088
+ [
1089
+ /(mac os x) ?([\w\. ]*)/i,
1090
+ /(macintosh|mac_powerpc\b)(?!.+haiku)/i
1091
+ // Mac OS
1092
+ ],
1093
+ [[NAME, MAC_OS], [VERSION, /_/g, "."]],
1094
+ [
1095
+ // Mobile OSes
1096
+ /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i
1097
+ // Android-x86/HarmonyOS
1098
+ ],
1099
+ [VERSION, NAME],
1100
+ [
1101
+ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS
1102
+ /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i,
1103
+ /(blackberry)\w*\/([\w\.]*)/i,
1104
+ // Blackberry
1105
+ /(tizen|kaios)[\/ ]([\w\.]+)/i,
1106
+ // Tizen/KaiOS
1107
+ /\((series40);/i
1108
+ // Series 40
1109
+ ],
1110
+ [NAME, VERSION],
1111
+ [
1112
+ /\(bb(10);/i
1113
+ // BlackBerry 10
1114
+ ],
1115
+ [VERSION, [NAME, BLACKBERRY]],
1116
+ [
1117
+ /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i
1118
+ // Symbian
1119
+ ],
1120
+ [VERSION, [NAME, "Symbian"]],
1121
+ [
1122
+ /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i
1123
+ // Firefox OS
1124
+ ],
1125
+ [VERSION, [NAME, FIREFOX + " OS"]],
1126
+ [
1127
+ /web0s;.+rt(tv)/i,
1128
+ /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i
1129
+ // WebOS
1130
+ ],
1131
+ [VERSION, [NAME, "webOS"]],
1132
+ [
1133
+ /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i
1134
+ // watchOS
1135
+ ],
1136
+ [VERSION, [NAME, "watchOS"]],
1137
+ [
1138
+ // Google Chromecast
1139
+ /crkey\/([\d\.]+)/i
1140
+ // Google Chromecast
1141
+ ],
1142
+ [VERSION, [NAME, CHROME + "cast"]],
1143
+ [
1144
+ /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i
1145
+ // Chromium OS
1146
+ ],
1147
+ [[NAME, CHROMIUM_OS], VERSION],
1148
+ [
1149
+ // Smart TVs
1150
+ /panasonic;(viera)/i,
1151
+ // Panasonic Viera
1152
+ /(netrange)mmh/i,
1153
+ // Netrange
1154
+ /(nettv)\/(\d+\.[\w\.]+)/i,
1155
+ // NetTV
1156
+ // Console
1157
+ /(nintendo|playstation) ([wids345portablevuch]+)/i,
1158
+ // Nintendo/Playstation
1159
+ /(xbox); +xbox ([^\);]+)/i,
1160
+ // Microsoft Xbox (360, One, X, S, Series X, Series S)
1161
+ // Other
1162
+ /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,
1163
+ // Joli/Palm
1164
+ /(mint)[\/\(\) ]?(\w*)/i,
1165
+ // Mint
1166
+ /(mageia|vectorlinux)[; ]/i,
1167
+ // Mageia/VectorLinux
1168
+ /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,
1169
+ // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire
1170
+ /(hurd|linux) ?([\w\.]*)/i,
1171
+ // Hurd/Linux
1172
+ /(gnu) ?([\w\.]*)/i,
1173
+ // GNU
1174
+ /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,
1175
+ // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly
1176
+ /(haiku) (\w+)/i
1177
+ // Haiku
1178
+ ],
1179
+ [NAME, VERSION],
1180
+ [
1181
+ /(sunos) ?([\w\.\d]*)/i
1182
+ // Solaris
1183
+ ],
1184
+ [[NAME, "Solaris"], VERSION],
1185
+ [
1186
+ /((?:open)?solaris)[-\/ ]?([\w\.]*)/i,
1187
+ // Solaris
1188
+ /(aix) ((\d)(?=\.|\)| )[\w\.])*/i,
1189
+ // AIX
1190
+ /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i,
1191
+ // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX/SerenityOS
1192
+ /(unix) ?([\w\.]*)/i
1193
+ // UNIX
1194
+ ],
1195
+ [NAME, VERSION]
1196
+ ]
1197
+ };
1198
+ var UAParser2 = function(ua, extensions) {
1199
+ if (typeof ua === OBJ_TYPE) {
1200
+ extensions = ua;
1201
+ ua = undefined2;
1202
+ }
1203
+ if (!(this instanceof UAParser2)) {
1204
+ return new UAParser2(ua, extensions).getResult();
1205
+ }
1206
+ var _navigator = typeof window2 !== UNDEF_TYPE && window2.navigator ? window2.navigator : undefined2;
1207
+ var _ua = ua || (_navigator && _navigator.userAgent ? _navigator.userAgent : EMPTY);
1208
+ var _uach = _navigator && _navigator.userAgentData ? _navigator.userAgentData : undefined2;
1209
+ var _rgxmap = extensions ? extend(regexes, extensions) : regexes;
1210
+ var _isSelfNav = _navigator && _navigator.userAgent == _ua;
1211
+ this.getBrowser = function() {
1212
+ var _browser = {};
1213
+ _browser[NAME] = undefined2;
1214
+ _browser[VERSION] = undefined2;
1215
+ rgxMapper.call(_browser, _ua, _rgxmap.browser);
1216
+ _browser[MAJOR] = majorize(_browser[VERSION]);
1217
+ if (_isSelfNav && _navigator && _navigator.brave && typeof _navigator.brave.isBrave == FUNC_TYPE) {
1218
+ _browser[NAME] = "Brave";
1219
+ }
1220
+ return _browser;
1221
+ };
1222
+ this.getCPU = function() {
1223
+ var _cpu = {};
1224
+ _cpu[ARCHITECTURE] = undefined2;
1225
+ rgxMapper.call(_cpu, _ua, _rgxmap.cpu);
1226
+ return _cpu;
1227
+ };
1228
+ this.getDevice = function() {
1229
+ var _device = {};
1230
+ _device[VENDOR] = undefined2;
1231
+ _device[MODEL] = undefined2;
1232
+ _device[TYPE] = undefined2;
1233
+ rgxMapper.call(_device, _ua, _rgxmap.device);
1234
+ if (_isSelfNav && !_device[TYPE] && _uach && _uach.mobile) {
1235
+ _device[TYPE] = MOBILE;
1236
+ }
1237
+ if (_isSelfNav && _device[MODEL] == "Macintosh" && _navigator && typeof _navigator.standalone !== UNDEF_TYPE && _navigator.maxTouchPoints && _navigator.maxTouchPoints > 2) {
1238
+ _device[MODEL] = "iPad";
1239
+ _device[TYPE] = TABLET;
1240
+ }
1241
+ return _device;
1242
+ };
1243
+ this.getEngine = function() {
1244
+ var _engine = {};
1245
+ _engine[NAME] = undefined2;
1246
+ _engine[VERSION] = undefined2;
1247
+ rgxMapper.call(_engine, _ua, _rgxmap.engine);
1248
+ return _engine;
1249
+ };
1250
+ this.getOS = function() {
1251
+ var _os = {};
1252
+ _os[NAME] = undefined2;
1253
+ _os[VERSION] = undefined2;
1254
+ rgxMapper.call(_os, _ua, _rgxmap.os);
1255
+ if (_isSelfNav && !_os[NAME] && _uach && _uach.platform != "Unknown") {
1256
+ _os[NAME] = _uach.platform.replace(/chrome os/i, CHROMIUM_OS).replace(/macos/i, MAC_OS);
1257
+ }
1258
+ return _os;
1259
+ };
1260
+ this.getResult = function() {
1261
+ return {
1262
+ ua: this.getUA(),
1263
+ browser: this.getBrowser(),
1264
+ engine: this.getEngine(),
1265
+ os: this.getOS(),
1266
+ device: this.getDevice(),
1267
+ cpu: this.getCPU()
1268
+ };
1269
+ };
1270
+ this.getUA = function() {
1271
+ return _ua;
1272
+ };
1273
+ this.setUA = function(ua2) {
1274
+ _ua = typeof ua2 === STR_TYPE && ua2.length > UA_MAX_LENGTH ? trim(ua2, UA_MAX_LENGTH) : ua2;
1275
+ return this;
1276
+ };
1277
+ this.setUA(_ua);
1278
+ return this;
1279
+ };
1280
+ UAParser2.VERSION = LIBVERSION;
1281
+ UAParser2.BROWSER = enumerize([NAME, VERSION, MAJOR]);
1282
+ UAParser2.CPU = enumerize([ARCHITECTURE]);
1283
+ UAParser2.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
1284
+ UAParser2.ENGINE = UAParser2.OS = enumerize([NAME, VERSION]);
1285
+ if (typeof exports !== UNDEF_TYPE) {
1286
+ if (typeof module !== UNDEF_TYPE && module.exports) {
1287
+ exports = module.exports = UAParser2;
1288
+ }
1289
+ exports.UAParser = UAParser2;
1290
+ } else {
1291
+ if (typeof define === FUNC_TYPE && define.amd) {
1292
+ define(function() {
1293
+ return UAParser2;
1294
+ });
1295
+ } else if (typeof window2 !== UNDEF_TYPE) {
1296
+ window2.UAParser = UAParser2;
1297
+ }
1298
+ }
1299
+ var $ = typeof window2 !== UNDEF_TYPE && (window2.jQuery || window2.Zepto);
1300
+ if ($ && !$.ua) {
1301
+ var parser = new UAParser2();
1302
+ $.ua = parser.getResult();
1303
+ $.ua.get = function() {
1304
+ return parser.getUA();
1305
+ };
1306
+ $.ua.set = function(ua) {
1307
+ parser.setUA(ua);
1308
+ var result = parser.getResult();
1309
+ for (var prop in result) {
1310
+ $.ua[prop] = result[prop];
1311
+ }
1312
+ };
1313
+ }
1314
+ })(typeof window === "object" ? window : exports);
1315
+ }
1316
+ });
1317
+
1318
+ // src/global.ts
1319
+ var global_exports = {};
1320
+ __export(global_exports, {
1321
+ addPlayer: () => addPlayer,
1322
+ autoDiscoverPlayers: () => autoDiscoverPlayers,
1323
+ initTracking: () => initTracking,
1324
+ removePlayer: () => removePlayer,
1325
+ stopTracking: () => stopTracking
1326
+ });
1327
+
1328
+ // src/lib/internal-events.ts
1329
+ var InternalEvent = ((InternalEvent2) => {
1330
+ InternalEvent2["PageView"] = "mpulse:" + "PageView" /* PageView */;
1331
+ InternalEvent2["MediaView"] = "mpulse:" + "MediaView" /* MediaView */;
1332
+ InternalEvent2["MediaReady"] = "mpulse:" + "MediaReady" /* MediaReady */;
1333
+ InternalEvent2["MediaPlay"] = "mpulse:" + "MediaPlay" /* MediaPlay */;
1334
+ InternalEvent2["MediaPause"] = "mpulse:" + "MediaPause" /* MediaPause */;
1335
+ InternalEvent2["MediaResume"] = "mpulse:" + "MediaResume" /* MediaResume */;
1336
+ InternalEvent2["MediaBuffer"] = "mpulse:" + "MediaBuffer" /* MediaBuffer */;
1337
+ InternalEvent2["MediaStop"] = "mpulse:" + "MediaStop" /* MediaStop */;
1338
+ InternalEvent2["MediaEnd"] = "mpulse:" + "MediaEnd" /* MediaEnd */;
1339
+ InternalEvent2["MediaAdStart"] = "mpulse:" + "MediaAdStart" /* MediaAdStart */;
1340
+ InternalEvent2["MediaAdEnd"] = "mpulse:" + "MediaAdEnd" /* MediaAdEnd */;
1341
+ InternalEvent2["MediaAdError"] = "mpulse:" + "MediaAdError" /* MediaAdError */;
1342
+ InternalEvent2["MediaAdSkip"] = "mpulse:" + "MediaAdSkip" /* MediaAdSkip */;
1343
+ return InternalEvent2;
1344
+ })(InternalEvent || {});
1345
+ function dispatchInternalEvent(event) {
1346
+ Object.entries(InternalEvent).forEach(([key, value]) => {
1347
+ if (key == event.event.name) {
1348
+ document.dispatchEvent(new CustomEvent(value, { detail: event }));
1349
+ }
1350
+ });
1351
+ }
1352
+
1353
+ // node_modules/uuid/dist/esm-browser/rng.js
1354
+ var getRandomValues;
1355
+ var rnds8 = new Uint8Array(16);
1356
+ function rng() {
1357
+ if (!getRandomValues) {
1358
+ getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
1359
+ if (!getRandomValues) {
1360
+ throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
1361
+ }
1362
+ }
1363
+ return getRandomValues(rnds8);
1364
+ }
1365
+
1366
+ // node_modules/uuid/dist/esm-browser/regex.js
1367
+ var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
1368
+
1369
+ // node_modules/uuid/dist/esm-browser/validate.js
1370
+ function validate(uuid) {
1371
+ return typeof uuid === "string" && regex_default.test(uuid);
1372
+ }
1373
+ var validate_default = validate;
1374
+
1375
+ // node_modules/uuid/dist/esm-browser/stringify.js
1376
+ var byteToHex = [];
1377
+ for (let i = 0; i < 256; ++i) {
1378
+ byteToHex.push((i + 256).toString(16).slice(1));
1379
+ }
1380
+ function unsafeStringify(arr, offset = 0) {
1381
+ return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
1382
+ }
1383
+
1384
+ // node_modules/uuid/dist/esm-browser/native.js
1385
+ var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
1386
+ var native_default = {
1387
+ randomUUID
1388
+ };
1389
+
1390
+ // node_modules/uuid/dist/esm-browser/v4.js
1391
+ function v4(options, buf, offset) {
1392
+ if (native_default.randomUUID && !buf && !options) {
1393
+ return native_default.randomUUID();
1394
+ }
1395
+ options = options || {};
1396
+ const rnds = options.random || (options.rng || rng)();
1397
+ rnds[6] = rnds[6] & 15 | 64;
1398
+ rnds[8] = rnds[8] & 63 | 128;
1399
+ if (buf) {
1400
+ offset = offset || 0;
1401
+ for (let i = 0; i < 16; ++i) {
1402
+ buf[offset + i] = rnds[i];
1403
+ }
1404
+ return buf;
1405
+ }
1406
+ return unsafeStringify(rnds);
1407
+ }
1408
+ var v4_default = v4;
1409
+
1410
+ // src/lib/request.ts
1411
+ var import_ua_parser_js = __toESM(require_ua_parser(), 1);
1412
+
1413
+ // src/config.ts
1414
+ var requestDelay = 10 * 1e3;
1415
+ var eventDefaultThrottleDelay = 5e3;
1416
+
1417
+ // src/lib/event-handler.ts
1418
+ var EventHandler = class {
1419
+ constructor(trackingUrl, throttleDelays = {}) {
1420
+ this.throttles = {};
1421
+ this.eventsStack = [];
1422
+ this.throttle = (key, callback, delay) => {
1423
+ if (!this.throttles[key]) {
1424
+ callback();
1425
+ this.throttles[key] = true;
1426
+ setTimeout(() => {
1427
+ this.throttles[key] = false;
1428
+ }, delay);
1429
+ }
1430
+ };
1431
+ this.trackingUrl = trackingUrl;
1432
+ this.throttleDelays = throttleDelays;
1433
+ this.requestInterval = window.setInterval(() => {
1434
+ if (this.eventsStack.length > 0) {
1435
+ this.sendEvents();
1436
+ }
1437
+ }, requestDelay);
1438
+ }
1439
+ pushEvent(event) {
1440
+ this.throttle(
1441
+ event.event.type + event.event.name + event.page.url + event.player?.play_id,
1442
+ () => {
1443
+ this.eventsStack.push(event);
1444
+ dispatchInternalEvent(event);
1445
+ },
1446
+ this.throttleDelays[event.event.name] || eventDefaultThrottleDelay
1447
+ );
1448
+ }
1449
+ addThrottleDelays(throttleDelays) {
1450
+ this.throttleDelays = { ...this.throttleDelays, ...throttleDelays };
1451
+ }
1452
+ async sendEvents() {
1453
+ const events = this.eventsStack;
1454
+ this.eventsStack = [];
1455
+ return sendEventsRequest(this.trackingUrl, events).catch((error) => {
1456
+ this.eventsStack = events.concat(this.eventsStack);
1457
+ console.error(error);
1458
+ });
1459
+ }
1460
+ destroy() {
1461
+ clearInterval(this.requestInterval);
1462
+ }
1463
+ };
1464
+
1465
+ // src/lib/utils.ts
1466
+ function getEventHandler(trackingUrl, throttleDelays = {}) {
1467
+ if (typeof window !== "undefined" && window.mpulse?.eventHandler) {
1468
+ if (throttleDelays && Object.keys(throttleDelays).length > 0) {
1469
+ window.mpulse.eventHandler.addThrottleDelays(throttleDelays);
1470
+ }
1471
+ return window.mpulse.eventHandler;
1472
+ }
1473
+ const handler = new EventHandler(trackingUrl, throttleDelays);
1474
+ if (typeof window !== "undefined" && window.mpulse) {
1475
+ window.mpulse.eventHandler = handler;
1476
+ }
1477
+ return handler;
1478
+ }
1479
+ function getPageMetaGetter() {
1480
+ if (typeof window !== "undefined" && typeof window.mpulse?.pageMetaGetter === "function") {
1481
+ return window.mpulse.pageMetaGetter;
1482
+ }
1483
+ return () => ({});
1484
+ }
1485
+ function getUserGetter() {
1486
+ if (typeof window !== "undefined" && typeof window.mpulse?.userGetter === "function") {
1487
+ return window.mpulse.userGetter;
1488
+ }
1489
+ return () => ({});
1490
+ }
1491
+
1492
+ // src/lib/session.ts
1493
+ function persistSession(session) {
1494
+ if (session.session_id) {
1495
+ setSessionId(session.session_id);
1496
+ }
1497
+ if (session.user_id) {
1498
+ setUserId(session.user_id);
1499
+ }
1500
+ if (session.device_id) {
1501
+ setDeviceId(session.device_id);
1502
+ }
1503
+ }
1504
+ function getUser() {
1505
+ const user = getUserGetter()() || {};
1506
+ return {
1507
+ ...user,
1508
+ id: user.id?.toString() || getUserId()
1509
+ };
1510
+ }
1511
+ var keys = {
1512
+ sessionId: "_goti_sid",
1513
+ userId: "_goti_uid",
1514
+ deviceId: "_goti_did"
1515
+ };
1516
+ function getIdFromSession(key) {
1517
+ const id = sessionStorage.getItem(key);
1518
+ if (id && validate_default(id)) {
1519
+ return id;
1520
+ }
1521
+ return void 0;
1522
+ }
1523
+ function getIdFromLocalStorage(key) {
1524
+ const id = localStorage.getItem(key);
1525
+ if (id && validate_default(id)) {
1526
+ return id;
1527
+ }
1528
+ return void 0;
1529
+ }
1530
+ function getSessionId() {
1531
+ return getIdFromSession(keys.sessionId);
1532
+ }
1533
+ function getUserId() {
1534
+ return getIdFromLocalStorage(keys.userId);
1535
+ }
1536
+ function getDeviceId() {
1537
+ return getIdFromLocalStorage(keys.deviceId);
1538
+ }
1539
+ function setSessionId(sessionId) {
1540
+ sessionStorage.setItem(keys.sessionId, sessionId);
1541
+ }
1542
+ function setUserId(userId) {
1543
+ localStorage.setItem(keys.userId, userId);
1544
+ }
1545
+ function setDeviceId(deviceId) {
1546
+ localStorage.setItem(keys.deviceId, deviceId);
1547
+ }
1548
+
1549
+ // src/lib/request.ts
1550
+ var lastRequestSentAt = 0;
1551
+ async function sendRequest(url, payload) {
1552
+ lastRequestSentAt = Date.now();
1553
+ const res = await fetch(url, {
1554
+ method: "POST",
1555
+ body: JSON.stringify(payload)
1556
+ });
1557
+ const data = await res.json();
1558
+ if (!res.ok || !data) {
1559
+ throw new Error(data?.message || res.statusText);
1560
+ }
1561
+ if (data.session) {
1562
+ persistSession(data.session);
1563
+ }
1564
+ return data;
1565
+ }
1566
+ function newRequestBody() {
1567
+ const uaParser = new import_ua_parser_js.UAParser();
1568
+ const ua = uaParser.getResult();
1569
+ return {
1570
+ session_id: getSessionId(),
1571
+ user: getUser(),
1572
+ device: {
1573
+ id: getDeviceId(),
1574
+ type: ua.device.type || getDeviceType(),
1575
+ os: ua.os.name,
1576
+ os_version: ua.os.version,
1577
+ browser: ua.browser.name,
1578
+ browser_version: ua.browser.version,
1579
+ width: window.screen.width,
1580
+ height: window.screen.height,
1581
+ brand: ua.device.vendor,
1582
+ model: ua.device.model,
1583
+ architecture: ua.cpu.architecture
1584
+ }
1585
+ };
1586
+ }
1587
+ function getDeviceType() {
1588
+ const userAgent = navigator.userAgent;
1589
+ const isTV = /(SMART-TV|SmartTV|Television|Internet.TV|NetCast|Tizen|WebTV|AppleTV|boxee|Kylo|Roku|DroidTV|SonyDTV|Xbox|IPTV|GoogleTV|CE-HTML)/i.test(
1590
+ userAgent
1591
+ );
1592
+ const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
1593
+ const isTablet = /iPad|Android/i.test(userAgent) && window.screen.width >= 768;
1594
+ const isDesktop = !isMobile && !isTablet && window.screen.width >= 1024;
1595
+ if (isTV) {
1596
+ return "tv";
1597
+ } else if (isTablet) {
1598
+ return "tablet";
1599
+ } else if (isMobile) {
1600
+ return "mobile";
1601
+ } else if (isDesktop) {
1602
+ return "desktop";
1603
+ }
1604
+ return "unknown";
1605
+ }
1606
+ async function sendPingRequest(trackingUrl) {
1607
+ return sendRequest(trackingUrl + "/ping", newRequestBody());
1608
+ }
1609
+ async function sendEventsRequest(trackingUrl, events) {
1610
+ const payload = newRequestBody();
1611
+ payload.events = events;
1612
+ return sendRequest(trackingUrl + "/events", payload);
1613
+ }
1614
+
1615
+ // src/lib/ping.ts
1616
+ var pingIntervals = /* @__PURE__ */ new Map();
1617
+ function enablePing(trackingUrl, delay = 15) {
1618
+ if (pingIntervals.has(trackingUrl)) {
1619
+ return;
1620
+ }
1621
+ pingIntervals.set(
1622
+ trackingUrl,
1623
+ window.setInterval(() => {
1624
+ if (Date.now() - lastRequestSentAt > delay * 1e3) {
1625
+ sendPingRequest(trackingUrl);
1626
+ }
1627
+ }, 5e3)
1628
+ );
1629
+ }
1630
+
1631
+ // src/page/performance.ts
1632
+ function calculatePageLoadTime() {
1633
+ const timing = window.performance.timing;
1634
+ if (!timing) {
1635
+ return 0;
1636
+ }
1637
+ return (timing.loadEventEnd || Date.now()) - timing.navigationStart;
1638
+ }
1639
+ function calculateFCP() {
1640
+ const entries = window.performance.getEntriesByType("paint");
1641
+ const fcpEntry = entries.find((entry) => entry.name === "first-contentful-paint");
1642
+ return fcpEntry ? Math.round(fcpEntry.startTime) : 0;
1643
+ }
1644
+ function calculatePageSize() {
1645
+ return Math.round(
1646
+ window.performance.getEntriesByType("resource").reduce(
1647
+ (size, resource) => size + (("transferSize" in resource ? resource.transferSize : 0) || 0),
1648
+ 0
1649
+ ) / 1024
1650
+ );
1651
+ }
1652
+ function calculateNumberOfRequests() {
1653
+ return window.performance.getEntriesByType("resource").length;
1654
+ }
1655
+ function calculateDNSLookupTime() {
1656
+ const timing = window.performance.timing;
1657
+ if (!timing) {
1658
+ return 0;
1659
+ }
1660
+ return Math.round(timing.domainLookupEnd - timing.domainLookupStart);
1661
+ }
1662
+ function calculateTTFB() {
1663
+ const timing = window.performance.timing;
1664
+ if (!timing) {
1665
+ return 0;
1666
+ }
1667
+ return Math.round(timing.responseStart - timing.requestStart);
1668
+ }
1669
+ function getPerformanceData() {
1670
+ return {
1671
+ pageLoadTime: calculatePageLoadTime(),
1672
+ fcp: calculateFCP(),
1673
+ pageSize: calculatePageSize(),
1674
+ numberOfRequests: calculateNumberOfRequests(),
1675
+ dnsLookupTime: calculateDNSLookupTime(),
1676
+ ttfb: calculateTTFB()
1677
+ };
1678
+ }
1679
+
1680
+ // src/page/utils.ts
1681
+ function getPageInfo() {
1682
+ const perf = getPerformanceData();
1683
+ const meta = getPageMetaGetter()() || {};
1684
+ return {
1685
+ title: document.title,
1686
+ url: window.location.href,
1687
+ referrer: document.referrer,
1688
+ scroll_x: window.scrollX > 0 ? Math.round(window.scrollX) : 0,
1689
+ // Some browser returns negative value
1690
+ scroll_y: window.scrollY > 0 ? Math.round(window.scrollY) : 0,
1691
+ // Performance
1692
+ size: perf.pageSize,
1693
+ load_time: perf.pageLoadTime,
1694
+ dns_lt: perf.dnsLookupTime,
1695
+ ttfb: perf.ttfb,
1696
+ fcp: perf.fcp,
1697
+ requests: perf.numberOfRequests,
1698
+ // Meta
1699
+ ...meta
1700
+ };
1701
+ }
1702
+
1703
+ // src/media/events.ts
1704
+ var mediaEventThrottleDelays = {
1705
+ MediaProgress: 1e3 * 10
1706
+ // 10 seconds
1707
+ };
1708
+ var nativeEvents = {
1709
+ loadstart: "MediaView" /* MediaView */,
1710
+ canplay: "MediaReady" /* MediaReady */,
1711
+ abort: "MediaStop" /* MediaStop */,
1712
+ ended: "MediaEnd" /* MediaEnd */,
1713
+ error: "MediaError" /* MediaError */,
1714
+ pause: "MediaPause" /* MediaPause */,
1715
+ play: "MediaPlay" /* MediaPlay */,
1716
+ ratechange: "MediaSpeedChange" /* MediaSpeedChange */,
1717
+ seeked: "MediaSeek" /* MediaSeek */,
1718
+ timeupdate: "MediaProgress" /* MediaProgress */,
1719
+ volumechange: "MediaVolume" /* MediaVolume */,
1720
+ waiting: "MediaBuffer" /* MediaBuffer */
1721
+ };
1722
+ var imaAdEvents = {
1723
+ start: "MediaAdStart" /* MediaAdStart */,
1724
+ skip: "MediaAdSkip" /* MediaAdSkip */,
1725
+ complete: "MediaAdEnd" /* MediaAdEnd */,
1726
+ adError: "MediaAdError" /* MediaAdError */
1727
+ };
1728
+
1729
+ // src/media/utils.ts
1730
+ function getMediaEventNameFromNativeEvent(type) {
1731
+ if (type in nativeEvents) {
1732
+ return nativeEvents[type];
1733
+ }
1734
+ if (type in imaAdEvents) {
1735
+ return imaAdEvents[type];
1736
+ }
1737
+ return type;
1738
+ }
1739
+
1740
+ // src/media/players/helpers/loaded-time-calculator.ts
1741
+ var VideoLoadedTimeClaculator = class {
1742
+ constructor(element) {
1743
+ this.element = element;
1744
+ this.initialLoadedTime = 0;
1745
+ this.loadedTime = 0;
1746
+ this.updateInitialLoadedTime = this.updateInitialLoadedTime.bind(this);
1747
+ this.updateLoadedTime = this.updateLoadedTime.bind(this);
1748
+ this.element.addEventListener("loadedmetadata", this.updateInitialLoadedTime);
1749
+ this.element.addEventListener("progress", this.updateLoadedTime);
1750
+ }
1751
+ dispose() {
1752
+ this.element.removeEventListener("loadedmetadata", this.updateInitialLoadedTime);
1753
+ this.element.removeEventListener("progress", this.updateLoadedTime);
1754
+ }
1755
+ getLoadedTime() {
1756
+ return this.loadedTime;
1757
+ }
1758
+ getTotalLoadedTime() {
1759
+ let total = 0;
1760
+ for (let i = 0; i < this.element.buffered.length; i++) {
1761
+ total += this.element.buffered.end(i) - this.element.buffered.start(i);
1762
+ }
1763
+ return total;
1764
+ }
1765
+ updateInitialLoadedTime() {
1766
+ this.initialLoadedTime = this.getTotalLoadedTime();
1767
+ }
1768
+ updateLoadedTime() {
1769
+ const currentTimeLoaded = this.getTotalLoadedTime();
1770
+ const timeLoadedSinceStart = currentTimeLoaded - this.initialLoadedTime;
1771
+ if (timeLoadedSinceStart > 0) {
1772
+ this.loadedTime = timeLoadedSinceStart;
1773
+ }
1774
+ }
1775
+ };
1776
+
1777
+ // src/media/players/helpers/frame-rate-calculator.ts
1778
+ var VideoFrameRateCalculator = class {
1779
+ constructor(element) {
1780
+ this.element = element;
1781
+ this.lastMediaTime = 0;
1782
+ this.lastFrameNum = 0;
1783
+ this.fps = 0;
1784
+ this.fpsRounder = [];
1785
+ this.frameNotSeeked = true;
1786
+ this.ticker = this.ticker.bind(this);
1787
+ this.onSeeked = this.onSeeked.bind(this);
1788
+ this.element.addEventListener("seeked", this.onSeeked);
1789
+ if ("requestVideoFrameCallback" in HTMLVideoElement.prototype) {
1790
+ this.element.requestVideoFrameCallback(this.ticker);
1791
+ }
1792
+ }
1793
+ dispose() {
1794
+ this.element.removeEventListener("seeked", this.onSeeked);
1795
+ }
1796
+ getFrameRate() {
1797
+ return this.fps;
1798
+ }
1799
+ ticker(_, metadata) {
1800
+ const mediaTimeDiff = Math.abs(metadata.mediaTime - this.lastMediaTime);
1801
+ const frameNumDiff = Math.abs(metadata.presentedFrames - this.lastFrameNum);
1802
+ const diff = mediaTimeDiff / frameNumDiff;
1803
+ if (diff && diff < 1 && this.frameNotSeeked && this.fpsRounder.length < 50 && this.element.playbackRate === 1 && document.hasFocus()) {
1804
+ this.fpsRounder.push(diff);
1805
+ this.fps = Math.round(1 / this.getFpsAverage());
1806
+ }
1807
+ this.frameNotSeeked = true;
1808
+ this.lastMediaTime = metadata.mediaTime;
1809
+ this.lastFrameNum = metadata.presentedFrames;
1810
+ this.element.requestVideoFrameCallback(this.ticker);
1811
+ }
1812
+ onSeeked() {
1813
+ this.fpsRounder.pop();
1814
+ this.frameNotSeeked = false;
1815
+ }
1816
+ getFpsAverage() {
1817
+ return this.fpsRounder.reduce((a, b) => a + b, 0) / this.fpsRounder.length;
1818
+ }
1819
+ };
1820
+
1821
+ // src/media/players/helpers/bitrate-calculator.ts
1822
+ var VideoBitrateCalculator = class {
1823
+ constructor(element) {
1824
+ this.element = element;
1825
+ this.loadVideoBitrate = this.loadVideoBitrate.bind(this);
1826
+ this.element.addEventListener("loadedmetadata", this.loadVideoBitrate);
1827
+ }
1828
+ dispose() {
1829
+ this.element.removeEventListener("loadedmetadata", this.loadVideoBitrate);
1830
+ }
1831
+ getBitrate() {
1832
+ return this.currentBitrate;
1833
+ }
1834
+ loadVideoBitrate() {
1835
+ const duration = this.element.duration;
1836
+ const src = this.element.currentSrc;
1837
+ if (!duration || !src) {
1838
+ return;
1839
+ }
1840
+ const srcType = this.getSrcType(src);
1841
+ if (!srcType || !["video/mp4", "video/webm", "video/ogg", "audio/mpeg", "audio/ogg", "audio/wav"].includes(srcType)) {
1842
+ return;
1843
+ }
1844
+ this.fetchVideoBitrate(src, duration).then((bitrate) => {
1845
+ this.currentBitrate = bitrate;
1846
+ console.log("Loaded media bitrate:", bitrate);
1847
+ });
1848
+ }
1849
+ async fetchVideoBitrate(url, duration) {
1850
+ return fetch(url, { method: "HEAD" }).then((response) => response.headers.get("content-length")).then((size) => {
1851
+ if (!size) return void 0;
1852
+ return Number(size) * 8 / duration;
1853
+ }).catch((error) => {
1854
+ console.log("Error fetching video bitrate", error);
1855
+ return void 0;
1856
+ });
1857
+ }
1858
+ getSrcType(src) {
1859
+ const type = this.element.querySelector('source[src="' + src + '"]')?.getAttribute("type");
1860
+ if (type) {
1861
+ return type;
1862
+ }
1863
+ const extension = src.split(".").pop()?.split("?")[0];
1864
+ if (extension) {
1865
+ return this.element.tagName.toLowerCase() + "/" + extension;
1866
+ }
1867
+ }
1868
+ };
1869
+
1870
+ // src/media/players/html.ts
1871
+ var HTMLMediaPlayer = class {
1872
+ constructor(element) {
1873
+ this.name = "HTML5";
1874
+ this.version = "1.0.0";
1875
+ this.eventListener = (event) => {
1876
+ if (this.onEvent) {
1877
+ const eventName = getMediaEventNameFromNativeEvent(event.type);
1878
+ this.onEvent(eventName, event);
1879
+ }
1880
+ };
1881
+ if (typeof element === "string") {
1882
+ this.element = document.querySelector(element);
1883
+ } else {
1884
+ this.element = element;
1885
+ }
1886
+ if (!this.element || !(this.element instanceof HTMLMediaElement)) {
1887
+ throw new Error("Invalid element, must be an HTMLMediaElement.");
1888
+ }
1889
+ this.addEventListeners();
1890
+ if (this.element instanceof HTMLVideoElement) {
1891
+ this.bitrateCalculator = new VideoBitrateCalculator(this.element);
1892
+ this.frameRateCalculator = new VideoFrameRateCalculator(this.element);
1893
+ this.loadedTimeCalculator = new VideoLoadedTimeClaculator(this.element);
1894
+ }
1895
+ }
1896
+ addEventListeners() {
1897
+ Object.keys(nativeEvents).forEach((key) => {
1898
+ this.element.addEventListener(key, this.eventListener);
1899
+ });
1900
+ }
1901
+ removeEventListeners() {
1902
+ Object.keys(nativeEvents).forEach((key) => {
1903
+ this.element.removeEventListener(key, this.eventListener);
1904
+ });
1905
+ }
1906
+ dispose() {
1907
+ this.removeEventListeners();
1908
+ this.bitrateCalculator?.dispose();
1909
+ this.frameRateCalculator?.dispose();
1910
+ this.loadedTimeCalculator?.dispose();
1911
+ }
1912
+ getMediaDuration() {
1913
+ return this.element.duration;
1914
+ }
1915
+ getMediaCurrentTime() {
1916
+ return this.element.currentTime;
1917
+ }
1918
+ getMediaId() {
1919
+ if (this.element.dataset.mediaId) {
1920
+ return this.element.dataset.mediaId;
1921
+ }
1922
+ if (this.element.dataset.id) {
1923
+ return this.element.dataset.id;
1924
+ }
1925
+ return void 0;
1926
+ }
1927
+ getMediaTitle() {
1928
+ if (this.element.dataset.mediaTitle) {
1929
+ return this.element.dataset.mediaTitle;
1930
+ }
1931
+ if (this.element.dataset.title) {
1932
+ return this.element.dataset.title;
1933
+ }
1934
+ if (this.element.title) {
1935
+ return this.element.title;
1936
+ }
1937
+ if (document.title) {
1938
+ return document.title;
1939
+ }
1940
+ return void 0;
1941
+ }
1942
+ getMediaType() {
1943
+ if (this.element.dataset.mediaType) {
1944
+ return this.element.dataset.mediaType;
1945
+ }
1946
+ if (this.element.dataset.type) {
1947
+ return this.element.dataset.type;
1948
+ }
1949
+ if (this.element.hasAttribute("type")) {
1950
+ return this.element.getAttribute("type") || void 0;
1951
+ }
1952
+ return void 0;
1953
+ }
1954
+ getMediaSrc() {
1955
+ if (this.element.dataset.mediaSrc) {
1956
+ return this.element.dataset.mediaSrc;
1957
+ }
1958
+ if (this.element.dataset.src) {
1959
+ return this.element.dataset.src;
1960
+ }
1961
+ if (this.element.currentSrc) {
1962
+ return this.element.currentSrc;
1963
+ }
1964
+ if (this.element.src) {
1965
+ return this.element.src;
1966
+ }
1967
+ return void 0;
1968
+ }
1969
+ getMediaWidth() {
1970
+ if (this.element.dataset.mediaWidth) {
1971
+ return Number(this.element.dataset.mediaWidth);
1972
+ }
1973
+ if (this.element.dataset.width) {
1974
+ return Number(this.element.dataset.width);
1975
+ }
1976
+ if (this.element instanceof HTMLVideoElement && this.element.videoWidth) {
1977
+ return this.element.videoWidth;
1978
+ }
1979
+ return void 0;
1980
+ }
1981
+ getMediaHeight() {
1982
+ if (this.element.dataset.mediaHeight) {
1983
+ return Number(this.element.dataset.mediaHeight);
1984
+ }
1985
+ if (this.element.dataset.height) {
1986
+ return Number(this.element.dataset.height);
1987
+ }
1988
+ if (this.element instanceof HTMLVideoElement && this.element.videoHeight) {
1989
+ return this.element.videoHeight;
1990
+ }
1991
+ return void 0;
1992
+ }
1993
+ getMediaPoster() {
1994
+ if (this.element.dataset.mediaPoster) {
1995
+ return this.element.dataset.mediaPoster;
1996
+ }
1997
+ if (this.element.dataset.poster) {
1998
+ return this.element.dataset.poster;
1999
+ }
2000
+ if (this.element instanceof HTMLVideoElement && this.element.poster) {
2001
+ return this.element.poster;
2002
+ }
2003
+ if (this.element.hasAttribute("poster")) {
2004
+ return this.element.getAttribute("poster") || void 0;
2005
+ }
2006
+ return void 0;
2007
+ }
2008
+ getMediaSeries() {
2009
+ if (this.element.dataset.mediaSeries) {
2010
+ return this.element.dataset.mediaSeries;
2011
+ }
2012
+ if (this.element.dataset.series) {
2013
+ return this.element.dataset.series;
2014
+ }
2015
+ if (this.element.hasAttribute("series")) {
2016
+ return this.element.getAttribute("series") || void 0;
2017
+ }
2018
+ return void 0;
2019
+ }
2020
+ getMediaSeason() {
2021
+ if (this.element.dataset.mediaSeason) {
2022
+ return this.element.dataset.mediaSeason;
2023
+ }
2024
+ if (this.element.dataset.season) {
2025
+ return this.element.dataset.season;
2026
+ }
2027
+ if (this.element.hasAttribute("season")) {
2028
+ return this.element.getAttribute("season") || void 0;
2029
+ }
2030
+ return void 0;
2031
+ }
2032
+ getMediaVolume() {
2033
+ return this.element.volume;
2034
+ }
2035
+ getMediaMuted() {
2036
+ return this.element.muted;
2037
+ }
2038
+ getMediaPlaybackRate() {
2039
+ return this.element.playbackRate;
2040
+ }
2041
+ getMediaFullscreen() {
2042
+ return document.fullscreenElement === this.element;
2043
+ }
2044
+ getMediaError() {
2045
+ if (!this.element.error) return void 0;
2046
+ return {
2047
+ type: this.element.error.constructor.name,
2048
+ code: this.element.error.code,
2049
+ message: this.element.error.message
2050
+ };
2051
+ }
2052
+ getMediaBitrate() {
2053
+ if (this.element.dataset.mediaBitrate) {
2054
+ return parseInt(this.element.dataset.mediaBitrate);
2055
+ }
2056
+ if (this.element.dataset.bitrate) {
2057
+ return parseInt(this.element.dataset.bitrate);
2058
+ }
2059
+ return this.bitrateCalculator?.getBitrate();
2060
+ }
2061
+ getMediaFramerate() {
2062
+ return this.frameRateCalculator?.getFrameRate();
2063
+ }
2064
+ getMediaLoadedTime() {
2065
+ return this.loadedTimeCalculator?.getLoadedTime();
2066
+ }
2067
+ getPlayerWidth() {
2068
+ return this.element.clientWidth;
2069
+ }
2070
+ getPlayerHeight() {
2071
+ return this.element.clientHeight;
2072
+ }
2073
+ getMediaMeta1() {
2074
+ return this.element.dataset.mediaMeta1 ?? this.element.dataset.meta1;
2075
+ }
2076
+ getMediaMeta2() {
2077
+ return this.element.dataset.mediaMeta2 ?? this.element.dataset.meta2;
2078
+ }
2079
+ getMediaMeta3() {
2080
+ return this.element.dataset.mediaMeta3 ?? this.element.dataset.meta3;
2081
+ }
2082
+ getMediaMeta4() {
2083
+ return this.element.dataset.mediaMeta4 ?? this.element.dataset.meta4;
2084
+ }
2085
+ getMediaMeta5() {
2086
+ return this.element.dataset.mediaMeta5 ?? this.element.dataset.meta5;
2087
+ }
2088
+ };
2089
+
2090
+ // src/media/analytics.ts
2091
+ var MediaAnalytics = class {
2092
+ constructor(options) {
2093
+ this.players = [];
2094
+ this.playbacks = /* @__PURE__ */ new Map();
2095
+ this.preEventSerializers = {
2096
+ ["MediaView" /* MediaView */]: ({ event, mediaId }) => {
2097
+ const prevPlayback = this.playbacks.get(mediaId);
2098
+ const isDuplicateEvent = prevPlayback && Date.now() - prevPlayback.firstEventTime < 1e3 * 5;
2099
+ if (isDuplicateEvent) {
2100
+ return { event, skip: true };
2101
+ }
2102
+ this.playbacks.set(mediaId, {
2103
+ playId: this.getPlaybackPlayId(),
2104
+ firstPlay: true,
2105
+ firstReady: true,
2106
+ status: void 0,
2107
+ watchTime: 0,
2108
+ buffer: {
2109
+ start: Date.now(),
2110
+ end: void 0
2111
+ },
2112
+ firstEventTime: Date.now(),
2113
+ lastEventTime: Date.now()
2114
+ });
2115
+ return { event };
2116
+ },
2117
+ ["MediaReady" /* MediaReady */]: ({ event, mediaId }) => {
2118
+ this.updatePlayback(mediaId, {
2119
+ buffer: {
2120
+ end: Date.now()
2121
+ }
2122
+ });
2123
+ return { event };
2124
+ },
2125
+ ["MediaPlay" /* MediaPlay */]: ({ event, mediaId }) => {
2126
+ if (this.playbacks.get(mediaId)?.status) {
2127
+ event.event.name = "MediaResume" /* MediaResume */;
2128
+ this.updatePlayback(mediaId, {
2129
+ status: "playing",
2130
+ firstPlay: false
2131
+ });
2132
+ } else {
2133
+ this.updatePlayback(mediaId, {
2134
+ status: "playing"
2135
+ });
2136
+ }
2137
+ return { event };
2138
+ },
2139
+ ["MediaPause" /* MediaPause */]: ({ event, mediaId }) => {
2140
+ this.updatePlayback(mediaId, {
2141
+ status: "paused"
2142
+ });
2143
+ return { event };
2144
+ },
2145
+ ["MediaBuffer" /* MediaBuffer */]: ({ event, mediaId }) => {
2146
+ this.updatePlayback(mediaId, {
2147
+ buffer: {
2148
+ start: Date.now(),
2149
+ end: void 0
2150
+ }
2151
+ });
2152
+ return { event, skip: true };
2153
+ },
2154
+ ["MediaStop" /* MediaStop */]: ({ event, mediaId }) => {
2155
+ this.updatePlayback(mediaId, {
2156
+ status: "paused"
2157
+ });
2158
+ return { event };
2159
+ },
2160
+ ["MediaEnd" /* MediaEnd */]: ({ event, mediaId }) => {
2161
+ this.updatePlayback(mediaId, {
2162
+ status: "ended"
2163
+ });
2164
+ return { event };
2165
+ }
2166
+ };
2167
+ this.postEventSerializers = {
2168
+ ["MediaReady" /* MediaReady */]: ({ event, mediaId }) => {
2169
+ if (!this.playbacks.get(mediaId)?.firstReady) {
2170
+ event.event.name = "MediaBuffer" /* MediaBuffer */;
2171
+ }
2172
+ this.updatePlayback(mediaId, {
2173
+ firstReady: false,
2174
+ buffer: {
2175
+ start: void 0,
2176
+ end: void 0
2177
+ }
2178
+ });
2179
+ return { event, skip: (event.media.buffer_time || 0) < 50 };
2180
+ }
2181
+ };
2182
+ this.options = options;
2183
+ this.eventHandler = getEventHandler(options.trackingUrl, mediaEventThrottleDelays);
2184
+ enablePing(this.options.trackingUrl);
2185
+ }
2186
+ startWatchTimeCounting() {
2187
+ if (this.watchTimeInterval) {
2188
+ return;
2189
+ }
2190
+ this.watchTimeInterval = window.setInterval(() => {
2191
+ this.playbacks.forEach((playback, mediaId) => {
2192
+ if (playback.status === "playing") {
2193
+ this.playbacks.set(mediaId, {
2194
+ ...playback,
2195
+ watchTime: playback.watchTime + 1
2196
+ });
2197
+ }
2198
+ });
2199
+ }, 1e3);
2200
+ }
2201
+ stopWatchTimeCounting() {
2202
+ if (this.watchTimeInterval) {
2203
+ clearInterval(this.watchTimeInterval);
2204
+ this.watchTimeInterval = void 0;
2205
+ }
2206
+ }
2207
+ afterNewPlayerAdded() {
2208
+ if (this.players.length > 0) {
2209
+ this.startWatchTimeCounting();
2210
+ }
2211
+ }
2212
+ afterPlayerRemoved() {
2213
+ if (this.players.length === 0) {
2214
+ this.stopWatchTimeCounting();
2215
+ }
2216
+ }
2217
+ addPlayer(player, uid = void 0, autoDiscovered = false) {
2218
+ const playerObj = player instanceof HTMLMediaPlayer ? player : new HTMLMediaPlayer(player);
2219
+ this.players.push({
2220
+ uid: uid || Math.random().toString(36).substr(2, 9),
2221
+ player: playerObj,
2222
+ autoDiscovered
2223
+ });
2224
+ playerObj.onEvent = (type) => {
2225
+ this.pushRegularEvent(playerObj, type);
2226
+ };
2227
+ this.afterNewPlayerAdded();
2228
+ return playerObj;
2229
+ }
2230
+ removePlayer(player) {
2231
+ const index = typeof player === "string" ? this.players.findIndex((p) => p.uid === player) : this.players.findIndex((p) => p.player === player);
2232
+ if (index <= -1) {
2233
+ console.error("Failed to dispose player, the player was not found.");
2234
+ return;
2235
+ }
2236
+ this.players[index].player.dispose();
2237
+ this.players.splice(index, 1);
2238
+ this.afterPlayerRemoved();
2239
+ }
2240
+ removeAllPlayers() {
2241
+ this.players.forEach((entry) => {
2242
+ entry.player.dispose();
2243
+ });
2244
+ this.players = [];
2245
+ this.afterPlayerRemoved();
2246
+ }
2247
+ autoDiscoverPlayers() {
2248
+ this.players.filter((p) => {
2249
+ if (p.autoDiscovered) {
2250
+ p.player.dispose();
2251
+ return false;
2252
+ }
2253
+ return true;
2254
+ });
2255
+ const players = document.querySelectorAll("video, audio");
2256
+ players.forEach((player) => {
2257
+ this.addPlayer(player, player.id, true);
2258
+ });
2259
+ }
2260
+ destroy() {
2261
+ this.players.forEach((entry) => {
2262
+ entry.player.dispose();
2263
+ this.pushRegularEvent(entry.player, "MediaStop" /* MediaStop */);
2264
+ });
2265
+ }
2266
+ pushRegularEvent(player, eventName) {
2267
+ const event = {
2268
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2269
+ event: {
2270
+ type: "media",
2271
+ name: eventName
2272
+ },
2273
+ page: getPageInfo(),
2274
+ player: {
2275
+ name: player.name,
2276
+ version: player.version,
2277
+ width: player.getPlayerWidth(),
2278
+ height: player.getPlayerHeight()
2279
+ },
2280
+ media: {
2281
+ length: Math.round(player.getMediaDuration() || 0),
2282
+ position: Math.round(player.getMediaCurrentTime() || 0),
2283
+ id: player.getMediaId(),
2284
+ title: player.getMediaTitle(),
2285
+ type: player.getMediaType(),
2286
+ src: player.getMediaSrc(),
2287
+ poster: player.getMediaPoster(),
2288
+ width: player.getMediaWidth(),
2289
+ height: player.getMediaHeight(),
2290
+ series: player.getMediaSeries(),
2291
+ season: player.getMediaSeason(),
2292
+ volume: Math.round((player.getMediaVolume() ?? 0) * 100),
2293
+ fullscreen: player.getMediaFullscreen(),
2294
+ bitrate: Math.round(player.getMediaBitrate() || 0),
2295
+ framerate: Math.round(player.getMediaFramerate() || 0),
2296
+ loaded_time: Math.round(player.getMediaLoadedTime() || 0),
2297
+ watch_time: 0,
2298
+ meta_1: player.getMediaMeta1(),
2299
+ meta_2: player.getMediaMeta2(),
2300
+ meta_3: player.getMediaMeta3(),
2301
+ meta_4: player.getMediaMeta4(),
2302
+ meta_5: player.getMediaMeta5()
2303
+ }
2304
+ };
2305
+ if (eventName === "MediaError" /* MediaError */ || eventName === "MediaAdError" /* MediaAdError */) {
2306
+ event.error = player.getMediaError();
2307
+ }
2308
+ this.pushMissedEvents(player, event);
2309
+ const { event: finalEvent, skip = false } = this.beforePushingEvent(event);
2310
+ if (!skip) {
2311
+ this.eventHandler.pushEvent(finalEvent);
2312
+ }
2313
+ }
2314
+ pushMissedEvents(player, event) {
2315
+ const mediaId = this.getMediaUid(event);
2316
+ if (!this.playbacks.has(mediaId) && event.event.name !== "MediaView" /* MediaView */) {
2317
+ this.pushRegularEvent(player, "MediaView" /* MediaView */);
2318
+ }
2319
+ if (this.playbacks.get(mediaId)?.status === void 0 && event.event.name !== "MediaView" /* MediaView */ && event.event.name !== "MediaReady" /* MediaReady */ && event.event.name !== "MediaPlay" /* MediaPlay */) {
2320
+ this.pushRegularEvent(player, "MediaPlay" /* MediaPlay */);
2321
+ }
2322
+ }
2323
+ beforePushingEvent(event) {
2324
+ const preSerialize = this.preEventSerializers[event.event.name];
2325
+ const postSerialize = this.postEventSerializers[event.event.name];
2326
+ const mediaId = this.getMediaUid(event);
2327
+ const pre = preSerialize?.({ event, mediaId }) ?? { event };
2328
+ const playback = this.playbacks.get(mediaId);
2329
+ event.player.play_id = this.getPlaybackPlayId(playback);
2330
+ event.media.watch_time = playback?.watchTime || 0;
2331
+ event.media.buffer_time = this.getPlaybackBufferTime(playback);
2332
+ const post = postSerialize?.({ event: pre.event, mediaId }) ?? { event: pre.event };
2333
+ return { event: post.event, skip: pre.skip || post.skip || false };
2334
+ }
2335
+ getPlaybackBufferTime(playback) {
2336
+ if (!playback?.buffer?.start || !playback?.buffer?.end) {
2337
+ return 0;
2338
+ }
2339
+ if (playback.buffer.end < playback.buffer.start) {
2340
+ return 0;
2341
+ }
2342
+ return playback.buffer.end - playback.buffer.start;
2343
+ }
2344
+ getPlaybackPlayId(playback) {
2345
+ if (!playback) {
2346
+ return v4_default();
2347
+ }
2348
+ return playback.playId;
2349
+ }
2350
+ updatePlayback(mediaId, playback) {
2351
+ const existing = this.playbacks.get(mediaId);
2352
+ const newPlayback = {
2353
+ playId: playback.playId ?? existing?.playId ?? this.getPlaybackPlayId(),
2354
+ firstPlay: playback.firstPlay ?? existing?.firstPlay ?? true,
2355
+ firstReady: playback.firstReady ?? existing?.firstReady ?? true,
2356
+ status: playback.status ?? existing?.status ?? void 0,
2357
+ watchTime: playback.watchTime ?? existing?.watchTime ?? 0,
2358
+ buffer: {
2359
+ start: existing?.buffer?.start,
2360
+ end: existing?.buffer?.end
2361
+ },
2362
+ firstEventTime: existing?.firstEventTime ?? Date.now(),
2363
+ lastEventTime: Date.now()
2364
+ };
2365
+ if (playback.buffer && "start" in playback.buffer) {
2366
+ newPlayback.buffer.start = playback.buffer.start;
2367
+ }
2368
+ if (playback.buffer && "end" in playback.buffer) {
2369
+ newPlayback.buffer.end = playback.buffer.end;
2370
+ }
2371
+ this.playbacks.set(mediaId, newPlayback);
2372
+ return newPlayback;
2373
+ }
2374
+ getMediaUid(event) {
2375
+ return event.media.id ? event.media.id : event.media.title + "" + event.media.src;
2376
+ }
2377
+ };
2378
+
2379
+ // src/page/analytics.ts
2380
+ var PageAnalytics = class {
2381
+ constructor({ hashMode = false, autoTrack = true, ...options }) {
2382
+ this.listeners = {
2383
+ popstate: this.trackPageView,
2384
+ hashchange: this.trackPageView,
2385
+ beforeunload: () => {
2386
+ this.pushRegularEvent("PageExit" /* PageExit */);
2387
+ },
2388
+ scroll: () => {
2389
+ this.eventHandler.throttle(
2390
+ "PageScroll" /* PageScroll */,
2391
+ () => {
2392
+ this.pushRegularEvent("PageScroll" /* PageScroll */);
2393
+ },
2394
+ 5e3
2395
+ );
2396
+ },
2397
+ resize: () => {
2398
+ this.eventHandler.throttle(
2399
+ "PageScroll" /* PageScroll */,
2400
+ () => {
2401
+ this.pushRegularEvent("PageResize" /* PageResize */);
2402
+ },
2403
+ 5e3
2404
+ );
2405
+ }
2406
+ };
2407
+ this.enableAutoPageViews = () => {
2408
+ const trackPageView = () => this.trackPageView();
2409
+ const originalPushState = history.pushState;
2410
+ if (originalPushState) {
2411
+ history.pushState = function(data, title, url) {
2412
+ originalPushState.apply(this, [data, title, url]);
2413
+ trackPageView();
2414
+ };
2415
+ }
2416
+ const originalReplaceState = history.replaceState;
2417
+ if (originalReplaceState) {
2418
+ history.replaceState = function(data, title, url) {
2419
+ originalReplaceState.apply(this, [data, title, url]);
2420
+ trackPageView();
2421
+ };
2422
+ }
2423
+ this.trackPageView();
2424
+ return function cleanup() {
2425
+ if (originalPushState) {
2426
+ history.pushState = originalPushState;
2427
+ }
2428
+ if (originalReplaceState) {
2429
+ history.replaceState = originalReplaceState;
2430
+ }
2431
+ };
2432
+ };
2433
+ this.options = {
2434
+ hashMode,
2435
+ autoTrack,
2436
+ ...options
2437
+ };
2438
+ this.eventHandler = getEventHandler(this.options.trackingUrl);
2439
+ enablePing(this.options.trackingUrl);
2440
+ this.addEventListeners();
2441
+ }
2442
+ destroy() {
2443
+ this.removeEventListeners();
2444
+ }
2445
+ addEventListeners() {
2446
+ Object.entries(this.listeners).forEach(([eventName, listener]) => {
2447
+ window.addEventListener(eventName, listener);
2448
+ });
2449
+ if (this.options.autoTrack) {
2450
+ this.autoPageViewsDisabler = this.enableAutoPageViews();
2451
+ }
2452
+ }
2453
+ removeEventListeners() {
2454
+ Object.entries(this.listeners).forEach(([eventName, listener]) => {
2455
+ window.removeEventListener(eventName, listener);
2456
+ });
2457
+ this.autoPageViewsDisabler?.();
2458
+ }
2459
+ trackPageView() {
2460
+ if (this.options.pageViewDelay && this.options.pageViewDelay > 0) {
2461
+ setTimeout(() => {
2462
+ this.pushRegularEvent("PageView" /* PageView */);
2463
+ }, this.options.pageViewDelay);
2464
+ } else {
2465
+ this.pushRegularEvent("PageView" /* PageView */);
2466
+ }
2467
+ }
2468
+ pushRegularEvent(eventName) {
2469
+ this.eventHandler.pushEvent({
2470
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2471
+ event: {
2472
+ type: "page",
2473
+ name: eventName
2474
+ },
2475
+ page: getPageInfo()
2476
+ });
2477
+ }
2478
+ };
2479
+
2480
+ // src/actions.ts
2481
+ var pushActions = {
2482
+ trackPageView: () => {
2483
+ window.mpulse?.page?.trackPageView();
2484
+ }
2485
+ };
2486
+ function push(action, ...args) {
2487
+ if (!window.mpulse) {
2488
+ return;
2489
+ }
2490
+ const actionFn = pushActions[action];
2491
+ if (actionFn) {
2492
+ actionFn(...args);
2493
+ }
2494
+ }
2495
+
2496
+ // src/index.ts
2497
+ function initTracking({
2498
+ trackingUrl,
2499
+ hashMode,
2500
+ trackPage = true,
2501
+ trackMedia = true,
2502
+ autoDiscoverPlayers: autoDiscoverPlayers2 = false,
2503
+ debugMode = false,
2504
+ pageViewDelay = 10,
2505
+ userGetter,
2506
+ pageMetaGetter
2507
+ }) {
2508
+ if (!trackingUrl) {
2509
+ throw new Error("Tracking URL is required");
2510
+ }
2511
+ if (window.mpulse?.page || window.mpulse?.media) {
2512
+ console.error("Analytics already initialized");
2513
+ stopTracking();
2514
+ }
2515
+ window.mpulse = {
2516
+ page: window.mpulse?.page,
2517
+ media: window.mpulse?.media,
2518
+ push,
2519
+ userGetter,
2520
+ pageMetaGetter,
2521
+ options: {
2522
+ autoDiscoverPlayers: autoDiscoverPlayers2,
2523
+ debugMode
2524
+ }
2525
+ };
2526
+ if (trackPage) {
2527
+ window.mpulse.page = new PageAnalytics({
2528
+ trackingUrl,
2529
+ hashMode,
2530
+ pageViewDelay
2531
+ });
2532
+ document.addEventListener(InternalEvent.PageView, discoverThings);
2533
+ }
2534
+ if (trackMedia) {
2535
+ window.mpulse.media = new MediaAnalytics({
2536
+ trackingUrl
2537
+ });
2538
+ }
2539
+ document.addEventListener("beforeunload", stopTracking);
2540
+ if (debugMode) {
2541
+ Object.entries(InternalEvent).forEach(([, event]) => {
2542
+ document.addEventListener(event, debugEvent);
2543
+ });
2544
+ }
2545
+ }
2546
+ function stopTracking() {
2547
+ window.mpulse?.page?.destroy();
2548
+ window.mpulse?.media?.destroy();
2549
+ document.removeEventListener(InternalEvent.PageView, discoverThings);
2550
+ if (window.mpulse?.options?.debugMode) {
2551
+ Object.entries(InternalEvent).forEach(([, event]) => {
2552
+ document.removeEventListener(event, debugEvent);
2553
+ });
2554
+ }
2555
+ }
2556
+ function discoverThings() {
2557
+ if (window.mpulse?.options?.autoDiscoverPlayers) {
2558
+ window.mpulse?.media?.autoDiscoverPlayers();
2559
+ }
2560
+ }
2561
+ function debugEvent(event) {
2562
+ console.log(event.type, event.detail);
2563
+ }
2564
+
2565
+ // src/media/index.ts
2566
+ function addPlayer(player) {
2567
+ if (!window.mpulse?.media) {
2568
+ console.error("Media analytics not initialized");
2569
+ return;
2570
+ }
2571
+ return window.mpulse.media.addPlayer(player);
2572
+ }
2573
+ function removePlayer(player) {
2574
+ if (!window.mpulse?.media) {
2575
+ console.error("Media analytics not initialized");
2576
+ return;
2577
+ }
2578
+ window.mpulse.media.removePlayer(player);
2579
+ }
2580
+ function autoDiscoverPlayers() {
2581
+ if (!window.mpulse?.media) {
2582
+ console.error("Media analytics not initialized");
2583
+ return;
2584
+ }
2585
+ window.mpulse.media.autoDiscoverPlayers();
2586
+ }
2587
+ return __toCommonJS(global_exports);
2588
+ })();