CM – New Yorker: It might be time to get an air quality app

0

Here’s something I, an Angeleno, would never have thought while visiting New York: When I woke up this morning in the shallow light of a post-apocalyptic orange sun hopping in a putty-colored sky, I cheered on the air- high quality app that I use at home. As I suspected: Haze from forest fires in the west has once again spread across the continent – nearly 3,000 miles away – to cover the eastern United States.

In the Air Quality Index, the Environmental Protection Agency’s method, air pollutants parts of Manhattan are currently reporting numbers over 175 and are therefore in the red « unhealthy » zone. Upstate the air is worse; Parts of Syracuse have AQI values ​​of up to 261, which gives them a purple indicator color for « very unhealthy ». All of this smoke comes from 80 major fires that are currently burning over 1 million acres in the west and continue to break all heat records. Oregon’s Bootleg Fire, for example, burned an area half the size of Rhode Island, and thanks to the smoke from that fire, Providence is currently showing AQI values ​​of 126. The fires will not be extinguished any time soon; The Bootleg Fire is expected to burn through Thanksgiving, though changing weather patterns can sweep smoke from the local skies.

While forest fire smoke monitoring has become a ritual for the people of the western United States, it could be for New Yorkers may be time to familiarize themselves with one more record in their daily life. Although most weather apps will now display the current AQI, I highly recommend downloading a dedicated air quality app – some of my California tested recommendations include AirVisual, AirNow, and PurpleAir – that display both current readings and forecasts. If the AQI climbs to threat level Orange and beyond, it is best to stay indoors, avoid outdoor activities, and wear a mask (again). You can also run an air purifier if you have one, although your air conditioner will do the job if you keep the filter clean. Aside from the long-term health effects this type of pollution causes – the tiny soot particles known as PM2.5 stay trapped in your lungs causing a number of negative effects – the short-term effects can include wheezing, burning eyes, etc., runny nose and dull, creeping headache. But a handful of smoky summer sunrises aren’t the only reason to have an app like this close at hand. Because hot days can trigger a chemical reaction that causes ground-level ozone pollution from vehicle exhaust, it doesn’t take wildfire to turn the AQI to red in a world where every fifth death worldwide is directly attributable to fossil fuel burning. Which of course also exacerbates the heat waves and droughts that make wildfires more dangerous, destructive and deadly.

A thick layer of smoke from wildfires in the western United States and Canada is sweeping the NYC Metro this morning. Hazy skies can already be seen and later become thicker, with some smoke even falling relatively close to the surface (where we are). pic.twitter.com/mXgdfTTQps

The last time New York saw such a sky – late September last year by the way, just to give you an idea of ​​how much worse this summer is likely to get – the smoke stayed relatively high in the atmosphere. Today, however, the haze will drop much lower, which means that at street level we are at a much higher risk of inhaling everything. On the light (orange) side, the sunset is likely spectacular. Just watch it from your home.

Already a subscriber?
Log in or link your magazine subscription

Already a subscriber?
Log in or link your magazine subscription

Already a subscriber?
Log in or link your magazine subscription

