prebid.js 7.33.0 → 7.35.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 (219) hide show
  1. package/.devcontainer/devcontainer.json +2 -1
  2. package/.github/workflows/issue_tracker.yml +27 -16
  3. package/dist/33acrossBidAdapter.js +1 -1
  4. package/dist/33acrossIdSystem.js +1 -1
  5. package/dist/adagioBidAdapter.js +1 -1
  6. package/dist/adbookpspBidAdapter.js +1 -1
  7. package/dist/adgenerationBidAdapter.js +1 -1
  8. package/dist/admaticBidAdapter.js +1 -1
  9. package/dist/admixerBidAdapter.js +1 -1
  10. package/dist/adnuntiusBidAdapter.js +1 -1
  11. package/dist/adrelevantisBidAdapter.js +1 -1
  12. package/dist/adtrgtmeBidAdapter.js +1 -1
  13. package/dist/adxcgBidAdapter.js +1 -1
  14. package/dist/adyoulikeBidAdapter.js +1 -1
  15. package/dist/ajaBidAdapter.js +1 -1
  16. package/dist/amxBidAdapter.js +1 -1
  17. package/dist/amxIdSystem.js +1 -1
  18. package/dist/appierAnalyticsAdapter.js +1 -1
  19. package/dist/appnexusBidAdapter.js +1 -1
  20. package/dist/arcspanRtdProvider.js +1 -0
  21. package/dist/asoBidAdapter.js +1 -1
  22. package/dist/axonixBidAdapter.js +1 -1
  23. package/dist/bidglassBidAdapter.js +1 -1
  24. package/dist/big-richmediaBidAdapter.js +1 -1
  25. package/dist/bliinkBidAdapter.js +1 -1
  26. package/dist/bridgewellBidAdapter.js +1 -1
  27. package/dist/brightMountainMediaBidAdapter.js +1 -1
  28. package/dist/carodaBidAdapter.js +1 -1
  29. package/dist/chtnwBidAdapter.js +1 -1
  30. package/dist/concertBidAdapter.js +1 -1
  31. package/dist/connectadBidAdapter.js +1 -1
  32. package/dist/consentManagement.js +1 -1
  33. package/dist/consumableBidAdapter.js +1 -1
  34. package/dist/conversantBidAdapter.js +1 -1
  35. package/dist/craftBidAdapter.js +1 -1
  36. package/dist/criteoBidAdapter.js +1 -1
  37. package/dist/cwireBidAdapter.js +1 -1
  38. package/dist/dspxBidAdapter.js +1 -1
  39. package/dist/emx_digitalBidAdapter.js +1 -1
  40. package/dist/eplanningBidAdapter.js +1 -1
  41. package/dist/feedadBidAdapter.js +1 -1
  42. package/dist/finativeBidAdapter.js +1 -1
  43. package/dist/glimpseBidAdapter.js +1 -1
  44. package/dist/gmosspBidAdapter.js +1 -1
  45. package/dist/goldbachBidAdapter.js +1 -1
  46. package/dist/gridBidAdapter.js +1 -1
  47. package/dist/gridNMBidAdapter.js +1 -1
  48. package/dist/gumgumBidAdapter.js +1 -1
  49. package/dist/h12mediaBidAdapter.js +1 -1
  50. package/dist/hadronIdSystem.js +1 -1
  51. package/dist/holidBidAdapter.js +1 -1
  52. package/dist/id5IdSystem.js +1 -1
  53. package/dist/improvedigitalBidAdapter.js +1 -1
  54. package/dist/inmarBidAdapter.js +1 -1
  55. package/dist/insticatorBidAdapter.js +1 -1
  56. package/dist/ixBidAdapter.js +1 -1
  57. package/dist/justpremiumBidAdapter.js +1 -1
  58. package/dist/kargoBidAdapter.js +1 -1
  59. package/dist/konduitAnalyticsAdapter.js +1 -1
  60. package/dist/kueezBidAdapter.js +1 -1
  61. package/dist/kueezRtbBidAdapter.js +1 -1
  62. package/dist/lassoBidAdapter.js +1 -1
  63. package/dist/lifestreetBidAdapter.js +1 -1
  64. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  65. package/dist/logicadBidAdapter.js +1 -1
  66. package/dist/loglyliftBidAdapter.js +1 -1
  67. package/dist/lotamePanoramaIdSystem.js +1 -1
  68. package/dist/magniteAnalyticsAdapter.js +1 -1
  69. package/dist/malltvAnalyticsAdapter.js +1 -1
  70. package/dist/marsmediaBidAdapter.js +1 -1
  71. package/dist/mediafuseBidAdapter.js +1 -1
  72. package/dist/mediasquareBidAdapter.js +1 -1
  73. package/dist/mgidBidAdapter.js +1 -1
  74. package/dist/minutemediaBidAdapter.js +1 -1
  75. package/dist/nextMillenniumBidAdapter.js +1 -1
  76. package/dist/nexx360BidAdapter.js +1 -1
  77. package/dist/not-for-prod/prebid.js +140 -149
  78. package/dist/oguryBidAdapter.js +1 -1
  79. package/dist/onetagBidAdapter.js +1 -1
  80. package/dist/ooloAnalyticsAdapter.js +1 -1
  81. package/dist/openxBidAdapter.js +1 -1
  82. package/dist/ortbConverter.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 +1 -1
  88. package/dist/prebidServerBidAdapter.js +1 -1
  89. package/dist/priceFloors.js +1 -1
  90. package/dist/publinkIdSystem.js +1 -1
  91. package/dist/pubmaticBidAdapter.js +1 -1
  92. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  93. package/dist/pulsepointBidAdapter.js +1 -1
  94. package/dist/pxyzBidAdapter.js +1 -1
  95. package/dist/quantcastBidAdapter.js +1 -1
  96. package/dist/readpeakBidAdapter.js +1 -1
  97. package/dist/relaidoBidAdapter.js +1 -1
  98. package/dist/rhythmoneBidAdapter.js +1 -1
  99. package/dist/riseBidAdapter.js +1 -1
  100. package/dist/rubiconAnalyticsAdapter.js +1 -1
  101. package/dist/rubiconBidAdapter.js +1 -1
  102. package/dist/seedingAllianceBidAdapter.js +1 -1
  103. package/dist/seedtagBidAdapter.js +1 -1
  104. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  105. package/dist/sharethroughBidAdapter.js +1 -1
  106. package/dist/shinezBidAdapter.js +1 -1
  107. package/dist/smaatoBidAdapter.js +1 -1
  108. package/dist/smartadserverBidAdapter.js +1 -1
  109. package/dist/smartxBidAdapter.js +1 -1
  110. package/dist/smartytechBidAdapter.js +1 -1
  111. package/dist/smilewantedBidAdapter.js +1 -1
  112. package/dist/sonobiBidAdapter.js +1 -1
  113. package/dist/sovrnAnalyticsAdapter.js +1 -1
  114. package/dist/sovrnBidAdapter.js +1 -1
  115. package/dist/sspBCBidAdapter.js +1 -1
  116. package/dist/sublimeBidAdapter.js +1 -1
  117. package/dist/synacormediaBidAdapter.js +1 -1
  118. package/dist/taboolaBidAdapter.js +1 -1
  119. package/dist/targetVideoBidAdapter.js +1 -1
  120. package/dist/teadsBidAdapter.js +1 -1
  121. package/dist/trionBidAdapter.js +1 -1
  122. package/dist/tripleliftBidAdapter.js +1 -1
  123. package/dist/ttdBidAdapter.js +1 -1
  124. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  125. package/dist/uid2IdSystem.js +1 -1
  126. package/dist/underdogmediaBidAdapter.js +1 -1
  127. package/dist/undertoneBidAdapter.js +1 -1
  128. package/dist/vidazooBidAdapter.js +1 -1
  129. package/dist/videobyteBidAdapter.js +1 -1
  130. package/dist/visxBidAdapter.js +1 -1
  131. package/dist/vuukleBidAdapter.js +1 -1
  132. package/dist/widespaceBidAdapter.js +1 -1
  133. package/dist/winrBidAdapter.js +1 -1
  134. package/dist/yahoosspBidAdapter.js +1 -1
  135. package/dist/yieldmoBidAdapter.js +1 -1
  136. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  137. package/dist/zeta_global_sspBidAdapter.js +1 -1
  138. package/dist/zeusPrimeRtdProvider.js +4 -14
  139. package/integrationExamples/gpt/hello_world.html +0 -0
  140. package/libraries/ortbConverter/processors/default.js +19 -1
  141. package/modules/.submodules.json +1 -0
  142. package/modules/admaticBidAdapter.js +2 -1
  143. package/modules/admixerBidAdapter.js +26 -4
  144. package/modules/adnuntiusBidAdapter.js +36 -38
  145. package/modules/adyoulikeBidAdapter.js +2 -0
  146. package/modules/arcspanRtdProvider.js +73 -0
  147. package/modules/arcspanRtdProvider.md +11 -0
  148. package/modules/bliinkBidAdapter.js +1 -1
  149. package/modules/consentManagement.js +33 -5
  150. package/modules/consumableBidAdapter.js +20 -2
  151. package/modules/criteoBidAdapter.js +1 -1
  152. package/modules/cwireBidAdapter.js +169 -242
  153. package/modules/cwireBidAdapter.md +15 -14
  154. package/modules/emx_digitalBidAdapter.js +9 -2
  155. package/modules/hadronIdSystem.js +37 -32
  156. package/modules/holidBidAdapter.js +9 -4
  157. package/modules/kargoBidAdapter.js +5 -1
  158. package/modules/lotamePanoramaIdSystem.js +9 -1
  159. package/modules/nextMillenniumBidAdapter.js +19 -9
  160. package/modules/nexx360BidAdapter.js +1 -2
  161. package/modules/onetagBidAdapter.js +12 -1
  162. package/modules/openxBidAdapter.js +5 -0
  163. package/modules/outbrainBidAdapter.js +103 -6
  164. package/modules/permutiveRtdProvider.js +17 -12
  165. package/modules/prebidServerBidAdapter/index.js +14 -1
  166. package/modules/prebidServerBidAdapter/ortbConverter.js +1 -1
  167. package/modules/priceFloors.js +7 -8
  168. package/modules/pulsepointBidAdapter.js +2 -0
  169. package/modules/seedingAllianceBidAdapter.js +129 -116
  170. package/modules/smartadserverBidAdapter.js +39 -28
  171. package/modules/smartyadsBidAdapter.md +9 -0
  172. package/modules/smartytechBidAdapter.js +67 -10
  173. package/modules/smartytechBidAdapter.md +44 -33
  174. package/modules/sonobiBidAdapter.js +17 -10
  175. package/modules/taboolaBidAdapter.js +2 -1
  176. package/modules/tripleliftBidAdapter.js +4 -0
  177. package/modules/vidazooBidAdapter.js +56 -22
  178. package/modules/zeta_global_sspBidAdapter.js +15 -0
  179. package/modules/zeusPrimeRtdProvider.js +3 -323
  180. package/modules/zeusPrimeRtdProvider.md +3 -0
  181. package/package.json +1 -1
  182. package/src/adloader.js +2 -1
  183. package/src/auction.js +2 -11
  184. package/src/prebid.js +8 -0
  185. package/src/utils/cpm.js +17 -0
  186. package/test/spec/modules/admixerBidAdapter_spec.js +140 -60
  187. package/test/spec/modules/adnuntiusBidAdapter_spec.js +120 -120
  188. package/test/spec/modules/adyoulikeBidAdapter_spec.js +3 -0
  189. package/test/spec/modules/arcspanRtdProvider_spec.js +187 -0
  190. package/test/spec/modules/bliinkBidAdapter_spec.js +7 -7
  191. package/test/spec/modules/consentManagement_spec.js +49 -1
  192. package/test/spec/modules/consumableBidAdapter_spec.js +46 -0
  193. package/test/spec/modules/cwireBidAdapter_spec.js +249 -335
  194. package/test/spec/modules/emx_digitalBidAdapter_spec.js +30 -1
  195. package/test/spec/modules/hadronIdSystem_spec.js +4 -6
  196. package/test/spec/modules/holidBidAdapter_spec.js +29 -0
  197. package/test/spec/modules/kargoBidAdapter_spec.js +32 -0
  198. package/test/spec/modules/lotamePanoramaIdSystem_spec.js +16 -10
  199. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +14 -2
  200. package/test/spec/modules/nexx360BidAdapter_spec.js +0 -4
  201. package/test/spec/modules/onetagBidAdapter_spec.js +43 -0
  202. package/test/spec/modules/openxBidAdapter_spec.js +41 -0
  203. package/test/spec/modules/openxOrtbBidAdapter_spec.js +41 -0
  204. package/test/spec/modules/outbrainBidAdapter_spec.js +182 -18
  205. package/test/spec/modules/prebidServerBidAdapter_spec.js +138 -0
  206. package/test/spec/modules/pulsepointBidAdapter_spec.js +11 -1
  207. package/test/spec/modules/seedingAllianceAdapter_spec.js +66 -23
  208. package/test/spec/modules/smartadserverBidAdapter_spec.js +116 -5
  209. package/test/spec/modules/smartytechBidAdapter_spec.js +172 -14
  210. package/test/spec/modules/sonobiBidAdapter_spec.js +2 -1
  211. package/test/spec/modules/taboolaBidAdapter_spec.js +12 -3
  212. package/test/spec/modules/tripleliftBidAdapter_spec.js +13 -0
  213. package/test/spec/modules/userId_spec.js +19 -14
  214. package/test/spec/modules/vidazooBidAdapter_spec.js +61 -22
  215. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +8 -0
  216. package/test/spec/ortbConverter/default_processors_spec.js +23 -0
  217. package/test/spec/unit/pbjs_api_spec.js +14 -0
  218. package/test/spec/unit/utils/cpm_spec.js +64 -0
  219. package/test/spec/modules/zeusPrimeRtdProvider_spec.js +0 -410
