@zoho_apptics/apptics-js-sdk 1.0.2 → 2.0.0-beta.1

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 (243) hide show
  1. package/CHANGELOG.md +193 -0
  2. package/LICENSE +13 -0
  3. package/README.md +846 -11
  4. package/dist/apptics.esm.min.js +3 -0
  5. package/dist/apptics.esm.min.js.map +1 -0
  6. package/dist/apptics.min.js +3 -0
  7. package/dist/apptics.min.js.map +1 -0
  8. package/dist/chunks/lifecycle-VYr43KcB.min.js +3 -0
  9. package/dist/chunks/lifecycle-VYr43KcB.min.js.map +1 -0
  10. package/dist/cjs/auto-init.d.ts +8 -0
  11. package/dist/cjs/auto-init.js +32 -0
  12. package/dist/cjs/core/attempts.d.ts +28 -0
  13. package/dist/cjs/core/attempts.js +113 -0
  14. package/dist/cjs/core/batch.d.ts +32 -0
  15. package/dist/cjs/core/batch.js +116 -0
  16. package/dist/cjs/core/callsite.d.ts +34 -0
  17. package/dist/cjs/core/callsite.js +115 -0
  18. package/dist/cjs/core/consent.d.ts +27 -0
  19. package/dist/cjs/core/consent.js +132 -0
  20. package/dist/cjs/core/constants.d.ts +237 -0
  21. package/dist/cjs/core/constants.js +315 -0
  22. package/dist/cjs/core/db.d.ts +48 -0
  23. package/dist/cjs/core/db.js +467 -0
  24. package/dist/cjs/core/debug.d.ts +22 -0
  25. package/dist/cjs/core/debug.js +88 -0
  26. package/dist/cjs/core/env.d.ts +28 -0
  27. package/dist/cjs/core/env.js +267 -0
  28. package/dist/cjs/core/framework-id.d.ts +1 -0
  29. package/dist/cjs/core/framework-id.js +9 -0
  30. package/dist/cjs/core/guard.d.ts +11 -0
  31. package/dist/cjs/core/guard.js +86 -0
  32. package/dist/cjs/core/hooks.d.ts +39 -0
  33. package/dist/cjs/core/hooks.js +22 -0
  34. package/dist/cjs/core/locks.d.ts +9 -0
  35. package/dist/cjs/core/locks.js +22 -0
  36. package/dist/cjs/core/logger.d.ts +15 -0
  37. package/dist/cjs/core/logger.js +50 -0
  38. package/dist/cjs/core/state.d.ts +70 -0
  39. package/dist/cjs/core/state.js +78 -0
  40. package/dist/cjs/core/storage.d.ts +61 -0
  41. package/dist/cjs/core/storage.js +327 -0
  42. package/dist/cjs/core/stylesheet.d.ts +8 -0
  43. package/dist/cjs/core/stylesheet.js +29 -0
  44. package/dist/cjs/core/transport.d.ts +85 -0
  45. package/dist/cjs/core/transport.js +456 -0
  46. package/dist/cjs/core/utils.d.ts +26 -0
  47. package/dist/cjs/core/utils.js +175 -0
  48. package/dist/cjs/core/validate.d.ts +18 -0
  49. package/dist/cjs/core/validate.js +233 -0
  50. package/dist/cjs/device/appversion.d.ts +15 -0
  51. package/dist/cjs/device/appversion.js +170 -0
  52. package/dist/cjs/device/index.d.ts +34 -0
  53. package/dist/cjs/device/index.js +472 -0
  54. package/dist/cjs/engagement/api-rules.d.ts +49 -0
  55. package/dist/cjs/engagement/api-rules.js +206 -0
  56. package/dist/cjs/engagement/auto-api.d.ts +7 -0
  57. package/dist/cjs/engagement/auto-api.js +200 -0
  58. package/dist/cjs/engagement/auto-screen.d.ts +18 -0
  59. package/dist/cjs/engagement/auto-screen.js +305 -0
  60. package/dist/cjs/engagement/defined-events.d.ts +23 -0
  61. package/dist/cjs/engagement/defined-events.js +58 -0
  62. package/dist/cjs/engagement/send.d.ts +6 -0
  63. package/dist/cjs/engagement/send.js +104 -0
  64. package/dist/cjs/engagement/session.d.ts +51 -0
  65. package/dist/cjs/engagement/session.js +463 -0
  66. package/dist/cjs/engagement/track.d.ts +56 -0
  67. package/dist/cjs/engagement/track.js +375 -0
  68. package/dist/cjs/errors/send.d.ts +6 -0
  69. package/dist/cjs/errors/send.js +73 -0
  70. package/dist/cjs/errors/track.d.ts +4 -0
  71. package/dist/cjs/errors/track.js +167 -0
  72. package/dist/cjs/feedback/controls.d.ts +37 -0
  73. package/dist/cjs/feedback/controls.js +316 -0
  74. package/dist/cjs/feedback/index.d.ts +9 -0
  75. package/dist/cjs/feedback/index.js +56 -0
  76. package/dist/cjs/feedback/logs.d.ts +45 -0
  77. package/dist/cjs/feedback/logs.js +241 -0
  78. package/dist/cjs/feedback/quartz.d.ts +18 -0
  79. package/dist/cjs/feedback/quartz.js +105 -0
  80. package/dist/cjs/feedback/send.d.ts +28 -0
  81. package/dist/cjs/feedback/send.js +203 -0
  82. package/dist/cjs/feedback/styles.d.ts +10 -0
  83. package/dist/cjs/feedback/styles.js +8 -0
  84. package/dist/cjs/feedback/template.d.ts +2 -0
  85. package/dist/cjs/feedback/template.js +162 -0
  86. package/dist/cjs/feedback/ui.d.ts +63 -0
  87. package/dist/cjs/feedback/ui.js +709 -0
  88. package/dist/cjs/heatmap/send.d.ts +13 -0
  89. package/dist/cjs/heatmap/send.js +82 -0
  90. package/dist/cjs/heatmap/track.d.ts +4 -0
  91. package/dist/cjs/heatmap/track.js +448 -0
  92. package/dist/cjs/index.d.ts +22 -0
  93. package/dist/cjs/index.js +162 -0
  94. package/dist/cjs/lifecycle.d.ts +21 -0
  95. package/dist/cjs/lifecycle.js +734 -0
  96. package/dist/cjs/package.json +3 -0
  97. package/dist/cjs/remoteconfig/country.d.ts +4 -0
  98. package/dist/cjs/remoteconfig/country.js +73 -0
  99. package/dist/cjs/remoteconfig/custom.d.ts +10 -0
  100. package/dist/cjs/remoteconfig/custom.js +58 -0
  101. package/dist/cjs/remoteconfig/evaluate.d.ts +24 -0
  102. package/dist/cjs/remoteconfig/evaluate.js +184 -0
  103. package/dist/cjs/remoteconfig/fetch.d.ts +24 -0
  104. package/dist/cjs/remoteconfig/fetch.js +200 -0
  105. package/dist/cjs/remoteconfig/index.d.ts +15 -0
  106. package/dist/cjs/remoteconfig/index.js +116 -0
  107. package/dist/cjs/remoteconfig/store.d.ts +18 -0
  108. package/dist/cjs/remoteconfig/store.js +98 -0
  109. package/dist/cjs/remoteconfig/tz-countries.d.ts +8 -0
  110. package/dist/cjs/remoteconfig/tz-countries.js +13 -0
  111. package/dist/cjs/remotelog/gate.d.ts +2 -0
  112. package/dist/cjs/remotelog/gate.js +28 -0
  113. package/dist/cjs/remotelog/index.d.ts +8 -0
  114. package/dist/cjs/remotelog/logger.d.ts +22 -0
  115. package/dist/cjs/remotelog/logger.js +111 -0
  116. package/dist/cjs/remotelog/send.d.ts +13 -0
  117. package/dist/cjs/remotelog/send.js +153 -0
  118. package/dist/cjs/remotelogger/index.d.ts +12 -0
  119. package/dist/cjs/remotelogger/index.js +18 -0
  120. package/dist/cjs/scheduler.d.ts +8 -0
  121. package/dist/cjs/scheduler.js +78 -0
  122. package/dist/cjs/types.d.ts +385 -0
  123. package/dist/cjs/user/index.d.ts +33 -0
  124. package/dist/cjs/user/index.js +183 -0
  125. package/dist/esm/auto-init.d.ts +8 -0
  126. package/dist/esm/auto-init.js +29 -0
  127. package/dist/esm/core/attempts.d.ts +28 -0
  128. package/dist/esm/core/attempts.js +106 -0
  129. package/dist/esm/core/batch.d.ts +32 -0
  130. package/dist/esm/core/batch.js +109 -0
  131. package/dist/esm/core/callsite.d.ts +34 -0
  132. package/dist/esm/core/callsite.js +110 -0
  133. package/dist/esm/core/consent.d.ts +27 -0
  134. package/dist/esm/core/consent.js +122 -0
  135. package/dist/esm/core/constants.d.ts +237 -0
  136. package/dist/esm/core/constants.js +292 -0
  137. package/dist/esm/core/db.d.ts +48 -0
  138. package/dist/esm/core/db.js +453 -0
  139. package/dist/esm/core/debug.d.ts +22 -0
  140. package/dist/esm/core/debug.js +81 -0
  141. package/dist/esm/core/env.d.ts +28 -0
  142. package/dist/esm/core/env.js +251 -0
  143. package/dist/esm/core/framework-id.d.ts +1 -0
  144. package/dist/esm/core/framework-id.js +7 -0
  145. package/dist/esm/core/guard.d.ts +11 -0
  146. package/dist/esm/core/guard.js +83 -0
  147. package/dist/esm/core/hooks.d.ts +39 -0
  148. package/dist/esm/core/hooks.js +20 -0
  149. package/dist/esm/core/locks.d.ts +9 -0
  150. package/dist/esm/core/locks.js +20 -0
  151. package/dist/esm/core/logger.d.ts +15 -0
  152. package/dist/esm/core/logger.js +46 -0
  153. package/dist/esm/core/state.d.ts +70 -0
  154. package/dist/esm/core/state.js +73 -0
  155. package/dist/esm/core/storage.d.ts +61 -0
  156. package/dist/esm/core/storage.js +314 -0
  157. package/dist/esm/core/stylesheet.d.ts +8 -0
  158. package/dist/esm/core/stylesheet.js +27 -0
  159. package/dist/esm/core/transport.d.ts +85 -0
  160. package/dist/esm/core/transport.js +439 -0
  161. package/dist/esm/core/utils.d.ts +26 -0
  162. package/dist/esm/core/utils.js +161 -0
  163. package/dist/esm/core/validate.d.ts +18 -0
  164. package/dist/esm/core/validate.js +226 -0
  165. package/dist/esm/device/appversion.d.ts +15 -0
  166. package/dist/esm/device/appversion.js +164 -0
  167. package/dist/esm/device/index.d.ts +34 -0
  168. package/dist/esm/device/index.js +461 -0
  169. package/dist/esm/engagement/api-rules.d.ts +49 -0
  170. package/dist/esm/engagement/api-rules.js +199 -0
  171. package/dist/esm/engagement/auto-api.d.ts +7 -0
  172. package/dist/esm/engagement/auto-api.js +198 -0
  173. package/dist/esm/engagement/auto-screen.d.ts +18 -0
  174. package/dist/esm/engagement/auto-screen.js +301 -0
  175. package/dist/esm/engagement/defined-events.d.ts +23 -0
  176. package/dist/esm/engagement/defined-events.js +55 -0
  177. package/dist/esm/engagement/send.d.ts +6 -0
  178. package/dist/esm/engagement/send.js +101 -0
  179. package/dist/esm/engagement/session.d.ts +51 -0
  180. package/dist/esm/engagement/session.js +448 -0
  181. package/dist/esm/engagement/track.d.ts +56 -0
  182. package/dist/esm/engagement/track.js +365 -0
  183. package/dist/esm/errors/send.d.ts +6 -0
  184. package/dist/esm/errors/send.js +70 -0
  185. package/dist/esm/errors/track.d.ts +4 -0
  186. package/dist/esm/errors/track.js +163 -0
  187. package/dist/esm/feedback/controls.d.ts +37 -0
  188. package/dist/esm/feedback/controls.js +309 -0
  189. package/dist/esm/feedback/index.d.ts +9 -0
  190. package/dist/esm/feedback/index.js +51 -0
  191. package/dist/esm/feedback/logs.d.ts +45 -0
  192. package/dist/esm/feedback/logs.js +227 -0
  193. package/dist/esm/feedback/quartz.d.ts +18 -0
  194. package/dist/esm/feedback/quartz.js +99 -0
  195. package/dist/esm/feedback/send.d.ts +28 -0
  196. package/dist/esm/feedback/send.js +198 -0
  197. package/dist/esm/feedback/styles.d.ts +10 -0
  198. package/dist/esm/feedback/styles.js +4 -0
  199. package/dist/esm/feedback/template.d.ts +2 -0
  200. package/dist/esm/feedback/template.js +159 -0
  201. package/dist/esm/feedback/ui.d.ts +63 -0
  202. package/dist/esm/feedback/ui.js +703 -0
  203. package/dist/esm/heatmap/send.d.ts +13 -0
  204. package/dist/esm/heatmap/send.js +79 -0
  205. package/dist/esm/heatmap/track.d.ts +4 -0
  206. package/dist/esm/heatmap/track.js +445 -0
  207. package/dist/esm/index.d.ts +22 -0
  208. package/dist/esm/index.js +150 -0
  209. package/dist/esm/lifecycle.d.ts +21 -0
  210. package/dist/esm/lifecycle.js +729 -0
  211. package/dist/esm/package.json +3 -0
  212. package/dist/esm/remoteconfig/country.d.ts +4 -0
  213. package/dist/esm/remoteconfig/country.js +70 -0
  214. package/dist/esm/remoteconfig/custom.d.ts +10 -0
  215. package/dist/esm/remoteconfig/custom.js +54 -0
  216. package/dist/esm/remoteconfig/evaluate.d.ts +24 -0
  217. package/dist/esm/remoteconfig/evaluate.js +179 -0
  218. package/dist/esm/remoteconfig/fetch.d.ts +24 -0
  219. package/dist/esm/remoteconfig/fetch.js +196 -0
  220. package/dist/esm/remoteconfig/index.d.ts +15 -0
  221. package/dist/esm/remoteconfig/index.js +111 -0
  222. package/dist/esm/remoteconfig/store.d.ts +18 -0
  223. package/dist/esm/remoteconfig/store.js +91 -0
  224. package/dist/esm/remoteconfig/tz-countries.d.ts +8 -0
  225. package/dist/esm/remoteconfig/tz-countries.js +11 -0
  226. package/dist/esm/remotelog/gate.d.ts +2 -0
  227. package/dist/esm/remotelog/gate.js +26 -0
  228. package/dist/esm/remotelog/index.d.ts +8 -0
  229. package/dist/esm/remotelog/logger.d.ts +22 -0
  230. package/dist/esm/remotelog/logger.js +108 -0
  231. package/dist/esm/remotelog/send.d.ts +13 -0
  232. package/dist/esm/remotelog/send.js +149 -0
  233. package/dist/esm/remotelogger/index.d.ts +12 -0
  234. package/dist/esm/remotelogger/index.js +13 -0
  235. package/dist/esm/scheduler.d.ts +8 -0
  236. package/dist/esm/scheduler.js +74 -0
  237. package/dist/esm/types.d.ts +385 -0
  238. package/dist/esm/user/index.d.ts +33 -0
  239. package/dist/esm/user/index.js +176 -0
  240. package/dist/feedback.esm.min.js +3 -0
  241. package/dist/feedback.esm.min.js.map +1 -0
  242. package/package.json +122 -7
  243. package/src/appticssdk.js +0 -1