= 0? (u = f.substr (0, v), c = f.substr (v 1)) 🙁 u = f, c = «  »), i = decodeURIComponent (u), l = decodeURIComponent (c), hasOwnProperty (o, i)? isArray (o [i])? o [i] .push (l): o [i] = [o [i], l]: o [i] = l } return o}; var isArray = Array.isArray || function (r) {return « [Object-Array] » === Object.prototype.toString.call (r)};
}, {}];
window.modules [« 1187 »] = [function (require, module, exports) {« use strict »; var stringifyPrimitive = function (r) {switch (typeof r) {case « string »: return r; case « boolean » : return r? « true »: « false »; case « number »: return isFinite (r)? r: «  »; default: return «  »}}; module.exports = function (r, e, t, n) {return e = e || « & », t = t || « = », null === r&& (r = void 0), « object » == typeof r? map (objectKeys (r), function (n ) {var i = encodeURIComponent (stringifyPrimitive (n)) t; return isArray (r [n])? map (r [n], function (r) {return i encodeURIComponent (stringifyPrimitive (r))}). join (e ): i encodeURIComponent (stringifyPrimitive (r [n]))}). join (e): n? encodeURIComponent (stringifyPrimitive (n)) t encodeURIComponent (stringifyPrimitive (r)): «  »}; var isArray = Array.isArray | | function (r) {return « [object Array] » === Object.prototype.toString.call (r)}; function map (r, e) {if (r.map) return r.map (e); for (var t = [], n = 0; n0&&a [a.length-1]) && (6 === i [0] || 2 === i [0])) {o = 0; next} if (3 === i [0] && (! a || i [1]> a [0] &&i [1] « : » akbar-men « , » ∑ « : » majmou « , » ¤ « : » omla « }, az: {}, ca: { » ∆ « : » delta « , » ∞ « : » infinit « , » ♥ « : » amor « , » & « : » i « , » | « : » o « , » « : » mes que « , » ∑ « : » suma dels « , » ¤ « : » moneda « }, cz: { » ∆ « : » delta « , » ∞ « : » nekonecno « , » ♥  » : « laska », « & »: « a », « | »: « nebo », «  »: « vice jako », « ∑ »: « soucet », « ¤ »: « mena »}, de: { » ∆ « : » delta « , » ∞ « : » infinite « , » ♥ « : » Love « , » & « : » and « , » | « : » or « , » « : » greater than « , » ∑  » : « Sum of », « ¤ »: « Currency »}, dv: {« ∆ »: « delta », « ∞ »: « kolunulaa », « ♥ »: « loabi », « & »: « aai », « | »: « noonee », «  »: « ah vure bodu », « ∑ »: « jumula », « ¤ »: « faisaa »}, en: {« ∆ »: « delta », « ∞ »:  » infinite « , » ♥ « : » love « , » & « : » and « , » | « : » or « , » « : » greater than « , » ∑ « : » sum « , » ¤ « : » currency  » }, es: {« ∆ »: « delta », « ∞ »: « infinito », « ♥ »: « amor », « & »: « y », « | »: « u », «  »: « mas que « , » ∑ « : » suma de los « , » ¤ « : » moneda « }, fr: { » ∆ « : » delta « , » ∞ « : » infinite « , » ♥ « : » Amour « , » & « : » et « , » | « : » ou « , » « : » superieure a « , » ∑ « : » somme des « , » ¤ « : » monnaie « }, gr: {}, hu: { » ∆ « : » delta « , » ∞ « : » vegtelen « , » ♥ « : » szerelem « , » & « : » es « , » | « : » vagy « , » « : » nagyobb mint « , » ∑ « : » szu mma « , » ¤  » : « penznem »}, it: {« ∆ »: « delta », « ∞ »: « infinito », « ♥ »: « amore », « & »: « e », « | »: « o »,  » « : » maggiore di « , » ∑ « : » somma « , » ¤ « : » moneta « }, lt: {}, lv: { » ∆ « : » delta « , » ∞ « : » bezgaliba « , » ♥ « : » milestiba « , » & « : » un « , » | « : » vai « , » « : » lielaks neka « , » ∑ « : » summa « , » ¤ « : » valuta « }, my: { « ∆ »: « kwahkhyaet », « ∞ »: « asaonasme », « ♥ »: « akhyait », « & »: « nhin », « | »: « tho », «  »: « kyithaw », « ∑ » : « paungld », « ¤ »: « ngwekye »}, mk: {}, nl: {« ∆ »: « delta », « ∞ »: « oneindig », « ♥ »: « fielde », « & »: « en », « | »: « of », «  »: « groter dan », « ∑ »: « som », « ¤ »: « valuta »}, pl: {« ∆ »: « delta », « ∞ « : » nieskonczonosc « , » ♥ « : » milosc « , » & « : » i « , » | « : » lub « , » « : » wieksze niz « , » ∑ « : » suma « , » ¤ « : « waluta »}, pt: {« ∆ »: « delta », « ∞ »: « infinito », « ♥ »: « amor », « & »: « e », « | »: « ou », «  » : « maior que », « ∑ »: « soma », « ¤ »: « moeda »}, ro: {« ∆ »: « delta », « ∞ »: « infinite », « ♥ »: « dragoste », « & »: « si », « | »: « sau », «  »: « mai mare ca », « ∑ « : » suma « , » ¤ « : » valuta « }, ru: { » ∆ « : » delta « , » ∞ « : » beskonechno « , » ♥ « : » lubov « , » & « : » i « , « | »: « ili », «  »: « bolshe », « ∑ »: « summa », « ¤ »: « valjuta »}, sk: {« ∆ »: « delta », « ∞ »: « nekonecno » , « ♥ »: « laska », « & »: « a », « | »: « alebo », «  »: « viac ako », « ∑ »: « sucet », « ¤ »: « mena »}, sr: {}, tr: {« ∆ »: « delta », « ∞ »: « sonsuzluk », « ♥ »: « ask », « & »: « ve », « | »: « veya », «  » : « buyuktur », « ∑ »: « toplam », « ¤ »: « para birimi »}, uk: {« ∆ »: « delta », « ∞ »: « bezkinechnist », « ♥ »: « lubov », « & »: « i », « | »: « abo », «  »: « bilshe », « ∑ »: « suma », « ¤ »: « valjuta »}, vn: {« ∆ »: « delta » , « ∞ »: « vo cuc », « ♥ »: « yeu », « & »: « va », « | »: « hoac », «  »: « lon hon », « ∑ »: « tong », « ¤ »: « tien te »}}; if (« string »! = Typeof e) return «  »; if (« string » == typeof a&& (A = a), m = I.en, c = C. en, « object » == typeof a) for (g in n = a.maintainCase ||! 1, O = a.custom&& « object » == typeof a.custom? a.custom: O, u = a.truncate > 1&&a.truncate ||! 1, l = a.uric ||! 1, s = a.uricNoSlash ||! 1, r = a.mark ||! 1, S =! 1! == a.symbols&&! 1! == a.lang , A = a.separator || A, l&& (p = b.join («  »)), s&& (p = z.join («  »)), r&& (p = [« . », « ! »,  » ~ « , » * « , » ‘ », » (« , ») « ]. join ( » « )), m = a.lang&&I [a.lang] && S? I [a.lang]: S? I .en: {}, c = a.lang&&C [a.lang]? C [a.lang] :! 1 === a.lang ||! 0 == = a.lang? {}: C.en, a.titleCase&& « number » == typeof a.titleCase.length&&Array.prototype.toString.call (a.titleCase)? (a.titleCase.forEach (function (e) {O [e « } ») = e  » , t =! 0): t = !! a.titleCase, a.custom&& « number » == typeof a.custom.length&&Array.prototype.toString.call (a. custom) &&a.custom (e )ach (function.forEach) {O [e «  »] = e «  »}), Object.keys (O) .forEach (function (a) {var n; n = a.length> 1? New RegExp (« \ b » o (a ) « \ b », « gi »): new RegExp (o (a), « gi »), e = e.replace (n, O [a])}), O) p = g; for (p = o (p = A), f =! 1, y =! 1, d = 0, k = (e = e. replace (/ (^ s | s $) / g, «  »)). length; d = 0? (j = g, g = «  ») :! 0 === y? (g = U [j ] v [g], j = «  »): g = f&&v [g] .match (/ [A-Za-z0-9] /)? «  » v [g]: v [g], f =! 1 , y =! 1): g in U? (j = g, g = «  », d === k-1&& (g = U [j]), y =! 0) :! m [g] || l&&-1! == b.join («  ») .indexOf (g) || s&&-1! == z.join («  »). indexOf (g)? (! 0 === y? (g = U [j] g, j = «  », y =! 1): f&& (/ [A-Za-z0-9] /. Test (g) || E.substr (-1). match (/ A-Za-z0-9] /)) && (g = «  » g), f =! 1) 🙁 g = f || E.substr (-1) .match (/ [A-Za -z0-9] /)? A m [g]: m [g], g = void 0! == e [d 1] &&e [d 1] .match (/ [A-Za-z0-9] / )? A: «  », f =! 0), E = g.replace (new RegExp (« [^ \ w \ s » p « _-] », « g »), A); return t&& ( E = E.replace (/ ( w) ( S *) / g, function (e, a, n) {var t = a.toUpperCase () (null! == n? N: «  »); return Object.keys (O) .indexOf (t.toLowerCase ()) u&& (h = E.charAt (u) === A, E = E.slice (0, u), h || (E = E.slice (0, E.lastIndexOf (A)))), n || t || (E = E.toLowerCase ()), E}, t = function (e) {return function (a) {return n (a, e )}}, o = function (e) {return e.replace (/ [- \ ^ $ *?. () | [] {} /] / g, « \ $ & »)}, i = function (e, a) {for (var n in a) if (a [n] === e) return! 0}; if (« undefined »! = typeof module&&module.exports) module.exports = n, module .exports.createSlug = t; else if (« undefined »! = typeof define&&define.amd) define ([], function () {return n}); else try {if (e.getSlug || e.createSlug) throw  » Speakingurl: globals exists / (getSlug | c reateSlug) / « ; e.getSlug = n, e.createSlug = t} catch (e) {}} (this);
}, {}];
window.modules [« 1220 »] = [function (require, module, exports) {var namespace = « expire_mixin »; function expirePlugin () {var e = this.createStore (this.storage, null, this._namespacePrefix namespace); return {set: function (t, n, a, r) ​​{this.hasNamespace (namespace) || e.set (n, r); return t ()}, get: function (e, n) {this.hasNamespace (namespace) || t.call (this, n); return e ()}, remove: function (t, n) {this.hasNamespace (namespace) || e.remove (n); return t ()}, getExpiration: function (t, n) {return e.get (n)}, removeExpiredKeys: function (e) {var n = []; this.each (function (e, t) {n.push (t)}) ; for (var a = 0; a = 0; r -) {var l = localStorage (). key (r); e (read (l), l)}} function remove (e) {return localStorage () .removeItem (e)} function clearAll () {return localStorage (). clear ()} module.exports = {name: « localStorage », read: read, write: write, each: each, remove: remove, clearAll: clearAll };
}, {« 1222 »: 1222}];
window.modules [« 1224 »] = [function (require, module, exports) {module.exports = {name: « memoryStorage », read: read, write: write, each: each, remove: remove, clearAll: clearAll} ; var memoryStorage = {}; function read (e) {return memoryStorage [e]} function write (e, r) {memoryStorage [e] = r} function each (e) {for (var r in memoryStorage) memoryStorage.hasOwnProperty (r) &&e (memoryStorage [r], r)} function remove (e) {delete memoryStorage [e]} function clearAll (e) {memoryStorage = {}}
}, {}];
window.modules [« 1245 »] = [function (require, module, exports) {! function (e) {var t = function (e) {return new y (e)}; t.version = « 0.6.8 » , « undefined »! = typeof module&&module.exports? module.exports = t: « function » == typeof define&&define.amd? define (function () {return t}): e.typogr = t; var n = function (e , t) {return new RegExp (e, t)}, s = /] *> / i, r = t.amp = function (e) {var t = / ( s |) (& | & | & # 38;) ( s |) / g; if (e || « string » == typeof e) return e.replace (/ ()? ([^)? / G, function (e, n, r, a) {return a = a || «  », (n = n || «  »). match (s)? nra: n (r = r.replace (t, ‘$ 1& $ 3’)) a})} , a = t.ord = function (e) {if (e || « string » == typeof e) {var t, n = f (e), r = [], a =! 1, p = / ( d) (st | nd | rd | th) / g; return n.forEach (function (e) {« tag » === e.type? (r.push (e.txt), t = s.exec (e.txt), a =! (! t || void 0! == t [1])): a? r.push (e.txt): r.push (e.txt.replace (p, ‘ $ 1 $ 2 ‘))}), r.join («  »)}}, p = t.initQuotes = function (e) {var t = n (« (?: (?:] *> | ^) \ s * (?:] *> \ s *) *) (?: ( « |“ | “) | (‘|’ | ‘)) », « i »); if (e || « string » = = typeof e) return e.replace (t, functio n (e, t, n) {var s = t? « dquo »: « quo », r = t || n; return [e.slice (0, e.lastIndexOf (r)),  », r, «  »] .join («  »)})}, c = t.widont = function (e) {var t = « (?:] *?>) *? [^ \ s] (? 🙁 ?: a | em | span | strong | i | b) [^>] *?>) *? « , s = n ( » (\ s « t » \ s « t ») (?: \ s) ([^ \ s] ( ?: \ s * (?: a | em | span | strong | i | b) [^>] *?> \ s * \. *) *? (?: \ s *? (?: p | h [1-6] | li | dt | dd)> | $)) « , » gi « ); return e.replace (s, ‘$ 1 $ 2’)}, i = t.caps = function (e ) {var t, r = f (e), a = [], p =! 1, c = n (« ((\ b [AZ \ d] * [AZ] \ d * [AZ] [ AZ \ d ‘] * \ b) | (\ b [AZ] \. \ s? (?: [AZ] \. \ s?)) (?: \ s | \ b | $)) « , » g « ); return r.forEach (function (e) { » tag « === e.type? (a.push (e.txt), t = s.exec (e. txt), p =! (! t || void 0! == t [1])): p? a.push (e.txt): a.push (e.txt.replace (c, function (e, t, n, s) {var r, a; return n? ‘% s’.replace (« % s », n) 🙁 «  » === s.slice (-1)? (r = s.slice (0, -1), a = «  ») 🙁 r = s, a = «  »), ‘% s1% s2’.replace (« % s1 », r) .replace (« % s2 », a) )}))}), a.join («  »)}; t.typogrify = function (e) {var t = e; return e.jquery&&e.html&& (t = e.html ()), t = r ( t), t = c (t), t = u (t), t = i (t), t = p (t), t = a (t)}; var l, o, u = t.smartypants = Function (e) {var t, n, r = f (e), a = [], p = [], c = «  », i = «  », l =! 1, o = «  »; return r. forEach (function (e) {if (« tag » === e.type) a.push (e.txt), null! == (i = s.exec (e.txt)) && (c = i [ 2]. ToLowerCa se (), i [1]? (p.length> 0&&c === p [p.length-1] &&p.pop (), 0 === p.length&& (l =! 1)) 🙁 p. push (c), l =! 0)); else {if (n = (n = e.txt) .replace (/ (rock) ‘n’ (roll) / gi, « $ 1’n ‘$ 2 »), t = n.slice (-1) ,! l) switch (n = g (n), n = h (n), n = d (n), n = x (n)) {case « ‘ »: n = / S / .test (o)? « ‘ »: « ‘ »; Break; case ‘ »‘: n = / S / .test (o)? » «  »: «  » « ; Break; default: n = m (n)} o = t, a.push (n)}}), a.join («  »)}, f = t.tokenize = function (e) {for (var t, n = [] , s = 0, r = / ([^] *>) / gi; zero! == (t = r.exec (e));) {var a = t [1], p = t [2]; a&&n.push ({type: « text », txt: a}), n.push ({type: « tag », txt: p}), s = r.lastIndex} return r.lastIndex) / g, « $ 1 -« )}, d = t.smartEllipses = function (e) {return e.replace (/…/ g, « … »). replace (/ . . ./ g, « … »)}, x = t.smartBackticks = function (e) {return e.replace ( /« /g, » » »).replace(/« /g, «  » « )}, m = t.smartQuotes = function (e) {var t = » (? =% s \ B)  » .replace (« % s », « [!  » # \ $ \% \ ‘() *, -. \ /:;? \ @ \ [\\] \ ^ _ `{|} ~] »), s = « [^ \ \ t \ r n \ [\ {\ (\ -] », r = n (« (\ s | | – | & [mn] dash; | – | – | ȁ [34];) ‘(? = \ w) « , » g « ), a = n ( » (« s »)’ (?! \ s | s \ b | \ d) « , » g « ), p = n ( » (« s ») ‘(?! \ s | s \ b) « , » g « ), c = n (‘(\ s | | – | & [mn] dash; | – | – | ȁ [34];) « (? = \ w)’, » g « ), i = n ( ‘ »(? = \ s)’, » g « ), l = n ( » (« s’) » ‘, « g »); return e.replace (n (« ^’% s » .replace ( « % s », t), « g »), « ‘ »). replace (n (‘ ^ « % s’.replace (« % s « , t), » g « ), » «  »). replace (/ »‘(?=w)/g, » »‘ »).replace(/ ‘ »(? = w) / g, »‘ «  »). replace (/ b ‘(? = d {2} s) / g, « ‘ »). Replace (r, « $ 1′ »). Replace (a, « $ 1 ‘ »). Replace (p, « $ 1’ $ 2 »). Replace (« ‘ », « ‘ ») .replace (c, « $ 1 » « ). replace (i, » «  »). replace (l, « $ 1 » « ). replace (‘ »‘, «  » « )}, y = function (e) {this._wrapped = e}, v = function (e, n) {y.prototype [e ] = function () {return e = n.call (t, this._wrapped), this._chain? t (e) .chain (): e; var e}}; for (l in t) t.hasOwnProperty ( l) && ((o = t [l]) &CS SEANDCHARo.constructor&&o.call&&o.apply) &&v (l, t this }, y.prototype.value = function () {return this._wrapped}} (dies);
}, {}];
window.modules [« 1315 »] = [function (require, module, exports) {« use strict »; module.exports = {isString: function (n) {return « string » == typeof n}, isObject: function ( n) {return « object » == typeof n&&null! == n}, isNull: function (n) {return null === n}, isNullOrUndefined: function (n) {return null == n}};
}, {}];
window.modules [« 1342 »] = [function (require, module, exports) {« use strict »; const universalAgora = require (1344), universalRest = require (20), universalQuery = require (1343), _ get = require ( 14); function searchByQueryWithRawResults (e, r) {const t = `// $ {r.site.host} $ {80! == r.site.port?`: $ {R.site.port} `: » « } $ {r.site.path} / _ agora / _search`; return universalRest.post (t, e,! 0)} function getProducts (e, r, t) {return searchByQueryWithRawResults (universalAgora.buildProductsQuery (e), r ) .then (e => {const r = universalQuery.formatSearchResult (e); return {total: e.hits.total, products: t? universalAgora.filterByLocale (r): r}})} function getMerchantsList (e) { return searchByQueryWithRawResults (universalAgora.buildMerchantsAggregation (1e6, _get (e, « site.agoraLocale »)), e) .then (universalQuery.formatAggregationResults ({aggregationName: « merchants », field: « key », subfield: « name »}) )} module.exports.getProduct = universalAgora.getProduct, module.exports.getProducts = getProducts, module.exports.getMerchantsList = getMerchantsList, module.exports.searchByCross yWith RawResults = searchByQueryWithRawResults, module.exports.buildMerchantsByUrlQuery = universalAgora.buildMerchantsByUrlQuery;
}, {« 14 »: 14, « 20 »: 20, « 1343 »: 1343, « 1344 »: 1344}];
window.modules [« 1343 »] = [function (require, module, exports) {« use strict »; const _map = require (73), _ get = require (14), _ isArray = require (172), _ set = require ( 129), _ isObject = require (110), _ cloneDeep = require (83), _ uniq = require (113); function formatSearchResult (e) {return _map (e.hits.hits, « _ source »)} function newQuery (e) { if (! e) throw new Error (« An` index` is required to create a query « ); return {index: e, type: » _ doc « , body: {query: {}}}} function addShould ( e, o) {var t = _get (e, « body.query.bool.should », void 0), r = _isArray (o); return t? r? _set (e, « body.query.bool.should « , t.concat (o)) 🙁 t.push (o), _ set (e, » body.query.bool.should « , t)): _ set (e, » body.query.bool.should « , r? o: [o]), e} function addMust (e, o) {var t = _get (e, « body.query.bool.must », void 0), r = _isArray (o); return t? r? _set (e, « body.query.bool.must », t.concat (o)) 🙁 t.push (o), _ set (e, « body.query.bool.must », t)): _ set ( e, « body.query.bool.must », r? o: [o]), e} function addMustNot (e, o) {var t = _get (e, « body.query.bool.must_not », void 0 ), r = _isArray (o); return t? r? _set (e, « body.query.bool.must_not », t .concat (o)) 🙁 t.push (o), _ set (e, « body .query.bool.must_not « , t)): _ set (e, » body.query.bool.must_not « , r? o: [o]), e} function addFilter (e, o) {var t = _get ( e, « body.query.bool.filter », void 0); if (! _ isObject (o)) throw new Error (« Filter query must be an object »); return t? _isArray (t)? (t.push ( o), _ set (e, « body.query.bool.filter », t)): _ set (e, « body .query.bool.filter », [_ cloneDeep (t), o]): _ set (e,  » body.query.bool.filter « , o), e} function addMinimumShould (e, o) {if ( » number « ! = typeof o) throw new Error ( » A number is required as a second argument « ); return _set ( e, « body.query.bool.minimum_should_match », o), e} function addSort (e, o) {var t = _get (e, « body.sort »); return _isArray (t) || _set (e, « body.sort », t = []), t.push (o), e} function addSize (e, o) {if (! o&CSSEANDC HAR0! == o) return e; if (o = parseInt (o), isNaN (o)) throw new Error (`Second argument must be a number: $ {o}`); return _set (e, « body. size « , o)} function addFrom (e, o) {if (! o&&0! == o) return e; if (o = parseInt (o), isNaN (o)) throw new Error (` Second argument must be a number be r: $ {o} `); return _set (e, » body.from « , o)} function onlyWithTheseFields (e, o) {if (! _ isArray (o)) throw new Error ( » Second argument must be an array « ); return _set (e, » body._source.include « , _ uniq (o)), e} function onlyWithinThisSite (e, o) {return o.subsiteSlug? addFilter (e, {term: {subsite: o .subsiteSlug }}) 🙁 addFilter (e, {term: {site: o.slug}}), addMustNot (e, {exists: {field: « subsite »}})), e} function onlyWithinThisDomain (e, o) { return addFilter (e, {prefix: {canonicalUrl: `http: // $ {o.host}`}}), e} function withinThisSiteAndCrossposts (e, o) {var t = {term: {}}, r = { bool: {should: [], minimum_should_match: 1}}; return t.term [« crosspost. » (o.subsiteSlug || o.slug)] =! 0, r.bool.should.push (t), o.subsiteSlug? r.bool.should.push ({term: {subsite: o.subsiteSlug}}) : (r.bool.should.push ({term: {site: o.slug}}), addMustNot (e, {exists: {field: « subsite »}})), addFilter (e, r), e} function withinThisDomainOrCrossposts (e, o) {return addShould (e, {term: {[`crosspost. $ {o.subsiteSlug || o.slug}`] :! 0}}), addShould (e, {prefix: {canonicalUrl : `http: // $ {o.host}`}}), addMinimumShould (e, 1), e} function moreLikeThis (e, o, t) {let r = {fields: [« tags »], like: {_index: e.index, _type: « _ doc », _ id: o}, include:! 1, min_term_freq: 1, max_query_terms: 12, min_doc_freq: 1}; return {more_like_this: Object.assign (r, t)}} Function addAggregation (e = {}, o) {const {body: t = {}} = e; return o? (T.aggs? _Set (e, « body.aggs », Object.assign (t.aggs, o )): _ set (e, « body.aggs », o), e): e} function formatAggregationResults ({aggregationName: e = «  », field: o = «  », subfield: t = «  », skipEmpty: r = ! 0}) {return function (s = {}) {let u = _get (s, `aggregations. $ {E} $ {t? ». « T ». « : ». « } Buckets`, []) ; return r&& (u = u.filter (e => 0! == _ get (e, « doc_cou nt « , 0))), u.map (e => e [o] || » « )}} function addGeo (e, o) {if (! _ isArray (o)) throw new Error ( » Second argument is required to be an array « ); if (2! == o.length) throw new Error ( » Array must have length 2 « ); if (o.some (isNaN)) throw new Error ( » Array may only be Contain numbers « ); return _set (e, » body.query.geo_shape.location.shape.type « , » point « ), _ set (e, » body.query.geo_shape.location.shape.coordinates « , o), e} combine functionFunctionScoreQueries (e, o) {let t = _cloneDeep (_get (e, « body.query », {})), r = _cloneDeep (_get (o, « body.query », {})), s = _get (e, « body.sort »); return _set (e, « body.query », {}), _ set (e, « body.query.function_score.functions », []), e.body.query .function_score.functions.push ({filter: t, weight: 20}), e.body.query.function_score.functions.push ({filter: r, weight: 10}), e.body.query.function_score.score_mode = « max », e.body. query.function_score.min_score = 10, _isArray (s) || _set (e, « body.sort », s = []), s.unshift ({_ score: « desc »}), e} function addNestedObjQuery (e, o, t) {if (! e) throw new Error (« There is no base query to run the addNestedObjQuery operation ion »); if (! o) throw new Error (« There is no nested object path to run the nested query » ); if (! t) throw new Error (« There is no nested query path to execute the nested query against »); return _set (e, « nested », {path: o, query: t}), e} function addMatchAll (e) {return _set (e, « body.query », {match_all: {}}), e} function addMultiMatch (e, o) {const t = _get (e, « body.query.bool.must », void 0), {fields: r, type: s, string: u} = o, i = {multi_match: {query: u, fields: r, type: s}}; return t? (t.push (i) , _set (e, « body.query.bool.must », t)): _ set (e, « body.query.bool.must », [i]), e} module.exports = newQuery, module.exports. addGeo = addGeo, module.exports.addAggregation = addAggregation, module.exports.addShould = addShould, module. exports.addFilter = addFilter, module.exports.addMust = addMust, module.exports.addMustNot = addMustNot, module.exports.addMinimumShould = addMinimumShould, module.exports.addSort = addSort, module.exports.addSize = addSize, module.exports addFrom = addFrom, module.exports.onlyWithTheseFields = only with synthesis fields, module.exports.onlyWithinThisS ite = only within this site, module.exports.onlyWithinThisDomain = only within this domain, module.exports.withinThisSiteAndCrossposts = withinThisSiteAndCrossposts, module.exports.withinThisDomainOrCrossposts = withinThisDomainOrCrossposts, module.exports.formatAggregationResults more like this , module.exports.combineFunctionScoreQueries = combineFunctionScoreQueries, module.exports.addNestedObjQuery = addNestedObjQuery, module.exports.addMatchAll = addMatchAll, module.exports.addMultiMatch = addMultiMatch;
}, {« 14 »: 14, « 73 »: 73, « 83 »: 83, « 110 »: 110, « 113 »: 113, « 129 »: 129, « 172 »: 172}];
window.modules [« 1344 »] = [function (require, module, exports) {(function (process, __ filename) {(function () {
« use strictly »; const _forEach = require (63), _ get = require (14), _ filter = require (156), _ map = require (73), _ isEmpty = require (109), urlParse = require (74), log = require (12) .setup ({file: __ filename}), queryService = require (1343), universalRest = require (20), AGORA_HOST = window.process.env.AGORA_HOST, AGORA_ELASTIC_PREFIX = window.process.env.AGORA_ELASTIC_PREFIX, =. GORA_END AGORA_HOST? `$ {AGORA_HOST} / api / v1`: null, requestHeader = { » Content-Type « : » application / json « }, PRODUCTS_INDEX = » agora-products « , AFFILIATES_INDEX = » affiliates « , RETAILERS_INDEX = » retailers « , FILTER_KEY = {merchants: » name « , affiliates: » affiliate « }, URL_RE = / ^ https?: / /.*$/; function getProducts (e, t) {const {limit: r = 100, start: a = 0, search: s = «  », sortDate: i = « desc »} = e, n = `$ {AGORA_ENDPOINT} / products? limit = $ {r} &start = $ {a} &search = $ { encodeURIComponent (s)} &sortDate = $ {i} `; return fetch (n) .then (handleResponse) .then (e => t? filterByLocale (e, t): e) .then (e => ({total: e .length, products: e})). catch (handleError (n))} function getProduct (e, t) {const r = `$ {AGORA_END PO INT} / products / $ {e} `; if (! AGORA_ENDPOINT) throw new Error ( » No Agora endpoint was set « ); if ( » string « ! = Typeof e) throw new Error ( » Request must be a Specify product id « ); return fetch (r) .then (handleResponse) .then (e => t? FilterByLocale (e, t): e) .catch (handleError (r))} function postProduct (e) {const t = `$ {AGORA_ENDPOINT} / products`, r = {method: » POST « , headers: requestHeader, body: JSON.stringify (e)}; return fetch (t, r) .then (handleResponse) .catch (handleError ( t))} Function putProduct (e, t) {const r = `$ {AGORA_ENDPOINT} / products / $ {e}`, a = {method: « PUT », headers: requestHeader, body: JSON.stringify (t) }; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} function patchProduct (e, t) {const r = `$ {AGORA_ENDPOINT} / products / $ {e}`, a = {method : « PATCH », headers: requestHeader, body: JSON.stringify (t)}; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} function deleteProduct (e) {const t = ` $ {AGORA_ENDPOINT} / products / $ {e} `; return fetch (t, {method: » DELETE « , headers: requestHeader}). Then (handleResponse) .catch (handleError (t))} function getMerchantList (e) { const {limit: t = 100, fields: r = «  »} = e; Return Promise.resolve ([{name: « Amazon »}]). catch (handleError («  »))} function getMerchant (e) {const t = `$ {AGORA_ENDPOINT} / merchants / $ {e}`; if (« string »! = typeof e) throw new Error (« Request must specify a merchant ID »); return fetch (t) .then (handleResponse ) .catch (handleError (t))} function patchMerchant (e, t) {const r = `$ {AGORA_ENDPOINT} / merchants / $ {e}`, a = {method: « PATCH », headers: requestHeader, body: JSON.stringify (t)}; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} function postMerchant (e) {const t = `$ {AGORA_ENDPO INT} / merchants`, r = {method: « POST », headers: requestHeader, body: JSON.stringify (e)}; return fetch (t, r) .then (handleResponse) .catch (handleError (t))} function putMerchant (e, t) {const r = `$ {AGORA_ENDPOINT} / merchants / $ {e}`, a = {method: « PUT », headers: requestHeader, body: JSON.stringify (t)}; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} function deleteMerchant (e) {const t = `$ {AGORA_ENDPOINT} / merchants / $ {e}`; return fetch (t, {method: « DELETE », hea ders: requestHeader}). Then (handleResponse) .catch (handleError (t))} function migrationMerchants (e) {const t = `$ {AGORA_ENDPOINT} / merchants / migrate-affiliate`, r = {method : « POST », headers: requestHeader, body: JSON.stringify (e)}; return fetch (t, r) .then (handleResponse) .catch (handleError (t))} function getRetailers (e) {const {limit: t = 100, start: r = 0} = e, a = `$ {AGORA_ENDPOINT} / retailers? limit = $ {t} &start = $ {r}`; return fetch (a) .then (handleResponse) .then ( e => ({total: e.length, retailers: e})). catch (handleError (a))} function getRetailer (e) {const t = `$ {AGORA_ENDPOINT} / retailers / $ {e} `; return fetch (t). then (handleResponse) .catch (handleError (t))} function postRetailer (e) {const t = `$ {AGORA_ENDPOINT} / retailers`, r = {method: » POST « , headers: requestHeader, body: JSON.stringify ( e)}; return fetch (t, r) .then (handleResponse) .catch (handleError (t))} function putRetailer (e, t) {const r = `$ {AGORA_ENDPOINT} / retailers / $ {e}`, a = {method: « PUT », headers: requestHeader, body: JSON.stringify (t)}; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} fun ction deleteRetailer (e) {const t = `$ {AGORA_ENDPOINT} / retailers / $ {e}`; return fetch (t, {method: « DELETE », headers: requestHeader}). then (handleResponse) .catch (handleError (t))} function getAffiliates (e) {const {limit: t = 100, start: r = 0} = e, a = `$ {AGORA_ENDPOINT} / affiliates? limit = $ {t} &start = $ {r}`; return fetch (a ) .then (handleResponse) .then (e => ({total: e.length, affiliates: e})). catch (handleError (a))} function getAffiliateRetailers (e) {const t = `$ {AGORA_ENDPOINT} / retailers / $ {e} / affiliates`; return fetch (t) .then (handleResponse) .catch (handleError (t))} function getAffiliateRetailer (e, t) {const r = `$ {AGORA_ENDPOINT} / retailers / $ {e} / affiliates / $ {t}`; return fetch (r) .then (handleResponse) .catch (handleError (r))} function postAffiliateRetailer (e, t ) {const r = `$ {AGORA_ENDPOINT} / retailers / $ {e} / affiliates`, a = {method: » POST « , headers: requestHeader, body: JSON.stringify (t)}; return fetch (r, a ) .then (handleResponse) .catch (handleError (r))} Function putAffiliateRetailer (e, t, r) {const a = `$ {AGORA_ENDPOINT} / retailers / $ {e} / affiliates / $ {t}`, s = {method: « PUT », headers: requestHeader, body: JSON.stringify (r)}; return fetch (a, s) .then (handleResponse) .catch (handleError (a))} function deleteAffiliateRetailer (e, t) {const r = `$ {AGORA_ENDPOINT} / retailers / $ {e} / affiliates / $ {t}`; return fetch (r, {method: « DELETE », headers: requestHeader}). catch (handleError (r)) } function postLocale (e) {const t = `$ {AGORA_ENDPOINT} / locales /`, r = {method: « POST », headers: requestHeader, body: JSON.stringify (e)}; return fetch (t, r) . then (handleResponse) .catch (handleError (t))} function patchLocale (e, t) {const r = `$ {AGORA_ENDPOINT} / locales / $ {e}`, a = {method: « PATCH », headers: requestHeader , body: JSON.stringify (t)}; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} function handleResponse (e) {try {return e.json (). then (t => {if (e.status> = 400) {const e = _get (t, « message.details [0] .message »); throw new Error (e)} return t})} catch (e) {throw new Error (e.message)}} function handleError (e) {return t => {throw log (« warn », `Failed request to $ {e}`, t), new Error (`Request to $ {e} failed`)}} function buildProductsQue ry ({search: e = «  », limit: t = 100, start: r = 0, sortDate: a = «  », filters: s, locale: i}) {const n = queryService (PRODUCTS_INDEX), c = s&&Object .keys (s) .length? Object.keys (s) .filter (e => Array.isArray (s [e]) &&s [e] .length): [], o = { }, l = {}; if (prependElasticPrefix (n), e || c.length || i || queryService.addMatchAll (n), i&& (queryService.addMust (o, {match: {« locales.locale »: i}}), queryService. addMust (l, {match: {« merchants.locale »: i}})), e) if (isURL (e)) queryService.addMust (n, [queryService.addNestedObjQuery ({}, « merchants », {match: {« merchants.buyUrl »: e}})]); else {const t = {}; queryService.addShould (t, [{match: {« locales.productId »: e}}, {match: {« locales. name « : {query: e, boost: 2}}}]), queryService.addMinimumShould (t, 1), queryService.addMust (o, _get (t, » body.query « ))} if (c.length) {const e = {}; c.forEach (t => {const r = s [t], a = FILTER_KEY [t], i = {}; a&& (i [`merchants. $ {a}`] = r , queryService.addMust (e, {terms: i}))}), queryService.addMust (l, _get (e, « body.query »))} return _isEmpty (o) || queryServi ce.addMust (n, [ queryService.addNestedObjQuery ({}, « locales », _ get (o, « body.query »))]), _ isEmpty (l) || queryService.addMust (n, [queryService.addNestedObjQuery ({}, « merchants », _ get (l, « body.query »))]), queryService.addSize (n, t), r> = 0&&q ueryService.addFrom (n, r), « desc » === a || « asc » === a? queryService.addSort (n, {updatedAt: {order: a}}): e&&queryService.addSort (n, {_ score: {order: « desc »}}), n} function prependElasticPrefix (e ) {return e.index = AGORA_ELASTIC_PREFIX? `$ {AGORA_ELASTIC_PREFIX} _ $ {e.index}`: e.index, e} function buildMerchantsAggregation (e = 1e6, t) {const r = queryService (PRODUCTS_INDEX); return prependElasticPrefix ( r), queryService.addMust (r, {match: {active:! 0}}), t&&queryService.addMust (r, queryService.addNestedObjQuery ({}, « merchants », _ get (queryService.addMust ({}, {match: {« merchants.locale »: t}}), « body.query »))), queryService.addAggregation (r, {merchants: {nested: {path: « merchants »}, aggs: {name: {terms: { field: « merchants.name », size: e}}}}}), queryService.addSize (r, 0), r} function isURL (e) {return URL_RE.test (e)} function filterByLocale (e, t, r = {locales: « US »}) {const a = Array.isArray (e); if (_isEmpty (e)) return a? []: {}; const s = [« locales », « merchants »], i = a? e: [e], n = Object.keys (r), c = _map (i, e => {const a = Object.assign ({}, e); return _forEach (s, s => {if (Object. keys (a) .includes (s)) {const i = t? _filter (e [s], [« locale », t]): e [s]; a [s] = i,! i.length&&n.includes (s) && (a [s] = (_ filter (e [s], [« locale », r [s]]) || []). map (e => (e.id = null, e.locale = t, e)))}}), a.name = _get (a, « locales [0] .name », «  »), a}); return a&&c.length? c: _get (c, « [0 ] « , {})} Function searchByQueryWithRawResults (e, t) {const r =` // $ {t .site.host} $ {80! == t.site.port? `: $ {T.site.port } `: » « } $ {t.site.path} / _ agora / _search`; return universalRest.post (r, e,! 0)} function buildMerchantsByUrlQuery (e) {const t = queryService (PRODUCTS_INDEX); return prependElasticPrefix ( t), queryService.addNestedObjQuery (t.body.query, « merchants », {match: {« merchants. buyUrl « : e}}), t} Function getAffiliatesByLocale (e, t) {const r = que ryService (AFFILIATES_INDEX); return prependElasticPrefix (r), queryService.addMust (r, {match: {locale: e}}), queryService.addSize (r, 1e3), queryService.addSort (r, {name: « asc »}), searchByQueryWithRawResults (r, t) .then (e => _ get (e, « hits.hits », []). map (e => _ get (e, « _ source », {})))} function buildRetailersQuery ({search: e = «  », limit: t = 50, start: r = 0, direction: a = « asc », locale: s = « US », sortColumn: i = « retailers »}) {const n = queryService (RETAILERS_INDEX); if (prependElasticPrefix (n), queryService.addMust (n, {match: {locale: s}}), e&&queryService.addMultiMatch (n, {fields: [« name », « domains ^ 2 »], string: e, type: « phrase_prefix »}), « Retailers » === i&&queryService.addSort (n, {« name.keyword « : a}), » affiliates « === i) {let e = {}; queryService .addNestedObjQuery (e, » affiliateRetailers « , {match_all: {}}), queryService.addMust (n, e), queryService. addSort (n, {« affiliateRetailers.affiliateName.keyword »: {order: a, nested_path: « affiliateRetailers »}})} return query Service.addSize (n, t), queryService.addFrom (n, r), n} function getRetailer sList (e, t) {return searchByQueryWithRawResults (buildRetailersQuery (e), t) .then (e => ({total: _get (e, « hits.total », 0), retailers: _get (e, « hits.hits », []). map (e => _ get (e, « _ source », {}))}))} function getRetailersByAffiliateId (e, t, r) {const a = queryService (RETAILERS_INDEX); return e? (prependElasticPrefix (a), queryService.addMust (a, {match: {locale: r}}), queryService.addMust (a, [ queryService.addNestedObjQuery ({}, « affiliateRetailers », {match: {« affiliateRetailers.affiliateId »: e}})]), queryService.addSize (a, 1e4), queryService.addSort (a, {« name.keyword »: « asc »}), searchByQueryWithRawResults (a, t) .then (e => _ get (e, « hits.hits », []). map (e => _ get (e, « _ source », {}))) ): Promise.reject ()} function getMerchantsList (e) {return searchByQueryWithRawResults (buildMerchantsAggregation (1e6, _get (e, « site.agoraLocale »)), e) .then (queryService.formatAggregationResults ({aggregationName: « . Merchants » : « key », subfield: « name »}))} function queryRetailersByUrl (e, t, r) {const a = urlPa rse (e) .host.split (« www. »). join («  »), s = queryService (RETAILERS_INDEX); return qu eryService.addMust (s, {match: {locale: r}}), queryService.addMust (s, {match: {domains: a}}), prependElasticPrefix (s), queryService.addSize (s, 10), searchByQueryWithRawResults (s, t) .then (e => _ get (e, « hits.hits », []). map (e => _ get (e, « _ source », {})))} function queryRetailersByName (e, t, r) {const a = queryService (RETAILERS_INDEX); Return queryService.addMust (a, {match : {locale: r}}), queryService.addMust (a, {match: {« name.keyword »: e}}), prependElasticPrefix (a), queryService.addSize (a, 10), searchByQueryWithRawResults (a, t) .then (e => _ get (e, « hits.hits », []). map (e => _ get (e, « _source », {})))} require (231), module.exports = {buildProductsQuery : buildProductsQuery, buildMerchantsAggregation: buildMerchantsAggregation, getProducts: getProducts, getProduct: getProduct, postProduct: postProduct, putProduct: putProduct, patchProduct: patchProduct, deleteProduct, patchProduct, deleteProduct, patch, postMerchant, patchMerchant, patch: getMerchantMerchant, patch: getMerchant, postProduct: getMerchant, postProduct: getMerchant: erchant, putMerchant: putMerchant, deleteMerchant: deleteMerchant, migrateMerchants: mig rate merchants, getRetailers: getRetailers, getRetailersList: getRetailersList, getRetailer: getRetailer, post retailer: post retailer, putRetailer: putRetailer, deleteRetailer: deleteRetailer, getRetailersByAffiliateId: getRetailersByAffiliateId, getAffiliates: getAffiliates, getAffiliateRetailers: getAffiliateRetailers , getAffiliateRetailer: getAffiliateRetailer, post affiliate retailer: post affiliate retailer, putAffiliateRetailer: putAffiliateRetailer, deleteAffiliateRetailer: deleteAffiliateRetailer, isURL: isURL, filterByLocale: filterByLocale, patch locale: patch locale, post locale: post locale, buildMerchantsByUrlQuery: buildMerchantsByUrlQuery, getAffiliatesByLocale: getAffiliatesByLocale, searchByQueryWithRawResults: searchByQueryWithRawResults, getMerchantsList: getMerchantsList, queryRetailersByUrl : queryRetailersByUrl, queryRetailersByName: queryRetailersByName};

}). call (this)}). call (this, require (26), « / services / universal / agora.js »)}, {« 12 »: 12, « 14 »: 14, « 20 »: 20 , « 26 »: 26, « 63 »: 63, « 73 »: 73, « 74 »: 74, « 109 »: 109, « 156 »: 156, « 231 »: 231, « 1343 »: 1343}] ;
window.modules [« 1345 »] = [function (require, module, exports) {« use strict »; const _map = require (73), _ mapValues ​​= require (226), _ reduce = require (112), _ assign = require ( 160), _ get = require (14), _ pickBy = require (161), _ find = require (65), affiliateFields = [« siteShortKey », « pageUri », « productId », « utmMedium », « utmSource », « sessionCount » , « format », « utmCampaign », « referrer », « deviceAbbreviation », « zone »], affiliateSettings = {amazon: {domains: [« amazon.com », « amazon.co.uk »], subtagKey: « ascsubtag « , maxLength: 99, delimiter: » standard « , encode:! 1}, narrative: {domains: [ » shop-links.co/ » ],subtagKey: »u1″,maxLength:99,delimiter: »standard « , encode:! 0}, rakuten: {domains: [« click.linksynergy.com/deeplink », »linksynergy.walmart.com/deeplink » ],subtagKey: »u1″,maxLength:72,delimiter: »standard »,encode :! 1}, shareasale: {domains: [« shareasale.com »], subtagKey: « afftrack », maxLength: 99, delimiter: « standard », encode:! 1}, skimlinks: {domains: [« go.redirectingat .com « ], subtagKey: » xcust « , maxLength: 50, delimiter: » alt « , encode:! 1}, impact: {domains: [], subtagKey: » subId2 « , maxLen gth: 99, delimiter: « standard », encode:! 1}, avantlink: {domains: [« avantlink.com »], subtagKey: « ctc », maxLength: 64, delimiter: « old », encode:! 1 }, cj: {domains: [« tkqlhce.com », « jdoqocy.com », « dpbolvw.net », « anrdoezrs.net », « kqzyfj.com »], subtagKey: « sid », maxLength: 64, separator : « alt », encode:! 1, joinBy: « / », assignBy: « / », positioned:! 0, position: « after », positionKey: « type / dlg / »}, partnerize: {domains: [ » prf .hn « ], subtagKey: » pubref « , maxLength: 100, delimiter: » alt « , encode:! 1, joinBy: » / « , assignBy: »: « , positioned:! 0, position: » before « , positionKey: « Target »}, pepperjam: {domains: [« gopjn.com », « pntrac.com », « pjtra.com », « pjatr.com », « pntrs.com », « pntra.com »], subtagKey: « sid », maxLength: 100, delimiter: « alt », encode:! 1}, awin: {domains: [« awin1.com »], subtagKey: « pref1 », maxLength: 100, delimiter: « alt » , encode:! 1, positioned:! 0, position: « before », positionKey: « ued »}}, subtagDictionary = {siteShortKey: «  », pageUri: « p », productId: « i », zone: « z » , device abbreviation: « d », utmSource: « s », utmMedium: « m », utmCampaign: « c », sessionCount: « u », referrer: « r », format: « t »}, d elimite rs = {standard: [« [« , « ] »], old: [« __ », « _ »]}; function parseValueFromSubtag (e, t, i) {const a = t [0] et [1] , s = i.split (a) [1] || «  »; return s? s.split (t [0]) [0]: null} function parseSubtag (e, t = delimiters.standard) {return _pickBy ( _mapValues ​​(subtagDictionary, i => parseValueFromSubtag (i, t, e)))} function generateSubtag (e, t, i = delimiters.standard, a =! 1) {const s = (e => t => `$ { e [0]} $ {t} $ {e [1]} `) (i); let n = _reduce (affiliateFields, (t, i) => {const a = s (subtagDictionary [i]), n = e [i]; return t (n? an: «  »)}, «  »); return a&& (n = encodeURIComponent (n)), n} function applySubtagMaxlength (e, t) {var i = t-3 * ( e .split (« , »). length-1 e.split (« | »). length-1); return e.substr (0, i)} function getSubtagData ({getters: e, fields: t = [] , visitState: i, locals: a, productLink: s}) {let n = {}; return t.forEach (t => {n [t] = e [t] &&e [t] ({visitState: i, locals : a, productLink: s})}), n} function parseQuery (e = «  ») {return e.split (« & »). reduce ((e, t) => {const i = t.split ( » = « ) [0], a = t.split ( » = « ) [1]; return void 0! == a&& (e [i ] = a), e}, {})} fun ction processSubtagPosition ({url: e, positionKey: t, subtagKey: i, position: a = « after », subtagString: s, joinBy: n, assignBy: o} = {}) {const [r, l] = e. split (t), u = `$ {i} $ {o} $ {s}`, g = []; if (« after » === a) {if (! l) return e; const [a, s = «  »] = l.split (`$ {i} $ {o}`), d = s.split (n) .slice (1) .join (n); g.push (`$ {r} $ {t} `, u), a&&g.push (a), d&&g.push (d)} if ( » before « === a) {const [e, a = » « ] = r.split (` $ {i} $ {o} `), s = a.split (n) .slice (1) .join (n); g.push (e), s&&g.push (s), g.push (u,` $ {t} $ {l} `)} return g.reduce ((e, t) => {return e.slice (-1) === n&& (e = e.slice (0, -1)), e.length? [e, t] .join (n): t}, «  »)} function processSubtag ({getters: e, affiliate: t, url: i, visitState: a = {}, locals: s}) {const n = affiliateFields, o = _get (affiliateSettings [t], « subtagKey »), r = _get (affiliateSettings [t], « maxLength »), l = _get (affiliateSettings [t], « encode »), u = _get (affiliateSettings [t], « delimiter »), g = _get (affiliateSettings [t], « positioned »,! 1), d = _get (affiliateSettings [t], « position »), c = _get (affiliateSettings [t ], « positionKey »), p = _get (affiliateSettings [t], « assignBy », « = »), m = _get (affiliateSettings [t], « joinBy », « & »), f = delimiters [u]; let b, y, S = i. indexOf (« ? »)> = 0? i.split (« ? »). pop (): «  », h = parseQuery (S), _ = getSubtagData ({getters: e, fields: n, visitState: a, locals: s, productLink: i}); return o&& (y = h [o] || «  », y = applySubtagMaxlength (b = generateSubtag (_ = _ assign (parseSubtag (y, f), _ pickBy (_)), t , f, l), r), h [o] = y, S = _map (h, (e, t) => `$ {t} = $ {e}`) .join (« & »), i = g? processSubtagPosition ({url: i, positionKey: c, subtagKey: o, position: d, subtagString: y, joinBy: m, assignBy: p}): i.split (« ? ») [0] `? $ {S} `), i} function getAffiliate (e) {const t = Object.keys (affiliateSettings); return _find (t, t => _ find (affiliateSettings [t] .domains, t => e.includes (t .toLowerCase ()))) || «  »} Function createSubtagProcessor (e) {return ({url: t, visitState: i, locals: a, affiliate: s}) => (s = getAffiliate (t) || s )? processSubtag ({getters: e, url: t, affiliate: s, visitState: i, locals: a}): «  »} module.exports.generateSubtag = generateSubtag, module.exports.getAffiliate = getAffiliate, module.exp orts .createSubtagProcessor = createSubtagProcessor, module.exports.processSubtag = processSubtag;
}, {« 14 »: 14, « 65 »: 65, « 73 »: 73, « 112 »: 112, « 160 »: 160, « 161 »: 161, « 226 »: 226}];
window.modules [« article-nav.client »] = [function (require, module, exports) {« use strict »; const dom = require (5), _ throttle = require (60), $ visibility = require (1) , $ popup = require (75), $ gtm = require (2), {reportSocial: reportSocial} = require (76), auth0 = require (11); module.exports = (t => {let e = dom.find (« .page-header »), i = dom.find (« . article-content »), r = dom.find (t, « . deepscroll-headline »), o = dom.find (t, « . deepscroll -rubric « ), s = dom.find (t, ». deepscroll-rubric-sponsored « ), l = dom.find (« . article .article-header .rubric « ), n = dom.find ( » # deepscroll_center_divider « ), a = dom.find (« . clay-paragraph « ), d = dom.find (t, ». logo « ), c = dom.find (t, ». dyn-cut-logo « ), p = dom.find (t, « . article-nav-top »), u = dom.find (t, « . article-nav-deepscroll »), m = dom.find (‘link [rel = « canonical »] ‘), f = m&&m.getAttribute (« href »), g = dom.find (‘ meta [property = « og: image »] ‘)? dom.find (‘ meta [property = « og: image »] ‘ ) .getAttribute (« content »): «  », h = dom.find (‘meta [property = « og: title »]’)? dom.find (‘meta [property = « og: title »]’). getAttribute (« content »): «  », y = dom.find ( t, « . shar e-link.facebook »), w = dom.find (t, « . share-link.twitter »), v = dom.find (t, « . share-link.pinterest »), b = t.classList. contains (« header-simple »), x = window.getComputedStyle (d, null) .getPropertyValue (« – targetFlexBasis »), L = window.getComputedStyle (d, null) .getPropertyValue (« – verticalStart ») || 0, C = window.getComputedStyle (d, null) .getPropertyValue (« – verticalEnd ») || 0, $ =! 1, _ = 55; function k () {_ = parseInt (window.getComputedStyle (d, null ) .getPropertyValue (« – stickyTop »)) || _, C = $ visibility.getViewportWidth ()> = 1180? window.getComputedStyle (d, null) .getPropertyValue (« – verticalEndDesktop ») || C: window. getComputedStyle (d, null) .getPropertyValue (« – verticalEnd ») || C} function S () {$ =! 1, P ()} function P () {let {top: r} = t.getBoundingClientRect () , o = window.getComputedStyle (d, null) .getPropertyValue (« – baseFlexBasis »), s = ox, l = (_- e.getBoundingClientRect (). top) / _, n = Math.max (0, Math .min (1, l)), m = LC-2, f = Math.round (L- (m * n 2)), g = Math.ceil (os * n); if (lt? e.classList. add (« header-after-scroll »): e.classList.remove (« header-after-scroll »), p.style.transform = `translateY ($ {C} px)`, u.style.transform = `translateY ($ {C} px)`, void (d.style.flexBasis = x « px »)} window.scrollY> r? t.classList.add (« after-scroll »): t.classList.remove ( « after-scroll »), window.scrollY> r? e.classList.add (« header-after-scroll »): e.classList .remove (« header-after-scroll »), p.style.transform = ` translateY ($ {f} px) `, u.style.transform =` translateY ($ {f} px) `, d.style. flexBasis = g » px « , c&& (c.style.flexBasis = g » px  » ), $ visibility.getViewportWidth ()> = 1180&&i&&function () {const t = a? $ visibility.getPageOffset (a) .top-70: 0, e = $ visibility.getPageOffset (i) .top, r = Math.max (e, t); return Math.max (window.scrollY, document.body.scrollTop)> = r} ()? T.classList .add (« deep-scroll »): t.classList.remove (« deep-scroll »)} function V (t) {var e = t.currentTarget, i = e.getAttribute (« href »), r = e .getAttribute (« data-handle »), o = $ popup.getPopupClass (e.classList), s = $ visibility.isBelowPrimaryContent (e)? « bottom »: « top »; $ gtm.reportNow ({event: « social -share-widget « , clickLocation: s, socialNet work: o}), reportSocial (o), $ visibility.getViewportWidth ()> = 768&&o&& (t.preventDefault (), $ popup.popWindow (o, r, i)) }! function () {const e = _throttle (P, 30); if (k (), dom.findAll (t, « . share-link »). forEach (t => t.addEventListener (« click », V )), y&& (y.href = « http: //www.facebook.com/sharer/sharer.php? u = » f « ? utm_source = fb&utm_medium = s3&utm_campaign = sharebutton-t »), wCSSEANDfCHARC (wCSSEANDfCHARC) « https://twitter.com/share? text = « encodeURIComponent (h) » &url = « f »? utm_source = tw&utm_medium = s3&utm_campaign = sharebutton-t&via = « w.getAttribute ( » data-handle « )), v&C: // pinterest. com / pin / create / button /? url = « f »? utm_source = pin&utm_medium = s3&utm_campaign = sharebutton-t&description = « encodeURIComponent (h) » &media = « g) », b) return; auth0.on (« init0.on ( » init ) => {auth0.isSubscriber () &&t.classList.add (« subscribed »)}), window.addEvent Listener (« scroll », e), window.addEventListener (« resize », S), window.addEventListener ( » resize « , k), l? l.classList.contains ( » rubric-sponsor-story « ) &&s? (o.classList.remove ( » visible « ), s.classList.add ( » visible « ), s.textContent = l.text || l.textContent) 🙁 o.textContent = l.text || l.textContent, o.href = l.href || « # ») 🙁 n.style.display = « none », o.style.display = « none »); S (), r.textContent = h} ()});
}, {« 1 »: 1, « 2 »: 2, « 5 »: 5, « 11 »: 11, « 60 »: 60, « 75 »: 75, « 76 »: 76}];
window.modules [« nav-search-button.client »] = [function (require, module, exports) {« use strict »; const dom = require (5), $ gtm = require (2), {reportSearch: reportSearch } = require (76), openClass = « open », closeClass = « closed »; module.exports = (e => {const s = e, t = dom.find (e, « . nav-search-button-trigger « ), n = dom.find (e, ». nav-search-form « ), o = dom.find (e, ». search-input « ); function i () {const e = dom.find ( » body « ); s.classList.toggle (closeClass), s.classList.toggle (openClass), e.classList.toggle ( » disabled « ), e.classList.toggle ( » search-active « )} function c () {i (), s.classList.contains (openClass) &&o.focus ()} function a (e) {! s.contains (e.target) &&s.classList.contains (openClass) &&i ()} function r (e ) {27 === e.keyCode&&s.classList.contains (openClass) &&i ()} function d (e) {e.preventDefault (), $ gtm.reportCustomEvent ({category: « search », label: « on = » window.location.href, action: o.value}), reportSearch ((o.value || «  »). split («  »), () => n.submit ())}! functi on (e, s, t) {s&&s.addEventListener (« click », c); t&&t.addEventListener (« submit », d); e.addEventListener (« click », a), document.addEventListener (« keydown », r), e .addEventListener (« touchend », a), n.addEventListener (« submit », d)} (dom.find (« body »), t, dom.find (e, « . nav-search-form Submit »)) });
}, {« 2 »: 2, « 5 »: 5, « 76 »: 76}];
window.modules [« nav-dropdown-button.client »] = [function (require, module, exports) {« use strict »; const dom = require (5), visibility = require (1), {reportSearch: reportSearch} = require (76); function getNextSiblings (e) {const t = []; let i = e; for (; i = i.nextElementSibling;) t.push (i); return t} function getMainChildren (e, t) {let i = [], n = e.firstChild; for (; n = n.nextElementSibling;) n.contains (t)? n.isSameNode (t) || (i = i.concat (getMainChildren (n, t ))): i.push (n); return i} function isMobile () {return visible.getViewportWidth () {let t; const i = e.querySelector (« . nav-dropdown-button-trigger »), n = dom.find (« body »), o = dom.find (« . top »), l = dom.find (« . confetti-list »), s = dom.find (« . nav-dropdown-button_nymag-homepage « ), r = dom.find ( » header.page-header « ) || o, c = dom.find (‘[data-editable = » main « ]’), a = dom.closest (e, ». page-header « ), d = a? a.querySelectorAll (« . confetti-image.blue « ): » « , g = a? a.querySelectorAll (« . confetti-image.green « ): » « , u = a? a.querySelectorAll (« . confetti-image.orange »): «  », f = a? a.querySelectorAll (« . confetti-image.orange2 »): «  », m = a? a.que rySe lectorAll (« . confetti-image.pink »): «  », p = a? a.querySelectorAll (« . confetti-image.purple »): «  », h = a? a.querySelectorAll (« . confetti-image . yellow « ): » « , y = e.querySelectorAll (« . dropdown-nav-search-form « ); function b (e) {let t = e.currentTarget, i = t.querySelector (« . nav-search- input « ), n = i? i.value.split ( » « ): []; e.preventDefault (), reportSearch (n, () => t.submit ())} i.addEventListener ( » click « , () => {initializeHeight (e), v ()}); for (let e = 0, t = y.length; e (function (e) {e.classList.remove (« c-right », « c -rightdown « , » c-left « , » c-leftdown « )}) (e))}, 500)} ()) 🙁 i.setAttribute ( » aria-expanded « , » true « ), t = window .scrollY), e.classList.toggle (« closed »), e.classList.toggle (« open »), n.classList.toggle (« disabled »), a&&e.isSameNode (s)? function () {if ( o.contains (e)) {const e = getMainChildren (o, s); S (e), w (o)} if (c.contains (e)) {const e = getMainChildren (c, s); o. classList.toggle (« hidden component »), w (c), S (e)} e.classList.toggle (« open-mobile »)} (): a&&! y&&r&& (w (r), function () { const i = e .classList.contains (« open »)? 0: t; window.scrollTo ({top: i})} ())} function w (e) {S (getNextSiblings (e))} function S ( e) {e .forE ach (e => {e.classList.toggle (« hidden-component »)})} n.addEventListener (« click », t => {! e.contains (t.target) &&e.classList.contains (« open « ) &&v ()}), document.addEventListener ( » keydown « , t => {27 === t.keyCode&&e.classList.contains ( » open « ) &&v ()})});
}, {« 1 »: 1, « 5 »: 5, « 76 »: 76}];
window.modules [« follow.client »] = [function (require, module, exports) {« use strict »; const _find = require (65), $ popup = require (75); DS.controller (« follow », [function () {function e (e) {this.el = e, this.handle = e.getAttribute (« data-handle »)} return e.prototype = {events: {click: « openFollow »}, openFollow: function (e) {var t, n, a = $ popup.position, o = $ popup.params, l = {}, r = {w: 780, h: 500}, s = new a (rw, rh) , c = this.el.classList; l.handle = this.handle, r.left = s.left, r.top = s.top, n = _find ([{className: « facebook », url: « https: //facebook.com/{handle} »,network: »Facebook »},{className: »pinterest »,url: »http://www.pinterest.com/ registers »,network: »Pinterest « }, {className: « instagram », url: « https://www.instagram.com/ Zonenhandle} », network: « Instagram »}, {className: « rss », url: « http: //feeds.feedburner. com / {handle} « , network: » RSS « }, {className: » twitter « , url: » https://twitter.com/intent/follow?screen_name=phiahandle Genealogie&tw_p=followbutton&variant=2.0 « , network: « Twitter »}, {className: « snapchat », url: « https://www.snapchat.com/discover/ Genealogiehandle} » , netw ork: « Snapchat »}], function (e) {return c.contains (e.className)}), l.url = n.url.replace (« {handle} », l.handle), l. network = n.network, l.name = « Follow » l.handle « on » l.network, t = new o (l, r), window.open (t.address, t.name, t.features), e. PreventDefault ()}}, e}]);
}, {« 65 »: 65, « 75 »: 75}];
window.modules [« comments-link.client »] = [function (require, module, exports) {« use strict »; const dom = require (5), _ get = require (14), _ isFinite = require (132), ajax = require (131); DS.controller (« comments-link », [function () {var t, e = « http: // » document.documentElement.getAttribute (« data-uri ») « .html »; Function n (n) {var o; (this.el = n, this.coral_talk_root = n.getAttribute (« data-coral-talk »), this.commentsCount = dom.find (n, « . Comments-link-count « ), this.commentsText = dom.find (n, ». comments-link-text « ), this.isNavVariation = n.classList.contains ( » comments-link_article-nav « ), this.cutoffCnt = n.getAttribute ( « data-cutoffCnt ») || 1e3, t = `$ {this.coral_talk_root} /api/v1/graph/ql`,this.shouldRenderCommentStream ()) && (o = this.onCommentCountFetched.bind (this), ajax. sendReceiveJson ({method: « GET », url: t ‘? query = {asset (url: « ‘ e ‘ ») {totalCommentCount}}’, dataType: « json »}, function (t, e) {var n = _get (e, « data.asset.totalCommentCount », 0); return t? o (t): _ isFinite (n)? void o (null, n): o (« Unexpected Coral Talk response »)})) } back ck n.prototype.onCommentCountFetched = function (t, e) {if (t) return console.warn (t); e> 0&& (this.isNavVariation&&e1? « s »: «  »), this.el.classList.remove (« no comments »))}, n.prototype.shouldRenderCommentStream = function () {return-1! == e.indexOf (« @ published »)}, n}]);
}, {« 5 »: 5, « 14 »: 14, « 131 »: 131, « 132 »: 132}];
window.modules [« head-gtm.client »] = [function (require, module, exports) {« use strict »; const {getCLS: getCLS, getFID: getFID, getLCP: getLCP} = require (164), isProduction = require (9) (); function reportWebVitals (e) {isProduction || console.log (« reportWebVitals:% O », e); const t = « string » == typeof e.name?e.name.toUpperCase () : e.name; window.dataLayer = window.dataLayer || [], window.dataLayer.push ({event: « analyticsEvent », event_action: t, event_category: « Web Vitals », event_label: e.id, event_value: e .delta, eventAction: t, eventCategory: « Web Vitals », eventLabel: e.id, eventNonInt:! 0, eventValue: e.delta, nonInteraction:! 0, transport: « beacon »})} getCLS (e => { e.delta = Math.round (1e3 * e.delta), reportWebVitals (e)}), getFID (e => {e.delta = Math.round (e.delta), reportWebVitals (e)}), getLCP ( e => {e.delta = Math.round (e.delta), reportWebVitals (e)});
}, {« 9 »: 9, « 164 »: 164}];
window.modules [« concert-ads.client »] = [function (require, module, exports) {« use strict »; const customMappings = {« crime-assault »: « power », « career money productivity »: « power « , » feminism-politics-identity « : » power « , » culture-media « : » culture « , celebrity: » culture « , living: » style « , fashion: » style « , shopping: » style « , weddings: « Style », Beauty: « Style », Animals: « Self », « Learn Creativity »: « Self », « Relationships-Friends-Family »: « Self », « Mental Health Personality Social Behavior »: « Self », « Learn creative « : » self « , » health-wellness « : » self « , parenting: » self « , » relationships-sex-dating marriage « : » self « }, striptags = require (77); function installConcertAds () {const e = new URLSearchParams (window.location.search) .get (« concert_config_url »), t = e || window.concertConfigUrl; window._nymPermutive || console.warn (« ConcertAds is initialized without permutive »), window.concertAds = createConcertAds (), window.concertAds.loadRemoteConfig (t) .then (function () {window.concertAds.install ()})} function createConcertAds () {const e = getAuth Status (); let t = getD ata (« title »), n = window.location.href, i = getData (« section »), o = «  », a = getData (« type »), r = getData ( « vertical »); t&& (t = striptags (htmlDecode (t)). split («  »)), n = n.slice (n.lastIndexOf (« / ») 1); const l = {kw: getKeywords () , network: r, page_type: a, entry_group: i, keywords: t, pn: n}; return « Homepage » === a? o = « homepage »: « Section Page » === a&& (o = (o = window.location.pathname). replace (/ // g, «  »)), i&&-1 === i.indexOf («  ») && (o = i), customMappings [i] && (o = customMappings [i]), window.location .hostname.match (/ . aws ./ i) ​​&& (l.clay_sandbox_env = r), new window.ConcertAds ({cmd: [], slots: [], dfpVariables: l, slugPath: « / » o. replace (/ – | – / g, « -« ), loggedIn: « unauthenticated »! == e, paywallActive: getPaywallStatus (e)})} function getKeywords () {try {const e = window._nymPermutive.article.keywords ; return e&&e.length> 0&&e.some (Boolean)? e: (document.querySelector (‘meta [name = « keywords »]’) || document.querySelector (‘meta [property = « article: tag »]’) ) .getAttribute (« content »). split (« , »). map (function (e) {return e.trim ()})} catch (e) {return}} function getData (e) {if (window. _nymPermutive) {if (e in window._nymPermutive) return window._nymPermutive [e]; if (window._nymPermutive.article&&e in window._nymPermutive.article) Return window. _nymPermutive.article [e]; if (window._nymPermutive.user&&e in window._nymPermutive.user) return window._nymPermutive.user [e]}} function htmlDecode (e) {var t = document.createElement (« div »); return t.innerHTML = e, 0 === t.childNodes.length? «  »: t.childNodes [0] .nodeValue} function getAuthStatus () {const e = JSON.parse (localStorage.getItem (« auth0: profile » )), t = e? e [« http://nymag.com/app_metadata »]: null; return t? t.has_subscription? « entitled »: « unentitled »: « unauthenticated »} function getPaywallStatus (e) {const t = getData (« totalCount ») || 0; return Boolean (t> = 3&& « entitled »! == e)} window.ConcertAds? installConcertAds (): window.addEventListener (« concertAdsReady », in stallConcertAds);
}, {« 77 »: 77}];
window.modules [« latest-news.client »] = [function (require, module, exports) {« use strict »; const dom = require (5), lazyLoad = require (118); function lazyLoadImage (a) {const o = dom.find (a, « img [data-src] »), d = dom.findAll (a, « source [data-srcset] »), e = dom.closest (a, « . result »); if (o&&e) {new lazyLoad.LazyLoader (e, o, d) .init ()}} Function handleLazyLoad (a) {(dom.findAll (a, « . result ») || []). forEach (lazyLoadImage)} module.exports = (a => {handleLazyLoad (a)});
}, {« 5 »: 5, « 118 »: 118}];
window.modules [« coral-talk.client »] = [function (require, module, exports) {« use strict »; const dom = require (5), store = require (138), visibility = require (1), auth0 = require (11), TALK_AUTH = « talk: auth_token »; let coralEmbed, hasEmbedScriptLoaded =! 1, hasCoralTalkRendered =! 1; function renderComments (e) {if (hasEmbedScriptLoaded&CSSEAND {{{= const! $ coralTalkRendered) .CORAL_TALK_HOST} `, auth_token: getAuthToken (), asset_url: e.TALK_ASSET_URL}; hasCoralTalkRendered =! 0, coralEmbed = window.Coral.Talk.render (e.commentStreamContainer, t)}} function getAuthToken = e&&e [« http://nymag.com/coral_talk »] || auth0.getTalkJwt (), i = store.get (TALK_AUTH); return t? i&&t == i? i: (store.set (TALK_AUTH, t) , t) 🙁 i&&store.remove (TALK_AUTH), null)} function coralLogin () {coralEmbed.login (getAuthToken ())} function embedScript (e, t) {let i = document.createElement (« script »); i.type = « text / javascript », i.async =! 0, i.src = e, i.addEventListener (« load », () => {hasEmbedScriptLoaded =! 0, renderComments (t)}), document. getElementsByTagName (« head ») [0] .appendChild (i)} function initVerificationMessage () {auth0.isAuthenticated () &&auth0.refresh (); let e = document.querySelector (« . coral -talk-container »); auth0. isAuthenticated () &&! auth0.isEmailVerified () && (e.insertAdjacentHTML (« beforebegin », ‘ n n Please check your account to activate comments. Did not receive a confirmation email? Resend email now . n ‘), document.querySelector (« . activation-link »). addEventListener (« click », sendVerificationEmail))} function sendVerificationEmail () {let e = document.querySelector (« . coral-talk -verify-address » ); return fetch (`https: // $ {window.location.host} / _user / verification-email? user_id = $ {auth0.getUserID ()}`, {method: « GET », headers: {« Content- Type « : » application / json « }}). Then (e => e) .then (t => {t&&200 == t.status? E.inn erHTML = « Confirmation email was sent successfully »: e.innerHTML = `$ {t.statusText}`}). catch (e => console.log (e))} Function attemptScriptEmbedding (e, t) {initVerificationMessage ( ), hasEmbedScriptLoaded? renderComments (t): embedScript (t .EMBED_URL, t)} function addVisibilityListener (e, t) {new Visibility.Visible (e, {preloadThreshold: 750}). on (« preload », () => attemptScriptEmbedding (e, t))} function removeSignInButton (e) {e&&e.parentNode&&dom.removeElement (e)} function init (e) {const t = e.getAttribute (« data-coral-talk-host »), i = ` $ {t} / static / embed.js`, n = `http: // $ {document.documentElement.getAttribute ( » data-uri « )}. html`, a = » true « === e.getAttribute ( « data-maintenance »), o = -1! == n.indexOf (« @ published »), r = e.querySelector (« . coral-talk-container »), s = e.querySelector (« . coral- talk-btn-signin « ), c = {CORAL_TALK_HOST: t, EMBED_URL: i, commentStreamContainer: r, signInButton: s, TALK_ASSET_URL: n}; e, c), « .addEventListener (s.addEventListener », () => auth0.showLogin ()), auth0.isAuthenticated () &&removeSignInButton (s)}), auth0.on (« login », t => {removeSignInButtonT (s)., getAuth., getAuth (t), visibility.isElementInViewport (e) &&attemptScriptEmbedding (c), hasCoralTalkRendered&&coralLogin ()}), auth0.on (« logout », () => {store.remove (TALK_AUTH; module.ex)})) init =}; module.ex)
}, {« 1 »: 1, « 5 »: 5, « 11 »: 11, « 138 »: 138}];
window.modules [« choreographer.client »] = [function (require, module, exports) {« use strict »; const cookie = require (64), _ get = require (14), _ omit = require (102), {insertSpeedBumpComponents : insertSpeedBumpComponents} = require (99), {insertNewsletterSpeedBumpComponents: insertNewsletterSpeedBumpComponents} = require (100), {generateGrowl: generateGrowl} = require (98), gtm = require (2), {getLocalStorage: getLocalStorage:} LocalStorage, set = 47) , {reportPaywall: reportPaywall} = require (76), moment = require (52), {getClientHistory: getClientHistory, updateClientHistoryWithPageData: updateClientHistoryWithPageData} = require (101), auth0 = require (11), {Scenario: Scenario} = require (95 ), cidReadyEvent = « nymcid-set », cidKey = « nymcid », isProduction = require (9) (), logger = require (96) .Logger (() => getLocalStorage (« show_choreographer_logs »)), {Verdon: Verdon } = require (97), TEST_COHORT_FLAG = « optimizeCohort »; function displayDebug (e = «  ») {if (« entitlement »! == e.split (« # »). pop ()) return; const t = _get ( window, « dataLayer [0] .userDetails », {}), o = _get (win dow, « dataLayer [0] .pageDetails.featureTypes « , » « ), n = o.includes ( » magazine « )? » magazine « : » « , r = o.includes ( » feature « )? » featured « : » « , i = » value of the article: « (n || r || » article « ), a = _get (JSON.parse (localStorage.getItem ( » auth0: profile « )), » http: // nymag. com / app_metadata « ), l = » Authentication status: « (a? » authenticated « : » unauthenticated « ), s = » Authorization status: « (!! a&&a.has_subscription? » entitled « : » unentitled « ), c = Object. keys (_omit (t, « newYorkMediaUserID »)). map (e => `$ {e}: $ {t [e]}`), d = document.body, g = document.createElement (« div »), u = document.createElement (« ul »); [i, l, s, … c] .map (e => {const t = document.createElement (« li »); return t.classList.add ( » debug-item « ), t.appendChild (document.createTextNode (e)), t}). forEach (e => {u.appendChild (e)}), u.classList.add ( » data-bullets « ), g.classList.add (« debug-choreographer »), g.classList.add (« display-debug-data »), g.appendChild (u), d.appendChild (g)} function initializeChoreographer (e) {const t = e.getAttribute (« data-site-slug »), o = pageShouldCountAsView (t), n = auth0.isSubscr iber (); return t? getClientId (cidKey, 8e3) .then (e => (logger.h1 ( « Choreographer initialized »), logger.log (`clientId: $ {e}`), logger.log (`page counts as view: $ {o}`), window.nymViewsResponse || (o? UpdateClientHistoryWithPageData (e, t ): ge tClientHistory (e)))). then (r => {if (logger.group (), logger .h2 (« Client history »), logger.table (r), logger.groupEnd (), isNCR ()) return; const {scenarios: i, touts: a, testCohort: l = «  »} = readJSONFromScript (e. querySelector (« script »)); if (! (l === (document.body.dataset [TEST_COHORT_FLAG] || «  »))) return; const s = i.map (e => Scenario (Object.assign ( {}, e, {history: r, siteSlug: t, isSubscriber: n}))). filter (e => (logger.group (), logger.h2 (« Evaluate scenarios »), logger.log (e) , logger.groupEnd (), e.shouldShow)). reduce ((e, {action: t, min: o, count: n}) => {const r = a.find (({value: e}) = > e === t); Return r? (e [r.type] = r, e [r.type] .viewCount = no, e): e}, {}); logger.group (), logger. h2 (« Active Touts »), logger.log (s), logger.groupEnd (), executeTouts (e, o, s, r)}). catch (console.error): console.error (« siteSlug not found. « )} Function documentInc ludesComponent (e) {return document.querySelector (` [data-uri * = « / $ {e} / »] `)} function pageShouldCountAsView (e) {const t = » strategist « === e, o = [« product », « product-grid »]. find (e => documentIncludesComponent (e)); return t ||! o} Function executeTouts (e, t, o = {}, n) {const {global : r} = n, i = {featureArticleCount: r.Feature || 0, magazineArticleCount: r.Magazine || 0, standardArticleCount: r.Article || 0, totalArticleCount: r.total || 0}, a = window. concertAds, l = window.ConcertAds; if (o [« speed-bump »] && (_get (a, « adsBlocked »,! 0)? insertSpeedBumpComponents (findTemplate (e, « speed-bump »), o [« speed- bump « ], i): a.lifecycle.listenAndPlayback (l.events.slotsInserted, () => {insertSpeedBumpComponents (findTemplate (e, » speed-bump « ), o [ » speed-bump « ], i)}) ), o [« newsletter-speed-bump »] && (_get (a, « adsBlocked »,! 0)? insertNewsletterSpeedBumpComponents (findTemplate ( e, « newsletter-speed-bump »), o [« newsletter-speed-bump »], i): a.lifecycle.listenAndPlayback (l.events.slotsInserted, () => {insertNewsletterSpeedBumpComponents (findTemplate (e, « newsletter -speed-bump « ), o [ » newsletter-speed-bump « ], i)})), o [ » branded-growl « ] &&brandedTakeoverTime (o [ » branded-growl « ]) &&t) return logger. log (« should show Branded Growl »), void GrowlManager (findTemplate (e, « branded-growl »), {baseTrackingData: i, body: o [« branded-growl »]. brandedGrowlBody, contentClass: « branded-content », cta: o [« branded-growl »]. brandedGrowlCTA, imageUrl: o [« branded-growl »]. imageUrl, link: o [« branded-growl »]. brandedGrowlLink, name: o [« branded-growl »]. name, scrollDepth: o [« branded-growl »]. brandedGrowlScrollDepth, title: o [« branded-growl »]. brandedGrowlTitle, toutType: « branded-growl »}, « # branded-growl »); if (t&&o [ » content -cliff « ]) contentCliff (findTemplate (e, » content-cliff « ), o [ » content-cliff « ], o [ » content-cliff « ]. viewsLeft, n); else {if (t&&o [ » cliff – takeover « ]) return / coronavirus news | pivot | paywall exclude / i.test (window._nymGtmPage.tags)? void (isProduction&&logger.log ( » Content cliff no-op due to excluded tag: « , window._nymGtmPage. tags)): void cliffTakeover (findTemplate (e, « paywall-reader-interface »), i, o [« cliff-takeover »]); if (o [« growl-newletter »] ||! o [« Promo- Grow l « ]) if (o [ » Baby-Growl « ]) babyGrowl (findTemplate (e, » Paywall-Reader-Interface « ), i, o [ » Baby-Growl « ]); else {if (! o [« warning-growl-2 »]) return o [« warning-growl »] &&shouldWarn ()? (setContentCliffWarningDisplayed (), logger.log (« should show a warning »), void GrowlManager (findTemplate ( e, « warning-growl »), {contentClass: « warning-content », title: o [« warning-growl »]. warningGrowlTitle, name: o [« warning-growl »]. name, scrollDepth: o [« warning -growl « ]. warningGrowlScrollDepth, cta: o [ » warning-growl « ]. warningGrowlCTA, body: o [ » warning-growl « ]. warningGrowlBody, link: o [ » warning-growl « ]. warningGrowlLink, baseTrackingData: i, toutType: « warning Growl »}, « # warning-growl »)): void 0; warningGrowl (findTemplate (e, « paywall-reader-interface »), i, o [« warning-growl-2 »])} else growlManager (findTemplate (e, « growl-message »), {contentClass: « promo-content », title: void 0, name: o [« promo- Growl »]. name, scrollDepth: o [« Promo-Growl »] .promoGrowlScrollDepth, cta: o [« Promo-Growl »]. promoGrowlCTA, body: o [« Promo-Growl »]. promoGrowlMessage, link: o [« promo-growl »]. promoGrowlLink, baseTrackingData: i, toutType: « promo Growl « }, » # growl-message « )}} functi on shouldWarn () {return! contentCliffWarningDisplayed ()} function getContentCliffWarningDisplayedKey () {const e = new Date, t = e.getMonth (); return`content-cliff-warning-displayed – $ {e.getFullYear ()} – $ {t} `} function contentCliffWarningDisplayed () {const e = getContentCliffWarningDisplayedKey (); return » true « === getLocalStorage (e)} function setContentCliffWarningDisplayed () {const e = getContentCliffWarningDisplayedKey (); return setLocalStorage (); return setLocalStorage (e) } function GrowlManager (e, {contentClass: t, scrollDepth: o, name: n, title: r, body: i, cta: a, link: l, baseTrackingData: s, toutType: c, imageUrl: d = null}, g = «  ») {const u = function () {const e = ` n n n n $ {r} n $ {d?  »: » « } n $ {i} n $ {d? « : «  »} n $ {a} n n n n `; Return document.createRange (). createContextualFragment (e)} (), p = {creative: i, id: c , name: n, position: « growl »}; u.querySelector (« a ») .addEventListener (« click », () => promotionReport (« Click », s, p)), generateGrowl (e, g, { content: u, scrollDepth: o, onShow: () => promotionReport (« View », s, p)})} Function contentCliff (e, t, o, n) {const {first_vi sit: r, global: i} = n, a = {totalArticleCount: i.total || 0, standardArticleCount: i.Article || 0, featureArticleCount: i.Feature || 0, magazineArticleCount: i.Magazine || 0} , {contentCliffBody: l} = t, s = document.importNode (e,! 0) .querySelector (« . content-cliff »), c = document.querySelector (« . article-content> .clay-paragraph »), d = {creative: l, id: « content cliff », name: « Content Cliff », position: « in-article »}; s&& (c.insertAdjacentHTML (« afterend », s.outerHTML), require (« content- cliff.client « ) (document.querySelector (.content-cliff »), {contentCliffOptions: t, viewsLeft: o, firstVisit: Number (r), onShow: () => promotionReport (« View », a, d), onClickCliff: () => promotionReport (« Click », a, d)}))} fu nction verdonFosseToutSetter (e, t, o, n, r) {const i = new Verdon ({container: « . paywall-reader- interface « , url: » https://fosse.nymag.com/fosse/v1.6.1 /index.html »}),a=e.type,l= Genealogie:auth0.getEmail(),isAuthenticated:auth0. isAuthenticated (), isSubscriber: auth0.isSubscriber ()}; n.classList.add (a), i.once (« frame: ready », () => {i.sendMessage (« tout: s how « , {readerState: l, toutType: a, toutData: e}), r&&i.sendMessage ( » frame: height « )}), i.on ( » tout: visible « , () => {promotionReport ( » View « , t, o)}), i.on ( » tout: sign-in « , () => {auth0 .showLogin (window.location.href)}), i.on ( » tout: log-out  » , () => {auth0.logout ()}), i.on (« tout: dismiss », () => {n.classList.add (« dismiss »), i.sendMessage (« tout: hide », {toutType: a, toutData: e})}), i.on (« tout: subscribe », () => {e.ctaLink = replaceQueryParams (e.ctaLink), promotionReport (« Click », t, o), window.location.href = e.ctaLink}), i.on (« frame: height », e => {n .style.height = `$ {e.payload.currentHeight 10} px`}), i.on (« tout: view-account », () => {window.location.href = « https: // subs. nymag.com/account »}))functional action pro tionReport (e, t, o) {const {creative: n, id: r, name: i, position: a} = o; t.event = `eec.promotion $ {e} `, t.ecommerce = {promoView: {promotions: [{creative: n.trim (), id: r, name: i, position: a}]}}, gtm.reportNow (t), reportPaywall ( {creative: n.trim (), eventType: e, id: r, name: i, position: a})} Function babyGrowl (e, t, o) {const n = document.importNode (e,! 0). querySelector (.paywall-reader-interface « ), r = {creative: o.babygrowlDescription, id: » babygrowl « , name: » babygrowl « , position: » growl « }; document.body.appendChild (n), o. ctaLink = o.babygrowlCtaLink, o. ctaText = o.babygrowlMessage, o.headline = o.babygrowlDescription, verdonFosseToutSetter (o, t, r, n)} function cliffTakeover (e, t, o) {const {cliffTakeoverCTA: n, cliffTakeoverCtaLink: r, cliffTakeImage. cliffTakeover: iiffTakeover : a, cliffTakeoverPromo: l, cliffTakeoverStatus: s, type: c} = o, d = document.importNode (e,! 0) .querySelector (« . paywall-reader-interface »), g = document.querySelectorAll (« . Clay-Paragraph « ), u = {creative: l, id: » content cliff « , name: » Content Cliff « , position: » growl « }, p = {cta: n, ctaLink: r, description: i, image : a, promo: l, status: s, type: c}; document.body.appendChild (d), g.forEach ((e, t) => {0! == t&&e.remove ()}), verdonFosseToutSetter (p, t, u, d,! 0), document.querySelector (« html »). style.overflowY = « hidden », document.body.style.position = « fixed »} function warningGrowl (e, t, o ) {const {type: n, warningGrowl2CTA: r, warningGrowl2CtaLink: i, warningGrowl2Description: a, warningGrowl2Image: l, warningGrowl2Promo: s, warningGrowl2Status: c} = o, d = document.importNode (e,! 0). querySelector (« . paywall-reader-interface »), g = {creative: s, id: « warning Growl », name: « Warning Growl », position: « growl »}, u = {cta: r, ctaLink: i , description: a, image: l, promo: s, status: c, type: n}; document.body.appendChild (d), verdonFosseToutSetter (u, t, g, d,! 0)} function getClientId (e = «  », t = 8e3) {let o = cookie.get (e); return o? Promise.resolve (o): new Promise ((o, n) => {const r = setTimeout (() => {n (`couldn’t find key: $ {e} on cookie after $ {t} ms`)}, t); window.addEventListener (cidReadyEvent, () => {clearTimeout (r), o (cookie.get (e) )})})} Function readJSONFromScript (e) {try {return JSON.parse (e.innerHTML)} catch (e) {return {touts: [], scenarios: []}}} function findTemplate (e, t = «  ») {const o = e&&e.querySelector (`[data -template-id = » $ {t} « ]`); return o&&o.content} function isNCR () {return / [? &] source = ncr / .test (location.search)} function brandedTakeoverTime (e) {const {startTime: t, endTime: o, startDate: n, endDate: r} = e, i = n.concat («  », t), a = r .concat («  », o), l = moment (i), s = moment (a); back hr moment (). isBetween (l, s)} functionOptimizeDebugger () {return new Promise (e => {const t = window.location.search || «  »; if (t) {const o = new URLSearchParams (t) , n = o.get (« optimize-attribute-name ») || «  », r = o.get (« optimize-attribute-value ») || «  », i = o.get (« optimize-delay » ) || 0, a = o.get (« optimize-cookie ») ||! 1; setTimeout (() => {a&& (document.cookie = randomNymcid ()), document .body.setAttribute (`data- $ {n} `, r), e ()}, i)} else e ()})} function randomNymcid () {return`nymcid = $ {(() => ([1e7] -1e3 -4e3 -8e3 – 1e11) .replace (/ [018] / g, e => (e ^ 16 * crypto.getRandomValues ​​(new Uint8Array (1)) [0] >> e / 4) .toString (16) [0])) ( )} `} Function replaceQueryParams (e) {const t = window.location.search || » « ; if (t) {const o = new URLSearchParams (t); if (e.includes (« ? « )) {Const t = e.split (« ? »), n = new URLSearchParams (t [1]); for (let e of o.entries ()) n.set (e [0], e [1]); e = `$ {t [0]}? $ {n.toString ()}`} else e = `$ {e}? $ {o.toString ()}`} return e} module.exports = (e => new Promise (e => {auth0.on (« init », () => {e ()})}). Then (() => OptimizeDebugger ()). Then (() => {displayDebug (window.location.href), initializeChoreographer (e)}));
}, {« 2 »: 2, « 9 »: 9, « 11 »: 11, « 14 »: 14, « 47 »: 47, « 52 »: 52, « 64 »: 64, « 76 »: 76 , « 95 »: 95, « 96 »: 96, « 97 »: 97, « 98 »: 98, « 99 »: 99, « 100 »: 100, « 101 »: 101, « 102 »: 102,  » content-cliff.client « : » content-cliff.client « }];
window.modules [« growl.client »] = [function (require, module, exports) {« use strict »; require (162); const _some = require (82), dom = require (5), localStorageKeyRoot = « slideout – « , {getLocalStorage: getLocalStorage, setLocalStorage: setLocalStorage} = require (47); module.exports = ((e, t) => {const {content: o, onShow: s, scrollDepth: r = 50, dismissable: i =! 1} = t, n = Number (r || e.getAttribute (« data-display-at-page-scroll-percentage »)), a = dom.find (e, « . Modal »), l = « slideout- » (t.id || e.getAttribute (« id »)), c = getLocalStorage (l); function d () {a.classList.add (« hidden »)} function g () {setLocalStorage ( l,! 0), d ()} i&&c? e.remove () 🙁 o&&e.querySelector (« [data content] »). appendChild (o), n&&function (e = 50) {constOb = new intersection (e = 50) > {_ some (e, « isIntersecting ») && (a.style.top = « inherit », a.classList.remove (« hidden », « initial »), « function » == typeof s&&s (), t .unobserve (a))}); a.style.top = `$ {document.querySelector ( » body « ). scrollHeight / (100 / e)} px`, t.ob serve (a)} (n), e.querySelector (« . dismiss-modal »). addEventListener (« click », () => i? g (): d ()), e.addEventListener (« growl: hide « , d), e.addEventListener ( » growl: dismiss « , g))});
}, {« 5 »: 5, « 47 »: 47, « 82 »: 82, « 162 »: 162}];
window.modules [« speed-bump.client »] = [function (require, module, exports) {« use strict »; const gtm = require (2), visibility = require (1); module.exports = ((e , i) => {if (! i ||! e) return; const {name: o, speedbumpDescription: r, speedbumpMessage: t, speedbumpLink: n, baseTrackingData: s} = i, c = new visibility.Visible (e , {shownThreshold: .5}); e.querySelector (« . description »). innerHTML = r, e.querySelector (« . promo-link »). innerHTML = t, e.querySelector (« . promo-link ») .href = n, e.classList.remove (« collapsed »), c.on (« shown », function () {if (visibility.isElementNotHidden (e)) {let e = s; e.event = « eec. promotionView « , e.ecommerce = {promoView: {promotions: [{name: o, creative: r, id: » speed Bump « , position: » in-article « }]}}, gtm.reportNow (e), c .destroy ()}}), e.querySelector (« . promo-link »). addEventListener (« click », function () {let e = s; e.event = « eec.promotionClick », e.ecommerce = { promoClick: {promotions: [{name: o, creative: r, id: « speed bump », position: « in-article »}]}}, gtm.reportNow (e)})});
}, {« 1 »: 1, « 2 »: 2}];
window.modules [« newsletter-speed-bump.client »] = [function (require, module, exports) {« use strict »; const {loadRecaptcha: loadRecaptcha} = require (130), _ isEmpty = require (109), _ set = require (129), _ kebabCase = require (103), gtm = require (2), auth0 = require (11), visibility = require (1), COMPONENT_NAME = « newsletter-speed-bump », EMAIL_VALID_REGEX = / ^ (? : (?: [^ () [] \.,;: s @ « ] (?: . [^ () [] \.,;: s @ »]) *) | (« . »)) @ (?: (?: [[0-9] {1,3} . [0-9] {1,3} . [0-9] {1,3} . [0-9] {1,3}]) | (?: (?: [A-zA-Z -0-9] .) [A-zA-Z] {2,})) $ /, LOCAL_STORAGE_KEY_NAME = « newsletterSpeedBumpSignUpStatus _ », MAX_EMAIL_LENGTH = 50; function setClass (e, t) {e.classList.add (t)} function getRequestUrl (e) {return e.getAttribute (« action »)} function getPageType (e) {const t = e? e.getAttribute (« content »): «  »; return _kebabCase (t)} function getPayloadObject (e, t, r, s) {const n = {}; return _set (n, `vars. source _ $ {t} `,` $ {COMPONENT_NAME} _ $ {s} `), n.email = r, n.lists = {}, n.lists [t] =! 0, n.recaptcha = e, n .signuppage = `$ {document.location.href} _ $ {t}`, n [`source _ $ {t}`] = « newsleter_speedbump », n} module .exports = ((e, t) => {if (! t ||! e) return; if (« success » === window.localStorage.getItem (`$ {LOCAL_STORAGE_KEY_NAME} $ {t.newsletterSpeedBumpNewsletterId}`) ) return void e.remove (); const {baseTrackingData: r, name: s, newsletterSpeedBumpCtaCopy: n, newsletterSpeedBumpDescription: i, newsletterSpeedBumpHeadline: a, newsletterSpeedBumpNewsletterId: o, newsletterSpeedBumpThank0.E. ), d = e.querySelector (« . description »), p = e.querySelector (« . input.email »), m = e.querySelector (« . error-message »), h = e.querySelector (« . form « ), E = e.querySelector (« . form-container « ), y = e.querySelector (« . form-recaptcha-container « ), g = e.querySelector (« . headline « ), v = e. querySelector (« . container »), S = e.querySelector (« . input.newsletterId »), _ = e.querySelector (« . recaptcha-wrapper »), L = e.querySelector (« . input.submit »), w = e.querySelector (.text-container « ), q = new visibility.Visible (e, {shownThreshold: .5}); u&& (p.removeAttribute ( » required « ), e.classList.add ( » signed – in « )), d.innerHTML = i, g.innerHTML = a, S.value = o, L .value = n, q.on ( » shown « , function () {if (visibility.isElementNotHidden (e)) {const e = r; e.event = « eec.promotionView », e.ecommerce = {promoView: {Promotions: [{creative: `$ {a} | $ {i}`, id: « Newsletter speed threshold », name: s, position: « in-article »}]}}, gtm.reportNow (e), q.destroy ()}}), p.addEventListener (« focus », () => {_. classList.remove (« hidden »)}), h.addEventListener (« submit », t => {t.preventDefault (); const s = new XMLHttpRequest, n = u | | e.querySelector (« . input.email »). value , i = getPageType (document.querySelector (‘meta [name = « type »]’)); u ||! (n.length> = 50) &&EMAIL_VALID_REGEX. test (n)? loadRecaptcha (l, « newsletterSubmit » ,! 0) .then (a => {s.ope n (« POST », getRequestUrl (h),! 0), s.setRequestHeader (« Content-Type », « application / json; charset = UTF-8 »), s.addEventListener (« load », s => { const a = s.currentTarget || s.target; if (a.status> = 200&&a.statussetClass (e, « success »)), [d, E, m, _]. forEach (e => setClass (e, « hidden »)), g.innerHTML = c.replace (« {{email}} », n), m.innerHTML = «  »; const s = JSON.parse (a.response), l = _isEmpty (s. sailthruIds)? «  »: Object.values ​​(s.sailthruIds) [0], u = r; u.event = « eec.purchase », u.ecommerce = {purchase: {actionField: {id: l, revenue:  » 0.00 « }, products: [{category: » Newsletter registration « , name: S.value, quantity: 1, variant:` $ {COMPONENT_NAME} – $ {i} `}]}}, gtm.reportNow (u) , setTimeout (() => {e.classList.add (« hidden »)}, 5e3), t.preventDefault ()} else m.innerHTML = « * An error has occurred. Please try again. « }), S.addEventListener ( » error « , () => {m.classList.remove ( » hidden « ), m.innerHTML = » * An error has occurred. Please try again . « }), s.send (JSON.stringify (getPayloadObject (a, o, n, i))), t.preventDefault ()}): m.innerHTML = » * Please enter a valid email address a »})});
}, {« 1 »: 1, « 2 »: 2, « 11 »: 11, « 103 »: 103, « 109 »: 109, « 129 »: 129, « 130 »: 130}];
window.modules [« content-cliff.client »] = [function (require, module, exports) {« use strict »; const auth0 = require (11), isProduction = require (9) (), logger = require (96 ) .Logger (() =>! IsProduction); module.exports = ((t, e) => {if (! E) return; logger.group (), logger.h2 (« Content Cliff »); const { contentCliffOptions: o, firstVisit: n, onShow: r, onClickCliff: i} = e, c = 300, l = Number (document.querySelector (« [data-components-count] »). getAttribute (« data-components-count « )), u = 3, s = [ » taboola « ], a = » # content-cliff « , f = t, d = function () {let t = 0; return document.querySelectorAll ( » [data-word -count] « ). forEach (function (e) {t = Number (e.getAttribute ( » data-word-count « ) || 0.10) || 0}), t} (), g = function ( t, e) {function o (t) {return Math.round (t.getTime () / 1e3 / 60)} const n = o (t), r = o (e); return nr} (new date, new Date (n)) {}, show: () => {r (), function () {(p = function (t = «  ») {return document.querySelectorAll (`$ {t} ~ *`)} ( a)). forEach (t => t.remove ()), function () {const {contentCliffStatus: e, contentCliffPromo: n, contentCliffCTA: r, contentCliffURL: c} = o, l = t.querySelector (« [data -Content -cliff-status] « ), u = t.querySelector ( » [data-content-cliff-promo] « ), s = t.querySelector ( » [data-content-cliff-cta] « ); s&&s. setAttribute (« href », c), s&&s.insertAdjacentHTML (« afterbegin », r), l&&l.insertAdjacentHTML (« afterbegin », e), u&&s.insertAdjacentHTML (« afterbegin », r), l&&l.insertAdjacentHTML (« afterbegin », e), u&&s.insertAdjacentHTML (click&&u.insert) « , Eventi} (), f.classList.remove ( » collapsed « ), e = s, e.forEach (t => {const e = document.querySelector (` [data-uri * = « / $ {t} / « ]`); e&&e.remove ()}), m.addEventListener (« click », () => auth0.showLogin ()); var e} ()}} [function () {if (dl) return logger.log (`Article word count $ {d} was too short for the cliff`), logger.log (` The number of article components is less than $ {u} and not suitable for the cliff`), « noop »; if (g&&isProduction) return « noop »; g&&logger.log (`First session check was $ {g}! Show the cliff anyway: isProduction => $ {isProduction} `); if (/ coronavirus news | pivot | paywall exclude / i.test (window._nymGtmPage.tags)) return isProduction&&logger.log ( » Content cliff no-op due to excluded Tag match: « , window._nymGtmPage.tags), » noop « ; return » show « } ()], m = t.querySelector (.content-cliff-login »); let p = []; return logger. log (`should be in production due to the 30-minute window of the first session: $ {g}`), logger.groupEnd (), auth0.on (« login », () => {f.classList.add ( » collapsed « ), (p = Array.prototype.slice.call (p, 0) .reverse ()). forEach (t => f.insertAdjacentElement ( » afterend « , t)), p = []}), » Function « == type of h? H (): void 0});
}, {« 9 »: 9, « 11 »: 11, « 96 »: 96}];
window.modules [« ad.client »] = [function (require, module, exports) {« use strict »; const _forEach = require (63), _ max = require (66), _ find = require (65), _ includes = require (67), $ visibility = require (1), dom = require (5), MAX_MOBILE_RE = / [[0-9] {1,3} – (768 | 600) /, MAX_TABLET_RE = / [0-9] {3} – (1024 | 1180) /, DESKTOP_RE = / (1024 | 1180) -plus /, AD_NAME_SELECTOR = ‘[data name ^ = « / 4088 / »], [data name ^ = « / 172968584 / »]’; var flaggedComponentsOnPage = function () {var e, t = document.querySelector (.article-content « ), n = []; return t&&_forEach ([‘. article-sidebar [data-width = » large « ]’], function ( a) {e = t.querySelectorAll (a), _ forEach (e, function (e) {n.push (e)})}), n} (); function getElementsVerticalOverlap (e, t) {var n = e. getBoundingClientRect (), a = t.getBoundingClientRect (); return! (n.top> a.bottom || n.righta.right)? a.bottom-n.top: 0} function getElementsOverlapAmount (e, t) {var n, a = []; return _forEach (t, function (t) {n = getElementsVerticalOverlap (e, t), a.push (n)}), _ max (a)} function getNYMagAdChannel (e) {var t =  » « ; switch (e) {case » Unternehmensinformatio nen « : t = » comp any « ; break; case » new york guides & things to do « : t = » to-do « ; break; case » other « : t = e; break; case » sponsored guides « : t = « s-guides »; break; case « urbanist »: t = « urbanist »; break; default: t = «  »} return t} function appendSectionToDfpAds () {var e, t, n, a = document.querySelector (« meta [property = ‘og: site_name’] »), o = document.querySelector (« article [data-content-channel] »), i = document.querySelectorAll (AD_NAME_SELECTOR); a&& (e = a.content) , o&& (t = o. getAttribute (« data-content-channel »). toLowerCase ()), t&& « New York Magazine » === e&& (n = getNYMagAdChannel (t)), n&&) {letPage) document.querySelector (« . body> div ») || {}, t = document.querySelector (« body ») || {}, n = e&&e.classList, a = n&&n.length? [… n]: [], o = _find (a, e => e.includes (« feature »)), i = document.querySelectorAll (AD_NAME_SELECTOR); n&& (o? appendPageNumberPositionToDfpAds (i, « Feature »): n.contains (« lede -gallery-content « )? appendPageNumberPositionToDfpAds (i, » Image_Gallery « ): t.classList.contains ( » one-column-layout « )? appendPageNumberPositionToDfpAds (i, » One_Column_Article « ): n .contains ( » article-content « ) &&appendPageNumberPositionToDfpAds (i, « Standard_Article »))} function appendPageNumberPositionToDfpAds (e, t) {const n = [« 528×379 », « 1100×200 », « 1×1 »]; let a = e || [], o = dom.find (« . ad-splash »), i = dom.find (« section.wrapper »), r = dom.find (« . secondary »), d = dom.find (« . bottom « ), s = dom.find (« . primary « ), c = {IA: {xsMobile: {normal: 1, grid: 1}, mobile: {normal: 1, grid: 1}, tablet: {normal : 1, grid: 1}, desktop: {normal: 1, grid: 1}}, BA: {xsMobile: {normal: 1, grid: 1}, mobile: {normal: 1, grid: 1}, tablet: {normal: 1, grid: 1}, desktop: {normal: 1, grid: 1}}}; a.forEach (e => {let a, l = «  », u = e.dataset.sizes, m = e.classList.value, p = _find (n, e => u.includes (e)), g = e.parentElement.classList.contains (« image-gallery-mobile-grid-ad »); if (u&&! p || e.setAttribute (« Datenname », e.getAttribute (« Datenname ») « / » t), iCSSEANDCHA R&u&&! p) {let n, u; if (o&&o.contains (e)? l = « LB » : i&&i.contains (e)? l = « IA » 🙁 r&&r.contains (e) || dCHAR&CSSEAND (e) || s&&s.contains (e)) = « l » BACHARCSSEAND (e)) = « l » BACHARCSSEAND {if (! (u = checkForAdViewport (m))) return; g? (n = c [l] [u] .grid, c [l] [u] .grid) 🙁 n = c [l] [u ] .normal, c [l] [u] .normal ), a = n {e.setAttribute (« data-name », e.getAttribute (« data-name ») « / » t)})} function injectGoogleScripts () {var e = document.createElement (« script ») , t = document.createElement (« script »), n = document.createDocumentFragment (); e.src = « // www.googletagservices.com/tag/js/gpt.js »,e.async= »async », t.src = « // pagead2.googlesyndication. com / pagead / js / adsbygoogle.js « , t.async = » async « , n.appendChild (e), n.appendChild (t), document.getElementsByTagName ( » body « ) [0] .appendChild (n)} appendSectionToDfpAds (), appendPageTypeToDfpAds (), injectGoogleScripts (), DS.controller (« ad », [« adService », function (e) {return function (t) {var n, a, o, i = t.getAttribu te ( « data-offload »), r = new $ visibility.Visible (t, {preloadThreshold: i? window.innerHeight / 4: 200}), d =! 1; function s () {window.innerWidth> = 1180&&t .parentElement .classList.contains (« ad-repeat ») &&flaggedComponentsOnPage.length&& (a = getElementsOverlapAmount (t, flaggedComponentsOnPage), o = parseint a « px »)} function c () {s (), e.refresh (n)} function l () {e.remove (n), d || (d =! 0, r.on (« shown » , c))} document.querySelector (‘script [data-name = « concert-ads »]’) || (n = e.create (t), r.preload&& $ visibility.isElementNotHidden (t)? (e. addToPageLoadQueue (n), i&&r.on (« hidden », l)): (r.on (« preload », function () {! n.slot&& $ visibility.isElementNotHidden (t) && (s (), e.load (n))}), i&&r.on (« hidden », l) ), this.adData = n)}}]);
}, {« 1 »: 1, « 5 »: 5, « 63 »: 63, « 65 »: 65, « 66 »: 66, « 67 »: 67}];
window.modules [« sticky-list.client »] = [function (require, module, exports) {« use strict »; const dom = require (5), $ gtm = require (2), _ get = require (14) , stickyContainer = require (« sticky-container.client »); DS.controller (« sticky-list », [« $ window », function (t) {var e = require (241), i = 40; function s ( s) {let n, r = function (t) {let s = t [0], n = 0, r = e.height (this.contentArea), o = this.contentArea.offsetHeight; if (this.containers&&this. container.length) {if (s.target.offsetHeight) {let t = this.breakouts.findIndex (t => (function (t, e) {return t! == document.body&&t.contains (e)}) ( t, s.target.parentElement)); if (t> -1&&this.breakouts [t]) {let e = this.breakouts [t] .offsetHeight i; this.containers [t] .style.marginBottom = `$ { e} px`}} if (o! == this.currentHeigh) {const t = e.rect (this.rightRail, this.contentArea); this.currentHeight = o, this.rightRail.style.height = rt.top -a (this.rightRail) « px », this.breakouts.forEach ((s, r) => {let a = e.rect (s, this.contentArea), o = e.intersection (a, t); if (o) {let e, s = o .top-t .top-n; n = s o.height i, this.containers [r] .style.height = `$ {s} px`, this.containers [r] .style.minHeight =` $ { s} px`, e = this.breakouts [r] .offsetHeight i, this.containers [r] .style.marginBottom = `$ {e} px`}})}}}. bind (this); t.innerWidth {let n = _get (e, « dataset.name », «  »), r = n.slice (-1) || « 1 », a = [« Image_Gallery », « Standard_Article », « Feature », « One_Column_Article « ] .find (t => n.includes (t)) || » « ; this.rightRail.parentElement.classList.contains ( » tertiary « ) &&a&& (e.dataset.name = parseInt (i, 10) se = == t) || 0; return i.slice (s 1) .reduce ((t, e) => t (e.offsetHeight || 0), 0) || 0} return s.prototype = {setPins: function () {const t = e.rect (this.rightRail, this.contentArea), i = e.height (this.contentArea), s = it.top-a (this.rightRail); let n, o, h , l; if (this.populatePinsList (), s1&&t.classList.add (« multi-children »), l = 0; l {const t = Array.from (e.children); let o, a, i = 0 ; for (; i {handleLazyLoad (a)});
}, {« 5 »: 5, « 118 »: 118}];
window.modules [« article.client »] = [function (require, module, exports) {« use strict »; const $ visibility = require (1), $ gtm = require (2), ImageZoom = require (79), $ sentry = require (80); DS.controller (« article », [function () {var e = 40; function t (t) {const i = document.querySelector (« . wrapper> .tertiary »), n = t.querySelector (« . lede-image-wrapper.full-bleed »), r = t.querySelector (« . attribution.full-bleed »), o = t.querySelector (« . article-header »), l = o? o.querySelector (« img »): null, c = function () {let t = o.getBoundingClientRect (). height; n&& (t = n.getBoundingClientRect (). height 25, r&CSSEANDRect (t = r.getBounding () .height)), i.style.paddingTop = te « px »}; i&&o&& (window.innerWidtht (e)), document.addEventListener (« closeBanner », function () {i (e)}), $ sentry .initializeIDListeners ()}}]);
}, {« 1 »: 1, « 2 »: 2, « 79 »: 79, « 80 »: 80}];
window.modules [« tags.client »] = [function (require, module, exports) {« use strict »; const _forEach = require (63); DS.controller (« tags », [function () {function e ( e) {this.el = e} return e.prototype = {events: {« a.more click »: « showAll »}, showAll: function (e) {var t = e.target, o = this.el. querySelectorAll (« li.hidden »); _ forEach (o, function (e) {e.classList.remove (« hidden »)}), t.parentNode.removeChild (t), e.preventDefault ()}}, e} ]);
}, {« 63 »: 63}];
window.modules [« image.client »] = [function (require, module, exports) {« use strict »; const dom = require (5), lazyLoad = require (118); module.exports = (e => { const a = dom.findAll (e, « source [data-srcset] »), d = dom.find (e, « img [data-src] »), o = dom.find (e, « . image-wrapper « ); new lazyLoad.LazyLoader (o, d, a) .init ()});
}, {« 5 »: 5, « 118 »: 118}];
window.modules [« affiliate-links.client »] = [function (require, module, exports) {« use strict »; const dom = require (5), _ includes = require (67), _ startsWith = require (71), globalClick = require (69), visit = require (70), productSubtags = require (72); var excluded Hostnames, skimlinksBaseUrl, skimlinksId, visitState, productUrl, ignoreDataAttribute = « data-affiliate-links-ignore », article = window.document. querySelector (« article »), isSponsored = article&& « Sponsor Story » === article.getAttribute (« data-type »); function setExcludedHostnames (t) {excludedHostnames = (t.getAttribute (« data-excluded-hostnames ») | | «  »). toLowerCase (). split (« , »)} function isSkimLink (t) {return !! (skimlinksId = t.getAttribute (« data-skimlinks »))} function isExcluded (t) {return _includes (excludedHostnames , t) || _startsWith (t, « www. ») &&_includes (excludedHostnames, t.slice (4)) || isSponsored} function isUrlProtocol (t) {return 0! == t.indexOf (« mailto: ») &&0 ! == t.indexOf (« javascript: »)} function getTargetHostname (t) {return (t.ho stname || t.host || t.href || «  »). toLowerCase ()} function convertSkimlinkUrl (t) {return (skimlinksBaseUrl = skimlinksBaseUrl || skimlinksId? « // go.redirectingat.com/?xs=1&id= » skimlinksId « &sref = » encodeURIComponent (window.location.href) « CSSimEANDCHARurlSSE )} function hasIgnoreAttribute (t) {return  » true « === t (t) {var e, i, r, s = dom.closest (t.target, » a « ), n = s&&s.href; n&&n.length&&! t.defaultPreventedHargetCSSEAND! t.defaultPreventedCSSEAND (i s), (isUrlProtocol n) || isExcluded (i) || hasIgnoreAttribute (s) || productSubtags.getAffiliate (n) || (e = convertSkimlinkUrl (n)) && (productUrl = n, r = s&s. « getAffiliate » data-track-id « ), s.href = productSubtags.ensureSubtag ({url: e, productId: r, visitState: visitState, anchorEl: s})))} function revertSkimLink (t) {var e = dom.closest ( t.target, « a »), i = e&C SSEANDCHARe.href || «  »; i.includes (skimlinksBaseUrl) &&i&&i.length&&productUrl&i.length&&productUrlCSSEAND => product isitm. {visitState = t}), e&& (setExcludedHostnames (t), globalClick.addHandler (convertSkimlink, revertSkimLink))});
}, {« 5 »: 5, « 67 »: 67, « 69 »: 69, « 70 »: 70, « 71 »: 71, « 72 »: 72}];
window.modules [« gtm.client »] = [function (require, module, exports) {« use strict »; const $ gtm = require (2); DS.controller (« gtm », [function () {return function (t) {$ gtm.init (t.getAttribute (« data-container-id »), t.getAttribute (« data-site-slug »))}}]);
}, {« 2 »: 2}];
window.modules [« global-nav.client »] = [function (require, module, exports) {« use strict »; const dom = require (5), auth0 = require (11), signInButton = dom.find ( » .user-signin « ), signOutButton = dom.find (« . user-signout « ), globalNav = dom.find (‘[class ^ = » global-nav « ]’), body = dom.find ( » body  » ), dropdownItems = dom.findAll (« . dropdown-wrap »), gtm = require (2), pageUri = require (158) .getPageUri (), subscriptionPromoLinks = dom.findAll (« . persist-params »), searchString = window.location.search || «  »; function closeDropdowns (e) {let t = globalNav.querySelectorAll (« . dropdown.open »); dropdownItems.forEach (function (n) {let i = n.querySelector (« . dropdown « ) ;! t || n.contains (e.target) &&27! == e.keyCode || i.classList.remove ( » open « )})} function gtmSendReport (e, t, n) {let i = {eventCategory: « ecommerce », eventAction: « componentClick », brand: e, dimension23: « global-nav », list: pageUri, pageZone: « header », variant: « nav-link »}; « global-nav-link « === n&& (i.eventLabel = t.href), gtm.reportNow (i)} function updateElementTargetUrlsIfQueryStri ngs (e) {if (searchString) {const t = new URLSearchParams (searchString); let n = e.href; if (n.includes (« ? »)) {const i = n.split (« ? »), o = new URLSearchParams (i [1]); for (see e from t.entries ()) o.set (e [0], e [1]); n = `$ {i [0]}? $ { o.toString ()} `, e.href = n} else e.href =` $ {n}? $ {t.toString ()} `}} function init (e) {auth0.on ( » init « , () => {signInButton.addEventListener (« click », function (e) {e.preventDefault (), auth0.showLogin ()}), signOutButton.addEventListener (« click », function (e) {e.preventDefault () , auth0.logout (), gtmSendReport (« Abmelden », e.target, « user-info-link »)}), auth0.isAuthenticated () &&e.classList.add (« signed-in »), auth0.isSubscriber ( ) &&e. classList.add (« subscribed »), e.querySelectorAll (« . user-link »). forEach (e => {e.classList.add (« active »)}), subscriptionPromoLinks.forEach (e => {updateElementTargetUrlsIfQueryStrings ( e)})}), auth0.on (« login », () => {e.classList.add (« signed-in »), auth0.isSubscriber () &&e.classList.add (« subscribed »)}) , auth0.on (« logout », () => {e.classList.remove (« registered »), e.classList.remove (« subscribed »)})} dropdownItems.forEach (function (e) {e.addEventListener (« click », function () {e.querySelector (« . dropdown »). classList.toggle (« open »)})}), body.addEventListener (« click », closeDropdowns), document.addEventListener (« keydown » , closeDropdowns), globalNav.addEventListener (« click », function (e) {let t = e.target; t.classList.contains (« global-nav-track ») &&gtmSendReport (t.text, t, « global-nav -link « )}), module.exports = init;
}, {« 2 »: 2, « 5 »: 5, « 11 »: 11, « 158 »: 158}];
window.modules [« aaa-module-mounting.legacy »] = [function (require, module, exports) {« use strict »; const _pickBy = require (161), _ each = require (322), Fingerprint2 = require (324 ), DS = require (323), Eventify = require (186); function registerGlobals () {window.DS = DS, window.Eventify = Eventify, window.Fingerprint2 = Fingerprint2, DS.value (« Eventify », Eventify), DS.value (« Fingerprint2 », Fingerprint2), DS.value (« $ document », window.document), DS.value (« $ window », window)} function mountDollarSliceComponents () {DS.service (« components », [« $ document », « $ module », function (e, n) {var o = _pickBy (n.definitions, e => e.providerStrategy === n.providers.controller), r = Object.keys (o ); Function t (e) {return o => {try {n.get (e, o)} catch (e) {logMountError (o, e)}}} _ each (r, n => {var o = e .querySelectorAll (‘[data-uri * = « / _ components /’ n ‘/ »▶’),r=e.querySelectorAll(‘[data-uri$= »/_components/’ n ‘ »]’); _ each ( o, t (n)), _ each (r, t (n))}), this.components = r}]), DS.get (« components »)} function logMountError (e, n) {const o = e .outerHTML.slice (0, e.outerHTML.indexOf (e.innerHTML)); con sole.er ror (« Error attaching the controller to » o, n)} registerGlobals (), « loading » === document.readyState? document.addEventListener (« DOMContentLoaded », () => {mountDollarSliceComponents ()}) : mountDollarSliceComponents ();
}, {« 161 »: 161, « 186 »: 186, « 322 »: 322, « 323 »: 323, « 324 »: 324}];
window.modules [« ads.legacy »] = [function (require, module, exports) {« use strict »; const _map = require (73), _ forEach = require (63), _ isString = require (205), _ intersectionWith = require (325), _ isEqual = require (212), _ each = require (322), _ debounce = require (121), _ sortBy = require (145), page = require (158), visit = require (70); DS.service (« adService », [« Eventify », « $ cid », « $ document », « $ window », function (e, t, a, i) {var o, n, s, r, d, c, l , u, g, p, h = {}, m = this, f = [], b = visit.getQueryParamsObject ([« utm_campaign »]), w = document.querySelector (‘script [data-type = « ad- a9 « ] ‘), v = [], y =! 1, _ = [], S = document.querySelector (‘ script [data-name = » ad-doubleverify « ] ‘); document.querySelector (‘ script [ data-name = « concert-ads »] ‘) || (i.NYM = {}, i.NYM.analytics = {}, i.NYM.analytics.adStartTime = i.performance.now (), i.googletag = i.googletag || {}, i.googletag.cmd = i.googletag.cmd || [], c = i.googletag, (w || S) && (i.googletag.cmd = i.googletag.cmd || [], i.googletag.cmd.push (function () {i.googletag.pubads (). disableInitialLoad ()})), w&& (l = i.setInterv al (func tion () {void 0! == window.apstag&&void 0! == window.apstag.timeout&& (i.clearInterval (l), window.apstag.cleared =! 0, l = null)}, 10), setTimeout (function () {l&& (i.clearInterval (l), i.googletag.pubads (). refresh (), window.apstag || console.log (« MESSAGE: Timeout for A9 load exceeded, abort »)) }, 500)), S&&v.push (new Promise (function (e) {y? E (): _. Push (e)})), u = document.createElement (« script »), g = document.createDocumentFragment (), p = document.getElementsByTagName (« head ») [0], u.src = « https://z.moatads.com/voxprebidheader841653991752/moatheader.js », g.appendChild (u), p.insertBefore ( g, p. firstChild), o = function (e) {var t, a, o = e.data, n = []; return o.loaded? e: (o.loaded =! 0, t = null, (t = o. Sizes? C.defineSlot (o.name, o.sizes, o.id) .addService (c.pubads ()): c.defineOutOfPageSlot (o.name, o.id) .addService (c.pubads ())) .setTargeting (« adid », o.id), b.hasOwnProperty (« utm_campaign ») &&t.setTargeting (« utmcamp », b.utm_campaign), a = m.getAdCount (o.label), t.se tTargeting ( » label « , o.label » _ « o.site » – « a), c.display (o.id), c.pubads (). addEventListener ( » slotOnload « , function () {i.NYM. analytics.firstAdLoadTime || (i.NYM.analytics.firstAdLoadTime = i.performance.now (), i.NYM.analytics.firstAdLoadLabel = e.data.label)}), n = T (o), Promise.all (v). then (function () {n? window.apstag&&window.apstag.cleared? window.apstag.fetchBids ({slots: [n], timeout: window.apstag.timeout}, function () {c.cmd.push (function ( ) {window.apstag.setDisplayBids (), c.pubads (). refresh ([t], {changeCorrelator:! 1})})}): S&&c.pubads (). refresh ([t], {changeCorrelator :! 1}): c.pubads (). Refresh ([t], {changeCorrel ator:! 1})}), e.slot = t, e)}, n = function (e) {var a, i, o, n = t (), s = e.getAttribute (« data-name » ), r = e.getAttribute (« data-sizes »), d = e.getAttribute (« data-label »), c = e.getAttribute (« data-site »); n = e.id, r&&r.length ? (r = r.split (« , »), a = [], _ map (r, function (e) {e = e .split (« x »), i = parseInt (e [0]), o = parseInt (e [1]), a.push ([i, o])})) 🙁 e.classList.add (« oop »), a =! 1), this.data = {id: n, na me: s, sizes: a, loaded:! 1, label: d, site: c}, h [n] = this}, r = function (e) {c.cmd.push (function () {var t = o (e); h [e.data.id] = t})}, s = function (e) {var t = []; e.slot? (t = T (e)) &&window.apstag&&window.apstag. cleared&&window.apstag.fetchBids ({slots: [t], timeout: window.apstag.timeout}, function () {c.cmd.push (function () {window.apstag.setDisplayBids (), c.pubads (). refresh ([e.slot], {changeCorrelator:! 1})})}): e&&r (e)}, c.cmd.push (function () {var e, t, o, n = page.getMeta ( » article: tag « ), s = page.getMeta ( » author « ), r = i.location.href, d = (e = a.head.querySelector (« . head-gtm « ), t = a.body. querySelector (« . gtm »), e&& « top » === e.getAttribute (« data-gtm »)? « gtmtop »: t&& « bottom » === t.getAttribute (« data-gtm »)? « gtmbottom « : » « ); o = [], _ forEach ([n, s, d], function (e) {_ forEach (e.split (« , « ), function (e) {(e = e.trim () .toLowerCase (). replace (/ s / g, « -« ). replace (/ ‘| ‘ / g, «  »)). length&&o.push (e)})}), c.pubads () .setTargeting (« kw », o), c.pub ads (). setTargeting (« entry_group », o), r = r.slice (r.lastIndexOf (« / ») 1), c.pubads (). setTargeting (« pn », r), c.companionAds () .setRefreshUnfilledSlots (! 0), c.pubads (). enableAsyncRendering (), c.enableServices ()}), this.load = r, this .create = function (e) {return new n (e)}, this. refresh = function (e) {var t; _isString (e)? (t = this.getById (e), s (t)): s (e)}, this.remove = function (e) {var t = e .data.id; a.getElementById (t) .innerHTML = «  »}, this.getAdCount = function (e) {var t, a = 0, i = Object.keys (h); return _each (i, function ( i) {(t = h [i]). data.loaded&&t.data.label === e&&a}), a}, this.getById = function (e) {return h [e]}, d = _debounce (function () {var e = {TopLeaderboard: 1, RightColTopMPU: 2, outOfPage: 99, « homepageTakeover / TopLeaderboard »: 1}, t = _sortBy (f, function (t) {return e [t.data.label] || 10}); _ forEach (t, function (e) {return e.data.sizes? R (e): i.setTimeout (function () {r (e)}, 2e3)}), S&&window.PQ.cmd. push (() => {try {window.PQ.loadSignals ([« ids », « bsc », « vlp »], q)} catch (e) {q (), console.error (`There has bee n an error loading the double verify signals: $ {e} `)}}), f = []}, 10), this.addToPageLoadQueue = function (e) {f.push (e), d ()}) ; function T (e) {var t, a = e.sizes; return a = _intersectionWith (a, [[970.250], [970.90], [728.90], [300,600], [300,250], [320,100 ], [320,50]], _ isEqual), e.sizes&&e.sizes.length&& (t = {slotID: e.id, sizes: a, slotName: e.label}), t} function q () {y =! 0, _forEach (_, function ( e) {e ()})}}]);
}, {« 63 »: 63, « 70 »: 70, « 73 »: 73, « 121 »: 121, « 145 »: 145, « 158 »: 158, « 205 »: 205, « 212 »: 212 , « 322 »: 322, « 325 »: 325}];
window.modules [« cid.legacy »] = [function (require, module, exports) {« use strict »; DS.service (« $ cid », function () {var r = Math.floor (100 * Math. random ()); return function () {return « cid- » r}});
}, {}];
window.modules [« client.legacy »] = [function (require, module, exports) {« use strict »; require (« cid.legacy »), require (« ads.legacy »), require (« facebook.legacy « ), require ( » aaa-module-mounting.legacy « );
}, {« cid.legacy »: « cid.legacy », « ads.legacy »: « ads.legacy », « aaa-module-mounting.legacy »: « aaa-module-mounting.legacy », « facebook. Legacy « : » facebook.legacy « }];
window.modules [« facebook.legacy »] = [function (require, module, exports) {« use strict »; DS.service (« facebook », [function () {this.fb = function (i) {window. FB&&window.FB [i] .apply (this, Array.prototype.slice.call (arguments, 1))}}]);
}, {}];
require = (function e (t, n, r) {function s (o, u) {if (! n [o]) {if (! t [o]) {var a = typeof require == « function » &&require ; if (! u&&a) return a (o,! 0); if (i) return i (o,! 0); var f = new Error (« Cannot find module ‘ » o « ‘ »); throw f.code = « MODULE_NOT_FOUND », f} var l = n [o] = {exports: {}}; t [o] [0] .call (l.exports, function (e) {var n = t [o] [1 ] [e]; return s (n? n: e)}, l, l.exports, e, t, n, r)} return n [o] .exports} var i = typeof require == « function » &&require ; for (var o = 0; o key type === ‘string’ && key.match (/ . legacy $ /)). forEach (key => window.require (key));
}

Function tryToMount (fn, el, name) {
To attempt {
fn (el); // initialize controller
} catch (e) {
const elementTag = el.outerHTML.slice (0, el.outerHTML.indexOf (el.innerHTML));
console.error (`Error initializing controller for » $ {name} « on » $ {elementTag} « `, e);
}
}
/ **
* mount client.js component controller
* /

Function mountComponentModules () {
Object.keys (window.modules) .filter (key => typeof key === ‘string’ && key.match (/ . Client $ /)). ForEach (key => {
let controllerFn = window.require (key);

if (control type Fn === ‘function’) {
const name = key.replace (‘. client’,  »),
instancesSelector = `[data-uri * = » _ components / $ {name} / « ]`,
defaultSelector = `[data-uri $ = » _ components $ {name} « ]`,
Instances = document.querySelectorAll (instancesSelector),
defaults = document.querySelectorAll (defaultSelector);

for (let el of instances) {
tryToMount (controllerFn, el, name);
}

for (let el from defaults) {
tryToMount (controllerFn, el, name);
}
}
});
} // Make sure there is a `window.process.env.NODE_ENV` available in the client for all dependencies,
// Services or components that might require it
// Note: The value «  is exchanged for the actual environment variable in /lib/cmd/compile/scripts.js

Window.process = window.process || {};
window.process.env = window.process.env || {};

if (! window.process.env.NODE_ENV) {
window.process.env.NODE_ENV =  »;
} // Note: Legacy controllers that need legacy services (e.g. Dollar-Slice) must
// wait for DOMContentLoaded to initialize itself, since the files themselves have to be mounted first

mountLegacyServices ();
mountComponentModules ();
//]]

Keywords:

Air pollution,Wildfire,Air quality index,Air pollution, Wildfire, Air quality index,,,bad air, air quality, wildfires, smoke, climate, the haze,

Donnez votre avis et abonnez-vous pour plus d’infos

[gs-fb-comments]

[comment]

[supsystic-newsletter-form id=4]

Vidéo du jour: