govuk_publishing_components 35.1.1 → 35.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,13 +21,23 @@
21
21
 
22
22
  (function () {
23
23
  'use strict';
24
-
25
- function now() {
26
- return Date.now ? Date.now() : +new Date();
24
+ /**
25
+ * Fit an array of user timing delimited strings into a URL and return both the entries that fit and
26
+ * the remaining entries that didn't fit.
27
+ */
28
+ function fitUserTimingEntries(utValues, config, url) {
29
+ // Start with the maximum allowed UT entries per beacon
30
+ var beaconUtValues = utValues.slice(0, config.maxBeaconUTEntries);
31
+ var remainingUtValues = utValues.slice(config.maxBeaconUTEntries);
32
+ // Trim UT entries until they fit within the maximum URL length, ensuring at least one UT entry
33
+ // is included.
34
+ while ((url + "&UT=" + beaconUtValues.join(",")).length > config.maxBeaconUrlLength &&
35
+ beaconUtValues.length > 1) {
36
+ remainingUtValues.unshift(beaconUtValues.pop());
37
+ }
38
+ return [beaconUtValues, remainingUtValues];
27
39
  }
28
40
 
29
- var scriptStartTime = now();
30
-
31
41
  function fromObject(obj) {
32
42
  var autoMode = getProperty(obj, "auto", true);
33
43
  return {
@@ -57,60 +67,50 @@
57
67
  return defaultValue;
58
68
  }
59
69
 
60
- var LogEvent = {
61
- // Internal events
62
- EvaluationStart: 1,
63
- EvaluationEnd: 2,
64
- InitCalled: 3,
65
- MarkCalled: 4,
66
- MeasureCalled: 5,
67
- AddDataCalled: 6,
68
- SendCalled: 7,
69
- ForceSampleCalled: 8,
70
- DataCollectionStart: 9,
71
- UnloadHandlerTriggered: 10,
72
- OnloadHandlerTriggered: 11,
73
- MarkLoadTimeCalled: 12,
74
- // Data collection events
75
- SessionIsSampled: 21,
76
- SessionIsNotSampled: 22,
77
- MainBeaconSent: 23,
78
- UserTimingBeaconSent: 24,
79
- InteractionBeaconSent: 25,
80
- CustomDataBeaconSent: 26,
81
- // Metric information
82
- NavigationStart: 41,
83
- PerformanceEntryReceived: 42,
84
- PerformanceEntryProcessed: 43,
85
- // Errors
86
- PerformanceObserverError: 51,
87
- InputEventPermissionError: 52,
88
- InnerHtmlAccessError: 53,
89
- EventTargetAccessError: 54,
90
- CookieReadError: 55,
91
- CookieSetError: 56,
92
- PageLabelEvaluationError: 57,
93
- // Browser support messages
94
- NavTimingNotSupported: 71,
95
- PaintTimingNotSupported: 72,
96
- };
97
- var Logger = /** @class */ (function () {
98
- function Logger() {
99
- this.events = [];
100
- }
101
- Logger.prototype.logEvent = function (event, args) {
102
- if (args === void 0) { args = []; }
103
- this.events.push([now(), event, args]);
104
- };
105
- Logger.prototype.getEvents = function () {
106
- return this.events;
107
- };
108
- return Logger;
109
- }());
110
-
111
70
  var START_MARK = "LUX_start";
112
71
  var END_MARK = "LUX_end";
113
72
 
73
+ var customDataValues = {};
74
+ var updatedCustomData = {};
75
+ function addCustomDataValue(name, value) {
76
+ var typeV = typeof value;
77
+ if (customDataValues[name] !== value) {
78
+ // If the value is new or different to the previous value, record it so that later we can send
79
+ // only the values that have changed.
80
+ updatedCustomData[name] = value;
81
+ }
82
+ if (typeV === "string" || typeV === "number" || typeV === "boolean") {
83
+ customDataValues[name] = value;
84
+ }
85
+ if (typeV === "undefined" || value === null) {
86
+ delete customDataValues[name];
87
+ }
88
+ }
89
+ function getAllCustomData() {
90
+ return customDataValues;
91
+ }
92
+ function getUpdatedCustomData() {
93
+ return updatedCustomData;
94
+ }
95
+ function clearUpdateCustomData() {
96
+ updatedCustomData = {};
97
+ }
98
+ /**
99
+ * Convert a set of custom data values to the string format expected by the backend.
100
+ */
101
+ function valuesToString(values) {
102
+ var strings = [];
103
+ for (var key in values) {
104
+ // Convert all values to strings
105
+ var value = "" + values[key];
106
+ // Strip out reserved characters (, and | are used as delimiters)
107
+ key = key.replace(/,/g, "").replace(/\|/g, "");
108
+ value = value.replace(/,/g, "").replace(/\|/g, "");
109
+ strings.push(key + "|" + value);
110
+ }
111
+ return encodeURIComponent(strings.join(","));
112
+ }
113
+
114
114
  var Flags = {
115
115
  InitCalled: 1 << 0,
116
116
  NavTimingNotSupported: 1 << 1,
@@ -177,6 +177,85 @@
177
177
  return null;
178
178
  }
179
179
 
180
+ function now() {
181
+ return Date.now ? Date.now() : +new Date();
182
+ }
183
+
184
+ var LogEvent = {
185
+ // Internal events
186
+ EvaluationStart: 1,
187
+ EvaluationEnd: 2,
188
+ InitCalled: 3,
189
+ MarkCalled: 4,
190
+ MeasureCalled: 5,
191
+ AddDataCalled: 6,
192
+ SendCalled: 7,
193
+ ForceSampleCalled: 8,
194
+ DataCollectionStart: 9,
195
+ UnloadHandlerTriggered: 10,
196
+ OnloadHandlerTriggered: 11,
197
+ MarkLoadTimeCalled: 12,
198
+ // Data collection events
199
+ SessionIsSampled: 21,
200
+ SessionIsNotSampled: 22,
201
+ MainBeaconSent: 23,
202
+ UserTimingBeaconSent: 24,
203
+ InteractionBeaconSent: 25,
204
+ CustomDataBeaconSent: 26,
205
+ // Metric information
206
+ NavigationStart: 41,
207
+ PerformanceEntryReceived: 42,
208
+ PerformanceEntryProcessed: 43,
209
+ // Errors
210
+ PerformanceObserverError: 51,
211
+ InputEventPermissionError: 52,
212
+ InnerHtmlAccessError: 53,
213
+ EventTargetAccessError: 54,
214
+ CookieReadError: 55,
215
+ CookieSetError: 56,
216
+ PageLabelEvaluationError: 57,
217
+ // Browser support messages
218
+ NavTimingNotSupported: 71,
219
+ PaintTimingNotSupported: 72,
220
+ };
221
+ var Logger = /** @class */ (function () {
222
+ function Logger() {
223
+ this.events = [];
224
+ }
225
+ Logger.prototype.logEvent = function (event, args) {
226
+ if (args === void 0) { args = []; }
227
+ this.events.push([now(), event, args]);
228
+ };
229
+ Logger.prototype.getEvents = function () {
230
+ return this.events;
231
+ };
232
+ return Logger;
233
+ }());
234
+ var sessionValue = 0;
235
+ var sessionEntries = [];
236
+ function addEntry$2(entry) {
237
+ if (!entry.hadRecentInput) {
238
+ var firstEntry = sessionEntries[0];
239
+ var latestEntry = sessionEntries[sessionEntries.length - 1];
240
+ if (sessionEntries.length &&
241
+ (entry.startTime - latestEntry.startTime >= 1000 ||
242
+ entry.startTime - firstEntry.startTime >= 5000)) {
243
+ reset$1();
244
+ }
245
+ sessionValue += entry.value;
246
+ sessionEntries.push(entry);
247
+ }
248
+ }
249
+ function reset$1() {
250
+ sessionValue = 0;
251
+ sessionEntries = [];
252
+ }
253
+ function getCLS() {
254
+ return sessionValue;
255
+ }
256
+
257
+ var scriptStartTime = now();
258
+
180
259
  var _a;
181
260
  // If the various performance APIs aren't available, we export an empty object to
182
261
  // prevent having to make regular typeof checks.
@@ -193,6 +272,32 @@
193
272
  }
194
273
  return now() - timing.navigationStart;
195
274
  }
275
+ function navigationType() {
276
+ if (performance.navigation && typeof performance.navigation.type !== "undefined") {
277
+ return performance.navigation.type;
278
+ }
279
+ return "";
280
+ }
281
+ function getNavigationEntry() {
282
+ var navEntries = getEntriesByType("navigation");
283
+ if (navEntries.length) {
284
+ return navEntries[0];
285
+ }
286
+ var navType = navigationType();
287
+ var entry = {
288
+ activationStart: 0,
289
+ startTime: 0,
290
+ type: navType == 2 ? "back_forward" : navType === 1 ? "reload" : "navigate",
291
+ };
292
+ if (__ENABLE_POLYFILLS) {
293
+ for (var key in timing) {
294
+ if (typeof timing[key] === "number" && key !== "navigationStart") {
295
+ entry[key] = Math.max(0, timing[key] - timing.navigationStart);
296
+ }
297
+ }
298
+ }
299
+ return entry;
300
+ }
196
301
  /**
197
302
  * Simple wrapper around performance.getEntriesByType to provide fallbacks for
198
303
  * legacy browsers, and work around edge cases where undefined is returned instead
@@ -208,91 +313,124 @@
208
313
  return [];
209
314
  }
210
315
 
211
- var Matching = /** @class */ (function () {
212
- function Matching() {
213
- }
214
- Matching.isMatching = function (pattern, url) {
215
- var regexp = Matching.createRegexpFromPattern(pattern);
216
- return url.match(regexp) ? true : false;
217
- };
218
- /**
219
- * Converts string pattern to RegExp object
220
- * @return RegExp
221
- */
222
- Matching.createRegexpFromPattern = function (pattern) {
223
- var regexp;
224
- if (pattern == "/") {
225
- regexp = this.getRegexpForHostnameRoot();
226
- }
227
- else if (!pattern.includes(Matching.wildcard)) {
228
- regexp = this.getRegexpForExactString(pattern);
316
+ /**
317
+ * This implementation is based on the web-vitals implementation, however it is stripped back to the
318
+ * bare minimum required to measure just the INP value and does not store the actual event entries.
319
+ */
320
+ // The maximum number of interactions to store
321
+ var MAX_INTERACTIONS = 10;
322
+ // A list of the slowest interactions
323
+ var slowestEntries = [];
324
+ // A map of the slowest interactions by ID
325
+ var slowestEntriesMap = {};
326
+ // The total number of interactions recorded on the page
327
+ var interactionCountEstimate = 0;
328
+ function reset() {
329
+ interactionCountEstimate = 0;
330
+ slowestEntries = [];
331
+ slowestEntriesMap = {};
332
+ }
333
+ function addEntry$1(entry) {
334
+ if (entry.interactionId || (entry.entryType === "first-input" && !entryExists(entry))) {
335
+ var duration = entry.duration, startTime = entry.startTime, interactionId = entry.interactionId;
336
+ var existingEntry = slowestEntriesMap[interactionId];
337
+ if (existingEntry) {
338
+ existingEntry.duration = Math.max(duration, existingEntry.duration);
229
339
  }
230
340
  else {
231
- regexp = this.createRegexpFromPathname(pattern);
341
+ interactionCountEstimate++;
342
+ slowestEntriesMap[interactionId] = { duration: duration, interactionId: interactionId, startTime: startTime };
343
+ slowestEntries.push(slowestEntriesMap[interactionId]);
344
+ }
345
+ // Only store the longest <MAX_INTERACTIONS> interactions
346
+ slowestEntries.sort(function (a, b) { return b.duration - a.duration; });
347
+ slowestEntries.splice(MAX_INTERACTIONS).forEach(function (entry) {
348
+ delete slowestEntriesMap[entry.interactionId];
349
+ });
350
+ }
351
+ }
352
+ function entryExists(e1) {
353
+ return slowestEntries.some(function (e2) { return e1.startTime === e2.startTime && e1.duration === e2.duration; });
354
+ }
355
+ /**
356
+ * Returns an estimated high percentile INP value based on the total number of interactions on the
357
+ * current page.
358
+ */
359
+ function getHighPercentileINP() {
360
+ var _a;
361
+ var index = Math.min(slowestEntries.length - 1, Math.floor(getInteractionCount() / 50));
362
+ return (_a = slowestEntries[index]) === null || _a === void 0 ? void 0 : _a.duration;
363
+ }
364
+ function getInteractionCount() {
365
+ if ("interactionCount" in performance) {
366
+ return performance.interactionCount;
367
+ }
368
+ return interactionCountEstimate;
369
+ }
370
+
371
+ /******************************************************************************
372
+ Copyright (c) Microsoft Corporation.
373
+
374
+ Permission to use, copy, modify, and/or distribute this software for any
375
+ purpose with or without fee is hereby granted.
376
+
377
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
378
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
379
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
380
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
381
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
382
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
383
+ PERFORMANCE OF THIS SOFTWARE.
384
+ ***************************************************************************** */
385
+
386
+ var __assign = function() {
387
+ __assign = Object.assign || function __assign(t) {
388
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
389
+ s = arguments[i];
390
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
232
391
  }
233
- return regexp;
392
+ return t;
234
393
  };
235
- /**
236
- * Converts URL pathname string pattern to RegExp object
237
- * Multile wildcards (*) are supported
238
- * @return RegExp
239
- */
240
- Matching.createRegexpFromPathname = function (pattern) {
241
- var anyDomain = pattern.charAt(0) == "/";
242
- pattern = this.escapeStringForRegexp(pattern);
243
- var expression = "^" +
244
- (anyDomain ? Matching.domainExpression : "") +
245
- pattern.replaceAll(Matching.wildcard, ".*?") +
246
- "$";
247
- return new RegExp(expression, "i");
248
- };
249
- /**
250
- * Matches hostname root (e.g. "/", "somedomain.com/", "www.somedomain.co.nz/")
251
- * Trailing slash is mandatory
252
- * @return RegExp
253
- */
254
- Matching.getRegexpForHostnameRoot = function () {
255
- return new RegExp("^" + Matching.domainExpression + "/$", "i");
256
- };
257
- /**
258
- * Matches exact string (no wildcard provided)
259
- * @return RegExp
260
- */
261
- Matching.getRegexpForExactString = function (string) {
262
- var anyDomain = string.charAt(0) == "/";
263
- return new RegExp("^" +
264
- (anyDomain ? Matching.domainExpression : "") +
265
- this.escapeStringForRegexp(string) +
266
- "/?$", "i");
267
- };
268
- /**
269
- * Escape special symbols in regexp string
270
- * @param string
271
- */
272
- Matching.escapeStringForRegexp = function (string) {
273
- // we don't escape * because it's our own special symbol!
274
- return string.replace(/[-/\\^$+?.()|[\]{}]/g, "\\$&");
275
- };
276
- Matching.wildcard = "*";
277
- Matching.domainExpression = "[a-zA-Z0-9-.]{1,61}[a-zA-Z0-9]\\.[a-zA-Z]{2,}";
278
- return Matching;
279
- }());
394
+ return __assign.apply(this, arguments);
395
+ };
280
396
 
281
- /**
282
- * Fit an array of user timing delimited strings into a URL and return both the entries that fit and
283
- * the remaining entries that didn't fit.
284
- */
285
- function fitUserTimingEntries(utValues, config, url) {
286
- // Start with the maximum allowed UT entries per beacon
287
- var beaconUtValues = utValues.slice(0, config.maxBeaconUTEntries);
288
- var remainingUtValues = utValues.slice(config.maxBeaconUTEntries);
289
- // Trim UT entries until they fit within the maximum URL length, ensuring at least one UT entry
290
- // is included.
291
- while ((url + "&UT=" + beaconUtValues.join(",")).length > config.maxBeaconUrlLength &&
292
- beaconUtValues.length > 1) {
293
- remainingUtValues.unshift(beaconUtValues.pop());
294
- }
295
- return [beaconUtValues, remainingUtValues];
397
+ var ALL_ENTRIES = [];
398
+ function observe(type, callback, options) {
399
+ if (typeof PerformanceObserver === "function" &&
400
+ PerformanceObserver.supportedEntryTypes.includes(type)) {
401
+ var po = new PerformanceObserver(function (list) {
402
+ list.getEntries().forEach(function (entry) { return callback(entry); });
403
+ });
404
+ po.observe(__assign({ type: type, buffered: true }, options));
405
+ return po;
406
+ }
407
+ return undefined;
408
+ }
409
+ function getEntries(type) {
410
+ return ALL_ENTRIES.filter(function (entry) { return entry.entryType === type; });
411
+ }
412
+ function addEntry(entry) {
413
+ ALL_ENTRIES.push(entry);
414
+ }
415
+ function clearEntries() {
416
+ ALL_ENTRIES.splice(0);
417
+ }
418
+
419
+ function patternMatchesUrl(pattern, hostname, pathname) {
420
+ var regex = createRegExpFromPattern(pattern);
421
+ if (pattern.charAt(0) === "/") {
422
+ // Rule is a pathname only
423
+ return regex.test(pathname);
424
+ }
425
+ // Rule is a hostname and pathname
426
+ return regex.test(hostname + pathname);
427
+ }
428
+ function createRegExpFromPattern(pattern) {
429
+ return new RegExp("^" + escapeStringForRegExp(pattern).replaceAll("*", ".*") + "$", "i");
430
+ }
431
+ function escapeStringForRegExp(str) {
432
+ // Note: we don't escape * because it's our own special symbol!
433
+ return str.replace(/[-/\\^$+?.()|[\]{}]/g, "\\$&");
296
434
  }
297
435
 
298
436
  var LUX = window.LUX || {};
@@ -306,8 +444,7 @@
306
444
  // -------------------------------------------------------------------------
307
445
  /// End
308
446
  // -------------------------------------------------------------------------
309
-
310
- var SCRIPT_VERSION = "305";
447
+ var SCRIPT_VERSION = "307";
311
448
  var logger = new Logger();
312
449
  var globalConfig = fromObject(LUX);
313
450
  logger.logEvent(LogEvent.EvaluationStart, [SCRIPT_VERSION]);
@@ -349,49 +486,53 @@
349
486
  }
350
487
  }
351
488
  window.addEventListener("error", errorHandler);
352
- // Initialize performance observer
353
- // Note: This code was later added to the LUX snippet. In the snippet we ONLY collect
354
- // Long Task entries because that is the only entry type that can not be buffered.
355
- // We _copy_ any Long Tasks collected by the snippet and ignore it after that.
356
- var gaSnippetLongTasks = typeof window.LUX_al === "object" ? window.LUX_al : [];
357
- var gaPerfEntries = gaSnippetLongTasks.slice(); // array of Long Tasks (prefer the array from the snippet)
358
- if (typeof PerformanceObserver === "function") {
359
- var perfObserver = new PerformanceObserver(function (list) {
360
- list.getEntries().forEach(function (entry) {
361
- logger.logEvent(LogEvent.PerformanceEntryReceived, [entry]);
362
- // Only record long tasks that weren't already recorded by the PerformanceObserver in the snippet
363
- if (entry.entryType !== "longtask" || gaPerfEntries.indexOf(entry) === -1) {
364
- gaPerfEntries.push(entry);
365
- }
366
- });
367
- });
368
- try {
369
- if (typeof PerformanceLongTaskTiming === "function") {
370
- perfObserver.observe({ type: "longtask", buffered: true });
371
- }
372
- if (typeof LargestContentfulPaint === "function") {
373
- perfObserver.observe({ type: "largest-contentful-paint", buffered: true });
374
- }
375
- if (typeof PerformanceElementTiming === "function") {
376
- perfObserver.observe({ type: "element", buffered: true });
377
- }
378
- if (typeof PerformancePaintTiming === "function") {
379
- perfObserver.observe({ type: "paint", buffered: true });
489
+ var logEntry = function (entry) {
490
+ logger.logEvent(LogEvent.PerformanceEntryReceived, [entry]);
491
+ };
492
+ // Most PerformanceEntry types we log an event for and add it to the global entry store.
493
+ var processAndLogEntry = function (entry) {
494
+ addEntry(entry);
495
+ logEntry(entry);
496
+ };
497
+ // Before long tasks were buffered, we added a PerformanceObserver to the lux.js snippet to capture
498
+ // any long tasks that occurred before the full script was loaded. To deal with this, we process
499
+ // all of the snippet long tasks, and we check for double-ups in the new PerformanceObserver.
500
+ var snippetLongTasks = typeof window.LUX_al === "object" ? window.LUX_al : [];
501
+ snippetLongTasks.forEach(processAndLogEntry);
502
+ try {
503
+ observe("longtask", function (entry) {
504
+ if (ALL_ENTRIES.indexOf(entry) === -1) {
505
+ processAndLogEntry(entry);
380
506
  }
381
- if (typeof LayoutShift === "function") {
382
- perfObserver.observe({ type: "layout-shift", buffered: true });
507
+ });
508
+ observe("largest-contentful-paint", processAndLogEntry);
509
+ observe("element", processAndLogEntry);
510
+ observe("paint", processAndLogEntry);
511
+ observe("layout-shift", function (entry) {
512
+ addEntry$2(entry);
513
+ logEntry(entry);
514
+ });
515
+ observe("first-input", function (entry) {
516
+ var fid = entry.processingStart - entry.startTime;
517
+ if (!gFirstInputDelay || gFirstInputDelay < fid) {
518
+ gFirstInputDelay = fid;
383
519
  }
384
- }
385
- catch (e) {
386
- logger.logEvent(LogEvent.PerformanceObserverError, [e]);
387
- }
520
+ // Allow first-input events to be considered for INP
521
+ addEntry$1(entry);
522
+ });
523
+ // TODO: Add { durationThreshold: 40 } once performance.interactionCount is widely supported.
524
+ // Right now we have to count every event to get the total interaction count so that we can
525
+ // estimate a high percentile value for INP.
526
+ observe("event", addEntry$1);
527
+ }
528
+ catch (e) {
529
+ logger.logEvent(LogEvent.PerformanceObserverError, [e]);
388
530
  }
389
531
  // Bitmask of flags for this session & page
390
532
  var gFlags = 0;
391
533
  var gaMarks = [];
392
534
  var gaMeasures = [];
393
535
  var ghIx = {}; // hash for Interaction Metrics (scroll, click, keyboard)
394
- var ghData = {}; // hash for data that is specific to the customer (eg, userid, conversion info)
395
536
  var gbLuxSent = 0; // have we sent the LUX data? (avoid sending twice in unload)
396
537
  var gbNavSent = 0; // have we sent the Nav Timing beacon yet? (avoid sending twice for SPA)
397
538
  var gbIxSent = 0; // have we sent the IX data? (avoid sending twice for SPA)
@@ -417,7 +558,7 @@
417
558
  // FIRST INPUT DELAY (FID)
418
559
  // The basic idea behind FID is to attach various input event listeners and measure the time
419
560
  // between when the event happens and when the handler executes. That is FID.
420
- var gFirstInputDelay; // this is FID
561
+ var gFirstInputDelay;
421
562
  var gaEventTypes = ["click", "mousedown", "keydown", "touchstart", "pointerdown"]; // NOTE: does NOT include scroll!
422
563
  var ghListenerOptions = { passive: true, capture: true };
423
564
  // Record the FIRST input delay.
@@ -587,7 +728,9 @@
587
728
  var startTime = typeof startMarkName === "number" ? startMarkName : 0;
588
729
  var endTime = typeof endMarkName === "number" ? endMarkName : _now();
589
730
  var throwError = function (missingMark) {
590
- throw new DOMException("Failed to execute 'measure' on 'Performance': The mark '".concat(missingMark, "' does not exist"));
731
+ throw new DOMException("Failed to execute 'measure' on 'Performance': The mark '" +
732
+ missingMark +
733
+ "' does not exist");
591
734
  };
592
735
  if (typeof startMarkName === "string") {
593
736
  var startMark = _getMark(startMarkName);
@@ -724,60 +867,56 @@
724
867
  // Return a string of Element Timing Metrics formatted for beacon querystring.
725
868
  function elementTimingValues() {
726
869
  var aET = [];
727
- if (gaPerfEntries.length) {
728
- for (var i = 0; i < gaPerfEntries.length; i++) {
729
- var pe = gaPerfEntries[i];
730
- if ("element" === pe.entryType && pe.identifier && pe.startTime) {
731
- logger.logEvent(LogEvent.PerformanceEntryProcessed, [pe]);
732
- aET.push(pe.identifier + "|" + Math.round(pe.startTime));
733
- }
870
+ var startMark = _getMark(START_MARK);
871
+ var tZero = startMark ? startMark.startTime : 0;
872
+ getEntries("element").forEach(function (entry) {
873
+ if (entry.identifier && entry.startTime) {
874
+ logger.logEvent(LogEvent.PerformanceEntryProcessed, [entry]);
875
+ aET.push(entry.identifier + "|" + Math.round(entry.startTime - tZero));
734
876
  }
735
- }
877
+ });
736
878
  return aET.join(",");
737
879
  }
738
880
  // Return a string of CPU times formatted for beacon querystring.
739
881
  function cpuTimes() {
740
- if (typeof PerformanceLongTaskTiming !== "function") {
882
+ if (!("PerformanceLongTaskTiming" in self)) {
741
883
  // Do not return any CPU metrics if Long Tasks API is not supported.
742
884
  return "";
743
885
  }
744
886
  var sCPU = "";
745
887
  var hCPU = {};
746
888
  var hCPUDetails = {}; // TODO - Could remove this later after large totals go away.
889
+ var longTaskEntries = getEntries("longtask");
747
890
  // Add up totals for each "type" of long task
748
- if (gaPerfEntries.length) {
891
+ if (longTaskEntries.length) {
749
892
  // Long Task start times are relative to NavigationStart which is "0".
750
893
  // But if it is a SPA then the relative start time is gStartMark.
751
894
  var startMark = _getMark(START_MARK);
752
- var tZero = startMark ? startMark.startTime : 0;
895
+ var tZero_1 = startMark ? startMark.startTime : 0;
753
896
  // Do not include Long Tasks that start after the page is done.
754
897
  // For full page loads, "done" is loadEventEnd.
755
- var tEnd = timing.loadEventEnd - timing.navigationStart;
898
+ var tEnd_1 = timing.loadEventEnd - timing.navigationStart;
756
899
  if (startMark) {
757
900
  // For SPA page loads (determined by the presence of a start mark), "done" is gEndMark.
758
901
  var endMark = _getMark(END_MARK);
759
902
  if (endMark) {
760
- tEnd = endMark.startTime;
903
+ tEnd_1 = endMark.startTime;
761
904
  }
762
905
  }
763
- for (var i = 0; i < gaPerfEntries.length; i++) {
764
- var p = gaPerfEntries[i];
765
- if ("longtask" !== p.entryType) {
766
- continue;
767
- }
768
- var dur = Math.round(p.duration);
769
- if (p.startTime < tZero) {
906
+ longTaskEntries.forEach(function (entry) {
907
+ var dur = Math.round(entry.duration);
908
+ if (entry.startTime < tZero_1) {
770
909
  // In a SPA it is possible that we were in the middle of a Long Task when
771
910
  // LUX.init() was called. If so, only include the duration after tZero.
772
- dur -= tZero - p.startTime;
911
+ dur -= tZero_1 - entry.startTime;
773
912
  }
774
- else if (p.startTime >= tEnd) {
913
+ else if (entry.startTime >= tEnd_1) {
775
914
  // In a SPA it is possible that a Long Task started after loadEventEnd but before our
776
915
  // callback from setTimeout(200) happened. Do not include anything that started after tEnd.
777
- continue;
916
+ return;
778
917
  }
779
- logger.logEvent(LogEvent.PerformanceEntryProcessed, [p]);
780
- var type = p.attribution[0].name; // TODO - is there ever more than 1 attribution???
918
+ logger.logEvent(LogEvent.PerformanceEntryProcessed, [entry]);
919
+ var type = entry.attribution[0].name; // TODO - is there ever more than 1 attribution???
781
920
  if (!hCPU[type]) {
782
921
  // initialize this category
783
922
  hCPU[type] = 0;
@@ -785,8 +924,8 @@
785
924
  }
786
925
  hCPU[type] += dur;
787
926
  // Send back the raw startTime and duration, as well as the adjusted duration.
788
- hCPUDetails[type] += "," + Math.round(p.startTime) + "|" + dur;
789
- }
927
+ hCPUDetails[type] += "," + Math.round(entry.startTime) + "|" + dur;
928
+ });
790
929
  }
791
930
  // TODO - Add more types if/when they become available.
792
931
  var jsType = typeof hCPU["script"] !== "undefined" ? "script" : "unknown"; // spec changed from "script" to "unknown" Nov 2018
@@ -803,14 +942,14 @@
803
942
  ",x|" +
804
943
  hStats["max"] +
805
944
  (0 === hStats["fci"] ? "" : ",i|" + hStats["fci"]); // only add FCI if it is non-zero
806
- sCPU += "s|" + hCPU[jsType] + sStats + hCPUDetails[jsType];
945
+ sCPU += "s|" + hCPU[jsType] + sStats + hCPUDetails[jsType];
807
946
  return sCPU;
808
947
  }
809
948
  // Return a hash of "stats" about the CPU details incl. count, max, and median.
810
949
  function cpuStats(sDetails) {
811
950
  // tuples of starttime|duration, eg: ,456|250,789|250,1012|250
812
951
  var max = 0;
813
- var fci = getFcp(); // FCI is beginning of 5 second window of no Long Tasks _after_ first contentful paint
952
+ var fci = getFcp() || 0; // FCI is beginning of 5 second window of no Long Tasks _after_ first contentful paint
814
953
  // If FCP is 0 then that means FCP is not supported.
815
954
  // If FCP is not supported then we can NOT calculate a valid FCI.
816
955
  // Thus, leave FCI = 0 and exclude it from the beacon above.
@@ -843,22 +982,13 @@
843
982
  var median = arrayMedian(aValues);
844
983
  return { count: count, median: median, max: max, fci: fci };
845
984
  }
846
- function calculateDCLS() {
847
- if (typeof LayoutShift !== "function") {
848
- return false;
985
+ function getCLS$1() {
986
+ if (!("LayoutShift" in self)) {
987
+ return undefined;
849
988
  }
850
- var DCLS = 0;
851
- for (var i = 0; i < gaPerfEntries.length; i++) {
852
- var p = gaPerfEntries[i];
853
- if ("layout-shift" !== p.entryType || p.hadRecentInput) {
854
- continue;
855
- }
856
- logger.logEvent(LogEvent.PerformanceEntryProcessed, [p]);
857
- DCLS += p.value;
858
- }
859
- // The DCL column in Redshift is REAL (FLOAT4) which stores a maximum
989
+ // The DCLS column in Redshift is REAL (FLOAT4) which stores a maximum
860
990
  // of 6 significant digits.
861
- return DCLS.toFixed(6);
991
+ return getCLS().toFixed(6);
862
992
  }
863
993
  // Return the median value from an array of integers.
864
994
  function arrayMedian(aValues) {
@@ -935,17 +1065,10 @@
935
1065
  }
936
1066
  return aIx.join(",");
937
1067
  }
938
- // _addData()
939
1068
  function _addData(name, value) {
940
1069
  logger.logEvent(LogEvent.AddDataCalled, [name, value]);
941
- var typeV = typeof value;
942
1070
  if (typeof name === "string") {
943
- if (typeV === "string" || typeV === "number" || typeV === "boolean") {
944
- ghData[name] = value;
945
- }
946
- if (typeV === "undefined" || value === null) {
947
- delete ghData[name];
948
- }
1071
+ addCustomDataValue(name, value);
949
1072
  }
950
1073
  if (gbLuxSent) {
951
1074
  // This is special: We want to allow customers to call LUX.addData()
@@ -956,7 +1079,7 @@
956
1079
  if (gCustomerDataTimeout) {
957
1080
  // Cancel the timer for any previous beacons so that if they have not
958
1081
  // yet been sent we can combine all the data in a new beacon.
959
- clearTimeout(gCustomerDataTimeout);
1082
+ window.clearTimeout(gCustomerDataTimeout);
960
1083
  }
961
1084
  gCustomerDataTimeout = window.setTimeout(_sendCustomerData, 100);
962
1085
  }
@@ -970,18 +1093,6 @@
970
1093
  var nThis = ("" + gUid).substr(-2); // number for THIS page - from 00 to 99
971
1094
  return parseInt(nThis) < globalConfig.samplerate;
972
1095
  }
973
- // Return a string of Customer Data formatted for beacon querystring.
974
- function customerDataValues() {
975
- var aData = [];
976
- for (var key in ghData) {
977
- var value = "" + ghData[key]; // convert to string (eg for ints and booleans)
978
- // strip delimiters (instead of escaping)
979
- key = key.replace(/,/g, "").replace(/\|/g, "");
980
- value = value.replace(/,/g, "").replace(/\|/g, "");
981
- aData.push(key + "|" + value);
982
- }
983
- return encodeURIComponent(aData.join(","));
984
- }
985
1096
  // _init()
986
1097
  // Use this function in Single Page Apps to reset things.
987
1098
  // This function should ONLY be called within a SPA!
@@ -1007,8 +1118,11 @@
1007
1118
  gbFirstPV = 0;
1008
1119
  gSyncId = createSyncId();
1009
1120
  gUid = refreshUniqueId(gSyncId);
1010
- gaPerfEntries.splice(0); // clear out the array of performance entries (do NOT redefine gaPerfEntries!)
1121
+ clearEntries();
1122
+ reset$1();
1123
+ reset();
1011
1124
  nErrors = 0;
1125
+ gFirstInputDelay = undefined;
1012
1126
  // Clear flags then set the flag that init was called (ie, this is a SPA).
1013
1127
  gFlags = 0;
1014
1128
  gFlags = addFlag(gFlags, Flags.InitCalled);
@@ -1031,9 +1145,12 @@
1031
1145
  var num = 0;
1032
1146
  for (var i = 0, len = aElems.length; i < len; i++) {
1033
1147
  var e = aElems[i];
1034
- if (e.src && !e.async && !e.defer && 0 !== (e.compareDocumentPosition(lastViewportElem) & 4)) {
1035
- // If the script has a SRC and async is false and it occurs BEFORE the last viewport element,
1036
- // then increment the counter.
1148
+ if (e.src &&
1149
+ !e.async &&
1150
+ !e.defer &&
1151
+ 0 !== (e.compareDocumentPosition(lastViewportElem) & 4)) {
1152
+ // If the script has a SRC and async is false and it occurs BEFORE the last viewport element,
1153
+ // then increment the counter.
1037
1154
  num++;
1038
1155
  }
1039
1156
  }
@@ -1158,9 +1275,9 @@
1158
1275
  (t.domComplete ? "oc" + (t.domComplete - ns) : "") +
1159
1276
  (t.loadEventStart ? "ls" + (t.loadEventStart - ns) : "") +
1160
1277
  (t.loadEventEnd ? "le" + (t.loadEventEnd - ns) : "") +
1161
- (startRender ? "sr" + startRender : "") +
1162
- (fcp ? "fc" + fcp : "") +
1163
- (lcp ? "lc" + lcp : "") +
1278
+ (typeof startRender !== "undefined" ? "sr" + startRender : "") +
1279
+ (typeof fcp !== "undefined" ? "fc" + fcp : "") +
1280
+ (typeof lcp !== "undefined" ? "lc" + lcp : "") +
1164
1281
  "";
1165
1282
  }
1166
1283
  else if (endMark) {
@@ -1178,7 +1295,7 @@
1178
1295
  }
1179
1296
  return s;
1180
1297
  }
1181
- // Return First Contentful Paint or zero if not supported.
1298
+ // Return First Contentful Paint or undefined if not supported.
1182
1299
  function getFcp() {
1183
1300
  var paintEntries = getEntriesByType("paint");
1184
1301
  for (var i = 0; i < paintEntries.length; i++) {
@@ -1187,25 +1304,21 @@
1187
1304
  return Math.round(entry.startTime);
1188
1305
  }
1189
1306
  }
1190
- return 0;
1307
+ return undefined;
1191
1308
  }
1192
- // Return Largest Contentful Paint or zero if not supported.
1309
+ // Return Largest Contentful Paint or undefined if not supported.
1193
1310
  function getLcp() {
1194
- if (gaPerfEntries.length) {
1195
- // Find the *LAST* LCP per https://web.dev/largest-contentful-paint
1196
- for (var i = gaPerfEntries.length - 1; i >= 0; i--) {
1197
- var pe = gaPerfEntries[i];
1198
- if ("largest-contentful-paint" === pe.entryType) {
1199
- logger.logEvent(LogEvent.PerformanceEntryProcessed, [pe]);
1200
- return Math.round(pe.startTime);
1201
- }
1202
- }
1311
+ var lcpEntries = getEntries("largest-contentful-paint");
1312
+ if (lcpEntries.length) {
1313
+ var lastEntry = lcpEntries[lcpEntries.length - 1];
1314
+ logger.logEvent(LogEvent.PerformanceEntryProcessed, [lastEntry]);
1315
+ return Math.max(0, Math.round(lastEntry.startTime - getNavigationEntry().activationStart));
1203
1316
  }
1204
- return 0;
1317
+ return undefined;
1205
1318
  }
1206
1319
  // Return best guess at Start Render time (in ms).
1207
1320
  // Mostly works on just Chrome and IE.
1208
- // Return null if not supported.
1321
+ // Return undefined if not supported.
1209
1322
  function getStartRender() {
1210
1323
  if (performance.timing) {
1211
1324
  var paintEntries = getEntriesByType("paint");
@@ -1224,20 +1337,23 @@
1224
1337
  }
1225
1338
  }
1226
1339
  logger.logEvent(LogEvent.PaintTimingNotSupported);
1227
- return null;
1340
+ return undefined;
1228
1341
  }
1229
- function getCustomerId() {
1230
- if (typeof LUX.customerid !== "undefined") {
1231
- // Return the id explicitly set in the JavaScript variable.
1232
- return LUX.customerid;
1342
+ function getINP() {
1343
+ if (!("PerformanceEventTiming" in self)) {
1344
+ return undefined;
1233
1345
  }
1234
- // Extract the id of the lux.js script element.
1235
- var luxScript = getScriptElement("/js/lux.js");
1236
- if (luxScript) {
1237
- LUX.customerid = getQuerystringParam(luxScript.src, "id");
1238
- return LUX.customerid;
1346
+ return getHighPercentileINP();
1347
+ }
1348
+ function getCustomerId() {
1349
+ if (typeof LUX.customerid === "undefined") {
1350
+ // Extract the id of the lux.js script element.
1351
+ var luxScript = getScriptElement("/js/lux.js");
1352
+ if (luxScript) {
1353
+ LUX.customerid = getQuerystringParam(luxScript.src, "id");
1354
+ }
1239
1355
  }
1240
- return "";
1356
+ return LUX.customerid || "";
1241
1357
  }
1242
1358
  // Return the SCRIPT DOM element whose SRC contains the URL snippet.
1243
1359
  // This is used to find the LUX script element.
@@ -1249,7 +1365,7 @@
1249
1365
  return script;
1250
1366
  }
1251
1367
  }
1252
- return null;
1368
+ return undefined;
1253
1369
  }
1254
1370
  function getQuerystringParam(url, name) {
1255
1371
  var qs = url.split("?")[1];
@@ -1295,19 +1411,7 @@
1295
1411
  }
1296
1412
  // Return the main HTML document transfer size (in bytes).
1297
1413
  function docSize() {
1298
- var aEntries = getEntriesByType("navigation");
1299
- if (aEntries.length && aEntries[0]["encodedBodySize"]) {
1300
- return aEntries[0]["encodedBodySize"];
1301
- }
1302
- return 0; // ERROR - NOT FOUND
1303
- }
1304
- // Return the navigation type. 0 = normal, 1 = reload, etc.
1305
- // Return empty string if not available.
1306
- function navigationType() {
1307
- if (performance.navigation && typeof performance.navigation.type !== "undefined") {
1308
- return performance.navigation.type;
1309
- }
1310
- return "";
1414
+ return getNavigationEntry().encodedBodySize || 0;
1311
1415
  }
1312
1416
  // Return the connection type based on Network Information API.
1313
1417
  // Note this API is in flux.
@@ -1421,10 +1525,10 @@
1421
1525
  }
1422
1526
  function clearMaxMeasureTimeout() {
1423
1527
  if (gMaxMeasureTimeout) {
1424
- clearTimeout(gMaxMeasureTimeout);
1528
+ window.clearTimeout(gMaxMeasureTimeout);
1425
1529
  }
1426
1530
  }
1427
- function _getBeaconUrl() {
1531
+ function _getBeaconUrl(customData) {
1428
1532
  var queryParams = [
1429
1533
  "v=" + SCRIPT_VERSION,
1430
1534
  "id=" + getCustomerId(),
@@ -1437,9 +1541,10 @@
1437
1541
  if (gFlags) {
1438
1542
  queryParams.push("fl=" + gFlags);
1439
1543
  }
1440
- var customerData = customerDataValues();
1544
+ var customerData = valuesToString(customData);
1441
1545
  if (customerData) {
1442
1546
  queryParams.push("CD=" + customerData);
1547
+ clearUpdateCustomData();
1443
1548
  }
1444
1549
  return globalConfig.beaconUrl + "?" + queryParams.join("&");
1445
1550
  }
@@ -1463,22 +1568,28 @@
1463
1568
  // with LUX.markLoadTime()
1464
1569
  _markLoadTime();
1465
1570
  }
1466
- var sET = elementTimingValues(); // Element Timing data
1467
- var sIx = ""; // Interaction Metrics
1571
+ var sIx = "";
1572
+ var INP = getINP();
1573
+ // It's possible that the interaction beacon has been sent before the main beacon. We don't want
1574
+ // to send the interaction metrics twice, so we only include them here if the interaction beacon
1575
+ // has not been sent.
1468
1576
  if (!gbIxSent) {
1469
- // It is possible for the IX beacon to be sent BEFORE the "main" window.onload LUX beacon.
1470
- // Make sure we do not send the IX data twice.
1471
1577
  sIx = ixValues();
1578
+ if (sIx === "") {
1579
+ // If there are no interaction metrics, we
1580
+ INP = undefined;
1581
+ }
1472
1582
  }
1583
+ var sET = elementTimingValues(); // Element Timing data
1473
1584
  var sCPU = cpuTimes();
1474
- var DCLS = calculateDCLS();
1585
+ var CLS = getCLS$1();
1475
1586
  var sLuxjs = selfLoading();
1476
1587
  if (document.visibilityState && "visible" !== document.visibilityState) {
1477
1588
  gFlags = addFlag(gFlags, Flags.VisibilityStateNotVisible);
1478
1589
  }
1479
1590
  // We want ALL beacons to have ALL the data used for query filters (geo, pagelabel, browser, & customerdata).
1480
1591
  // So we create a base URL that has all the necessary information:
1481
- var baseUrl = _getBeaconUrl();
1592
+ var baseUrl = _getBeaconUrl(getAllCustomData());
1482
1593
  var is = inlineTagSize("script");
1483
1594
  var ic = inlineTagSize("style");
1484
1595
  var metricsQueryString =
@@ -1517,13 +1628,14 @@
1517
1628
  "er" +
1518
1629
  nErrors +
1519
1630
  "nt" +
1520
- navigationType() + // reload
1631
+ navigationType() +
1521
1632
  (navigator.deviceMemory ? "dm" + Math.round(navigator.deviceMemory) : "") + // device memory (GB)
1522
1633
  (sIx ? "&IX=" + sIx : "") +
1523
1634
  (typeof gFirstInputDelay !== "undefined" ? "&FID=" + gFirstInputDelay : "") +
1524
1635
  (sCPU ? "&CPU=" + sCPU : "") +
1525
1636
  (sET ? "&ET=" + sET : "") + // element timing
1526
- (DCLS !== false ? "&CLS=" + DCLS : "");
1637
+ (typeof CLS !== "undefined" ? "&CLS=" + CLS : "") +
1638
+ (typeof INP !== "undefined" ? "&INP=" + INP : "");
1527
1639
  // We add the user timing entries last so that we can split them to reduce the URL size if necessary.
1528
1640
  var utValues = userTimingValues();
1529
1641
  var _b = fitUserTimingEntries(utValues, globalConfig, baseUrl + metricsQueryString), beaconUtValues = _b[0], remainingUtValues = _b[1];
@@ -1545,6 +1657,11 @@
1545
1657
  _sendBeacon(utBeaconUrl);
1546
1658
  }
1547
1659
  }
1660
+ var ixTimerId;
1661
+ function _sendIxAfterDelay() {
1662
+ window.clearTimeout(ixTimerId);
1663
+ ixTimerId = window.setTimeout(_sendIx, 100);
1664
+ }
1548
1665
  // Beacon back the IX data separately (need to sync with LUX beacon on the backend).
1549
1666
  function _sendIx() {
1550
1667
  var customerid = getCustomerId();
@@ -1557,11 +1674,13 @@
1557
1674
  return;
1558
1675
  }
1559
1676
  var sIx = ixValues(); // Interaction Metrics
1677
+ var INP = getINP();
1560
1678
  if (sIx) {
1561
- var beaconUrl = _getBeaconUrl() +
1679
+ var beaconUrl = _getBeaconUrl(getUpdatedCustomData()) +
1562
1680
  "&IX=" +
1563
1681
  sIx +
1564
- (typeof gFirstInputDelay !== "undefined" ? "&FID=" + gFirstInputDelay : "");
1682
+ (typeof gFirstInputDelay !== "undefined" ? "&FID=" + gFirstInputDelay : "") +
1683
+ (typeof INP !== "undefined" ? "&INP=" + INP : "");
1565
1684
  logger.logEvent(LogEvent.InteractionBeaconSent, [beaconUrl]);
1566
1685
  _sendBeacon(beaconUrl);
1567
1686
  gbIxSent = 1;
@@ -1578,9 +1697,9 @@
1578
1697
  ) {
1579
1698
  return;
1580
1699
  }
1581
- var sCustomerData = customerDataValues(); // customer data
1700
+ var sCustomerData = valuesToString(getUpdatedCustomData());
1582
1701
  if (sCustomerData) {
1583
- var beaconUrl = _getBeaconUrl();
1702
+ var beaconUrl = _getBeaconUrl(getUpdatedCustomData());
1584
1703
  logger.logEvent(LogEvent.CustomDataBeaconSent, [beaconUrl]);
1585
1704
  _sendBeacon(beaconUrl);
1586
1705
  }
@@ -1596,11 +1715,10 @@
1596
1715
  // Most of the time, however, IX happens *after* LUX, so we send a separate IX beacon but
1597
1716
  // only beacon back the first interaction that happens.
1598
1717
  function _scrollHandler() {
1599
- // Leave handlers IN PLACE so we can track which ID is clicked/keyed.
1600
- // _removeIxHandlers();
1718
+ // Note for scroll input we don't remove the handlers or send the IX beacon because we want to
1719
+ // capture click and key events as well, since these are typically more important than scrolls.
1601
1720
  if (typeof ghIx["s"] === "undefined") {
1602
1721
  ghIx["s"] = Math.round(_now());
1603
- // _sendIx(); // wait for key or click to send the IX beacon
1604
1722
  }
1605
1723
  }
1606
1724
  function _keyHandler(e) {
@@ -1613,7 +1731,7 @@
1613
1731
  ghIx["ki"] = trackId;
1614
1732
  }
1615
1733
  }
1616
- _sendIx();
1734
+ _sendIxAfterDelay();
1617
1735
  }
1618
1736
  }
1619
1737
  function _clickHandler(e) {
@@ -1641,7 +1759,7 @@
1641
1759
  ghIx["ci"] = trackId;
1642
1760
  }
1643
1761
  }
1644
- _sendIx();
1762
+ _sendIxAfterDelay();
1645
1763
  }
1646
1764
  }
1647
1765
  // Wrapper to support older browsers (<= IE8)
@@ -1706,9 +1824,9 @@
1706
1824
  if (inSampleBucket === void 0) { inSampleBucket = false; }
1707
1825
  if (inSampleBucket) {
1708
1826
  // "00" matches all sample rates
1709
- return "".concat(Number(new Date()), "00000");
1827
+ return Number(new Date()) + "00000";
1710
1828
  }
1711
- return "".concat(Number(new Date())).concat(_padLeft(String(Math.round(100000 * Math.random())), "00000"));
1829
+ return Number(new Date()) + _padLeft(String(Math.round(100000 * Math.random())), "00000");
1712
1830
  }
1713
1831
  // Unique ID (also known as Session ID)
1714
1832
  // We use this to track all the page views in a single user session.
@@ -1749,13 +1867,12 @@
1749
1867
  }
