prebid.js 7.12.0 → 7.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/.github/PULL_REQUEST_TEMPLATE.md +16 -10
  2. package/.github/codeql/codeql-config.yml +4 -0
  3. package/.github/workflows/codeql-analysis.yml +73 -0
  4. package/dist/33acrossBidAdapter.js +1 -1
  5. package/dist/acuityAdsBidAdapter.js +1 -0
  6. package/dist/adagioBidAdapter.js +1 -1
  7. package/dist/adbookpspBidAdapter.js +1 -1
  8. package/dist/adgenerationBidAdapter.js +1 -1
  9. package/dist/adrelevantisBidAdapter.js +1 -1
  10. package/dist/adtrgtmeBidAdapter.js +1 -1
  11. package/dist/adxcgBidAdapter.js +1 -1
  12. package/dist/adyoulikeBidAdapter.js +1 -1
  13. package/dist/ajaBidAdapter.js +1 -1
  14. package/dist/amxBidAdapter.js +1 -1
  15. package/dist/amxIdSystem.js +1 -1
  16. package/dist/aolBidAdapter.js +1 -1
  17. package/dist/appierAnalyticsAdapter.js +1 -1
  18. package/dist/appnexusBidAdapter.js +1 -1
  19. package/dist/asoBidAdapter.js +1 -1
  20. package/dist/audiencerunBidAdapter.js +1 -1
  21. package/dist/axonixBidAdapter.js +1 -1
  22. package/dist/beopBidAdapter.js +1 -1
  23. package/dist/bidglassBidAdapter.js +1 -1
  24. package/dist/big-richmediaBidAdapter.js +1 -1
  25. package/dist/bluebillywigBidAdapter.js +1 -1
  26. package/dist/brandmetricsRtdProvider.js +1 -1
  27. package/dist/bridgewellBidAdapter.js +1 -1
  28. package/dist/brightMountainMediaBidAdapter.js +1 -1
  29. package/dist/browsiRtdProvider.js +1 -1
  30. package/dist/cleanioRtdProvider.js +1 -1
  31. package/dist/concertBidAdapter.js +1 -1
  32. package/dist/connectadBidAdapter.js +1 -1
  33. package/dist/consentManagement.js +1 -1
  34. package/dist/consentManagementUsp.js +1 -1
  35. package/dist/consumableBidAdapter.js +1 -1
  36. package/dist/conversantBidAdapter.js +1 -1
  37. package/dist/craftBidAdapter.js +1 -1
  38. package/dist/criteoBidAdapter.js +1 -1
  39. package/dist/currency.js +1 -1
  40. package/dist/debugging-standalone.js +1 -1
  41. package/dist/dspxBidAdapter.js +1 -1
  42. package/dist/enrichmentFpdModule.js +1 -1
  43. package/dist/eplanningBidAdapter.js +1 -1
  44. package/dist/finativeBidAdapter.js +1 -1
  45. package/dist/glimpseBidAdapter.js +1 -1
  46. package/dist/gmosspBidAdapter.js +1 -1
  47. package/dist/goldbachBidAdapter.js +1 -1
  48. package/dist/gridBidAdapter.js +1 -1
  49. package/dist/gridNMBidAdapter.js +1 -1
  50. package/dist/gumgumBidAdapter.js +1 -1
  51. package/dist/h12mediaBidAdapter.js +1 -1
  52. package/dist/id5IdSystem.js +1 -1
  53. package/dist/imRtdProvider.js +1 -1
  54. package/dist/impactifyBidAdapter.js +1 -1
  55. package/dist/improvedigitalBidAdapter.js +1 -1
  56. package/dist/inmarBidAdapter.js +1 -1
  57. package/dist/insticatorBidAdapter.js +1 -1
  58. package/dist/ixBidAdapter.js +1 -1
  59. package/dist/jixieBidAdapter.js +1 -1
  60. package/dist/justpremiumBidAdapter.js +1 -1
  61. package/dist/konduitAnalyticsAdapter.js +1 -1
  62. package/dist/kueezBidAdapter.js +1 -1
  63. package/dist/lassoBidAdapter.js +1 -1
  64. package/dist/lifestreetBidAdapter.js +1 -0
  65. package/dist/limelightDigitalBidAdapter.js +1 -1
  66. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  67. package/dist/logicadBidAdapter.js +1 -1
  68. package/dist/loglyliftBidAdapter.js +1 -1
  69. package/dist/mabidderBidAdapter.js +1 -0
  70. package/dist/malltvAnalyticsAdapter.js +1 -1
  71. package/dist/marsmediaBidAdapter.js +1 -1
  72. package/dist/mediafuseBidAdapter.js +1 -1
  73. package/dist/mediakeysBidAdapter.js +1 -1
  74. package/dist/mediasquareBidAdapter.js +1 -1
  75. package/dist/mgidBidAdapter.js +1 -1
  76. package/dist/minutemediaBidAdapter.js +1 -1
  77. package/dist/not-for-prod/prebid.js +132 -127
  78. package/dist/oguryBidAdapter.js +1 -1
  79. package/dist/oneKeyIdSystem.js +1 -0
  80. package/dist/oneKeyRtdProvider.js +1 -0
  81. package/dist/onetagBidAdapter.js +1 -1
  82. package/dist/ooloAnalyticsAdapter.js +1 -1
  83. package/dist/outbrainBidAdapter.js +1 -1
  84. package/dist/parrableIdSystem.js +1 -1
  85. package/dist/permutiveRtdProvider.js +1 -1
  86. package/dist/pixfutureBidAdapter.js +1 -1
  87. package/dist/prebid-core.js +2 -2
  88. package/dist/publinkIdSystem.js +1 -1
  89. package/dist/pubmaticBidAdapter.js +1 -1
  90. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  91. package/dist/pxyzBidAdapter.js +1 -1
  92. package/dist/quantcastBidAdapter.js +1 -1
  93. package/dist/readpeakBidAdapter.js +1 -1
  94. package/dist/relaidoBidAdapter.js +1 -1
  95. package/dist/rhythmoneBidAdapter.js +1 -1
  96. package/dist/riseBidAdapter.js +1 -1
  97. package/dist/rtbhouseBidAdapter.js +1 -1
  98. package/dist/rubiconAnalyticsAdapter.js +1 -1
  99. package/dist/rubiconBidAdapter.js +1 -1
  100. package/dist/seedingAllianceBidAdapter.js +1 -1
  101. package/dist/seedtagBidAdapter.js +1 -1
  102. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  103. package/dist/sharethroughBidAdapter.js +1 -1
  104. package/dist/shinezBidAdapter.js +1 -1
  105. package/dist/smaatoBidAdapter.js +1 -1
  106. package/dist/smartadserverBidAdapter.js +1 -1
  107. package/dist/smartxBidAdapter.js +1 -1
  108. package/dist/smilewantedBidAdapter.js +1 -1
  109. package/dist/sonobiBidAdapter.js +1 -1
  110. package/dist/sovrnAnalyticsAdapter.js +1 -1
  111. package/dist/sovrnBidAdapter.js +1 -1
  112. package/dist/sspBCBidAdapter.js +1 -1
  113. package/dist/sublimeBidAdapter.js +1 -1
  114. package/dist/synacormediaBidAdapter.js +1 -1
  115. package/dist/targetVideoBidAdapter.js +1 -1
  116. package/dist/teadsBidAdapter.js +1 -1
  117. package/dist/trionBidAdapter.js +1 -1
  118. package/dist/tripleliftBidAdapter.js +1 -1
  119. package/dist/trustpidSystem.js +1 -1
  120. package/dist/ttdBidAdapter.js +1 -1
  121. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  122. package/dist/underdogmediaBidAdapter.js +1 -1
  123. package/dist/undertoneBidAdapter.js +1 -1
  124. package/dist/userId.js +1 -1
  125. package/dist/vidazooBidAdapter.js +1 -1
  126. package/dist/videobyteBidAdapter.js +1 -1
  127. package/dist/viewability.js +1 -1
  128. package/dist/visxBidAdapter.js +1 -1
  129. package/dist/vuukleBidAdapter.js +1 -1
  130. package/dist/widespaceBidAdapter.js +1 -1
  131. package/dist/winrBidAdapter.js +1 -1
  132. package/dist/yahoosspBidAdapter.js +1 -1
  133. package/dist/yieldmoBidAdapter.js +1 -1
  134. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  135. package/modules/.submodules.json +2 -0
  136. package/modules/acuityAdsBidAdapter.js +207 -0
  137. package/modules/acuityAdsBidAdapter.md +79 -0
  138. package/modules/adgenerationBidAdapter.js +2 -2
  139. package/modules/adriverBidAdapter.js +1 -1
  140. package/modules/appnexusBidAdapter.js +13 -93
  141. package/modules/beopBidAdapter.js +4 -4
  142. package/modules/browsiRtdProvider.js +1 -1
  143. package/modules/consentManagement.js +1 -1
  144. package/modules/consentManagementUsp.js +1 -1
  145. package/modules/consumableBidAdapter.js +23 -1
  146. package/modules/currency.js +1 -0
  147. package/modules/datawrkzBidAdapter.js +13 -13
  148. package/modules/enrichmentFpdModule.js +11 -0
  149. package/modules/id5IdSystem.js +2 -2
  150. package/modules/imRtdProvider.js +20 -7
  151. package/modules/imRtdProvider.md +3 -1
  152. package/modules/insticatorBidAdapter.js +1 -1
  153. package/modules/ixBidAdapter.js +8 -22
  154. package/modules/ixBidAdapter.md +1 -19
  155. package/modules/lifestreetBidAdapter.js +143 -0
  156. package/modules/limelightDigitalBidAdapter.js +2 -1
  157. package/modules/mabidderBidAdapter.js +60 -0
  158. package/modules/mabidderBidAdapter.md +31 -0
  159. package/modules/oneKeyIdSystem.js +78 -0
  160. package/modules/oneKeyIdSystem.md +109 -0
  161. package/modules/oneKeyRtdProvider.js +98 -0
  162. package/modules/oneKeyRtdProvider.md +127 -0
  163. package/modules/permutiveRtdProvider.js +55 -8
  164. package/modules/pubmaticBidAdapter.js +14 -0
  165. package/modules/rtbhouseBidAdapter.js +24 -0
  166. package/modules/seedtagBidAdapter.md +25 -56
  167. package/modules/tripleliftBidAdapter.js +20 -1
  168. package/modules/trustpidSystem.js +6 -42
  169. package/modules/trustpidSystem.md +10 -10
  170. package/modules/userId/eids.js +26 -0
  171. package/modules/userId/userId.md +2 -2
  172. package/modules/viewability.js +14 -14
  173. package/modules/yahoosspBidAdapter.js +1 -1
  174. package/package.json +1 -1
  175. package/src/auction.js +2 -1
  176. package/src/native.js +22 -3
  177. package/src/sizeMapping.js +4 -6
  178. package/src/utils/promise.js +3 -1
  179. package/src/utils.js +27 -0
  180. package/src/video.js +5 -4
  181. package/test/pages/instream.html +2 -2
  182. package/test/spec/modules/acuityAdsBidAdapter_spec.js +398 -0
  183. package/test/spec/modules/appnexusBidAdapter_spec.js +1 -0
  184. package/test/spec/modules/beopBidAdapter_spec.js +11 -0
  185. package/test/spec/modules/big-richmediaBidAdapter_spec.js +1 -0
  186. package/test/spec/modules/consumableBidAdapter_spec.js +19 -0
  187. package/test/spec/modules/currency_spec.js +22 -0
  188. package/test/spec/modules/enrichmentFpdModule_spec.js +14 -0
  189. package/test/spec/modules/imRtdProvider_spec.js +10 -5
  190. package/test/spec/modules/ixBidAdapter_spec.js +6 -19
  191. package/test/spec/modules/lifestreetBidAdapter_spec.js +232 -0
  192. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +59 -7
  193. package/test/spec/modules/mabidderBidAdapter_spec.js +125 -0
  194. package/test/spec/modules/oneKeyIdSystem_spec.js +107 -0
  195. package/test/spec/modules/oneKeyRtdProvider_spec.js +152 -0
  196. package/test/spec/modules/permutiveRtdProvider_spec.js +152 -2
  197. package/test/spec/modules/pubmaticBidAdapter_spec.js +16 -0
  198. package/test/spec/modules/tripleliftBidAdapter_spec.js +18 -0
  199. package/test/spec/modules/trustpidSystem_spec.js +27 -45
  200. package/test/spec/native_spec.js +17 -2
