@financial-times/cmp-client 2.0.4-alpha → 2.0.5-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/client.d.ts +3 -63
  2. package/dist/client.d.ts.map +1 -0
  3. package/dist/consent-ready/index.d.ts +5 -0
  4. package/dist/consent-ready/index.d.ts.map +1 -0
  5. package/dist/consent-ready/utils/__fixtures__/strings.d.ts +9 -0
  6. package/dist/consent-ready/utils/__fixtures__/strings.d.ts.map +1 -0
  7. package/dist/consent-ready/utils/__tests__/check-consent.test.d.ts +2 -0
  8. package/dist/consent-ready/utils/__tests__/check-consent.test.d.ts.map +1 -0
  9. package/dist/consent-ready/utils/__tests__/get-parsed-consent.test.d.ts +2 -0
  10. package/dist/consent-ready/utils/__tests__/get-parsed-consent.test.d.ts.map +1 -0
  11. package/dist/consent-ready/utils/__tests__/validators.test.d.ts +2 -0
  12. package/dist/consent-ready/utils/__tests__/validators.test.d.ts.map +1 -0
  13. package/dist/consent-ready/utils/get-consent-payload.d.ts +18 -0
  14. package/dist/consent-ready/utils/get-consent-payload.d.ts.map +1 -0
  15. package/dist/consent-ready/utils/get-parsed-consent.d.ts +14 -0
  16. package/dist/consent-ready/utils/get-parsed-consent.d.ts.map +1 -0
  17. package/dist/consent-ready/utils/has-consent-changed.d.ts +3 -0
  18. package/dist/consent-ready/utils/has-consent-changed.d.ts.map +1 -0
  19. package/dist/consent-ready/utils/validators.d.ts +16 -0
  20. package/dist/consent-ready/utils/validators.d.ts.map +1 -0
  21. package/dist/html/__tests__/cmp-footer-links.test.d.ts +2 -0
  22. package/dist/html/__tests__/cmp-footer-links.test.d.ts.map +1 -0
  23. package/dist/html/cmp-footer-link.d.ts +8 -0
  24. package/dist/html/cmp-footer-link.d.ts.map +1 -0
  25. package/dist/html/cmp-scripts.d.ts +16 -0
  26. package/dist/html/cmp-scripts.d.ts.map +1 -0
  27. package/dist/{client.cjs → index.cjs} +409 -158
  28. package/dist/index.d.ts +6 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/{client.js → index.js} +408 -157
  31. package/dist/lib/constants.d.ts +13 -0
  32. package/dist/lib/constants.d.ts.map +1 -0
  33. package/dist/{debug.d.ts → lib/debug.d.ts} +12 -13
  34. package/dist/lib/debug.d.ts.map +1 -0
  35. package/dist/{properties.d.ts → lib/properties.d.ts} +17 -19
  36. package/dist/lib/properties.d.ts.map +1 -0
  37. package/dist/utils/dom.d.ts +3 -0
  38. package/dist/utils/dom.d.ts.map +1 -0
  39. package/package.json +20 -30
  40. package/typings/globals.d.ts +20 -0
  41. package/typings/modules.d.ts +1 -0
  42. package/typings/types.d.ts +88 -0
  43. package/dist/debug.cjs +0 -32
  44. package/dist/debug.js +0 -32
  45. package/dist/properties.cjs +0 -21
  46. package/dist/properties.js +0 -21
@@ -1,6 +1,12 @@
1
1
  "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => {
