1//#region Assets/js-libs/launch-darkly/launchdarkly-client.mjs 2var _client = null; 3var _resolveReady; 4var _ready = new Promise((resolve) => { 5 _resolveReady = resolve; 6}); 7function buildContext(userKey, station, anonymous, pageType) { 8 return { 9 kind: "user", 10 key: userKey || "anonymous", 11 anonymous: anonymous === true, 12 station: station ? station.trim().toUpperCase() : void 0, 13 device_type: /Mobi|Android|iPhone|iPad/i.test(navigator.userAgent) ? "mobile" : "desktop", 14 page_type: pageType || "unknown" 15 }; 16} 17function init(initializeFn, clientSideId, userKey, station, anonymous, pageType) { 18 const context = buildContext(userKey, station, anonymous, pageType); 19 if (typeof initializeFn !== "function") { 20 console.warn("[LD] LaunchDarkly SDK (initialize) is not available; skipping initialization."); 21 _resolveReady(); 22 return _ready; 23 } 24 try { 25 _client = initializeFn(clientSideId, context, { application: { id: "tegna-web-" + (context.station || "unknown").toLowerCase() } }); 26 } catch (e) { 27 console.warn("[LD] LaunchDarkly initialize threw an error", e); 28 _resolveReady(); 29 return _ready; 30 } 31 _client.waitForInitialization(5).catch(function(err) { 32 console.warn("[LD] LaunchDarkly failed to initialize", err); 33 }).finally(function() { 34 _resolveReady(); 35 }); 36 return _ready; 37} 38function getLdOverride(flagKey) { 39 const el = document.querySelector("[data-ld-overrides]"); 40 if (!el) return void 0; 41 try { 42 const overrides = JSON.parse(el.dataset.ldOverrides || "{}"); 43 if (!(flagKey in overrides)) return void 0; 44 return overrides[flagKey]; 45 } catch (_e) { 46 return; 47 } 48} 49var READY_TIMEOUT_MS = 3e3; 50function awaitReady() { 51 return Promise.race([_ready, new Promise(function(resolve) { 52 window.setTimeout(resolve, READY_TIMEOUT_MS); 53 })]); 54} 55function getFlag(flagKey, defaultValue) { 56 defaultValue = defaultValue === void 0 ? null : defaultValue; 57 const override = getLdOverride(flagKey); 58 if (override !== void 0) return Promise.resolve(override); 59 return awaitReady().then(function() { 60 return _client ? _client.variation(flagKey, defaultValue) : defaultValue; 61 }); 62} 63function getFlags(flagKeys, defaultValue) { 64 defaultValue = defaultValue === void 0 ? null : defaultValue; 65 return awaitReady().then(function() { 66 const result = {}; 67 flagKeys.forEach(function(key) { 68 result[key] = _client ? _client.variation(key, defaultValue) : defaultValue; 69 }); 70 return result; 71 }); 72} 73function getAllFlags() { 74 return awaitReady().then(function() { 75 return _client ? _client.allFlags() : {}; 76 }); 77} 78function trackEvent(eventKey) { 79 if (_client) _client.track(eventKey); 80} 81function identify(userKey, station, anonymous, pageType) { 82 if (!_client) return Promise.resolve(); 83 return _client.identify(buildContext(userKey, station, anonymous, pageType)); 84} 85var LD = { 86 init, 87 getFlag, 88 getFlags, 89 getAllFlags, 90 trackEvent, 91 identify 92}; 93//#endregion 94//#region Assets/js-libs/tegna-utils/tegna-utils.mjs 95var AjaxModule = class extends HTMLElement { 96 get auto() { 97 return this.hasAttribute("auto"); 98 } 99 async load(callback) { 100 let moduleConfig = {}; 101 for (let d in this.dataset) moduleConfig[d] = this.dataset[d]; 102 const url = "/ajax/content/module"; 103 const rvt = document.querySelector("[name=\"__RequestVerificationToken\"]").value; 104 (await fetch(url, { 105 "method": "POST", 106 "mode": "same-origin", 107 "headers": { 108 "Content-Type": "application/json", 109 "XSRF-TOKEN": rvt 110 }, 111 "body": JSON.stringify(moduleConfig) 112 })).text().then((res) => { 113 this.innerHTML = res; 114 let moduleList = []; 115 this.querySelectorAll("[data-module]").forEach((module) => { 116 const moduleName = module.dataset.module; 117 moduleList.push(moduleName); 118 }); 119 window.require(moduleList, () => { 120 utils.broadcast("grid", "addedSection", { "el": this }); 121 utils.broadcast("responsive-grid", "addedSection", { "el": this }); 122 }); 123 if (typeof callback === "function") callback(); 124 }); 125 } 126 constructor() { 127 super(); 128 if (this.auto) this.load(); 129 else new IntersectionObserver((entries, obs) => { 130 if (entries[0].isIntersecting) { 131 obs.disconnect(); 132 this.load(); 133 } 134 }).observe(this); 135 } 136}; 137window.customElements.define("tegna-ajax-module", AjaxModule); 138var Alert = class extends HTMLElement { 139 constructor() { 140 super(); 141 const shadowRoot = this.attachShadow({ "mode": "open" }); 142 shadowRoot.innerHTML = ` 143 <style> 144 :host { 145 position: fixed; 146 top: 0; 147 right: 0; 148 bottom: 0; 149 left: 0; 150 background-color: rgba(0,0,0,.8); 151 z-index: 5; 152 opacity: 0; 153 transition: .2s ease opacity; 154 } 155 #inner { 156 position: fixed; 157 left: 50%; 158 top: 50%; 159 transform: translate(-50%, -50%); 160 padding: 15px 15px 15px 15px; 161 width: 320px; 162 max-width: calc(100% - 45px); 163 background-color: #fff; 164 color: #000; 165 } 166 #close { 167 position: absolute; 168 top: -45px; 169 right: -12px; 170 width: 45px; 171 height: 45px; 172 border-width: 0; 173 text-indent: -9001px; 174 background: transparent url('/assets/shared-images/icons/close.svg') center center no-repeat; 175 filter: invert(1); 176 cursor: pointer; 177 } 178 </style> 179 <div id="inner"> 180 <slot></slot> 181 <button id="close">close</button> 182 </div> 183 `; 184 this.shadowRoot.querySelector("#close").addEventListener("click", (_e) => this.remove()); 185 window.setTimeout(() => { 186 this.style.opacity = 1; 187 }, 100); 188 } 189}; 190window.customElements.define("tegna-alert", Alert); 191HTMLElement.prototype.on = function(event, selector, handler) { 192 this.addEventListener(event, function(e) { 193 try { 194 let target = e.target; 195 if (typeof selector === "string") { 196 while (!target.matches(selector) && target !== this) target = target.parentElement; 197 if (target.matches(selector)) handler.call(target, e); 198 } else selector.call(this, e); 199 } catch (_ex) {} 200 }); 201}; 202Array.prototype.last = function() { 203 return this[this.length - 1]; 204}; 205Array.prototype.pushIfUnique = function(item, maxSize) { 206 if (this.indexOf(item) === -1) this.push(item); 207 if (typeof maxSize !== "undefined" && maxSize >= 0) while (this.length > maxSize) this.shift(); 208}; 209Array.prototype.joinIfSet = function(combinator) {
210 return this.filter(Boolean).join(combinator); 211}; 212var loadedCss = {}; 213var criticalCssModules = (document.documentElement.dataset.criticalCss || "").split(","); 214var utils = { 215 "loadModuleCss": function(moduleName) { 216 if (loadedCss[moduleName] || criticalCssModules.indexOf(moduleName) !== -1) return; 217 var href = (window.tegna && window.tegna.assets && window.tegna.assets.modules || {})[moduleName]; 218 if (!href) { 219 var version = document.documentElement.dataset.version || "0.0.1"; 220 href = "/css/modules/" + moduleName + ".css?v=" + version; 221 } 222 var fileName = href.split("/").pop().split("?")[0]; 223 if (document.querySelector("link[href*=\"" + fileName + "\"]")) { 224 loadedCss[moduleName] = true; 225 return; 226 } 227 var link = document.createElement("link"); 228 link.rel = "stylesheet"; 229 link.href = href; 230 document.head.appendChild(link); 231 loadedCss[moduleName] = true; 232 }, 233 "assembleHtmlAttributes": function(attrs) { 234 var attrString; 235 var attrArray = []; 236 Object.keys(attrs).forEach((k) => { 237 var v = attrs[k]; 238 var pair; 239 if (typeof v !== "undefined" && v !== null && v !== "") { 240 v = v.toString(); 241 v = v.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'"); 242 pair = k + "=\"" + v + "\""; 243 attrArray.push(pair); 244 } 245 }); 246 attrString = attrArray.join(" "); 247 return attrString; 248 }, 249 "assembleQueryString": function(params, nested, preencoded, allowEmptyString) { 250 var queryString; 251 var queryArray = []; 252 Object.keys(params).forEach((k) => { 253 var v = params[k]; 254 var pair; 255 if (typeof v !== "undefined" && v !== null && (v !== "" || allowEmptyString)) { 256 if (!nested) { 257 k = encodeURIComponent(k); 258 if (typeof v !== "object") { 259 if (!preencoded) v = encodeURIComponent(v.toString()); 260 } 261 } 262 if (typeof v === "object") pair = k + "=" + utils.assembleQueryString(v, true); 263 else pair = k + "=" + v; 264 queryArray.push(pair); 265 } 266 }); 267 queryString = queryArray.join("&"); 268 if (nested) queryString = encodeURIComponent(queryString); 269 return queryString; 270 }, 271 "formatBroadcast": function(broadcastSource, broadcastAction, broadcastData, severity, silent) { 272 if (typeof broadcastData === "undefined") broadcastData = {}; 273 var sourcePadding = 20 - broadcastSource.length; 274 sourcePadding = sourcePadding < 0 ? 0 : sourcePadding; 275 var actionPadding = 30 - broadcastAction.length; 276 actionPadding = actionPadding < 0 ? 0 : actionPadding; 277 var type = "log"; 278 if ("error" in console && severity === 3) type = "error"; 279 else if ("warn" in console && severity === 2) type = "warn"; 280 else if ("info" in console) type = "info"; 281 var message = "[" + broadcastSource + "] " + " ".repeat(sourcePadding) + broadcastAction + " ".repeat(actionPadding); 282 const environment = document.getElementsByClassName("page")[0].dataset.environment.toLowerCase(); 283 if (silent !== true && environment !== "production") if (Object.keys(broadcastData).length > 0) console[type](message, broadcastData); 284 else console[type](message); 285 return [ 286 broadcastSource, 287 broadcastAction, 288 broadcastData 289 ]; 290 }, 291 "broadcast": function(broadcastSource, broadcastAction, broadcastData, severity, silent) { 292 const msg = utils.formatBroadcast(broadcastSource, broadcastAction, broadcastData, severity, silent); 293 window.dispatchEvent(new CustomEvent("tegnaBroadcast", { "detail": { 294 "source": msg[0], 295 "action": msg[1], 296 "data": msg[2] 297 } })); 298 }, 299 "clone": function(inObject) { 300 let outObject, value, key; 301 if (typeof inObject !== "object" || inObject === null) return inObject; 302 outObject = Array.isArray(inObject) ? [] : {}; 303 for (key in inObject) { 304 value = inObject[key]; 305 outObject[key] = utils.clone(value); 306 } 307 return outObject; 308 }, 309 "_moduleInstances": {}, 310 "_disposeModule": function(moduleName) { 311 var instances = utils._moduleInstances[moduleName]; 312 if (instances) { 313 instances.forEach(function(instance) { 314 if (instance._hmrDispose) instance._hmrDispose(); 315 if (instance.dispose) instance.dispose(); 316 }); 317 utils._moduleInstances[moduleName] = []; 318 } 319 document.querySelectorAll("." + moduleName + "[data-initialized]").forEach(function(el) { 320 delete el.dataset.initialized; 321 }); 322 }, 323 "createModule": function(module, Constructor, callback) { 324 tegna.log("utils", "creatingModule", { "module": module }); 325 function instantiate(module, Constructor, el) { 326 if (el.dataset.initialized !== "true") { 327 el.dataset.initialized = "true"; 328 Constructor.prototype.broadcast = function(action, data) { 329 data = data || {}; 330 data.el = this.el; 331 utils.broadcast(this.module.name, action, data); 332 }; 333 Constructor.prototype.listen = utils.listen; 334 var instance = new Constructor(el); 335 var _ac = new AbortController(); 336 var _intervals = /* @__PURE__ */ new Set(); 337 var _timeouts = /* @__PURE__ */ new Set(); 338 var _observers = /* @__PURE__ */ new Set(); 339 instance.on = function(target, event, handler, options) { 340 options = Object.assign({}, options, { signal: _ac.signal }); 341 target.addEventListener(event, handler, options); 342 }; 343 instance.setInterval = function(fn, ms) { 344 var id = window.setInterval(fn, ms); 345 _intervals.add(id); 346 return id; 347 }; 348 instance.clearInterval = function(id) { 349 window.clearInterval(id); 350 _intervals.delete(id); 351 }; 352 instance.setTimeout = function(fn, ms) { 353 var id = window.setTimeout(fn, ms); 354 _timeouts.add(id); 355 return id; 356 }; 357 instance.clearTimeout = function(id) { 358 window.clearTimeout(id); 359 _timeouts.delete(id); 360 }; 361 instance.observe = function(el, cb, options) { 362 var observer = utils.observeIntersections(el, cb, options); 363 if (observer) _observers.add(observer); 364 return observer; 365 }; 366 instance.observeMutations = function(target, options, cb) { 367 var observer = new MutationObserver(cb); 368 observer.observe(target, options); 369 _observers.add(observer); 370 return observer; 371 }; 372 instance.listen = function(source, action, cb) { 373 utils.listen(source, action, cb, { signal: _ac.signal }); 374 }; 375 instance._hmrDispose = function() { 376 _ac.abort();
377 _intervals.forEach(function(id) { 378 window.clearInterval(id); 379 }); 380 _intervals.clear(); 381 _timeouts.forEach(function(id) { 382 window.clearTimeout(id); 383 }); 384 _timeouts.clear(); 385 _observers.forEach(function(obs) { 386 obs.disconnect(); 387 }); 388 _observers.clear(); 389 }; 390 instance.init(); 391 if (!utils._moduleInstances[module]) utils._moduleInstances[module] = []; 392 utils._moduleInstances[module].push(instance); 393 if (callback) callback(instance); 394 } 395 } 396 utils.docReady(() => { 397 utils.loadModuleCss(module); 398 document.querySelectorAll(`.${module}`).forEach((thisModule) => { 399 tegna.log("utils", "instantiatingModule", { "module": module }); 400 instantiate(module, Constructor, thisModule); 401 }); 402 utils.listen("grid", "addedSection", function(source, action, data) { 403 data.el.querySelectorAll(`.${module}`).forEach((thisModule) => { 404 tegna.log("utils", "instantiatingLazyModule", { "module": module }); 405 utils.loadModuleCss(module); 406 instantiate(module, Constructor, thisModule); 407 }); 408 }); 409 utils.listen("responsive-grid", "addedSection", function(source, action, data) { 410 data.el.querySelectorAll(`.${module}`).forEach((thisModule) => { 411 tegna.log("utils", "instantiatingLazyModule", { "module": module }); 412 utils.loadModuleCss(module); 413 instantiate(module, Constructor, thisModule); 414 }); 415 }); 416 }); 417 }, 418 "dashesToCamel": function(str) { 419 str = str.replace(/-([a-z])/g, function(m, w) { 420 return w.toUpperCase(); 421 }); 422 return str; 423 }, 424 "dataCleanup": { "images": { 425 "getImageList": function(primaryImageUrl, primaryImageSizes) { 426 let imageList = []; 427 if (primaryImageSizes && primaryImageSizes.length > 0) { 428 const server = primaryImageUrl.includes("//") ? "" : document.getElementsByClassName("page")[0].dataset.assetsBaseUrl;
429 primaryImageSizes.forEach((size) => { 430 const extension = primaryImageUrl.split(".")[primaryImageUrl.split(".").length - 1]; 431 let baseUrlSegments = primaryImageUrl.split("."); 432 baseUrlSegments.pop(); 433 const baseUrl = baseUrlSegments.join("."); 434 const width = parseInt(size.split("x")[0]); 435 const height = parseInt(size.split("x")[1]); 436 const url = `${server}${baseUrl}_${width}x${height}.${extension}`; 437 imageList.push({ 438 "width": width, 439 "height": height, 440 "url": url 441 }); 442 }); 443 } 444 return imageList; 445 }, 446 "getBestImageBySize": function(primaryImageUrl, primaryImageSizes, width, height) { 447 const imageList = utils.dataCleanup.images.getImageList(primaryImageUrl, primaryImageSizes); 448 let bestImage = {}; 449 let largestImage = {}; 450 let bestWidth = Number.MAX_SAFE_INTEGER; 451 let bestHeight = Number.MAX_SAFE_INTEGER; 452 let largestWidth = 0; 453 let largestHeight = 0; 454 let foundGoodImage = false; 455 imageList.forEach((image) => { 456 if (image.width <= bestWidth && image.width >= width && image.height <= bestHeight && image.height >= height) { 457 bestWidth = image.width; 458 bestHeight = image.height; 459 bestImage = image; 460 foundGoodImage = true; 461 } 462 if (image.width >= largestWidth && image.height >= largestHeight) { 463 largestWidth = image.width; 464 largestHeight = image.height; 465 largestImage = image; 466 } 467 }); 468 if (!foundGoodImage) bestImage = largestImage; 469 return bestImage; 470 }, 471 "getSmallestImage": function(primaryImageUrl, primaryImageSizes) { 472 return utils.dataCleanup.images.getBestImageBySize(primaryImageUrl, primaryImageSizes, 0, 0); 473 }, 474 "getSrcSet": function(primaryImageUrl, primaryImageSizes) { 475 const imageList = utils.dataCleanup.images.getImageList(primaryImageUrl, primaryImageSizes); 476 let sources = []; 477 imageList.forEach((image) => { 478 sources.push(`${image.url} ${image.width}w`); 479 }); 480 return sources.join(", "); 481 } 482 } }, 483 "delegateEvent": function(el, event, selector, handler) { 484 el.addEventListener(event, function(e) { 485 let target = e.target; 486 if (typeof selector === "string") { 487 while (!target.matches(selector) && target !== el) target = target.parentElement; 488 if (target.matches(selector)) handler.call(target, e); 489 } else selector.call(el, e); 490 }); 491 }, 492 "docReady": function(callback) { 493 if (document.readyState === "complete" || document.readyState === "interactive") window.setTimeout(callback, 1); 494 else document.addEventListener("DOMContentLoaded", callback); 495 }, 496 "formatSeconds": function(seconds) { 497 return (/* @__PURE__ */ new Date(seconds * 1e3)).toISOString().substr(14, 5); 498 }, 499 "getAutoHeight": function(el) { 500 let clone = el.cloneNode(true); 501 clone.setAttribute("id", "utils__auto-height"); 502 clone.style.opacity = "0"; 503 clone.style.pointerEvents = "none"; 504 clone.style.position = "fixed"; 505 clone.style.left = "-9001px"; 506 clone.style.top = "-9001px"; 507 clone.style.bottom = "auto"; 508 clone.style.right = "auto"; 509 clone.style.height = "auto"; 510 clone.style.width = utils.getWidth(el); 511 el.parentNode.append(clone); 512 let height = utils.getHeight(el); 513 clone.remove(); 514 return height; 515 }, 516 "getClasses": function(el) { 517 return el.getAttribute("class").split(/\s+/); 518 }, 519 "getHeight": (el) => { 520 return parseFloat(getComputedStyle(el, null).height.replace("px", "")); 521 }, 522 "getRect": (el) => { 523 const rect = el.getBoundingClientRect(); 524 return { 525 "left": rect.left, 526 "right": rect.right, 527 "top": rect.top, 528 "bottom": rect.bottom, 529 "width": rect.right - rect.left, 530 "height": rect.bottom - rect.top 531 }; 532 }, 533 "getWidth": (el) => { 534 return parseFloat(getComputedStyle(el, null).width.replace("px", "")); 535 }, 536 "initialCap": function(str) { 537 return str.charAt(0).toUpperCase() + str.slice(1); 538 }, 539 "joinIfSet": function(combinator, arr) { 540 let nonEmptyItems = []; 541 arr.forEach((item) => { 542 if (typeof item !== "undefined" && item !== null && item !== "") nonEmptyItems.push(item); 543 }); 544 return nonEmptyItems.join(combinator); 545 }, 546 "listen": function(listenSource, listenAction, listenCallback, listenOptions) { 547 var splitAction; 548 if (typeof listenSource === "function") { 549 listenCallback = listenSource; 550 listenSource = null; 551 listenAction = null; 552 } else if (typeof listenAction === "function") { 553 listenOptions = listenCallback; 554 listenCallback = listenAction; 555 listenAction = null; 556 } 557 if (listenAction !== null) splitAction = listenAction.split(" "); 558 if (listenAction !== null && splitAction.length > 1) splitAction.forEach(function(action) { 559 utils.listen(listenSource, action, listenCallback, listenOptions); 560 }); 561 else window.addEventListener("tegnaBroadcast", (e) => { 562 if (listenCallback && (listenSource === e.detail.source || listenSource === null) && (listenAction === e.detail.action || listenAction === null)) { 563 var data = e.detail.data || {}; 564 listenCallback(e.detail.source, e.detail.action, data); 565 } 566 }, listenOptions); 567 }, 568 "loadScript": function(url) { 569 return new Promise((resolve, reject) => { 570 var script = document.createElement("script"); 571 script.src = url; 572 script.onload = () => { 573 resolve(); 574 }; 575 script.onerror = () => { 576 reject("cannot load script " + url); 577 }; 578 document.body.appendChild(script); 579 }); 580 }, 581 "observeIntersections": function(el, callback, options) { 582 var observer; 583 var intersectionObserverIsSupported = "IntersectionObserver" in window && "IntersectionObserverEntry" in window; 584 options = options || {}; 585 options.threshold = options.threshold || 0; 586 if (intersectionObserverIsSupported) { 587 observer = new window.IntersectionObserver(function(entries, observer) {
588 entries.forEach(function(entry) { 589 if (entry.target.dataset.firstObservation === "true") { 590 entry.isInitialObservation = true; 591 entry.target.removeAttribute("data-first-observation"); 592 } 593 entry.isIntersectingThreshold = entry.intersectionRatio >= options.threshold; 594 callback(entry, observer); 595 }); 596 }, options); 597 el.dataset.firstObservation = "true"; 598 observer.observe(el); 599 tegna.log("utils", "observingIntersections", { 600 "el": el, 601 "options": options 602 }); 603 } 604 return observer; 605 }, 606 "padNumber": function(num, size) { 607 return (Math.sign(num) === -1 ? "-" : "") + new Array(size).concat([Math.abs(num)]).join("0").slice(-size); 608 }, 609 "parseSSTS": function(ssts) { 610 var sstsArray, section, subsection, topic, subtopic; 611 if (Array.isArray(ssts)) sstsArray = ssts; 612 else sstsArray = ssts.split("/"); 613 section = sstsArray[0] || ""; 614 subsection = sstsArray[1] || ""; 615 topic = sstsArray[2] || ""; 616 subtopic = sstsArray[3] || ""; 617 return { 618 "section": section, 619 "subsection": subsection, 620 "topic": topic, 621 "subtopic": subtopic, 622 "0": section, 623 "1": subsection, 624 "2": topic, 625 "3": subtopic, 626 "length": 4, 627 "toString": function() { 628 var str = ""; 629 if (section !== "") { 630 str += section; 631 if (subsection !== "") { 632 str += "/" + subsection; 633 if (topic !== "") { 634 str += "/" + topic; 635 if (subtopic !== "") str += "/" + subtopic; 636 } 637 } 638 } 639 return str; 640 } 641 }; 642 }, 643 "performance": { 644 "initialBacklogHasBeenParsed": false, 645 "pageLoadOffset": 0, 646 "track": function(event, data, time) { 647 if (event === "received") { 648 window.tegna.log("performance", "(" + Math.round((time / 1e3 + 1e-8) * 1e5) / 1e5 + ") serverResponse"); 649 utils.performance.pageLoadOffset = time; 650 } 651 if (utils.performance.initialBacklogHasBeenParsed === false) utils.performance.parseBacklog(); 652 if (typeof time === "undefined" || time === null) time = window.performance.now(); 653 var frontendTime = Math.round(((time - utils.performance.pageLoadOffset) / 1e3 + 1e-8) * 1e5) / 1e5; 654 if (window.tegna.hasBeenBlurred === false && document.hasFocus()) { 655 if (typeof data === "undefined" || data === null) tegna.log("performance", "(" + frontendTime + ") " + event); 656 else tegna.log("performance", "(" + frontendTime + ") " + event, data); 657 if (window.appInsights && window.tegna.hasBeenBlurred === false) window.appInsights.trackMetric(event, frontendTime, data); 658 else tegna.log("performance", "Application Insights not loaded."); 659 } else window.tegna.log("performance", "(" + frontendTime + ") " + event); 660 }, 661 "parseBacklog": function() { 662 utils.performance.initialBacklogHasBeenParsed = true; 663 Object.keys(window.tegna.performance).forEach((key) => { 664 utils.performance.track(key, window.tegna.performance[key].data, window.tegna.performance[key].time); 665 }); 666 window.tegna.performance = {}; 667 } 668 }, 669 "queue": function(arr, callback, delay) { 670 arr.forEach((v, k) => { 671 window.setTimeout(function() { 672 callback(v); 673 }, delay * k); 674 }); 675 }, 676 "repeat": function(iterations, callback) { 677 for (let i = 0; i < iterations; i++) callback(i); 678 }, 679 "setTriggerPoint": function(offset, callback) { 680 let el = document.createElement("div"); 681 el.classList.add("utils__trigger-point"); 682 el.style.height = "1px"; 683 el.style.width = "100%"; 684 el.style.position = "absolute"; 685 el.style.left = "0"; 686 el.style.zIndex = "2"; 687 el.style.pointerEvents = "none"; 688 el.style.top = `${offset}px`; 689 document.body.appendChild(el); 690 utils.observeIntersections(el, function(entry, _observer) { 691 var scrollDirection = parseInt(entry.target.dataset.oldOffset) > entry.boundingClientRect.top ? "down" : "up"; 692 var onScreen = entry.isIntersecting; 693 var position; 694 if (onScreen) position = "on"; 695 else if (scrollDirection === "up") position = "below"; 696 else position = "above"; 697 callback(position, scrollDirection); 698 entry.target.dataset.oldOffset = entry.boundingClientRect.top; 699 }); 700 }, 701 "Timer": function(fn, t) { 702 var timerObj = window.setInterval(fn, t); 703 this.stop = function() { 704 if (timerObj) { 705 window.clearInterval(timerObj); 706 timerObj = null; 707 } 708 return this; 709 }; 710 this.start = function() { 711 if (!timerObj) { 712 this.stop(); 713 timerObj = window.setInterval(fn, t); 714 } 715 return this; 716 }; 717 this.reset = function(newT) { 718 if (typeof newT !== "undefined") t = newT; 719 if (timerObj !== null) return this.stop().start(); 720 }; 721 }, 722 "truncate": function(str, length) { 723 if (typeof str === "string") return str.substring(0, length); 724 return str; 725 }, 726 "tryParseJSON": function(str) { 727 try { 728 var o = JSON.parse(str); 729 if (o && typeof o === "object") return o; 730 } catch (_e) { 731 return str; 732 } 733 }, 734 "url": { 735 "getQueryParam": function(name, url) { 736 if (!url) url = window.location.href; 737 name = name.replace(/[\[\]]/g, "\\$&"); 738 var results = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)").exec(url); 739 if (!results) return null; 740 if (!results[2]) return ""; 741 return decodeURIComponent(results[2].replace(/\+/g, " ")); 742 }, 743 "removeQueryParam": function(url, name) { 744 var newUrl = url, regex; 745 if (utils.getQueryParam(name, url) !== null) { 746 regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"); 747 newUrl = newUrl.replace(regex, ""); 748 } 749 return newUrl; 750 }, 751 "addQueryParam": function(url, name, value) { 752 if (url.indexOf("?") > -1) return url + "&" + name + "=" + value; 753 else return url + "?" + name + "=" + value; 754 }, 755 "setQueryParam": function(url, name, value) { 756 var newUrl = url; 757 newUrl = utils.removeQueryParam(newUrl, name); 758 newUrl = utils.addQueryParam(newUrl, name, value); 759 return newUrl; 760 } 761 }, 762 "uuid": function() { 763 var d = (/* @__PURE__ */ new Date()).getTime(); 764 if (typeof performance !== "undefined" && typeof performance.now === "function") d += performance.now(); 765 return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { 766 var r = (d + Math.random() * 16) % 16 | 0; 767 d = Math.floor(d / 16); 768 return (c === "x" ? r : r & 3 | 8).toString(16); 769 }); 770 }, 771 "getFlag": function(flagKey, defaultValue) { 772 return LD.getFlag(flagKey, defaultValue); 773 }, 774 "getXSRFToken": function() { 775 return document.querySelector("[name=\"__RequestVerificationToken\"]").value; 776 }, 777 "postForm": function(url, params) { 778 var body = new URLSearchParams();
779 Object.keys(params).forEach(function(key) { 780 var val = params[key]; 781 if (Array.isArray(val)) val.forEach(function(v, i) { 782 body.append(key + "[" + i + "]", v); 783 }); 784 else body.append(key, val); 785 }); 786 return fetch(url, { 787 method: "POST", 788 headers: { 789 "XSRF-TOKEN": utils.getXSRFToken(), 790 "Content-Type": "application/x-www-form-urlencoded" 791 }, 792 body 793 }); 794 }, 795 "initRecaptcha": function(el, sitekey) { 796 return utils.pollUntil(function() { 797 return window.grecaptcha && window.grecaptcha.render; 798 }, 200, 50).then(function() { 799 return window.grecaptcha.render(el, { 800 sitekey, 801 size: "invisible", 802 badge: "inline" 803 }); 804 }); 805 }, 806 "executeRecaptcha": function(widgetId) { 807 if (!window.grecaptcha || widgetId === null) return Promise.reject(/* @__PURE__ */ new Error("reCAPTCHA not ready")); 808 return window.grecaptcha.execute(widgetId).catch(function(err) { 809 window.grecaptcha.reset(widgetId); 810 throw err; 811 }); 812 }, 813 "pollUntil": function(check, interval, maxAttempts) { 814 return new Promise(function(resolve, reject) { 815 var attempts = 0; 816 (function poll() { 817 if (check()) return resolve(); 818 if (++attempts >= maxAttempts) return reject(); 819 window.setTimeout(poll, interval); 820 })(); 821 }); 822 }, 823 "validateEmail": function(email) { 824 var parts = email.split("@"); 825 return parts.length === 2 && parts[1].includes("."); 826 }, 827 "getOperatingSystem": function() { 828 var ua = navigator.userAgent; 829 var patterns = [
830 [/windows phone/i, "Windows Phone"], 831 [/android/i, "Android"], 832 [/iPad|iPhone|iPod/, "iOS"], 833 [/Mac/i, "macOS"], 834 [/Windows/i, "Windows"], 835 [/Linux/i, "Linux"] 836 ]; 837 for (var i = 0; i < patterns.length; i++) if (patterns[i][0].test(ua)) return patterns[i][1]; 838 return "unknown"; 839 }, 840 "getCookie": function(cname) { 841 let name = cname + "="; 842 let ca = decodeURIComponent(document.cookie).split(";"); 843 for (let i = 0; i < ca.length; i++) { 844 let c = ca[i]; 845 while (c.charAt(0) === " ") c = c.substring(1); 846 if (c.indexOf(name) === 0) return c.substring(name.length, c.length); 847 } 848 return ""; 849 } 850}; 851//#endregion 852//#region Assets/js-libs/tegna-storage/tegna-storage.mjs 853var prefix = "_tegna_"; 854var dayLength = 864e5; 855var storage = { 856 "expire": function() { 857 try { 858 for (var i = 0; i < window.localStorage.length; i++) { 859 var key = window.localStorage.key(i); 860 if (key.startsWith(prefix)) { 861 var data = JSON.parse(window.localStorage.getItem(key)); 862 if (data.expire !== null && data.expire < Date.now()) window.localStorage.removeItem(key); 863 } 864 } 865 return storage; 866 } catch (_e) { 867 return storage; 868 } 869 }, 870 "set": function(key, value, expireDays) { 871 try { 872 var expireTimestamp = null; 873 if (typeof expireDays !== "undefined" && expireDays !== null) expireTimestamp = expireDays * dayLength + Date.now(); 874 var data = { 875 "key": key, 876 "value": value, 877 "expire": expireTimestamp 878 }; 879 window.localStorage.setItem(prefix + key, JSON.stringify(data)); 880 utils.broadcast("_storage", "set", data); 881 return storage; 882 } catch (_e) { 883 return storage; 884 } 885 }, 886 "get": function(key) { 887 try { 888 storage.expire(); 889 var item = window.localStorage.getItem(prefix + key); 890 if (typeof item !== "undefined" && item !== null) return JSON.parse(item).value; 891 else return null; 892 } catch (_e) { 893 return null; 894 } 895 }, 896 "remove": function(key) { 897 try { 898 window.localStorage.removeItem(prefix + key); 899 return storage; 900 } catch (_e) { 901 return storage; 902 } 903 }, 904 "list": function() { 905 var list = {}; 906 try { 907 storage.expire(); 908 for (var i = 0; i < window.localStorage.length; i++) { 909 var key = window.localStorage.key(i); 910 if (key.startsWith(prefix)) (function() { 911 var item = window.localStorage.getItem(key); 912 var data = JSON.parse(item); 913 list[data.key] = data.value; 914 })(); 915 } 916 return list; 917 } catch (_e) { 918 return list; 919 } 920 }, 921 "getTimeRemaining": function(key) { 922 try { 923 storage.expire(); 924 var item = window.localStorage.getItem(prefix + key); 925 if (typeof item !== "undefined" && item !== null) { 926 var data = JSON.parse(item); 927 if (data.expire !== null) return data.expire - Date.now(); 928 else return null; 929 } else return null; 930 } catch (_e) { 931 return null; 932 } 933 } 934}; 935//#endregion 936export { utils as n, LD as r, storage as t }; 937 938//# sourceMappingURL=tegna-storage-BGZLdD41.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.