prebid.js 6.3.0 → 6.7.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 (157) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/gulpfile.js +87 -74
  3. package/integrationExamples/gpt/amp/creative.html +11 -33
  4. package/karma.conf.maker.js +1 -1
  5. package/modules/.submodules.json +2 -1
  6. package/modules/adbookpspBidAdapter.js +27 -10
  7. package/modules/adhashBidAdapter.js +3 -3
  8. package/modules/adkernelBidAdapter.js +148 -62
  9. package/modules/adlooxAdServerVideo.js +2 -2
  10. package/modules/adlooxAnalyticsAdapter.js +4 -4
  11. package/modules/admanBidAdapter.js +10 -4
  12. package/modules/adomikAnalyticsAdapter.js +27 -9
  13. package/modules/adqueryIdSystem.js +103 -0
  14. package/modules/adqueryIdSystem.md +35 -0
  15. package/modules/adyoulikeBidAdapter.js +13 -9
  16. package/modules/aniviewBidAdapter.js +1 -1
  17. package/modules/beopBidAdapter.js +1 -1
  18. package/modules/bidViewability.js +3 -3
  19. package/modules/bidViewabilityIO.js +3 -3
  20. package/modules/bliinkBidAdapter.js +3 -2
  21. package/modules/colossussspBidAdapter.js +12 -8
  22. package/modules/colossussspBidAdapter.md +15 -1
  23. package/modules/compassBidAdapter.js +208 -0
  24. package/modules/compassBidAdapter.md +79 -0
  25. package/modules/consentManagement.js +7 -1
  26. package/modules/consumableBidAdapter.md +1 -1
  27. package/modules/criteoBidAdapter.js +1 -1
  28. package/modules/criteoIdSystem.js +29 -7
  29. package/modules/currency.js +2 -2
  30. package/modules/dailyhuntBidAdapter.js +435 -0
  31. package/modules/dailyhuntBidAdapter.md +4 -0
  32. package/modules/docereeBidAdapter.js +10 -1
  33. package/modules/docereeBidAdapter.md +2 -0
  34. package/modules/engageyaBidAdapter.js +1 -1
  35. package/modules/feedadBidAdapter.js +2 -2
  36. package/modules/feedadBidAdapter.md +4 -2
  37. package/modules/glimpseBidAdapter.js +66 -44
  38. package/modules/gnetBidAdapter.js +3 -3
  39. package/modules/gnetBidAdapter.md +4 -4
  40. package/modules/gptPreAuction.js +55 -7
  41. package/modules/gridBidAdapter.js +4 -3
  42. package/modules/gumgumBidAdapter.js +4 -4
  43. package/modules/idImportLibrary.js +45 -8
  44. package/modules/idImportLibrary.md +4 -0
  45. package/modules/improvedigitalBidAdapter.js +42 -4
  46. package/modules/instreamTracking.js +4 -4
  47. package/modules/invibesBidAdapter.js +49 -5
  48. package/modules/invibesBidAdapter.md +2 -1
  49. package/modules/ixBidAdapter.js +53 -18
  50. package/modules/jwplayerRtdProvider.js +71 -6
  51. package/modules/jwplayerRtdProvider.md +27 -11
  52. package/modules/kargoBidAdapter.js +2 -2
  53. package/modules/limelightDigitalBidAdapter.js +2 -1
  54. package/modules/livewrappedAnalyticsAdapter.js +3 -1
  55. package/modules/livewrappedBidAdapter.js +8 -2
  56. package/modules/loglyliftBidAdapter.js +79 -0
  57. package/modules/loglyliftBidAdapter.md +55 -0
  58. package/modules/nextMillenniumBidAdapter.js +11 -7
  59. package/modules/oguryBidAdapter.js +9 -2
  60. package/modules/onetagBidAdapter.js +4 -2
  61. package/modules/optimeraRtdProvider.js +8 -1
  62. package/modules/ozoneBidAdapter.js +21 -64
  63. package/modules/pilotxBidAdapter.js +147 -0
  64. package/modules/pilotxBidAdapter.md +50 -0
  65. package/modules/proxistoreBidAdapter.js +0 -2
  66. package/modules/pubgeniusBidAdapter.js +1 -1
  67. package/modules/pubmaticAnalyticsAdapter.js +16 -0
  68. package/modules/pubxaiAnalyticsAdapter.js +17 -0
  69. package/modules/richaudienceBidAdapter.js +3 -2
  70. package/modules/riseBidAdapter.js +1 -1
  71. package/modules/rtbhouseBidAdapter.js +14 -4
  72. package/modules/rtdModule/index.js +14 -15
  73. package/modules/rubiconAnalyticsAdapter.js +3 -2
  74. package/modules/rubiconBidAdapter.js +21 -11
  75. package/modules/seedingAllianceBidAdapter.js +3 -3
  76. package/modules/sharethroughBidAdapter.js +12 -17
  77. package/modules/showheroes-bsBidAdapter.js +13 -2
  78. package/modules/synacormediaBidAdapter.js +31 -10
  79. package/modules/tappxBidAdapter.js +8 -5
  80. package/modules/teadsBidAdapter.js +1 -2
  81. package/modules/telariaBidAdapter.js +2 -2
  82. package/modules/trustxBidAdapter.js +8 -16
  83. package/modules/userId/eids.js +7 -1
  84. package/modules/userId/userId.md +8 -0
  85. package/modules/viewability.js +177 -0
  86. package/modules/viewability.md +87 -0
  87. package/modules/welectBidAdapter.js +106 -0
  88. package/modules/yieldmoBidAdapter.js +23 -5
  89. package/modules/zeta_global_sspAnalyticsAdapter.js +97 -0
  90. package/modules/zeta_global_sspAnalyticsAdapter.md +24 -0
  91. package/package.json +1 -1
  92. package/src/auction.js +2 -2
  93. package/src/config.js +27 -3
  94. package/src/hook.js +5 -1
  95. package/src/prebid.js +20 -4
  96. package/src/secureCreatives.js +3 -2
  97. package/src/utils.js +12 -1
  98. package/test/helpers/prebidGlobal.js +1 -0
  99. package/test/spec/config_spec.js +279 -0
  100. package/test/spec/modules/adbookpspBidAdapter_spec.js +17 -3
  101. package/test/spec/modules/adhashBidAdapter_spec.js +2 -2
  102. package/test/spec/modules/adlooxAnalyticsAdapter_spec.js +6 -6
  103. package/test/spec/modules/admanBidAdapter_spec.js +2 -2
  104. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +9 -1
  105. package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
  106. package/test/spec/modules/adyoulikeBidAdapter_spec.js +49 -0
  107. package/test/spec/modules/beopBidAdapter_spec.js +1 -1
  108. package/test/spec/modules/bidViewabilityIO_spec.js +2 -2
  109. package/test/spec/modules/bidViewability_spec.js +4 -4
  110. package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
  111. package/test/spec/modules/colossussspBidAdapter_spec.js +5 -2
  112. package/test/spec/modules/compassBidAdapter_spec.js +398 -0
  113. package/test/spec/modules/consentManagement_spec.js +20 -0
  114. package/test/spec/modules/criteoIdSystem_spec.js +6 -3
  115. package/test/spec/modules/dailyhuntBidAdapter_spec.js +404 -0
  116. package/test/spec/modules/docereeBidAdapter_spec.js +9 -1
  117. package/test/spec/modules/eids_spec.js +15 -0
  118. package/test/spec/modules/feedadBidAdapter_spec.js +15 -0
  119. package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
  120. package/test/spec/modules/gnetBidAdapter_spec.js +6 -6
  121. package/test/spec/modules/gptPreAuction_spec.js +177 -2
  122. package/test/spec/modules/idImportLibrary_spec.js +197 -10
  123. package/test/spec/modules/improvedigitalBidAdapter_spec.js +45 -1
  124. package/test/spec/modules/invibesBidAdapter_spec.js +119 -0
  125. package/test/spec/modules/ixBidAdapter_spec.js +112 -62
  126. package/test/spec/modules/jwplayerRtdProvider_spec.js +195 -2
  127. package/test/spec/modules/kargoBidAdapter_spec.js +1 -1
  128. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +75 -17
  129. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +22 -0
  130. package/test/spec/modules/livewrappedBidAdapter_spec.js +31 -0
  131. package/test/spec/modules/loglyliftBidAdapter_spec.js +172 -0
  132. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +9 -2
  133. package/test/spec/modules/oguryBidAdapter_spec.js +10 -2
  134. package/test/spec/modules/optimeraRtdProvider_spec.js +14 -1
  135. package/test/spec/modules/ozoneBidAdapter_spec.js +43 -31
  136. package/test/spec/modules/pilotxBidAdapter_spec.js +244 -0
  137. package/test/spec/modules/pubgeniusBidAdapter_spec.js +3 -3
  138. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
  139. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +11 -0
  140. package/test/spec/modules/realTimeDataModule_spec.js +67 -5
  141. package/test/spec/modules/richaudienceBidAdapter_spec.js +40 -0
  142. package/test/spec/modules/riseBidAdapter_spec.js +1 -1
  143. package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
  144. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +30 -0
  145. package/test/spec/modules/rubiconBidAdapter_spec.js +48 -9
  146. package/test/spec/modules/sharethroughBidAdapter_spec.js +91 -6
  147. package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
  148. package/test/spec/modules/synacormediaBidAdapter_spec.js +70 -0
  149. package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
  150. package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
  151. package/test/spec/modules/userId_spec.js +68 -19
  152. package/test/spec/modules/viewability_spec.js +280 -0
  153. package/test/spec/modules/welectBidAdapter_spec.js +211 -0
  154. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +427 -0
  155. package/test/spec/unit/pbjs_api_spec.js +3 -1
  156. package/test/test_deps.js +3 -0
  157. package/test/test_index.js +1 -3