@@ -10,6 +10,7 @@ import {
10
10
  getMaxValueFromArray,
11
11
  getMinValueFromArray,
12
12
  getParameterByName,
13
+ getUniqueIdentifierStr,
13
14
  isArray,
14
15
  isArrayOfNums,
15
16
  isEmpty,
@@ -444,16 +445,6 @@ export const spec = {
444
445
  }
445
446
 
446
447
  return params;
447
- },
448
-
449
- /**
450
- * Add element selector to javascript tracker to improve native viewability
451
- * @param {Bid} bid
452
- */
453
- onBidWon: function (bid) {
454
- if (FEATURES.NATIVE && bid.native) {
455
- reloadViewabilityScriptWithCorrectParameters(bid);
456
- }
457
448
  }
458
449
  };
459
450
 
@@ -467,58 +458,9 @@ function deleteValues(keyPairObj) {
467
458
  }
468
459
  }
469
460
 
470
- function reloadViewabilityScriptWithCorrectParameters(bid) {
471
- let viewJsPayload = getAppnexusViewabilityScriptFromJsTrackers(bid.native.javascriptTrackers);
472
-
473
- if (viewJsPayload) {
474
- let prebidParams = 'pbjs_adid=' + bid.adId + ';pbjs_auc=' + bid.adUnitCode;
475
-
476
- let jsTrackerSrc = getViewabilityScriptUrlFromPayload(viewJsPayload);
477
-
478
- let newJsTrackerSrc = jsTrackerSrc.replace('dom_id=%native_dom_id%', prebidParams);
479
-
480
- // find iframe containing script tag
481
- let frameArray = document.getElementsByTagName('iframe');
482
-
483
- // boolean var to modify only one script. That way if there are muliple scripts,
484
- // they won't all point to the same creative.
485
- let modifiedAScript = false;
486
-
487
- // first, loop on all ifames
488
- for (let i = 0; i < frameArray.length && !modifiedAScript; i++) {
489
- let currentFrame = frameArray[i];
490
- try {
491
- // IE-compatible, see https://stackoverflow.com/a/3999191/2112089
492
- let nestedDoc = currentFrame.contentDocument || currentFrame.contentWindow.document;
493
-
494
- if (nestedDoc) {
495
- // if the doc is present, we look for our jstracker
496
- let scriptArray = nestedDoc.getElementsByTagName('script');
497
- for (let j = 0; j < scriptArray.length && !modifiedAScript; j++) {
498
- let currentScript = scriptArray[j];
499
- if (currentScript.getAttribute('data-src') == jsTrackerSrc) {
500
- currentScript.setAttribute('src', newJsTrackerSrc);
501
- currentScript.setAttribute('data-src', '');
502
- if (currentScript.removeAttribute) {
503
- currentScript.removeAttribute('data-src');
504
- }
505
- modifiedAScript = true;
506
- }
507
- }
508
- }
509
- } catch (exception) {
510
- // trying to access a cross-domain iframe raises a SecurityError
511
- // this is expected and ignored
512
- if (!(exception instanceof DOMException && exception.name === 'SecurityError')) {
513
- // all other cases are raised again to be treated by the calling function
514
- throw exception;
515
- }
516
- }
517
- }
518
- }
519
- }
520
-
521
461
  function strIsAppnexusViewabilityScript(str) {
462
+ if (!str || str === '') return false;
463
+
522
464
  let regexMatchUrlStart = str.match(VIEWABILITY_URL_START);
523
465
  let viewUrlStartInStr = regexMatchUrlStart != null && regexMatchUrlStart.length >= 1;
524
466
 
@@ -528,30 +470,6 @@ function strIsAppnexusViewabilityScript(str) {
528
470
  return str.startsWith(SCRIPT_TAG_START) && fileNameInStr && viewUrlStartInStr;
529
471
  }
530
472
 
531
- function getAppnexusViewabilityScriptFromJsTrackers(jsTrackerArray) {
532
- let viewJsPayload;
533
- if (isStr(jsTrackerArray) && strIsAppnexusViewabilityScript(jsTrackerArray)) {
534
- viewJsPayload = jsTrackerArray;
535
- } else if (isArray(jsTrackerArray)) {
536
- for (let i = 0; i < jsTrackerArray.length; i++) {
537
- let currentJsTracker = jsTrackerArray[i];
538
- if (strIsAppnexusViewabilityScript(currentJsTracker)) {
539
- viewJsPayload = currentJsTracker;
540
- }
541
- }
542
- }
543
- return viewJsPayload;
544
- }
545
-
546
- function getViewabilityScriptUrlFromPayload(viewJsPayload) {
547
- // extracting the content of the src attribute
548
- // -> substring between src=" and "
549
- let indexOfFirstQuote = viewJsPayload.indexOf('src="') + 5; // offset of 5: the length of 'src=' + 1
550
- let indexOfSecondQuote = viewJsPayload.indexOf('"', indexOfFirstQuote);
551
- let jsTrackerSrc = viewJsPayload.substring(indexOfFirstQuote, indexOfSecondQuote);
552
- return jsTrackerSrc;
553
- }
554
-
555
473
  function formatRequest(payload, bidderRequest) {
556
474
  let request = [];
557
475
  let options = {
@@ -633,7 +551,9 @@ function newRenderer(adUnitCode, rtbBid, rendererOptions = {}) {
633
551
  */
634
552
  function newBid(serverBid, rtbBid, bidderRequest) {
635
553
  const bidRequest = getBidRequest(serverBid.uuid, [bidderRequest]);
554
+ const adId = getUniqueIdentifierStr();
636
555
  const bid = {
556
+ adId: adId,
637
557
  requestId: serverBid.uuid,
638
558
  cpm: rtbBid.cpm,
639
559
  creativeId: rtbBid.creative_id,
@@ -721,20 +641,20 @@ function newBid(serverBid, rtbBid, bidderRequest) {
721
641
  }
722
642
  } else if (FEATURES.NATIVE && rtbBid.rtb[NATIVE]) {
723
643
  const nativeAd = rtbBid.rtb[NATIVE];
644
+ let viewScript;
724
645
 
725
- // setting up the jsTracker:
726
- // we put it as a data-src attribute so that the tracker isn't called
727
- // until we have the adId (see onBidWon)
728
- let jsTrackerDisarmed = rtbBid.viewability.config.replace('src=', 'data-src=');
646
+ if (strIsAppnexusViewabilityScript(rtbBid.viewability.config)) {
647
+ let prebidParams = 'pbjs_adid=' + adId + ';pbjs_auc=' + bidRequest.adUnitCode;
648
+ viewScript = rtbBid.viewability.config.replace('dom_id=%native_dom_id%', prebidParams);
649
+ }
729
650
 
730
651
  let jsTrackers = nativeAd.javascript_trackers;
731
-
732
652
  if (jsTrackers == undefined) {
733
- jsTrackers = jsTrackerDisarmed;
653
+ jsTrackers = viewScript;
734
654
  } else if (isStr(jsTrackers)) {
735
- jsTrackers = [jsTrackers, jsTrackerDisarmed];
655
+ jsTrackers = [jsTrackers, viewScript];
736
656
  } else {
737
- jsTrackers.push(jsTrackerDisarmed);
657
+ jsTrackers.push(viewScript);
738
658
  }
739
659
 
740
660
  bid[NATIVE] = {
@@ -99,12 +99,12 @@ export const spec = {
99
99
  }
100
100
 
101
101
  function buildTrackingParams(data, info, value) {
102
- const accountId = data.params.accountId;
102
+ let params = Array.isArray(data.params) ? data.params[0] : data.params;
103
103
  const pageUrl = getPageUrl(null, window);
104
104
  return {
105
- pid: accountId === undefined ? data.ad.match(/account: \“([a-f\d]{24})\“/)[1] : accountId,
106
- nid: data.params.networkId,
107
- nptnid: data.params.networkPartnerId,
105
+ pid: params.accountId === undefined ? data.ad.match(/account: \“([a-f\d]{24})\“/)[1] : params.accountId,
106
+ nid: params.networkId,
107
+ nptnid: params.networkPartnerId,
108
108
  bid: data.bidId || data.requestId,
109
109
  sl_n: data.adUnitCode,
110
110
  aid: data.auctionId,
@@ -348,7 +348,7 @@ export const browsiSubmodule = {
348
348
  function getTargetingData(uc, c, us, a) {
349
349
  const targetingData = getRTD(uc);
350
350
  const auctionId = a.auctionId;
351
- const sendAdRequestEvent = _browsiData['bet'] === 'AD_REQUEST';
351
+ const sendAdRequestEvent = (_browsiData && _browsiData['bet'] === 'AD_REQUEST');
352
352
  uc.forEach(auc => {
353
353
  if (isNumber(_ic[auc])) {
354
354
  _ic[auc] = _ic[auc] + 1;
@@ -145,7 +145,7 @@ function lookupIabConsent({onSuccess, onError}) {
145
145
  if (json[cmpDataPkgName] && json[cmpDataPkgName].callId) {
146
146
  const payload = json[cmpDataPkgName];
147
147
  // TODO - clean up this logic (move listeners?); we have duplicate messages responses because 2 eventlisteners are active from the 2 cmp requests running in parallel
148
- if (typeof cmpCallbacks[payload.callId] !== 'undefined') {
148
+ if (cmpCallbacks.hasOwnProperty(payload.callId)) {
149
149
  cmpCallbacks[payload.callId](payload.returnValue, payload.success);
150
150
  }
151
151
  }
@@ -150,7 +150,7 @@ function lookupUspConsent({onSuccess, onError}) {
150
150
  function readPostMessageResponse(event) {
151
151
  const res = event && event.data && event.data.__uspapiReturn;
152
152
  if (res && res.callId) {
153
- if (typeof uspapiCallbacks[res.callId] !== 'undefined') {
153
+ if (uspapiCallbacks.hasOwnProperty(res.callId)) {
154
154
  uspapiCallbacks[res.callId](res.returnValue, res.success);
155
155
  delete uspapiCallbacks[res.callId];
156
156
  }
@@ -1,4 +1,4 @@
1
- import { logWarn, deepAccess, isArray, deepSetValue } from '../src/utils.js';
1
+ import { logWarn, deepAccess, isArray, deepSetValue, isFn, isPlainObject } from '../src/utils.js';
2
2
  import {config} from '../src/config.js';
3
3
  import { registerBidder } from '../src/adapters/bidderFactory.js';
4
4
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
@@ -84,6 +84,8 @@ export const spec = {
84
84
  adTypes: bid.adTypes || getSize(sizes)
85
85
  }, bid.params);
86
86
 
87
+ placement.bidfloor = getBidFloor(bid, sizes);
88
+
87
89
  if (bid.mediaTypes.video && bid.mediaTypes.video.playerSize) {
88
90
  placement.video = bid.mediaTypes.video;
89
91
  }
@@ -272,4 +274,24 @@ function handleEids(data, validBidRequests) {
272
274
  }
273
275
  }
274
276
 
277
+ function getBidFloor(bid, sizes) {
278
+ if (!isFn(bid.getFloor)) {
279
+ return bid.params.bidFloor ? bid.params.bidFloor : null;
280
+ }
281
+
282
+ let floor;
283
+
284
+ let floorInfo = bid.getFloor({
285
+ currency: 'USD',
286
+ mediaType: bid.mediaTypes.video ? 'video' : 'banner',
287
+ size: sizes.length === 1 ? sizes[0] : '*'
288
+ });
289
+
290
+ if (isPlainObject(floorInfo) && floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) {
291
+ floor = parseFloat(floorInfo.floor);
292
+ }
293
+
294
+ return floor;
295
+ }
296
+
275
297
  registerBidder(spec);
@@ -146,6 +146,7 @@ function initCurrency(url) {
146
146
  try {
147
147
  currencyRates = JSON.parse(response);
148
148
  logInfo('currencyRates set to ' + JSON.stringify(currencyRates));
149
+ conversionCache = {};
149
150
  currencyRatesLoaded = true;
150
151
  processBidResponseQueue();
151
152
  ready.done();
@@ -162,10 +162,10 @@ function buildNativeRequest(bidRequest, bidderRequest) {
162
162
  assets.push(generateNativeDataObj(body, 'desc', ++counter));
163
163
  }
164
164
 
165
- let request = JSON.stringify({assets: assets})
165
+ let request = JSON.stringify({assets: assets});
166
166
  const native = {
167
167
  request: request
168
- }
168
+ };
169
169
 
170
170
  var deals = [];
171
171
  if (bidRequest.params.deals && bidRequest.params.deals.length > 0) {
@@ -220,7 +220,7 @@ function buildVideoRequest(bidRequest, bidderRequest) {
220
220
  };
221
221
 
222
222
  let context = deepAccess(bidRequest, 'mediaTypes.video.context');
223
- if (context == 'outstream' && !bidRequest.renderer) video.mimes = OUTSTREAM_MIMES
223
+ if (context == 'outstream' && !bidRequest.renderer) video.mimes = OUTSTREAM_MIMES;
224
224
 
225
225
  var imp = [];
226
226
  var deals = [];
@@ -293,7 +293,7 @@ function generatePayload(imp, bidderRequest) {
293
293
  publisher: {}
294
294
  };
295
295
 
296
- let regs = {ext: {}}
296
+ let regs = {ext: {}};
297
297
 
298
298
  if (bidderRequest.uspConsent) {
299
299
  regs.ext.us_privacy = bidderRequest.uspConsent;
@@ -346,7 +346,7 @@ function generateNativeImgObj(obj, type, id) {
346
346
  type: parseInt(typeId),
347
347
  w: adW,
348
348
  h: adH
349
- }
349
+ };
350
350
  return {
351
351
  id: id,
352
352
  required: required,
@@ -413,8 +413,8 @@ function buildBannerResponse(bidRequest, bidResponse) {
413
413
  return;
414
414
  }
415
415
  let bidSizes = (deepAccess(bidRequest, 'mediaTypes.banner.sizes')) ? deepAccess(bidRequest, 'mediaTypes.banner.sizes') : bidRequest.sizes;
416
- bidResponse.requestId = bidRequest.bidId
417
- bidResponse.transactionId = bidRequest.transactionId
416
+ bidResponse.requestId = bidRequest.bidId;
417
+ bidResponse.transactionId = bidRequest.transactionId;
418
418
  bidResponse.placementCode = placementCode;
419
419
  bidResponse.cpm = responseCPM;
420
420
  bidResponse.size = bidSizes;
@@ -454,8 +454,8 @@ function buildNativeResponse(bidRequest, response) {
454
454
  bidResponses.push(bid);
455
455
  return;
456
456
  }
457
- bidResponse.requestId = bidRequest.bidId
458
- bidResponse.transactionId = bidRequest.transactionId
457
+ bidResponse.requestId = bidRequest.bidId;
458
+ bidResponse.transactionId = bidRequest.transactionId;
459
459
  bidResponse.placementCode = placementCode;
460
460
  bidResponse.cpm = responseCPM;
461
461
 
@@ -506,8 +506,8 @@ function buildVideoResponse(bidRequest, response) {
506
506
  }
507
507
  let context = bidRequest.mediaTypes.video.context;
508
508
 
509
- bidResponse.requestId = bidRequest.bidId
510
- bidResponse.transactionId = bidRequest.transactionId
509
+ bidResponse.requestId = bidRequest.bidId;
510
+ bidResponse.transactionId = bidRequest.transactionId;
511
511
  bidResponse.placementCode = placementCode;
512
512
  bidResponse.cpm = responseCPM;
513
513
 
@@ -531,7 +531,7 @@ function buildVideoResponse(bidRequest, response) {
531
531
 
532
532
  switch (context) {
533
533
  case OUTSTREAM:
534
- var outstreamType = contains(OUTSTREAM_TYPES, bidRequest.params.outstreamType) ? bidRequest.params.outstreamType : ''
534
+ var outstreamType = contains(OUTSTREAM_TYPES, bidRequest.params.outstreamType) ? bidRequest.params.outstreamType : '';
535
535
  bidResponse.outstreamType = outstreamType;
536
536
  bidResponse.ad = vastXml;
537
537
  if (!bidRequest.renderer) {
@@ -542,7 +542,7 @@ function buildVideoResponse(bidRequest, response) {
542
542
  loaded: false,
543
543
  adUnitCode
544
544
  });
545
- renderer.setRender(outstreamRender)
545
+ renderer.setRender(outstreamRender);
546
546
  bidResponse.renderer = renderer;
547
547
  } else { bidResponse.adResponse = vastXml; }
548
548
  break;
@@ -124,6 +124,16 @@ function setKeywords() {
124
124
  if (keywords && keywords.content) mergeDeep(ortb2, { site: { keywords: keywords.content.replace(/\s/g, '') } });
125
125
  }
126
126
 
127
+ /**
128
+ * Checks the Global Privacy Control status, and if exists and is true, merges into regs.ext.gpc
129
+ */
130
+ function setGpc() {
131
+ const gpcValue = navigator.globalPrivacyControl;
132
+ if (gpcValue) {
133
+ mergeDeep(ortb2, { regs: { ext: { gpc: 1 } } })
134
+ }
135
+ }
136
+
127
137
  /**
128
138
  * Resets modules global ortb2 data
129
139
  */
@@ -135,6 +145,7 @@ function runEnrichments() {
135
145
  setDomain();
136
146
  setDimensions();
137
147
  setKeywords();
148
+ setGpc();
138
149
 
139
150
  return ortb2;
140
151
  }
@@ -28,7 +28,7 @@ export const ID5_STORAGE_NAME = 'id5id';
28
28
  export const ID5_PRIVACY_STORAGE_NAME = `${ID5_STORAGE_NAME}_privacy`;
29
29
  const LOCAL_STORAGE = 'html5';
30
30
  const LOG_PREFIX = 'User ID - ID5 submodule: ';
31
- const ID5_API_CONFIG_URL = 'https://id5-sync.com/api/config/prebid'
31
+ const ID5_API_CONFIG_URL = 'https://id5-sync.com/api/config/prebid';
32
32
 
33
33
  // order the legacy cookie names in reverse priority order so the last
34
34
  // cookie in the array is the most preferred to use
@@ -277,7 +277,7 @@ class IdFetchFlow {
277
277
  enabled: true, control_group_pct: abTestingConfig.controlGroupPct // The server validates
278
278
  };
279
279
  }
280
- return data
280
+ return data;
281
281
  }
282
282
  }
283
283
 
@@ -37,28 +37,40 @@ function setImDataInCookie(value) {
37
37
  );
38
38
  }
39
39
 
40
+ /**
41
+ * @param {Object} segments
42
+ * @param {Object} moduleConfig
43
+ */
44
+ function getSegments(segments, moduleConfig) {
45
+ if (!segments) return;
46
+ const maxSegments = !Number.isNaN(moduleConfig.params.maxSegments) ? moduleConfig.params.maxSegments : 200;
47
+ return segments.slice(0, maxSegments);
48
+ }
49
+
40
50
  /**
41
51
  * @param {string} bidderName
42
52
  */
43
53
  export function getBidderFunction(bidderName) {
44
54
  const biddersFunction = {
45
- pubmatic: function (bid, data) {
55
+ pubmatic: function (bid, data, moduleConfig) {
46
56
  if (data.im_segments && data.im_segments.length) {
57
+ const segments = getSegments(data.im_segments, moduleConfig);
47
58
  const dctr = deepAccess(bid, 'params.dctr');
48
59
  deepSetValue(
49
60
  bid,
50
61
  'params.dctr',
51
- `${dctr ? dctr + '|' : ''}im_segments=${data.im_segments.join(',')}`
62
+ `${dctr ? dctr + '|' : ''}im_segments=${segments.join(',')}`
52
63
  );
53
64
  }
54
65
  return bid
55
66
  },
56
- fluct: function (bid, data) {
67
+ fluct: function (bid, data, moduleConfig) {
57
68
  if (data.im_segments && data.im_segments.length) {
69
+ const segments = getSegments(data.im_segments, moduleConfig);
58
70
  deepSetValue(
59
71
  bid,
60
72
  'params.kv.imsids',
61
- data.im_segments
73
+ segments
62
74
  );
63
75
  }
64
76
  return bid
@@ -88,14 +100,15 @@ export function setRealTimeData(bidConfig, moduleConfig, data) {
88
100
  const utils = {deepSetValue, deepAccess, logInfo, logError, mergeDeep};
89
101
 
90
102
  if (data.im_segments) {
103
+ const segments = getSegments(data.im_segments, moduleConfig);
91
104
  const ortb2 = bidConfig.ortb2Fragments?.global || {};
92
- deepSetValue(ortb2, 'user.ext.data.im_segments', data.im_segments);
105
+ deepSetValue(ortb2, 'user.ext.data.im_segments', segments);
93
106
 
94
107
  if (moduleConfig.params.setGptKeyValues || !moduleConfig.params.hasOwnProperty('setGptKeyValues')) {
95
108
  window.googletag = window.googletag || {cmd: []};
96
109
  window.googletag.cmd = window.googletag.cmd || [];
97
110
  window.googletag.cmd.push(() => {
98
- window.googletag.pubads().setTargeting('im_segments', data.im_segments);
111
+ window.googletag.pubads().setTargeting('im_segments', segments);
99
112
  });
100
113
  }
101
114
  }
@@ -107,7 +120,7 @@ export function setRealTimeData(bidConfig, moduleConfig, data) {
107
120
  if (overwriteFunction) {
108
121
  overwriteFunction(bid, data, utils, config);
109
122
  } else if (bidderFunction) {
110
- bidderFunction(bid, data);
123
+ bidderFunction(bid, data, moduleConfig);
111
124
  }
112
125
  })
113
126
  });
@@ -21,7 +21,8 @@ pbjs.setConfig(
21
21
  waitForIt: true,
22
22
  params: {
23
23
  cid: 5126, // Set your Intimate Merger Customer ID here for production
24
- setGptKeyValues: true
24
+ setGptKeyValues: true,
25
+ maxSegments: 200 // maximum number is 200
25
26
  }
26
27
  }
27
28
  ]
@@ -39,3 +40,4 @@ pbjs.setConfig(
39
40
  | params | Required | Object | Details of module params. | |
40
41
  | params.cid | Required | Number | This is the Customer ID value obtained via Intimate Merger. | `5126` |
41
42
  | params.setGptKeyValues | Optional | Boolean | This is set targeting for GPT/GAM. Default setting is true. | `true` |
43
+ | params.maxSegments | Optional | Number | This is set maximum number of rtd segments at once. Default setting is 200. | `200` |
@@ -43,7 +43,7 @@ function setUserId(userId) {
43
43
  }
44
44
 
45
45
  if (storage.cookiesAreEnabled()) {
46
- const expires = new Date(Date.now() + USER_ID_COOKIE_EXP).toISOString();
46
+ const expires = new Date(Date.now() + USER_ID_COOKIE_EXP).toUTCString();
47
47
  storage.setCookie(USER_ID_KEY, userId, expires);
48
48
  }
49
49
  }
@@ -586,8 +586,6 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
586
586
  r.ext = {};
587
587
  r.ext.source = 'prebid';
588
588
  r.ext.ixdiag = {};
589
- r.ext.ixdiag.msd = 0;
590
- r.ext.ixdiag.msi = 0;
591
589
  r.imp = [];
592
590
  r.at = 1;
593
591
 
@@ -732,12 +730,6 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
732
730
  if (typeof otherIxConfig.timeout === 'number') {
733
731
  payload.t = otherIxConfig.timeout;
734
732
  }
735
-
736
- if (typeof otherIxConfig.detectMissingSizes === 'boolean') {
737
- r.ext.ixdiag.dms = otherIxConfig.detectMissingSizes;
738
- } else {
739
- r.ext.ixdiag.dms = true;
740
- }
741
733
  }
742
734
 
743
735
  for (let adUnitIndex = 0; adUnitIndex < transactionIds.length; adUnitIndex++) {
@@ -746,7 +738,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
746
738
  }
747
739
 
748
740
  const adUnitImpressions = impressions[transactionIds[adUnitIndex]];
749
- const { missingCount = 0, missingImps: missingBannerImpressions = [], ixImps = [] } = adUnitImpressions;
741
+ const { missingImps: missingBannerImpressions = [], ixImps = [] } = adUnitImpressions;
750
742
  let wasAdUnitImpressionsTrimmed = false;
751
743
  let remainingRequestSize = MAX_REQUEST_SIZE - currentRequestSize;
752
744
  const sourceImpressions = { ixImps, missingBannerImpressions };
@@ -781,6 +773,11 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
781
773
  },
782
774
  };
783
775
 
776
+ const position = impressions[transactionIds[adUnitIndex]].pos;
777
+ if (isInteger(position)) {
778
+ _bannerImpression.banner.pos = position;
779
+ }
780
+
784
781
  if (dfpAdUnitCode || gpid || tid) {
785
782
  _bannerImpression.ext = {};
786
783
  _bannerImpression.ext.dfp_ad_unit_code = dfpAdUnitCode;
@@ -797,8 +794,6 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
797
794
  }
798
795
 
799
796
  r.imp.push(_bannerImpression);
800
- r.ext.ixdiag.msd += missingCount;
801
- r.ext.ixdiag.msi += missingBannerImpressions.length;
802
797
  } else {
803
798
  // set imp.ext.gpid to resolved gpid for each imp
804
799
  impressionObjects.forEach(imp => deepSetValue(imp, 'ext.gpid', gpid));
@@ -882,8 +877,6 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
882
877
 
883
878
  currentRequestSize = baseRequestSize;
884
879
  r.imp = [];
885
- r.ext.ixdiag.msd = 0;
886
- r.ext.ixdiag.msi = 0;
887
880
  isFpdAdded = false;
888
881
  }
889
882
  }
@@ -1035,12 +1028,6 @@ function createVideoImps(validBidRequest, videoImps) {
1035
1028
  * @param {object} bannerImps reference to created banner impressions
1036
1029
  */
1037
1030
  function createBannerImps(validBidRequest, missingBannerSizes, bannerImps) {
1038
- const DEFAULT_IX_CONFIG = {
1039
- detectMissingSizes: true,
1040
- };
1041
-
1042
- const ixConfig = { ...DEFAULT_IX_CONFIG, ...config.getConfig('ix') };
1043
-
1044
1031
  let imp = bidToBannerImp(validBidRequest);
1045
1032
 
1046
1033
  const bannerSizeDefined = includesSize(deepAccess(validBidRequest, 'mediaTypes.banner.sizes'), deepAccess(validBidRequest, 'params.size'));
@@ -1054,6 +1041,7 @@ function createBannerImps(validBidRequest, missingBannerSizes, bannerImps) {
1054
1041
  bannerImps[validBidRequest.transactionId].tid = deepAccess(validBidRequest, 'ortb2Imp.ext.tid');
1055
1042
  bannerImps[validBidRequest.transactionId].pbadslot = deepAccess(validBidRequest, 'ortb2Imp.ext.data.pbadslot');
1056
1043
  bannerImps[validBidRequest.transactionId].tagId = deepAccess(validBidRequest, 'params.tagId');
1044
+ bannerImps[validBidRequest.transactionId].pos = deepAccess(validBidRequest, 'mediaTypes.banner.pos');
1057
1045
 
1058
1046
  const adUnitCode = validBidRequest.adUnitCode;
1059
1047
  const divId = document.getElementById(adUnitCode) ? adUnitCode : getGptSlotInfoForAdUnitCode(adUnitCode).divId;
@@ -1068,9 +1056,7 @@ function createBannerImps(validBidRequest, missingBannerSizes, bannerImps) {
1068
1056
  bannerImps[validBidRequest.transactionId].ixImps.push(imp);
1069
1057
  }
1070
1058
 
1071
- if (ixConfig.hasOwnProperty('detectMissingSizes') && ixConfig.detectMissingSizes) {
1072
- updateMissingSizes(validBidRequest, missingBannerSizes, imp);
1073
- }
1059
+ updateMissingSizes(validBidRequest, missingBannerSizes, imp);
1074
1060
  }
1075
1061
 
1076
1062
  /**
@@ -362,25 +362,7 @@ pbjs.setConfig({
362
362
  });
363
363
  ```
364
364
  #### The **detectMissingSizes** feature
365
- By default, the IX bidding adapter bids on all banner sizes available in the ad unit when configured to at least one banner size. If you want the IX bidding adapter to only bid on the banner size it’s configured to, switch off this feature using `detectMissingSizes`.
366
- ```
367
- pbjs.setConfig({
368
- ix: {
369
- detectMissingSizes: false
370
- }
371
- });
372
- ```
373
- OR
374
- ```
375
- pbjs.setBidderConfig({
376
- bidders: ["ix"],
377
- config: {
378
- ix: {
379
- detectMissingSizes: false
380
- }
381
- }
382
- });
383
- ```
365
+ `detectMissingSize` config is now deprecated and IX bidding adapter bids on all banner sizes available in the ad unit when configured to at least one banner size.
384
366
 
385
367
  **Native**
386
368