5
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
+ return value;
7
+ };
8
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
2
9
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const properties = require("./properties.cjs");
4
10
  const request = (url, { credentials = "omit" } = {}) => {
5
11
  return fetch(`https://session-next.ft.com${url}`, {
6
12
  credentials,
@@ -71,10 +77,68 @@ const getUuid = () => {
71
77
  }
72
78
  return requests.uuid;
73
79
  };
80
+ const SOURCEPOINT_CONSENT_SOURCE = "sourcepoint-cmp";
81
+ const SOURCEPOINT_FOW_SCOPE = "FTPINK";
82
+ const CONSENT_COOKIE_NAME = "FTConsent";
83
+ const SOURCEPOINT_FOW_ID = "sourcepointCmp/VngD.XycZut.595cp9fWdp5XYP9vlFvk";
84
+ const FT_COOKIE_DOMAIN = ".ft.com";
85
+ const FT_CONSENT_PROXY_HOST = "https://consent.ft.com";
86
+ const legislation = {
87
+ CCPA: "ccpa",
88
+ GDPR: "gdpr"
89
+ };
90
+ const iabCustomCategories = {
91
+ permutiveAds: {
92
+ purposes: [2, 4, 8, 9],
93
+ iabVendors: [361],
94
+ customVendors: [],
95
+ specialFeatures: []
96
+ },
97
+ demographicAds: {
98
+ purposes: [3, 4, 7, 9, 10],
99
+ iabVendors: [],
100
+ customVendors: [],
101
+ specialFeatures: []
102
+ }
103
+ };
104
+ const defaults = {
105
+ joinHref: true,
106
+ gdpr: {},
107
+ ccpa: {}
108
+ };
109
+ const FT_DOTCOM_LOCAL = {
110
+ ...defaults,
111
+ accountId: 1906,
112
+ baseEndpoint: "https://cdn.privacy-mgmt.com",
113
+ propertyHref: "https://local.ft.com"
114
+ };
115
+ const FT_DOTCOM_PROD = {
116
+ ...defaults,
117
+ accountId: 1906,
118
+ baseEndpoint: "https://cdn.privacy-mgmt.com",
119
+ propertyId: 31642
120
+ };
121
+ const properties = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
122
+ __proto__: null,
123
+ FT_DOTCOM_LOCAL,
124
+ FT_DOTCOM_PROD
125
+ }, Symbol.toStringTag, { value: "Module" }));
126
+ function createContentScript(content) {
127
+ const s = document.createElement("script");
128
+ s.innerHTML = content;
129
+ return s;
130
+ }
131
+ function createSourceScript(src) {
132
+ const s = document.createElement("script");
133
+ s.src = src;
134
+ return s;
135
+ }
74
136
  function encodeConfig(obj) {
75
137
  let str = "";
138
+ if (!obj)
139
+ return str;
76
140
  for (const [key, val] of Object.entries(obj)) {
77
- switch (typeof obj[key]) {
141
+ switch (typeof val) {
78
142
  case "function":
79
143
  str += `${key}:${val.toString().replace(/"/g, "'").replace(/\s/g, "")},`;
80
144
  break;
@@ -102,13 +166,42 @@ const scriptContent = {
102
166
  tcfStub: `"use strict";function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(){var t=function(){var t,e,o=[],n=window,r=n;for(;r;){try{if(r.frames.__tcfapiLocator){t=r;break}}catch(t){}if(r===n.top)break;r=r.parent}t||(!function t(){var e=n.document,o=!!n.frames.__tcfapiLocator;if(!o)if(e.body){var r=e.createElement("iframe");r.style.cssText="display:none",r.name="__tcfapiLocator",e.body.appendChild(r)}else setTimeout(t,5);return!o}(),n.__tcfapi=function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];if(!n.length)return o;"setGdprApplies"===n[0]?n.length>3&&2===parseInt(n[1],10)&&"boolean"==typeof n[3]&&(e=n[3],"function"==typeof n[2]&&n[2]("set",!0)):"ping"===n[0]?"function"==typeof n[2]&&n[2]({gdprApplies:e,cmpLoaded:!1,cmpStatus:"stub"}):o.push(n)},n.addEventListener("message",(function(t){var e="string"==typeof t.data,o={};if(e)try{o=JSON.parse(t.data)}catch(t){}else o=t.data;var n="object"===_typeof(o)&&null!==o?o.__tcfapiCall:null;n&&window.__tcfapi(n.command,n.version,(function(o,r){var a={__tcfapiReturn:{returnValue:o,success:r,callId:n.callId}};t&&t.source&&t.source.postMessage&&t.source.postMessage(e?JSON.stringify(a):a,"*")}),n.parameter)}),!1))};"undefined"!=typeof module?module.exports=t:t()}();`,
103
167
  uspStub: `"use strict";(function () { var e = false; var c = window; var t = document; function r() { if (!c.frames["__uspapiLocator"]) { if (t.body) { var a = t.body; var e = t.createElement("iframe"); e.style.cssText = "display:none"; e.name = "__uspapiLocator"; a.appendChild(e) } else { setTimeout(r, 5) } } } r(); function p() { var a = arguments; __uspapi.a = __uspapi.a || []; if (!a.length) { return __uspapi.a } else if (a[0] === "ping") { a[2]({ gdprAppliesGlobally: e, cmpLoaded: false }, true) } else { __uspapi.a.push([].slice.apply(a)) } } function l(t) { var r = typeof t.data === "string"; try { var a = r ? JSON.parse(t.data) : t.data; if (a.__cmpCall) { var n = a.__cmpCall; c.__uspapi(n.command, n.parameter, function (a, e) { var c = { __cmpReturn: { returnValue: a, success: e, callId: n.callId } }; t.source.postMessage(r ? JSON.stringify(c) : c, "*") }) } } catch (a) { } } if (typeof __uspapi !== "function") { c.__uspapi = p; __uspapi.msgHandler = l; c.addEventListener("message", l, false) } })();`
104
168
  };
105
- var __defProp = Object.defineProperty;
106
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
107
- var __publicField = (obj, key, value) => {
108
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
109
- return value;
110
- };
111
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
169
+ function getCmpScripts(config) {
170
+ const fragment = document.createDocumentFragment();
171
+ fragment.appendChild(createContentScript(scriptContent.tcfStub));
172
+ fragment.appendChild(createContentScript(scriptContent.uspStub));
173
+ fragment.appendChild(createContentScript(scriptContent.getSPConfig(config)));
174
+ fragment.appendChild(createSourceScript(scriptSources.cmpFrames));
175
+ return fragment;
176
+ }
177
+ function getConsentPayload(parsedConsent, { shouldUpdateConsentStore, formOfWordsId, cookieDomain }) {
178
+ const categoryNames = Object.keys(parsedConsent);
179
+ const data = categoryNames.reduce(
180
+ (payload, categoryName) => {
181
+ payload[categoryName] = {
182
+ onsite: {
183
+ status: parsedConsent[categoryName],
184
+ lbi: false,
185
+ source: SOURCEPOINT_CONSENT_SOURCE,
186
+ fow: formOfWordsId
187
+ }
188
+ };
189
+ return payload;
190
+ },
191
+ {}
192
+ );
193
+ if (!shouldUpdateConsentStore) {
194
+ return { data };
195
+ } else {
196
+ return {
197
+ setConsentCookie: true,
198
+ formOfWordsId,
199
+ consentSource: SOURCEPOINT_CONSENT_SOURCE,
200
+ cookieDomain,
201
+ data
202
+ };
203
+ }
204
+ }
112
205
  class DecodingError extends Error {
113
206
  /**
114
207
  * constructor - constructs an DecodingError
@@ -197,6 +290,10 @@ class Base64Url {
197
290
  return result;
198
291
  }
199
292
  }
293
+ /**
294
+ * Base 64 URL character set. Different from standard Base64 char set
295
+ * in that '+' and '/' are replaced with '-' and '_'.
296
+ */
200
297
  __publicField(Base64Url, "DICT", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
201
298
  __publicField(Base64Url, "REVERSE_DICT", /* @__PURE__ */ new Map([
202
299
  ["A", 0],
@@ -264,26 +361,29 @@ __publicField(Base64Url, "REVERSE_DICT", /* @__PURE__ */ new Map([
264
361
  ["-", 62],
265
362
  ["_", 63]
266
363
  ]));
364
+ /**
365
+ * log2(64) = 6
366
+ */
267
367
  __publicField(Base64Url, "BASIS", 6);
268
368
  __publicField(Base64Url, "LCM", 24);
269
- const _ConsentLanguages = class _ConsentLanguages2 {
369
+ const _ConsentLanguages = class _ConsentLanguages {
270
370
  has(key) {
271
- return _ConsentLanguages2.langSet.has(key);
371
+ return _ConsentLanguages.langSet.has(key);
272
372
  }
273
373
  parseLanguage(lang) {
274
374
  lang = lang.toUpperCase();
275
375
  const primaryLanguage = lang.split("-")[0];
276
376
  if (lang.length >= 2 && primaryLanguage.length == 2) {
277
- if (_ConsentLanguages2.langSet.has(lang)) {
377
+ if (_ConsentLanguages.langSet.has(lang)) {
278
378
  return lang;
279
- } else if (_ConsentLanguages2.langSet.has(primaryLanguage)) {
379
+ } else if (_ConsentLanguages.langSet.has(primaryLanguage)) {
280
380
  return primaryLanguage;
281
381
  }
282
382
  const fullPrimaryLang = primaryLanguage + "-" + primaryLanguage;
283
- if (_ConsentLanguages2.langSet.has(fullPrimaryLang)) {
383
+ if (_ConsentLanguages.langSet.has(fullPrimaryLang)) {
284
384
  return fullPrimaryLang;
285
385
  }
286
- for (const supportedLang of _ConsentLanguages2.langSet) {
386
+ for (const supportedLang of _ConsentLanguages.langSet) {
287
387
  if (supportedLang.indexOf(lang) !== -1 || supportedLang.indexOf(primaryLanguage) !== -1) {
288
388
  return supportedLang;
289
389
  }
@@ -292,10 +392,10 @@ const _ConsentLanguages = class _ConsentLanguages2 {
292
392
  throw new Error(`unsupported language ${lang}`);
293
393
  }
294
394
  forEach(callback) {
295
- _ConsentLanguages2.langSet.forEach(callback);
395
+ _ConsentLanguages.langSet.forEach(callback);
296
396
  }
297
397
  get size() {
298
- return _ConsentLanguages2.langSet.size;
398
+ return _ConsentLanguages.langSet.size;
299
399
  }
300
400
  };
301
401
  __publicField(_ConsentLanguages, "langSet", /* @__PURE__ */ new Set([
@@ -426,7 +526,7 @@ var RestrictionType;
426
526
  RestrictionType2[RestrictionType2["REQUIRE_CONSENT"] = 1] = "REQUIRE_CONSENT";
427
527
  RestrictionType2[RestrictionType2["REQUIRE_LI"] = 2] = "REQUIRE_LI";
428
528
  })(RestrictionType || (RestrictionType = {}));
429
- const _PurposeRestriction = class _PurposeRestriction2 extends Cloneable {
529
+ const _PurposeRestriction = class _PurposeRestriction extends Cloneable {
430
530
  /**
431
531
  * constructor
432
532
  *
@@ -449,7 +549,7 @@ const _PurposeRestriction = class _PurposeRestriction2 extends Cloneable {
449
549
  }
450
550
  static unHash(hash) {
451
551
  const splitUp = hash.split(this.hashSeparator);
452
- const purpRestriction = new _PurposeRestriction2();
552
+ const purpRestriction = new _PurposeRestriction();
453
553
  if (splitUp.length !== 2) {
454
554
  throw new TCModelError("hash", hash);
455
555
  }
@@ -461,7 +561,7 @@ const _PurposeRestriction = class _PurposeRestriction2 extends Cloneable {
461
561
  if (!this.isValid()) {
462
562
  throw new Error("cannot hash invalid PurposeRestriction");
463
563
  }
464
- return `${this.purposeId}${_PurposeRestriction2.hashSeparator}${this.restrictionType}`;
564
+ return `${this.purposeId}${_PurposeRestriction.hashSeparator}${this.restrictionType}`;
465
565
  }
466
566
  /**
467
567
  * @return {number} The purpose Id associated with a publisher
@@ -491,7 +591,15 @@ let PurposeRestriction = _PurposeRestriction;
491
591
  class PurposeRestrictionVector extends Cloneable {
492
592
  constructor() {
493
593
  super(...arguments);
594
+ /**
595
+ * if this originatd from an encoded string we'll need a place to store the
596
+ * bit length; it can be set and got from here
597
+ */
494
598
  __publicField(this, "bitLength", 0);
599
+ /**
600
+ * a map indexed by a string which will be a 'hash' of the purpose and
601
+ * restriction type.
602
+ */
495
603
  __publicField(this, "map", /* @__PURE__ */ new Map());
496
604
  __publicField(this, "gvl_");
497
605
  }
@@ -728,6 +836,12 @@ var Segment;
728
836
  })(Segment || (Segment = {}));
729
837
  class SegmentIDs {
730
838
  }
839
+ /**
840
+ * 0 = default - reserved for core string (does not need to be present in the core string)
841
+ * 1 = OOB vendors disclosed
842
+ * 2 = OOB vendors allowed
843
+ * 3 = PublisherTC
844
+ */
731
845
  __publicField(SegmentIDs, "ID_TO_KEY", [
732
846
  Segment.CORE,
733
847
  Segment.VENDORS_DISCLOSED,
@@ -743,6 +857,10 @@ __publicField(SegmentIDs, "KEY_TO_ID", {
743
857
  class Vector extends Cloneable {
744
858
  constructor() {
745
859
  super(...arguments);
860
+ /**
861
+ * if this originatd from an encoded string we'll need a place to store the
862
+ * bit length; it can be set and got from here
863
+ */
746
864
  __publicField(this, "bitLength", 0);
747
865
  __publicField(this, "maxId_", 0);
748
866
  __publicField(this, "set_", /* @__PURE__ */ new Set());
@@ -1486,7 +1604,7 @@ class Json {
1486
1604
  return this.absCall(url, null, sendCookies, timeout);
1487
1605
  }
1488
1606
  }
1489
- const _GVL = class _GVL2 extends Cloneable {
1607
+ const _GVL = class _GVL extends Cloneable {
1490
1608
  /**
1491
1609
  * @param {VersionOrVendorList} [versionOrVendorList] - can be either a
1492
1610
  * [[VendorList]] object or a version number represented as a string or
@@ -1495,31 +1613,94 @@ const _GVL = class _GVL2 extends Cloneable {
1495
1613
  */
1496
1614
  constructor(versionOrVendorList) {
1497
1615
  super();
1616
+ /**
1617
+ * @param {Promise} resolved when this GVL object is populated with the data
1618
+ * or rejected if there is an error.
1619
+ */
1498
1620
  __publicField(this, "readyPromise");
1621
+ /**
1622
+ * @param {number} gvlSpecificationVersion - schema version for the GVL that is used
1623
+ */
1499
1624
  __publicField(this, "gvlSpecificationVersion");
1625
+ /**
1626
+ * @param {number} incremented with each published file change
1627
+ */
1500
1628
  __publicField(this, "vendorListVersion");
1629
+ /**
1630
+ * @param {number} tcfPolicyVersion - The TCF MO will increment this value
1631
+ * whenever a GVL change (such as adding a new Purpose or Feature or a change
1632
+ * in Purpose wording) legally invalidates existing TC Strings and requires
1633
+ * CMPs to re-establish transparency and consent from users. If the policy
1634
+ * version number in the latest GVL is different from the value in your TC
1635
+ * String, then you need to re-establish transparency and consent for that
1636
+ * user. A version 1 format TC String is considered to have a version value
1637
+ * of 1.
1638
+ */
1501
1639
  __publicField(this, "tcfPolicyVersion");
1640
+ /**
1641
+ * @param {string | Date} lastUpdated - the date in which the vendor list
1642
+ * json file was last updated.
1643
+ */
1502
1644
  __publicField(this, "lastUpdated");
1645
+ /**
1646
+ * @param {IntMap<Purpose>} a collection of [[Purpose]]s
1647
+ */
1503
1648
  __publicField(this, "purposes");
1649
+ /**
1650
+ * @param {IntMap<Purpose>} a collection of [[Purpose]]s
1651
+ */
1504
1652
  __publicField(this, "specialPurposes");
1653
+ /**
1654
+ * @param {IntMap<Feature>} a collection of [[Feature]]s
1655
+ */
1505
1656
  __publicField(this, "features");
1657
+ /**
1658
+ * @param {IntMap<Feature>} a collection of [[Feature]]s
1659
+ */
1506
1660
  __publicField(this, "specialFeatures");
1661
+ /**
1662
+ * @param {boolean} internal reference of when the GVL is ready to be used
1663
+ */
1507
1664
  __publicField(this, "isReady_", false);
1665
+ /**
1666
+ * @param {IntMap<Vendor>} a collection of [[Vendor]]s
1667
+ */
1508
1668
  __publicField(this, "vendors_");
1509
1669
  __publicField(this, "vendorIds");
1670
+ /**
1671
+ * @param {IntMap<Vendor>} a collection of [[Vendor]]. Used as a backup if a whitelist is sets
1672
+ */
1510
1673
  __publicField(this, "fullVendorList");
1674
+ /**
1675
+ * @param {ByPurposeVendorMap} vendors by purpose
1676
+ */
1511
1677
  __publicField(this, "byPurposeVendorMap");
1678
+ /**
1679
+ * @param {IDSetMap} vendors by special purpose
1680
+ */
1512
1681
  __publicField(this, "bySpecialPurposeVendorMap");
1682
+ /**
1683
+ * @param {IDSetMap} vendors by feature
1684
+ */
1513
1685
  __publicField(this, "byFeatureVendorMap");
1686
+ /**
1687
+ * @param {IDSetMap} vendors by special feature
1688
+ */
1514
1689
  __publicField(this, "bySpecialFeatureVendorMap");
1690
+ /**
1691
+ * @param {IntMap<Stack>} a collection of [[Stack]]s
1692
+ */
1515
1693
  __publicField(this, "stacks");
1694
+ /**
1695
+ * @param {IntMap<DataCategory>} a collection of [[DataCategory]]s
1696
+ */
1516
1697
  __publicField(this, "dataCategories");
1517
1698
  __publicField(this, "lang_");
1518
1699
  __publicField(this, "cacheLang_");
1519
1700
  __publicField(this, "isLatest", false);
1520
- let url = _GVL2.baseUrl;
1521
- this.lang_ = _GVL2.DEFAULT_LANGUAGE;
1522
- this.cacheLang_ = _GVL2.DEFAULT_LANGUAGE;
1701
+ let url = _GVL.baseUrl;
1702
+ this.lang_ = _GVL.DEFAULT_LANGUAGE;
1703
+ this.cacheLang_ = _GVL.DEFAULT_LANGUAGE;
1523
1704
  if (this.isVendorList(versionOrVendorList)) {
1524
1705
  this.populate(versionOrVendorList);
1525
1706
  this.readyPromise = Promise.resolve();
@@ -1529,20 +1710,20 @@ const _GVL = class _GVL2 extends Cloneable {
1529
1710
  }
1530
1711
  if (versionOrVendorList > 0) {
1531
1712
  const version = versionOrVendorList;
1532
- if (_GVL2.CACHE.has(version)) {
1533
- this.populate(_GVL2.CACHE.get(version));
1713
+ if (_GVL.CACHE.has(version)) {
1714
+ this.populate(_GVL.CACHE.get(version));
1534
1715
  this.readyPromise = Promise.resolve();
1535
1716
  } else {
1536
- url += _GVL2.versionedFilename.replace("[VERSION]", String(version));
1717
+ url += _GVL.versionedFilename.replace("[VERSION]", String(version));
1537
1718
  this.readyPromise = this.fetchJson(url);
1538
1719
  }
1539
1720
  } else {
1540
- if (_GVL2.CACHE.has(_GVL2.LATEST_CACHE_KEY)) {
1541
- this.populate(_GVL2.CACHE.get(_GVL2.LATEST_CACHE_KEY));
1721
+ if (_GVL.CACHE.has(_GVL.LATEST_CACHE_KEY)) {
1722
+ this.populate(_GVL.CACHE.get(_GVL.LATEST_CACHE_KEY));
1542
1723
  this.readyPromise = Promise.resolve();
1543
1724
  } else {
1544
1725
  this.isLatest = true;
1545
- this.readyPromise = this.fetchJson(url + _GVL2.latestFilename);
1726
+ this.readyPromise = this.fetchJson(url + _GVL.latestFilename);
1546
1727
  }
1547
1728
  }
1548
1729
  }
@@ -1599,11 +1780,11 @@ const _GVL = class _GVL2 extends Cloneable {
1599
1780
  */
1600
1781
  static emptyLanguageCache(lang) {
1601
1782
  let result = false;
1602
- if (lang == null && _GVL2.LANGUAGE_CACHE.size > 0) {
1603
- _GVL2.LANGUAGE_CACHE = /* @__PURE__ */ new Map();
1783
+ if (lang == null && _GVL.LANGUAGE_CACHE.size > 0) {
1784
+ _GVL.LANGUAGE_CACHE = /* @__PURE__ */ new Map();
1604
1785
  result = true;
1605
1786
  } else if (typeof lang === "string" && this.consentLanguages.has(lang.toUpperCase())) {
1606
- _GVL2.LANGUAGE_CACHE.delete(lang.toUpperCase());
1787
+ _GVL.LANGUAGE_CACHE.delete(lang.toUpperCase());
1607
1788
  result = true;
1608
1789
  }
1609
1790
  return result;
@@ -1618,17 +1799,17 @@ const _GVL = class _GVL2 extends Cloneable {
1618
1799
  static emptyCache(vendorListVersion) {
1619
1800
  let retr = false;
1620
1801
  if (Number.isInteger(vendorListVersion) && vendorListVersion >= 0) {
1621
- _GVL2.CACHE.delete(vendorListVersion);
1802
+ _GVL.CACHE.delete(vendorListVersion);
1622
1803
  retr = true;
1623
1804
  } else if (vendorListVersion === void 0) {
1624
- _GVL2.CACHE = /* @__PURE__ */ new Map();
1805
+ _GVL.CACHE = /* @__PURE__ */ new Map();
1625
1806
  retr = true;
1626
1807
  }
1627
1808
  return retr;
1628
1809
  }
1629
1810
  cacheLanguage() {
1630
- if (!_GVL2.LANGUAGE_CACHE.has(this.cacheLang_)) {
1631
- _GVL2.LANGUAGE_CACHE.set(this.cacheLang_, {
1811
+ if (!_GVL.LANGUAGE_CACHE.has(this.cacheLang_)) {
1812
+ _GVL.LANGUAGE_CACHE.set(this.cacheLang_, {
1632
1813
  purposes: this.purposes,
1633
1814
  specialPurposes: this.specialPurposes,
1634
1815
  features: this.features,
@@ -1678,25 +1859,25 @@ const _GVL = class _GVL2 extends Cloneable {
1678
1859
  async changeLanguage(lang) {
1679
1860
  let parsedLanguage = lang;
1680
1861
  try {
1681
- parsedLanguage = _GVL2.consentLanguages.parseLanguage(lang);
1862
+ parsedLanguage = _GVL.consentLanguages.parseLanguage(lang);
1682
1863
  } catch (e) {
1683
1864
  throw new GVLError("Error during parsing the language: " + e.message);
1684
1865
  }
1685
1866
  const cacheLang = lang.toUpperCase();
1686
- if (parsedLanguage.toLowerCase() === _GVL2.DEFAULT_LANGUAGE.toLowerCase() && !_GVL2.LANGUAGE_CACHE.has(cacheLang)) {
1867
+ if (parsedLanguage.toLowerCase() === _GVL.DEFAULT_LANGUAGE.toLowerCase() && !_GVL.LANGUAGE_CACHE.has(cacheLang)) {
1687
1868
  return;
1688
1869
  }
1689
1870
  if (parsedLanguage !== this.lang_) {
1690
1871
  this.lang_ = parsedLanguage;
1691
- if (_GVL2.LANGUAGE_CACHE.has(cacheLang)) {
1692
- const cached = _GVL2.LANGUAGE_CACHE.get(cacheLang);
1872
+ if (_GVL.LANGUAGE_CACHE.has(cacheLang)) {
1873
+ const cached = _GVL.LANGUAGE_CACHE.get(cacheLang);
1693
1874
  for (const prop in cached) {
1694
1875
  if (cached.hasOwnProperty(prop)) {
1695
1876
  this[prop] = cached[prop];
1696
1877
  }
1697
1878
  }
1698
1879
  } else {
1699
- const url = _GVL2.baseUrl + _GVL2.languageFilename.replace("[LANG]", this.lang_.toLowerCase());
1880
+ const url = _GVL.baseUrl + _GVL.languageFilename.replace("[LANG]", this.lang_.toLowerCase());
1700
1881
  try {
1701
1882
  await this.fetchJson(url);
1702
1883
  this.cacheLang_ = cacheLang;
@@ -1733,10 +1914,10 @@ const _GVL = class _GVL2 extends Cloneable {
1733
1914
  this.mapVendors();
1734
1915
  this.isReady_ = true;
1735
1916
  if (this.isLatest) {
1736
- _GVL2.CACHE.set(_GVL2.LATEST_CACHE_KEY, this.getJson());
1917
+ _GVL.CACHE.set(_GVL.LATEST_CACHE_KEY, this.getJson());
1737
1918
  }
1738
- if (!_GVL2.CACHE.has(this.vendorListVersion)) {
1739
- _GVL2.CACHE.set(this.vendorListVersion, this.getJson());
1919
+ if (!_GVL.CACHE.has(this.vendorListVersion)) {
1920
+ _GVL.CACHE.set(this.vendorListVersion, this.getJson());
1740
1921
  }
1741
1922
  }
1742
1923
  this.cacheLanguage();
@@ -1899,8 +2080,8 @@ const _GVL = class _GVL2 extends Cloneable {
1899
2080
  * @return {GVL}
1900
2081
  */
1901
2082
  clone() {
1902
- const result = new _GVL2(this.getJson());
1903
- if (this.lang_ !== _GVL2.DEFAULT_LANGUAGE) {
2083
+ const result = new _GVL(this.getJson());
2084
+ if (this.lang_ !== _GVL.DEFAULT_LANGUAGE) {
1904
2085
  result.changeLanguage(this.lang_);
1905
2086
  }
1906
2087
  return result;
@@ -1914,10 +2095,47 @@ __publicField(_GVL, "LANGUAGE_CACHE", /* @__PURE__ */ new Map());
1914
2095
  __publicField(_GVL, "CACHE", /* @__PURE__ */ new Map());
1915
2096
  __publicField(_GVL, "LATEST_CACHE_KEY", 0);
1916
2097
  __publicField(_GVL, "DEFAULT_LANGUAGE", "EN");
2098
+ /**
2099
+ * Set of available consent languages published by the IAB
2100
+ */
1917
2101
  __publicField(_GVL, "consentLanguages", new ConsentLanguages());
1918
2102
  __publicField(_GVL, "baseUrl_");
2103
+ /**
2104
+ * @static
2105
+ * @param {string} - the latest is assumed to be vendor-list.json because
2106
+ * that is what the iab uses, but it could be different... if you want
2107
+ */
1919
2108
  __publicField(_GVL, "latestFilename", "vendor-list.json");
2109
+ /**
2110
+ * @static
2111
+ * @param {string} - the versioned name is assumed to be
2112
+ * vendor-list-v[VERSION].json where [VERSION] will be replaced with the
2113
+ * specified version. But it could be different... if you want just make
2114
+ * sure to include the [VERSION] macro if you have a numbering scheme, it's a
2115
+ * simple string substitution.
2116
+ *
2117
+ * eg.
2118
+ * ```javascript
2119
+ * GVL.baseUrl = "http://www.mydomain.com/iabcmp/";
2120
+ * GVL.versionedFilename = "vendorlist?getVersion=[VERSION]";
2121
+ * ```
2122
+ */
1920
2123
  __publicField(_GVL, "versionedFilename", "archives/vendor-list-v[VERSION].json");
2124
+ /**
2125
+ * @param {string} - Translations of the names and descriptions for Purposes,
2126
+ * Special Purposes, Features, and Special Features to non-English languages
2127
+ * are contained in a file where attributes containing English content
2128
+ * (except vendor declaration information) are translated. The iab publishes
2129
+ * one following the scheme below where the LANG is the iso639-1 language
2130
+ * code. For a list of available translations
2131
+ * [please go here](https://register.consensu.org/Translation).
2132
+ *
2133
+ * eg.
2134
+ * ```javascript
2135
+ * GVL.baseUrl = "http://www.mydomain.com/iabcmp/";
2136
+ * GVL.languageFilename = "purposes?getPurposes=[LANG]";
2137
+ * ```
2138
+ */
1921
2139
  __publicField(_GVL, "languageFilename", "purposes-[LANG].json");
1922
2140
  let GVL = _GVL;
1923
2141
  class TCModel extends Cloneable {
@@ -1943,20 +2161,83 @@ class TCModel extends Cloneable {
1943
2161
  __publicField(this, "cmpVersion_", 0);
1944
2162
  __publicField(this, "vendorListVersion_", 0);
1945
2163
  __publicField(this, "numCustomPurposes_", 0);
2164
+ // Member Variable for GVL
1946
2165
  __publicField(this, "gvl_");
1947
2166
  __publicField(this, "created");
1948
2167
  __publicField(this, "lastUpdated");
2168
+ /**
2169
+ * The TCF designates certain Features as special, that is, a CMP must afford
2170
+ * the user a means to opt in to their use. These Special Features are
2171
+ * published and numbered in the GVL separately from normal Features.
2172
+ * Provides for up to 12 special features.
2173
+ */
1949
2174
  __publicField(this, "specialFeatureOptins", new Vector());
2175
+ /**
2176
+ * Renamed from `PurposesAllowed` in TCF v1.1
2177
+ * The user’s consent value for each Purpose established on the legal basis
2178
+ * of consent. Purposes are published in the Global Vendor List (see. [[GVL]]).
2179
+ */
1950
2180
  __publicField(this, "purposeConsents", new Vector());
2181
+ /**
2182
+ * The user’s permission for each Purpose established on the legal basis of
2183
+ * legitimate interest. If the user has exercised right-to-object for a
2184
+ * purpose.
2185
+ */
1951
2186
  __publicField(this, "purposeLegitimateInterests", new Vector());
2187
+ /**
2188
+ * The user’s consent value for each Purpose established on the legal basis
2189
+ * of consent, for the publisher. Purposes are published in the Global
2190
+ * Vendor List.
2191
+ */
1952
2192
  __publicField(this, "publisherConsents", new Vector());
2193
+ /**
2194
+ * The user’s permission for each Purpose established on the legal basis of
2195
+ * legitimate interest. If the user has exercised right-to-object for a
2196
+ * purpose.
2197
+ */
1953
2198
  __publicField(this, "publisherLegitimateInterests", new Vector());
2199
+ /**
2200
+ * The user’s consent value for each Purpose established on the legal basis
2201
+ * of consent, for the publisher. Purposes are published in the Global
2202
+ * Vendor List.
2203
+ */
1954
2204
  __publicField(this, "publisherCustomConsents", new Vector());
2205
+ /**
2206
+ * The user’s permission for each Purpose established on the legal basis of
2207
+ * legitimate interest. If the user has exercised right-to-object for a
2208
+ * purpose that is established in the publisher's custom purposes.
2209
+ */
1955
2210
  __publicField(this, "publisherCustomLegitimateInterests", new Vector());
2211
+ /**
2212
+ * set by a publisher if they wish to collect consent and LI Transparency for
2213
+ * purposes outside of the TCF
2214
+ */
1956
2215
  __publicField(this, "customPurposes");
2216
+ /**
2217
+ * Each [[Vendor]] is keyed by id. Their consent value is true if it is in
2218
+ * the Vector
2219
+ */
1957
2220
  __publicField(this, "vendorConsents", new Vector());
2221
+ /**
2222
+ * Each [[Vendor]] is keyed by id. Whether their Legitimate Interests
2223
+ * Disclosures have been established is stored as boolean.
2224
+ * see: [[Vector]]
2225
+ */
1958
2226
  __publicField(this, "vendorLegitimateInterests", new Vector());
2227
+ /**
2228
+ * The value included for disclosed vendors signals which vendors have been
2229
+ * disclosed to the user in the interface surfaced by the CMP. This section
2230
+ * content is required when writing a TC string to the global (consensu)
2231
+ * scope. When a CMP has read from and is updating a TC string from the
2232
+ * global consensu.org storage, the CMP MUST retain the existing disclosure
2233
+ * information and only add information for vendors that it has disclosed
2234
+ * that had not been disclosed by other CMPs in prior interactions with this
2235
+ * device/user agent.
2236
+ */
1959
2237
  __publicField(this, "vendorsDisclosed", new Vector());
2238
+ /**
2239
+ * Signals which vendors the publisher permits to use OOB legal bases.
2240
+ */
1960
2241
  __publicField(this, "vendorsAllowed", new Vector());
1961
2242
  __publicField(this, "publisherRestrictions", new PurposeRestrictionVector());
1962
2243
  if (gvl) {
@@ -2338,6 +2619,9 @@ class TCModel extends Cloneable {
2338
2619
  this.lastUpdated = utcDate;
2339
2620
  }
2340
2621
  }
2622
+ /**
2623
+ * Set of available consent languages published by the IAB
2624
+ */
2341
2625
  __publicField(TCModel, "consentLanguages", GVL.consentLanguages);
2342
2626
  class TCString {
2343
2627
  /**
@@ -2391,20 +2675,6 @@ class TCString {
2391
2675
  return tcModel;
2392
2676
  }
2393
2677
  }
2394
- const iabCustomCategories = {
2395
- permutiveAds: {
2396
- purposes: [2, 4, 8, 9],
2397
- iabVendors: [361],
2398
- customVendors: [],
2399
- specialFeatures: []
2400
- },
2401
- demographicAds: {
2402
- purposes: [3, 4, 7, 9, 10],
2403
- iabVendors: [],
2404
- customVendors: [],
2405
- specialFeatures: []
2406
- }
2407
- };
2408
2678
  function isValidGdprValue(val) {
2409
2679
  if (val === null) {
2410
2680
  return true;
@@ -2446,10 +2716,6 @@ function validateIabConsentCategory(categoryName) {
2446
2716
  throw new Error("Provided custom category identifier does not exist. Please check");
2447
2717
  }
2448
2718
  }
2449
- const legislation = {
2450
- CCPA: "ccpa",
2451
- GDPR: "gdpr"
2452
- };
2453
2719
  function checkConsentFor(categoryName, consentState) {
2454
2720
  validateIabConsentCategory(categoryName);
2455
2721
  validateRawConsentState(consentState);
@@ -2479,47 +2745,29 @@ function getParsedConsent(rawConsentState) {
2479
2745
  return parsedConsent;
2480
2746
  }, {});
2481
2747
  }
2482
- function updateFooterLinkCMP() {
2483
- const cookieLink = document.querySelector(
2484
- "[href='https://www.ft.com/preferences/manage-cookies']"
2748
+ function getConsentCookieValue() {
2749
+ const cookies = Object.fromEntries(
2750
+ document.cookie.split("; ").map((cookie) => cookie.split("="))
2751
+ );
2752
+ const encodedValue = cookies[CONSENT_COOKIE_NAME];
2753
+ if (!encodedValue)
2754
+ return {};
2755
+ const decodedValue = decodeURIComponent(encodedValue);
2756
+ return Object.fromEntries(
2757
+ decodedValue.split(",").map((consent) => {
2758
+ const [category, value] = consent.split(":");
2759
+ const booleanConsent = [category, value === "on" ? true : false];
2760
+ return booleanConsent;
2761
+ })
2485
2762
  );
2486
- if (cookieLink) {
2487
- cookieLink.href = "#";
2488
- cookieLink.setAttribute("onclick", "window._sp_.gdpr.loadPrivacyManagerModal(827767);");
2489
- cookieLink.dataset.cmpLink = "updated";
2490
- return true;
2491
- } else {
2492
- console.warn("CMP Footer Link was not found and not updated");
2493
- return false;
2494
- }
2495
2763
  }
2496
- const SOURCEPOINT_CONSENT_SOURCE = "sourcepoint-cmp";
2497
- const SOURCEPOINT_FOW_SCOPE = "FTPINK";
2498
- const CONSENT_COOKIE_NAME = "FTConsent";
2499
- function getPayload(parsedConsent, { shouldUpdateConsentStore, formOfWordsId, cookieDomain }) {
2500
- const categoryNames = Object.keys(parsedConsent);
2501
- const data = categoryNames.reduce((payload, categoryName) => {
2502
- payload[categoryName] = {
2503
- onsite: {
2504
- status: parsedConsent[categoryName],
2505
- lbi: false,
2506
- source: SOURCEPOINT_CONSENT_SOURCE,
2507
- fow: formOfWordsId
2508
- }
2509
- };
2510
- return payload;
2511
- }, {});
2512
- if (!shouldUpdateConsentStore) {
2513
- return { data };
2514
- } else {
2515
- return {
2516
- setConsentCookie: true,
2517
- formOfWordsId,
2518
- consentSource: SOURCEPOINT_CONSENT_SOURCE,
2519
- cookieDomain,
2520
- data
2521
- };
2522
- }
2764
+ function hasConsentChanged(parsedConsent) {
2765
+ const categories = Object.keys(parsedConsent);
2766
+ const previousConsent = getConsentCookieValue();
2767
+ return categories.some((category) => {
2768
+ const adaptedCategoryName = `${category.toLowerCase()}Onsite`;
2769
+ return parsedConsent[category] !== previousConsent[adaptedCategoryName];
2770
+ });
2523
2771
  }
2524
2772
  async function saveConsent(consentEndpoint, payload) {
2525
2773
  try {
@@ -2540,7 +2788,7 @@ async function saveConsent(consentEndpoint, payload) {
2540
2788
  }
2541
2789
  function consentReadyHandlerFn(props) {
2542
2790
  const { userId, consentProxyHost, cookieDomain, formOfWordsId, useConsentStore } = props;
2543
- return async (legislation2, _, consentString, consentMeta) => {
2791
+ return async function consentReadyHandler(legislation2, _, consentString, consentMeta) {
2544
2792
  const activeLegislation = consentMeta.applies ? legislation2 : "gdpr";
2545
2793
  if (activeLegislation !== legislation2 || !consentString) {
2546
2794
  return;
@@ -2559,7 +2807,7 @@ function consentReadyHandlerFn(props) {
2559
2807
  if (shouldUpdateConsentStore) {
2560
2808
  consentEndpoint = `${consentProxyHost}/__consent/consent-record/${SOURCEPOINT_FOW_SCOPE}/${userId}`;
2561
2809
  }
2562
- const payload = getPayload(parsedConsent, {
2810
+ const payload = getConsentPayload(parsedConsent, {
2563
2811
  formOfWordsId,
2564
2812
  cookieDomain,
2565
2813
  shouldUpdateConsentStore
@@ -2568,53 +2816,8 @@ function consentReadyHandlerFn(props) {
2568
2816
  document.dispatchEvent(new CustomEvent("oCookieMessage.act", { bubbles: true }));
2569
2817
  };
2570
2818
  }
2571
- function hasConsentChanged(parsedConsent) {
2572
- const categories = Object.keys(parsedConsent);
2573
- const previousConsent = getConsentCookieValue();
2574
- return categories.some((category) => {
2575
- const adaptedCategoryName = `${category.toLowerCase()}Onsite`;
2576
- return parsedConsent[category] !== previousConsent[adaptedCategoryName];
2577
- });
2578
- }
2579
- function getConsentCookieValue() {
2580
- const cookies = Object.fromEntries(
2581
- document.cookie.split("; ").map((cookie) => cookie.split("="))
2582
- );
2583
- const encodedValue = cookies[CONSENT_COOKIE_NAME];
2584
- if (!encodedValue)
2585
- return {};
2586
- const decodedValue = decodeURIComponent(encodedValue);
2587
- return Object.fromEntries(
2588
- decodedValue.split(",").map((consent) => {
2589
- const [category, value] = consent.split(":");
2590
- const booleanConsent = [category, value === "on" ? true : false];
2591
- return booleanConsent;
2592
- })
2593
- );
2594
- }
2595
- const SOURCEPOINT_FOW_ID = "sourcepointCmp/VngD.XycZut.595cp9fWdp5XYP9vlFvk";
2596
- const FT_COOKIE_DOMAIN = ".ft.com";
2597
- const FT_CONSENT_PROXY_HOST = "https://consent.ft.com";
2598
- function createContentScript(content) {
2599
- const s = document.createElement("script");
2600
- s.innerHTML = content;
2601
- return s;
2602
- }
2603
- function createSourceScript(src) {
2604
- const s = document.createElement("script");
2605
- s.src = src;
2606
- return s;
2607
- }
2608
- function getCmpScripts(config) {
2609
- const fragment = document.createDocumentFragment();
2610
- fragment.appendChild(createContentScript(scriptContent.tcfStub));
2611
- fragment.appendChild(createContentScript(scriptContent.uspStub));
2612
- fragment.appendChild(createContentScript(scriptContent.getSPConfig(config)));
2613
- fragment.appendChild(createSourceScript(scriptSources.cmpFrames));
2614
- return fragment;
2615
- }
2616
2819
  async function initSourcepointCmp({
2617
- propertyConfig = properties.FT_DOTCOM_PROD,
2820
+ propertyConfig = FT_DOTCOM_PROD,
2618
2821
  userId,
2619
2822
  useFTSession = true,
2620
2823
  consentProxyHost = FT_CONSENT_PROXY_HOST,
@@ -2622,11 +2825,10 @@ async function initSourcepointCmp({
2622
2825
  formOfWordsId = SOURCEPOINT_FOW_ID,
2623
2826
  useConsentStore = true
2624
2827
  }) {
2625
- let maybeUserId = userId;
2626
- if (!maybeUserId && useFTSession) {
2828
+ if (!userId && useFTSession) {
2627
2829
  try {
2628
2830
  const response = await getUuid();
2629
- maybeUserId = response == null ? void 0 : response.uuid;
2831
+ userId = response == null ? void 0 : response.uuid;
2630
2832
  } catch (error) {
2631
2833
  console.error(error);
2632
2834
  }
@@ -2634,8 +2836,8 @@ async function initSourcepointCmp({
2634
2836
  if (!(propertyConfig == null ? void 0 : propertyConfig.accountId)) {
2635
2837
  throw new Error("Please pass a valid property config");
2636
2838
  }
2637
- if (maybeUserId) {
2638
- propertyConfig.authId = maybeUserId;
2839
+ if (userId) {
2840
+ propertyConfig.authId = userId;
2639
2841
  }
2640
2842
  const scripts = getCmpScripts(propertyConfig);
2641
2843
  document.head.appendChild(scripts);
@@ -2643,7 +2845,7 @@ async function initSourcepointCmp({
2643
2845
  window._sp_.addEventListener(
2644
2846
  "onConsentReady",
2645
2847
  consentReadyHandlerFn({
2646
- userId: maybeUserId,
2848
+ userId,
2647
2849
  consentProxyHost,
2648
2850
  cookieDomain,
2649
2851
  formOfWordsId,
@@ -2652,6 +2854,55 @@ async function initSourcepointCmp({
2652
2854
  );
2653
2855
  });
2654
2856
  }
2857
+ const events = {
2858
+ onMessageChoiceSelect: (...args) => {
2859
+ console.log("[event] onMessageChoiceSelect", args);
2860
+ },
2861
+ onMessageReady: (...args) => {
2862
+ console.log("[event] onMessageReady", args);
2863
+ },
2864
+ onMessageChoiceError: (...args) => {
2865
+ console.log("[event] onMessageChoiceError", args);
2866
+ },
2867
+ onPrivacyManagerAction: (...args) => {
2868
+ console.log("[event] onPrivacyManagerAction", args);
2869
+ },
2870
+ onPMCancel: (...args) => {
2871
+ console.log("[event] onPMCancel", args);
2872
+ },
2873
+ onMessageReceiveData: (...args) => {
2874
+ console.log("[event] onMessageReceiveData", args);
2875
+ },
2876
+ onSPPMObjectReady: (...args) => {
2877
+ console.log("[event] onSPPMObjectReady", args);
2878
+ },
2879
+ onConsentReady: (...args) => {
2880
+ console.log("[event] onConsentReady", args);
2881
+ },
2882
+ onError: (...args) => {
2883
+ console.log("[event] onError", args);
2884
+ }
2885
+ };
2886
+ const debug = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2887
+ __proto__: null,
2888
+ events
2889
+ }, Symbol.toStringTag, { value: "Module" }));
2890
+ function updateFooterLinkCMP() {
2891
+ const cookieLink = document.querySelector(
2892
+ "[href='https://www.ft.com/preferences/manage-cookies']"
2893
+ );
2894
+ if (cookieLink) {
2895
+ cookieLink.href = "#";
2896
+ cookieLink.setAttribute("onclick", "window._sp_.gdpr.loadPrivacyManagerModal(827767);");
2897
+ cookieLink.dataset.cmpLink = "updated";
2898
+ return true;
2899
+ } else {
2900
+ console.warn("CMP Footer Link was not found and not updated");
2901
+ return false;
2902
+ }
2903
+ }
2904
+ exports.debug = debug;
2655
2905
  exports.getCmpScripts = getCmpScripts;
2656
2906
  exports.initSourcepointCmp = initSourcepointCmp;
2907
+ exports.properties = properties;
2657
2908
  exports.updateFooterLinkCMP = updateFooterLinkCMP;