@@ -0,0 +1,734 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.1 | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ 'use strict';
3
+
4
+ var constants = require('./core/constants.js');
5
+ var state = require('./core/state.js');
6
+ var logger = require('./core/logger.js');
7
+ var utils = require('./core/utils.js');
8
+ var storage = require('./core/storage.js');
9
+ var hooks = require('./core/hooks.js');
10
+ var debug = require('./core/debug.js');
11
+ var env = require('./core/env.js');
12
+ var index = require('./device/index.js');
13
+ var appversion = require('./device/appversion.js');
14
+ var session = require('./engagement/session.js');
15
+ var autoApi = require('./engagement/auto-api.js');
16
+ var autoScreen = require('./engagement/auto-screen.js');
17
+ var track = require('./engagement/track.js');
18
+ var track$1 = require('./errors/track.js');
19
+ var scheduler = require('./scheduler.js');
20
+ var send = require('./remotelog/send.js');
21
+ var index$1 = require('./user/index.js');
22
+ var attempts = require('./core/attempts.js');
23
+ var frameworkId = require('./core/framework-id.js');
24
+
25
+ let listenersAttached = false;
26
+ /** The config init() was last called with; reset() starts again from it. */
27
+ let lastConfig = null;
28
+ /** Bumped by every init(); a start() from an earlier init() that was reset in between does nothing. */
29
+ let generation = 0;
30
+ function isBrowser() {
31
+ if (typeof window === 'undefined' || typeof document === 'undefined' || typeof Promise === 'undefined') { // no i18n
32
+ return false;
33
+ }
34
+ try {
35
+ return typeof indexedDB !== 'undefined' || !!window.localStorage; // no i18n
36
+ }
37
+ catch (err) {
38
+ return false; // storage access can throw in sandboxed frames
39
+ }
40
+ }
41
+ /**
42
+ * The config as the SDK keeps it: base_url, auth_key and app_domain under their inside names
43
+ * (serviceUrl, zak, identifier; see CONFIG_KEYS), and appversion as text. An earlier name of a
44
+ * key is still read when the key itself is not given, with a warning naming the key to use.
45
+ * The base url loses any trailing slash, because request paths add their own.
46
+ */
47
+ function normaliseConfig(config) {
48
+ var settings = Object.assign({}, config);
49
+ Object.keys(constants.CONFIG_KEYS).forEach(function (key) {
50
+ var inside = constants.CONFIG_KEYS[key];
51
+ if (!utils.isEmpty(config[key])) {
52
+ settings[inside] = config[key];
53
+ return;
54
+ }
55
+ delete settings[inside];
56
+ Object.keys(constants.RETIRED_CONFIG_NAMES).forEach(function (old) {
57
+ if (constants.RETIRED_CONFIG_NAMES[old] !== key || utils.isEmpty(config[old])) {
58
+ return;
59
+ }
60
+ logger.warnAlways('Apptics.init: ' + old + ' is now ' + key + '; rename it in your config'); // no i18n
61
+ if (utils.isEmpty(settings[inside])) {
62
+ settings[inside] = config[old];
63
+ }
64
+ });
65
+ });
66
+ if (!utils.isEmpty(settings.serviceUrl)) {
67
+ settings.serviceUrl = String(settings.serviceUrl).replace(/\/+$/, ''); // no i18n
68
+ }
69
+ settings.appversion = appVersionText(settings.appversion);
70
+ return settings;
71
+ }
72
+ /**
73
+ * The version as the text it is stored and sent as: a string trimmed, a finite number as its digits.
74
+ * Anything else — blank, NaN, an object — is '', which init() reports as missing.
75
+ */
76
+ function appVersionText(value) {
77
+ if (typeof value === 'number') { // no i18n
78
+ return isFinite(value) ? String(value) : ''; // no i18n
79
+ }
80
+ return typeof value === 'string' ? value.trim() : ''; // no i18n
81
+ }
82
+ /**
83
+ * The placeholders the console's snippets and the docs show for appversion. Starting with one
84
+ * would register a version that was never shipped, and every visit after it would report under it.
85
+ */
86
+ const APPVERSION_PLACEHOLDERS = ['YOUR_APP_VERSION', 'YOUR_BUILD_OR_APP_VERSION', 'YOUR_APPVERSION']; // no i18n
87
+ function isAppVersionPlaceholder(version) {
88
+ return APPVERSION_PLACEHOLDERS.indexOf(version.toUpperCase()) !== -1;
89
+ }
90
+ /**
91
+ * The framework id this SDK reports to serviceUrl. The id built into the package is the one
92
+ * sdk-apptics.zoho.com issued at publish time, and localzoho servers don't know it: any
93
+ * localzoho serviceUrl reports 5970 instead, the id apptics.localzoho.com issued for 2.0.0-beta
94
+ * (Browser), so the same package also runs there.
95
+ */
96
+ const LOCALZOHO_FRAMEWORK_ID = 5970;
97
+ function frameworkIdFor(serviceUrl) {
98
+ var host = serviceUrl;
99
+ try {
100
+ host = new URL(serviceUrl).hostname;
101
+ }
102
+ catch (err) {
103
+ // not a url: judge the text as it is
104
+ }
105
+ return host.indexOf('localzoho') !== -1 ? LOCALZOHO_FRAMEWORK_ID : frameworkId.FRAMEWORK_ID; // no i18n
106
+ }
107
+ /** Which app this browser's stored data belongs to, before app/addversion has named it. */
108
+ function appKey(settings) {
109
+ return settings.serviceUrl + '|' + settings.identifier; // no i18n
110
+ }
111
+ /**
112
+ * The app version stored data belongs to, read before app/addversion replaces it: what tells a
113
+ * new release of the app from a reload. '' on a first visit.
114
+ */
115
+ var previousAppVersion = ''; // no i18n
116
+ /**
117
+ * Data stored for another app on this origin is discarded before anything else reads it,
118
+ * including the stored app/addversion answer that would otherwise hand out that app's ids.
119
+ */
120
+ function discardOtherAppData(settings) {
121
+ // which app it is, and which version, are in app_version_info (serviceUrl, identifier and
122
+ // appversion): no keys of their own. 2.0.0-beta's appkey and appversion are read this once
123
+ var info = storage.user_defaults.item('app_version_info') || {}; // no i18n
124
+ var stored = !utils.isEmpty(info.serviceUrl) && !utils.isEmpty(info.identifier)
125
+ ? appKey(info)
126
+ : storage.user_defaults.item('appkey'); // no i18n
127
+ previousAppVersion = String((!utils.isEmpty(info.appversion) ? info.appversion : storage.user_defaults.item('appversion')) || ''); // no i18n
128
+ storage.user_defaults.add('appkey', undefined); // no i18n
129
+ storage.user_defaults.add('appversion', undefined); // no i18n
130
+ if (!utils.isEmpty(stored) && stored !== appKey(settings)) {
131
+ logger.Console.log('init: stored data belongs to another app, resetting'); // no i18n
132
+ clearStorage();
133
+ previousAppVersion = ''; // no i18n
134
+ }
135
+ }
136
+ /**
137
+ * Timing an app may tune in init(). Each has a range: a value outside it is ignored with a
138
+ * warning rather than applied, since a 10 ms flush interval would hammer the server.
139
+ */
140
+ const TUNABLE = Object.freeze([
141
+ { key: 'batch_flush_interval', min: 1000, max: 3600000 }, // no i18n
142
+ { key: 'getupdates_interval', min: 10000, max: 86400000 }, // no i18n
143
+ { key: 'batch_size', min: 1, max: 500 }, // no i18n
144
+ { key: 'batch_request_timeout', min: 1, max: 30 }, // no i18n
145
+ { key: 'min_session_duration', min: 0, max: 60000 }, // no i18n
146
+ { key: 'heatmap_max_per_session', min: 0, max: 10000 }, // no i18n
147
+ ]);
148
+ /** Reads the tunable timings out of the config. Anything missing goes back to its default. */
149
+ function applyIntervals(config) {
150
+ TUNABLE.forEach(function (rule) {
151
+ var value = config[rule.key];
152
+ // every init() decides these on its own, so a value from an earlier one never lingers
153
+ state._ZAP._config[rule.key] = constants.AP_CONFIG[rule.key];
154
+ if (utils.isEmpty(value)) {
155
+ return;
156
+ }
157
+ var num = Number(value);
158
+ if (!isFinite(num) || num < rule.min || num > rule.max) {
159
+ logger.warnAlways('Apptics.init: ' + rule.key + ' must be between ' + rule.min + ' and ' + rule.max + ', keeping ' + state._ZAP._config[rule.key]); // no i18n
160
+ return;
161
+ }
162
+ state._ZAP._config[rule.key] = num;
163
+ logger.Console.log('Apptics.init: ' + rule.key + ' set to ' + num); // no i18n
164
+ });
165
+ // inactiveduration lives on state, not in _config
166
+ state._ZAP.inactiveduration = constants.DEFAULT_INACTIVE_MINUTES;
167
+ if (!utils.isEmpty(config.inactiveduration)) {
168
+ var minutes = Number(config.inactiveduration);
169
+ if (!isFinite(minutes) || minutes < 1 || minutes > 1440) {
170
+ logger.warnAlways('Apptics.init: inactiveduration must be between 1 and 1440 minutes, keeping ' + state._ZAP.inactiveduration); // no i18n
171
+ }
172
+ else {
173
+ state._ZAP.inactiveduration = minutes;
174
+ logger.Console.log('Apptics.init: inactiveduration set to ' + minutes); // no i18n
175
+ }
176
+ }
177
+ }
178
+ function clearStorage() {
179
+ attempts.clearAttempts();
180
+ storage.user_defaults.clear();
181
+ storage.engagement_transactions.clear();
182
+ storage.error_transactions.clear();
183
+ }
184
+ /**
185
+ * Starts the SDK. The config object is required: pass it directly, or let the console snippet
186
+ * supply it (auto-init reads window.appticssettings._defaultoptions and calls init with it).
187
+ * Returns true when the config has base_url, auth_key, app_domain and appversion and start-up has
188
+ * begun (see ready()), false when it was already running, the config is missing or incomplete, or
189
+ * there is no browser. Start-up calls app/addversion with those four, which answers with aaid, the
190
+ * portal and project ids and the rest; then device/add registers the browser, as in 1.x.
191
+ */
192
+ function init(config) {
193
+ if (!config || typeof config !== 'object') { // no i18n
194
+ logger.warnAlways('Apptics.init: a config object is required, e.g. Apptics.init({ base_url, auth_key, app_domain, appversion })'); // no i18n
195
+ return false;
196
+ }
197
+ if (state._ZAP._initialised) {
198
+ logger.Console.warn('Apptics.init: already initialised; call Apptics.reset() to start again'); // no i18n
199
+ return false;
200
+ }
201
+ if (!isBrowser()) {
202
+ logger.warnAlways('Apptics.init: skipped, no browser with storage and Promise support'); // no i18n
203
+ return false;
204
+ }
205
+ var settings = normaliseConfig(config);
206
+ var missing = constants.REQUIRED_CONFIG.filter(function (key) {
207
+ return utils.isEmpty(settings[constants.CONFIG_KEYS[key] || key]);
208
+ });
209
+ if (missing.length > 0) {
210
+ logger.warnAlways('Apptics.init: missing required config: ' + missing.join(', ')); // no i18n
211
+ return false;
212
+ }
213
+ if (isAppVersionPlaceholder(settings.appversion)) {
214
+ logger.warnAlways('Apptics.init: appversion is still the placeholder "' + settings.appversion // no i18n
215
+ + '"; replace it with your app\'s version or build number, e.g. \'2.4.0\''); // no i18n
216
+ return false;
217
+ }
218
+ state._ZAP._defaultoptions = settings;
219
+ // every request goes to serviceUrl; there is no other host to learn about
220
+ state._ZAP._defaultoptions.base_domain = settings.serviceUrl;
221
+ // decided per init(), so a reset() or a page on another host never keeps the last one
222
+ state._ZAP._frameworkID = frameworkIdFor(settings.serviceUrl);
223
+ // marks the SDK as started for the checks that need it; app/addversion replaces it with aaid
224
+ state._ZAP._token = settings.identifier;
225
+ // console_log: the SDK's own activity in the browser console
226
+ if (!utils.isEmpty(config.console_log)) {
227
+ state._ZAP._config.debug = !!config.console_log;
228
+ }
229
+ if (typeof config.ignore_do_not_track === 'boolean') { // no i18n
230
+ state._ZAP._config.ignore_do_not_track = config.ignore_do_not_track;
231
+ }
232
+ // debug: debug mode, the debug endpoints. Same payloads, but the answer says where to trace the
233
+ // request. debug_api is its earlier name and still works; debug wins when both are given
234
+ state._ZAP._config.debug_api = typeof config.debug === 'boolean' ? config.debug // no i18n
235
+ : typeof config.debug_api === 'boolean' ? config.debug_api : constants.AP_CONFIG.debug_api; // no i18n
236
+ // starts (or clears) the idle hour that closes debug mode on its own
237
+ // an enableDebug() or disableDebug() call the app already made wins over the config
238
+ debug.applyDebugConfig(state._ZAP._config.debug_api);
239
+ // what to call this device in the debug stream; see devicename in core/transport.ts
240
+ state._ZAP._config.device_name = typeof config.device_name === 'string' ? config.device_name : constants.AP_CONFIG.device_name; // no i18n
241
+ // the SDK no longer reports its own failures to the Remote Logger page: only the lines an app
242
+ // logs with AppticsLogger go there
243
+ if (config.remote_log !== undefined) {
244
+ logger.warnAlways('Apptics.init: remote_log is no longer read; the Remote Logger page shows the lines your app logs with AppticsLogger'); // no i18n
245
+ }
246
+ // AppticsLogger lines go to the Remote Logger page only, never to the browser console
247
+ if (config.show_logs !== undefined) {
248
+ logger.warnAlways('Apptics.init: show_logs is no longer read; AppticsLogger lines are not printed to the browser console'); // no i18n
249
+ }
250
+ // automatic api tracking: the app's own requests, wrapped. Which hosts it records is
251
+ // configureApiTracking's to say; the two keys that once did it are refused out loud rather
252
+ // than quietly ignored, since an app relying on them would otherwise record hosts it meant not to
253
+ state._ZAP._config.track_api = constants.AP_CONFIG.track_api;
254
+ ['track_api_hosts', 'track_api_exclude_hosts'].forEach(function (key) {
255
+ if (config[key] !== undefined) {
256
+ logger.warnAlways('Apptics.init: ' + key + ' is no longer supported; use AppticsApi.configure(new AppticsApi.ApiTrackingBuilder().' // no i18n
257
+ + (key === 'track_api_hosts' ? 'allowOnlyDomains' : 'ignoreDomains') + '(...).build())'); // no i18n
258
+ }
259
+ });
260
+ // screen recording is set up in the console now, and arrives with getsdkconfig
261
+ ['DC', 'quartz_workspace_key', 'quartz_department_key'].forEach(function (key) {
262
+ if (config[key] !== undefined) {
263
+ logger.warnAlways('Apptics.init: ' + key + ' is no longer read; screen recording in the feedback form is set up from the Apptics console'); // no i18n
264
+ }
265
+ });
266
+ // sessions are what everything else is recorded in; an app that wants nothing tracked uses
267
+ // AppticsSettings.setTrackingStatus instead
268
+ if (config.track_session !== undefined) {
269
+ logger.warnAlways('Apptics.init: track_session is no longer read; sessions are always recorded. To stop tracking, use AppticsSettings.setTrackingStatus(AppticsSettings.AP_TRACKING_STATUS.NO_TRACKING)'); // no i18n
270
+ }
271
+ if (typeof config.track_api === 'boolean') { // no i18n
272
+ state._ZAP._config.track_api = config.track_api;
273
+ }
274
+ autoApi.enableApiTracking(state._ZAP._config.track_api);
275
+ // heatmap capture: switched through the hook heatmap/track.ts sets
276
+ state._ZAP._config.track_heatmap = typeof config.track_heatmap === 'boolean' // no i18n
277
+ ? config.track_heatmap
278
+ : constants.AP_CONFIG.track_heatmap;
279
+ hooks.hooks.trackHeatmap(state._ZAP._config.track_heatmap);
280
+ // automatic screen tracking, on unless the config says false: switched on by start(), once a
281
+ // screen view can be stored
282
+ state._ZAP._config.track_screen = typeof config.track_screen === 'boolean' ? config.track_screen : constants.AP_CONFIG.track_screen; // no i18n
283
+ state._ZAP._config.screen_routes = screenRouteRules(config.screen_routes);
284
+ // a theme in the config wins; without one, what AppticsFeedback.setFeedbackTheme set stays
285
+ if (config.feedback_theme === 'light' || config.feedback_theme === 'dark' || config.feedback_theme === 'auto') { // no i18n
286
+ state._ZAP._config.feedback_theme = config.feedback_theme;
287
+ }
288
+ applyIntervals(config);
289
+ lastConfig = config;
290
+ state._ZAP._initialised = true;
291
+ state._ZAP._ready = false;
292
+ state._ZAP._pending = [];
293
+ var myGeneration = ++generation;
294
+ state._ZAP._readyPromise = storage.storageReady().then(function (backend) {
295
+ if (myGeneration !== generation) {
296
+ return false;
297
+ }
298
+ if (!backend) {
299
+ logger.warnAlways('Apptics.init: no usable storage (IndexedDB or localStorage), not starting'); // no i18n
300
+ state._ZAP._initialised = false;
301
+ state._ZAP._token = ''; // no i18n
302
+ state._ZAP._pending = [];
303
+ return false;
304
+ }
305
+ discardOtherAppData(state._ZAP._defaultoptions);
306
+ // app/addversion is the first call and everything waits on it: it is what turns the four
307
+ // values init() was given into aaid, the portal and project ids every url carries, and
308
+ // appreleaseversionid, which metaWebSDKV2 refuses a payload without
309
+ return appversion.registerAppVersion().then(function (registered) {
310
+ if (myGeneration !== generation) {
311
+ return false;
312
+ }
313
+ if (!registered && appversion.appVersionFailedForNetwork()) {
314
+ // a first visit with no network: start once it is back, keeping what the app
315
+ // tracks until then queued, rather than giving up for the rest of the page
316
+ logger.warnAlways('Apptics.init: offline, so app/addversion is tried again when the browser is back online; calls made until then are kept'); // no i18n
317
+ return registerWhenOnline(myGeneration).then(function (ok) {
318
+ if (myGeneration !== generation) {
319
+ return false;
320
+ }
321
+ if (!ok) {
322
+ state._ZAP._initialised = false;
323
+ state._ZAP._token = ''; // no i18n
324
+ state._ZAP._pending = [];
325
+ return false;
326
+ }
327
+ return start(config, myGeneration);
328
+ });
329
+ }
330
+ if (!registered) {
331
+ logger.warnAlways('Apptics.init: app/addversion did not return the app ids, not starting'); // no i18n
332
+ state._ZAP._initialised = false;
333
+ state._ZAP._token = ''; // no i18n
334
+ state._ZAP._pending = [];
335
+ return false;
336
+ }
337
+ return start(config, myGeneration);
338
+ });
339
+ }).catch(function (err) {
340
+ logger.Console.error('Apptics.init: start-up failed', err); // no i18n
341
+ return false;
342
+ });
343
+ return true;
344
+ }
345
+ /** How often a start-up waiting on the network tries app/addversion again, besides on `online`. */
346
+ const OFFLINE_RETRY_MS = 60 * 1000;
347
+ /**
348
+ * app/addversion again once the network is back: on the `online` event, and every minute for a
349
+ * network that came back without one. Resolves true once registered, false when the server
350
+ * refuses it or a reset()/new init() took over.
351
+ */
352
+ function registerWhenOnline(myGeneration) {
353
+ return new Promise(function (resolve) {
354
+ var timer = null;
355
+ var trying = false;
356
+ function done(ok) {
357
+ window.removeEventListener('online', attempt); // no i18n
358
+ if (timer !== null)
359
+ clearInterval(timer);
360
+ resolve(ok);
361
+ }
362
+ function attempt() {
363
+ if (myGeneration !== generation) {
364
+ done(false);
365
+ return;
366
+ }
367
+ if (trying || navigator.onLine === false) {
368
+ return;
369
+ }
370
+ trying = true;
371
+ appversion.registerAppVersion().then(function (registered) {
372
+ trying = false;
373
+ if (registered) {
374
+ done(true);
375
+ }
376
+ else if (!appversion.appVersionFailedForNetwork()) {
377
+ logger.warnAlways('Apptics.init: app/addversion did not return the app ids, not starting'); // no i18n
378
+ done(false);
379
+ }
380
+ });
381
+ }
382
+ window.addEventListener('online', attempt); // no i18n
383
+ timer = setInterval(attempt, OFFLINE_RETRY_MS);
384
+ });
385
+ }
386
+ /**
387
+ * screen_routes as init() keeps it: each entry checked, an exact path cleaned up, a regex given as
388
+ * a string compiled. An entry that cannot be used is left out, and said, rather than matching
389
+ * something its author did not mean.
390
+ */
391
+ function screenRouteRules(routes) {
392
+ if (!Array.isArray(routes)) {
393
+ return [];
394
+ }
395
+ var out = [];
396
+ routes.forEach(function (route) {
397
+ if (typeof route === 'string') { // no i18n
398
+ if (route.trim() !== '') { // no i18n
399
+ out.push({ kind: 'pattern', pattern: route.trim() }); // no i18n
400
+ }
401
+ return;
402
+ }
403
+ var rule = route && typeof route === 'object' ? route : null; // no i18n
404
+ var name = rule && typeof rule.name === 'string' ? rule.name.trim() : ''; // no i18n
405
+ if (rule && name !== '' && typeof rule.equals === 'string' && rule.equals.trim() !== '') { // no i18n
406
+ out.push({ kind: 'equals', path: autoScreen.routePath(rule.equals.trim()), name: name }); // no i18n
407
+ return;
408
+ }
409
+ if (rule && name !== '' && rule.regex !== undefined) {
410
+ var regex = null;
411
+ if (rule.regex instanceof RegExp) {
412
+ regex = rule.regex;
413
+ }
414
+ else if (typeof rule.regex === 'string' && rule.regex !== '') { // no i18n
415
+ try {
416
+ regex = new RegExp(rule.regex);
417
+ }
418
+ catch (err) {
419
+ regex = null;
420
+ }
421
+ }
422
+ if (regex) {
423
+ out.push({ kind: 'regex', regex: regex, name: name }); // no i18n
424
+ return;
425
+ }
426
+ }
427
+ logger.warnAlways('Apptics.init: screen_routes entry ' + safeJson(route) + ' is left out: give a route pattern, { equals, name } or { regex, name }'); // no i18n
428
+ });
429
+ return out;
430
+ }
431
+ /** An entry as the warning shows it: a RegExp as its source, which JSON.stringify would hide. */
432
+ function safeJson(value) {
433
+ try {
434
+ return JSON.stringify(value, function (_key, one) { return one instanceof RegExp ? String(one) : one; }) || String(value);
435
+ }
436
+ catch (err) {
437
+ return String(value);
438
+ }
439
+ }
440
+ /** Resolves true once start-up has finished, false if init() refused or storage is unusable. */
441
+ function ready() {
442
+ return state._ZAP._readyPromise || Promise.resolve(false);
443
+ }
444
+ function start(config, myGeneration) {
445
+ // this tab's lock, before any screen view: it is how other tabs tell this one is still open
446
+ session.holdTabLock();
447
+ // app/addversion named the app; data stored for another one was discarded before it ran
448
+ state._ZAP._token = String(state._ZAP._defaultoptions.aaid);
449
+ // last known server settings (getupdates) apply before anything is tracked
450
+ index.restoreServerSettings();
451
+ // a new release of the app, against the version the stored data was for (see
452
+ // discardOtherAppData): a first visit has none, and is no change
453
+ var appVersionChanged = previousAppVersion !== '' && previousAppVersion != state._ZAP._defaultoptions.appversion; // no i18n
454
+ state._ZAP._ignoreDnt = state._ZAP._config.ignore_do_not_track;
455
+ // the visitor's own stored choice, not getTrackingStatus(): that answers NO_TRACKING while Do
456
+ // Not Track is on, and storing it made one such visit switch tracking off for good
457
+ storage.tracking_preference.update_status(storage.tracking_preference.opt_in_status());
458
+ // the uuid and device info, and a registration on a first visit, under a lock shared with the
459
+ // site's other tabs (see prepareDevice)
460
+ return index.prepareDevice().then(function () {
461
+ if (myGeneration !== generation) {
462
+ return false;
463
+ }
464
+ return startTracking(appVersionChanged, myGeneration);
465
+ });
466
+ }
467
+ /** The rest of start-up, once the device is set up. */
468
+ function startTracking(appVersionChanged, myGeneration) {
469
+ // no getsdkconfig here, straight after app/addversion: it is asked for once device/add has
470
+ // succeeded (registerDeviceWithApptics), then every getupdates_interval. A returning visit
471
+ // starts from the settings saved by the last one (restoreServerSettings, in start())
472
+ if (appVersionChanged) {
473
+ state._ZAP._device_info.appversionid = ''; // no i18n
474
+ index.updateDeviceWithApptics(state._ZAP._device_info).then(function (result) {
475
+ if (utils.isSuccess(result)) {
476
+ logger.Console.log('init: appversion updated to ' + state._ZAP._defaultoptions.appversion); // no i18n
477
+ }
478
+ }).catch(function (err) {
479
+ logger.Console.log('init: error updating appversion: ' + err); // no i18n
480
+ });
481
+ }
482
+ // attempt to resolve connection type
483
+ state._ZAP._device_info.connectionType = env.getConnectionType();
484
+ attachListeners();
485
+ state._ZAP._properties.orientation = env.getOrientation();
486
+ index$1.getUserInfo();
487
+ return session.checkAndUpdateSession().then(function () {
488
+ if (myGeneration !== generation) {
489
+ return false;
490
+ }
491
+ scheduler.startTimers();
492
+ send.sendStoredLogs();
493
+ state._ZAP._ready = true;
494
+ // replay calls made while storage was loading, in order
495
+ var pending = state._ZAP._pending;
496
+ state._ZAP._pending = [];
497
+ pending.forEach(function (call) {
498
+ try {
499
+ call();
500
+ }
501
+ catch (err) {
502
+ logger.Console.error('apptics: buffered call failed', err); // no i18n
503
+ }
504
+ });
505
+ // after the replay, so a inScreen() the app made during start-up keeps its place, and
506
+ // the first automatic view is the page as it is now
507
+ autoScreen.enableScreenTracking(state._ZAP._config.track_screen);
508
+ // a no-op unless the remote-config entry was imported, which sets the hook
509
+ hooks.hooks.remoteConfigStarted();
510
+ window.appticsReadyStatus = true;
511
+ if (typeof window.appticsReady == 'function') { // no i18n
512
+ window.appticsReady();
513
+ }
514
+ return true;
515
+ });
516
+ }
517
+ /** Clears stored identity and queues, then starts again from the snippet. */
518
+ function reset() {
519
+ generation++;
520
+ scheduler.stopTimers();
521
+ // the wrappers come off with everything else; the init() below puts them back if the config
522
+ // asked for them, so a reset that has no config to restore leaves XHR and fetch untouched
523
+ autoApi.enableApiTracking(false);
524
+ autoScreen.enableScreenTracking(false);
525
+ appversion.clearAppVersion();
526
+ hooks.hooks.trackHeatmap(false);
527
+ hooks.hooks.resetHeatmap();
528
+ hooks.hooks.resetRemoteConfig();
529
+ clearStorage();
530
+ state._ZAP._initialised = false;
531
+ state._ZAP._ready = false;
532
+ state._ZAP._pending = [];
533
+ state._ZAP._readyPromise = null;
534
+ state._ZAP._device_info = {};
535
+ state._ZAP._user_info = {};
536
+ state._ZAP._current_screen = {};
537
+ state._ZAP._current_session = {};
538
+ state._ZAP._uuid = ''; // no i18n
539
+ state._ZAP._apid = ''; // no i18n
540
+ state._ZAP._mapid = ''; // no i18n
541
+ state._ZAP._sending = false;
542
+ logger.Console.log('Apptics.reset()'); // no i18n
543
+ // start again with the config init() was called with
544
+ if (lastConfig) {
545
+ init(lastConfig);
546
+ }
547
+ }
548
+ function isActive() {
549
+ return state._ZAP._ready;
550
+ }
551
+ /**
552
+ * A click-tracking attribute, in either spelling: `apeventaction`, or `data-apeventaction`, which
553
+ * is valid HTML and what React and TypeScript accept without declaring the attribute.
554
+ */
555
+ function trackingAttribute(el, name) {
556
+ var value = el.getAttribute(name);
557
+ return value !== null && value !== '' ? value : el.getAttribute('data-' + name); // no i18n
558
+ }
559
+ /** `[name]` and `[data-name]`, empty values left out, for closest(). */
560
+ function trackingSelector(name) {
561
+ return '[' + name + ']:not([' + name + '=""]),[data-' + name + ']:not([data-' + name + '=""])'; // no i18n
562
+ }
563
+ // Declarative click tracking: <el apeventaction="name" apeventprops='{"k":"v"}'> inside <el apgroupaction="group">,
564
+ // or the same attributes with a data- prefix
565
+ function onDocumentClick(event) {
566
+ if (!window.appticsReadyStatus || !isActive()) {
567
+ return;
568
+ }
569
+ var start = event.target;
570
+ if (start && typeof start.closest !== 'function') { // no i18n
571
+ start = start.parentElement;
572
+ }
573
+ if (!start) {
574
+ return;
575
+ }
576
+ var targetElem = start.closest(trackingSelector('apeventaction')); // no i18n
577
+ if (!targetElem) {
578
+ return;
579
+ }
580
+ var eventName = trackingAttribute(targetElem, 'apeventaction') || ''; // no i18n
581
+ var groupElem = targetElem.closest(trackingSelector('apgroupaction')); // no i18n
582
+ var groupName = (groupElem && trackingAttribute(groupElem, 'apgroupaction')) || constants.AP_CONFIG.default_group_name; // no i18n
583
+ var eventProps = {};
584
+ var rawProps = trackingAttribute(targetElem, 'apeventprops'); // no i18n
585
+ if (!utils.isEmpty(rawProps)) {
586
+ try {
587
+ eventProps = JSON.parse(rawProps);
588
+ }
589
+ catch (err) {
590
+ logger.Console.warn('apptics: invalid JSON in apeventprops for "' + eventName + '", sending no properties'); // no i18n
591
+ eventProps = {};
592
+ }
593
+ }
594
+ if (!utils.isEmpty(eventName)) {
595
+ track.trackEvent(eventName, groupName, eventProps);
596
+ }
597
+ }
598
+ /**
599
+ * Page is in the background but still there: close the open screen and send what's queued.
600
+ * By keepalive, because hidden is often the last moment before the tab closes, and a send still
601
+ * waiting on its answer would hold the queue as pagehide tries to send it.
602
+ */
603
+ function onPageHidden() {
604
+ if (!isActive())
605
+ return;
606
+ session.updateScreenWithEndtime();
607
+ scheduler.flush(true);
608
+ logger.Console.log('page hidden: closing the open screen and flushing'); // no i18n
609
+ }
610
+ /**
611
+ * The tab is closing, or the page is being replaced or frozen into the back/forward cache.
612
+ * The session ends here, and everything queued goes out by keepalive, since a normal
613
+ * request would be cancelled with the page.
614
+ */
615
+ function onPageClosing() {
616
+ if (!isActive())
617
+ return;
618
+ logger.Console.log('page closing: ending the session and sending what is queued'); // no i18n
619
+ session.updateScreenWithEndtime();
620
+ send.forgetStoredLogs();
621
+ session.endCurrentSession().then(function () {
622
+ return scheduler.flush(true);
623
+ });
624
+ }
625
+ function attachListeners() {
626
+ if (listenersAttached) {
627
+ return;
628
+ }
629
+ listenersAttached = true;
630
+ // listen for connection change events (only available in w3c implementation)
631
+ var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
632
+ if (connection && connection.addEventListener) {
633
+ connection.addEventListener('change', function () {
634
+ state._ZAP._device_info.connectionType = env.getConnectionType();
635
+ });
636
+ }
637
+ // Track when the window loses focus (user switches to another window or application)
638
+ window.addEventListener('blur', function () {
639
+ if (!isActive())
640
+ return;
641
+ logger.Console.log('Window lost focus, user switched to another window or application'); // no i18n
642
+ session.updateLastActiveTimeOfSession();
643
+ });
644
+ // Track when the window gains focus (user switches back to the window)
645
+ window.addEventListener('focus', function () {
646
+ if (!isActive())
647
+ return;
648
+ logger.Console.log('Window regained focus, user switched back to the window'); // no i18n
649
+ session.checkAndUpdateSession();
650
+ scheduler.startTimers();
651
+ });
652
+ // IndexedDB writes are async, so unload work starts on pagehide rather than beforeunload
653
+ window.addEventListener('pagehide', onPageClosing); // no i18n
654
+ // back/forward cache: pagehide ended the session, so coming back starts a new one
655
+ window.addEventListener('pageshow', function (event) {
656
+ if (!isActive() || !event.persisted)
657
+ return;
658
+ logger.Console.log('restored from the back/forward cache: starting a new session'); // no i18n
659
+ // the screen the page was left on starts a new view, in the new session
660
+ session.checkAndUpdateSession().then(track.resumeScreen);
661
+ scheduler.startTimers();
662
+ });
663
+ document.addEventListener('visibilitychange', function () {
664
+ if (!isActive())
665
+ return;
666
+ if (document.visibilityState === 'hidden') { // no i18n
667
+ onPageHidden();
668
+ return;
669
+ }
670
+ // back in view: the server's tracking flags may have changed while we were away
671
+ logger.Console.log('page visible: refreshing the server settings'); // no i18n
672
+ // hiding ended the screen view; the screen the user is back on starts a new one, after the
673
+ // session is settled so the view belongs to the right one
674
+ session.checkAndUpdateSession().then(track.resumeScreen);
675
+ index.refreshServerSettings();
676
+ });
677
+ // if we are running in cordova use ondeviceready otherwise onload
678
+ window.addEventListener(window.cordova ? 'deviceready' : 'load', function () {
679
+ if (isActive())
680
+ session.checkAndUpdateSession();
681
+ }, { passive: true });
682
+ // Always send pending requests when the connection comes back online
683
+ window.addEventListener('online', function () {
684
+ if (!isActive())
685
+ return;
686
+ // a first visit that started offline has no device ids yet, and nothing can be sent
687
+ // until it has them: register before flushing, and flush once that has landed
688
+ if (index.needsDevice()) {
689
+ logger.Console.log('back online: registering this device before sending'); // no i18n
690
+ // the same locked path as start-up, so two tabs coming back online register it once
691
+ index.prepareDevice().then(index.deviceReady).then(function () {
692
+ if (!isActive())
693
+ return;
694
+ scheduler.flush();
695
+ // the lines logged while offline are waiting too, and log/add needs the same ids
696
+ send.sendStoredLogs();
697
+ });
698
+ return;
699
+ }
700
+ scheduler.flush();
701
+ send.sendStoredLogs();
702
+ }, { passive: true });
703
+ if (window.screen && window.screen.orientation && typeof window.screen.orientation.addEventListener === 'function') { // no i18n
704
+ window.screen.orientation.addEventListener('change', function () {
705
+ state._ZAP._properties.orientation = env.getOrientation();
706
+ });
707
+ }
708
+ window.addEventListener('unhandledrejection', function (event) {
709
+ if (isActive() && state._ZAP._isGlobalErrorTracking) {
710
+ track$1.trackError(event);
711
+ }
712
+ });
713
+ // in the capture phase: a <script>, <img> or <link> that fails to load fires `error` on the
714
+ // element, and it does not bubble, so a bubbling listener never hears of it. One listener
715
+ // hears both kinds, the window's own errors included, so none is counted twice
716
+ window.addEventListener('error', function (event) {
717
+ if (!isActive() || !state._ZAP._isGlobalErrorTracking) {
718
+ return;
719
+ }
720
+ var target = event.target;
721
+ if (target && target !== window && typeof target.tagName === 'string') { // no i18n
722
+ // named by describeTarget: Event "error" on <script src="...">
723
+ track$1.trackError({ type: 'error', reason: event }); // no i18n
724
+ return;
725
+ }
726
+ track$1.trackError(event);
727
+ }, true);
728
+ window.addEventListener('click', onDocumentClick, true); // no i18n
729
+ }
730
+
731
+ exports.init = init;
732
+ exports.ready = ready;
733
+ exports.reset = reset;
734
+ exports.screenRouteRules = screenRouteRules;