@@ -85,11 +85,12 @@ export const spec = {
85
85
  }
86
86
 
87
87
  const syncs = []
88
+ const bidders = getBidders(serverResponse)
88
89
 
89
- if (optionsType.iframeEnabled) {
90
+ if (optionsType.iframeEnabled && bidders) {
90
91
  const queryParams = []
91
92
 
92
- queryParams.push('bidders=' + getBidders(serverResponse))
93
+ queryParams.push('bidders=' + bidders)
93
94
  queryParams.push('gdpr=' + +gdprConsent.gdprApplies)
94
95
  queryParams.push('gdpr_consent=' + gdprConsent.consentString)
95
96
  queryParams.push('usp_consent=' + (uspConsent || ''))
@@ -107,6 +108,8 @@ export const spec = {
107
108
 
108
109
  return syncs
109
110
  }
111
+
112
+ return []
110
113
  },
111
114
  }
112
115
 
@@ -136,10 +139,12 @@ function getImp(bid) {
136
139
 
137
140
  function getBidders(serverResponse) {
138
141
  const bidders = serverResponse
139
- .map((res) => Object.keys(res.body.ext.responsetimemillis))
142
+ .map((res) => Object.keys(res.body.ext.responsetimemillis || []))
140
143
  .flat(1)
141
144
 
142
- return encodeURIComponent(JSON.stringify([...new Set(bidders)]))
145
+ if (bidders.length) {
146
+ return encodeURIComponent(JSON.stringify([...new Set(bidders)]))
147
+ }
143
148
  }
144
149
 
145
150
  function addWurl(auctionId, adId, wurl) {
@@ -116,7 +116,11 @@ export const spec = {
116
116
  };
117
117
 
118
118
  if (meta.mediaType == VIDEO) {
119
- bidResponse.vastXml = adUnit.adm;
119
+ if (adUnit.admUrl) {
120
+ bidResponse.vastUrl = adUnit.admUrl;
121
+ } else {
122
+ bidResponse.vastXml = adUnit.adm;
123
+ }
120
124
  }
121
125
 
122
126
  bidResponses.push(bidResponse);
@@ -29,6 +29,7 @@ const DAY_MS = 60 * 60 * 24 * 1000;
29
29
  const MISSING_CORE_CONSENT = 111;
30
30
  const GVLID = 95;
31
31
  const ID_HOST = 'id.crwdcntrl.net';
32
+ const ID_HOST_COOKIELESS = 'c.ltmsphrcl.net';
32
33
 
33
34
  export const storage = getStorageManager({gvlid: GVLID, moduleName: MODULE_NAME});
34
35
  let cookieDomain;
@@ -252,6 +253,13 @@ export const lotamePanoramaIdSubmodule = {
252
253
  usPrivacy = getFromStorage('us_privacy');
253
254
  }
254
255
 
256
+ const getRequestHost = function() {
257
+ if (navigator.userAgent && navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
258
+ return ID_HOST_COOKIELESS;
259
+ }
260
+ return ID_HOST;
261
+ }
262
+
255
263
  const resolveIdFunction = function (callback) {
256
264
  let queryParams = {};
257
265
  if (storedUserId) {
@@ -288,7 +296,7 @@ export const lotamePanoramaIdSubmodule = {
288
296
 
289
297
  const url = buildUrl({
290
298
  protocol: 'https',
291
- host: ID_HOST,
299
+ host: getRequestHost(),
292
300
  pathname: '/id',
293
301
  search: isEmpty(queryParams) ? undefined : queryParams,
294
302
  });
@@ -271,15 +271,25 @@ export const spec = {
271
271
  };
272
272
 
273
273
  function replaceUsersyncMacros(url, gdprConsent, uspConsent) {
274
- const { consentString, gdprApplies } = gdprConsent;
275
-
276
- return url.replace(
277
- '{{.GDPR}}', Number(gdprApplies)
278
- ).replace(
279
- '{{.GDPRConsent}}', consentString
280
- ).replace(
281
- '{{.USPrivacy}}', uspConsent
282
- );
274
+ const { consentString, gdprApplies } = gdprConsent || {};
275
+
276
+ if (gdprApplies) {
277
+ const gdpr = Number(gdprApplies);
278
+ url = url.replace('{{.GDPR}}', gdpr);
279
+
280
+ if (gdpr == 1 && consentString && consentString.length > 0) {
281
+ url = url.replace('{{.GDPRConsent}}', consentString);
282
+ }
283
+ } else {
284
+ url = url.replace('{{.GDPR}}', 0);
285
+ url = url.replace('{{.GDPRConsent}}', '');
286
+ }
287
+
288
+ if (uspConsent) {
289
+ url = url.replace('{{.USPrivacy}}', uspConsent);
290
+ }
291
+
292
+ return url;
283
293
  };
284
294
 
285
295
  function getAdEl(bid) {
@@ -258,14 +258,13 @@ function interpretResponse(response, req) {
258
258
  currency: respBody.cur || 'USD',
259
259
  netRevenue: true,
260
260
  ttl: 120,
261
- bidderCode: allowAlternateBidderCodes ? `n360-${bid.ssp}` : 'nexx360',
262
261
  mediaType: bid.type === 'banner' ? 'banner' : 'video',
263
262
  meta: {
264
263
  advertiserDomains: bid.adomain,
265
264
  demandSource: ssp,
266
265
  },
267
266
  };
268
- // if (bid.dealid) response.dealid = bid.dealid;
267
+ if (allowAlternateBidderCodes) response.bidderCode = `n360-${bid.ssp}`;
269
268
 
270
269
  if (response.mediaType === 'banner') {
271
270
  response.adUrl = bid.adUrl;
@@ -61,6 +61,12 @@ function buildRequests(validBidRequests, bidderRequest) {
61
61
  consentRequired: bidderRequest.gdprConsent.gdprApplies
62
62
  };
63
63
  }
64
+ if (bidderRequest && bidderRequest.gppConsent) {
65
+ payload.gppConsent = {
66
+ consentString: bidderRequest.gppConsent.gppString,
67
+ applicableSections: bidderRequest.gppConsent.applicableSections
68
+ }
69
+ }
64
70
  if (bidderRequest && bidderRequest.uspConsent) {
65
71
  payload.usPrivacy = bidderRequest.uspConsent;
66
72
  }
@@ -340,7 +346,7 @@ function getSizes(sizes) {
340
346
  return ret;
341
347
  }
342
348
 
343
- function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) {
349
+ function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) {
344
350
  let syncs = [];
345
351
  let params = '';
346
352
  if (gdprConsent) {
@@ -351,6 +357,11 @@ function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) {
351
357
  params += '&gdpr_consent=' + gdprConsent.consentString;
352
358
  }
353
359
  }
360
+ if (gppConsent) {
361
+ if (typeof gppConsent.gppString === 'string') {
362
+ params += '&gpp_consent=' + gppConsent.gppString;
363
+ }
364
+ }
354
365
  if (uspConsent && typeof uspConsent === 'string') {
355
366
  params += '&us_privacy=' + uspConsent;
356
367
  }
@@ -268,6 +268,11 @@ function buildCommonQueryParamsFromBids(bids, bidderRequest) {
268
268
  nocache: new Date().getTime()
269
269
  };
270
270
 
271
+ const userAgentClientHints = deepAccess(bidderRequest, 'ortb2.device.sua');
272
+ if (userAgentClientHints) {
273
+ defaultParams.sua = JSON.stringify(userAgentClientHints);
274
+ }
275
+
271
276
  const userDataSegments = buildFpdQueryParams('user.data', bidderRequest.ortb2);
272
277
  if (userDataSegments.length > 0) {
273
278
  defaultParams.sm = userDataSegments;
@@ -4,11 +4,13 @@
4
4
  import {
5
5
  registerBidder
6
6
  } from '../src/adapters/bidderFactory.js';
7
- import { NATIVE, BANNER } from '../src/mediaTypes.js';
8
- import { deepAccess, deepSetValue, replaceAuctionPrice, _map, isArray } from '../src/utils.js';
7
+ import { NATIVE, BANNER, VIDEO } from '../src/mediaTypes.js';
8
+ import { OUTSTREAM } from '../src/video.js';
9
+ import { deepAccess, deepSetValue, replaceAuctionPrice, _map, isArray, logWarn } from '../src/utils.js';
9
10
  import { ajax } from '../src/ajax.js';
10
11
  import { config } from '../src/config.js';
11
12
  import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
13
+ import { Renderer } from '../src/Renderer.js';
12
14
 
13
15
  const BIDDER_CODE = 'outbrain';
14
16
  const GVLID = 164;
@@ -22,11 +24,12 @@ const NATIVE_PARAMS = {
22
24
  body: { id: 4, name: 'data', type: 2 },
23
25
  cta: { id: 1, type: 12, name: 'data' }
24
26
  };
27
+ const OUTSTREAM_RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js';
25
28
 
26
29
  export const spec = {
27
30
  code: BIDDER_CODE,
28
31
  gvlid: GVLID,
29
- supportedMediaTypes: [ NATIVE, BANNER ],
32
+ supportedMediaTypes: [ NATIVE, BANNER, VIDEO ],
30
33
  isBidRequestValid: (bid) => {
31
34
  if (typeof bid.params !== 'object') {
32
35
  return false;
@@ -50,7 +53,7 @@ export const spec = {
50
53
 
51
54
  return (
52
55
  !!config.getConfig('outbrain.bidderUrl') &&
53
- !!(bid.nativeParams || bid.sizes)
56
+ (!!(bid.nativeParams || bid.sizes) || isValidVideoRequest(bid))
54
57
  );
55
58
  },
56
59
  buildRequests: (validBidRequests, bidderRequest) => {
@@ -85,6 +88,8 @@ export const spec = {
85
88
  assets: getNativeAssets(bid)
86
89
  })
87
90
  }
91
+ } else if (isVideoRequest(bid)) {
92
+ imp.video = getVideoAsset(bid);
88
93
  } else {
89
94
  imp.banner = {
90
95
  format: transformSizes(bid.sizes)
@@ -163,7 +168,12 @@ export const spec = {
163
168
  return bids.map((bid, id) => {
164
169
  const bidResponse = bidResponses[id];
165
170
  if (bidResponse) {
166
- const type = bid.nativeParams ? NATIVE : BANNER;
171
+ let type = BANNER;
172
+ if (bid.nativeParams) {
173
+ type = NATIVE;
174
+ } else if (isVideoRequest(bid)) {
175
+ type = VIDEO;
176
+ }
167
177
  const bidObject = {
168
178
  requestId: bid.bidId,
169
179
  cpm: bidResponse.price,
@@ -176,10 +186,16 @@ export const spec = {
176
186
  };
177
187
  if (type === NATIVE) {
178
188
  bidObject.native = parseNative(bidResponse);
179
- } else {
189
+ } else if (type === BANNER) {
180
190
  bidObject.ad = bidResponse.adm;
181
191
  bidObject.width = bidResponse.w;
182
192
  bidObject.height = bidResponse.h;
193
+ } else if (type === VIDEO) {
194
+ bidObject.vastXml = bidResponse.adm;
195
+ const videoContext = deepAccess(bid, 'mediaTypes.video.context');
196
+ if (videoContext === OUTSTREAM) {
197
+ bidObject.renderer = createRenderer(bid);
198
+ }
183
199
  }
184
200
  bidObject.meta = {};
185
201
  if (bidResponse.adomain && bidResponse.adomain.length > 0) {
@@ -304,6 +320,27 @@ function getNativeAssets(bid) {
304
320
  }).filter(Boolean);
305
321
  }
306
322
 
323
+ function getVideoAsset(bid) {
324
+ const sizes = flatten(bid.mediaTypes.video.playerSize);
325
+ return {
326
+ w: parseInt(sizes[0], 10),
327
+ h: parseInt(sizes[1], 10),
328
+ protocols: bid.mediaTypes.video.protocols,
329
+ playbackmethod: bid.mediaTypes.video.playbackmethod,
330
+ mimes: bid.mediaTypes.video.mimes,
331
+ skip: bid.mediaTypes.video.skip,
332
+ delivery: bid.mediaTypes.video.delivery,
333
+ api: bid.mediaTypes.video.api,
334
+ minbitrate: bid.mediaTypes.video.minbitrate,
335
+ maxbitrate: bid.mediaTypes.video.maxbitrate,
336
+ minduration: bid.mediaTypes.video.minduration,
337
+ maxduration: bid.mediaTypes.video.maxduration,
338
+ startdelay: bid.mediaTypes.video.startdelay,
339
+ placement: bid.mediaTypes.video.placement,
340
+ linearity: bid.mediaTypes.video.linearity
341
+ };
342
+ }
343
+
307
344
  /* Turn bid request sizes into ut-compatible format */
308
345
  function transformSizes(requestSizes) {
309
346
  if (!isArray(requestSizes)) {
@@ -338,3 +375,63 @@ function _getFloor(bid, type) {
338
375
  }
339
376
  return null;
340
377
  }
378
+
379
+ function isVideoRequest(bid) {
380
+ return bid.mediaType === 'video' || !!deepAccess(bid, 'mediaTypes.video');
381
+ }
382
+
383
+ function createRenderer(bid) {
384
+ let config = {};
385
+ let playerUrl = OUTSTREAM_RENDERER_URL;
386
+ let render = function (bid) {
387
+ bid.renderer.push(() => {
388
+ window.ANOutstreamVideo.renderAd({
389
+ sizes: bid.sizes,
390
+ targetId: bid.adUnitCode,
391
+ adResponse: { content: bid.vastXml }
392
+ });
393
+ });
394
+ };
395
+
396
+ let externalRenderer = deepAccess(bid, 'mediaTypes.video.renderer');
397
+ if (!externalRenderer) {
398
+ externalRenderer = deepAccess(bid, 'renderer');
399
+ }
400
+
401
+ if (externalRenderer) {
402
+ config = externalRenderer.options;
403
+ playerUrl = externalRenderer.url;
404
+ render = externalRenderer.render;
405
+ }
406
+
407
+ const renderer = Renderer.install({
408
+ id: bid.adUnitCode,
409
+ url: playerUrl,
410
+ config: config,
411
+ adUnitCode: bid.adUnitCode,
412
+ loaded: false
413
+ });
414
+ try {
415
+ renderer.setRender(render);
416
+ } catch (err) {
417
+ logWarn('Prebid Error calling setRender on renderer', err);
418
+ }
419
+ return renderer;
420
+ }
421
+
422
+ function isValidVideoRequest(bid) {
423
+ const videoAdUnit = deepAccess(bid, 'mediaTypes.video')
424
+ if (!videoAdUnit) {
425
+ return false;
426
+ }
427
+
428
+ if (!Array.isArray(videoAdUnit.playerSize)) {
429
+ return false;
430
+ }
431
+
432
+ if (videoAdUnit.context == '') {
433
+ return false;
434
+ }
435
+
436
+ return true;
437
+ }
@@ -311,16 +311,19 @@ export function isPermutiveOnPage () {
311
311
  * @return {Object}
312
312
  */
313
313
  export function getSegments (maxSegs) {
314
- const legacySegs = readSegments('_psegs').map(Number).filter(seg => seg >= 1000000).map(String)
315
- const _ppam = readSegments('_ppam')
316
- const _pcrprs = readSegments('_pcrprs')
314
+ const legacySegs = readSegments('_psegs', []).map(Number).filter(seg => seg >= 1000000).map(String)
315
+ const _ppam = readSegments('_ppam', [])
316
+ const _pcrprs = readSegments('_pcrprs', [])
317
317
 
318
318
  const segments = {
319
319
  ac: [..._pcrprs, ..._ppam, ...legacySegs],
320
- rubicon: readSegments('_prubicons'),
321
- appnexus: readSegments('_papns'),
322
- gam: readSegments('_pdfps'),
323
- ssp: readSegments('_pssps'),
320
+ rubicon: readSegments('_prubicons', []),
321
+ appnexus: readSegments('_papns', []),
322
+ gam: readSegments('_pdfps', []),
323
+ ssp: readSegments('_pssps', {
324
+ cohorts: [],
325
+ ssps: []
326
+ }),
324
327
  }
325
328
 
326
329
  for (const bidder in segments) {
@@ -338,15 +341,17 @@ export function getSegments (maxSegs) {
338
341
 
339
342
  /**
340
343
  * Gets an array of segment IDs from LocalStorage
341
- * or returns an empty array
344
+ * or return the default value provided.
345
+ * @template A
342
346
  * @param {string} key
343
- * @return {string[]|number[]}
347
+ * @param {A} defaultValue
348
+ * @return {A}
344
349
  */
345
- function readSegments (key) {
350
+ function readSegments (key, defaultValue) {
346
351
  try {
347
- return JSON.parse(storage.getDataFromLocalStorage(key) || '[]')
352
+ return JSON.parse(storage.getDataFromLocalStorage(key)) || defaultValue
348
353
  } catch (e) {
349
- return []
354
+ return defaultValue
350
355
  }
351
356
  }
352
357
 
@@ -222,10 +222,23 @@ function queueSync(bidderCodes, gdprConsent, uspConsent, gppConsent, s2sConfig)
222
222
  }
223
223
  _syncCount++;
224
224
 
225
+ let filterSettings = {};
226
+ const userSyncFilterSettings = getConfig('userSync.filterSettings');
227
+
228
+ if (userSyncFilterSettings) {
229
+ const { all, iframe, image } = userSyncFilterSettings;
230
+ const ifrm = iframe || all;
231
+ const img = image || all;
232
+
233
+ if (ifrm) filterSettings = Object.assign({ iframe: ifrm }, filterSettings);
234
+ if (img) filterSettings = Object.assign({ image: img }, filterSettings);
235
+ }
236
+
225
237
  const payload = {
226
238
  uuid: generateUUID(),
227
239
  bidders: bidderCodes,
228
- account: s2sConfig.accountId
240
+ account: s2sConfig.accountId,
241
+ filterSettings
229
242
  };
230
243
 
231
244
  let userSyncLimit = s2sConfig.userSyncLimit;
@@ -47,7 +47,7 @@ const PBS_CONVERTER = ortbConverter({
47
47
  request.tmax = s2sBidRequest.s2sConfig.timeout;
48
48
  deepSetValue(request, 'source.tid', proxyBidderRequest.auctionId);
49
49
 
50
- [request.app, request.site].forEach(section => {
50
+ [request.app, request.dooh, request.site].forEach(section => {
51
51
  if (section && !section.publisher?.id) {
52
52
  deepSetValue(section, 'publisher.id', s2sBidRequest.s2sConfig.accountId);
53
53
  }
@@ -28,6 +28,7 @@ import {auctionManager} from '../src/auctionManager.js';
28
28
  import {IMP, PBS, registerOrtbProcessor, REQUEST} from '../src/pbjsORTB.js';
29
29
  import {timedAuctionHook, timedBidResponseHook} from '../src/utils/perfMetrics.js';
30
30
  import {beConvertCurrency} from '../src/utils/currency.js';
31
+ import {adjustCpm} from '../src/utils/cpm.js';
31
32
 
32
33
  /**
33
34
  * @summary This Module is intended to provide users with the ability to dynamically set and enforce price floors on a per auction basis.
@@ -179,12 +180,8 @@ function generatePossibleEnumerations(arrayOfFields, delimiter) {
179
180
  /**
180
181
  * @summary If a the input bidder has a registered cpmadjustment it returns the input CPM after being adjusted
181
182
  */
182
- export function getBiddersCpmAdjustment(bidderName, inputCpm, bid, bidRequest) {
183
- const adjustmentFunction = bidderSettings.get(bidderName, 'bidCpmAdjustment');
184
- if (adjustmentFunction) {
185
- return parseFloat(adjustmentFunction(inputCpm, { ...bid, cpm: inputCpm }, bidRequest));
186
- }
187
- return parseFloat(inputCpm);
183
+ export function getBiddersCpmAdjustment(inputCpm, bid, bidRequest) {
184
+ return parseFloat(adjustCpm(inputCpm, {...bid, cpm: inputCpm}, bidRequest));
188
185
  }
189
186
 
190
187
  /**
@@ -254,7 +251,7 @@ export function getFloor(requestParams = {currency: 'USD', mediaType: '*', size:
254
251
  if (inverseFunction) {
255
252
  floorInfo.matchingFloor = inverseFunction(floorInfo.matchingFloor, bidRequest);
256
253
  } else {
257
- let cpmAdjustment = getBiddersCpmAdjustment(bidRequest.bidder, floorInfo.matchingFloor, {}, bidRequest);
254
+ let cpmAdjustment = getBiddersCpmAdjustment(floorInfo.matchingFloor, null, bidRequest);
258
255
  floorInfo.matchingFloor = cpmAdjustment ? calculateAdjustedFloor(floorInfo.matchingFloor, cpmAdjustment) : floorInfo.matchingFloor;
259
256
  }
260
257
  }
@@ -313,6 +310,8 @@ export function getFloorDataFromAdUnits(adUnits) {
313
310
  // copy over the new rules into our values object
314
311
  Object.assign(accum.values, newRules);
315
312
  }
313
+ } else if (adUnit.floors != null) {
314
+ logWarn(`adUnit '${adUnit.code}' provides an invalid \`floor\` definition, it will be ignored for floor calculations`, adUnit);
316
315
  }
317
316
  return accum;
318
317
  }, {});
@@ -737,7 +736,7 @@ export const addBidResponseHook = timedBidResponseHook('priceFloors', function a
737
736
  }
738
737
 
739
738
  // ok we got the bid response cpm in our desired currency. Now we need to run the bidders CPMAdjustment function if it exists
740
- adjustedCpm = getBiddersCpmAdjustment(bid.bidderCode, adjustedCpm, bid, matchingBidRequest);
739
+ adjustedCpm = getBiddersCpmAdjustment(adjustedCpm, bid, matchingBidRequest);
741
740
 
742
741
  // add necessary data information for analytics adapters / floor providers would possibly need
743
742
  addFloorDataToBid(floorData, floorInfo, bid, adjustedCpm);
@@ -16,6 +16,7 @@ const DEFAULT_BID_TTL = 20;
16
16
  const DEFAULT_CURRENCY = 'USD';
17
17
  const DEFAULT_NET_REVENUE = true;
18
18
  const KNOWN_PARAMS = ['cp', 'ct', 'cf', 'video', 'battr', 'bcat', 'badv', 'bidfloor'];
19
+ const DEFAULT_TMAX = 500;
19
20
 
20
21
  /**
21
22
  * PulsePoint Bid Adapter.
@@ -54,6 +55,7 @@ export const spec = {
54
55
  user: user(bidRequests[0], bidderRequest),
55
56
  regs: regs(bidderRequest),
56
57
  source: source(bidRequests[0].schain),
58
+ tmax: bidderRequest.timeout || DEFAULT_TMAX,
57
59
  };
58
60
  return {
59
61
  method: 'POST',