1750
1868
  else if (typeof LUX.pagegroups !== "undefined") {
1751
1869
  var pagegroups = LUX.pagegroups;
1752
- var url_1 = "".concat(document.location.hostname).concat(document.location.pathname);
1753
1870
  var label_1 = "";
1754
1871
  var _loop_1 = function (pagegroup) {
1755
1872
  var rules = pagegroups[pagegroup];
1756
1873
  if (Array.isArray(rules)) {
1757
1874
  rules.every(function (rule) {
1758
- if (Matching.isMatching(rule, url_1)) {
1875
+ if (patternMatchesUrl(rule, document.location.hostname, document.location.pathname)) {
1759
1876
  label_1 = pagegroup;
1760
1877
  return false; // stop when first match is found
1761
1878
  }
@@ -1763,7 +1880,7 @@
1763
1880
  });
1764
1881
  }
1765
1882
  // exits loop when first match is found
1766
- if (label_1.length) {
1883
+ if (label_1) {
1767
1884
  gFlags = addFlag(gFlags, Flags.PageLabelFromPagegroup);
1768
1885
  return { value: label_1 };
1769
1886
  }
@@ -1771,11 +1888,11 @@
1771
1888
  for (var pagegroup in pagegroups) {
1772
1889
  var state_1 = _loop_1(pagegroup);
1773
1890
  if (typeof state_1 === "object")
1774
- return state_1.value;
1891
+ return state_1.value;
1775
1892
  }
1776
1893
  }
1777
1894
  if (typeof LUX.jspagelabel !== "undefined") {
1778
- var evaluateJsPageLabel = Function("\"use strict\"; return ".concat(LUX.jspagelabel));
1895
+ var evaluateJsPageLabel = Function('"use strict"; return ' + LUX.jspagelabel);
1779
1896
  try {
1780
1897
  var label = evaluateJsPageLabel();
1781
1898
  if (label) {
@@ -1912,7 +2029,6 @@
1912
2029
  })();
1913
2030
  window.LUX = LUX;
1914
2031
  scriptEndTime = now();
1915
-
1916
2032
  // ---------------------------------------------------------------------------
1917
2033
  // More settings
1918
2034
  // ---------------------------------------------------------------------------
@@ -1934,3 +2050,4 @@
1934
2050
  // End of more settings
1935
2051
  // ---------------------------------------------------------------------------
1936
2052
  })();
2053
+ //# sourceMappingURL=lux.js.map