@@ -4,16 +4,16 @@ import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
4
4
  import {config} from '../src/config.js';
5
5
  import {getPriceBucketString} from '../src/cpmBucketManager.js';
6
6
  import { Renderer } from '../src/Renderer.js';
7
+
7
8
  const BIDDER_CODE = 'ozone';
8
9
 
9
- // *** PROD ***
10
10
  const ORIGIN = 'https://elb.the-ozone-project.com' // applies only to auction & cookie
11
11
  const AUCTIONURI = '/openrtb2/auction';
12
12
  const OZONECOOKIESYNC = '/static/load-cookie.html';
13
13
  const OZONE_RENDERER_URL = 'https://prebid.the-ozone-project.com/ozone-renderer.js';
14
14
  const ORIGIN_DEV = 'https://test.ozpr.net';
15
15
 
16
- const OZONEVERSION = '2.6.0';
16
+ const OZONEVERSION = '2.7.0';
17
17
  export const spec = {
18
18
  gvlid: 524,
19
19
  aliases: [{code: 'lmc', gvlid: 524}, {code: 'newspassid', gvlid: 524}],
@@ -52,6 +52,7 @@ export const spec = {
52
52
  this.propertyBag.whitelabel.auctionUrl = bidderConfig.endpointOverride.origin + AUCTIONURI;
53
53
  this.propertyBag.whitelabel.cookieSyncUrl = bidderConfig.endpointOverride.origin + OZONECOOKIESYNC;
54
54
  }
55
+
55
56
  if (arr.hasOwnProperty('renderer')) {
56
57
  if (arr.renderer.match('%3A%2F%2F')) {
57
58
  this.propertyBag.whitelabel.rendererUrl = decodeURIComponent(arr['renderer']);
@@ -99,9 +100,9 @@ export const spec = {
99
100
  this.loadWhitelabelData(bid);
100
101
  logInfo('isBidRequestValid : ', config.getConfig(), bid);
101
102
  let adUnitCode = bid.adUnitCode; // adunit[n].code
102
-
103
+ let err1 = 'VALIDATION FAILED : missing {param} : siteId, placementId and publisherId are REQUIRED'
103
104
  if (!(bid.params.hasOwnProperty('placementId'))) {
104
- logError('VALIDATION FAILED : missing placementId : siteId, placementId and publisherId are REQUIRED', adUnitCode);
105
+ logError(err1.replace('{param}', 'placementId'), adUnitCode);
105
106
  return false;
106
107
  }
107
108
  if (!this.isValidPlacementId(bid.params.placementId)) {
@@ -109,7 +110,7 @@ export const spec = {
109
110
  return false;
110
111
  }
111
112
  if (!(bid.params.hasOwnProperty('publisherId'))) {
112
- logError('VALIDATION FAILED : missing publisherId : siteId, placementId and publisherId are REQUIRED', adUnitCode);
113
+ logError(err1.replace('{param}', 'publisherId'), adUnitCode);
113
114
  return false;
114
115
  }
115
116
  if (!(bid.params.publisherId).toString().match(/^[a-zA-Z0-9\-]{12}$/)) {
@@ -117,7 +118,7 @@ export const spec = {
117
118
  return false;
118
119
  }
119
120
  if (!(bid.params.hasOwnProperty('siteId'))) {
120
- logError('VALIDATION FAILED : missing siteId : siteId, placementId and publisherId are REQUIRED', adUnitCode);
121
+ logError(err1.replace('{param}', 'siteId'), adUnitCode);
121
122
  return false;
122
123
  }
123
124
  if (!(bid.params.siteId).toString().match(/^[0-9]{10}$/)) {
@@ -173,7 +174,6 @@ export const spec = {
173
174
  let whitelabelBidder = this.propertyBag.whitelabel.bidder; // by default = ozone
174
175
  let whitelabelPrefix = this.propertyBag.whitelabel.keyPrefix;
175
176
  logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${OZONEVERSION} validBidRequests`, JSON.parse(JSON.stringify(validBidRequests)), 'bidderRequest', JSON.parse(JSON.stringify(bidderRequest)));
176
- // First check - is there any config to block this request?
177
177
  if (this.blockTheRequest()) {
178
178
  return [];
179
179
  }
@@ -191,7 +191,6 @@ export const spec = {
191
191
  let ozoneRequest = {}; // we only want to set specific properties on this, not validBidRequests[0].params
192
192
  delete ozoneRequest.test; // don't allow test to be set in the config - ONLY use $_GET['pbjs_debug']
193
193
 
194
- // First party data module : look for ortb2 in setconfig & set the User object. NOTE THAT this should happen before we set the consentString
195
194
  let fpd = config.getConfig('ortb2');
196
195
  if (fpd && deepAccess(fpd, 'user')) {
197
196
  logInfo('added FPD user object');
@@ -203,14 +202,13 @@ export const spec = {
203
202
  const isTestMode = getParams[wlOztestmodeKey] || null; // this can be any string, it's used for testing ads
204
203
  ozoneRequest.device = {'w': window.innerWidth, 'h': window.innerHeight};
205
204
  let placementIdOverrideFromGetParam = this.getPlacementIdOverrideFromGetParam(); // null or string
206
- // build the array of params to attach to `imp`
205
+ let schain = null;
207
206
  let tosendtags = validBidRequests.map(ozoneBidRequest => {
208
207
  var obj = {};
209
208
  let placementId = placementIdOverrideFromGetParam || this.getPlacementId(ozoneBidRequest); // prefer to use a valid override param, else the bidRequest placement Id
210
209
  obj.id = ozoneBidRequest.bidId; // this causes an error if we change it to something else, even if you update the bidRequest object: "WARNING: Bidder ozone made bid for unknown request ID: mb7953.859498327448. Ignoring."
211
210
  obj.tagid = placementId;
212
211
  obj.secure = window.location.protocol === 'https:' ? 1 : 0;
213
- // is there a banner (or nothing declared, so banner is the default)?
214
212
  let arrBannerSizes = [];
215
213
  if (!ozoneBidRequest.hasOwnProperty('mediaTypes')) {
216
214
  if (ozoneBidRequest.hasOwnProperty('sizes')) {
@@ -226,13 +224,11 @@ export const spec = {
226
224
  }
227
225
  if (ozoneBidRequest.mediaTypes.hasOwnProperty(VIDEO)) {
228
226
  logInfo('openrtb 2.5 compliant video');
229
- // examine all the video attributes in the config, and either put them into obj.video if allowed by IAB2.5 or else in to obj.video.ext
230
227
  if (typeof ozoneBidRequest.mediaTypes[VIDEO] == 'object') {
231
228
  let childConfig = deepAccess(ozoneBidRequest, 'params.video', {});
232
229
  obj.video = this.unpackVideoConfigIntoIABformat(ozoneBidRequest.mediaTypes[VIDEO], childConfig);
233
230
  obj.video = this.addVideoDefaults(obj.video, ozoneBidRequest.mediaTypes[VIDEO], childConfig);
234
231
  }
235
- // we need to duplicate some of the video values
236
232
  let wh = getWidthAndHeightFromVideoObject(obj.video);
237
233
  logInfo('setting video object from the mediaTypes.video element: ' + obj.id + ':', obj.video, 'wh=', wh);
238
234
  if (wh && typeof wh === 'object') {
@@ -249,12 +245,10 @@ export const spec = {
249
245
  logWarn('cannot set w, h & format values for video; the config is not right');
250
246
  }
251
247
  }
252
- // Native integration is not complete yet
253
248
  if (ozoneBidRequest.mediaTypes.hasOwnProperty(NATIVE)) {
254
249
  obj.native = ozoneBidRequest.mediaTypes[NATIVE];
255
250
  logInfo('setting native object from the mediaTypes.native element: ' + obj.id + ':', obj.native);
256
251
  }
257
- // is the publisher specifying floors, and is the floors module enabled?
258
252
  if (ozoneBidRequest.hasOwnProperty('getFloor')) {
259
253
  logInfo('This bidRequest object has property: getFloor');
260
254
  obj.floor = this.getFloorObjectForAuction(ozoneBidRequest);
@@ -264,7 +258,6 @@ export const spec = {
264
258
  }
265
259
  }
266
260
  if (arrBannerSizes.length > 0) {
267
- // build the banner request using banner sizes we found in either possible location:
268
261
  obj.banner = {
269
262
  topframe: 1,
270
263
  w: arrBannerSizes[0][0] || 0,
@@ -274,11 +267,8 @@ export const spec = {
274
267
  })
275
268
  };
276
269
  }
277
- // these 3 MUST exist - we check them in the validation method
278
270
  obj.placementId = placementId;
279
- // build the imp['ext'] object - NOTE - Dont obliterate anything that' already in obj.ext
280
271
  deepSetValue(obj, 'ext.prebid', {'storedrequest': {'id': placementId}});
281
- // obj.ext = {'prebid': {'storedrequest': {'id': placementId}}};
282
272
  obj.ext[whitelabelBidder] = {};
283
273
  obj.ext[whitelabelBidder].adUnitCode = ozoneBidRequest.adUnitCode; // eg. 'mpu'
284
274
  obj.ext[whitelabelBidder].transactionId = ozoneBidRequest.transactionId; // this is the transactionId PER adUnit, common across bidders for this unit
@@ -298,33 +288,30 @@ export const spec = {
298
288
  }
299
289
  }
300
290
  if (fpd && deepAccess(fpd, 'site')) {
301
- // attach the site fpd into exactly : imp[n].ext.[whitelabel].customData.0.targeting
302
- logInfo('added FPD site object');
291
+ logInfo('added fpd.site');
303
292
  if (deepAccess(obj, 'ext.' + whitelabelBidder + '.customData.0.targeting', false)) {
304
293
  obj.ext[whitelabelBidder].customData[0].targeting = Object.assign(obj.ext[whitelabelBidder].customData[0].targeting, fpd.site);
305
- // let keys = getKeys(fpd.site);
306
- // for (let i = 0; i < keys.length; i++) {
307
- // obj.ext[whitelabelBidder].customData[0].targeting[keys[i]] = fpd.site[keys[i]];
308
- // }
309
294
  } else {
310
295
  deepSetValue(obj, 'ext.' + whitelabelBidder + '.customData.0.targeting', fpd.site);
311
296
  }
312
297
  }
298
+ if (!schain && deepAccess(ozoneBidRequest, 'schain')) {
299
+ schain = ozoneBidRequest.schain;
300
+ }
313
301
  return obj;
314
302
  });
315
303
 
316
- // in v 2.0.0 we moved these outside of the individual ad slots
317
304
  let extObj = {};
318
305
  extObj[whitelabelBidder] = {};
319
306
  extObj[whitelabelBidder][whitelabelPrefix + '_pb_v'] = OZONEVERSION;
320
307
  extObj[whitelabelBidder][whitelabelPrefix + '_rw'] = placementIdOverrideFromGetParam ? 1 : 0;
321
308
  if (validBidRequests.length > 0) {
322
309
  let userIds = this.cookieSyncBag.userIdObject; // 2021-01-06 - slight optimisation - we've already found this info
323
- // let userIds = this.findAllUserIds(validBidRequests[0]);
324
310
  if (userIds.hasOwnProperty('pubcid')) {
325
311
  extObj[whitelabelBidder].pubcid = userIds.pubcid;
326
312
  }
327
313
  }
314
+
328
315
  extObj[whitelabelBidder].pv = this.getPageId(); // attach the page ID that will be common to all auciton calls for this page if refresh() is called
329
316
  let ozOmpFloorDollars = this.getWhitelabelConfigItem('ozone.oz_omp_floor'); // valid only if a dollar value (typeof == 'number')
330
317
  logInfo(`${whitelabelPrefix}_omp_floor dollar value = `, ozOmpFloorDollars);
@@ -340,14 +327,12 @@ export const spec = {
340
327
  logInfo('setting aliases object');
341
328
  extObj.prebid = {aliases: {'ozone': whitelabelBidder}};
342
329
  }
343
- // 20210413 - adding a set of GET params to pass to auction
344
330
  if (getParams.hasOwnProperty('ozf')) { extObj[whitelabelBidder]['ozf'] = getParams.ozf == 'true' || getParams.ozf == 1 ? 1 : 0; }
345
331
  if (getParams.hasOwnProperty('ozpf')) { extObj[whitelabelBidder]['ozpf'] = getParams.ozpf == 'true' || getParams.ozpf == 1 ? 1 : 0; }
346
332
  if (getParams.hasOwnProperty('ozrp') && getParams.ozrp.match(/^[0-3]$/)) { extObj[whitelabelBidder]['ozrp'] = parseInt(getParams.ozrp); }
347
333
  if (getParams.hasOwnProperty('ozip') && getParams.ozip.match(/^\d+$/)) { extObj[whitelabelBidder]['ozip'] = parseInt(getParams.ozip); }
348
334
  if (this.propertyBag.endpointOverride != null) { extObj[whitelabelBidder]['origin'] = this.propertyBag.endpointOverride; }
349
335
 
350
- // extObj.ortb2 = config.getConfig('ortb2'); // original test location
351
336
  var userExtEids = this.generateEids(validBidRequests); // generate the UserIDs in the correct format for UserId module
352
337
 
353
338
  ozoneRequest.site = {
@@ -357,7 +342,6 @@ export const spec = {
357
342
  };
358
343
  ozoneRequest.test = (getParams.hasOwnProperty('pbjs_debug') && getParams['pbjs_debug'] === 'true') ? 1 : 0;
359
344
 
360
- // this should come as late as possible so it overrides any user.ext.consent value
361
345
  if (bidderRequest && bidderRequest.gdprConsent) {
362
346
  logInfo('ADDING GDPR info');
363
347
  let apiVersion = deepAccess(bidderRequest, 'gdprConsent.apiVersion', 1);
@@ -376,21 +360,22 @@ export const spec = {
376
360
  } else {
377
361
  logInfo('WILL NOT ADD CCPA info; no bidderRequest.uspConsent.');
378
362
  }
363
+ if (schain) { // we set this while iterating over the bids
364
+ logInfo('schain found');
365
+ deepSetValue(ozoneRequest, 'source.ext.schain', schain);
366
+ }
379
367
 
380
- // this is for 2.2.1
381
- // coppa compliance
382
368
  if (config.getConfig('coppa') === true) {
383
369
  deepSetValue(ozoneRequest, 'regs.coppa', 1);
384
370
  }
385
371
 
386
- // return the single request object OR the array:
387
372
  if (singleRequest) {
388
373
  logInfo('buildRequests starting to generate response for a single request');
389
374
  ozoneRequest.id = bidderRequest.auctionId; // Unique ID of the bid request, provided by the exchange.
390
375
  ozoneRequest.auctionId = bidderRequest.auctionId; // not sure if this should be here?
391
376
  ozoneRequest.imp = tosendtags;
392
377
  ozoneRequest.ext = extObj;
393
- ozoneRequest.source = {'tid': bidderRequest.auctionId}; // RTB 2.5 : tid is Transaction ID that must be common across all participants in this bid request (e.g., potentially multiple exchanges).
378
+ deepSetValue(ozoneRequest, 'source.tid', bidderRequest.auctionId);// RTB 2.5 : tid is Transaction ID that must be common across all participants in this bid request (e.g., potentially multiple exchanges).
394
379
  deepSetValue(ozoneRequest, 'user.ext.eids', userExtEids);
395
380
  var ret = {
396
381
  method: 'POST',
@@ -403,7 +388,6 @@ export const spec = {
403
388
  logInfo(`buildRequests going to return for single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, ret);
404
389
  return ret;
405
390
  }
406
- // not single request - pull apart the tosendtags array & return an array of objects each containing one element in the imp array.
407
391
  let arrRet = tosendtags.map(imp => {
408
392
  logInfo('buildRequests starting to generate non-single response, working on imp : ', imp);
409
393
  let ozoneRequestSingle = Object.assign({}, ozoneRequest);
@@ -412,7 +396,7 @@ export const spec = {
412
396
  ozoneRequestSingle.auctionId = imp.ext[whitelabelBidder].transactionId; // not sure if this should be here?
413
397
  ozoneRequestSingle.imp = [imp];
414
398
  ozoneRequestSingle.ext = extObj;
415
- ozoneRequestSingle.source = {'tid': imp.ext[whitelabelBidder].transactionId};
399
+ deepSetValue(ozoneRequestSingle, 'source.tid', imp.ext[whitelabelBidder].transactionId);// RTB 2.5 : tid is Transaction ID that must be common across all participants in this bid request (e.g., potentially multiple exchanges).
416
400
  deepSetValue(ozoneRequestSingle, 'user.ext.eids', userExtEids);
417
401
  logInfo('buildRequests RequestSingle (for non-single) = ', ozoneRequestSingle);
418
402
  return {
@@ -477,7 +461,6 @@ export const spec = {
477
461
  logInfo(`interpretResponse time: ${startTime} . Time between buildRequests done and interpretResponse start was ${startTime - this.propertyBag.buildRequestsEnd}ms`);
478
462
  logInfo(`serverResponse, request`, JSON.parse(JSON.stringify(serverResponse)), JSON.parse(JSON.stringify(request)));
479
463
  serverResponse = serverResponse.body || {};
480
- // note that serverResponse.id value is the auction_id we might want to use for reporting reasons.
481
464
  if (!serverResponse.hasOwnProperty('seatbid')) {
482
465
  return [];
483
466
  }
@@ -492,7 +475,6 @@ export const spec = {
492
475
  }
493
476
  logInfo('enhancedAdserverTargeting', enhancedAdserverTargeting);
494
477
 
495
- // 2021-03-05 - comment this out for a build without adding adid to the response
496
478
  serverResponse.seatbid = injectAdIdsIntoAllBidResponses(serverResponse.seatbid); // we now make sure that each bid in the bidresponse has a unique (within page) adId attribute.
497
479
 
498
480
  serverResponse.seatbid = this.removeSingleBidderMultipleBids(serverResponse.seatbid);
@@ -508,7 +490,6 @@ export const spec = {
508
490
  logInfo(`seatbid:${i}, bid:${j} Going to set default w h for seatbid/bidRequest`, sb.bid[j], thisRequestBid);
509
491
  const {defaultWidth, defaultHeight} = defaultSize(thisRequestBid);
510
492
  let thisBid = ozoneAddStandardProperties(sb.bid[j], defaultWidth, defaultHeight);
511
- // prebid 4.0 compliance
512
493
  thisBid.meta = {advertiserDomains: thisBid.adomain || []};
513
494
  let videoContext = null;
514
495
  let isVideo = false;
@@ -527,11 +508,9 @@ export const spec = {
527
508
  let adserverTargeting = {};
528
509
  if (enhancedAdserverTargeting) {
529
510
  let allBidsForThisBidid = ozoneGetAllBidsForBidId(thisBid.bidId, serverResponse.seatbid);
530
- // add all the winning & non-winning bids for this bidId:
531
511
  logInfo('Going to iterate allBidsForThisBidId', allBidsForThisBidid);
532
512
  Object.keys(allBidsForThisBidid).forEach((bidderName, index, ar2) => {
533
513
  logInfo(`adding adserverTargeting for ${bidderName} for bidId ${thisBid.bidId}`);
534
- // let bidderName = bidderNameWH.split('_')[0];
535
514
  adserverTargeting[whitelabelPrefix + '_' + bidderName] = bidderName;
536
515
  adserverTargeting[whitelabelPrefix + '_' + bidderName + '_crid'] = String(allBidsForThisBidid[bidderName].crid);
537
516
  adserverTargeting[whitelabelPrefix + '_' + bidderName + '_adv'] = String(allBidsForThisBidid[bidderName].adomain);
@@ -565,7 +544,6 @@ export const spec = {
565
544
  logInfo(`${whitelabelBidder}.enhancedAdserverTargeting is set to false, so no per-bid keys will be sent to adserver.`);
566
545
  }
567
546
  }
568
- // also add in the winning bid, to be sent to dfp
569
547
  let {seat: winningSeat, bid: winningBid} = ozoneGetWinnerForRequestBid(thisBid.bidId, serverResponse.seatbid);
570
548
  adserverTargeting[whitelabelPrefix + '_auc_id'] = String(request.bidderRequest.auctionId);
571
549
  adserverTargeting[whitelabelPrefix + '_winner'] = String(winningSeat);
@@ -594,14 +572,14 @@ export const spec = {
594
572
  /**
595
573
  * Use this to get all config values
596
574
  * Now it's getting complicated with whitelabeling, this simplifies the code for getting config values.
597
- * eg. to get ozone.oz_omp_floor you just send '_omp_floor'
575
+ * eg. to get whitelabelled version you just sent the ozone default string like ozone.oz_omp_floor
598
576
  * @param ozoneVersion string like 'ozone.oz_omp_floor'
599
577
  * @return {string|object}
600
578
  */
601
579
  getWhitelabelConfigItem(ozoneVersion) {
602
580
  if (this.propertyBag.whitelabel.bidder == 'ozone') { return config.getConfig(ozoneVersion); }
603
581
  let whitelabelledSearch = ozoneVersion.replace('ozone', this.propertyBag.whitelabel.bidder);
604
- whitelabelledSearch = ozoneVersion.replace('oz_', this.propertyBag.whitelabel.keyPrefix + '_');
582
+ whitelabelledSearch = whitelabelledSearch.replace('oz_', this.propertyBag.whitelabel.keyPrefix + '_');
605
583
  return config.getConfig(whitelabelledSearch);
606
584
  },
607
585
  /**
@@ -631,8 +609,6 @@ export const spec = {
631
609
  }
632
610
  return ret;
633
611
  },
634
- // see http://prebid.org/dev-docs/bidder-adaptor.html#registering-user-syncs
635
- // us privacy: https://docs.prebid.org/dev-docs/modules/consentManagementUsp.html
636
612
  getUserSyncs(optionsType, serverResponse, gdprConsent, usPrivacy) {
637
613
  logInfo('getUserSyncs optionsType', optionsType, 'serverResponse', serverResponse, 'gdprConsent', gdprConsent, 'usPrivacy', usPrivacy, 'cookieSyncBag', this.cookieSyncBag);
638
614
  if (!serverResponse || serverResponse.length === 0) {
@@ -646,11 +622,6 @@ export const spec = {
646
622
  arrQueryString.push('gdpr=' + (deepAccess(gdprConsent, 'gdprApplies', false) ? '1' : '0'));
647
623
  arrQueryString.push('gdpr_consent=' + deepAccess(gdprConsent, 'consentString', ''));
648
624
  arrQueryString.push('usp_consent=' + (usPrivacy || ''));
649
- // var objKeys = Object.getOwnPropertyNames(this.cookieSyncBag.userIdObject);
650
- // for (let idx in objKeys) {
651
- // let keyname = objKeys[idx];
652
- // arrQueryString.push(keyname + '=' + this.cookieSyncBag.userIdObject[keyname]);
653
- // }
654
625
  for (let keyname in this.cookieSyncBag.userIdObject) {
655
626
  arrQueryString.push(keyname + '=' + this.cookieSyncBag.userIdObject[keyname]);
656
627
  }
@@ -704,10 +675,7 @@ export const spec = {
704
675
  */
705
676
  findAllUserIds(bidRequest) {
706
677
  var ret = {};
707
- // @todo - what is Neustar fabrick called & where to look for it? If it's a simple value then it will automatically be ok
708
- // it is not in the table 'Bidder Adapter Implementation' on https://docs.prebid.org/dev-docs/modules/userId.html#prebidjs-adapters
709
678
  let searchKeysSingle = ['pubcid', 'tdid', 'idl_env', 'criteoId', 'lotamePanoramaId', 'fabrickId'];
710
-
711
679
  if (bidRequest.hasOwnProperty('userId')) {
712
680
  for (let arrayId in searchKeysSingle) {
713
681
  let key = searchKeysSingle[arrayId];
@@ -716,7 +684,6 @@ export const spec = {
716
684
  ret[key] = bidRequest.userId[key];
717
685
  } else if (typeof (bidRequest.userId[key]) == 'object') {
718
686
  logError(`WARNING: findAllUserIds had to use first key in user object to get value for bid.userId key: ${key}. Prebid adapter should be updated.`);
719
- // fallback - get the value of the first key in the object; this is NOT desirable behaviour
720
687
  ret[key] = bidRequest.userId[key][Object.keys(bidRequest.userId[key])[0]]; // cannot use Object.values
721
688
  } else {
722
689
  logError(`failed to get string key value for userId : ${key}`);
@@ -815,7 +782,6 @@ export const spec = {
815
782
  });
816
783
  }
817
784
  },
818
- // Try to use this as the mechanism for reading GET params because it's easy to mock it for tests
819
785
  getGetParametersAsObject() {
820
786
  let items = location.search.substr(1).split('&');
821
787
  let ret = {};
@@ -831,7 +797,6 @@ export const spec = {
831
797
  * @return {boolean|*[]} true = block the request, else false
832
798
  */
833
799
  blockTheRequest() {
834
- // if there is an ozone.oz_request = false then quit now.
835
800
  let ozRequest = this.getWhitelabelConfigItem('ozone.oz_request');
836
801
  if (typeof ozRequest == 'boolean' && !ozRequest) {
837
802
  logWarn(`Will not allow auction : ${this.propertyBag.whitelabel.keyPrefix}one.${this.propertyBag.whitelabel.keyPrefix}_request is set to false`);
@@ -882,7 +847,6 @@ export const spec = {
882
847
  ret.ext[key] = objConfig[key];
883
848
  }
884
849
  }
885
- // handle ext separately, if it exists; we have probably built up an ext object already
886
850
  if (objConfig.hasOwnProperty('ext') && typeof objConfig.ext === 'object') {
887
851
  if (objConfig.hasOwnProperty('ext')) {
888
852
  ret.ext = mergeDeep(ret.ext, objConfig.ext);
@@ -906,7 +870,6 @@ export const spec = {
906
870
  * @private
907
871
  */
908
872
  _addVideoDefaults(objRet, objConfig, addIfMissing) {
909
- // add inferred values & any default values we want.
910
873
  let context = deepAccess(objConfig, 'context');
911
874
  if (context === 'outstream') {
912
875
  objRet.placement = 3;
@@ -936,8 +899,6 @@ export function injectAdIdsIntoAllBidResponses(seatbid) {
936
899
  for (let i = 0; i < seatbid.length; i++) {
937
900
  let sb = seatbid[i];
938
901
  for (let j = 0; j < sb.bid.length; j++) {
939
- // modify the bidId per-bid, so each bid has a unique adId within this response, and dfp can select one.
940
- // 2020-06 we now need a second level of ID because there might be multiple identical impid's within a seatbid!
941
902
  sb.bid[j]['adId'] = `${sb.bid[j]['impid']}-${i}-${spec.propertyBag.whitelabel.keyPrefix}-${j}`;
942
903
  }
943
904
  }
@@ -985,7 +946,6 @@ export function ozoneGetWinnerForRequestBid(requestBidId, serverResponseSeatBid)
985
946
  let thisSeat = serverResponseSeatBid[j].seat;
986
947
  for (let k = 0; k < theseBids.length; k++) {
987
948
  if (theseBids[k].impid === requestBidId) {
988
- // we've found a matching server response bid for this request bid
989
949
  if ((thisBidWinner == null) || (thisBidWinner.price < theseBids[k].price)) {
990
950
  thisBidWinner = theseBids[k];
991
951
  winningSeat = thisSeat;
@@ -1011,7 +971,6 @@ export function ozoneGetAllBidsForBidId(matchBidId, serverResponseSeatBid) {
1011
971
  for (let k = 0; k < theseBids.length; k++) {
1012
972
  if (theseBids[k].impid === matchBidId) {
1013
973
  if (objBids.hasOwnProperty(thisSeat)) { // > 1 bid for an adunit from a bidder - only use the one with the highest bid
1014
- // objBids[`${thisSeat}${theseBids[k].w}x${theseBids[k].h}`] = theseBids[k];
1015
974
  if (objBids[thisSeat]['price'] < theseBids[k].price) {
1016
975
  objBids[thisSeat] = theseBids[k];
1017
976
  }
@@ -1044,7 +1003,6 @@ export function getRoundedBid(price, mediaType) {
1044
1003
  config.getConfig('currency.granularityMultiplier')
1045
1004
  );
1046
1005
  logInfo('priceStringsObj', priceStringsObj);
1047
- // by default, without any custom granularity set, you get granularity name : 'medium'
1048
1006
  let granularityNamePriceStringsKeyMapping = {
1049
1007
  'medium': 'med',
1050
1008
  'custom': 'custom',
@@ -1195,7 +1153,6 @@ function newRenderer(adUnitCode, rendererOptions = {}) {
1195
1153
  }
1196
1154
  function outstreamRender(bid) {
1197
1155
  logInfo('outstreamRender called. Going to push the call to window.ozoneVideo.outstreamRender(bid) bid =', JSON.parse(JSON.stringify(bid)));
1198
- // push to render queue because ozoneVideo may not be loaded yet
1199
1156
  bid.renderer.push(() => {
1200
1157
  window.ozoneVideo.outstreamRender(bid);
1201
1158
  });
@@ -0,0 +1,147 @@
1
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
2
+ const BIDDER_CODE = 'pilotx';
3
+ const ENDPOINT_URL = '//adn.pilotx.tv/hb'
4
+ export const spec = {
5
+ code: BIDDER_CODE,
6
+ supportedMediaTypes: ['banner', 'video'],
7
+ aliases: ['pilotx'], // short code
8
+ /**
9
+ * Determines whether or not the given bid request is valid.
10
+ *
11
+ * @param {BidRequest} bid The bid params to validate.
12
+ * @return boolean True if this is a valid bid, and false otherwise.
13
+ */
14
+ isBidRequestValid: function (bid) {
15
+ let sizesCheck = !!bid.sizes
16
+ let paramSizesCheck = !!bid.params.sizes
17
+ var sizeConfirmed = false
18
+ if (sizesCheck) {
19
+ if (bid.sizes.length < 1) {
20
+ return false
21
+ } else {
22
+ sizeConfirmed = true
23
+ }
24
+ }
25
+ if (paramSizesCheck) {
26
+ if (bid.params.sizes.length < 1 && !sizeConfirmed) {
27
+ return false
28
+ } else {
29
+ sizeConfirmed = true
30
+ }
31
+ }
32
+ if (!sizeConfirmed) {
33
+ return false
34
+ }
35
+ return !!(bid.params.placementId);
36
+ },
37
+ /**
38
+ * Make a server request from the list of BidRequests.
39
+ *
40
+ * @param {validBidRequests[]} - an array of bids
41
+ * @return ServerRequest Info describing the request to the server.
42
+ */
43
+ buildRequests: function (validBidRequests, bidderRequest) {
44
+ let payloadItems = {};
45
+ validBidRequests.forEach(bidRequest => {
46
+ let sizes = [];
47
+ let placementId = this.setPlacementID(bidRequest.params.placementId)
48
+ payloadItems[placementId] = {}
49
+ if (bidRequest.sizes.length > 0) {
50
+ if (Array.isArray(bidRequest.sizes[0])) {
51
+ for (let i = 0; i < bidRequest.sizes.length; i++) {
52
+ sizes[i] = [(bidRequest.sizes[i])[0], (bidRequest.sizes[i])[1]]
53
+ }
54
+ } else {
55
+ sizes[0] = [bidRequest.sizes[0], bidRequest.sizes[1]]
56
+ }
57
+ payloadItems[placementId]['sizes'] = sizes
58
+ }
59
+ if (bidRequest.mediaTypes != null) {
60
+ for (let i in bidRequest.mediaTypes) {
61
+ payloadItems[placementId][i] = {
62
+ ...bidRequest.mediaTypes[i]
63
+ }
64
+ }
65
+ }
66
+ let consentTemp = ''
67
+ let consentRequiredTemp = false
68
+ if (bidderRequest && bidderRequest.gdprConsent) {
69
+ consentTemp = bidderRequest.gdprConsent.consentString
70
+ // will check if the gdprApplies field was populated with a boolean value (ie from page config). If it's undefined, then default to true
71
+ consentRequiredTemp = (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true
72
+ }
73
+
74
+ payloadItems[placementId]['gdprConsentString'] = consentTemp
75
+ payloadItems[placementId]['gdprConsentRequired'] = consentRequiredTemp
76
+ payloadItems[placementId]['bidId'] = bidRequest.bidId
77
+ });
78
+ const payload = payloadItems;
79
+ const payloadString = JSON.stringify(payload);
80
+ return {
81
+ method: 'POST',
82
+ url: ENDPOINT_URL,
83
+ data: payloadString,
84
+ };
85
+ },
86
+ /**
87
+ * Unpack the response from the server into a list of bids.
88
+ *
89
+ * @param {ServerResponse} serverResponse A successful response from the server.
90
+ * @return {Bid[]} An array of bids which were nested inside the server.
91
+ */
92
+ interpretResponse: function (serverResponse, bidRequest) {
93
+ const serverBody = serverResponse.body;
94
+ const bidResponses = [];
95
+ if (serverBody.mediaType == 'banner') {
96
+ const bidResponse = {
97
+ requestId: serverBody.requestId,
98
+ cpm: serverBody.cpm,
99
+ width: serverBody.width,
100
+ height: serverBody.height,
101
+ creativeId: serverBody.creativeId,
102
+ currency: serverBody.currency,
103
+ netRevenue: false,
104
+ ttl: serverBody.ttl,
105
+ ad: serverBody.ad,
106
+ mediaType: 'banner',
107
+ meta: {
108
+ mediaType: 'banner',
109
+ advertiserDomains: serverBody.advertiserDomains
110
+ }
111
+ }
112
+ bidResponses.push(bidResponse)
113
+ } else if (serverBody.mediaType == 'video') {
114
+ const bidResponse = {
115
+ requestId: serverBody.requestId,
116
+ cpm: serverBody.cpm,
117
+ width: serverBody.width,
118
+ height: serverBody.height,
119
+ creativeId: serverBody.creativeId,
120
+ currency: serverBody.currency,
121
+ netRevenue: false,
122
+ ttl: serverBody.ttl,
123
+ vastUrl: serverBody.vastUrl,
124
+ mediaType: 'video',
125
+ meta: {
126
+ mediaType: 'video',
127
+ advertiserDomains: serverBody.advertiserDomains
128
+ }
129
+ }
130
+ bidResponses.push(bidResponse)
131
+ }
132
+
133
+ return bidResponses;
134
+ },
135
+
136
+ /**
137
+ * Formats placement ids for adserver ingestion purposes
138
+ * @param {string[]} The placement ID/s in an array
139
+ */
140
+ setPlacementID: function (placementId) {
141
+ if (Array.isArray(placementId)) {
142
+ return placementId.join('#')
143
+ }
144
+ return placementId
145
+ },
146
+ }
147
+ registerBidder(spec);
@@ -0,0 +1,50 @@
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: Pilotx Prebid Adapter
5
+ Module Type: Bidder Adapter
6
+ Maintainer: tony@pilotx.tv
7
+ ```
8
+
9
+ # Description
10
+
11
+ Connects to Pilotx
12
+
13
+ Pilotx's bid adapter supports banner and video.
14
+
15
+ # Test Parameters
16
+ ```
17
+ // Banner adUnit
18
+ var adUnits = [{
19
+ code: 'div-gpt-ad-1460505748561-0',
20
+ mediaTypes: {
21
+ banner: {
22
+ sizes: [[300, 250], [300,600]],
23
+ }
24
+ },
25
+ bids: [{
26
+ bidder: 'pilotx',
27
+ params: {
28
+ placementId: ["1423"]
29
+ }
30
+ }]
31
+
32
+ }];
33
+
34
+ // Video adUnit
35
+ var videoAdUnit = {
36
+ code: 'video1',
37
+ mediaTypes: {
38
+ video: {
39
+ context: 'instream',
40
+ playerSize: [640, 480],
41
+ }
42
+ },
43
+ bids: [{
44
+ bidder: 'pilotx',
45
+ params: {
46
+ placementId: '1422',
47
+ }
48
+ }]
49
+ };
50
+ ```
@@ -172,8 +172,6 @@ function interpretResponse(serverResponse, bidRequest) {
172
172
 
173
173
  function _assignFloor(bid) {
174
174
  if (!isFn(bid.getFloor)) {
175
- // eslint-disable-next-line no-console
176
- console.log(bid.params.bidFloor);
177
175
  return bid.params.bidFloor ? bid.params.bidFloor : null;
178
176
  }
179
177
  const floor = bid.getFloor({
@@ -16,7 +16,7 @@ import {
16
16
  } from '../src/utils.js';
17
17
 
18
18
  const BIDDER_VERSION = '1.1.0';
19
- const BASE_URL = 'https://ortb.adpearl.io';
19
+ const BASE_URL = 'https://auction.adpearl.io';
20
20
 
21
21
  export const spec = {
22
22
  code: 'pubgenius',
@@ -200,6 +200,21 @@ function getAdapterNameForAlias(aliasName) {
200
200
  return adapterManager.aliasRegistry[aliasName] || aliasName;
201
201
  }
202
202
 
203
+ function getAdDomain(bidResponse) {
204
+ if (bidResponse.meta && bidResponse.meta.advertiserDomains) {
205
+ let adomain = bidResponse.meta.advertiserDomains[0]
206
+ if (adomain) {
207
+ try {
208
+ let hostname = (new URL(adomain));
209
+ return hostname.hostname.replace('www.', '');
210
+ } catch (e) {
211
+ logWarn(LOG_PRE_FIX + 'Adomain URL (Not a proper URL):', adomain);
212
+ return adomain.replace('www.', '');
213
+ }
214
+ }
215
+ }
216
+ }
217
+
203
218
  function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) {
204
219
  highestBid = (highestBid && highestBid.length > 0) ? highestBid[0] : null;
205
220
  return Object.keys(adUnit.bids).reduce(function(partnerBids, bidId) {
@@ -218,6 +233,7 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) {
218
233
  'dc': bid.bidResponse ? (bid.bidResponse.dealChannel || EMPTY_STRING) : EMPTY_STRING,
219
234
  'l1': bid.bidResponse ? bid.clientLatencyTimeMs : 0,
220
235
  'l2': 0,
236
+ 'adv': bid.bidResponse ? getAdDomain(bid.bidResponse) || undefined : undefined,
221
237
  'ss': (s2sBidders.indexOf(bid.bidder) > -1) ? 1 : 0,
222
238
  't': (bid.status == ERROR && bid.error.code == TIMEOUT_ERROR) ? 1 : 0,
223
239
  'wb': (highestBid && highestBid.requestId === bid.bidId ? 1 : 0),