From 69451d018d8b74ee237f7e31192d4250120dc027 Mon Sep 17 00:00:00 2001 From: Catalin Ciocov Date: Fri, 24 Jan 2020 16:09:01 +0200 Subject: [PATCH 001/496] Upgrade Inskin adapter to Prebid 3 (#4753) * Stop using deprecated functions. * Added unit tests for Inskin adapter. --- modules/inskinBidAdapter.js | 245 +++++++++++++++++ test/spec/modules/inskinBidAdapter_spec.js | 291 +++++++++++++++++++++ 2 files changed, 536 insertions(+) create mode 100644 modules/inskinBidAdapter.js create mode 100644 test/spec/modules/inskinBidAdapter_spec.js diff --git a/modules/inskinBidAdapter.js b/modules/inskinBidAdapter.js new file mode 100644 index 00000000000..28b533ec917 --- /dev/null +++ b/modules/inskinBidAdapter.js @@ -0,0 +1,245 @@ +import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory'; + +const BIDDER_CODE = 'inskin'; + +const CONFIG = { + 'inskin': { + 'BASE_URI': 'https://mfad.inskinad.com/api/v2' + } +}; + +export const spec = { + code: BIDDER_CODE, + + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function(bid) { + return !!(bid.params.networkId && bid.params.siteId); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @param {validBidRequests[]} - an array of bids + * @param {bidderRequest} - the full bidder request object + * @return ServerRequest Info describing the request to the server. + */ + + buildRequests: function(validBidRequests, bidderRequest) { + // Do we need to group by bidder? i.e. to make multiple requests for + // different endpoints. + + let ret = { + method: 'POST', + url: '', + data: '', + bidRequest: [] + }; + + if (validBidRequests.length < 1) { + return ret; + } + + let ENDPOINT_URL; + + const data = Object.assign({ + placements: [], + time: Date.now(), + user: {}, + url: bidderRequest.refererInfo.referer, + enableBotFiltering: true, + includePricingData: true, + parallel: true + }, validBidRequests[0].params); + + if (bidderRequest && bidderRequest.gdprConsent) { + data.consent = { + gdprVendorId: 150, + gdprConsentString: bidderRequest.gdprConsent.consentString, + // will check if the gdprApplies field was populated with a boolean value (ie from page config). If it's undefined, then default to true + gdprConsentRequired: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true + }; + } + + validBidRequests.map(bid => { + let config = CONFIG[bid.bidder]; + ENDPOINT_URL = config.BASE_URI; + + const placement = Object.assign({ + divName: bid.bidId, + adTypes: bid.adTypes || getSize(bid.sizes), + eventIds: [40, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295] + }, bid.params); + + placement.adTypes.push(5, 9, 163, 2163, 3006); + + if (placement.networkId && placement.siteId) { + data.placements.push(placement); + } + }); + + ret.data = JSON.stringify(data); + ret.bidRequest = validBidRequests; + ret.url = ENDPOINT_URL; + + return ret; + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function(serverResponse, bidRequest) { + let bid; + let bids; + let bidId; + let bidObj; + let bidResponses = []; + let bidsMap = {}; + + bids = bidRequest.bidRequest; + + serverResponse = (serverResponse || {}).body; + for (let i = 0; i < bids.length; i++) { + bid = {}; + bidObj = bids[i]; + bidId = bidObj.bidId; + + bidsMap[bidId] = bidObj; + + if (serverResponse) { + const decision = serverResponse.decisions && serverResponse.decisions[bidId]; + const data = decision && decision.contents && decision.contents[0] && decision.contents[0].data; + const pubCPM = data && data.customData && data.customData.pubCPM; + const clearPrice = decision && decision.pricing && decision.pricing.clearPrice; + const price = pubCPM || clearPrice; + + if (decision && price) { + decision.impressionUrl += ('&property:pubcpm=' + price); + bidObj.price = price; + + bid.requestId = bidId; + bid.cpm = price; + bid.width = decision.width; + bid.height = decision.height; + bid.ad = retrieveAd(bidId, decision); + bid.currency = 'USD'; + bid.creativeId = decision.adId; + bid.ttl = 360; + bid.netRevenue = true; + + bidResponses.push(bid); + } + } + } + + if (bidResponses.length) { + window.addEventListener('message', function(e) { + if (!e.data || e.data.from !== 'ism-bid') { + return; + } + + const decision = serverResponse.decisions && serverResponse.decisions[e.data.bidId]; + if (!decision) { + return; + } + + const id = 'ism_tag_' + Math.floor((Math.random() * 10e16)); + window[id] = { + bidId: e.data.bidId, + bidPrice: bidsMap[e.data.bidId].price, + serverResponse + }; + const script = document.createElement('script'); + script.src = 'https://cdn.inskinad.com/isfe/publishercode/' + bidsMap[e.data.bidId].params.siteId + '/default.js?autoload&id=' + id; + document.getElementsByTagName('head')[0].appendChild(script); + }); + } + + return bidResponses; + }, + + getUserSyncs: function(syncOptions) { + const userSyncs = []; + + if (syncOptions.pixelEnabled) { + userSyncs.push({ + type: 'image', + url: 'https://e.serverbid.com/udb/9969/match?redir=https%3A%2F%2Fmfad.inskinad.com%2Fudb%2F9874%2Fpool%2Fset%2Fi.gif%3FpoolId%3D9969%26poolKey%3D' + }); + userSyncs.push({ + type: 'image', + url: 'https://ssum.casalemedia.com/usermatchredir?s=185638&cb=https%3A%2F%2Fmfad.inskinad.com%2Fudb%2F9874%2Fsync%2Fi.gif%3FpartnerId%3D1%26userId%3D' + }); + } + + if (syncOptions.iframeEnabled) { + userSyncs.push({ + type: 'iframe', + url: 'https://ssum-sec.casalemedia.com/usermatch?s=184665&cb=https%3A%2F%2Fmfad.inskinad.com%2Fudb%2F9874%2Fsync%2Fi.gif%3FpartnerId%3D1%26userId%3D' + }); + } + + return userSyncs; + } +}; + +const sizeMap = [ + null, + '120x90', + '120x90', + '468x60', + '728x90', + '300x250', + '160x600', + '120x600', + '300x100', + '180x150', + '336x280', + '240x400', + '234x60', + '88x31', + '120x60', + '120x240', + '125x125', + '220x250', + '250x250', + '250x90', + '0x0', + '200x90', + '300x50', + '320x50', + '320x480', + '185x185', + '620x45', + '300x125', + '800x250' +]; + +sizeMap[77] = '970x90'; +sizeMap[123] = '970x250'; +sizeMap[43] = '300x600'; + +function getSize(sizes) { + const result = []; + sizes.forEach(function(size) { + const index = sizeMap.indexOf(size[0] + 'x' + size[1]); + if (index >= 0) { + result.push(index); + } + }); + return result; +} + +function retrieveAd(bidId, decision) { + return "'; + let formattedAd = '
'; + + it('should get correct bid response', () => { + var request = spec.buildRequests(bidRequests); + + let expectedResponse = [ + { + requestId: '30b31c1838de1e', + cpm: '0.2000', + width: 300, + height: 600, + creativeId: '28517153', + currency: 'EUR', + netRevenue: true, + ttl: 360, + ad: ad + } + ]; + + let result = spec.interpretResponse(response, request); + expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); + }); + + it('should get correct bid response with formated ad', () => { + var request = spec.buildRequests(formattedBidRequests); + + let expectedResponse = [ + { + requestId: '30b31c1838de1e', + cpm: '0.2000', + width: 300, + height: 600, + creativeId: '28517153', + currency: 'EUR', + netRevenue: true, + ttl: 360, + ad: formattedAd + } + ]; + + let result = spec.interpretResponse(response, request); + expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); + }); + it('handles nobid responses', () => { var reqest = spec.buildRequests(formattedBidRequests); let response = ''; From b76897dbf814ba420c415714f5d7b96ab7ba1829 Mon Sep 17 00:00:00 2001 From: Denis Logachov Date: Wed, 29 Jan 2020 05:51:37 +0200 Subject: [PATCH 011/496] CCPA support for adkernel and adkernelAdn adapters (#4767) --- modules/adkernelAdnBidAdapter.js | 17 ++++++------- modules/adkernelBidAdapter.js | 24 ++++++++++++------- .../modules/adkernelAdnBidAdapter_spec.js | 7 +++--- test/spec/modules/adkernelBidAdapter_spec.js | 6 ++--- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/modules/adkernelAdnBidAdapter.js b/modules/adkernelAdnBidAdapter.js index 3131aa2a38c..36689c24b9a 100644 --- a/modules/adkernelAdnBidAdapter.js +++ b/modules/adkernelAdnBidAdapter.js @@ -49,23 +49,24 @@ function canonicalizeSizesArray(sizes) { return sizes; } -function buildRequestParams(tags, auctionId, transactionId, gdprConsent, refInfo) { +function buildRequestParams(tags, auctionId, transactionId, gdprConsent, uspConsent, refInfo) { let req = { id: auctionId, tid: transactionId, site: buildSite(refInfo), imp: tags }; - - if (gdprConsent && (gdprConsent.gdprApplies !== undefined || gdprConsent.consentString !== undefined)) { - req.user = {}; + if (gdprConsent) { if (gdprConsent.gdprApplies !== undefined) { - req.user.gdpr = ~~(gdprConsent.gdprApplies); + utils.deepSetValue(req, 'user.gdpr', ~~gdprConsent.gdprApplies); } if (gdprConsent.consentString !== undefined) { - req.user.consent = gdprConsent.consentString; + utils.deepSetValue(req, 'user.consent', gdprConsent.consentString); } } + if (uspConsent) { + utils.deepSetValue(req, 'user.us_privacy', uspConsent); + } return req; } @@ -132,11 +133,11 @@ export const spec = { return acc; }, {}); - let {auctionId, gdprConsent, transactionId, refererInfo} = bidderRequest; + let {auctionId, gdprConsent, uspConsent, transactionId, refererInfo} = bidderRequest; let requests = []; Object.keys(dispatch).forEach(host => { Object.keys(dispatch[host]).forEach(pubId => { - let request = buildRequestParams(dispatch[host][pubId], auctionId, transactionId, gdprConsent, refererInfo); + let request = buildRequestParams(dispatch[host][pubId], auctionId, transactionId, gdprConsent, uspConsent, refererInfo); requests.push({ method: 'POST', url: `https://${host}/tag?account=${pubId}&pb=1${isRtbDebugEnabled(refererInfo) ? '&debug=1' : ''}`, diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index 29c23452814..64e70727cf9 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -36,11 +36,11 @@ export const spec = { }, buildRequests: function(bidRequests, bidderRequest) { let impDispatch = dispatchImps(bidRequests, bidderRequest.refererInfo); - const {gdprConsent, auctionId, refererInfo, timeout} = bidderRequest; + const {gdprConsent, auctionId, refererInfo, timeout, uspConsent} = bidderRequest; const requests = []; Object.keys(impDispatch).forEach(host => { Object.keys(impDispatch[host]).forEach(zoneId => { - const request = buildRtbRequest(impDispatch[host][zoneId], auctionId, gdprConsent, refererInfo, timeout); + const request = buildRtbRequest(impDispatch[host][zoneId], auctionId, gdprConsent, uspConsent, refererInfo, timeout); requests.push({ method: 'POST', url: `https://${host}/hb?zone=${zoneId}&v=${VERSION}`, @@ -149,12 +149,13 @@ function buildImp(bidRequest, secure) { * Builds complete rtb request * @param imps collection of impressions * @param auctionId - * @param gdprConsent + * @param gdprConsent {string=} + * @param uspConsent {string=} * @param refInfo * @param timeout * @return Object complete rtb request */ -function buildRtbRequest(imps, auctionId, gdprConsent, refInfo, timeout) { +function buildRtbRequest(imps, auctionId, gdprConsent, uspConsent, refInfo, timeout) { let req = { 'id': auctionId, 'imp': imps, @@ -174,11 +175,16 @@ function buildRtbRequest(imps, auctionId, gdprConsent, refInfo, timeout) { if (utils.getDNT()) { req.device.dnt = 1; } - if (gdprConsent && gdprConsent.gdprApplies !== undefined) { - req.regs = {ext: {gdpr: Number(gdprConsent.gdprApplies)}}; + if (gdprConsent) { + if (gdprConsent.gdprApplies !== undefined) { + utils.deepSetValue(req, 'regs.ext.gdpr', ~~gdprConsent.gdprApplies); + } + if (gdprConsent.consentString !== undefined) { + utils.deepSetValue(req, 'user.ext.consent', gdprConsent.consentString); + } } - if (gdprConsent && gdprConsent.consentString !== undefined) { - req.user = {ext: {consent: gdprConsent.consentString}}; + if (uspConsent) { + utils.deepSetValue(req, 'regs.ext.us_privacy', uspConsent); } return req; } @@ -195,7 +201,7 @@ function createSite(refInfo) { let url = parseUrl(refInfo.referer); let site = { 'domain': url.hostname, - 'page': url.protocol + '://' + url.hostname + url.pathname + 'page': `${url.protocol}://${url.hostname}${url.pathname}` }; if (self === top && document.referrer) { site.ref = document.referrer; diff --git a/test/spec/modules/adkernelAdnBidAdapter_spec.js b/test/spec/modules/adkernelAdnBidAdapter_spec.js index 98e3f6b3408..4c84790cb40 100644 --- a/test/spec/modules/adkernelAdnBidAdapter_spec.js +++ b/test/spec/modules/adkernelAdnBidAdapter_spec.js @@ -243,17 +243,18 @@ describe('AdkernelAdn adapter', function () { expect(tagRequest).to.not.have.property('user'); }); - it('shouldn\'t contain gdpr-related information for default request', function () { + it('shouldn\'t contain gdpr nor ccpa information for default request', function () { let [_, tagRequests] = buildRequest([bid1_pub1]); expect(tagRequests[0]).to.not.have.property('user'); }); - it('should contain gdpr-related information if consent is configured', function () { + it('should contain gdpr and ccpa information if consent is configured', function () { let [_, bidRequests] = buildRequest([bid1_pub1], - {gdprConsent: {gdprApplies: true, consentString: 'test-consent-string'}}); + {gdprConsent: {gdprApplies: true, consentString: 'test-consent-string'}, uspConsent: '1YNN'}); expect(bidRequests[0]).to.have.property('user'); expect(bidRequests[0].user).to.have.property('gdpr', 1); expect(bidRequests[0].user).to.have.property('consent', 'test-consent-string'); + expect(bidRequests[0].user).to.have.property('us_privacy', '1YNN'); }); it('should\'t contain consent string if gdpr isn\'t applied', function () { diff --git a/test/spec/modules/adkernelBidAdapter_spec.js b/test/spec/modules/adkernelBidAdapter_spec.js index 294aba72a6b..b5c64f3fa49 100644 --- a/test/spec/modules/adkernelBidAdapter_spec.js +++ b/test/spec/modules/adkernelBidAdapter_spec.js @@ -238,7 +238,7 @@ describe('Adkernel adapter', function () { expect(bidRequest.device).to.have.property('dnt', 1); }); - it('shouldn\'t contain gdpr-related information for default request', function () { + it('shouldn\'t contain gdpr nor ccpa information for default request', function () { let [_, bidRequests] = buildRequest([bid1_zone1]); expect(bidRequests[0]).to.not.have.property('regs'); expect(bidRequests[0]).to.not.have.property('user'); @@ -247,10 +247,10 @@ describe('Adkernel adapter', function () { it('should contain gdpr-related information if consent is configured', function () { let [_, bidRequests] = buildRequest([bid1_zone1], buildBidderRequest('https://example.com/index.html', - {gdprConsent: {gdprApplies: true, consentString: 'test-consent-string', vendorData: {}}})); + {gdprConsent: {gdprApplies: true, consentString: 'test-consent-string', vendorData: {}}, uspConsent: '1YNN'})); let bidRequest = bidRequests[0]; expect(bidRequest).to.have.property('regs'); - expect(bidRequest.regs.ext).to.be.eql({'gdpr': 1}); + expect(bidRequest.regs.ext).to.be.eql({'gdpr': 1, 'us_privacy': '1YNN'}); expect(bidRequest).to.have.property('user'); expect(bidRequest.user.ext).to.be.eql({'consent': 'test-consent-string'}); }); From 03241416d5d8f0b6d8350c8444618e2f3c47cf58 Mon Sep 17 00:00:00 2001 From: "Isaac A. Dettman" Date: Tue, 28 Jan 2020 20:18:56 -0800 Subject: [PATCH 012/496] change to allow number or string (#4793) --- modules/prebidServerBidAdapter/index.js | 2 +- modules/rubiconBidAdapter.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js index 8c32ab634d9..3f7687479ec 100644 --- a/modules/prebidServerBidAdapter/index.js +++ b/modules/prebidServerBidAdapter/index.js @@ -494,7 +494,7 @@ const OPEN_RTB_PROTOCOL = { Object.assign(imp, mediaTypes); // if storedAuctionResponse has been set, pass SRID - const storedAuctionResponseBid = find(bidRequests[0].bids, bid => (bid.adUnitCode === adUnit.code && typeof bid.storedAuctionResponse === 'number')); + const storedAuctionResponseBid = find(bidRequests[0].bids, bid => (bid.adUnitCode === adUnit.code && bid.storedAuctionResponse)); if (storedAuctionResponseBid) { utils.deepSetValue(imp, 'ext.prebid.storedauctionresponse.id', storedAuctionResponseBid.storedAuctionResponse.toString()); } diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index 4b53cf78e0c..ec8537cc0bf 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -277,7 +277,7 @@ export const spec = { } // if storedAuctionResponse has been set, pass SRID - if (typeof bidRequest.storedAuctionResponse === 'number') { + if (bidRequest.storedAuctionResponse) { utils.deepSetValue(data.imp[0], 'ext.prebid.storedauctionresponse.id', bidRequest.storedAuctionResponse.toString()); } From d63ab86e05266e466de5b1e0f7f7b746a2a611c4 Mon Sep 17 00:00:00 2001 From: Mariya Mego <31904600+mash-a@users.noreply.github.com> Date: Wed, 29 Jan 2020 11:11:51 -0800 Subject: [PATCH 013/496] Update underdogmedia adapter to contain getUserSyncs (#4777) * Add userSyncs to udm adapter * Lint fix * Update adapter version * Prevent user syncs from loading when empty array --- modules/underdogmediaBidAdapter.js | 37 +++++++++- .../modules/underdogmediaBidAdapter_spec.js | 73 ++++++++++++++++++- 2 files changed, 105 insertions(+), 5 deletions(-) diff --git a/modules/underdogmediaBidAdapter.js b/modules/underdogmediaBidAdapter.js index 0cda14d3849..0ad11fe7fd6 100644 --- a/modules/underdogmediaBidAdapter.js +++ b/modules/underdogmediaBidAdapter.js @@ -2,12 +2,18 @@ import * as utils from '../src/utils'; import { config } from '../src/config'; import { registerBidder } from '../src/adapters/bidderFactory'; const BIDDER_CODE = 'underdogmedia'; -const UDM_ADAPTER_VERSION = '3.0V'; +const UDM_ADAPTER_VERSION = '3.5V'; const UDM_VENDOR_ID = '159'; const prebidVersion = '$prebid.version$'; +let USER_SYNCED = false; utils.logMessage(`Initializing UDM Adapter. PBJS Version: ${prebidVersion} with adapter version: ${UDM_ADAPTER_VERSION} Updated 20191028`); +// helper function for testing user syncs +export function resetUserSync() { + USER_SYNCED = false; +} + export const spec = { code: BIDDER_CODE, bidParams: [], @@ -31,7 +37,8 @@ export const spec = { tid: 1, dt: 10, sid: siteId, - sizes: sizes.join(',') + sizes: sizes.join(','), + version: UDM_ADAPTER_VERSION } if (bidderRequest && bidderRequest.gdprConsent) { @@ -61,6 +68,23 @@ export const spec = { } }, + getUserSyncs: function (syncOptions, serverResponses) { + if (!USER_SYNCED && serverResponses.length > 0 && serverResponses[0].body && serverResponses[0].body.userSyncs && serverResponses[0].body.userSyncs.length > 0) { + USER_SYNCED = true; + const userSyncs = serverResponses[0].body.userSyncs; + const syncs = userSyncs.filter(sync => { + const {type} = sync; + if (syncOptions.iframeEnabled && type === 'iframe') { + return true + } + if (syncOptions.pixelEnabled && type === 'image') { + return true + } + }) + return syncs; + } + }, + interpretResponse: function (serverResponse, bidRequest) { const bidResponses = []; bidRequest.bidParams.forEach(bidParam => { @@ -118,9 +142,14 @@ export const spec = { }; function makeNotification(bid, mid, bidParam) { - var url = mid.notification_url; + let url = mid.notification_url; + + const versionIndex = url.indexOf(';version=') + if (versionIndex + 1) { + url = url.substring(0, versionIndex) + } - url += UDM_ADAPTER_VERSION; + url += `;version=${UDM_ADAPTER_VERSION}`; url += ';cb=' + Math.random(); url += ';qqq=' + (1 / bid.cpm); url += ';hbt=' + config.getConfig('_bidderTimeout'); diff --git a/test/spec/modules/underdogmediaBidAdapter_spec.js b/test/spec/modules/underdogmediaBidAdapter_spec.js index 65c4cb5cb33..66668c39b48 100644 --- a/test/spec/modules/underdogmediaBidAdapter_spec.js +++ b/test/spec/modules/underdogmediaBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/underdogmediaBidAdapter'; +import { spec, resetUserSync } from 'modules/underdogmediaBidAdapter'; describe('UnderdogMedia adapter', function () { let bidRequests; @@ -411,4 +411,75 @@ describe('UnderdogMedia adapter', function () { }); }); }); + + describe('getUserSyncs', function () { + const syncOptionsPixelOnly = { + 'pixelEnabled': true + }; + + const syncOptionsIframeOnly = { + 'iframeEnabled': true + }; + + const syncOptionsPixelAndIframe = { + 'pixelEnabled': true, + 'iframeEnabled': true + }; + + const responseWithUserSyncs = [{ + body: { + userSyncs: [ + { + type: 'image', + url: 'https://test.url.com' + }, + { + type: 'iframe', + url: 'https://test.url.com' + } + ] + } + }]; + + const responseWithEmptyUserSyncs = [{ + body: { + userSyncs: [] + } + }]; + + it('user syncs should only return what is allowed', function () { + const result = spec.getUserSyncs(syncOptionsPixelOnly, responseWithUserSyncs); + expect(result[0].type).to.equal('image'); + expect(result.length).to.equal(1); + }); + + it('user syncs should only load once per user', function () { + const result = spec.getUserSyncs(syncOptionsPixelAndIframe, responseWithUserSyncs); + expect(result).to.equal(undefined); + }); + + it('user syncs should return undefined when empty', function () { + resetUserSync(); + + const result = spec.getUserSyncs(syncOptionsPixelAndIframe, responseWithEmptyUserSyncs); + expect(result).to.equal(undefined); + }); + + it('should reset USER_SYNCED flag, allowing another sync', function () { + resetUserSync(); + + const result = spec.getUserSyncs(syncOptionsIframeOnly, responseWithUserSyncs); + expect(result[0].type).to.equal('iframe'); + expect(result.length).to.equal(1); + }); + + it('should return all enabled syncs', function () { + resetUserSync(); + + const result = spec.getUserSyncs(syncOptionsPixelAndIframe, responseWithUserSyncs); + expect(result[0].type).to.equal('image'); + expect(result[1].type).to.equal('iframe'); + expect(result.length).to.equal(2); + }); + }); }); From e7332042778b85f9b27fad7ed868c4b7c3ebab08 Mon Sep 17 00:00:00 2001 From: Tomas Roos Date: Wed, 29 Jan 2020 21:54:15 +0100 Subject: [PATCH 014/496] Allow auctionId to be passed back to bidsBackHandler (#4789) --- src/auction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auction.js b/src/auction.js index 43f517fd84c..2f040918837 100644 --- a/src/auction.js +++ b/src/auction.js @@ -175,7 +175,7 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, a const bids = _bidsReceived .filter(utils.bind.call(adUnitsFilter, this, adUnitCodes)) .reduce(groupByPlacement, {}); - _callback.apply($$PREBID_GLOBAL$$, [bids, timedOut]); + _callback.apply($$PREBID_GLOBAL$$, [bids, timedOut, _auctionId]); _callback = null; } } catch (e) { From f0845c8771d396de2961482c50e0f819693a7192 Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Wed, 29 Jan 2020 15:57:00 -0500 Subject: [PATCH 015/496] change addEventListener to window.addEventlistener (#4792) https://github.com/prebid/Prebid.js/issues/4371 --- src/secureCreatives.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/secureCreatives.js b/src/secureCreatives.js index 7584c5d2bf7..88e0bc44f87 100644 --- a/src/secureCreatives.js +++ b/src/secureCreatives.js @@ -14,7 +14,7 @@ import { isRendererRequired, executeRenderer } from './Renderer'; const BID_WON = EVENTS.BID_WON; export function listenMessagesFromCreative() { - addEventListener('message', receiveMessage, false); + window.addEventListener('message', receiveMessage, false); } function receiveMessage(ev) { From b492e3a26234e4eed79db990110e30db95307eb0 Mon Sep 17 00:00:00 2001 From: Matt Kendall <1870166+mkendall07@users.noreply.github.com> Date: Wed, 29 Jan 2020 16:14:33 -0500 Subject: [PATCH 016/496] 3.5.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cc5b4e4e9f7..b3a5c7a5060 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.5.0-pre", + "version": "3.5.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 754311628f8b7e1ca5f9b82e7ad36e40b891e15d Mon Sep 17 00:00:00 2001 From: vladi-mmg Date: Thu, 30 Jan 2020 12:05:30 +0200 Subject: [PATCH 017/496] Add new bid adapter for ResultsMedia (#4785) --- modules/resultsmediaBidAdapter.js | 269 ++++++++ modules/resultsmediaBidAdapter.md | 47 ++ .../modules/resultsmediaBidAdapter_spec.js | 574 ++++++++++++++++++ 3 files changed, 890 insertions(+) create mode 100644 modules/resultsmediaBidAdapter.js create mode 100644 modules/resultsmediaBidAdapter.md create mode 100644 test/spec/modules/resultsmediaBidAdapter_spec.js diff --git a/modules/resultsmediaBidAdapter.js b/modules/resultsmediaBidAdapter.js new file mode 100644 index 00000000000..5d9934c51e4 --- /dev/null +++ b/modules/resultsmediaBidAdapter.js @@ -0,0 +1,269 @@ +'use strict'; + +import * as utils from '../src/utils'; +import {registerBidder} from '../src/adapters/bidderFactory'; +import { BANNER, VIDEO } from '../src/mediaTypes'; + +function ResultsmediaAdapter() { + this.code = 'resultsmedia'; + this.aliases = ['resultsmedia']; + this.supportedMediaTypes = [VIDEO, BANNER]; + + let SUPPORTED_VIDEO_PROTOCOLS = [2, 3, 5, 6]; + let SUPPORTED_VIDEO_MIMES = ['video/mp4']; + let SUPPORTED_VIDEO_PLAYBACK_METHODS = [1, 2, 3, 4]; + let SUPPORTED_VIDEO_DELIVERY = [1]; + let SUPPORTED_VIDEO_API = [1, 2, 5]; + let slotsToBids = {}; + let that = this; + let version = '2.1'; + + this.isBidRequestValid = function (bid) { + return !!(bid.params && bid.params.zoneId); + }; + + this.getUserSyncs = function (syncOptions, responses, gdprConsent) { + return []; + }; + + function frameImp(BRs, bidderRequest) { + var impList = []; + var isSecure = 0; + if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.stack.length) { + // clever trick to get the protocol + var el = document.createElement('a'); + el.href = bidderRequest.refererInfo.stack[0]; + isSecure = (el.protocol == 'https:') ? 1 : 0; + } + for (var i = 0; i < BRs.length; i++) { + slotsToBids[BRs[i].adUnitCode] = BRs[i]; + var impObj = {}; + impObj.id = BRs[i].adUnitCode; + impObj.secure = isSecure; + + if (utils.deepAccess(BRs[i], 'mediaTypes.banner') || utils.deepAccess(BRs[i], 'mediaType') === 'banner') { + let banner = frameBanner(BRs[i]); + if (banner) { + impObj.banner = banner; + } + } + if (utils.deepAccess(BRs[i], 'mediaTypes.video') || utils.deepAccess(BRs[i], 'mediaType') === 'video') { + impObj.video = frameVideo(BRs[i]); + } + if (!(impObj.banner || impObj.video)) { + continue; + } + impObj.ext = frameExt(BRs[i]); + impList.push(impObj); + } + return impList; + } + + function frameSite(bidderRequest) { + var site = { + domain: '', + page: '', + ref: '' + } + if (bidderRequest && bidderRequest.refererInfo) { + var ri = bidderRequest.refererInfo; + site.ref = ri.referer; + + if (ri.stack.length) { + site.page = ri.stack[ri.stack.length - 1]; + + // clever trick to get the domain + var el = document.createElement('a'); + el.href = ri.stack[0]; + site.domain = el.hostname; + } + } + return site; + } + + function frameDevice() { + return { + ua: navigator.userAgent, + ip: '', // Empty Ip string is required, server gets the ip from HTTP header + dnt: utils.getDNT() ? 1 : 0, + } + } + + function getValidSizeSet(dimensionList) { + let w = parseInt(dimensionList[0]); + let h = parseInt(dimensionList[1]); + // clever check for NaN + if (! (w !== w || h !== h)) { // eslint-disable-line + return [w, h]; + } + return false; + } + + function frameBanner(adUnit) { + // adUnit.sizes is scheduled to be deprecated, continue its support but prefer adUnit.mediaTypes.banner + var sizeList = adUnit.sizes; + if (adUnit.mediaTypes && adUnit.mediaTypes.banner) { + sizeList = adUnit.mediaTypes.banner.sizes; + } + var sizeStringList = utils.parseSizesInput(sizeList); + var format = []; + sizeStringList.forEach(function(size) { + if (size) { + var dimensionList = getValidSizeSet(size.split('x')); + if (dimensionList) { + format.push({ + 'w': dimensionList[0], + 'h': dimensionList[1], + }); + } + } + }); + if (format.length) { + return { + 'format': format + }; + } + + return false; + } + + function frameVideo(bid) { + var size = []; + if (utils.deepAccess(bid, 'mediaTypes.video.playerSize')) { + var dimensionSet = bid.mediaTypes.video.playerSize; + if (utils.isArray(bid.mediaTypes.video.playerSize[0])) { + dimensionSet = bid.mediaTypes.video.playerSize[0]; + } + var validSize = getValidSizeSet(dimensionSet) + if (validSize) { + size = validSize; + } + } + return { + mimes: utils.deepAccess(bid, 'mediaTypes.video.mimes') || SUPPORTED_VIDEO_MIMES, + protocols: utils.deepAccess(bid, 'mediaTypes.video.protocols') || SUPPORTED_VIDEO_PROTOCOLS, + w: size[0], + h: size[1], + startdelay: utils.deepAccess(bid, 'mediaTypes.video.startdelay') || 0, + skip: utils.deepAccess(bid, 'mediaTypes.video.skip') || 0, + playbackmethod: utils.deepAccess(bid, 'mediaTypes.video.playbackmethod') || SUPPORTED_VIDEO_PLAYBACK_METHODS, + delivery: utils.deepAccess(bid, 'mediaTypes.video.delivery') || SUPPORTED_VIDEO_DELIVERY, + api: utils.deepAccess(bid, 'mediaTypes.video.api') || SUPPORTED_VIDEO_API, + } + } + + function frameExt(bid) { + return { + bidder: { + zoneId: bid.params['zoneId'] + } + } + } + + function frameBid(BRs, bidderRequest) { + let bid = { + id: BRs[0].bidderRequestId, + imp: frameImp(BRs, bidderRequest), + site: frameSite(bidderRequest), + device: frameDevice(), + user: { + ext: { + consent: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? bidderRequest.gdprConsent.consentString : '' + } + }, + at: 1, + tmax: 1000, + regs: { + ext: { + gdpr: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? Boolean(bidderRequest.gdprConsent.gdprApplies & 1) : false + } + } + }; + if (BRs[0].schain) { + bid.source = { + 'ext': { + 'schain': BRs[0].schain + } + } + } + return bid; + } + + function getFirstParam(key, validBidRequests) { + for (let i = 0; i < validBidRequests.length; i++) { + if (validBidRequests[i].params && validBidRequests[i].params[key]) { + return validBidRequests[i].params[key]; + } + } + } + + this.buildRequests = function (BRs, bidderRequest) { + let fallbackZoneId = getFirstParam('zoneId', BRs); + if (fallbackZoneId === undefined || BRs.length < 1) { + return []; + } + + var uri = 'https://bid306.rtbsrv.com/bidder/?bid=3mhdom&zoneId=' + fallbackZoneId; + + var fat = /(^v|(\.0)+$)/gi; + var prebidVersion = '$prebid.version$'; + uri += '&hbv=' + prebidVersion.replace(fat, '') + ',' + version.replace(fat, ''); + + var bidRequest = frameBid(BRs, bidderRequest); + if (!bidRequest.imp.length) { + return {}; + } + + return { + method: 'POST', + url: uri, + data: JSON.stringify(bidRequest) + }; + }; + + this.interpretResponse = function (serverResponse) { + let responses = serverResponse.body || []; + let bids = []; + let i = 0; + + if (responses.seatbid) { + let temp = []; + for (i = 0; i < responses.seatbid.length; i++) { + for (let j = 0; j < responses.seatbid[i].bid.length; j++) { + temp.push(responses.seatbid[i].bid[j]); + } + } + responses = temp; + } + + for (i = 0; i < responses.length; i++) { + let bid = responses[i]; + let bidRequest = slotsToBids[bid.impid]; + let bidResponse = { + requestId: bidRequest.id, + bidderCode: that.code, + cpm: parseFloat(bid.price), + width: bid.w, + height: bid.h, + creativeId: bid.crid, + currency: 'USD', + netRevenue: true, + ttl: 350 + }; + + if (bidRequest.mediaTypes && bidRequest.mediaTypes.video) { + bidResponse.vastUrl = bid.adm; + bidResponse.mediaType = 'video'; + bidResponse.ttl = 600; + } else { + bidResponse.ad = bid.adm; + } + bids.push(bidResponse); + } + + return bids; + }; +} + +export const spec = new ResultsmediaAdapter(); +registerBidder(spec); diff --git a/modules/resultsmediaBidAdapter.md b/modules/resultsmediaBidAdapter.md new file mode 100644 index 00000000000..0b65264c8e4 --- /dev/null +++ b/modules/resultsmediaBidAdapter.md @@ -0,0 +1,47 @@ +# Overview + +``` +Module Name: ResultsMedia (resultsmedia.com) Bidder Adapter +Module Type: Bidder Adapter +Maintainer: prebid@resultsmedia.COM +``` + +# Description + +Prebid adapter for ResultsMedia RTB. Requires approval and account setup. + +# Test Parameters + +## Web +``` + var adUnits = [{ + code: 'banner-ad-div', + mediaTypes: { + banner: { + sizes: [ + [300, 200] // banner sizes + ], + } + }, + bids: [{ + bidder: 'resultsmedia', + params: { + zoneId: 9999 + } + }] + }, { + code: 'video-ad-player', + mediaTypes: { + video: { + context: 'instream', // or 'outstream' + playerSize: [640, 480] // video player size + } + }, + bids: [{ + bidder: 'resultsmedia', + params: { + zoneId: 9999 + } + }] + }]; +``` \ No newline at end of file diff --git a/test/spec/modules/resultsmediaBidAdapter_spec.js b/test/spec/modules/resultsmediaBidAdapter_spec.js new file mode 100644 index 00000000000..e06da25ebf2 --- /dev/null +++ b/test/spec/modules/resultsmediaBidAdapter_spec.js @@ -0,0 +1,574 @@ +import {spec} from '../../../modules/resultsmediaBidAdapter'; +import * as utils from '../../../src/utils'; +import * as sinon from 'sinon'; + +var r1adapter = spec; + +describe('resultsmedia adapter tests', function () { + beforeEach(function() { + this.defaultBidderRequest = { + 'refererInfo': { + 'referer': 'Reference Page', + 'stack': [ + 'aodomain.dvl', + 'page.dvl' + ] + } + }; + }); + + describe('Verify 1.0 POST Banner Bid Request', function () { + it('buildRequests works', function () { + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaType': 'banner', + 'adUnitCode': 'div-gpt-ad-1438287399331-0', + 'sizes': [[300, 250]], + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + + expect(bidRequest.url).to.have.string('https://bid306.rtbsrv.com/bidder/?bid=3mhdom&zoneId=9999&hbv='); + expect(bidRequest.method).to.equal('POST'); + const openrtbRequest = JSON.parse(bidRequest.data); + expect(openrtbRequest.site).to.not.equal(null); + expect(openrtbRequest.site.ref).to.equal('Reference Page'); + expect(openrtbRequest.device).to.not.equal(null); + expect(openrtbRequest.device.ua).to.equal(navigator.userAgent); + expect(openrtbRequest.device.dnt).to.equal(0); + expect(openrtbRequest.imp[0].banner).to.not.equal(null); + expect(openrtbRequest.imp[0].banner.format[0].w).to.equal(300); + expect(openrtbRequest.imp[0].banner.format[0].h).to.equal(250); + expect(openrtbRequest.imp[0].ext.bidder.zoneId).to.equal(9999); + }); + + it('interpretResponse works', function() { + var bidList = { + 'body': [ + { + 'impid': 'div-gpt-ad-1438287399331-0', + 'w': 300, + 'h': 250, + 'adm': '
My Compelling Ad
', + 'price': 1, + 'crid': 'cr-cfy24' + } + ] + }; + + var bannerBids = r1adapter.interpretResponse(bidList); + + expect(bannerBids.length).to.equal(1); + const bid = bannerBids[0]; + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); + expect(bid.creativeId).to.equal('cr-cfy24'); + expect(bid.currency).to.equal('USD'); + expect(bid.netRevenue).to.equal(true); + expect(bid.cpm).to.equal(1.0); + expect(bid.ttl).to.equal(350); + }); + }); + + describe('Verify POST Video Bid Request', function() { + it('buildRequests works', function () { + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaTypes': { + 'video': { + 'playerSize': [640, 480], + 'context': 'instream' + } + }, + 'adUnitCode': 'div-gpt-ad-1438287399331-1', + 'sizes': [ + [300, 250] + ], + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + + expect(bidRequest.url).to.have.string('https://bid306.rtbsrv.com/bidder/?bid=3mhdom&zoneId=9999&hbv='); + expect(bidRequest.method).to.equal('POST'); + const openrtbRequest = JSON.parse(bidRequest.data); + expect(openrtbRequest.site).to.not.equal(null); + expect(openrtbRequest.device).to.not.equal(null); + expect(openrtbRequest.device.ua).to.equal(navigator.userAgent); + expect(openrtbRequest.device).to.have.property('dnt'); + expect(openrtbRequest.imp[0].video).to.not.equal(null); + expect(openrtbRequest.imp[0].video.w).to.equal(640); + expect(openrtbRequest.imp[0].video.h).to.equal(480); + expect(openrtbRequest.imp[0].video.mimes[0]).to.equal('video/mp4'); + expect(openrtbRequest.imp[0].video.protocols).to.eql([2, 3, 5, 6]); + expect(openrtbRequest.imp[0].video.startdelay).to.equal(0); + expect(openrtbRequest.imp[0].video.skip).to.equal(0); + expect(openrtbRequest.imp[0].video.playbackmethod).to.eql([1, 2, 3, 4]); + expect(openrtbRequest.imp[0].video.delivery[0]).to.equal(1); + expect(openrtbRequest.imp[0].video.api).to.eql([1, 2, 5]); + }); + + it('interpretResponse works', function() { + var bidList = { + 'body': [ + { + 'impid': 'div-gpt-ad-1438287399331-1', + 'price': 1, + 'adm': 'https://example.com/', + 'adomain': [ + 'test.com' + ], + 'cid': '467415', + 'crid': 'cr-vid', + 'w': 800, + 'h': 600 + } + ] + }; + + var videoBids = r1adapter.interpretResponse(bidList); + + expect(videoBids.length).to.equal(1); + const bid = videoBids[0]; + expect(bid.width).to.equal(800); + expect(bid.height).to.equal(600); + expect(bid.vastUrl).to.equal('https://example.com/'); + expect(bid.mediaType).to.equal('video'); + expect(bid.creativeId).to.equal('cr-vid'); + expect(bid.currency).to.equal('USD'); + expect(bid.netRevenue).to.equal(true); + expect(bid.cpm).to.equal(1.0); + expect(bid.ttl).to.equal(600); + }); + }); + + describe('misc buildRequests', function() { + it('should send GDPR Consent data to resultsmedia tag', function () { + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250]] + } + }, + 'adUnitCode': 'div-gpt-ad-1438287399331-3', + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var consentString = 'testConsentString'; + var gdprBidderRequest = this.defaultBidderRequest; + gdprBidderRequest.gdprConsent = { + 'gdprApplies': true, + 'consentString': consentString + }; + + var bidRequest = r1adapter.buildRequests(bidRequestList, gdprBidderRequest); + + const openrtbRequest = JSON.parse(bidRequest.data); + expect(openrtbRequest.user.ext.consent).to.equal(consentString); + expect(openrtbRequest.regs.ext.gdpr).to.equal(true); + }); + + it('prefer 2.0 sizes', function () { + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 600]] + } + }, + 'adUnitCode': 'div-gpt-ad-1438287399331-0', + 'sizes': [[300, 250]], + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + + const openrtbRequest = JSON.parse(bidRequest.data); + expect(openrtbRequest.imp[0].banner.format[0].w).to.equal(300); + expect(openrtbRequest.imp[0].banner.format[0].h).to.equal(600); + }); + + it('does not return request for invalid banner size configuration', function () { + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[300]] + } + }, + 'adUnitCode': 'div-gpt-ad-1438287399331-0', + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + expect(bidRequest.method).to.be.undefined; + }); + + it('does not return request for missing banner size configuration', function () { + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaTypes': { + 'banner': {} + }, + 'adUnitCode': 'div-gpt-ad-1438287399331-0', + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + expect(bidRequest.method).to.be.undefined; + }); + + it('reject bad sizes', function () { + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaTypes': { + 'banner': {'sizes': [['400', '500'], ['4n0', '5g0']]} + }, + 'adUnitCode': 'div-gpt-ad-1438287399331-0', + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + const openrtbRequest = JSON.parse(bidRequest.data); + expect(openrtbRequest.imp[0].banner.format.length).to.equal(1); + }); + + it('dnt is correctly set to 1', function () { + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 600]] + } + }, + 'adUnitCode': 'div-gpt-ad-1438287399331-0', + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var dntStub = sinon.stub(utils, 'getDNT').returns(1); + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + + dntStub.restore(); + + const openrtbRequest = JSON.parse(bidRequest.data); + expect(openrtbRequest.device.dnt).to.equal(1); + }); + + it('supports string video sizes', function () { + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaTypes': { + 'video': { + 'context': 'instream', + 'playerSize': ['600', '300'] + } + }, + 'adUnitCode': 'div-gpt-ad-1438287399331-1', + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + + const openrtbRequest = JSON.parse(bidRequest.data); + expect(openrtbRequest.imp[0].video.w).to.equal(600); + expect(openrtbRequest.imp[0].video.h).to.equal(300); + }); + + it('rejects bad video sizes', function () { + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaTypes': { + 'video': { + 'context': 'instream', + 'playerSize': ['badWidth', 'badHeight'] + } + }, + 'adUnitCode': 'div-gpt-ad-1438287399331-1', + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + + const openrtbRequest = JSON.parse(bidRequest.data); + expect(openrtbRequest.imp[0].video.w).to.be.undefined; + expect(openrtbRequest.imp[0].video.h).to.be.undefined; + }); + + it('supports missing video size', function () { + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaTypes': { + 'video': { + 'context': 'instream' + } + }, + 'adUnitCode': 'div-gpt-ad-1438287399331-1', + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + + const openrtbRequest = JSON.parse(bidRequest.data); + expect(openrtbRequest.imp[0].video.w).to.be.undefined; + expect(openrtbRequest.imp[0].video.h).to.be.undefined; + }); + + it('should return empty site data when refererInfo is missing', function() { + delete this.defaultBidderRequest.refererInfo; + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaType': 'banner', + 'adUnitCode': 'div-gpt-ad-1438287399331-0', + 'sizes': [[300, 250]], + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + const openrtbRequest = JSON.parse(bidRequest.data); + + expect(openrtbRequest.site.domain).to.equal(''); + expect(openrtbRequest.site.page).to.equal(''); + expect(openrtbRequest.site.ref).to.equal(''); + }); + }); + + it('should return empty site.domain and site.page when refererInfo.stack is empty', function() { + this.defaultBidderRequest.refererInfo.stack = []; + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaType': 'banner', + 'adUnitCode': 'div-gpt-ad-1438287399331-0', + 'sizes': [[300, 250]], + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + const openrtbRequest = JSON.parse(bidRequest.data); + + expect(openrtbRequest.site.domain).to.equal(''); + expect(openrtbRequest.site.page).to.equal(''); + expect(openrtbRequest.site.ref).to.equal('Reference Page'); + }); + + it('should secure correctly', function() { + this.defaultBidderRequest.refererInfo.stack[0] = ['https://securesite.dvl']; + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaType': 'banner', + 'adUnitCode': 'div-gpt-ad-1438287399331-0', + 'sizes': [[300, 250]], + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead' + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + const openrtbRequest = JSON.parse(bidRequest.data); + + expect(openrtbRequest.imp[0].secure).to.equal(1); + }); + + it('should pass schain', function() { + var schain = { + 'ver': '1.0', + 'complete': 1, + 'nodes': [{ + 'asi': 'indirectseller.com', + 'sid': '00001', + 'hp': 1 + }, { + 'asi': 'indirectseller-2.com', + 'sid': '00002', + 'hp': 1 + }] + }; + var bidRequestList = [ + { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaType': 'banner', + 'adUnitCode': 'div-gpt-ad-1438287399331-0', + 'sizes': [[300, 250]], + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1, + 'bidId': '51ef8751f9aead', + 'schain': schain + } + ]; + + var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); + const openrtbRequest = JSON.parse(bidRequest.data); + + expect(openrtbRequest.source.ext.schain).to.deep.equal(schain); + }); + + describe('misc interpretResponse', function () { + it('No bid response', function() { + var noBidResponse = r1adapter.interpretResponse({ + 'body': '' + }); + expect(noBidResponse.length).to.equal(0); + }); + }); + + describe('isBidRequestValid', function () { + var bid = { + 'bidder': 'resultsmedia', + 'params': { + 'zoneId': 9999 + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250]] + } + }, + 'adUnitCode': 'bannerDiv' + }; + + it('should return true when required params found', function () { + expect(r1adapter.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when placementId missing', function () { + delete bid.params.zoneId; + expect(r1adapter.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('getUserSyncs', function () { + it('returns an empty string', function () { + expect(r1adapter.getUserSyncs()).to.deep.equal([]); + }); + }); +}); From b7ec7f56785a5b77d97892a3e803ce4c30f1b3de Mon Sep 17 00:00:00 2001 From: "Isaac A. Dettman" Date: Thu, 30 Jan 2020 05:57:10 -0800 Subject: [PATCH 018/496] Fix for test console messages added by storedrequest (#4798) * change to allow number or string * fix to remove added console logs when running tests * reverted code from another update --- test/spec/auctionmanager_spec.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/spec/auctionmanager_spec.js b/test/spec/auctionmanager_spec.js index 657afa1cba9..a8e5c446db8 100644 --- a/test/spec/auctionmanager_spec.js +++ b/test/spec/auctionmanager_spec.js @@ -990,11 +990,19 @@ describe('auctionmanager.js', function () { let spec1; let auction; let ajaxStub; + let logMessageStub; + let logInfoStub; + let logWarnStub; + let logErrorStub; let bids = TEST_BIDS; let bids1 = [mockBid({ bidderCode: BIDDER_CODE1 })]; before(function () { + logMessageStub = sinon.stub(utils, 'logMessage'); + logInfoStub = sinon.stub(utils, 'logInfo'); + logWarnStub = sinon.stub(utils, 'logWarn'); + logErrorStub = sinon.stub(utils, 'logError'); let bidRequests = [ mockBidRequest(bids[0]), mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }) @@ -1006,6 +1014,10 @@ describe('auctionmanager.js', function () { }); after(function () { + logMessageStub.restore(); + logInfoStub.restore(); + logWarnStub.restore(); + logErrorStub.restore(); ajaxStub.restore(); adapterManager.makeBidRequests.restore(); }); @@ -1046,6 +1058,10 @@ describe('auctionmanager.js', function () { }); afterEach(function () { + logMessageStub.resetHistory(); + logInfoStub.resetHistory(); + logWarnStub.resetHistory(); + logErrorStub.resetHistory(); auctionModule.newAuction.restore(); config.resetConfig(); }); From 15216355b988e4c49c25cf4ee94287b8ac26bddc Mon Sep 17 00:00:00 2001 From: Kai Date: Thu, 30 Jan 2020 23:41:34 +0800 Subject: [PATCH 019/496] Bridgewell bid adapter: Prebid.js v3 support (#4748) * Bridgewell bid adapter: Prebid.js v3 support * fix 'valid' may not be boolean --- modules/bridgewellBidAdapter.js | 266 +++++ modules/bridgewellBidAdapter.md | 35 +- .../spec/modules/bridgewellBidAdapter_spec.js | 1014 +++++++++++++++++ 3 files changed, 1288 insertions(+), 27 deletions(-) create mode 100644 modules/bridgewellBidAdapter.js create mode 100644 test/spec/modules/bridgewellBidAdapter_spec.js diff --git a/modules/bridgewellBidAdapter.js b/modules/bridgewellBidAdapter.js new file mode 100644 index 00000000000..a988fad1478 --- /dev/null +++ b/modules/bridgewellBidAdapter.js @@ -0,0 +1,266 @@ +import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory'; +import { BANNER, NATIVE } from '../src/mediaTypes'; +import find from 'core-js/library/fn/array/find'; + +const BIDDER_CODE = 'bridgewell'; +const REQUEST_ENDPOINT = 'https://prebid.scupio.com/recweb/prebid.aspx?cb=' + Math.random(); +const BIDDER_VERSION = '0.0.2'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, NATIVE], + + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bid) { + let valid = false; + + if (bid && bid.params && bid.params.ChannelID) { + valid = true; + } + + return valid; + }, + + /** + * Make a server request from the list of BidRequests. + * + * @param {BidRequest[]} validBidRequests - an array of bids + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function (validBidRequests, bidderRequest) { + const adUnits = []; + utils._each(validBidRequests, function (bid) { + adUnits.push({ + ChannelID: bid.params.ChannelID, + mediaTypes: bid.mediaTypes || { + banner: { + sizes: bid.sizes + } + } + }); + }); + + let topUrl = ''; + if (bidderRequest && bidderRequest.refererInfo) { + topUrl = bidderRequest.refererInfo.referer; + } + + return { + method: 'POST', + url: REQUEST_ENDPOINT, + data: { + version: { + prebid: '$prebid.version$', + bridgewell: BIDDER_VERSION + }, + inIframe: utils.inIframe(), + url: topUrl, + referrer: getTopWindowReferrer(), + adUnits: adUnits + }, + validBidRequests: validBidRequests + }; + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @param {*} bidRequest + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function (serverResponse, bidRequest) { + const bidResponses = []; + + // map responses to requests + utils._each(bidRequest.validBidRequests, function (req) { + const bidResponse = {}; + + if (!serverResponse.body) { + return; + } + + let matchedResponse = find(serverResponse.body, function (res) { + let valid = false; + + if (res) { + let mediaTypes = req.mediaTypes; + if (res.width && res.height && mediaTypes) { + if (mediaTypes.native) { // dont care native sizes + valid = true; + } else if (mediaTypes.banner) { + if (mediaTypes.banner.sizes) { + let width = res.width; + let height = res.height; + let sizes = mediaTypes.banner.sizes; + // check response size validation + if (typeof sizes[0] === 'number') { // for foramt Array[Number] check + valid = width === sizes[0] && height === sizes[1]; + } else { // for format Array[Array[Number]] check + valid = !!find(sizes, function (size) { + return (width === size[0] && height === size[1]); + }); + } + } + } + } + } + + return valid; + }); + + if (matchedResponse) { + // check required parameters + if (typeof matchedResponse.cpm !== 'number') { + return; + } else if (typeof matchedResponse.netRevenue !== 'boolean') { + return; + } else if (typeof matchedResponse.currency !== 'string') { + return; + } else if (typeof matchedResponse.mediaType !== 'string') { + return; + } + + bidResponse.requestId = req.bidId; + bidResponse.cpm = matchedResponse.cpm; + bidResponse.width = matchedResponse.width; + bidResponse.height = matchedResponse.height; + bidResponse.ttl = matchedResponse.ttl; + bidResponse.creativeId = matchedResponse.id; + bidResponse.netRevenue = matchedResponse.netRevenue; + bidResponse.currency = matchedResponse.currency; + bidResponse.mediaType = matchedResponse.mediaType; + + // check required parameters by matchedResponse.mediaType + switch (matchedResponse.mediaType) { + case BANNER: + // check banner required parameters + if (typeof matchedResponse.ad !== 'string') { + return; + } + + bidResponse.ad = matchedResponse.ad; + break; + case NATIVE: + // check native required parameters + if (!matchedResponse.native) { + return; + } + + let reqNativeLayout = req.mediaTypes.native; + let resNative = matchedResponse.native; + + // check title + let title = reqNativeLayout.title; + if (title && title.required) { + if (typeof resNative.title !== 'string') { + return; + } else if (title.len && title.len < resNative.title.length) { + return; + } + } + + // check body + let body = reqNativeLayout.body; + if (body && body.required) { + if (typeof resNative.body !== 'string') { + return; + } + } + + // check image + let image = reqNativeLayout.image; + if (image && image.required) { + if (resNative.image) { + if (typeof resNative.image.url !== 'string') { // check image url + return; + } else { + if (resNative.image.width !== image.sizes[0] || resNative.image.height !== image.sizes[1]) { // check image sizes + return; + } + } + } else { + return; + } + } + + // check sponsoredBy + let sponsoredBy = reqNativeLayout.sponsoredBy; + if (sponsoredBy && sponsoredBy.required) { + if (typeof resNative.sponsoredBy !== 'string') { + return; + } + } + + // check icon + let icon = reqNativeLayout.icon; + if (icon && icon.required) { + if (resNative.icon) { + if (typeof resNative.icon.url !== 'string') { // check icon url + return; + } else { + if (resNative.icon.width !== icon.sizes[0] || resNative.icon.height !== icon.sizes[0]) { // check image sizes + return; + } + } + } else { + return; + } + } + + // check clickUrl + if (typeof resNative.clickUrl !== 'string') { + return; + } + + // check clickTracker + let clickTrackers = resNative.clickTrackers; + if (clickTrackers) { + if (clickTrackers.length === 0) { + return; + } + } else { + return; + } + + // check impressionTrackers + let impressionTrackers = resNative.impressionTrackers; + if (impressionTrackers) { + if (impressionTrackers.length === 0) { + return; + } + } else { + return; + } + + bidResponse.native = matchedResponse.native; + + break; + + default: // response mediaType is not supported + return; + } + + bidResponses.push(bidResponse); + } + }); + + return bidResponses; + } +}; + +function getTopWindowReferrer() { + try { + return window.top.document.referrer; + } catch (e) { + return ''; + } +} + +registerBidder(spec); diff --git a/modules/bridgewellBidAdapter.md b/modules/bridgewellBidAdapter.md index 014be62ccef..6bcab4b8820 100644 --- a/modules/bridgewellBidAdapter.md +++ b/modules/bridgewellBidAdapter.md @@ -1,8 +1,8 @@ # Overview -Module Name: Bridgewell Bidder Adapter -Module Type: Bidder Adapter -Maintainer: kuchunchou@bridgewell.com +Module Name: Bridgewell Bidder Adapter +Module Type: Bidder Adapter +Maintainer: scupio@bridgewell.com # Description @@ -12,34 +12,15 @@ Module that connects to Bridgewell demand source to fetch bids. ``` var adUnits = [{ code: 'test-div', - sizes: [ - [300, 250] - ], - bids: [{ - bidder: 'bridgewell', - params: { - ChannelID: 'CgUxMjMzOBIBNiIFcGVubnkqCQisAhD6ARoBOQ' - } - }] - }, { - code: 'test-div', - sizes: [ - [728, 90] - ], - bids: [{ - bidder: 'bridgewell', - params: { - ChannelID: 'CgUxMjMzOBIBNiIGcGVubnkzKggI2AUQWhoBOQ', - cpmWeight: 1.5 + mediaTypes: { + banner: { + sizes: [300, 250] } - }] - }, { - code: 'test-div', - sizes: [728, 90], + }, bids: [{ bidder: 'bridgewell', params: { - ChannelID: 'CgUxMjMzOBIBNiIGcGVubnkzKggI2AUQWhoBOQ' + ChannelID: 'CgUxMjMzOBIBNiIFcGVubnkqCQisAhD6ARoBOQ' } }] }, { diff --git a/test/spec/modules/bridgewellBidAdapter_spec.js b/test/spec/modules/bridgewellBidAdapter_spec.js new file mode 100644 index 00000000000..512777cf796 --- /dev/null +++ b/test/spec/modules/bridgewellBidAdapter_spec.js @@ -0,0 +1,1014 @@ +import { expect } from 'chai'; +import { spec } from 'modules/bridgewellBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; + +describe('bridgewellBidAdapter', function () { + const adapter = newBidder(spec); + + describe('inherited functions', function () { + it('exists and is a function', function () { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', function () { + it('should return true when required params found', function () { + const validTag = { + 'bidder': 'bridgewell', + 'params': { + 'ChannelID': 'CLJgEAYYvxUiBXBlbm55KgkIrAIQ-gEaATk' + }, + }; + expect(spec.isBidRequestValid(validTag)).to.equal(true); + }); + + it('should return false when required params not found', function () { + const invalidTag = { + 'bidder': 'bridgewell', + 'params': {}, + }; + expect(spec.isBidRequestValid(invalidTag)).to.equal(false); + }); + + it('should return false when required params are empty', function () { + const invalidTag = { + 'bidder': 'bridgewell', + 'params': { + 'ChannelID': '', + }, + }; + expect(spec.isBidRequestValid(invalidTag)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + const bidRequests = [ + { + 'bidder': 'bridgewell', + 'params': { + 'ChannelID': 'CgUxMjMzOBIBNiIGcGVubnkzKggI2AUQWhoBOQ', + }, + 'adUnitCode': 'adunit-code-2', + 'mediaTypes': { + 'banner': { + 'sizes': [728, 90] + } + }, + 'bidId': '3150ccb55da321', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }, + { + 'bidder': 'bridgewell', + 'params': { + 'ChannelID': 'CgUxMjMzOBIBNiIGcGVubnkzKggI2AUQWhoBOQ', + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [1, 1], + 'mediaTypes': { + 'native': { + 'title': { + 'required': true, + 'len': 15 + }, + 'body': { + 'required': true + }, + 'image': { + 'required': true, + 'sizes': [150, 150] + }, + 'icon': { + 'required': true, + 'sizes': [50, 50] + }, + 'clickUrl': { + 'required': true + }, + 'cta': { + 'required': true + }, + 'sponsoredBy': { + 'required': true + } + } + }, + 'bidId': '3150ccb55da321', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + } + ]; + + it('should attach valid params to the tag', function () { + const bidderRequest = { + refererInfo: { + referer: 'https://www.bridgewell.com/' + } + } + const request = spec.buildRequests(bidRequests, bidderRequest); + const payload = request.data; + + expect(payload).to.be.an('object'); + expect(payload.adUnits).to.be.an('array'); + expect(payload.url).to.exist.and.to.equal('https://www.bridgewell.com/'); + for (let i = 0, max_i = payload.adUnits.length; i < max_i; i++) { + expect(payload.adUnits[i]).to.have.property('ChannelID').that.is.a('string'); + } + }); + + it('should attach validBidRequests to the tag', function () { + const request = spec.buildRequests(bidRequests); + const validBidRequests = request.validBidRequests; + expect(validBidRequests).to.deep.equal(bidRequests); + }); + }); + + describe('interpretResponse', function () { + const nativeBidRequests = { + validBidRequests: [ + { + 'bidder': 'bridgewell', + 'params': { + 'ChannelID': 'CgUxMjMzOBIBNiIGcGVubnkzKggI2AUQWhoBOQ', + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [1, 1], + 'mediaTypes': { + 'native': { + 'title': { + 'required': true, + 'len': 15 + }, + 'body': { + 'required': true + }, + 'image': { + 'required': true, + 'sizes': [150, 150] + }, + 'icon': { + 'required': true, + 'sizes': [50, 50] + }, + 'clickUrl': { + 'required': true + }, + 'cta': { + 'required': true + }, + 'sponsoredBy': { + 'required': true + } + } + }, + 'bidId': '3150ccb55da321', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }, + ] + }; + const nativeServerResponses = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + const bannerBidRequests = { + validBidRequests: [ + { + 'mediaTypes': { + 'banner': { + 'sizes': [300, 250] + } + }, + 'bidId': '3150ccb55da321', + }, + ] + }; + const bannerServerResponses = [ + { + 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', + 'bidder_code': 'bridgewell', + 'cpm': 5.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 360, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + it('should return all required parameters', function () { + const result = spec.interpretResponse({ 'body': nativeServerResponses }, nativeBidRequests); + + expect(result[0].requestId).to.equal('3150ccb55da321'); + expect(result[0].cpm).to.equal(7.0); + expect(result[0].width).to.equal(1); + expect(result[0].height).to.equal(1); + expect(result[0].ttl).to.equal(400); + expect(result[0].creativeId).to.equal('0e4048d3-5c74-4380-a21a-00ba35629f7d'); + expect(result[0].netRevenue).to.equal(true); + expect(result[0].currency).to.equal('NTD'); + expect(result[0].mediaType).to.equal('native'); + expect(result[0].native.image.url).to.equal('https://img.scupio.com/test/test-image.jpg'); + }); + + it('should return all required parameters banner', function () { + const result = spec.interpretResponse({ 'body': bannerServerResponses }, bannerBidRequests); + + expect(result[0].requestId).to.equal('3150ccb55da321'); + expect(result[0].cpm).to.equal(5.0); + expect(result[0].width).to.equal(300); + expect(result[0].height).to.equal(250); + expect(result[0].ttl).to.equal(360); + expect(result[0].creativeId).to.equal('e5b10774-32bf-4931-85ee-05095e8cff21'); + expect(result[0].netRevenue).to.equal(true); + expect(result[0].currency).to.equal('NTD'); + expect(result[0].mediaType).to.equal('banner'); + expect(result[0].ad).to.equal('
test 300x250
'); + }); + + it('should give up bid if server response is undefiend', function () { + let result = spec.interpretResponse({ 'body': undefined }, bannerBidRequests); + + expect(result).to.deep.equal([]); + }); + + it('should give up bid if request sizes is missing', function () { + const request = { + validBidRequests: [ + { + 'mediaTypes': { + 'banner': {} + }, + 'bidId': '3150ccb55da321', + }, + ] + }; + const result = spec.interpretResponse({ 'body': bannerServerResponses }, request); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if response sizes is invalid', function () { + const request = { + validBidRequests: [ + { + 'mediaTypes': { + 'banner': { + 'sizes': [728, 90] + } + }, + 'bidId': '3150ccb55da321', + }, + ] + }; + const result = spec.interpretResponse({ 'body': bannerServerResponses }, request); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if cpm is missing', function () { + const response = [ + { + 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', + 'bidder_code': 'bridgewell', + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 360, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if width or height is missing', function () { + const response = [ + { + 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', + 'bidder_code': 'bridgewell', + 'cpm': 5.0, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 360, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if ad is missing', function () { + const response = [ + { + 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', + 'bidder_code': 'bridgewell', + 'cpm': 5.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ttl': 360, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if revenue mode is missing', function () { + const response = [ + { + 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', + 'bidder_code': 'bridgewell', + 'cpm': 5.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 360, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if currency is missing', function () { + const response = [ + { + 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', + 'bidder_code': 'bridgewell', + 'cpm': 5.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 360, + 'netRevenue': true, + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if mediaType is missing', function () { + const response = [ + { + 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', + 'bidder_code': 'bridgewell', + 'cpm': 5.0, + 'width': 300, + 'height': 250, + 'ad': '
test 300x250
', + 'ttl': 360, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if mediaType is not support', function () { + const responses = [ + { + 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', + 'bidder_code': 'bridgewell', + 'cpm': 5.0, + 'width': 300, + 'height': 250, + 'mediaType': 'superNiceAd', + 'ad': '
test 300x250
', + 'ttl': 360, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': responses }, bannerBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if property native of mediaType native is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native title is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native title is too long', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-titletest-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native body is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native image url is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native image is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native image is empty', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': {}, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native image sizes is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg' + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native sponsoredBy is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native icon is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native icon url is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native icon sizes is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native clickUrl is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native clickTrackers is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native clickTrackers is empty', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': [], + 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native impressionTrackers is missing', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + + it('should give up bid if native impressionTrackers is empty', function () { + const response = [ + { + 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 1, + 'height': 1, + 'mediaType': 'native', + 'native': { + 'image': { + 'url': 'https://img.scupio.com/test/test-image.jpg', + 'width': 150, + 'height': 150 + }, + 'title': 'test-title', + 'sponsoredBy': 'test-sponsoredBy', + 'body': 'test-body', + 'icon': { + 'url': 'https://img.scupio.com/test/test-icon.jpg', + 'width': 50, + 'height': 50 + }, + 'clickUrl': 'https://img.scupio.com/test-clickUrl', + 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], + 'impressionTrackers': [] + }, + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, + ]; + + const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); + expect(result).to.deep.equal([]); + }); + }); +}); From 9c08696da84020b15f344eaa80543fcfde52529a Mon Sep 17 00:00:00 2001 From: Matt Kendall <1870166+mkendall07@users.noreply.github.com> Date: Thu, 30 Jan 2020 14:38:30 -0500 Subject: [PATCH 020/496] 3.6.0 pre --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b3a5c7a5060..56aded033c0 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.5.0", + "version": "3.6.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 613b99badef72a37119f567618afb8e6e7f244fd Mon Sep 17 00:00:00 2001 From: Audiencerun <57719351+audiencerun@users.noreply.github.com> Date: Fri, 31 Jan 2020 17:45:48 +0100 Subject: [PATCH 021/496] Audiencerun bid adapter (#4761) * New adapter AudienceRun * Fix issues AudiencerunAdapter * Fix issues AudiencerunAdapter * Fix issues AudiencerunAdapter * Fix issues AudiencerunAdapter --- modules/audiencerunBidAdapter.js | 142 ++++++++++++ modules/audiencerunBidAdapter.md | 48 +++++ .../modules/audiencerunBidAdapter_spec.js | 204 ++++++++++++++++++ 3 files changed, 394 insertions(+) create mode 100644 modules/audiencerunBidAdapter.js create mode 100644 modules/audiencerunBidAdapter.md create mode 100644 test/spec/modules/audiencerunBidAdapter_spec.js diff --git a/modules/audiencerunBidAdapter.js b/modules/audiencerunBidAdapter.js new file mode 100644 index 00000000000..83e805d8eb5 --- /dev/null +++ b/modules/audiencerunBidAdapter.js @@ -0,0 +1,142 @@ +import * as utils from '../src/utils'; +import { config } from '../src/config'; +import { registerBidder } from '../src/adapters/bidderFactory'; +import { BANNER } from '../src/mediaTypes'; + +const BIDDER_CODE = 'audiencerun'; +const ENDPOINT_URL = 'https://d.audiencerun.com/prebid'; + +export const spec = { + version: '1.0.0', + code: BIDDER_CODE, + supportedMediaTypes: [BANNER], + + /** + * Determines whether or not the given bid request is valid. + * + * @param {object} bid The bid to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bid) { + let isValid = true; + if (!utils.deepAccess(bid, 'params.zoneId')) { + utils.logError('AudienceRun zoneId parameter is required. Bid aborted.'); + isValid = false; + } + return isValid; + }, + + /** + * Make a server request from the list of BidRequests. + * + * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. + * @param {*} bidderRequest + * @return {ServerRequest} Info describing the request to the server. + */ + buildRequests: function(bidRequests, bidderRequest) { + const bids = bidRequests.map(bid => { + const sizes = utils.deepAccess(bid, 'mediaTypes.banner.sizes', []); + return { + zoneId: utils.getValue(bid.params, 'zoneId'), + sizes: sizes.map(size => ({ + w: size[0], + h: size[1] + })), + bidfloor: bid.params.bidfloor || 0.0, + bidId: bid.bidId, + bidderRequestId: utils.getBidIdParameter('bidderRequestId', bid), + adUnitCode: utils.getBidIdParameter('adUnitCode', bid), + auctionId: utils.getBidIdParameter('auctionId', bid), + transactionId: utils.getBidIdParameter('transactionId', bid) + }; + }); + + const payload = { + libVersion: this.version, + referer: bidderRequest.refererInfo ? bidderRequest.refererInfo.referer || null : null, + currencyCode: config.getConfig('currency.adServerCurrency'), + timeout: config.getConfig('bidderTimeout'), + bids + }; + + if (bidderRequest && bidderRequest.gdprConsent) { + payload.gdpr = { + consent: bidderRequest.gdprConsent.consentString, + applies: bidderRequest.gdprConsent.gdprApplies + }; + } else { + payload.gdpr = { + consent: '' + } + } + + return { + method: 'POST', + url: ENDPOINT_URL, + data: JSON.stringify(payload), + options: { + withCredentials: true + } + }; + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function (serverResponse, bidRequest) { + const bids = []; + utils._each(serverResponse.body.bid, function (bidObject) { + if (!bidObject.cpm || bidObject.cpm === null || !bidObject.adm) { + return; + } + + const bid = {}; + + bid.ad = bidObject.adm; + bid.mediaType = BANNER; + + // Common properties + bid.requestId = bidObject.bidId; + bid.adId = bidObject.zoneId; + bid.cpm = parseFloat(bidObject.cpm); + bid.creativeId = bidObject.crid; + bid.currency = bidObject.currency ? bidObject.currency.toUpperCase() : 'USD'; + + bid.height = bidObject.h; + bid.width = bidObject.w; + bid.netRevenue = bidObject.isNet ? bidObject.isNet : false; + bid.ttl = 300; + + bids.push(bid); + }); + return bids; + }, + + /** + * Register the user sync pixels which should be dropped after the auction. + * + * @param {SyncOptions} syncOptions Which user syncs are allowed? + * @param {ServerResponse[]} serverResponses List of server's responses. + * @return {UserSync[]} The user syncs which should be dropped. + */ + getUserSyncs: function(syncOptions, serverResponses) { + if (!serverResponses || !serverResponses.length) return []; + + const syncs = []; + serverResponses.forEach(response => { + response.body.bid.forEach(bidObject => { + syncs.push({ + type: 'iframe', + url: bidObject.syncUrl + }); + }); + }); + + return syncs; + } +}; + +registerBidder(spec); diff --git a/modules/audiencerunBidAdapter.md b/modules/audiencerunBidAdapter.md new file mode 100644 index 00000000000..3704922fdd5 --- /dev/null +++ b/modules/audiencerunBidAdapter.md @@ -0,0 +1,48 @@ +# Overview + +**Module Name**: AudienceRun Bidder Adapter +**Module Type**: Bidder Adapter +**Maintainer**: prebid@audiencerun.com + +# Description + +Module that connects to AudienceRun demand sources + +Use `audiencerun` as bidder. + +`zoneId` is required and must be 10 alphanumeric characters. + +## AdUnits configuration example +``` + var adUnits = [{ + code: 'ad-slot-300x600', + mediaTypes: { + banner: { + sizes: [ + [300, 600] + ], + } + }, + bids: [{ + bidder: 'audiencerun', + params: { + zoneId: 'xtov2mgij0' + } + }] + },{ + code: 'ad-slot-728x90', + mediaTypes: { + banner: { + sizes: [ + [728, 90] + ], + } + }, + bids: [{ + bidder: 'audiencerun', + params: { + zoneId: 'u4q6z6u97b' + } + }] + }]; +``` diff --git a/test/spec/modules/audiencerunBidAdapter_spec.js b/test/spec/modules/audiencerunBidAdapter_spec.js new file mode 100644 index 00000000000..212a081f0ce --- /dev/null +++ b/test/spec/modules/audiencerunBidAdapter_spec.js @@ -0,0 +1,204 @@ +import { expect } from 'chai'; +import { spec } from 'modules/audiencerunBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; + +const ENDPOINT = 'https://d.audiencerun.com/prebid'; + +const BID_SERVER_RESPONSE = { + body: { + bid: [ + { + 'bidId': '51ef8751f9aead', + 'zoneId': '12345abcde', + 'adId': '1234', + 'crid': '5678', + 'cpm': 8.021951999999999999, + 'currency': 'USD', + 'w': 728, + 'h': 90, + 'isNet': false, + 'buying_type': 'rtb', + 'syncUrl': 'https://ac.audiencerun.com/f/sync.html', + 'adm': '' + } + ] + } +}; + +describe('AudienceRun bid adapter tests', function() { + const adapter = newBidder(spec); + + describe('inherited functions', function() { + it('exists and is a function', function() { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', function() { + let bid = { + 'bidder': 'audiencerun', + 'params': { + 'zoneId': '12345abcde' + }, + 'adUnitCode': 'adunit-code', + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250], [300, 600]] + } + }, + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + 'creativeId': 'er2ee' + }; + + it('should return true when required params found', function() { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return true when zoneId is valid', function() { + let bid = Object.assign({}, bid); + delete bid.params; + bid.params = { + 'zoneId': '12345abcde' + }; + + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when required params are not passed', function() { + let bid = Object.assign({}, bid); + delete bid.params; + + bid.params = {}; + + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function() { + let bidRequests = [ + { + 'bidder': 'audiencerun', + 'bidId': '51ef8751f9aead', + 'params': { + 'zoneId': '12345abcde' + }, + 'adUnitCode': 'div-gpt-ad-1460505748561-0', + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'mediaTypes': { + 'banner': { + 'sizes': [[320, 50], [300, 250], [300, 600]] + } + }, + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757', + 'bidRequestsCount': 1 + } + ]; + + it('sends a valid bid request to ENDPOINT via POST', function() { + const request = spec.buildRequests(bidRequests, { + gdprConsent: { + consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', + gdprApplies: true + }, + refererInfo: { + canonicalUrl: 'https://example.com/canonical', + referer: 'https://example.com' + } + }); + + expect(request.url).to.equal(ENDPOINT); + expect(request.method).to.equal('POST'); + + const payload = JSON.parse(request.data); + expect(payload.gdpr).to.exist; + + expect(payload.bids).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(payload.referer).to.exist; + + const bid = payload.bids[0]; + expect(bid).to.exist; + expect(bid).to.have.property('bidId'); + expect(bid).to.have.property('zoneId'); + expect(bid).to.have.property('sizes'); + expect(bid.sizes[0].w).to.be.a('number'); + expect(bid.sizes[0].h).to.be.a('number'); + }); + + it('should send GDPR to endpoint and honor gdprApplies value', function() { + let consentString = 'bogusConsent'; + let bidderRequest = { + 'gdprConsent': { + 'consentString': consentString, + 'gdprApplies': true + } + }; + + const request = spec.buildRequests(bidRequests, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.gdpr).to.exist; + expect(payload.gdpr.consent).to.equal(consentString); + expect(payload.gdpr.applies).to.equal(true); + + let bidderRequest2 = { + 'gdprConsent': { + 'consentString': consentString, + 'gdprApplies': false + } + }; + + const request2 = spec.buildRequests(bidRequests, bidderRequest2); + const payload2 = JSON.parse(request2.data); + + expect(payload2.gdpr).to.exist; + expect(payload2.gdpr.consent).to.equal(consentString); + expect(payload2.gdpr.applies).to.equal(false); + }); + }); + + describe('interpretResponse', function () { + const expectedResponse = [{ + 'requestId': '51ef8751f9aead', + 'adId': '12345abcde', + 'cpm': 8.021951999999999999, + 'width': '728', + 'height': '90', + 'creativeId': '5678', + 'currency': 'USD', + 'netRevenue': false, + 'ttl': 300, + 'ad': '', + 'mediaType': 'banner' + }]; + + it('should get the correct bid response by display ad', function () { + let result = spec.interpretResponse(BID_SERVER_RESPONSE); + expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); + }); + + it('handles empty bid response', function () { + const response = { + body: {} + }; + let result = spec.interpretResponse(response); + expect(result.length).to.equal(0); + }); + }); + + describe('getUserSyncs', function () { + const serverResponses = [ BID_SERVER_RESPONSE ]; + const syncOptions = { iframeEnabled: true }; + + it('should return empty if no server responses', function() { + const syncs = spec.getUserSyncs(syncOptions, []); + expect(syncs).to.deep.equal([]) + }); + + it('should return user syncs', function () { + const syncs = spec.getUserSyncs(syncOptions, serverResponses); + expect(syncs).to.deep.equal([{type: 'iframe', url: 'https://ac.audiencerun.com/f/sync.html'}]) + }); + }); +}); From a9b379cccff70790e3cd556c262c3f448f5788dd Mon Sep 17 00:00:00 2001 From: ariellenramirez <48992569+ariellenramirez@users.noreply.github.com> Date: Fri, 31 Jan 2020 16:15:08 -0500 Subject: [PATCH 022/496] added criteo id and tests (#4786) --- modules/tripleliftBidAdapter.js | 7 +++- .../spec/modules/tripleliftBidAdapter_spec.js | 33 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/modules/tripleliftBidAdapter.js b/modules/tripleliftBidAdapter.js index 7120929059d..8cd1dda1120 100644 --- a/modules/tripleliftBidAdapter.js +++ b/modules/tripleliftBidAdapter.js @@ -115,7 +115,8 @@ function _buildPostBody(bidRequests) { let eids = [ ...getUnifiedIdEids(bidRequests), - ...getIdentityLinkEids(bidRequests) + ...getIdentityLinkEids(bidRequests), + ...getCriteoEids(bidRequests) ]; if (eids.length > 0) { @@ -140,6 +141,10 @@ function getIdentityLinkEids(bidRequests) { return getEids(bidRequests, 'idl_env', 'liveramp.com', 'idl'); } +function getCriteoEids(bidRequests) { + return getEids(bidRequests, 'criteoId', 'criteo.com', 'criteoId'); +} + function getEids(bidRequests, type, source, rtiPartner) { return bidRequests .map(getUserId(type)) // bids -> userIds of a certain type diff --git a/test/spec/modules/tripleliftBidAdapter_spec.js b/test/spec/modules/tripleliftBidAdapter_spec.js index 17dd64b8deb..fc8608f522a 100644 --- a/test/spec/modules/tripleliftBidAdapter_spec.js +++ b/test/spec/modules/tripleliftBidAdapter_spec.js @@ -152,11 +152,22 @@ describe('triplelift adapter', function () { expect(payload.user).to.deep.equal({ext: {eids: [{source: 'liveramp.com', uids: [{id, ext: {rtiPartner: 'idl'}}]}]}}); }); - it('should add both tdid and idl_env to the payload if both are included', function () { + it('should add criteoId to the payload if included', function () { + const id = '53e30ea700424f7bbdd793b02abc5d7'; + bidRequests[0].userId.criteoId = id; + const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); + const payload = request.data; + expect(payload).to.exist; + expect(payload.user).to.deep.equal({ext: {eids: [{source: 'criteo.com', uids: [{id, ext: {rtiPartner: 'criteoId'}}]}]}}); + }); + + it('should add tdid, idl_env and criteoId to the payload if both are included', function () { const tdidId = '6bca7f6b-a98a-46c0-be05-6020f7604598'; const idlEnvId = 'XY6104gr0njcH9UDIR7ysFFJcm2XNpqeJTYslleJ_cMlsFOfZI'; + const criteoId = '53e30ea700424f7bbdd793b02abc5d7'; bidRequests[0].userId.tdid = tdidId; bidRequests[0].userId.idl_env = idlEnvId; + bidRequests[0].userId.criteoId = criteoId; const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); const payload = request.data; @@ -182,6 +193,15 @@ describe('triplelift adapter', function () { ext: { rtiPartner: 'idl' } } ] + }, + { + source: 'criteo.com', + uids: [ + { + id: criteoId, + ext: { rtiPartner: 'criteoId' } + } + ] } ] } @@ -191,10 +211,12 @@ describe('triplelift adapter', function () { it('should add user ids from multiple bid requests', function () { const tdidId = '6bca7f6b-a98a-46c0-be05-6020f7604598'; const idlEnvId = 'XY6104gr0njcH9UDIR7ysFFJcm2XNpqeJTYslleJ_cMlsFOfZI'; + const criteoId = '53e30ea700424f7bbdd793b02abc5d7'; const bidRequestsMultiple = [ { ...bidRequests[0], userId: { tdid: tdidId } }, { ...bidRequests[0], userId: { idl_env: idlEnvId } }, + { ...bidRequests[0], userId: { criteoId: criteoId } } ]; const request = tripleliftAdapterSpec.buildRequests(bidRequestsMultiple, bidderRequest); @@ -220,6 +242,15 @@ describe('triplelift adapter', function () { ext: { rtiPartner: 'idl' } } ] + }, + { + source: 'criteo.com', + uids: [ + { + id: criteoId, + ext: { rtiPartner: 'criteoId' } + } + ] } ] } From 14dcedd616c1b5208ec19c57b58a4f2668644bc2 Mon Sep 17 00:00:00 2001 From: daisato-tsumiki Date: Sat, 1 Feb 2020 06:54:09 +0900 Subject: [PATCH 023/496] ByPlay adapter (#4646) * byplay adapter * remove Promise * remove tracker * fix unused import * change endpoint url * add test parameter --- modules/byplayBidAdapter.js | 67 ++++++++++++++++ modules/byplayBidAdapter.md | 37 +++++++++ test/spec/modules/byplayBidAdapter_spec.js | 93 ++++++++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100644 modules/byplayBidAdapter.js create mode 100644 modules/byplayBidAdapter.md create mode 100644 test/spec/modules/byplayBidAdapter_spec.js diff --git a/modules/byplayBidAdapter.js b/modules/byplayBidAdapter.js new file mode 100644 index 00000000000..324d2a14b49 --- /dev/null +++ b/modules/byplayBidAdapter.js @@ -0,0 +1,67 @@ +import { config } from '../src/config'; +import { registerBidder } from '../src/adapters/bidderFactory'; +import { Renderer } from '../src/Renderer'; +import { VIDEO } from '../src/mediaTypes'; + +const BIDDER_CODE = 'byplay'; +const ENDPOINT_URL = 'https://prebid.byplay.net/bidder'; +const VIDEO_PLAYER_URL = 'https://cdn.byplay.net/prebid-byplay-v2.js'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [VIDEO], + isBidRequestValid: (bid) => { + return !!bid.params.sectionId; + }, + buildRequests: function(validBidRequests) { + return validBidRequests.map(req => { + const payload = { + requestId: req.bidId, + sectionId: req.params.sectionId, + ...(req.params.env ? { env: req.params.env } : {}) + }; + + return { + method: 'POST', + url: ENDPOINT_URL, + data: JSON.stringify(payload), + options: { + withCredentials: false + } + }; + }); + }, + interpretResponse: (serverResponse, bidderRequest) => { + const response = serverResponse.body; + const data = JSON.parse(bidderRequest.data); + const bidResponse = { + requestId: data.requestId, + cpm: response.cpm, + width: response.width, + height: response.height, + creativeId: response.creativeId || '0', + ttl: config.getConfig('_bidderTimeout'), + currency: 'JPY', + netRevenue: response.netRevenue, + mediaType: VIDEO, + vastXml: response.vastXml, + renderer: createRenderer() + }; + + return [bidResponse]; + } +}; + +function createRenderer() { + const renderer = Renderer.install({ url: VIDEO_PLAYER_URL }); + + renderer.setRender(bid => { + bid.renderer.push(() => { + adtagRender(bid.vastXml); + }); + }); + + return renderer; +} + +registerBidder(spec); diff --git a/modules/byplayBidAdapter.md b/modules/byplayBidAdapter.md new file mode 100644 index 00000000000..9e1666f5161 --- /dev/null +++ b/modules/byplayBidAdapter.md @@ -0,0 +1,37 @@ +# Overview + +``` +Module Name: ByPlay Bidder Adapter +Module Type: Bidder Adapter +Maintainer: byplayers@tsumikiinc.com +``` + +# Description + +Connects to ByPlay exchange for bids. + +ByPlay bid adapter supports Video. + +# Test Parameters +``` + const adUnits = [ + { + code: 'byplay-ad', + mediaTypes: { + video: { + playerSize: [400, 225], + context: 'outstream' + } + }, + bids: [ + { + bidder: 'byplay' + params: { + sectionId: '7986', + env: 'dev' + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/byplayBidAdapter_spec.js b/test/spec/modules/byplayBidAdapter_spec.js new file mode 100644 index 00000000000..21249c0c9f2 --- /dev/null +++ b/test/spec/modules/byplayBidAdapter_spec.js @@ -0,0 +1,93 @@ +import { expect } from 'chai'; +import { spec } from 'modules/byplayBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; +import * as bidderFactory from 'src/adapters/bidderFactory'; + +describe('byplayBidAdapter', () => { + describe('isBidRequestValid', () => { + describe('exist sectionId', () => { + const bid = { + 'bidder': 'byplay', + 'params': { + 'sectionId': '11111' + }, + }; + + it('should equal true', () => { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + }); + + describe('not exist sectionId', () => { + const bid = { + 'bidder': 'byplay', + 'params': { + }, + }; + + it('should equal false', () => { + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + }); + + describe('buildRequests', () => { + const bids = [ + { + 'bidder': 'byplay', + 'bidId': '1234', + 'params': { + 'sectionId': '1111' + }, + } + ]; + + const request = spec.buildRequests(bids); + + it('should return POST', () => { + expect(request[0].method).to.equal('POST'); + }); + + it('should return data', () => { + expect(request[0].data).to.equal('{"requestId":"1234","sectionId":"1111"}'); + }); + }); + + describe('interpretResponse', () => { + const serverResponse = { + body: { + 'cpm': 1500, + 'width': 320, + 'height': 180, + 'netRevenue': true, + 'creativeId': '1', + 'requestId': '209c1fb5ad88f5', + 'vastXml': '' + } + }; + + const bidderRequest = { + 'method': 'GET', + 'url': 'https://tasp0g98f2.execute-api.ap-northeast-1.amazonaws.com/v1/bidder', + 'data': '{"requestId":"209c1fb5ad88f5","sectionId":7986}' + }; + + const result = spec.interpretResponse(serverResponse, bidderRequest); + + it('should return Array', () => { + expect(Array.isArray(result)).to.equal(true); + }); + + it('should get the correct bid response', () => { + expect(result[0].cpm).to.equal(1500); + expect(result[0].creativeId).to.equal('1'); + expect(result[0].width).to.equal(320); + expect(result[0].height).to.equal(180); + expect(result[0].mediaType).to.equal('video'); + expect(result[0].netRevenue).to.equal(true); + expect(result[0].requestId).to.equal('209c1fb5ad88f5'); + expect(result[0].ttl).to.equal(3000); + expect(result[0].vastXml).to.equal(''); + }); + }); +}); From f80f3ab5f80acafffe95539a0fb7641aa672540d Mon Sep 17 00:00:00 2001 From: Mike Chowla Date: Fri, 31 Jan 2020 14:01:18 -0800 Subject: [PATCH 024/496] Revert "ByPlay adapter (#4646)" due to lint failure This reverts commit 14dcedd616c1b5208ec19c57b58a4f2668644bc2. --- modules/byplayBidAdapter.js | 67 ---------------- modules/byplayBidAdapter.md | 37 --------- test/spec/modules/byplayBidAdapter_spec.js | 93 ---------------------- 3 files changed, 197 deletions(-) delete mode 100644 modules/byplayBidAdapter.js delete mode 100644 modules/byplayBidAdapter.md delete mode 100644 test/spec/modules/byplayBidAdapter_spec.js diff --git a/modules/byplayBidAdapter.js b/modules/byplayBidAdapter.js deleted file mode 100644 index 324d2a14b49..00000000000 --- a/modules/byplayBidAdapter.js +++ /dev/null @@ -1,67 +0,0 @@ -import { config } from '../src/config'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { Renderer } from '../src/Renderer'; -import { VIDEO } from '../src/mediaTypes'; - -const BIDDER_CODE = 'byplay'; -const ENDPOINT_URL = 'https://prebid.byplay.net/bidder'; -const VIDEO_PLAYER_URL = 'https://cdn.byplay.net/prebid-byplay-v2.js'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [VIDEO], - isBidRequestValid: (bid) => { - return !!bid.params.sectionId; - }, - buildRequests: function(validBidRequests) { - return validBidRequests.map(req => { - const payload = { - requestId: req.bidId, - sectionId: req.params.sectionId, - ...(req.params.env ? { env: req.params.env } : {}) - }; - - return { - method: 'POST', - url: ENDPOINT_URL, - data: JSON.stringify(payload), - options: { - withCredentials: false - } - }; - }); - }, - interpretResponse: (serverResponse, bidderRequest) => { - const response = serverResponse.body; - const data = JSON.parse(bidderRequest.data); - const bidResponse = { - requestId: data.requestId, - cpm: response.cpm, - width: response.width, - height: response.height, - creativeId: response.creativeId || '0', - ttl: config.getConfig('_bidderTimeout'), - currency: 'JPY', - netRevenue: response.netRevenue, - mediaType: VIDEO, - vastXml: response.vastXml, - renderer: createRenderer() - }; - - return [bidResponse]; - } -}; - -function createRenderer() { - const renderer = Renderer.install({ url: VIDEO_PLAYER_URL }); - - renderer.setRender(bid => { - bid.renderer.push(() => { - adtagRender(bid.vastXml); - }); - }); - - return renderer; -} - -registerBidder(spec); diff --git a/modules/byplayBidAdapter.md b/modules/byplayBidAdapter.md deleted file mode 100644 index 9e1666f5161..00000000000 --- a/modules/byplayBidAdapter.md +++ /dev/null @@ -1,37 +0,0 @@ -# Overview - -``` -Module Name: ByPlay Bidder Adapter -Module Type: Bidder Adapter -Maintainer: byplayers@tsumikiinc.com -``` - -# Description - -Connects to ByPlay exchange for bids. - -ByPlay bid adapter supports Video. - -# Test Parameters -``` - const adUnits = [ - { - code: 'byplay-ad', - mediaTypes: { - video: { - playerSize: [400, 225], - context: 'outstream' - } - }, - bids: [ - { - bidder: 'byplay' - params: { - sectionId: '7986', - env: 'dev' - } - } - ] - } - ]; -``` diff --git a/test/spec/modules/byplayBidAdapter_spec.js b/test/spec/modules/byplayBidAdapter_spec.js deleted file mode 100644 index 21249c0c9f2..00000000000 --- a/test/spec/modules/byplayBidAdapter_spec.js +++ /dev/null @@ -1,93 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/byplayBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import * as bidderFactory from 'src/adapters/bidderFactory'; - -describe('byplayBidAdapter', () => { - describe('isBidRequestValid', () => { - describe('exist sectionId', () => { - const bid = { - 'bidder': 'byplay', - 'params': { - 'sectionId': '11111' - }, - }; - - it('should equal true', () => { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - - describe('not exist sectionId', () => { - const bid = { - 'bidder': 'byplay', - 'params': { - }, - }; - - it('should equal false', () => { - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - }); - - describe('buildRequests', () => { - const bids = [ - { - 'bidder': 'byplay', - 'bidId': '1234', - 'params': { - 'sectionId': '1111' - }, - } - ]; - - const request = spec.buildRequests(bids); - - it('should return POST', () => { - expect(request[0].method).to.equal('POST'); - }); - - it('should return data', () => { - expect(request[0].data).to.equal('{"requestId":"1234","sectionId":"1111"}'); - }); - }); - - describe('interpretResponse', () => { - const serverResponse = { - body: { - 'cpm': 1500, - 'width': 320, - 'height': 180, - 'netRevenue': true, - 'creativeId': '1', - 'requestId': '209c1fb5ad88f5', - 'vastXml': '' - } - }; - - const bidderRequest = { - 'method': 'GET', - 'url': 'https://tasp0g98f2.execute-api.ap-northeast-1.amazonaws.com/v1/bidder', - 'data': '{"requestId":"209c1fb5ad88f5","sectionId":7986}' - }; - - const result = spec.interpretResponse(serverResponse, bidderRequest); - - it('should return Array', () => { - expect(Array.isArray(result)).to.equal(true); - }); - - it('should get the correct bid response', () => { - expect(result[0].cpm).to.equal(1500); - expect(result[0].creativeId).to.equal('1'); - expect(result[0].width).to.equal(320); - expect(result[0].height).to.equal(180); - expect(result[0].mediaType).to.equal('video'); - expect(result[0].netRevenue).to.equal(true); - expect(result[0].requestId).to.equal('209c1fb5ad88f5'); - expect(result[0].ttl).to.equal(3000); - expect(result[0].vastXml).to.equal(''); - }); - }); -}); From d0542cbb1cce78dc29709c408b194654ad9bc96f Mon Sep 17 00:00:00 2001 From: Aigolkin1991 Date: Mon, 3 Feb 2020 12:57:05 +0200 Subject: [PATCH 025/496] Reviving and moving to prebid 3.0 of smartyAds bi adapter (#4671) * revive smarty sadapter, upgrade to 3.0 * revive smarty adapter, upgrade to 3.0 * name change * fix * fix * Update smartyadsBidAdapter.md * remove propertie deation * video context, native validness check * fix test --- modules/smartyadsBidAdapter.js | 106 ++++++++ modules/smartyadsBidAdapter.md | 63 ++++- test/spec/modules/smartyadsBidAdapter_spec.js | 231 ++++++++++++++++++ 3 files changed, 390 insertions(+), 10 deletions(-) create mode 100644 modules/smartyadsBidAdapter.js create mode 100644 test/spec/modules/smartyadsBidAdapter_spec.js diff --git a/modules/smartyadsBidAdapter.js b/modules/smartyadsBidAdapter.js new file mode 100644 index 00000000000..7737b805158 --- /dev/null +++ b/modules/smartyadsBidAdapter.js @@ -0,0 +1,106 @@ +import {registerBidder} from '../src/adapters/bidderFactory'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils'; + +const BIDDER_CODE = 'smartyads'; +const AD_URL = 'https://ssp-nj.webtradehub.com/?c=o&m=multi'; +const URL_SYNC = 'https://ssp-nj.webtradehub.com/?c=o&m=cookie'; + +function isBidResponseValid(bid) { + if (!bid.requestId || !bid.cpm || !bid.creativeId || + !bid.ttl || !bid.currency) { + return false; + } + switch (bid['mediaType']) { + case BANNER: + return Boolean(bid.width && bid.height && bid.ad); + case VIDEO: + return Boolean(bid.vastUrl); + case NATIVE: + return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); + default: + return false; + } +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid: (bid) => { + return Boolean(bid.bidId && bid.params && !isNaN(bid.params.placementId)); + }, + + buildRequests: (validBidRequests = [], bidderRequest) => { + let winTop = window; + let location; + try { + location = new URL(bidderRequest.refererInfo.referer) + winTop = window.top; + } catch (e) { + location = winTop.location; + utils.logMessage(e); + }; + let placements = []; + let request = { + 'deviceWidth': winTop.screen.width, + 'deviceHeight': winTop.screen.height, + 'language': (navigator && navigator.language) ? navigator.language : '', + 'secure': 1, + 'host': location.host, + 'page': location.pathname, + 'placements': placements + }; + request.language.indexOf('-') != -1 && (request.language = request.language.split('-')[0]) + if (bidderRequest) { + if (bidderRequest.uspConsent) { + request.ccpa = bidderRequest.uspConsent; + } + if (bidderRequest.gdprConsent) { + request.gdpr = bidderRequest.gdprConsent + } + } + const len = validBidRequests.length; + + for (let i = 0; i < len; i++) { + let bid = validBidRequests[i]; + let traff = bid.params.traffic || BANNER + placements.push({ + placementId: bid.params.placementId, + bidId: bid.bidId, + sizes: bid.mediaTypes && bid.mediaTypes[traff] && bid.mediaTypes[traff].sizes ? bid.mediaTypes[traff].sizes : [], + traffic: traff + }); + if (bid.schain) { + placements.schain = bid.schain; + } + } + return { + method: 'POST', + url: AD_URL, + data: request + }; + }, + + interpretResponse: (serverResponse) => { + let response = []; + serverResponse = serverResponse.body; + for (let i = 0; i < serverResponse.length; i++) { + let resItem = serverResponse[i]; + if (isBidResponseValid(resItem)) { + response.push(resItem); + } + } + return response; + }, + + getUserSyncs: (syncOptions, serverResponses) => { + return [{ + type: 'image', + url: URL_SYNC + }]; + } + +}; + +registerBidder(spec); diff --git a/modules/smartyadsBidAdapter.md b/modules/smartyadsBidAdapter.md index 5102a6fd128..4fe4d51a2e6 100644 --- a/modules/smartyadsBidAdapter.md +++ b/modules/smartyadsBidAdapter.md @@ -12,16 +12,59 @@ Module that connects to SmartyAds' demand sources # Test Parameters ``` - var adUnits = [{ - code: 'placementId_0', - sizes: [[300, 250]], - bids: [{ - bidder: 'smartyads', - params: { - placementId: 0, - traffic: 'banner' + var adUnits = [ + // Will return static native ad. Assets are stored through user UI for each placement separetly + { + code: 'placementId_0', + mediaTypes: { + native: {} + }, + bids: [ + { + bidder: 'smartyads', + params: { + placementId: 0, + traffic: 'native' + } } - }] + ] + }, + // Will return static test banner + { + code: 'placementId_0', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [ + { + bidder: 'smartyads', + params: { + placementId: 0, + traffic: 'banner' + } + } + ] + }, + // Will return test vast xml. All video params are stored under placement in publishers UI + { + code: 'placementId_0', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream' + } + }, + bids: [ + { + bidder: 'smartyads', + params: { + placementId: 0, + traffic: 'video' + } + } + ] } ]; -``` \ No newline at end of file +``` diff --git a/test/spec/modules/smartyadsBidAdapter_spec.js b/test/spec/modules/smartyadsBidAdapter_spec.js new file mode 100644 index 00000000000..65f28d440a8 --- /dev/null +++ b/test/spec/modules/smartyadsBidAdapter_spec.js @@ -0,0 +1,231 @@ +import {expect} from 'chai'; +import {spec} from '../../../modules/smartyadsBidAdapter'; + +describe('SmartyadsAdapter', function () { + let bid = { + bidId: '23fhj33i987f', + bidder: 'smartyads', + params: { + placementId: 0, + traffic: 'banner' + } + }; + + describe('isBidRequestValid', function () { + it('Should return true if there are bidId, params and placementId parameters present', function () { + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + it('Should return false if at least one of parameters is not present', function () { + delete bid.params.placementId; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests([bid]); + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + it('Returns valid URL', function () { + expect(serverRequest.url).to.equal('https://ssp-nj.webtradehub.com/?c=o&m=multi'); + }); + it('Returns valid data if array of bids is valid', function () { + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.language).to.be.a('string'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + let placement = data['placements'][0]; + expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes'); + expect(placement.placementId).to.equal(0); + expect(placement.bidId).to.equal('23fhj33i987f'); + expect(placement.traffic).to.equal('banner'); + }); + it('Returns empty data if no valid requests are passed', function () { + serverRequest = spec.buildRequests([]); + let data = serverRequest.data; + expect(data.placements).to.be.an('array').that.is.empty; + }); + }); + describe('interpretResponse', function () { + it('Should interpret banner response', function () { + const banner = { + body: [{ + mediaType: 'banner', + width: 300, + height: 250, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let bannerResponses = spec.interpretResponse(banner); + expect(bannerResponses).to.be.an('array').that.is.not.empty; + let dataItem = bannerResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.width).to.equal(300); + expect(dataItem.height).to.equal(250); + expect(dataItem.ad).to.equal('Test'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret video response', function () { + const video = { + body: [{ + vastUrl: 'test.com', + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let videoResponses = spec.interpretResponse(video); + expect(videoResponses).to.be.an('array').that.is.not.empty; + + let dataItem = videoResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.5); + expect(dataItem.vastUrl).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret native response', function () { + const native = { + body: [{ + mediaType: 'native', + native: { + clickUrl: 'test.com', + title: 'Test', + image: 'test.com', + impressionTrackers: ['test.com'], + }, + ttl: 120, + cpm: 0.4, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let nativeResponses = spec.interpretResponse(native); + expect(nativeResponses).to.be.an('array').that.is.not.empty; + + let dataItem = nativeResponses[0]; + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); + expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.native.clickUrl).to.equal('test.com'); + expect(dataItem.native.title).to.equal('Test'); + expect(dataItem.native.image).to.equal('test.com'); + expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; + expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should return an empty array if invalid banner response is passed', function () { + const invBanner = { + body: [{ + width: 300, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + + let serverResponses = spec.interpretResponse(invBanner); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid video response is passed', function () { + const invVideo = { + body: [{ + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invVideo); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid native response is passed', function () { + const invNative = { + body: [{ + mediaType: 'native', + clickUrl: 'test.com', + title: 'Test', + impressionTrackers: ['test.com'], + ttl: 120, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let serverResponses = spec.interpretResponse(invNative); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid response is passed', function () { + const invalid = { + body: [{ + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invalid); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); + describe('getUserSyncs', function () { + let userSync = spec.getUserSyncs(); + it('Returns valid URL and type', function () { + expect(userSync).to.be.an('array').with.lengthOf(1); + expect(userSync[0].type).to.exist; + expect(userSync[0].url).to.exist; + expect(userSync[0].type).to.be.equal('image'); + expect(userSync[0].url).to.be.equal('https://ssp-nj.webtradehub.com/?c=o&m=cookie'); + }); + }); +}); From 575e6b4e08c949668618381a844663f399fef8f3 Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Mon, 3 Feb 2020 19:13:31 +0530 Subject: [PATCH 026/496] add TODO remark (#4811) --- src/sizeMapping.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sizeMapping.js b/src/sizeMapping.js index a3422a6cdc4..a549ca89d97 100644 --- a/src/sizeMapping.js +++ b/src/sizeMapping.js @@ -125,6 +125,8 @@ function evaluateSizeConfig(configs) { ) { let ruleMatch = false; + // TODO: (Prebid - 4.0) Remove empty mediaQuery string check. Disallow empty mediaQuery in sizeConfig. + // Refer: https://github.com/prebid/Prebid.js/pull/4691, https://github.com/prebid/Prebid.js/issues/4810 for more details. if (config.mediaQuery === '') { ruleMatch = true; } else { From 146b2a6da1a062897e53bb7a93a0be25f72f88df Mon Sep 17 00:00:00 2001 From: daisato-tsumiki Date: Tue, 4 Feb 2020 06:14:34 +0900 Subject: [PATCH 027/496] ByPlay adapter - fix lint (#4809) * Revert "Revert "ByPlay adapter (#4646)" due to lint failure" This reverts commit f80f3ab5f80acafffe95539a0fb7641aa672540d. * fix ByPlay adapter --- modules/byplayBidAdapter.js | 67 ++++++++++++++++ modules/byplayBidAdapter.md | 37 +++++++++ test/spec/modules/byplayBidAdapter_spec.js | 93 ++++++++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100644 modules/byplayBidAdapter.js create mode 100644 modules/byplayBidAdapter.md create mode 100644 test/spec/modules/byplayBidAdapter_spec.js diff --git a/modules/byplayBidAdapter.js b/modules/byplayBidAdapter.js new file mode 100644 index 00000000000..e354af61eaa --- /dev/null +++ b/modules/byplayBidAdapter.js @@ -0,0 +1,67 @@ +import { config } from '../src/config'; +import { registerBidder } from '../src/adapters/bidderFactory'; +import { Renderer } from '../src/Renderer'; +import { VIDEO } from '../src/mediaTypes'; + +const BIDDER_CODE = 'byplay'; +const ENDPOINT_URL = 'https://prebid.byplay.net/bidder'; +const VIDEO_PLAYER_URL = 'https://cdn.byplay.net/prebid-byplay-v2.js'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [VIDEO], + isBidRequestValid: (bid) => { + return !!bid.params.sectionId; + }, + buildRequests: function(validBidRequests) { + return validBidRequests.map(req => { + const payload = { + requestId: req.bidId, + sectionId: req.params.sectionId, + ...(req.params.env ? { env: req.params.env } : {}) + }; + + return { + method: 'POST', + url: ENDPOINT_URL, + data: JSON.stringify(payload), + options: { + withCredentials: false + } + }; + }); + }, + interpretResponse: (serverResponse, bidderRequest) => { + const response = serverResponse.body; + const data = JSON.parse(bidderRequest.data); + const bidResponse = { + requestId: data.requestId, + cpm: response.cpm, + width: response.width, + height: response.height, + creativeId: response.creativeId || '0', + ttl: config.getConfig('_bidderTimeout'), + currency: 'JPY', + netRevenue: response.netRevenue, + mediaType: VIDEO, + vastXml: response.vastXml, + renderer: createRenderer() + }; + + return [bidResponse]; + } +}; + +function createRenderer() { + const renderer = Renderer.install({ url: VIDEO_PLAYER_URL }); + + renderer.setRender(bid => { + bid.renderer.push(() => { + window.adtagRender(bid.vastXml); + }); + }); + + return renderer; +} + +registerBidder(spec); diff --git a/modules/byplayBidAdapter.md b/modules/byplayBidAdapter.md new file mode 100644 index 00000000000..67fb9c40d35 --- /dev/null +++ b/modules/byplayBidAdapter.md @@ -0,0 +1,37 @@ +# Overview + +``` +Module Name: ByPlay Bidder Adapter +Module Type: Bidder Adapter +Maintainer: byplayers@tsumikiinc.com +``` + +# Description + +Connects to ByPlay exchange for bids. + +ByPlay bid adapter supports Video. + +# Test Parameters +``` + const adUnits = [ + { + code: 'byplay-ad', + mediaTypes: { + video: { + playerSize: [400, 225], + context: 'outstream' + } + }, + bids: [ + { + bidder: 'byplay', + params: { + sectionId: '7986', + env: 'dev' + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/byplayBidAdapter_spec.js b/test/spec/modules/byplayBidAdapter_spec.js new file mode 100644 index 00000000000..21249c0c9f2 --- /dev/null +++ b/test/spec/modules/byplayBidAdapter_spec.js @@ -0,0 +1,93 @@ +import { expect } from 'chai'; +import { spec } from 'modules/byplayBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; +import * as bidderFactory from 'src/adapters/bidderFactory'; + +describe('byplayBidAdapter', () => { + describe('isBidRequestValid', () => { + describe('exist sectionId', () => { + const bid = { + 'bidder': 'byplay', + 'params': { + 'sectionId': '11111' + }, + }; + + it('should equal true', () => { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + }); + + describe('not exist sectionId', () => { + const bid = { + 'bidder': 'byplay', + 'params': { + }, + }; + + it('should equal false', () => { + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + }); + + describe('buildRequests', () => { + const bids = [ + { + 'bidder': 'byplay', + 'bidId': '1234', + 'params': { + 'sectionId': '1111' + }, + } + ]; + + const request = spec.buildRequests(bids); + + it('should return POST', () => { + expect(request[0].method).to.equal('POST'); + }); + + it('should return data', () => { + expect(request[0].data).to.equal('{"requestId":"1234","sectionId":"1111"}'); + }); + }); + + describe('interpretResponse', () => { + const serverResponse = { + body: { + 'cpm': 1500, + 'width': 320, + 'height': 180, + 'netRevenue': true, + 'creativeId': '1', + 'requestId': '209c1fb5ad88f5', + 'vastXml': '' + } + }; + + const bidderRequest = { + 'method': 'GET', + 'url': 'https://tasp0g98f2.execute-api.ap-northeast-1.amazonaws.com/v1/bidder', + 'data': '{"requestId":"209c1fb5ad88f5","sectionId":7986}' + }; + + const result = spec.interpretResponse(serverResponse, bidderRequest); + + it('should return Array', () => { + expect(Array.isArray(result)).to.equal(true); + }); + + it('should get the correct bid response', () => { + expect(result[0].cpm).to.equal(1500); + expect(result[0].creativeId).to.equal('1'); + expect(result[0].width).to.equal(320); + expect(result[0].height).to.equal(180); + expect(result[0].mediaType).to.equal('video'); + expect(result[0].netRevenue).to.equal(true); + expect(result[0].requestId).to.equal('209c1fb5ad88f5'); + expect(result[0].ttl).to.equal(3000); + expect(result[0].vastXml).to.equal(''); + }); + }); +}); From faec915341a79db87881f569a1e08241b64c7bac Mon Sep 17 00:00:00 2001 From: Aparna Rao-Hegde Date: Mon, 3 Feb 2020 16:24:42 -0500 Subject: [PATCH 028/496] 33Across BidAdapter: Set Page URL in request (#4795) * send page url in ortb * Removed redundant pageUrl default * Restored package-log.json that mirrors prebid's repo Co-authored-by: Gleb Glushtsov --- modules/33acrossBidAdapter.js | 9 ++- test/spec/modules/33acrossBidAdapter_spec.js | 61 +++++++++++++++++--- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js index 6d372ac8b72..772fc360c17 100644 --- a/modules/33acrossBidAdapter.js +++ b/modules/33acrossBidAdapter.js @@ -65,7 +65,7 @@ function _getAdSlotHTMLElement(adUnitCode) { // Infer the necessary data from valid bid for a minimal ttxRequest and create HTTP request // NOTE: At this point, TTX only accepts request for a single impression -function _createServerRequest(bidRequest, gdprConsent = {}) { +function _createServerRequest(bidRequest, gdprConsent = {}, pageUrl) { const ttxRequest = {}; const params = bidRequest.params; const element = _getAdSlotHTMLElement(bidRequest.adUnitCode); @@ -94,6 +94,9 @@ function _createServerRequest(bidRequest, gdprConsent = {}) { }; ttxRequest.site = { id: params.siteId }; + if (pageUrl) { + ttxRequest.site.page = pageUrl; + } // Go ahead send the bidId in request to 33exchange so it's kept track of in the bid response and // therefore in ad targetting process ttxRequest.id = bidRequest.bidId; @@ -298,9 +301,11 @@ function buildRequests(bidRequests, bidderRequest) { gdprApplies: false }, bidderRequest && bidderRequest.gdprConsent); + const pageUrl = (bidderRequest && bidderRequest.refererInfo) ? (bidderRequest.refererInfo.referer) : (undefined); + adapterState.uniqueSiteIds = bidRequests.map(req => req.params.siteId).filter(utils.uniques); - return bidRequests.map(req => _createServerRequest(req, gdprConsent)); + return bidRequests.map(req => _createServerRequest(req, gdprConsent, pageUrl)); } // NOTE: At this point, the response from 33exchange will only ever contain one bid i.e. the highest bid diff --git a/test/spec/modules/33acrossBidAdapter_spec.js b/test/spec/modules/33acrossBidAdapter_spec.js index b18181eae40..80cd56d3255 100644 --- a/test/spec/modules/33acrossBidAdapter_spec.js +++ b/test/spec/modules/33acrossBidAdapter_spec.js @@ -75,7 +75,7 @@ describe('33acrossBidAdapter:', function () { return this; }; - this.withViewabiliuty = viewability => { + this.withViewability = viewability => { Object.assign(ttxRequest.imp[0].banner, { ext: { ttx: { viewability } @@ -103,6 +103,14 @@ describe('33acrossBidAdapter:', function () { return this; }; + this.withPageUrl = pageUrl => { + Object.assign(ttxRequest.site, { + page: pageUrl + }); + + return this; + }; + this.build = () => ttxRequest; } @@ -267,7 +275,7 @@ describe('33acrossBidAdapter:', function () { context('when element is fully in view', function() { it('returns 100', function() { const ttxRequest = new TtxRequestBuilder() - .withViewabiliuty({amount: 100}) + .withViewability({amount: 100}) .build(); const serverRequest = new ServerRequestBuilder() .withData(ttxRequest) @@ -282,7 +290,7 @@ describe('33acrossBidAdapter:', function () { context('when element is out of view', function() { it('returns 0', function() { const ttxRequest = new TtxRequestBuilder() - .withViewabiliuty({amount: 0}) + .withViewability({amount: 0}) .build(); const serverRequest = new ServerRequestBuilder() .withData(ttxRequest) @@ -297,7 +305,7 @@ describe('33acrossBidAdapter:', function () { context('when element is partially in view', function() { it('returns percentage', function() { const ttxRequest = new TtxRequestBuilder() - .withViewabiliuty({amount: 75}) + .withViewability({amount: 75}) .build(); const serverRequest = new ServerRequestBuilder() .withData(ttxRequest) @@ -313,7 +321,7 @@ describe('33acrossBidAdapter:', function () { it('try to use alternative values', function() { const ttxRequest = new TtxRequestBuilder() .withSizes([{ w: 800, h: 2400, ext: {} }]) - .withViewabiliuty({amount: 25}) + .withViewability({amount: 25}) .build(); const serverRequest = new ServerRequestBuilder() .withData(ttxRequest) @@ -329,7 +337,7 @@ describe('33acrossBidAdapter:', function () { context('when nested iframes', function() { it('returns \'nm\'', function() { const ttxRequest = new TtxRequestBuilder() - .withViewabiliuty({amount: spec.NON_MEASURABLE}) + .withViewability({amount: spec.NON_MEASURABLE}) .build(); const serverRequest = new ServerRequestBuilder() .withData(ttxRequest) @@ -349,7 +357,7 @@ describe('33acrossBidAdapter:', function () { context('when tab is inactive', function() { it('returns 0', function() { const ttxRequest = new TtxRequestBuilder() - .withViewabiliuty({amount: 0}) + .withViewability({amount: 0}) .build(); const serverRequest = new ServerRequestBuilder() .withData(ttxRequest) @@ -445,6 +453,45 @@ describe('33acrossBidAdapter:', function () { expect(builtServerRequests).to.deep.equal([serverRequest]); }); }); + + context('when referer value is available', function() { + it('returns corresponding server requests with site.page set', function() { + const bidderRequest = { + refererInfo: { + referer: 'http://foo.com/bar' + } + }; + + const ttxRequest = new TtxRequestBuilder() + .withPageUrl('http://foo.com/bar') + .build(); + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .build(); + + const builtServerRequests = spec.buildRequests(bidRequests, bidderRequest); + + expect(builtServerRequests).to.deep.equal([serverRequest]); + }); + }); + + context('when referer value is not available', function() { + it('returns corresponding server requests without site.page set', function() { + const bidderRequest = { + refererInfo: {} + }; + + const ttxRequest = new TtxRequestBuilder() + .build(); + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .build(); + + const builtServerRequests = spec.buildRequests(bidRequests, bidderRequest); + + expect(builtServerRequests).to.deep.equal([serverRequest]); + }); + }); }); describe('interpretResponse', function() { From 5f9a3b23b30a3dc00ab76674e906854c45ac716e Mon Sep 17 00:00:00 2001 From: DeepthiNeeladri Date: Tue, 4 Feb 2020 03:00:08 +0530 Subject: [PATCH 029/496] Missing protocols and linearity params in onevideo adaptor (#4800) * adding linearity and protocols --- modules/oneVideoBidAdapter.js | 2 ++ test/spec/modules/oneVideoBidAdapter_spec.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/modules/oneVideoBidAdapter.js b/modules/oneVideoBidAdapter.js index 8228427c369..162699217c4 100644 --- a/modules/oneVideoBidAdapter.js +++ b/modules/oneVideoBidAdapter.js @@ -199,6 +199,8 @@ function getRequestData(bid, consentData, bidRequest) { if (bid.params.video.rewarded) { bidData.imp[0].ext.rewarded = bid.params.video.rewarded } + bidData.imp[0].video.linearity = 1; + bidData.imp[0].video.protocols = bid.params.video.protocols || [2, 5]; } else if (bid.params.video.display == 1) { bidData.imp[0].banner = { mimes: bid.params.video.mimes, diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js index 82f7ca91091..b4417caada3 100644 --- a/test/spec/modules/oneVideoBidAdapter_spec.js +++ b/test/spec/modules/oneVideoBidAdapter_spec.js @@ -401,6 +401,8 @@ describe('OneVideoBidAdapter', function () { expect(data.imp[0].video.h).to.equal(height); expect(data.imp[0].video.pos).to.equal(position); expect(data.imp[0].video.mimes).to.equal(bidRequest.params.video.mimes); + expect(data.imp[0].video.protocols).to.equal(bidRequest.params.video.protocols); + expect(data.imp[0].video.linearity).to.equal(1); }); describe('getUserSyncs', function () { const GDPR_CONSENT_STRING = 'GDPR_CONSENT_STRING'; From 2506506f668ea864bf9663b568a6c1ea8570fab4 Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Mon, 3 Feb 2020 16:44:21 -0500 Subject: [PATCH 030/496] Trion request param update (#4805) * Trion adapter update. Changing request params to trion including removing support for optional 're' param, cleaning up existing params to send 1/0 instead of null when non is present and adding prebid version. --- modules/trionBidAdapter.js | 7 +- test/spec/modules/trionBidAdapter_spec.js | 86 ++++++++++++++++------- 2 files changed, 65 insertions(+), 28 deletions(-) diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index 6d564a66e2d..70889d8d14c 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -108,12 +108,11 @@ function getPublisherUrl() { function buildTrionUrlParams(bid, bidderRequest) { var pubId = utils.getBidIdParameter('pubId', bid.params); var sectionId = utils.getBidIdParameter('sectionId', bid.params); - var re = utils.getBidIdParameter('re', bid.params); var url = getPublisherUrl(); var bidSizes = getBidSizesFromBidRequest(bid); var sizes = utils.parseSizesInput(bidSizes).join(','); - var isAutomated = (navigator && navigator.webdriver) ? 1 : 0; - var isHidden = (document.hidden) ? 1 : 0; + var isAutomated = (navigator && navigator.webdriver) ? '1' : '0'; + var isHidden = (document.hidden) ? '1' : '0'; var visibilityState = encodeURIComponent(document.visibilityState); var intT = window.TR_INT_T && window.TR_INT_T != -1 ? window.TR_INT_T : null; @@ -129,7 +128,7 @@ function buildTrionUrlParams(bid, bidderRequest) { trionUrl = utils.tryAppendQueryString(trionUrl, 'bidId', bid.bidId); trionUrl = utils.tryAppendQueryString(trionUrl, 'pubId', pubId); trionUrl = utils.tryAppendQueryString(trionUrl, 'sectionId', sectionId); - trionUrl = utils.tryAppendQueryString(trionUrl, 're', re); + trionUrl = utils.tryAppendQueryString(trionUrl, 'vers', '$prebid.version$'); if (url) { trionUrl += 'url=' + url + '&'; } diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index 9a57f79e24f..eaa206df984 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -137,17 +137,13 @@ describe('Trion adapter tests', function () { expect(bidUrlParams).to.include('pubId=1'); expect(bidUrlParams).to.include('sectionId=2'); expect(bidUrlParams).to.include('sizes=300x250,300x600'); + expect(bidUrlParams).to.include('vers=$prebid.version$'); }); it('should call buildRequests with the correct optional params', function () { - let params = TRION_BID_REQUEST[0].params; - params.re = 1; let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - let bidUrlParams = bidRequests[0].data; - expect(bidUrlParams).to.include('re=1'); expect(bidUrlParams).to.include(getPublisherUrl()); - delete params.re; }); describe('webdriver', function () { @@ -155,9 +151,6 @@ describe('Trion adapter tests', function () { beforeEach(function () { originalWD = window.navigator.webdriver; - window.navigator['__defineGetter__']('webdriver', function () { - return 1; - }); }); afterEach(function () { @@ -166,26 +159,42 @@ describe('Trion adapter tests', function () { }); }); - it('should send the correct state when there is non human traffic', function () { - let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - let bidUrlParams = bidRequests[0].data; - expect(bidUrlParams).to.include('tr_wd=1'); + describe('is present', function () { + beforeEach(function () { + window.navigator['__defineGetter__']('webdriver', function () { + return 1; + }); + }); + + it('when there is non human traffic', function () { + let bidRequests = spec.buildRequests(TRION_BID_REQUEST); + let bidUrlParams = bidRequests[0].data; + expect(bidUrlParams).to.include('tr_wd=1'); + }); + }); + + describe('is not present', function () { + beforeEach(function () { + window.navigator['__defineGetter__']('webdriver', function () { + return 0; + }); + }); + + it('when there is not non human traffic', function () { + let bidRequests = spec.buildRequests(TRION_BID_REQUEST); + let bidUrlParams = bidRequests[0].data; + expect(bidUrlParams).to.include('tr_wd=0'); + }); }); }); - describe('visibility', function () { + describe('document', function () { let originalHD; let originalVS; beforeEach(function () { originalHD = document.hidden; originalVS = document.visibilityState; - document['__defineGetter__']('hidden', function () { - return 1; - }); - document['__defineGetter__']('visibilityState', function () { - return 'hidden'; - }); }); afterEach(function () { @@ -197,11 +206,40 @@ describe('Trion adapter tests', function () { }); }); - it('should send the correct states when the document is not visible', function () { - let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - let bidUrlParams = bidRequests[0].data; - expect(bidUrlParams).to.include('tr_hd=1'); - expect(bidUrlParams).to.include('tr_vs=hidden'); + describe('is visible', function () { + beforeEach(function () { + document['__defineGetter__']('hidden', function () { + return 1; + }); + document['__defineGetter__']('visibilityState', function () { + return 'visible'; + }); + }); + + it('should detect and send the document is visible', function () { + let bidRequests = spec.buildRequests(TRION_BID_REQUEST); + let bidUrlParams = bidRequests[0].data; + expect(bidUrlParams).to.include('tr_hd=1'); + expect(bidUrlParams).to.include('tr_vs=visible'); + }); + }); + + describe('is hidden', function () { + beforeEach(function () { + document['__defineGetter__']('hidden', function () { + return 1; + }); + document['__defineGetter__']('visibilityState', function () { + return 'hidden'; + }); + }); + + it('should detect and send the document is hidden', function () { + let bidRequests = spec.buildRequests(TRION_BID_REQUEST); + let bidUrlParams = bidRequests[0].data; + expect(bidUrlParams).to.include('tr_hd=1'); + expect(bidUrlParams).to.include('tr_vs=hidden'); + }); }); }); From 563e1663e330c279a085bf305f7a836d7a57251e Mon Sep 17 00:00:00 2001 From: Gena Date: Tue, 4 Feb 2020 03:22:10 +0200 Subject: [PATCH 031/496] ViewdeosDX outstream support (#4692) * add outstream params extension * update outsream version * Tests added + doc sample * remove return * add uspConsent support * Change enpoint to geo-balanced --- modules/viewdeosDXBidAdapter.js | 21 ++++++++---- modules/viewdeosDXBidAdapter.md | 14 +++++--- .../spec/modules/viewdeosDXBidAdapter_spec.js | 32 +++++++++++++++++-- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/modules/viewdeosDXBidAdapter.js b/modules/viewdeosDXBidAdapter.js index 1de93aad95a..2267c3a090a 100644 --- a/modules/viewdeosDXBidAdapter.js +++ b/modules/viewdeosDXBidAdapter.js @@ -4,7 +4,7 @@ import {VIDEO, BANNER} from '../src/mediaTypes'; import {Renderer} from '../src/Renderer'; import findIndex from 'core-js/library/fn/array/find-index'; -const URL = 'https://hb.sync.viewdeos.com/auction/'; +const URL = 'https://ghb.sync.viewdeos.com/auction/'; const OUTSTREAM_SRC = 'https://player.sync.viewdeos.com/outstream-unit/2.01/outstream.min.js'; const BIDDER_CODE = 'viewdeosDX'; const OUTSTREAM = 'outstream'; @@ -112,7 +112,8 @@ function parseRTBResponse(serverResponse, bidderRequest) { }); if (serverBid.cpm !== 0 && requestId !== -1) { - const bid = createBid(serverBid, getMediaType(bidderRequest.bids[requestId])); + const bidReq = bidderRequest.bids[requestId]; + const bid = createBid(serverBid, getMediaType(bidReq), bidReq.params); bids.push(bid); } @@ -131,6 +132,10 @@ function bidToTag(bidRequests, bidderRequest) { tag.gdpr_consent = utils.deepAccess(bidderRequest, 'gdprConsent.consentString'); } + if (utils.deepAccess(bidderRequest, 'bidderRequest.uspConsent')) { + tag.us_privacy = bidderRequest.uspConsent; + } + for (let i = 0, length = bidRequests.length; i < length; i++) { Object.assign(tag, prepareRTBRequestParams(i, bidRequests[i])); } @@ -174,7 +179,7 @@ function getMediaType(bidderRequest) { * @param mediaType {Object} * @returns {object} */ -function createBid(bidResponse, mediaType) { +function createBid(bidResponse, mediaType, bidderParams) { const bid = { requestId: bidResponse.requestId, creativeId: bidResponse.cmpId, @@ -201,7 +206,7 @@ function createBid(bidResponse, mediaType) { Object.assign(bid, { mediaType: 'video', adResponse: bidResponse, - renderer: newRenderer(bidResponse.requestId) + renderer: newRenderer(bidResponse.requestId, bidderParams) }); } @@ -213,10 +218,11 @@ function createBid(bidResponse, mediaType) { * @param requestId * @returns {*} */ -function newRenderer(requestId) { +function newRenderer(requestId, bidderParams) { const renderer = Renderer.install({ id: requestId, url: OUTSTREAM_SRC, + config: bidderParams.outstream || {}, loaded: false }); @@ -231,12 +237,13 @@ function newRenderer(requestId) { */ function outstreamRender(bid) { bid.renderer.push(() => { - window.VOutstreamAPI.initOutstreams([{ + const opts = Object.assign({}, bid.renderer.getConfig(), { width: bid.width, height: bid.height, vastUrl: bid.vastUrl, elId: bid.adUnitCode - }]); + }); + window.VOutstreamAPI.initOutstreams([opts]); }); } diff --git a/modules/viewdeosDXBidAdapter.md b/modules/viewdeosDXBidAdapter.md index d9ede8cc312..a3fa34525b8 100644 --- a/modules/viewdeosDXBidAdapter.md +++ b/modules/viewdeosDXBidAdapter.md @@ -14,10 +14,10 @@ Get access to multiple demand partners across Viewdeos and maximize your yield w // Video instream adUnit { code: 'div-test-div', - sizes: [[640, 480]], mediaTypes: { video: { - context: 'instream' + context: 'instream', + playerSize: [[640, 480]] } }, bids: [{ @@ -31,16 +31,20 @@ Get access to multiple demand partners across Viewdeos and maximize your yield w // Video outstream adUnit { code: 'outstream-test-div', - sizes: [[640, 480]], mediaTypes: { video: { - context: 'outstream' + context: 'outstream', + playerSize: [[640, 480]] } }, bids: [{ bidder: 'viewdeosDX', params: { - aid: 331133 + aid: 331133, + outstream: { + default_volume:50, + video_controls:'show' + } } }] }, diff --git a/test/spec/modules/viewdeosDXBidAdapter_spec.js b/test/spec/modules/viewdeosDXBidAdapter_spec.js index b5d61d18964..89fe1ff94ef 100644 --- a/test/spec/modules/viewdeosDXBidAdapter_spec.js +++ b/test/spec/modules/viewdeosDXBidAdapter_spec.js @@ -2,7 +2,7 @@ import {expect} from 'chai'; import {spec} from 'modules/viewdeosDXBidAdapter'; import {newBidder} from 'src/adapters/bidderFactory'; -const ENDPOINT = 'https://hb.sync.viewdeos.com/auction/'; +const ENDPOINT = 'https://ghb.sync.viewdeos.com/auction/'; const DISPLAY_REQUEST = { 'bidder': 'viewdeos', @@ -43,6 +43,7 @@ const SERVER_VIDEO_RESPONSE = { } ] }; +const SERVER_OUSTREAM_VIDEO_RESPONSE = SERVER_VIDEO_RESPONSE; const SERVER_DISPLAY_RESPONSE = { 'source': {'aid': 12345, 'pubId': 54321}, @@ -74,6 +75,25 @@ const SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS = { 'cookieURLSTypes': ['image', 'iframe'] }; +const outstreamVideoBidderRequest = { + bidderCode: 'bidderCode', + bids: [{ + 'params': { + 'aid': 12345, + 'outstream': { + 'video_controls': 'show' + } + }, + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 480] + } + }, + bidId: '2e41f65424c87c' + }] +}; + const videoBidderRequest = { bidderCode: 'bidderCode', bids: [{mediaTypes: {video: {}}, bidId: '2e41f65424c87c'}] @@ -119,9 +139,17 @@ const displayEqResponse = [{ cpm: 0.9 }]; -describe('viewdeosDXBidAdapter', function () { // todo remove only +describe('viewdeosDXBidAdapter', function () { const adapter = newBidder(spec); + describe('when outstream params are passing properly', function() { + const videoBids = spec.interpretResponse({body: SERVER_OUSTREAM_VIDEO_RESPONSE}, {bidderRequest: outstreamVideoBidderRequest}); + it('should return renderer with expected outstream params config', function() { + expect(!!videoBids[0].renderer).to.equal(true); + expect(videoBids[0].renderer.getConfig().video_controls).to.equal('show'); + }) + }) + describe('user syncs as image', function () { it('should be returned if pixel enabled', function () { const syncs = spec.getUserSyncs({pixelEnabled: true}, [{body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS}]); From 50d2a291804b0794a65f7c0dd4075f415fa7f3d9 Mon Sep 17 00:00:00 2001 From: Roffray Date: Wed, 5 Feb 2020 12:04:21 +0100 Subject: [PATCH 032/496] GDPR support added to the vuble bidder (#4804) * Add: gdpr consent * Del: comma * Mod: properties names * Check if gdpr applies is a boolean --- modules/vubleBidAdapter.js | 7 +++++ test/spec/modules/vubleBidAdapter_spec.js | 31 +++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/modules/vubleBidAdapter.js b/modules/vubleBidAdapter.js index 288390f01c9..75ad4308db6 100644 --- a/modules/vubleBidAdapter.js +++ b/modules/vubleBidAdapter.js @@ -108,6 +108,13 @@ export const spec = { adUnitCode: bidRequest.adUnitCode }; + if (bidderRequest && bidderRequest.gdprConsent) { + data.gdpr_consent = { + consent_string: bidderRequest.gdprConsent.consentString, + gdpr_applies: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true + } + } + return { method: 'POST', url: url, diff --git a/test/spec/modules/vubleBidAdapter_spec.js b/test/spec/modules/vubleBidAdapter_spec.js index b00dbca9b01..81e7936809a 100644 --- a/test/spec/modules/vubleBidAdapter_spec.js +++ b/test/spec/modules/vubleBidAdapter_spec.js @@ -202,7 +202,27 @@ describe('VubleAdapter', function () { adUnitCode: '' } }; - let bidderRequest = { + let request4 = { + method: 'POST', + url: 'https://player.mediabong.net/prebid/request', + data: { + width: '640', + height: '360', + pub_id: '3', + zone_id: '3579', + context: 'instream', + floor_price: 0, + url: '', + env: 'net', + bid_id: 'ijkl', + adUnitCode: '', + gdpr_consent: { + consent_string: 'test', + gdpr_applies: true + } + } + }; + let bidderRequest1 = { refererInfo: { referer: 'https://www.vuble.tv/', reachedTop: true, @@ -214,10 +234,17 @@ describe('VubleAdapter', function () { ] } }; + let bidderRequest2 = { + 'gdprConsent': { + consentString: 'test', + gdprApplies: true + } + }; it('must return the right formatted requests', function () { expect(adapter.buildRequests([bid1, bid2])).to.deep.equal([request1, request2]); - expect(adapter.buildRequests([bid3], bidderRequest)).to.deep.equal([request3]); + expect(adapter.buildRequests([bid3], bidderRequest1)).to.deep.equal([request3]); + expect(adapter.buildRequests([bid3], bidderRequest2)).to.deep.equal([request4]); }); }); From 1964f2734c76e90e2c5b28496b867db41438af47 Mon Sep 17 00:00:00 2001 From: bjorn-lw <32431346+bjorn-lw@users.noreply.github.com> Date: Wed, 5 Feb 2020 20:01:06 +0100 Subject: [PATCH 033/496] Collect data about native + minor changes (#4807) * Livewrapped bid and analytics adapter * Fixed some tests for browser compatibility * Fixed some tests for browser compatibility * Changed analytics adapter code name * Fix double quote in debug message * modified how gdpr is being passed * Added support for Publisher Common ID Module * Corrections for ttr in analytics * ANalytics updates * Auction start time stamp changed * Detect recovered ad blocked requests Make it possible to pass dynamic parameters to adapter * Collect info on ad units receiving any valid bid * Support for ID5 Pass metadata from adapter * Typo in test + eids on wrong level * Fix for Prebid 3.0 * Fix get referer * http -> https in tests * Native support * Read sizes from mediatype.banner * Revert accidental commit * Support native data collection + minor refactorings * Set analytics endpoint --- modules/livewrappedAnalyticsAdapter.js | 7 ++- modules/livewrappedBidAdapter.js | 10 ++-- .../livewrappedAnalyticsAdapter_spec.js | 46 +++++++++++++++++-- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/modules/livewrappedAnalyticsAdapter.js b/modules/livewrappedAnalyticsAdapter.js index d15577e215b..75d4e90fded 100644 --- a/modules/livewrappedAnalyticsAdapter.js +++ b/modules/livewrappedAnalyticsAdapter.js @@ -60,6 +60,7 @@ let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE bidResponse.cpm = args.cpm; bidResponse.ttr = args.timeToRespond; bidResponse.readyToSend = 1; + bidResponse.mediaType = args.mediaType == 'native' ? 2 : 1; if (!bidResponse.ttr) { bidResponse.ttr = time - bidResponse.start; } @@ -129,7 +130,7 @@ livewrappedAnalyticsAdapter.sendEvents = function() { return; } - ajax(URL, undefined, JSON.stringify(events), {method: 'POST'}); + ajax(initOptions.endpoint || URL, undefined, JSON.stringify(events), {method: 'POST'}); } function getAdblockerRecovered() { @@ -178,7 +179,8 @@ function getResponses() { height: bid.height, cpm: bid.cpm, ttr: bid.ttr, - IsBid: bid.isBid + IsBid: bid.isBid, + mediaType: bid.mediaType }); } }); @@ -204,6 +206,7 @@ function getWins() { width: bid.width, height: bid.height, cpm: bid.cpm, + mediaType: bid.mediaType }); } }); diff --git a/modules/livewrappedBidAdapter.js b/modules/livewrappedBidAdapter.js index c5c71a4131e..4dfd25c1fcd 100644 --- a/modules/livewrappedBidAdapter.js +++ b/modules/livewrappedBidAdapter.js @@ -193,19 +193,17 @@ function bidToAdRequest(bid) { options: bid.params.options }; - if (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.native) { - adRequest.banner = true; - } + adRequest.native = utils.deepAccess(bid, 'mediaTypes.native'); - if (bid.mediaTypes && bid.mediaTypes.native) { - adRequest.native = bid.mediaTypes.native; + if (adRequest.native && utils.deepAccess(bid, 'mediaTypes.banner')) { + adRequest.banner = true; } return adRequest; } function getSizes(bid) { - if (typeof utils.deepAccess(bid, 'mediaTypes.banner.sizes') !== 'undefined') { + if (utils.deepAccess(bid, 'mediaTypes.banner.sizes')) { return bid.mediaTypes.banner.sizes; } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { return bid.sizes; diff --git a/test/spec/modules/livewrappedAnalyticsAdapter_spec.js b/test/spec/modules/livewrappedAnalyticsAdapter_spec.js index 98ed21132e3..2676de0de10 100644 --- a/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +++ b/test/spec/modules/livewrappedAnalyticsAdapter_spec.js @@ -32,6 +32,7 @@ const BID1 = { requestId: '2ecff0db240757', adId: '2ecff0db240757', auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', + mediaType: 'banner', getStatusCode() { return CONSTANTS.STATUS.GOOD; } @@ -52,6 +53,7 @@ const BID3 = { requestId: '4ecff0db240757', adId: '4ecff0db240757', auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', + mediaType: 'banner', getStatusCode() { return CONSTANTS.STATUS.NO_BID; } @@ -154,7 +156,8 @@ const ANALYTICS_MESSAGE = { height: 240, cpm: 1.1, ttr: 200, - IsBid: true + IsBid: true, + mediaType: 1 }, { timeStamp: 1519149562216, @@ -164,7 +167,8 @@ const ANALYTICS_MESSAGE = { height: 250, cpm: 2.2, ttr: 300, - IsBid: true + IsBid: true, + mediaType: 1 }, { timeStamp: 1519149562216, @@ -182,7 +186,8 @@ const ANALYTICS_MESSAGE = { bidder: 'livewrapped', width: 980, height: 240, - cpm: 1.1 + cpm: 1.1, + mediaType: 1 }, { timeStamp: 1519149562216, @@ -190,7 +195,8 @@ const ANALYTICS_MESSAGE = { bidder: 'livewrapped', width: 300, height: 250, - cpm: 2.2 + cpm: 2.2, + mediaType: 1 } ] }; @@ -316,4 +322,36 @@ describe('Livewrapped analytics adapter', function () { expect(message.rcv).to.equal(true); }); }); + + describe('when given other endpoint', function () { + adapterManager.registerAnalyticsAdapter({ + code: 'livewrapped', + adapter: livewrappedAnalyticsAdapter + }); + + beforeEach(function () { + adapterManager.enableAnalytics({ + provider: 'livewrapped', + options: { + publisherId: 'CC411485-42BC-4F92-8389-42C503EE38D7', + endpoint: 'https://whitelabeled.com/analytics/10' + } + }); + }); + + afterEach(function () { + livewrappedAnalyticsAdapter.disableAnalytics(); + }); + + it('should call the endpoint', function () { + performStandardAuction(); + + clock.tick(BID_WON_TIMEOUT + 1000); + + expect(server.requests.length).to.equal(1); + let request = server.requests[0]; + + expect(request.url).to.equal('https://whitelabeled.com/analytics/10'); + }); + }); }); From 8569a712fd5532ffc3cf58fe0b523a2266e281a7 Mon Sep 17 00:00:00 2001 From: Mike Chowla Date: Thu, 6 Feb 2020 11:32:30 -0800 Subject: [PATCH 034/496] Prebid 3.6.0 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 56aded033c0..f26df6f9c13 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.6.0-pre", + "version": "3.6.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From a9ce6547e429299c48d875b7a0870d8d244f1669 Mon Sep 17 00:00:00 2001 From: Mike Chowla Date: Thu, 6 Feb 2020 12:21:01 -0800 Subject: [PATCH 035/496] Increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f26df6f9c13..8eac6d9f8be 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.6.0", + "version": "3.7.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 659b23cf5d2671685b7117b8be00e32d5bd82c3e Mon Sep 17 00:00:00 2001 From: DeepthiNeeladri Date: Sat, 8 Feb 2020 03:59:46 +0530 Subject: [PATCH 036/496] Onevideo adapter version param support (#4826) * adding version params * test cases for version * removing console log --- modules/oneVideoBidAdapter.js | 4 ++++ test/spec/modules/oneVideoBidAdapter_spec.js | 3 +++ 2 files changed, 7 insertions(+) diff --git a/modules/oneVideoBidAdapter.js b/modules/oneVideoBidAdapter.js index 162699217c4..eff8bd9f34b 100644 --- a/modules/oneVideoBidAdapter.js +++ b/modules/oneVideoBidAdapter.js @@ -3,6 +3,7 @@ import {registerBidder} from '../src/adapters/bidderFactory'; const BIDDER_CODE = 'oneVideo'; export const spec = { code: 'oneVideo', + VERSION: '3.0.0', ENDPOINT: 'https://ads.adaptv.advertising.com/rtb/openrtb?ext_id=', SYNC_ENDPOINT1: 'https://cm.g.doubleclick.net/pixel?google_nid=adaptv_dbm&google_cm&google_sc', SYNC_ENDPOINT2: 'https://pr-bh.ybp.yahoo.com/sync/adaptv_ortb/{combo_uid}', @@ -153,6 +154,8 @@ function getRequestData(bid, consentData, bidRequest) { bidfloor: bid.params.bidfloor, ext: { hb: 1, + prebidver: '$prebid.version$', + adapterver: spec.VERSION, } }], site: { @@ -246,6 +249,7 @@ function getRequestData(bid, consentData, bidRequest) { } }; } + // ccpa support if (bidRequest && bidRequest.uspConsent) { bidData.regs.ext.us_privacy = bidRequest.uspConsent } diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js index b4417caada3..c2e698737cf 100644 --- a/test/spec/modules/oneVideoBidAdapter_spec.js +++ b/test/spec/modules/oneVideoBidAdapter_spec.js @@ -136,12 +136,15 @@ describe('OneVideoBidAdapter', function () { const placement = bidRequest.params.video.placement; const rewarded = bidRequest.params.video.rewarded; const inventoryid = bidRequest.params.video.inventoryid; + const VERSION = '3.0.0'; expect(data.imp[0].video.w).to.equal(width); expect(data.imp[0].video.h).to.equal(height); expect(data.imp[0].bidfloor).to.equal(bidRequest.params.bidfloor); expect(data.imp[0].ext.rewarded).to.equal(rewarded); expect(data.imp[0].video.placement).to.equal(placement); expect(data.imp[0].ext.inventoryid).to.equal(inventoryid); + expect(data.imp[0].ext.prebidver).to.equal('$prebid.version$'); + expect(data.imp[0].ext.adapterver).to.equal(VERSION); }); it('must parse bid size from a nested array', function () { From c24e8e1b0a6e9f4378d2141939c1e53aff2ad6e4 Mon Sep 17 00:00:00 2001 From: Jozef Bartek <31618107+jbartek25@users.noreply.github.com> Date: Mon, 10 Feb 2020 10:36:45 +0100 Subject: [PATCH 037/496] Improve Digital: CCPA support (#4828) --- modules/improvedigitalBidAdapter.js | 11 +++++++++-- test/spec/modules/improvedigitalBidAdapter_spec.js | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index cd7ab1bd50b..4e43b137c9f 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -6,7 +6,7 @@ import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; const BIDDER_CODE = 'improvedigital'; export const spec = { - version: '6.0.1', + version: '6.1.0', code: BIDDER_CODE, aliases: ['id'], supportedMediaTypes: [BANNER, NATIVE, VIDEO], @@ -43,6 +43,10 @@ export const spec = { requestParameters.gdpr = bidderRequest.gdprConsent.consentString; } + if (bidderRequest && bidderRequest.uspConsent) { + requestParameters.usPrivacy = bidderRequest.uspConsent; + } + if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { requestParameters.referrer = bidderRequest.refererInfo.referer; } @@ -343,7 +347,7 @@ export function ImproveDigitalAdServerJSClient(endPoint) { AD_SERVER_BASE_URL: 'ice.360yield.com', END_POINT: endPoint || 'hb', AD_SERVER_URL_PARAM: 'jsonp=', - CLIENT_VERSION: 'JS-6.2.0', + CLIENT_VERSION: 'JS-6.3.0', MAX_URL_LENGTH: 2083, ERROR_CODES: { MISSING_PLACEMENT_PARAMS: 2, @@ -497,6 +501,9 @@ export function ImproveDigitalAdServerJSClient(endPoint) { if (requestParameters.gdpr || requestParameters.gdpr === 0) { impressionBidRequestObject.gdpr = requestParameters.gdpr; } + if (requestParameters.usPrivacy) { + impressionBidRequestObject.us_privacy = requestParameters.usPrivacy; + } if (requestParameters.schain) { impressionBidRequestObject.schain = requestParameters.schain; } diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 15b7e2ff3e8..8983b47fcb0 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -103,6 +103,8 @@ describe('Improve Digital Adapter Tests', function () { expect(params.bid_request).to.be.an('object'); expect(params.bid_request.id).to.be.a('string'); expect(params.bid_request.version).to.equal(`${spec.version}-${idClient.CONSTANTS.CLIENT_VERSION}`); + expect(params.bid_request.gdpr).to.not.exist; + expect(params.bid_request.us_privacy).to.not.exist; expect(params.bid_request.imp).to.deep.equal([ { id: '33e9500b21129f', @@ -186,6 +188,13 @@ describe('Improve Digital Adapter Tests', function () { expect(params.bid_request.gdpr).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); }); + it('should add CCPA consent string', function () { + const bidRequest = Object.assign({}, simpleBidRequest); + const request = spec.buildRequests([bidRequest], { uspConsent: '1YYY' })[0]; + const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); + expect(params.bid_request.us_privacy).to.equal('1YYY'); + }); + it('should add referrer', function () { const bidRequest = Object.assign({}, simpleBidRequest); const request = spec.buildRequests([bidRequest], bidderRequestReferrer)[0]; From d958588fe2f6c34cc5eb900c177413cef4d1fcfd Mon Sep 17 00:00:00 2001 From: hdeodhar <35999856+hdeodhar@users.noreply.github.com> Date: Mon, 10 Feb 2020 13:28:12 +0000 Subject: [PATCH 038/496] Added size 1800x200 (#4822) Persgroep wants to run full page takeovers hence the request. Separate discussion on-going for Demand Manager too. --- modules/rubiconBidAdapter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index ec8537cc0bf..801bbc3dd8c 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -97,6 +97,7 @@ var sizeMap = { 257: '400x600', 264: '970x1000', 265: '1920x1080', + 274: '1800x200', 278: '320x500', 288: '640x380' }; From 872e815aa0113d1f988feb1fe6184e062c32886b Mon Sep 17 00:00:00 2001 From: martacieslak Date: Mon, 10 Feb 2020 15:27:59 +0100 Subject: [PATCH 039/496] AdOcean adapter improvement (#4831) * Initial revision of adocean bid adapter (ADOCEAN-13634, ADOCEAN-13635) * Minor fixes * new demo placement * formating after lint * move request parameters to params * adocean adpater tests * minor fixes * added ttl, netRevenue nad creativeId. merged with upstream * GDPR support * do not send empty gdpr_consent * GDPR support * do not send empty gdpr_consent * AdOcean adapter: tests for gdpr_support * remove old comment * Added possibility to use multiple times same ad placement * Tests for placement duplication and gdpr support. * formating * add randomized part to endpoint url * fix tests after endpoint url change Co-authored-by: Jacek Drobiecki --- modules/adoceanBidAdapter.js | 8 +++++--- test/spec/modules/adoceanBidAdapter_spec.js | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/adoceanBidAdapter.js b/modules/adoceanBidAdapter.js index aa89bf3a23d..9a09cfffdde 100644 --- a/modules/adoceanBidAdapter.js +++ b/modules/adoceanBidAdapter.js @@ -12,7 +12,8 @@ function buildEndpointUrl(emiter, payload) { payloadString += k + '=' + encodeURIComponent(v); }); - return 'https://' + emiter + '/ad.json?' + payloadString; + const randomizedPart = Math.random().toString().slice(2); + return 'https://' + emiter + '/_' + randomizedPart + '/ad.json?' + payloadString; } function buildRequest(masterBidRequests, masterId, gdprConsent) { @@ -57,7 +58,8 @@ function assignToMaster(bidRequest, bidRequestsByMaster) { } function interpretResponse(placementResponse, bidRequest, bids) { - if (!placementResponse.error) { + const requestId = bidRequest.bidIdMap[placementResponse.id]; + if (!placementResponse.error && requestId) { let adCode = '', + 'adomain': ['amazon.com'], + 'iurl': 'https://thetradedesk-t-general.s3.amazonaws.com/AdvertiserLogos/vgl908z.png', + 'cid': '22918', + 'crid': 'v55jutrh', + 'h': 250, + 'w': 300, + 'ext': {} + }] + }] + } + }; + }); + describe('implementation', function() { + describe('Bid validations', function() { + it('valid bid case', function() { + var validBid = { + bidder: 'lemma', + params: { + pubId: 1001, + adunitId: 1 + } + }, + isValid = spec.isBidRequestValid(validBid); + expect(isValid).to.equal(true); + }); + it('invalid bid case', function() { + var isValid = spec.isBidRequestValid(); + expect(isValid).to.equal(false); + }); + it('invalid bid case: pubId not passed', function() { + var validBid = { + bidder: 'lemma', + params: { + adunitId: 1 + } + }, + isValid = spec.isBidRequestValid(validBid); + expect(isValid).to.equal(false); + }); + it('invalid bid case: pubId is not number', function() { + var validBid = { + bidder: 'lemma', + params: { + pubId: '301', + adunitId: 1 + } + }, + isValid = spec.isBidRequestValid(validBid); + expect(isValid).to.equal(false); + }); + it('invalid bid case: adunitId is not passed', function() { + var validBid = { + bidder: 'lemma', + params: { + pubId: 1001 + } + }, + isValid = spec.isBidRequestValid(validBid); + expect(isValid).to.equal(false); + }); + it('invalid bid case: video bid request mimes is not passed', function() { + var validBid = { + bidder: 'lemma', + params: { + pubId: 1001, + adunitId: 1, + video: { + skippable: true, + minduration: 5, + maxduration: 30 + } + } + }, + isValid = spec.isBidRequestValid(validBid); + expect(isValid).to.equal(false); + validBid.params.video.mimes = []; + isValid = spec.isBidRequestValid(validBid); + expect(isValid).to.equal(false); + }); + }); + describe('Request formation', function() { + it('buildRequests function should not modify original bidRequests object', function() { + var originalBidRequests = utils.deepClone(bidRequests); + var request = spec.buildRequests(bidRequests); + expect(bidRequests).to.deep.equal(originalBidRequests); + }); + it('Endpoint checking', function() { + var request = spec.buildRequests(bidRequests); + expect(request.url).to.equal('https://ads.lemmatechnologies.com/lemma/servad?pid=1001&aid=1'); + expect(request.method).to.equal('POST'); + }); + it('Request params check', function() { + var request = spec.buildRequests(bidRequests); + var data = JSON.parse(request.data); + expect(data.site.domain).to.be.a('string'); // domain should be set + expect(data.site.publisher.id).to.equal(bidRequests[0].params.pubId.toString()); // publisher Id + expect(data.imp[0].tagid).to.equal('1'); // tagid + expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); + }); + it('Request params check without mediaTypes object', function() { + var bidRequests = [{ + bidder: 'lemma', + params: { + pubId: 1001, + adunitId: 1, + currency: 'AUD' + }, + sizes: [ + [300, 250], + [300, 600] + ] + }]; + var request = spec.buildRequests(bidRequests); + var data = JSON.parse(request.data); + expect(data.imp[0].banner.w).to.equal(300); // width + expect(data.imp[0].banner.h).to.equal(250); // height + expect(data.imp[0].banner.format).exist.and.to.be.an('array'); + expect(data.imp[0].banner.format[0]).exist.and.to.be.an('object'); + expect(data.imp[0].banner.format[0].w).to.equal(300); // width + expect(data.imp[0].banner.format[0].h).to.equal(600); // height + }); + it('Request params check: without tagId', function() { + delete bidRequests[0].params.adunitId; + var request = spec.buildRequests(bidRequests); + var data = JSON.parse(request.data); + expect(data.site.domain).to.be.a('string'); // domain should be set + expect(data.site.publisher.id).to.equal(bidRequests[0].params.pubId.toString()); // publisher Id + expect(data.imp[0].tagid).to.equal(undefined); // tagid + expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); + }); + it('Request params multi size format object check', function() { + var bidRequests = [{ + bidder: 'lemma', + mediaTypes: { + banner: { + sizes: [ + [300, 250], + [300, 600] + ], + } + }, + params: { + pubId: 1001, + adunitId: 1, + currency: 'AUD' + }, + sizes: [ + [300, 250], + [300, 600] + ] + }]; + /* case 1 - size passed in adslot */ + var request = spec.buildRequests(bidRequests); + var data = JSON.parse(request.data); + expect(data.imp[0].banner.w).to.equal(300); // width + expect(data.imp[0].banner.h).to.equal(250); // height + /* case 2 - size passed in adslot as well as in sizes array */ + bidRequests[0].sizes = [ + [300, 600], + [300, 250] + ]; + bidRequests[0].mediaTypes = { + banner: { + sizes: [ + [300, 600], + [300, 250] + ] + } + }; + request = spec.buildRequests(bidRequests); + data = JSON.parse(request.data); + expect(data.imp[0].banner.w).to.equal(300); // width + expect(data.imp[0].banner.h).to.equal(600); // height + /* case 3 - size passed in sizes but not in adslot */ + bidRequests[0].params.adunitId = 1; + bidRequests[0].sizes = [ + [300, 250], + [300, 600] + ]; + bidRequests[0].mediaTypes = { + banner: { + sizes: [ + [300, 250], + [300, 600] + ] + } + }; + request = spec.buildRequests(bidRequests); + data = JSON.parse(request.data); + expect(data.imp[0].banner.w).to.equal(300); // width + expect(data.imp[0].banner.h).to.equal(250); // height + expect(data.imp[0].banner.format).exist.and.to.be.an('array'); + expect(data.imp[0].banner.format[0]).exist.and.to.be.an('object'); + expect(data.imp[0].banner.format[0].w).to.equal(300); // width + expect(data.imp[0].banner.format[0].h).to.equal(250); // height + }); + it('Request params currency check', function() { + var bidRequest = [{ + bidder: 'lemma', + mediaTypes: { + banner: { + sizes: [ + [300, 250], + [300, 600] + ], + } + }, + params: { + pubId: 1001, + adunitId: 1, + currency: 'AUD' + }, + sizes: [ + [300, 250], + [300, 600] + ] + }]; + /* case 1 - + currency specified in adunits + output: imp[0] use currency specified in bidRequests[0].params.currency + */ + var request = spec.buildRequests(bidRequest); + var data = JSON.parse(request.data); + expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); + /* case 2 - + currency specified in adunit + output: imp[0] use default currency - USD + */ + delete bidRequest[0].params.currency; + request = spec.buildRequests(bidRequest); + data = JSON.parse(request.data); + expect(data.imp[0].bidfloorcur).to.equal('USD'); + }); + it('Request params check for video ad', function() { + var request = spec.buildRequests(videoBidRequests); + var data = JSON.parse(request.data); + expect(data.imp[0].video).to.exist; + expect(data.imp[0].tagid).to.equal('1'); + expect(data.imp[0]['video']['mimes']).to.exist.and.to.be.an('array'); + expect(data.imp[0]['video']['mimes'][0]).to.equal(videoBidRequests[0].params.video['mimes'][0]); + expect(data.imp[0]['video']['mimes'][1]).to.equal(videoBidRequests[0].params.video['mimes'][1]); + expect(data.imp[0]['video']['minduration']).to.equal(videoBidRequests[0].params.video['minduration']); + expect(data.imp[0]['video']['maxduration']).to.equal(videoBidRequests[0].params.video['maxduration']); + expect(data.imp[0]['video']['w']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[0]); + expect(data.imp[0]['video']['h']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[1]); + }); + describe('Response checking', function() { + it('should check for valid response values', function() { + var request = spec.buildRequests(bidRequests); + var data = JSON.parse(request.data); + var response = spec.interpretResponse(bidResponses, request); + expect(response).to.be.an('array').with.length.above(0); + expect(response[0].requestId).to.equal(bidResponses.body.seatbid[0].bid[0].impid); + expect(response[0].cpm).to.equal((bidResponses.body.seatbid[0].bid[0].price).toFixed(2)); + expect(response[0].width).to.equal(bidResponses.body.seatbid[0].bid[0].w); + expect(response[0].height).to.equal(bidResponses.body.seatbid[0].bid[0].h); + if (bidResponses.body.seatbid[0].bid[0].crid) { + expect(response[0].creativeId).to.equal(bidResponses.body.seatbid[0].bid[0].crid); + } else { + expect(response[0].creativeId).to.equal(bidResponses.body.seatbid[0].bid[0].id); + } + expect(response[0].dealId).to.equal(bidResponses.body.seatbid[0].bid[0].dealid); + expect(response[0].currency).to.equal('USD'); + expect(response[0].netRevenue).to.equal(false); + expect(response[0].ttl).to.equal(300); + }); + }); + }); + }); +}); From 86981e146eca4e2c9b2ff4f2d77b93a92ac6a8da Mon Sep 17 00:00:00 2001 From: Jonathan Mullins Date: Tue, 11 Feb 2020 15:10:04 +1100 Subject: [PATCH 042/496] added support for US Privacy consent string (#4799) updated GDPR implementation for OpenRTB v2.2+ support --- modules/playgroundxyzBidAdapter.js | 17 ++++++++-- .../modules/playgroundxyzBidAdapter_spec.js | 34 +++++++++++++++---- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/modules/playgroundxyzBidAdapter.js b/modules/playgroundxyzBidAdapter.js index 88d68f899ff..0132b6a13d6 100644 --- a/modules/playgroundxyzBidAdapter.js +++ b/modules/playgroundxyzBidAdapter.js @@ -49,13 +49,24 @@ export const spec = { language: navigator.language, devicetype: isMobile() ? 1 : isConnectedTV() ? 3 : 2, }, - imp: bidRequests.map(mapImpression) + imp: bidRequests.map(mapImpression), + Regs: { ext: {} } }; + // GDPR if (bidderRequest && bidderRequest.gdprConsent) { - payload.user = {ext: {consent: bidderRequest.gdprConsent.consentString}}; const gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - payload.regs = {ext: {gdpr: gdpr}}; + const consentString = bidderRequest.gdprConsent.consentString; + utils.logInfo(`PXYZ: GDPR applies ${gdpr}`); + utils.logInfo(`PXYZ: GDPR consent string ${consentString}`); + payload.Regs.ext.gdpr = gdpr; + payload.User = { ext: { consent: consentString } }; + } + + // CCPA + if (bidderRequest && bidderRequest.uspConsent) { + utils.logInfo(`PXYZ: USP Consent ${bidderRequest.uspConsent}`); + payload.Regs.ext['us_privacy'] = bidderRequest.uspConsent; } return { diff --git a/test/spec/modules/playgroundxyzBidAdapter_spec.js b/test/spec/modules/playgroundxyzBidAdapter_spec.js index 5d02cede9af..7b89a4a160c 100644 --- a/test/spec/modules/playgroundxyzBidAdapter_spec.js +++ b/test/spec/modules/playgroundxyzBidAdapter_spec.js @@ -75,13 +75,35 @@ describe('playgroundxyzBidAdapter', function () { expect(request.method).to.equal('POST'); }); + describe('CCPA', function () { + describe('when USP consent object is NOT present in bidder request', function () { + const request = spec.buildRequests(bidRequests, BIDDER_REQUEST); + const data = JSON.parse(request.data); + it('should not populate ext.gdpr or ext.consent', function () { + expect(data).to.not.have.property('Regs.ext.us_privacy'); + }); + }); + + describe('when USP consent object is present in bidder request', function () { + describe('when GDPR is applicable', function () { + const request = spec.buildRequests( + bidRequests, + Object.assign({}, BIDDER_REQUEST, { uspConsent: '1YYY' }) + ); + const data = JSON.parse(request.data); + it('should set Regs.ext.us_privacy with the correct value', function () { + expect(data.Regs.ext['us_privacy']).to.equal('1YYY'); + }); + }); + }); + }); + describe('GDPR', function () { describe('when no GDPR consent object is present in bidder request', function () { const request = spec.buildRequests(bidRequests, BIDDER_REQUEST); const data = JSON.parse(request.data); it('should not populate ext.gdpr or ext.consent', function () { - expect(data).to.not.have.property('user'); - expect(data).to.not.have.property('regs'); + expect(data).to.not.have.property('Regs.ext.consent'); }); }); @@ -95,10 +117,10 @@ describe('playgroundxyzBidAdapter', function () { ); const data = JSON.parse(request.data); it('should set ext.gdpr with 1', function () { - expect(data.regs.ext.gdpr).to.equal(1); + expect(data.Regs.ext.gdpr).to.equal(1); }); it('should set ext.consent', function () { - expect(data.user.ext.consent).to.equal('XYZ-CONSENT'); + expect(data.User.ext.consent).to.equal('XYZ-CONSENT'); }); }); describe('when GDPR is NOT applicable', function () { @@ -110,10 +132,10 @@ describe('playgroundxyzBidAdapter', function () { ); const data = JSON.parse(request.data); it('should set ext.gdpr to 0', function () { - expect(data.regs.ext.gdpr).to.equal(0); + expect(data.Regs.ext.gdpr).to.equal(0); }); it('should populate ext.consent', function () { - expect(data.user.ext.consent).to.equal('XYZ-CONSENT'); + expect(data.User.ext.consent).to.equal('XYZ-CONSENT'); }); }); }); From c99c78f84c8f484380995a8e399708af43418c6b Mon Sep 17 00:00:00 2001 From: Joseph Tyler Jones Date: Tue, 11 Feb 2020 05:45:21 -0800 Subject: [PATCH 043/496] Fixed oneVideo TypeError when consentData is undefined (#4788) * Fixed oneVideo TypeError when consentData is undefined * Check consentData is defined --- modules/oneVideoBidAdapter.js | 4 ++-- test/spec/modules/oneVideoBidAdapter_spec.js | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/oneVideoBidAdapter.js b/modules/oneVideoBidAdapter.js index eff8bd9f34b..792784cb7ac 100644 --- a/modules/oneVideoBidAdapter.js +++ b/modules/oneVideoBidAdapter.js @@ -103,7 +103,7 @@ export const spec = { * @param {ServerResponse[]} serverResponses List of server's responses. * @return {UserSync[]} The user syncs which should be dropped. */ - getUserSyncs: function(syncOptions, responses, consentData) { + getUserSyncs: function(syncOptions, responses, consentData = {}) { let { gdprApplies, consentString = '' } = consentData; if (syncOptions.pixelEnabled) { @@ -242,7 +242,7 @@ function getRequestData(bid, consentData, bidRequest) { bidData.regs.ext.gdpr = 1 } - if (consentData.consentString) { + if (consentData && consentData.consentString) { bidData.user = { ext: { consent: consentData.consentString diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js index c2e698737cf..623fbeaf90d 100644 --- a/test/spec/modules/oneVideoBidAdapter_spec.js +++ b/test/spec/modules/oneVideoBidAdapter_spec.js @@ -415,6 +415,11 @@ describe('OneVideoBidAdapter', function () { expect(pixel[2].type).to.equal('image'); expect(pixel[2].url).to.equal('https://sync-tm.everesttech.net/upi/pid/m7y5t93k?gdpr=1&gdpr_consent=' + GDPR_CONSENT_STRING + '&redir=https%3A%2F%2Fpixel.advertising.com%2Fups%2F55986%2Fsync%3Fuid%3D%24%7BUSER_ID%7D%26_origin%3D0&gdpr=1&gdpr_consent=' + encodeURI(GDPR_CONSENT_STRING)); }); + + it('should default to gdprApplies=0 when consentData is undefined', function () { + let pixel = spec.getUserSyncs({pixelEnabled: true}, {}, undefined); + expect(pixel[2].url).to.equal('https://sync-tm.everesttech.net/upi/pid/m7y5t93k?gdpr=0&gdpr_consent=&redir=https%3A%2F%2Fpixel.advertising.com%2Fups%2F55986%2Fsync%3Fuid%3D%24%7BUSER_ID%7D%26_origin%3D0&gdpr=0&gdpr_consent='); + }); }); }); }); From 469ec57c2fb91d74bbc058446d753ae8709b1b19 Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Wed, 12 Feb 2020 01:17:58 -0500 Subject: [PATCH 044/496] implements the todo comment in the code (#4821) * implements the todo comment in the code adUnit.sizes was still being referenced here in two places despite being deprecated. This simply deletes the references. * Update pbjs_api_spec.js * Update pbjs_api_spec.js --- src/prebid.js | 4 +--- test/spec/unit/pbjs_api_spec.js | 8 -------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/prebid.js b/src/prebid.js index f1ead426496..004f0fa29dd 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -93,8 +93,6 @@ export const checkAdUnitSetup = hook('sync', function (adUnits) { const bannerSizes = validateSizes(mediaTypes.banner.sizes); if (bannerSizes.length > 0) { mediaTypes.banner.sizes = bannerSizes; - // TODO eventually remove this internal copy once we're ready to deprecate bidders from reading this adUnit.sizes property - adUnit.sizes = bannerSizes; } else { utils.logError('Detected a mediaTypes.banner object without a proper sizes field. Please ensure the sizes are listed like: [[300, 250], ...]. Removing invalid mediaTypes.banner object from request.'); delete adUnit.mediaTypes.banner; @@ -107,7 +105,7 @@ export const checkAdUnitSetup = hook('sync', function (adUnits) { let tarPlayerSizeLen = (typeof video.playerSize[0] === 'number') ? 2 : 1; const videoSizes = validateSizes(video.playerSize, tarPlayerSizeLen); if (videoSizes.length > 0) { - adUnit.sizes = video.playerSize = videoSizes; + video.playerSize = videoSizes; } else { utils.logError('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.'); delete adUnit.mediaTypes.video.playerSize; diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index 6d98830ac42..e70956a3eed 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -1513,7 +1513,6 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: fullAdUnit }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[640, 480]]); expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.deep.equal([[640, 480]]); expect(auctionArgs.adUnits[0].mediaTypes.native.image.sizes).to.deep.equal([150, 150]); expect(auctionArgs.adUnits[0].mediaTypes.native.icon.sizes).to.deep.equal([75, 75]); @@ -1543,7 +1542,6 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: noOptnlFieldAdUnit }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[300, 250]]); expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; let mixedAdUnit = [{ @@ -1566,7 +1564,6 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: mixedAdUnit }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[400, 350]]); expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; let altVideoPlayerSize = [{ @@ -1582,7 +1579,6 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: altVideoPlayerSize }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[640, 480]]); expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.deep.equal([[640, 480]]); expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; }); @@ -1601,7 +1597,6 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: normalizeAdUnit }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[300, 250]]); expect(auctionArgs.adUnits[0].mediaTypes.banner.sizes).to.deep.equal([[300, 250]]); }); }); @@ -1621,7 +1616,6 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: badBanner }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[300, 250], [300, 600]]); expect(auctionArgs.adUnits[0].mediaTypes.banner).to.be.undefined; assert.ok(logErrorSpy.calledWith('Detected a mediaTypes.banner object without a proper sizes field. Please ensure the sizes are listed like: [[300, 250], ...]. Removing invalid mediaTypes.banner object from request.')); @@ -1638,7 +1632,6 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: badVideo1 }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[600, 600]]); expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.be.undefined; expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; assert.ok(logErrorSpy.calledWith('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.')); @@ -1656,7 +1649,6 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: badVideo2 }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[600, 600]]); expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.be.undefined; expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; assert.ok(logErrorSpy.calledWith('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.')); From 3fe85c3ce5c54c48e83a7cd0d87faf16978bb296 Mon Sep 17 00:00:00 2001 From: Chris Connors Date: Wed, 12 Feb 2020 08:02:10 -0500 Subject: [PATCH 045/496] Scaleable Analytics Adapter: Grouping Server Calls (#4634) * Initial draft changes for adapter * Updated bids and tests * Fixed timeouts being sent all the time * Added prod endpoint back * Test Updates to be more in line with base spec file * Sending bidder params to server with win event * Missed a conflict with new XHR functionality * Added local Object.entries polyfill --- modules/scaleableAnalyticsAdapter.js | 148 ++++++++++++------ .../modules/scaleableAnalyticsAdapter_spec.js | 110 +++++++++---- 2 files changed, 175 insertions(+), 83 deletions(-) diff --git a/modules/scaleableAnalyticsAdapter.js b/modules/scaleableAnalyticsAdapter.js index c875dab7e18..2fcc5943ae4 100644 --- a/modules/scaleableAnalyticsAdapter.js +++ b/modules/scaleableAnalyticsAdapter.js @@ -6,9 +6,18 @@ import adapter from '../src/AnalyticsAdapter'; import adapterManager from '../src/adapterManager'; import * as utils from '../src/utils'; +// Object.entries polyfill +const entries = Object.entries || function(obj) { + const ownProps = Object.keys(obj); + let i = ownProps.length; + let resArray = new Array(i); // preallocate the Array + while (i--) { resArray[i] = [ownProps[i], obj[ownProps[i]]]; } + + return resArray; +}; + const BID_TIMEOUT = CONSTANTS.EVENTS.BID_TIMEOUT; const AUCTION_INIT = CONSTANTS.EVENTS.AUCTION_INIT; -const BID_RESPONSE = CONSTANTS.EVENTS.BID_RESPONSE; const BID_WON = CONSTANTS.EVENTS.BID_WON; const AUCTION_END = CONSTANTS.EVENTS.AUCTION_END; @@ -35,9 +44,6 @@ let scaleableAnalytics = Object.assign({}, case BID_WON: onBidWon(args); break; - case BID_RESPONSE: - onBidResponse(args); - break; case BID_TIMEOUT: onBidTimeout(args); break; @@ -70,22 +76,93 @@ const sendDataToServer = data => ajax(URL, () => {}, JSON.stringify(data)); const onAuctionInit = args => { const config = scaleableAnalytics.config || {options: {}}; - for (let idx = args.adUnitCodes.length; idx--;) { - const data = { - event: 'request', - site: config.options.site, - adunit: args.adUnitCodes[idx] - }; + let adunitObj = {}; + let adunits = []; + + // Loop through adunit codes first + args.adUnitCodes.forEach((code) => { + adunitObj[code] = [{ + bidder: 'scaleable_adunit_request' + }] + }); + + // Loop through bidder requests and bids + args.bidderRequests.forEach((bidderObj) => { + bidderObj.bids.forEach((bidObj) => { + adunitObj[bidObj.adUnitCode].push({ + bidder: bidObj.bidder, + params: bidObj.params + }) + }); + }); + + entries(adunitObj).forEach(([adunitCode, bidRequests]) => { + adunits.push({ + code: adunitCode, + bidRequests: bidRequests + }); + }); - sendDataToServer(data); + const data = { + event: 'request', + site: config.options.site, + adunits: adunits } + + sendDataToServer(data); } // Handle all events besides requests and wins const onAuctionEnd = args => { - for (let adunit in auctionData) { - sendDataToServer(auctionData[adunit]); + const config = scaleableAnalytics.config || {options: {}}; + + let adunitObj = {}; + let adunits = []; + + // Add Bids Received + args.bidsReceived.forEach((bidObj) => { + if (!adunitObj[bidObj.adUnitCode]) { adunitObj[bidObj.adUnitCode] = []; } + + adunitObj[bidObj.adUnitCode].push({ + bidder: bidObj.bidderCode || bidObj.bidder, + cpm: bidObj.cpm, + currency: bidObj.currency, + dealId: bidObj.dealId, + type: bidObj.mediaType, + ttr: bidObj.timeToRespond, + size: bidObj.size + }); + }); + + // Add in other data (timeouts) as we push to adunits + entries(adunitObj).forEach(([adunitCode, bidsReceived]) => { + const bidData = bidsReceived.concat(auctionData[adunitCode] || []); + adunits.push({ + code: adunitCode, + bidData: bidData + }); + + delete auctionData[adunitCode]; + }); + + // Add in any missed auction data + entries(auctionData).forEach(([adunitCode, bidData]) => { + adunits.push({ + code: adunitCode, + bidData: bidData + }) + }); + + const data = { + event: 'bids', + site: config.options.site, + adunits: adunits } + + if (adunits.length) { sendDataToServer(data); } + + // Reset auctionData + auctionData = {} } // Bid Win Events occur after auction end @@ -98,51 +175,24 @@ const onBidWon = args => { adunit: args.adUnitCode, code: args.bidderCode, cpm: args.cpm, - ttr: args.timeToRespond + ttr: args.timeToRespond, + params: args.params }; sendDataToServer(data); } -const onBidResponse = args => { - const config = scaleableAnalytics.config || {options: {}}; - - if (!auctionData[args.adUnitCode]) { - auctionData[args.adUnitCode] = { - event: 'bids', - bids: [], - adunit: args.adUnitCode, - site: config.options.site - }; - } - - const currBidData = { - code: args.bidderCode, - cpm: args.cpm, - ttr: args.timeToRespond - }; - - auctionData[args.adUnitCode].bids.push(currBidData); -} - const onBidTimeout = args => { - const config = scaleableAnalytics.config || {options: {}}; - - for (let i = args.length; i--;) { - let currObj = args[i]; - + args.forEach(currObj => { if (!auctionData[currObj.adUnitCode]) { - auctionData[currObj.adUnitCode] = { - event: 'bids', - bids: [], - timeouts: [], - adunit: currObj.adUnitCode, - site: config.options.site - }; + auctionData[currObj.adUnitCode] = [] } - auctionData[currObj.adUnitCode].timeouts.push(currObj.bidder); - } + auctionData[currObj.adUnitCode].push({ + timeouts: 1, + bidder: currObj.bidder + }); + }); } adapterManager.registerAnalyticsAdapter({ diff --git a/test/spec/modules/scaleableAnalyticsAdapter_spec.js b/test/spec/modules/scaleableAnalyticsAdapter_spec.js index f26d91f7aa1..7ee1a7b1e96 100644 --- a/test/spec/modules/scaleableAnalyticsAdapter_spec.js +++ b/test/spec/modules/scaleableAnalyticsAdapter_spec.js @@ -6,19 +6,44 @@ import { server } from 'test/mocks/xhr'; const BID_TIMEOUT = CONSTANTS.EVENTS.BID_TIMEOUT; const AUCTION_INIT = CONSTANTS.EVENTS.AUCTION_INIT; -const BID_RESPONSE = CONSTANTS.EVENTS.BID_RESPONSE; const BID_WON = CONSTANTS.EVENTS.BID_WON; const AUCTION_END = CONSTANTS.EVENTS.AUCTION_END; describe('Scaleable Analytics Adapter', function() { + const bidsReceivedObj = { + adUnitCode: '12345', + bidderCode: 'test-code', + cpm: 3.14, + currency: 'USD', + dealId: null, + mediaType: 'banner', + timeToRespond: 285, + size: '300x250' + }; + const MOCK_DATA = { adUnitCode: '12345', + auctionEnd: { + bidsReceived: [bidsReceivedObj] + }, + bidderRequests: [{ + bids: [{ + adUnitCode: '12345', + bidder: 'test-code', + params: { + test: 'value' + } + }] + }], site: '5c4fab7a829e955d6c265e72', bidResponse: { adUnitCode: '12345', bidderCode: 'test-code', cpm: 3.14, - timeToRespond: 285 + timeToRespond: 285, + params: [{ + test: 'value' + }] }, bidTimeout: [ { @@ -28,25 +53,52 @@ describe('Scaleable Analytics Adapter', function() { ] }; - MOCK_DATA.expectedBidResponse = { - event: 'bids', - bids: [{ - code: MOCK_DATA.bidResponse.bidderCode, - cpm: MOCK_DATA.bidResponse.cpm, - ttr: MOCK_DATA.bidResponse.timeToRespond - }], - adunit: MOCK_DATA.adUnitCode, - site: MOCK_DATA.site - }; + const bidObj = MOCK_DATA.bidderRequests[0].bids[0]; + + const expectedBidRequests = [{bidder: 'scaleable_adunit_request'}].concat([ + { + bidder: bidObj.bidder, + params: bidObj.params + } + ]); + + MOCK_DATA.expectedRequestResponse = { + event: 'request', + site: MOCK_DATA.site, + adunits: [{ + code: bidObj.adUnitCode, + bidRequests: expectedBidRequests + }] + } MOCK_DATA.expectedBidTimeout = { - event: 'bids', - bids: [], - timeouts: [MOCK_DATA.bidTimeout[0].bidder], - adunit: MOCK_DATA.bidTimeout[0].adUnitCode, - site: MOCK_DATA.site + [MOCK_DATA.bidTimeout[0].adUnitCode]: [{ + timeouts: 1, + bidder: MOCK_DATA.bidTimeout[0].bidder + }] }; + MOCK_DATA.expectedAuctionEndResponse = { + event: 'bids', + site: MOCK_DATA.site, + adunits: [{ + code: MOCK_DATA.auctionEnd.bidsReceived[0].adUnitCode, + bidData: [{ + bidder: bidsReceivedObj.bidderCode, + cpm: bidsReceivedObj.cpm, + currency: bidsReceivedObj.currency, + dealId: bidsReceivedObj.dealId, + type: bidsReceivedObj.mediaType, + ttr: bidsReceivedObj.timeToRespond, + size: bidsReceivedObj.size + }] + }, + { + bidData: MOCK_DATA.expectedBidTimeout[MOCK_DATA.bidTimeout[0].adUnitCode], + code: MOCK_DATA.bidTimeout[0].adUnitCode + }] + } + describe('Event Handling', function() { beforeEach(function() { sinon.stub(events, 'getEvents').returns([]); @@ -66,33 +118,22 @@ describe('Scaleable Analytics Adapter', function() { it('should handle the auction init event', function(done) { events.emit(AUCTION_INIT, { - adUnitCodes: [MOCK_DATA.adUnitCode] + adUnitCodes: [MOCK_DATA.adUnitCode], + bidderRequests: MOCK_DATA.bidderRequests }); const result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({ - event: 'request', - site: MOCK_DATA.site, - adunit: MOCK_DATA.adUnitCode - }); + expect(result).to.deep.equal(MOCK_DATA.expectedRequestResponse); done(); }); - it('should handle the bid response event', function() { - events.emit(BID_RESPONSE, MOCK_DATA.bidResponse); - - const actual = scaleableAnalytics.getAuctionData(); - - expect(actual[MOCK_DATA.adUnitCode]).to.deep.equal(MOCK_DATA.expectedBidResponse); - }); - it('should handle the bid timeout event', function() { events.emit(BID_TIMEOUT, MOCK_DATA.bidTimeout); const actual = scaleableAnalytics.getAuctionData(); - expect(actual[MOCK_DATA.bidTimeout[0].adUnitCode]).to.deep.equal(MOCK_DATA.expectedBidTimeout); + expect(actual).to.deep.equal(MOCK_DATA.expectedBidTimeout); }); it('should handle the bid won event', function(done) { @@ -104,6 +145,7 @@ describe('Scaleable Analytics Adapter', function() { code: MOCK_DATA.bidResponse.bidderCode, cpm: MOCK_DATA.bidResponse.cpm, ttr: MOCK_DATA.bidResponse.timeToRespond, + params: MOCK_DATA.bidResponse.params, event: 'win', site: MOCK_DATA.site }); @@ -112,10 +154,10 @@ describe('Scaleable Analytics Adapter', function() { }); it('should handle the auction end event', function(done) { - events.emit(AUCTION_END, {}); + events.emit(AUCTION_END, MOCK_DATA.auctionEnd); const result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal(MOCK_DATA.expectedBidResponse); + expect(result).to.deep.equal(MOCK_DATA.expectedAuctionEndResponse); done(); }); From 720038ee652a9a6041fb0b790a4e1a6eee8743b2 Mon Sep 17 00:00:00 2001 From: omerBrowsi <54346241+omerBrowsi@users.noreply.github.com> Date: Wed, 12 Feb 2020 16:11:22 +0200 Subject: [PATCH 046/496] Improvements for browsi RTD provider (#4598) * real time data module, browsi sub module for real time data, new hook bidsBackCallback, fix for config unsubscribe * change timeout&primary ad server only to auctionDelay update docs * support multiple providers * change promise to callbacks configure submodule on submodules.json * bug fixes * use Prebid ajax * tests fix * browsi real time data provider improvements * real time data module, browsi sub module for real time data, new hook bidsBackCallback, fix for config unsubscribe * change timeout&primary ad server only to auctionDelay update docs * support multiple providers * change promise to callbacks configure submodule on submodules.json * bug fixes * use Prebid ajax * tests fix * browsi real time data provider improvements * remove eval * use external script, update macro function * lint errors * removed log --- modules/browsiRtdProvider.js | 94 ++++++++++++++++++++---- modules/rtdModule/index.js | 11 ++- src/auction.js | 2 +- test/spec/modules/realTimeModule_spec.js | 8 +- 4 files changed, 94 insertions(+), 21 deletions(-) diff --git a/modules/browsiRtdProvider.js b/modules/browsiRtdProvider.js index a288869215b..e2bd208f32f 100644 --- a/modules/browsiRtdProvider.js +++ b/modules/browsiRtdProvider.js @@ -13,17 +13,20 @@ * @property {string} pubKey * @property {string} url * @property {?string} keyName - * @property {number} auctionDelay + * @property {?number} auctionDelay + * @property {?number} timeout */ import {config} from '../src/config.js'; import * as utils from '../src/utils'; import {submodule} from '../src/hook'; -import {ajax} from '../src/ajax'; +import {ajaxBuilder} from '../src/ajax'; import {loadExternalScript} from '../src/adloader'; /** @type {string} */ const MODULE_NAME = 'realTimeData'; +/** @type {number} */ +const DEF_TIMEOUT = 1000; /** @type {ModuleParams} */ let _moduleParams = {}; /** @type {null|Object} */ @@ -33,14 +36,20 @@ let _dataReadyCallback = null; /** * add browsi script to page - * @param {string} bptUrl + * @param {Object} data */ -export function addBrowsiTag(bptUrl) { - let script = loadExternalScript(bptUrl, 'browsi'); +export function addBrowsiTag(data) { + let script = loadExternalScript(data.u, 'browsi'); + script.async = true; script.setAttribute('data-sitekey', _moduleParams.siteKey); script.setAttribute('data-pubkey', _moduleParams.pubKey); script.setAttribute('prebidbpt', 'true'); script.setAttribute('id', 'browsi-tag'); + script.setAttribute('src', data.u); + script.prebidData = utils.deepClone(data); + if (_moduleParams.keyName) { + script.prebidData.kn = _moduleParams.keyName; + } return script; } @@ -109,17 +118,20 @@ function sendDataToModule(adUnits, onDone) { return onDone({}); } const slots = getAllSlots(); - if (!slots) { + if (!slots || !slots.length) { return onDone({}); } let dataToReturn = adUnits.reduce((rp, cau) => { const adUnitCode = cau && cau.code; if (!adUnitCode) { return rp } - const predictionData = _predictions[adUnitCode]; + const adSlot = getSlotById(adUnitCode); + if (!adSlot) { return rp } + const macroId = getMacroId(_predictionsData.pmd, adUnitCode, adSlot); + const predictionData = _predictions[macroId]; if (!predictionData) { return rp } if (predictionData.p) { - if (!isIdMatchingAdUnit(adUnitCode, slots, predictionData.w)) { + if (!isIdMatchingAdUnit(adUnitCode, adSlot, predictionData.w)) { return rp; } rp[adUnitCode] = getKVObject(predictionData.p, _predictionsData.kn); @@ -155,24 +167,75 @@ function getKVObject(p, keyName) { /** * check if placement id matches one of given ad units * @param {number} id placement id - * @param {Object[]} allSlots google slots on page + * @param {Object} slot google slot * @param {string[]} whitelist ad units * @return {boolean} */ -export function isIdMatchingAdUnit(id, allSlots, whitelist) { +export function isIdMatchingAdUnit(id, slot, whitelist) { if (!whitelist || !whitelist.length) { return true; } - const slot = allSlots.filter(s => s.getSlotElementId() === id); - const slotAdUnits = slot.map(s => s.getAdUnitPath()); - return slotAdUnits.some(a => whitelist.indexOf(a) !== -1); + const slotAdUnits = slot.getAdUnitPath(); + return whitelist.indexOf(slotAdUnits) !== -1; } +/** + * get GPT slot by placement id + * @param {string} id placement id + * @return {?Object} + */ +function getSlotById(id) { + const slots = getAllSlots(); + if (!slots || !slots.length) { + return null; + } + return slots.filter(s => s.getSlotElementId() === id)[0] || null; +} + +/** + * generate id according to macro script + * @param {string} macro replacement macro + * @param {string} id placement id + * @param {Object} slot google slot + * @return {?Object} + */ +function getMacroId(macro, id, slot) { + if (macro) { + try { + const macroResult = evaluate(macro, slot.getSlotElementId(), slot.getAdUnitPath(), (match, p1) => { + return (p1 && slot.getTargeting(p1).join('_')) || 'NA'; + }); + return macroResult; + } catch (e) { + utils.logError(`failed to evaluate: ${macro}`); + } + } + return id; +} + +function evaluate(macro, divId, adUnit, replacer) { + let macroResult = macro.p + .replace(/['"]+/g, '') + .replace(//g, divId); + + if (adUnit) { + macroResult = macroResult.replace(//g, adUnit); + } + if (replacer) { + macroResult = macroResult.replace(//g, replacer); + } + if (macro.s) { + macroResult = macroResult.substring(macro.s.s, macro.s.e); + } + return macroResult; +} /** * XMLHttpRequest to get data form browsi server * @param {string} url server url with query params */ function getPredictionsFromServer(url) { + let ajax = ajaxBuilder(_moduleParams.auctionDelay || _moduleParams.timeout || DEF_TIMEOUT); + ajax(url, { success: function (response, req) { @@ -180,11 +243,11 @@ function getPredictionsFromServer(url) { try { const data = JSON.parse(response); if (data && data.p && data.kn) { - setData({p: data.p, kn: data.kn}); + setData({p: data.p, kn: data.kn, pmd: data.pmd}); } else { setData({}); } - addBrowsiTag(data.u); + addBrowsiTag(data); } catch (err) { utils.logError('unable to parse data'); setData({}) @@ -235,6 +298,7 @@ export function init(config) { _moduleParams = realTimeData.dataProviders && realTimeData.dataProviders.filter( pr => pr.name && pr.name.toLowerCase() === 'browsi')[0].params; _moduleParams.auctionDelay = realTimeData.auctionDelay; + _moduleParams.timeout = realTimeData.timeout; } catch (e) { _moduleParams = {}; } diff --git a/modules/rtdModule/index.js b/modules/rtdModule/index.js index e7ba364c0e5..3136d20ab13 100644 --- a/modules/rtdModule/index.js +++ b/modules/rtdModule/index.js @@ -47,6 +47,13 @@ * @type {Object} */ +/** + * @property + * @summary timeout (if no auction dealy) + * @name ModuleConfig#timeout + * @type {number} + */ + import {getGlobal} from '../../src/prebidGlobal'; import {config} from '../../src/config.js'; import {targeting} from '../../src/targeting'; @@ -55,6 +62,8 @@ import * as utils from '../../src/utils'; /** @type {string} */ const MODULE_NAME = 'realTimeData'; +/** @type {number} */ +const DEF_TIMEOUT = 1000; /** @type {RtdSubmodule[]} */ let subModules = []; /** @type {ModuleConfig} */ @@ -100,7 +109,7 @@ function getProviderData(adUnits, callback) { const dataWaitTimeout = setTimeout(() => { processDone = true; callback(dataReceived); - }, _moduleConfig.auctionDelay); + }, _moduleConfig.auctionDelay || _moduleConfig.timeout || DEF_TIMEOUT); subModules.forEach(sm => { sm.getData(adUnits, onDataReceived); diff --git a/src/auction.js b/src/auction.js index 2f040918837..1880a9ac8d7 100644 --- a/src/auction.js +++ b/src/auction.js @@ -168,7 +168,7 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, a _auctionEnd = Date.now(); events.emit(CONSTANTS.EVENTS.AUCTION_END, getProperties()); - bidsBackCallback(_adUnitCodes, function () { + bidsBackCallback(_adUnits, function () { try { if (_callback != null) { const adUnitCodes = _adUnitCodes; diff --git a/test/spec/modules/realTimeModule_spec.js b/test/spec/modules/realTimeModule_spec.js index 6f54df01c51..ae83e83e10f 100644 --- a/test/spec/modules/realTimeModule_spec.js +++ b/test/spec/modules/realTimeModule_spec.js @@ -178,10 +178,10 @@ describe('Real time module', function() { expect(script.async).to.equal(true); const slots = createSlots(); - const test1 = isIdMatchingAdUnit('browsiAd_1', slots, ['/57778053/Browsi_Demo_300x250']); // true - const test2 = isIdMatchingAdUnit('browsiAd_1', slots, ['/57778053/Browsi_Demo_300x250', '/57778053/Browsi']); // true - const test3 = isIdMatchingAdUnit('browsiAd_1', slots, ['/57778053/Browsi_Demo_Low']); // false - const test4 = isIdMatchingAdUnit('browsiAd_1', slots, []); // true + const test1 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_300x250']); // true + const test2 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_300x250', '/57778053/Browsi']); // true + const test3 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_Low']); // false + const test4 = isIdMatchingAdUnit('browsiAd_1', slots[0], []); // true expect(test1).to.equal(true); expect(test2).to.equal(true); From 41fb95fedf5517f88637228efe54773886a8d91c Mon Sep 17 00:00:00 2001 From: redaguermas Date: Wed, 12 Feb 2020 09:02:08 -0800 Subject: [PATCH 047/496] Support for user block from the Adapter (#4779) * Support for user block from the Adapter * Added Unit tests and using utils.getCookie and utils.setCookie() * Dummy change to triger CI * Dummy change * Support for pixel sync urls --- modules/nobidBidAdapter.js | 37 +++++++++++++-- test/spec/modules/nobidBidAdapter_spec.js | 55 ++++++++++++++++++++++- 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index 6f04c194bee..63c54b998c4 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -2,7 +2,7 @@ import * as utils from '../src/utils'; import { registerBidder } from '../src/adapters/bidderFactory'; import { BANNER } from '../src/mediaTypes'; const BIDDER_CODE = 'nobid'; -window.nobidVersion = '1.2.0'; +window.nobidVersion = '1.2.1'; window.nobid = window.nobid || {}; window.nobid.bidResponses = window.nobid.bidResponses || {}; window.nobid.timeoutTotal = 0; @@ -11,6 +11,15 @@ window.nobid.refreshCount = 0; function log(msg, obj) { utils.logInfo('-NoBid- ' + msg, obj) } +function nobidSetCookie(cname, cvalue, hours) { + var d = new Date(); + d.setTime(d.getTime() + (hours * 60 * 60 * 1000)); + var expires = 'expires=' + d.toUTCString(); + utils.setCookie(cname, cvalue, expires); +} +function nobidGetCookie(cname) { + return utils.getCookie(cname); +} function nobidBuildRequests(bids, bidderRequest) { var serializeState = function(divIds, siteId, adunits) { var filterAdUnitsByIds = function(divIds, adUnits) { @@ -146,6 +155,11 @@ function nobidBuildRequests(bids, bidderRequest) { if (typeof window.nobid.refreshLimit !== 'undefined') { if (window.nobid.refreshLimit < window.nobid.refreshCount) return false; } + let ublock = nobidGetCookie('_ublock'); + if (ublock) { + log('Request blocked for user. hours: ', ublock); + return false; + } /* DISCOVER SLOTS */ var divids = []; var siteId = 0; @@ -180,7 +194,13 @@ function nobidInterpretResponse(response, bidRequest) { var setRefreshLimit = function(response) { if (response && typeof response.rlimit !== 'undefined') window.nobid.refreshLimit = response.rlimit; } + var setUserBlock = function(response) { + if (response && typeof response.ublock !== 'undefined') { + nobidSetCookie('_ublock', '1', response.ublock); + } + } setRefreshLimit(response); + setUserBlock(response); var bidResponses = []; for (var i = 0; response.bids && i < response.bids.length; i++) { var bid = response.bids[i]; @@ -273,8 +293,8 @@ export const spec = { * @return {Bid[]} An array of bids which were nested inside the server. */ interpretResponse: function(serverResponse, bidRequest) { - log('interpretResponse', serverResponse); - log('interpretResponse', bidRequest); + log('interpretResponse -> serverResponse', serverResponse); + log('interpretResponse -> bidRequest', bidRequest); return nobidInterpretResponse(serverResponse.body, bidRequest); }, @@ -305,6 +325,17 @@ export const spec = { type: 'iframe', url: 'https://public.servenobid.com/sync.html' + params }]; + } else if (syncOptions.pixelEnabled && serverResponses.length > 0) { + let syncs = []; + if (serverResponses[0].body.syncs && serverResponses[0].body.syncs.length > 0) { + serverResponses[0].body.syncs.forEach(element => { + syncs.push({ + type: 'image', + url: element + }); + }) + } + return syncs; } else { utils.logWarn('-NoBid- Please enable iframe based user sync.', syncOptions); return []; diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js index fef2fefdfc4..f86ec0ce22e 100644 --- a/test/spec/modules/nobidBidAdapter_spec.js +++ b/test/spec/modules/nobidBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; +import * as utils from 'src/utils'; import { spec } from 'modules/nobidBidAdapter'; import { newBidder } from 'src/adapters/bidderFactory'; -import { deepClone } from 'src/utils'; describe('Nobid Adapter', function () { const adapter = newBidder(spec); @@ -281,6 +281,59 @@ describe('Nobid Adapter', function () { }); }); + describe('interpretResponseWithUserLimit', function () { + const CREATIVE_ID_300x250 = 'CREATIVE-100'; + const ADUNIT_300x250 = 'ADUNIT-1'; + const ADMARKUP_300x250 = 'ADMARKUP-300x250'; + const PRICE_300x250 = 0.51; + const REQUEST_ID = '3db3773286ee59'; + const DEAL_ID = 'deal123'; + const ULIMIT = 1; + let response = { + country: 'US', + ip: '68.83.15.75', + device: 'COMPUTER', + site: 2, + ublock: ULIMIT, + bids: [ + {id: 1, + bdrid: 101, + divid: ADUNIT_300x250, + dealid: DEAL_ID, + creativeid: CREATIVE_ID_300x250, + size: {'w': 300, 'h': 250}, + adm: ADMARKUP_300x250, + price: '' + PRICE_300x250 + } + ] + }; + + it('should ULimit be respected', function () { + const bidderRequest = { + bids: [{ + bidId: REQUEST_ID, + adUnitCode: ADUNIT_300x250 + }] + } + const bidRequests = [ + { + 'bidder': 'nobid', + 'params': { + 'siteId': 2 + }, + 'adUnitCode': 'adunit-code', + 'sizes': [[300, 250]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + } + ]; + spec.interpretResponse({ body: response }, {bidderRequest: bidderRequest}); + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request).to.equal(undefined); + }); + }); + describe('getUserSyncs', function () { const GDPR_CONSENT_STRING = 'GDPR_CONSENT_STRING'; it('should get correct user sync when iframeEnabled', function () { From 0d823da1572826b08750882a7d4761e9b4fc7413 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Wed, 12 Feb 2020 17:16:51 -0500 Subject: [PATCH 048/496] Prebid 3.7.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8eac6d9f8be..d9e4505930d 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.7.0-pre", + "version": "3.7.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 7b9b5e2a50cd192ba1d128022bd771f822c75037 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Wed, 12 Feb 2020 17:27:11 -0500 Subject: [PATCH 049/496] Increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d9e4505930d..3b7307bc581 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.7.0", + "version": "3.8.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 835348baeb9773f1aaeeb01727a91aa03a66a640 Mon Sep 17 00:00:00 2001 From: Wesley Whitney Date: Thu, 13 Feb 2020 08:33:42 -0700 Subject: [PATCH 050/496] Updated Maintainer email (#4853) Updated email for current maintainer contact at sovrn jrosendahl@sovrn.com. --- modules/sovrnBidAdapter.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/sovrnBidAdapter.md b/modules/sovrnBidAdapter.md index 3b189016a9f..2b5d21d5515 100644 --- a/modules/sovrnBidAdapter.md +++ b/modules/sovrnBidAdapter.md @@ -3,7 +3,7 @@ ``` Module Name: Sovrn Bid Adapter Module Type: Bidder Adapter -Maintainer: trand@sovrn.com +Maintainer: jrosendahl@sovrn.com ``` # Description @@ -44,4 +44,4 @@ var adUnits = [ }] } ] -``` \ No newline at end of file +``` From ec6faef7e2964c74e77800bf034a77050c643bff Mon Sep 17 00:00:00 2001 From: SeedingAllianceTech <55976067+SeedingAllianceTech@users.noreply.github.com> Date: Thu, 13 Feb 2020 17:19:22 +0100 Subject: [PATCH 051/496] Add two more default native params to seedingalliance adapter (#4841) * add seedingAlliance Adapter * add two native default params * ... * ... * seedingAlliance Adapter: add two more default native params --- modules/seedingAllianceBidAdapter.js | 14 +++++++++++++- test/spec/modules/seedingAllianceAdapter_spec.js | 8 ++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/modules/seedingAllianceBidAdapter.js b/modules/seedingAllianceBidAdapter.js index e118849e666..54f161287bd 100755 --- a/modules/seedingAllianceBidAdapter.js +++ b/modules/seedingAllianceBidAdapter.js @@ -10,7 +10,7 @@ const BIDDER_CODE = 'seedingAlliance'; const DEFAULT_CUR = 'EUR'; const ENDPOINT_URL = 'https://b.nativendo.de/cds/rtb/bid?format=openrtb2.5&ssp=nativendo'; -const NATIVE_ASSET_IDS = {0: 'title', 1: 'body', 2: 'sponsoredBy', 3: 'image'}; +const NATIVE_ASSET_IDS = {0: 'title', 1: 'body', 2: 'sponsoredBy', 3: 'image', 4: 'cta', 5: 'icon'}; const NATIVE_PARAMS = { title: { @@ -34,6 +34,18 @@ const NATIVE_PARAMS = { id: 3, type: 3, name: 'img' + }, + + cta: { + id: 4, + type: 12, + name: 'data' + }, + + icon: { + id: 5, + type: 1, + name: 'img' } }; diff --git a/test/spec/modules/seedingAllianceAdapter_spec.js b/test/spec/modules/seedingAllianceAdapter_spec.js index e7915bc2d22..f4c833b41a8 100755 --- a/test/spec/modules/seedingAllianceAdapter_spec.js +++ b/test/spec/modules/seedingAllianceAdapter_spec.js @@ -88,6 +88,12 @@ describe('SeedingAlliance adapter', function () { }, sponsoredBy: { required: true + }, + cta: { + required: true + }, + icon: { + required: true } } }]; @@ -98,6 +104,8 @@ describe('SeedingAlliance adapter', function () { assert.equal(assets[1].id, 3); assert.equal(assets[2].id, 0); assert.equal(assets[3].id, 2); + assert.equal(assets[4].id, 4); + assert.equal(assets[5].id, 5); }); }); From c38dca4cf18a36ba8e26007c57c7bf1ec70bdb03 Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Thu, 13 Feb 2020 13:24:37 -0500 Subject: [PATCH 052/496] Revert "implements the todo comment in the code (#4821)" (#4861) This reverts commit 469ec57c2fb91d74bbc058446d753ae8709b1b19. --- src/prebid.js | 4 +++- test/spec/unit/pbjs_api_spec.js | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/prebid.js b/src/prebid.js index 004f0fa29dd..f1ead426496 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -93,6 +93,8 @@ export const checkAdUnitSetup = hook('sync', function (adUnits) { const bannerSizes = validateSizes(mediaTypes.banner.sizes); if (bannerSizes.length > 0) { mediaTypes.banner.sizes = bannerSizes; + // TODO eventually remove this internal copy once we're ready to deprecate bidders from reading this adUnit.sizes property + adUnit.sizes = bannerSizes; } else { utils.logError('Detected a mediaTypes.banner object without a proper sizes field. Please ensure the sizes are listed like: [[300, 250], ...]. Removing invalid mediaTypes.banner object from request.'); delete adUnit.mediaTypes.banner; @@ -105,7 +107,7 @@ export const checkAdUnitSetup = hook('sync', function (adUnits) { let tarPlayerSizeLen = (typeof video.playerSize[0] === 'number') ? 2 : 1; const videoSizes = validateSizes(video.playerSize, tarPlayerSizeLen); if (videoSizes.length > 0) { - video.playerSize = videoSizes; + adUnit.sizes = video.playerSize = videoSizes; } else { utils.logError('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.'); delete adUnit.mediaTypes.video.playerSize; diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index e70956a3eed..6d98830ac42 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -1513,6 +1513,7 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: fullAdUnit }); + expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[640, 480]]); expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.deep.equal([[640, 480]]); expect(auctionArgs.adUnits[0].mediaTypes.native.image.sizes).to.deep.equal([150, 150]); expect(auctionArgs.adUnits[0].mediaTypes.native.icon.sizes).to.deep.equal([75, 75]); @@ -1542,6 +1543,7 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: noOptnlFieldAdUnit }); + expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[300, 250]]); expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; let mixedAdUnit = [{ @@ -1564,6 +1566,7 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: mixedAdUnit }); + expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[400, 350]]); expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; let altVideoPlayerSize = [{ @@ -1579,6 +1582,7 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: altVideoPlayerSize }); + expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[640, 480]]); expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.deep.equal([[640, 480]]); expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; }); @@ -1597,6 +1601,7 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: normalizeAdUnit }); + expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[300, 250]]); expect(auctionArgs.adUnits[0].mediaTypes.banner.sizes).to.deep.equal([[300, 250]]); }); }); @@ -1616,6 +1621,7 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: badBanner }); + expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[300, 250], [300, 600]]); expect(auctionArgs.adUnits[0].mediaTypes.banner).to.be.undefined; assert.ok(logErrorSpy.calledWith('Detected a mediaTypes.banner object without a proper sizes field. Please ensure the sizes are listed like: [[300, 250], ...]. Removing invalid mediaTypes.banner object from request.')); @@ -1632,6 +1638,7 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: badVideo1 }); + expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[600, 600]]); expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.be.undefined; expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; assert.ok(logErrorSpy.calledWith('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.')); @@ -1649,6 +1656,7 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.requestBids({ adUnits: badVideo2 }); + expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[600, 600]]); expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.be.undefined; expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; assert.ok(logErrorSpy.calledWith('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.')); From 0c041fbdff7c8987b6c2a75b70878f1b7a4be4dd Mon Sep 17 00:00:00 2001 From: Jason Snellbaker Date: Thu, 13 Feb 2020 13:44:09 -0500 Subject: [PATCH 053/496] Prebid 3.7.1 release --- package-lock.json | 34370 ++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 17374 insertions(+), 16998 deletions(-) mode change 100755 => 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json old mode 100755 new mode 100644 index d0400d54ff7..3e205ff2e30 --- a/package-lock.json +++ b/package-lock.json @@ -1,17277 +1,17653 @@ { - "name": "prebid.js", - "version": "3.1.0-pre", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/core": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.5.tgz", - "integrity": "sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.5", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "name": "prebid.js", + "version": "3.7.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/compat-data": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.5.tgz", + "integrity": "sha512-jWYUqQX/ObOhG1UiEkbH5SANsE/8oKXiQWjj7p7xgj9Zmnt//aUvyz4dBkK0HNsS8/cbyC5NmmH87VekW+mXFg==", + "dev": true, + "requires": { + "browserslist": "^4.8.5", + "invariant": "^2.2.4", + "semver": "^5.5.0" + } + }, + "@babel/core": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz", + "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.4", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } - }, - "@babel/generator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", - "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", + "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", + "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-call-delegate": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.3.tgz", + "integrity": "sha512-6Q05px0Eb+N4/GTyKPPvnkig7Lylw+QzihMpws9iiZQv7ZImf84ZsZpQH7QoWN4n4tm81SnSzPgHw2qtO0Zf3A==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.4.tgz", + "integrity": "sha512-3k3BsKMvPp5bjxgMdrFyq0UaEO48HciVrOVF0+lon8pp95cyJ2ujAh0TrBHNMnJGT2rr0iKOJPFFbSqjDyf/Pg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.8.4", + "browserslist": "^4.8.5", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.3.tgz", + "integrity": "sha512-Gcsm1OHCUr9o9TcJln57xhWHtdXbA2pgQ58S0Lxlks0WMGNXuki4+GLfX0p+L2ZkINUGZvfkz8rzoqJQSthI+Q==", + "dev": true, + "requires": { + "@babel/helper-regex": "^7.8.3", + "regexpu-core": "^4.6.0" + } + }, + "@babel/helper-define-map": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", + "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/types": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", + "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", + "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-transforms": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.3.tgz", + "integrity": "sha512-C7NG6B7vfBa/pwCOshpMbOYUmrYQDfCpVL/JCRu0ek8B5p8kue1+BCXpg2vOYs7w5ACB9GTOBYQ5U6NwrMg+3Q==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", + "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "dev": true, + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", + "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-wrap-function": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-replace-supers": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz", + "integrity": "sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-wrap-function": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", + "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helpers": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", + "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", + "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", + "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz", + "integrity": "sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.3.tgz", + "integrity": "sha512-1/1/rEZv2XGweRwwSkLpY+s60za9OZ1hJs4YDqFHCw0kYWYwL5IFljVY1MYBL+weT1l9pokDO2uhSTLVxzoHkQ==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", + "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", + "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", + "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", + "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", + "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.3.tgz", + "integrity": "sha512-SjT0cwFJ+7Rbr1vQsvphAHwUHvSUPmMjMU/0P59G8U2HLFqSa082JO7zkbDNWs9kH/IUqpHI6xWNesGf8haF1w==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-define-map": "^7.8.3", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", + "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.3.tgz", + "integrity": "sha512-H4X646nCkiEcHZUZaRkhE2XVsoz0J/1x3VVujnn96pSoGCtKPA99ZZA+va+gK+92Zycd6OBKCD8tDb/731bhgQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", + "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", + "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", + "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.4.tgz", + "integrity": "sha512-iAXNlOWvcYUYoV8YIxwS7TxGRJcxyl8eQCfT+A5j8sKUzRFvJdcyjp97jL2IghWSRDaL2PU2O2tX8Cu9dTBq5A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", + "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", + "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", + "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz", + "integrity": "sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz", + "integrity": "sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-simple-access": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz", + "integrity": "sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz", + "integrity": "sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", + "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", + "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", + "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.4.tgz", + "integrity": "sha512-IsS3oTxeTsZlE5KqzTbcC2sV0P9pXdec53SU+Yxv7o/6dvGM5AkTotQKhoSffhNgZ/dftsSiOoxy7evCYJXzVA==", + "dev": true, + "requires": { + "@babel/helper-call-delegate": "^7.8.3", + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", + "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.3.tgz", + "integrity": "sha512-qt/kcur/FxrQrzFR432FGZznkVAjiyFtCOANjkAKwCbt465L6ZCiUQh2oMYGU3Wo8LRFJxNDFwWn106S5wVUNA==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.0" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", + "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", + "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", + "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", + "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-regex": "^7.8.3" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", + "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", + "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", + "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/preset-env": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.4.tgz", + "integrity": "sha512-HihCgpr45AnSOHRbS5cWNTINs0TwaR8BS8xIIH+QwiW8cKL0llV91njQMpeMReEPVs+1Ao0x3RLEBLtt1hOq4w==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.8.4", + "@babel/helper-compilation-targets": "^7.8.4", + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-proposal-async-generator-functions": "^7.8.3", + "@babel/plugin-proposal-dynamic-import": "^7.8.3", + "@babel/plugin-proposal-json-strings": "^7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.8.3", + "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.8.3", + "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.8.3", + "@babel/plugin-transform-async-to-generator": "^7.8.3", + "@babel/plugin-transform-block-scoped-functions": "^7.8.3", + "@babel/plugin-transform-block-scoping": "^7.8.3", + "@babel/plugin-transform-classes": "^7.8.3", + "@babel/plugin-transform-computed-properties": "^7.8.3", + "@babel/plugin-transform-destructuring": "^7.8.3", + "@babel/plugin-transform-dotall-regex": "^7.8.3", + "@babel/plugin-transform-duplicate-keys": "^7.8.3", + "@babel/plugin-transform-exponentiation-operator": "^7.8.3", + "@babel/plugin-transform-for-of": "^7.8.4", + "@babel/plugin-transform-function-name": "^7.8.3", + "@babel/plugin-transform-literals": "^7.8.3", + "@babel/plugin-transform-member-expression-literals": "^7.8.3", + "@babel/plugin-transform-modules-amd": "^7.8.3", + "@babel/plugin-transform-modules-commonjs": "^7.8.3", + "@babel/plugin-transform-modules-systemjs": "^7.8.3", + "@babel/plugin-transform-modules-umd": "^7.8.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.8.3", + "@babel/plugin-transform-object-super": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.8.4", + "@babel/plugin-transform-property-literals": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.3", + "@babel/plugin-transform-reserved-words": "^7.8.3", + "@babel/plugin-transform-shorthand-properties": "^7.8.3", + "@babel/plugin-transform-spread": "^7.8.3", + "@babel/plugin-transform-sticky-regex": "^7.8.3", + "@babel/plugin-transform-template-literals": "^7.8.3", + "@babel/plugin-transform-typeof-symbol": "^7.8.4", + "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/types": "^7.8.3", + "browserslist": "^4.8.5", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.7.4.tgz", - "integrity": "sha512-2BQmQgECKzYKFPpiycoF9tlb5HA4lrVyAmLLVK177EcQAqjVLciUb2/R+n1boQ9y5ENV3uz2ZqiNw7QMBBw1Og==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@gulp-sourcemaps/identity-map": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz", + "integrity": "sha512-ciiioYMLdo16ShmfHBXJBOFm3xPC4AuwO4xeRpFeHz7WK9PYsWCmigagG2XyzZpubK4a3qNKoUBDhbzHfa50LQ==", + "dev": true, + "requires": { + "acorn": "^5.0.3", + "css": "^2.2.1", + "normalize-path": "^2.1.1", + "source-map": "^0.6.0", + "through2": "^2.0.3" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.7.4.tgz", - "integrity": "sha512-Biq/d/WtvfftWZ9Uf39hbPBYDUo986m5Bb4zhkeYDGUllF43D+nUe5M6Vuo6/8JDK/0YX/uBdeoQpyaNhNugZQ==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.7.4", - "@babel/types": "^7.7.4" + } + }, + "@gulp-sourcemaps/map-sources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", + "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", + "dev": true, + "requires": { + "normalize-path": "^2.0.1", + "through2": "^2.0.3" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } } - }, - "@babel/helper-call-delegate": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.7.4.tgz", - "integrity": "sha512-8JH9/B7J7tCYJ2PpWVpw9JhPuEVHztagNVuQAFBVFYluRMlpG7F1CgKEgGeL6KFqcsIa92ZYVj6DSc0XwmN1ZA==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" + } + }, + "@jest/console": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", + "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", + "dev": true, + "requires": { + "@jest/source-map": "^24.9.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + }, + "dependencies": { + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.7.4.tgz", - "integrity": "sha512-Mt+jBKaxL0zfOIWrfQpnfYCN7/rS6GKx6CCCfuoqVVd+17R8zNDlzVYmIi9qyb2wOk002NsmSTDymkIygDUH7A==", - "dev": true, - "requires": { - "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.6.0" + } + }, + "@jest/core": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz", + "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/reporters": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-changed-files": "^24.9.0", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-resolve-dependencies": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "jest-watcher": "^24.9.0", + "micromatch": "^3.1.10", + "p-each-series": "^1.0.0", + "realpath-native": "^1.1.0", + "rimraf": "^2.5.4", + "slash": "^2.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } } - }, - "@babel/helper-define-map": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.7.4.tgz", - "integrity": "sha512-v5LorqOa0nVQUvAUTUF3KPastvUt/HzByXNamKQ6RdJRTV7j8rLL+WB5C/MzzWAwOomxDhYFb1wLLxHqox86lg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.7.4", - "@babel/types": "^7.7.4", - "lodash": "^4.17.13" + } + }, + "@jest/environment": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", + "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", + "dev": true, + "requires": { + "@jest/fake-timers": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0" + } + }, + "@jest/fake-timers": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", + "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0" + } + }, + "@jest/reporters": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", + "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "istanbul-lib-coverage": "^2.0.2", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.1", + "istanbul-reports": "^2.2.6", + "jest-haste-map": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.6.0", + "node-notifier": "^5.4.2", + "slash": "^2.0.0", + "source-map": "^0.6.0", + "string-length": "^2.0.0" + }, + "dependencies": { + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.7.4.tgz", - "integrity": "sha512-2/SicuFrNSXsZNBxe5UGdLr+HZg+raWBLE9vC98bdYOKX/U6PY0mdGlYUJdtTDPSU0Lw0PNbKKDpwYHJLn2jLg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" + } + }, + "@jest/source-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", + "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.1.15", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "@babel/helper-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", - "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" + } + }, + "@jest/test-result": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", + "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", + "dev": true, + "requires": { + "@jest/console": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/test-sequencer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", + "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "dev": true, + "requires": { + "@jest/test-result": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0" + } + }, + "@jest/transform": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", + "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.9.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.9.0", + "jest-regex-util": "^24.9.0", + "jest-util": "^24.9.0", + "micromatch": "^3.1.10", + "pirates": "^4.0.1", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + }, + "dependencies": { + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", - "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" + } + }, + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } + }, + "@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "dev": true + }, + "@sinonjs/commons": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.0.tgz", + "integrity": "sha512-qbk9AP+cZUsKdW1GJsBpxPKFmCJ0T8swwzVje3qFd+AkQb74Q/tiuzrdfFg8AD2g5HH/XbE/I8Uc1KYHVYWfhg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, + "@sinonjs/samsam": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", + "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "array-from": "^2.1.1", + "lodash": "^4.17.15" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@types/babel__core": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", + "integrity": "sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.8.tgz", + "integrity": "sha512-yGeB2dHEdvxjP0y4UbRtQaSkXJ9649fYCmIdRoul5kfAoGCwxuCbMhag0k3RPfnuh9kPGm8x89btcfDEXdVWGw==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", + "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/yargs": { + "version": "13.0.8", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", + "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "dev": true, + "requires": { + "acorn": "^4.0.3" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true } - }, - "@babel/helper-hoist-variables": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.7.4.tgz", - "integrity": "sha512-wQC4xyvc1Jo/FnLirL6CEgPgPCa8M74tOdjWpRhQYapz5JC7u3NYU1zCVoVAGCE3EaIP9T1A3iW0WLJ+reZlpQ==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" + } + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", + "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", + "dev": true } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.7.4.tgz", - "integrity": "sha512-9KcA1X2E3OjXl/ykfMMInBK+uVdfIVakVe7W7Lg3wfXUNyS3Q1HWLFRwZIjhqiCGbslummPDnmb7vIekS0C1vw==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" + } + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true } - }, - "@babel/helper-module-imports": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz", - "integrity": "sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } - }, - "@babel/helper-module-transforms": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz", - "integrity": "sha512-A7pSxyJf1gN5qXVcidwLWydjftUN878VkalhXX5iQDuGyiGK3sOrrKKHF4/A4fwHtnsotv/NipwAeLzY4KQPvw==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.7.4", - "@babel/helper-simple-access": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4", - "lodash": "^4.17.13" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "dev": true, + "requires": { + "ansi-wrap": "^0.1.0" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz", - "integrity": "sha512-VB7gWZ2fDkSuqW6b1AKXkJWO5NyNI3bFL/kK79/30moK57blr6NbH8xcl2XcKCwOmJosftWunZqfO84IGq3ZZg==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" + } + }, + "append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, + "requires": { + "buffer-equal": "^1.0.0" + } + }, + "append-transform": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "dev": true, + "requires": { + "default-require-extensions": "^1.0.0" + } + }, + "archiver": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-2.1.1.tgz", + "integrity": "sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw=", + "dev": true, + "requires": { + "archiver-utils": "^1.3.0", + "async": "^2.0.0", + "buffer-crc32": "^0.2.1", + "glob": "^7.0.0", + "lodash": "^4.8.0", + "readable-stream": "^2.0.0", + "tar-stream": "^1.5.0", + "zip-stream": "^1.2.0" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } } - }, - "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" - }, - "@babel/helper-regex": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", - "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", - "dev": true, - "requires": { - "lodash": "^4.17.13" + } + }, + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "graceful-fs": "^4.1.0", + "lazystream": "^1.0.0", + "lodash": "^4.8.0", + "normalize-path": "^2.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } } - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.7.4.tgz", - "integrity": "sha512-Sk4xmtVdM9sA/jCI80f+KS+Md+ZHIpjuqmYPk1M7F/upHou5e4ReYmExAiu6PVe65BhJPZA2CY9x9k4BqE5klw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.7.4", - "@babel/helper-wrap-function": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-filter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", + "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", + "dev": true, + "requires": { + "make-iterator": "^1.0.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", + "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", + "dev": true, + "requires": { + "make-iterator": "^1.0.0" + } + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "dev": true + }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, + "array-initial": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", + "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", + "dev": true, + "requires": { + "array-slice": "^1.0.0", + "is-number": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true } - }, - "@babel/helper-replace-supers": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.7.4.tgz", - "integrity": "sha512-pP0tfgg9hsZWo5ZboYGuBn/bbYT/hdLPVSS4NMmiRJdwWhP0IznPwN9AE1JwyGsjSPLC364I0Qh5p+EPkGPNpg==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.7.4", - "@babel/helper-optimise-call-expression": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" + } + }, + "array-last": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", + "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", + "dev": true, + "requires": { + "is-number": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true } - }, - "@babel/helper-simple-access": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.7.4.tgz", - "integrity": "sha512-zK7THeEXfan7UlWsG2A6CI/L9jVnI5+xxKZOdej39Y0YtDYKx9raHk5F2EtK9K8DHRTihYwg20ADt9S36GR78A==", - "dev": true, - "requires": { - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" + } + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, + "array-sort": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", + "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", + "dev": true, + "requires": { + "default-compare": "^1.0.0", + "get-value": "^2.0.6", + "kind-of": "^5.0.2" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", - "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } } - }, - "@babel/helper-wrap-function": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.7.4.tgz", - "integrity": "sha512-VsfzZt6wmsocOaVU0OokwrIytHND55yvyT4BPB9AIIgwr8+x7617hetdJTsuGwygN5RC6mxA9EJztTjuwm2ofg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-done": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", + "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.2", + "process-nextick-args": "^2.0.0", + "stream-exhaust": "^1.0.1" + } + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "async-settle": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", + "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", + "dev": true, + "requires": { + "async-done": "^1.2.2" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true } - }, - "@babel/helpers": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.4.tgz", - "integrity": "sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg==", - "dev": true, - "requires": { - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" + } + }, + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true } - }, - "@babel/parser": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz", - "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.7.4.tgz", - "integrity": "sha512-1ypyZvGRXriY/QP668+s8sFr2mqinhkRDMPSQLNghCQE+GAkFtp+wkHVvg2+Hdki8gwP+NFzJBJ/N1BfzCCDEw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.7.4", - "@babel/plugin-syntax-async-generators": "^7.7.4" + } + }, + "babel-helper-bindify-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", + "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-builder-react-jsx": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", + "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "esutils": "^2.0.2" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-explode-class": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", + "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", + "dev": true, + "requires": { + "babel-helper-bindify-decorators": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", + "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", + "dev": true, + "requires": { + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.9.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" + }, + "dependencies": { + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.7.4.tgz", - "integrity": "sha512-StH+nGAdO6qDB1l8sZ5UBV8AC3F2VW2I8Vfld73TMKyptMU9DY5YsJAS8U81+vEtxcH3Y/La0wG0btDrhpnhjQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-dynamic-import": "^7.7.4" + } + }, + "babel-loader": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", + "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==", + "dev": true, + "requires": { + "find-cache-dir": "^2.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1", + "pify": "^4.0.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-istanbul": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", + "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "find-up": "^3.0.0", + "istanbul-lib-instrument": "^3.3.0", + "test-exclude": "^5.2.3" + } + }, + "babel-plugin-jest-hoist": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", + "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "dev": true, + "requires": { + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-async-generators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", + "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", + "dev": true + }, + "babel-plugin-syntax-class-constructor-call": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", + "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=", + "dev": true + }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", + "dev": true + }, + "babel-plugin-syntax-decorators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", + "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", + "dev": true + }, + "babel-plugin-syntax-do-expressions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", + "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=", + "dev": true + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-export-extensions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", + "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=", + "dev": true + }, + "babel-plugin-syntax-flow": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", + "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", + "dev": true + }, + "babel-plugin-syntax-function-bind": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", + "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=", + "dev": true + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", + "dev": true + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-system-import-transformer": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-system-import-transformer/-/babel-plugin-system-import-transformer-3.1.0.tgz", + "integrity": "sha1-038Mro5h7zkGAggzHZMbXmMNfF8=", + "dev": true, + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0" + } + }, + "babel-plugin-transform-async-generator-functions": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", + "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-generators": "^6.5.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-class-constructor-call": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz", + "integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=", + "dev": true, + "requires": { + "babel-plugin-syntax-class-constructor-call": "^6.18.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", + "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", + "dev": true, + "requires": { + "babel-helper-explode-class": "^6.24.1", + "babel-plugin-syntax-decorators": "^6.13.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-decorators-legacy": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.5.tgz", + "integrity": "sha512-jYHwjzRXRelYQ1uGm353zNzf3QmtdCfvJbuYTZ4gKveK7M9H1fs3a5AKdY1JUDl0z97E30ukORW1dzhWvsabtA==", + "dev": true, + "requires": { + "babel-plugin-syntax-decorators": "^6.1.18", + "babel-runtime": "^6.2.0", + "babel-template": "^6.3.0" + } + }, + "babel-plugin-transform-do-expressions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz", + "integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=", + "dev": true, + "requires": { + "babel-plugin-syntax-do-expressions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.7.4.tgz", - "integrity": "sha512-wQvt3akcBTfLU/wYoqm/ws7YOAQKu8EVJEvHip/mzkNtjaclQoCCIqKXFP5/eyfnfbQCDV3OLRIK3mIVyXuZlw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-json-strings": "^7.7.4" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-export-extensions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", + "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=", + "dev": true, + "requires": { + "babel-plugin-syntax-export-extensions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-flow-strip-types": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", + "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", + "dev": true, + "requires": { + "babel-plugin-syntax-flow": "^6.18.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-function-bind": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", + "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=", + "dev": true, + "requires": { + "babel-plugin-syntax-function-bind": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-object-assign": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-assign/-/babel-plugin-transform-object-assign-6.22.0.tgz", + "integrity": "sha1-+Z0vZvGgsNSY40bFNZaEdAyqILo=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-react-display-name": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", + "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", + "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", + "dev": true, + "requires": { + "babel-helper-builder-react-jsx": "^6.24.1", + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx-self": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", + "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx-source": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", + "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "requires": { + "regenerator-transform": "^0.10.0" + }, + "dependencies": { + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz", - "integrity": "sha512-rnpnZR3/iWKmiQyJ3LKJpSwLDcX/nSXhdLk4Aq/tXOApIvyu7qoabrige0ylsAJffaUC51WiBu209Q0U+86OWQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.7.4" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-preset-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + }, + "dependencies": { + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.7.4.tgz", - "integrity": "sha512-DyM7U2bnsQerCQ+sejcTNZh8KQEUuC3ufzdnVnSiUv/qoGJp2Z3hanKL18KDhsBT5Wj6a7CMT5mdyCNJsEaA9w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.7.4" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.4.tgz", - "integrity": "sha512-cHgqHgYvffluZk85dJ02vloErm3Y6xtH+2noOBOJ2kXOJH3aVCDnj5eR/lVNlTnYu4hndAPJD3rTFjW3qee0PA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.7.4.tgz", - "integrity": "sha512-Li4+EjSpBgxcsmeEF8IFcfV/+yJGxHXDirDkEoyFjumuwbmfCVHUt0HuowD/iGM7OhIRyXJH9YXxqiH6N815+g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.7.4.tgz", - "integrity": "sha512-jHQW0vbRGvwQNgyVxwDh4yuXu4bH1f5/EICJLAhl1SblLs2CDhrsmCk+v5XLdE9wxtAFRyxx+P//Iw+a5L/tTg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.7.4.tgz", - "integrity": "sha512-QpGupahTQW1mHRXddMG5srgpHWqRLwJnJZKXTigB9RPFCCGbDGCgBeM/iC82ICXp414WeYx/tD54w7M2qRqTMg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz", - "integrity": "sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.7.4.tgz", - "integrity": "sha512-4ZSuzWgFxqHRE31Glu+fEr/MirNZOMYmD/0BhBWyLyOOQz/gTAl7QmWm2hX1QxEIXsr2vkdlwxIzTyiYRC4xcQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.4.tgz", - "integrity": "sha512-wdsOw0MvkL1UIgiQ/IFr3ETcfv1xb8RMM0H9wbiDyLaJFyiDg5oZvDLCXosIXmFeIlweML5iOBXAkqddkYNizg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.7.4.tgz", - "integrity": "sha512-zUXy3e8jBNPiffmqkHRNDdZM2r8DWhCB7HhcoyZjiK1TxYEluLHAvQuYnTT+ARqRpabWqy/NHkO6e3MsYB5YfA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.7.4.tgz", - "integrity": "sha512-zpUTZphp5nHokuy8yLlyafxCJ0rSlFoSHypTUWgpdwoDXWQcseaect7cJ8Ppk6nunOM6+5rPMkod4OYKPR5MUg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-remap-async-to-generator": "^7.7.4" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.7.4.tgz", - "integrity": "sha512-kqtQzwtKcpPclHYjLK//3lH8OFsCDuDJBaFhVwf8kqdnF6MN4l618UDlcA7TfRs3FayrHj+svYnSX8MC9zmUyQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.7.4.tgz", - "integrity": "sha512-2VBe9u0G+fDt9B5OV5DQH4KBf5DoiNkwFKOz0TCvBWvdAN2rOykCTkrL+jTLxfCAm76l9Qo5OqL7HBOx2dWggg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "lodash": "^4.17.13" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.7.4.tgz", - "integrity": "sha512-sK1mjWat7K+buWRuImEzjNf68qrKcrddtpQo3swi9j7dUcG6y6R6+Di039QN2bD1dykeswlagupEmpOatFHHUg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.7.4", - "@babel/helper-define-map": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-optimise-call-expression": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.7.4.tgz", - "integrity": "sha512-bSNsOsZnlpLLyQew35rl4Fma3yKWqK3ImWMSC/Nc+6nGjC9s5NFWAer1YQ899/6s9HxO2zQC1WoFNfkOqRkqRQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.7.4.tgz", - "integrity": "sha512-4jFMXI1Cu2aXbcXXl8Lr6YubCn6Oc7k9lLsu8v61TZh+1jny2BWmdtvY9zSUlLdGUvcy9DMAWyZEOqjsbeg/wA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.4.tgz", - "integrity": "sha512-mk0cH1zyMa/XHeb6LOTXTbG7uIJ8Rrjlzu91pUx/KS3JpcgaTDwMS8kM+ar8SLOvlL2Lofi4CGBAjCo3a2x+lw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.7.4.tgz", - "integrity": "sha512-g1y4/G6xGWMD85Tlft5XedGaZBCIVN+/P0bs6eabmcPP9egFleMAo65OOjlhcz1njpwagyY3t0nsQC9oTFegJA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.7.4.tgz", - "integrity": "sha512-MCqiLfCKm6KEA1dglf6Uqq1ElDIZwFuzz1WH5mTf8k2uQSxEJMbOIEh7IZv7uichr7PMfi5YVSrr1vz+ipp7AQ==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.7.4.tgz", - "integrity": "sha512-zZ1fD1B8keYtEcKF+M1TROfeHTKnijcVQm0yO/Yu1f7qoDoxEIc/+GX6Go430Bg84eM/xwPFp0+h4EbZg7epAA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.7.4.tgz", - "integrity": "sha512-E/x09TvjHNhsULs2IusN+aJNRV5zKwxu1cpirZyRPw+FyyIKEHPXTsadj48bVpc1R5Qq1B5ZkzumuFLytnbT6g==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "babel-preset-flow": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", + "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", + "dev": true, + "requires": { + "babel-plugin-transform-flow-strip-types": "^6.22.0" + } + }, + "babel-preset-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", + "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "dev": true, + "requires": { + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.9.0" + } + }, + "babel-preset-react": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", + "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.3.13", + "babel-plugin-transform-react-display-name": "^6.23.0", + "babel-plugin-transform-react-jsx": "^6.24.1", + "babel-plugin-transform-react-jsx-self": "^6.22.0", + "babel-plugin-transform-react-jsx-source": "^6.22.0", + "babel-preset-flow": "^6.23.0" + } + }, + "babel-preset-stage-0": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", + "integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=", + "dev": true, + "requires": { + "babel-plugin-transform-do-expressions": "^6.22.0", + "babel-plugin-transform-function-bind": "^6.22.0", + "babel-preset-stage-1": "^6.24.1" + } + }, + "babel-preset-stage-1": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", + "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=", + "dev": true, + "requires": { + "babel-plugin-transform-class-constructor-call": "^6.24.1", + "babel-plugin-transform-export-extensions": "^6.22.0", + "babel-preset-stage-2": "^6.24.1" + } + }, + "babel-preset-stage-2": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", + "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "dev": true, + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-decorators": "^6.24.1", + "babel-preset-stage-3": "^6.24.1" + } + }, + "babel-preset-stage-3": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", + "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "dev": true, + "requires": { + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-exponentiation-operator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.22.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + }, + "dependencies": { + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true } - }, - "@babel/plugin-transform-literals": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.7.4.tgz", - "integrity": "sha512-X2MSV7LfJFm4aZfxd0yLVFrEXAgPqYoDG53Br/tCKiKYfX0MjVjQeWPIhPHHsCqzwQANq+FLN786fF5rgLS+gw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.7.4.tgz", - "integrity": "sha512-9VMwMO7i69LHTesL0RdGy93JU6a+qOPuvB4F4d0kR0zyVjJRVJRaoaGjhtki6SzQUu8yen/vxPKN6CWnCUw6bA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "babelify": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-8.0.0.tgz", + "integrity": "sha512-xVr63fKEvMWUrrIbqlHYsMcc5Zdw4FSVesAHgkgajyCE1W8gbm9rbMakqavhxKvikGYMhEcqxTwB/gQmQ6lBtw==", + "dev": true + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "bach": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", + "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", + "dev": true, + "requires": { + "arr-filter": "^1.1.1", + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "array-each": "^1.0.0", + "array-initial": "^1.0.0", + "array-last": "^1.1.1", + "async-done": "^1.2.2", + "async-settle": "^1.0.0", + "now-and-later": "^2.0.0" + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.5.tgz", - "integrity": "sha512-CT57FG4A2ZUNU1v+HdvDSDrjNWBrtCmSH6YbbgN3Lrf0Di/q/lWRxZrE72p3+HCCz9UjfZOEBdphgC0nzOS6DQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.7.5", - "@babel/helper-plugin-utils": "^7.0.0", - "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "bfj": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz", + "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "check-types": "^8.0.3", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "binaryextensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.2.0.tgz", + "integrity": "sha512-bHhs98rj/7i/RZpCSJ3uk55pLXOItjIrh2sRQZSM6OoktScX+LxJzvlU+FELp9j3TdcddTmmYArLSGptCTwjuw==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "dev": true, + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", + "dev": true, + "requires": { + "continuable-cache": "^0.3.1", + "error": "^7.0.0", + "raw-body": "~1.1.0", + "safe-json-parse": "~1.0.1" + }, + "dependencies": { + "bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", + "dev": true + }, + "raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", + "dev": true, + "requires": { + "bytes": "1", + "string_decoder": "0.10" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.5.tgz", - "integrity": "sha512-9Cq4zTFExwFhQI6MT1aFxgqhIsMWQWDVwOgLzl7PTWJHsNaqFvklAU+Oz6AQLAS0dJKTwZSOCo20INwktxpi3Q==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.7.5", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-simple-access": "^7.7.4", - "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.7.4.tgz", - "integrity": "sha512-y2c96hmcsUi6LrMqvmNDPBBiGCiQu0aYqpHatVVu6kD4mFEXKjyNxd/drc18XXAf9dv7UXjrZwBVmTTGaGP8iw==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "dev": true + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.7.4.tgz", - "integrity": "sha512-u2B8TIi0qZI4j8q4C51ktfO7E3cQ0qnaXFI1/OXITordD40tt17g/sXqgNNCcMTcBFKrUPcGDx+TBJuZxLx7tw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.8.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.7.tgz", + "integrity": "sha512-gFOnZNYBHrEyUML0xr5NJ6edFaaKbTFX9S9kQHlYfCP0Rit/boRIz4G+Avq6/4haEKJXdGGUnoolx+5MWW2BoA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001027", + "electron-to-chromium": "^1.3.349", + "node-releases": "^1.1.49" + } + }, + "browserstack": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.3.tgz", + "integrity": "sha512-AO+mECXsW4QcqC9bxwM29O7qWa7bJT94uBFzeb5brylIQwawuEziwq20dPYbins95GlWzOawgyDNdjYAo32EKg==", + "dev": true, + "requires": { + "https-proxy-agent": "^2.2.1" + } + }, + "browserstack-local": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.4.5.tgz", + "integrity": "sha512-0/VdSv2YVXmcnwBb64XThMvjM1HnZJnPdv7CUgQbC5y/N9Wsr0Fu+j1oknE9fC/VPx9CpoSC6CJ0kza42skMSA==", + "dev": true, + "requires": { + "https-proxy-agent": "^4.0.0", + "is-running": "^2.1.0", + "ps-tree": "=1.2.0", + "temp-fs": "^0.9.9" + }, + "dependencies": { + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "dev": true, + "requires": { + "agent-base": "5", + "debug": "4" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.7.4.tgz", - "integrity": "sha512-jBUkiqLKvUWpv9GLSuHUFYdmHg0ujC1JEYoZUfeOOfNydZXp1sXObgyPatpcwjWgsdBGsagWW0cdJpX/DO2jMw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz", + "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", + "dev": true, + "requires": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + }, + "dependencies": { + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true + }, + "normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dev": true, + "requires": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + } + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } } - }, - "@babel/plugin-transform-new-target": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.7.4.tgz", - "integrity": "sha512-CnPRiNtOG1vRodnsyGX37bHQleHE14B9dnnlgSeEs3ek3fHN1A1SScglTCg1sfbe7sRQ2BUcpgpTpWSfMKz3gg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + }, + "dependencies": { + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true } - }, - "@babel/plugin-transform-object-super": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.7.4.tgz", - "integrity": "sha512-ho+dAEhC2aRnff2JCA0SAK7V2R62zJd/7dmtoe7MHcso4C2mS+vZjn1Pb1pCVZvJs1mgsvv5+7sT+m3Bysb6eg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.7.4" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true } - }, - "@babel/plugin-transform-parameters": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz", - "integrity": "sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw==", - "dev": true, - "requires": { - "@babel/helper-call-delegate": "^7.7.4", - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001027", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001027.tgz", + "integrity": "sha512-7xvKeErvXZFtUItTHgNtLgS9RJpVnwBlWX8jSo/BO8VsF6deszemZSkJJJA1KOKrXuzZH4WALpAJdq5EyfgMLg==", + "dev": true + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "ccount": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz", + "integrity": "sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw==", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true + }, + "character-entities-html4": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", + "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", + "dev": true + }, + "character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true + }, + "character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "check-types": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", + "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==", + "dev": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.7.4.tgz", - "integrity": "sha512-MatJhlC4iHsIskWYyawl53KuHrt+kALSADLQQ/HkhTjX954fkxIEh4q5slL4oRAnsm/eDoZ4q0CIZpcqBuxhJQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.5.tgz", - "integrity": "sha512-/8I8tPvX2FkuEyWbjRCt4qTAgZK0DVy8QRguhA524UH48RfGJy94On2ri+dCuwOpcerPRl9O4ebQkRcVzIaGBw==", - "dev": true, - "requires": { - "regenerator-transform": "^0.14.0" + } + }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "cloneable-readable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "dev": true + }, + "collection-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", + "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", + "dev": true, + "requires": { + "arr-map": "^2.0.2", + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "combine-lists": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", + "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", + "dev": true, + "requires": { + "lodash": "^4.5.0" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "compress-commons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", + "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.1", + "crc32-stream": "^2.0.0", + "normalize-path": "^2.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.7.4.tgz", - "integrity": "sha512-OrPiUB5s5XvkCO1lS7D8ZtHcswIC57j62acAnJZKqGGnHP+TIc/ljQSrgdX/QyOTdEK5COAhuc820Hi1q2UgLQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "concat-with-sourcemaps": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", + "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz", - "integrity": "sha512-q+suddWRfIcnyG5YiDP58sT65AJDZSUhXQDZE3r04AuqD6d/XLaQPPXSBzP2zGerkgBivqtQm9XKGLuHqBID6Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + } + }, + "connect-livereload": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.6.1.tgz", + "integrity": "sha512-3R0kMOdL7CjJpU66fzAkCe6HNtd3AavCS4m+uW4KtJjrdGPT0SQEZieAYd+cm+lJoBznNQ4lqipYWkhBMgk00g==", + "dev": true + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-props": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", + "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", + "dev": true, + "requires": { + "each-props": "^1.3.0", + "is-plain-object": "^2.0.1" + } + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + }, + "core-js-compat": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz", + "integrity": "sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA==", + "dev": true, + "requires": { + "browserslist": "^4.8.3", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true } - }, - "@babel/plugin-transform-spread": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.7.4.tgz", - "integrity": "sha512-8OSs0FLe5/80cndziPlg4R0K6HcWSM0zyNhHhLsmw/Nc5MaA49cAsnoJ/t/YZf8qkG7fD+UjTRaApVDB526d7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "coveralls": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.9.tgz", + "integrity": "sha512-nNBg3B1+4iDox5A5zqHKzUTiwl2ey4k2o0NEcVZYvl+GOSJdKBj4AJGKLv6h3SvWch7tABHePAQOSZWM9E2hMg==", + "dev": true, + "requires": { + "js-yaml": "^3.13.1", + "lcov-parse": "^1.0.0", + "log-driver": "^1.2.7", + "minimist": "^1.2.0", + "request": "^2.88.0" + } + }, + "crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "requires": { + "buffer": "^5.1.0" + } + }, + "crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^2.0.0" + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "criteo-direct-rsa-validate": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/criteo-direct-rsa-validate/-/criteo-direct-rsa-validate-1.1.0.tgz", + "integrity": "sha512-7gQ3zX+d+hS/vOxzLrZ4aRAceB7qNJ0VzaGNpcWjDCmtOpASB50USJDupTik/H2nHgiSAA3VNZ3SFuONs8LR9Q==" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "crypto-js": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", + "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.7.4.tgz", - "integrity": "sha512-Ls2NASyL6qtVe1H1hXts9yuEeONV2TJZmplLONkMPUG158CtmnrzW5Q5teibM5UVOFjG0D3IC5mzXR6pPpUY7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-regex": "^7.0.0" + } + }, + "css-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", + "dev": true, + "requires": { + "css": "^2.0.0" + } + }, + "css-value": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", + "integrity": "sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo=", + "dev": true + }, + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.7.4.tgz", - "integrity": "sha512-sA+KxLwF3QwGj5abMHkHgshp9+rRz+oY9uoRil4CyLtgEuE/88dpkeWgNk5qKVsJE9iSfly3nvHapdRiIS2wnQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "date-format": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz", + "integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg=", + "dev": true + }, + "dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1", + "meow": "^3.3.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "debug-fabulous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", + "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", + "dev": true, + "requires": { + "debug": "3.X", + "memoizee": "0.4.X", + "object-assign": "4.X" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.7.4.tgz", - "integrity": "sha512-KQPUQ/7mqe2m0B8VecdyaW5XcQYaePyl9R7IsKd+irzj6jvbhoGnRE+M0aNkyAzI07VfUQ9266L5xMARitV3wg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "deepmerge": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.0.1.tgz", + "integrity": "sha512-VIPwiMJqJ13ZQfaCsIFnp5Me9tnjURiaIFxfz7EH0Ci0dTSQpZtSLrqOicXqEd/z2r+z+Klk9GzmnRsgpgbOsQ==", + "dev": true + }, + "default-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", + "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", + "dev": true, + "requires": { + "kind-of": "^5.0.2" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.7.4.tgz", - "integrity": "sha512-N77UUIV+WCvE+5yHw+oks3m18/umd7y392Zv7mYTpFqHtkpcc+QUz+gLJNTWVlWROIWeLqY0f3OjZxV5TcXnRw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "default-require-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "dev": true, + "requires": { + "strip-bom": "^2.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } } - }, - "@babel/preset-env": { - "version": "7.7.6", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.7.6.tgz", - "integrity": "sha512-k5hO17iF/Q7tR9Jv8PdNBZWYW6RofxhnxKjBMc0nG4JTaWvOTiPoO/RLFwAKcA4FpmuBFm6jkoqaRJLGi0zdaQ==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-async-generator-functions": "^7.7.4", - "@babel/plugin-proposal-dynamic-import": "^7.7.4", - "@babel/plugin-proposal-json-strings": "^7.7.4", - "@babel/plugin-proposal-object-rest-spread": "^7.7.4", - "@babel/plugin-proposal-optional-catch-binding": "^7.7.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.7.4", - "@babel/plugin-syntax-async-generators": "^7.7.4", - "@babel/plugin-syntax-dynamic-import": "^7.7.4", - "@babel/plugin-syntax-json-strings": "^7.7.4", - "@babel/plugin-syntax-object-rest-spread": "^7.7.4", - "@babel/plugin-syntax-optional-catch-binding": "^7.7.4", - "@babel/plugin-syntax-top-level-await": "^7.7.4", - "@babel/plugin-transform-arrow-functions": "^7.7.4", - "@babel/plugin-transform-async-to-generator": "^7.7.4", - "@babel/plugin-transform-block-scoped-functions": "^7.7.4", - "@babel/plugin-transform-block-scoping": "^7.7.4", - "@babel/plugin-transform-classes": "^7.7.4", - "@babel/plugin-transform-computed-properties": "^7.7.4", - "@babel/plugin-transform-destructuring": "^7.7.4", - "@babel/plugin-transform-dotall-regex": "^7.7.4", - "@babel/plugin-transform-duplicate-keys": "^7.7.4", - "@babel/plugin-transform-exponentiation-operator": "^7.7.4", - "@babel/plugin-transform-for-of": "^7.7.4", - "@babel/plugin-transform-function-name": "^7.7.4", - "@babel/plugin-transform-literals": "^7.7.4", - "@babel/plugin-transform-member-expression-literals": "^7.7.4", - "@babel/plugin-transform-modules-amd": "^7.7.5", - "@babel/plugin-transform-modules-commonjs": "^7.7.5", - "@babel/plugin-transform-modules-systemjs": "^7.7.4", - "@babel/plugin-transform-modules-umd": "^7.7.4", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.7.4", - "@babel/plugin-transform-new-target": "^7.7.4", - "@babel/plugin-transform-object-super": "^7.7.4", - "@babel/plugin-transform-parameters": "^7.7.4", - "@babel/plugin-transform-property-literals": "^7.7.4", - "@babel/plugin-transform-regenerator": "^7.7.5", - "@babel/plugin-transform-reserved-words": "^7.7.4", - "@babel/plugin-transform-shorthand-properties": "^7.7.4", - "@babel/plugin-transform-spread": "^7.7.4", - "@babel/plugin-transform-sticky-regex": "^7.7.4", - "@babel/plugin-transform-template-literals": "^7.7.4", - "@babel/plugin-transform-typeof-symbol": "^7.7.4", - "@babel/plugin-transform-unicode-regex": "^7.7.4", - "@babel/types": "^7.7.4", - "browserslist": "^4.6.0", - "core-js-compat": "^3.4.7", - "invariant": "^2.2.2", - "js-levenshtein": "^1.1.3", - "semver": "^5.5.0" + } + }, + "default-resolution": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", + "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } } - }, - "@babel/template": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", - "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.3.tgz", + "integrity": "sha512-Up8P0clUVwq0FnFjDclzZsy9PadzRn5FFxrr47tQQvMHqyiFYVbpH8oXDzWtF0Q7pYy3l+RPmtBl+BsFF6wH0A==", + "dev": true, + "requires": { + "repeat-string": "^1.5.4" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true + }, + "detective": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", + "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", + "dev": true, + "requires": { + "acorn": "^5.2.1", + "defined": "^1.0.0" + } + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "dev": true + }, + "diff-sequences": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", + "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "disparity": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/disparity/-/disparity-2.0.0.tgz", + "integrity": "sha1-V92stHMkrl9Y0swNqIbbTOnutxg=", + "dev": true, + "requires": { + "ansi-styles": "^2.0.1", + "diff": "^1.3.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true } - }, - "@babel/traverse": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", - "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" + } + }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "doctrine-temporary-fork": { + "version": "2.0.0-alpha-allowarrayindex", + "resolved": "https://registry.npmjs.org/doctrine-temporary-fork/-/doctrine-temporary-fork-2.0.0-alpha-allowarrayindex.tgz", + "integrity": "sha1-QAFahn6yfnWybIKLcVJPE3+J+fA=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "documentation": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/documentation/-/documentation-5.5.0.tgz", + "integrity": "sha512-Aod3HOI+8zMhwWztDlECRsDfJ8SFu4oADvipOLq3gnWKy4Cpg2oF5AWT+U6PcX85KuguDI6c+q+2YwYEx99B/A==", + "dev": true, + "requires": { + "ansi-html": "^0.0.7", + "babel-core": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-plugin-system-import-transformer": "3.1.0", + "babel-plugin-transform-decorators-legacy": "^1.3.4", + "babel-preset-env": "^1.6.1", + "babel-preset-react": "^6.24.1", + "babel-preset-stage-0": "^6.24.1", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babelify": "^8.0.0", + "babylon": "^6.18.0", + "chalk": "^2.3.0", + "chokidar": "^2.0.0", + "concat-stream": "^1.6.0", + "disparity": "^2.0.0", + "doctrine-temporary-fork": "2.0.0-alpha-allowarrayindex", + "get-port": "^3.2.0", + "git-url-parse": "^8.0.0", + "github-slugger": "1.2.0", + "glob": "^7.1.2", + "globals-docs": "^2.4.0", + "highlight.js": "^9.12.0", + "js-yaml": "^3.10.0", + "lodash": "^4.17.4", + "mdast-util-inject": "^1.1.0", + "micromatch": "^3.1.5", + "mime": "^1.4.1", + "module-deps-sortable": "4.0.6", + "parse-filepath": "^1.0.2", + "pify": "^3.0.0", + "read-pkg-up": "^3.0.0", + "remark": "^9.0.0", + "remark-html": "7.0.0", + "remark-reference-links": "^4.0.1", + "remark-toc": "^5.0.0", + "remote-origin-url": "0.4.0", + "shelljs": "^0.8.1", + "stream-array": "^1.1.2", + "strip-json-comments": "^2.0.1", + "tiny-lr": "^1.1.0", + "unist-builder": "^1.0.2", + "unist-util-visit": "^1.3.0", + "vfile": "^2.3.0", + "vfile-reporter": "^4.0.0", + "vfile-sort": "^2.1.0", + "vinyl": "^2.1.0", + "vinyl-fs": "^3.0.2", + "yargs": "^9.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true } - } - }, - "@babel/types": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", - "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@cnakazawa/watch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", - "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", - "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - } - }, - "@gulp-sourcemaps/identity-map": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz", - "integrity": "sha512-ciiioYMLdo16ShmfHBXJBOFm3xPC4AuwO4xeRpFeHz7WK9PYsWCmigagG2XyzZpubK4a3qNKoUBDhbzHfa50LQ==", - "dev": true, - "requires": { - "acorn": "^5.0.3", - "css": "^2.2.1", - "normalize-path": "^2.1.1", - "source-map": "^0.6.0", - "through2": "^2.0.3" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true } - } - }, - "@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", - "dev": true, - "requires": { - "normalize-path": "^2.0.1", - "through2": "^2.0.3" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true } } - } - }, - "@jest/console": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", - "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", - "requires": { - "@jest/source-map": "^24.9.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - }, - "dependencies": { - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" } - } - }, - "@jest/core": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz", - "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==", - "requires": { - "@jest/console": "^24.7.1", - "@jest/reporters": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-changed-files": "^24.9.0", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-resolve-dependencies": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "jest-watcher": "^24.9.0", - "micromatch": "^3.1.10", - "p-each-series": "^1.0.0", - "realpath-native": "^1.1.0", - "rimraf": "^2.5.4", - "slash": "^2.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } } } - } - }, - "@jest/environment": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", - "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", - "requires": { - "@jest/fake-timers": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0" - } - }, - "@jest/fake-timers": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", - "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", - "requires": { - "@jest/types": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0" - } - }, - "@jest/reporters": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", - "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", - "requires": { - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.2", - "istanbul-lib-coverage": "^2.0.2", - "istanbul-lib-instrument": "^3.0.1", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.1", - "istanbul-reports": "^2.2.6", - "jest-haste-map": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", - "node-notifier": "^5.4.2", - "slash": "^2.0.0", - "source-map": "^0.6.0", - "string-length": "^2.0.0" - }, - "dependencies": { - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } } - } - }, - "@jest/source-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", - "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.1.15", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", + "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + }, + "dependencies": { + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + } + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "^4.1.0" } } - }, - "@jest/test-result": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", - "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", - "requires": { - "@jest/console": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/test-sequencer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", - "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", - "requires": { - "@jest/test-result": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0" - } - }, - "@jest/transform": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", - "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.9.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.9.0", - "jest-regex-util": "^24.9.0", - "jest-util": "^24.9.0", - "micromatch": "^3.1.10", - "pirates": "^4.0.1", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - }, - "dependencies": { - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "dset": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/dset/-/dset-2.0.1.tgz", + "integrity": "sha512-nI29OZMRYq36hOcifB6HTjajNAAiBKSXsyWZrq+VniusseuP2OpNlTiYgsaNRSGvpyq5Wjbc2gQLyBdTyWqhnQ==" + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "each-props": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", + "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.1", + "object.defaults": "^1.1.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "editions": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", + "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "2.5.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.9.tgz", + "integrity": "sha512-GJCAeDBKfREgkBtgrYSf9hQy9kTb3helv0zGdzqhM7iAkW8FA/ZF97VQDbwFiwIT8MQLLOe5VlPZOEvZAqtUAQ==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.349", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.349.tgz", + "integrity": "sha512-uEb2zs6EJ6OZIqaMsCSliYVgzE/f7/s1fLWqtvRtHg/v5KBF2xds974fUnyatfxIDgkqzQVwFtam5KExqywx0Q==", + "dev": true + }, + "elliptic": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~3.3.1" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" } - } - }, - "@jest/types": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" - } - }, - "@sindresorhus/is": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", - "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", - "dev": true - }, - "@sinonjs/commons": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.6.0.tgz", - "integrity": "sha512-w4/WHG7C4WWFyE5geCieFJF6MZkbW4VAriol5KlmQXpAQdxvV0p26sqNZOW6Qyw6Y0l9K4g+cHvvczR2sEEpqg==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/formatio": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", - "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", - "dev": true, - "requires": { - "samsam": "1.3.0" - } - }, - "@sinonjs/samsam": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", - "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.3.0", - "array-from": "^2.1.1", - "lodash": "^4.17.15" - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", - "dev": true - }, - "@types/babel__core": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", - "integrity": "sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.8.tgz", - "integrity": "sha512-yGeB2dHEdvxjP0y4UbRtQaSkXJ9649fYCmIdRoul5kfAoGCwxuCbMhag0k3RPfnuh9kPGm8x89btcfDEXdVWGw==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/crypto-js": { - "version": "3.1.43", - "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-3.1.43.tgz", - "integrity": "sha512-EHe/YKctU3IYNBsDmSOPX/7jLHPRlx8WaiDKSY9JCTnJ8XJeM4c0ZJvx+9Gxmr2s2ihI92R+3U/gNL1sq5oRuQ==" - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==" - }, - "@types/istanbul-lib-report": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", - "integrity": "sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==", - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "24.0.23", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.23.tgz", - "integrity": "sha512-L7MBvwfNpe7yVPTXLn32df/EK+AMBFAFvZrRuArGs7npEWnlziUXK+5GMIUTI4NIuwok3XibsjXCs5HxviYXjg==", - "requires": { - "jest-diff": "^24.3.0" - } - }, - "@types/node": { - "version": "12.12.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz", - "integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==" - }, - "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" - }, - "@types/yargs": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.3.tgz", - "integrity": "sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ==", - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-13.1.0.tgz", - "integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==" - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "abab": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", - "dev": true - }, - "abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" - }, - "acorn-dynamic-import": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", - "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", - "dev": true, - "requires": { - "acorn": "^4.0.3" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } } - }, - "acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", - "requires": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" - }, - "dependencies": { - "acorn": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", - "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", - "dev": true + } + }, + "engine.io-client": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" } - } - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } } - }, - "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" - }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "dev": true - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "enhanced-resolve": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "object-assign": "^4.0.1", + "tapable": "^0.2.7" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", + "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", + "dev": true, + "requires": { + "string-template": "~0.2.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es5-shim": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/es5-shim/-/es5-shim-4.5.13.tgz", + "integrity": "sha512-xi6hh6gsvDE0MaW4Vp1lgNEBpVcCXRWfPXj5egDvtgLz4L9MEvNwYEMdJH+JJinWkwa8c3c3o5HduV7dB/e1Hw==", + "dev": true + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + }, + "dependencies": { + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" } } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-cyan": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", - "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true - }, - "ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", + "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true } - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } + } + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "dev": true, + "requires": { + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } - } - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "append-transform": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", - "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", - "dev": true, - "requires": { - "default-require-extensions": "^1.0.0" - } - }, - "archiver": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-2.1.1.tgz", - "integrity": "sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw=", - "dev": true, - "requires": { - "archiver-utils": "^1.3.0", - "async": "^2.0.0", - "buffer-crc32": "^0.2.1", - "glob": "^7.0.0", - "lodash": "^4.8.0", - "readable-stream": "^2.0.0", - "tar-stream": "^1.5.0", - "zip-stream": "^1.2.0" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" } - } - }, - "archiver-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", - "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", - "dev": true, - "requires": { - "glob": "^7.0.0", - "graceful-fs": "^4.1.0", - "lazystream": "^1.0.0", - "lodash": "^4.8.0", - "normalize-path": "^2.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" } } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" + } + }, + "eslint-config-standard": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", + "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + } + }, + "eslint-module-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", + "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", - "requires": { - "make-iterator": "^1.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", + "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", - "requires": { - "make-iterator": "^1.0.0" + } + }, + "eslint-plugin-node": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz", + "integrity": "sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==", + "dev": true, + "requires": { + "ignore": "^3.3.6", + "minimatch": "^3.0.4", + "resolve": "^1.3.3", + "semver": "5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true } - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=" - }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "array-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", - "dev": true - }, - "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" + } + }, + "eslint-plugin-prebid": { + "version": "file:plugins/eslint", + "dev": true + }, + "eslint-plugin-promise": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz", + "integrity": "sha512-JiFL9UFR15NKpHyGii1ZcvmtIqa3UTwiDAGb8atSffe43qJ3+1czVGN6UtkklpcJ2DVnqvTMzEKRaJdBkAL2aQ==", + "dev": true + }, + "eslint-plugin-standard": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.1.0.tgz", + "integrity": "sha512-fVcdyuKRr0EZ4fjWl3c+gp1BANFJD1+RaWa2UPYfMZ6jCtp5RG00kSaXnK/dE5sYzt4kaWJ9qdxqUfc0d9kX0w==", + "dev": true + }, + "eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", + "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "dev": true, + "requires": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + }, + "dependencies": { + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "dev": true } - }, - "array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", - "requires": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + } + }, + "eventemitter3": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", + "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "dev": true + }, + "events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" } } - }, - "array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-braces": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", + "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", + "dev": true, + "requires": { + "array-slice": "^0.2.3", + "array-unique": "^0.2.1", + "braces": "^0.1.2" + }, + "dependencies": { + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", + "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", + "dev": true, + "requires": { + "expand-range": "^0.1.0" } } - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==" - }, - "array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "requires": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" } - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "array.prototype.flat": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.2.tgz", - "integrity": "sha512-VXjh7lAL4KXKF2hY4FnEW9eRW6IhdvFW1sN/JwLbmECbCgACCnBHNyP3lFiYuttr0jxRN9Bsc5+G27dMseSWqQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.15.0", - "function-bind": "^1.1.1" - } - }, - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" } } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" + } + }, + "expand-range": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", + "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", + "dev": true, + "requires": { + "is-number": "^0.1.1", + "repeat-string": "^0.2.2" + }, + "dependencies": { + "is-number": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", + "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", + "dev": true + }, + "repeat-string": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", + "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", + "dev": true } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, - "async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", - "requires": { - "async-done": "^1.2.2" + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "expect": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", + "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.9.0" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "dev": true, + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", + "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==", + "dev": true } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", - "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" } } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true + } + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" } - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } - }, - "babel-helper-bindify-decorators": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", - "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "faker": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-3.1.0.tgz", + "integrity": "sha1-D5CPr05uwCUk5UpX5DLFwBPgjJ8=", + "dev": true + }, + "fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "requires": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + } + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "fibers": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fibers/-/fibers-3.1.1.tgz", + "integrity": "sha512-dl3Ukt08rHVQfY8xGD0ODwyjwrRALtaghuqGH2jByYX1wpY+nAnRQjJ6Dbqq0DnVgNVQ9yibObzbF4IlPyiwPw==", + "dev": true, + "requires": { + "detect-libc": "^1.0.3" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "requires": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "filesize": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", + "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", + "dev": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + } + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, + "flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } } - }, - "babel-helper-builder-react-jsx": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", - "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "esutils": "^2.0.2" + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.10.0.tgz", + "integrity": "sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ==", + "dev": true, + "requires": { + "debug": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-explode-class": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", - "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", - "dev": true, - "requires": { - "babel-helper-bindify-decorators": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", - "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", - "requires": { - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/babel__core": "^7.1.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.9.0", - "chalk": "^2.4.2", - "slash": "^2.0.0" - }, - "dependencies": { - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" - } - } - }, - "babel-loader": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", - "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==", - "dev": true, - "requires": { - "find-cache-dir": "^2.0.0", - "loader-utils": "^1.0.2", - "mkdirp": "^0.5.1", - "pify": "^4.0.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", - "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-istanbul": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", - "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "find-up": "^3.0.0", - "istanbul-lib-instrument": "^3.3.0", - "test-exclude": "^5.2.3" - } - }, - "babel-plugin-jest-hoist": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", - "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", - "requires": { - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", - "dev": true - }, - "babel-plugin-syntax-async-generators": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", - "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", - "dev": true - }, - "babel-plugin-syntax-class-constructor-call": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", - "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=", - "dev": true - }, - "babel-plugin-syntax-class-properties": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", - "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", - "dev": true - }, - "babel-plugin-syntax-decorators": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", - "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", - "dev": true - }, - "babel-plugin-syntax-do-expressions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", - "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=", - "dev": true - }, - "babel-plugin-syntax-dynamic-import": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", - "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", - "dev": true - }, - "babel-plugin-syntax-export-extensions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", - "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=", - "dev": true - }, - "babel-plugin-syntax-flow": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", - "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", - "dev": true - }, - "babel-plugin-syntax-function-bind": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", - "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=", - "dev": true - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", - "dev": true - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", - "dev": true - }, - "babel-plugin-system-import-transformer": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-system-import-transformer/-/babel-plugin-system-import-transformer-3.1.0.tgz", - "integrity": "sha1-038Mro5h7zkGAggzHZMbXmMNfF8=", - "dev": true, - "requires": { - "babel-plugin-syntax-dynamic-import": "^6.18.0" - } - }, - "babel-plugin-transform-async-generator-functions": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", - "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", - "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-generators": "^6.5.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-class-constructor-call": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz", - "integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=", - "dev": true, - "requires": { - "babel-plugin-syntax-class-constructor-call": "^6.18.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-class-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", - "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-plugin-syntax-class-properties": "^6.8.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-decorators": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", - "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", - "dev": true, - "requires": { - "babel-helper-explode-class": "^6.24.1", - "babel-plugin-syntax-decorators": "^6.13.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-decorators-legacy": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.5.tgz", - "integrity": "sha512-jYHwjzRXRelYQ1uGm353zNzf3QmtdCfvJbuYTZ4gKveK7M9H1fs3a5AKdY1JUDl0z97E30ukORW1dzhWvsabtA==", - "dev": true, - "requires": { - "babel-plugin-syntax-decorators": "^6.1.18", - "babel-runtime": "^6.2.0", - "babel-template": "^6.3.0" - } - }, - "babel-plugin-transform-do-expressions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz", - "integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=", - "dev": true, - "requires": { - "babel-plugin-syntax-do-expressions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "dev": true, - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "dev": true, - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "dev": true, - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "dev": true, - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "dev": true, - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - } - } - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "dev": true, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-export-extensions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", - "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=", - "dev": true, - "requires": { - "babel-plugin-syntax-export-extensions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-flow-strip-types": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", - "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", - "dev": true, - "requires": { - "babel-plugin-syntax-flow": "^6.18.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-function-bind": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", - "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=", - "dev": true, - "requires": { - "babel-plugin-syntax-function-bind": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-object-assign": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-assign/-/babel-plugin-transform-object-assign-6.22.0.tgz", - "integrity": "sha1-+Z0vZvGgsNSY40bFNZaEdAyqILo=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", - "dev": true, - "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, - "babel-plugin-transform-react-display-name": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", - "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-react-jsx": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", - "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", - "dev": true, - "requires": { - "babel-helper-builder-react-jsx": "^6.24.1", - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-react-jsx-self": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", - "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", - "dev": true, - "requires": { - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-react-jsx-source": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", - "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", - "dev": true, - "requires": { - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", - "dev": true, - "requires": { - "regenerator-transform": "^0.10.0" - }, - "dependencies": { - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "dev": true, - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - } - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-preset-env": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", - "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - }, - "dependencies": { - "browserslist": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - } - } - } - }, - "babel-preset-flow": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", - "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", - "dev": true, - "requires": { - "babel-plugin-transform-flow-strip-types": "^6.22.0" - } - }, - "babel-preset-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", - "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", - "requires": { - "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.9.0" - } - }, - "babel-preset-react": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", - "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", - "dev": true, - "requires": { - "babel-plugin-syntax-jsx": "^6.3.13", - "babel-plugin-transform-react-display-name": "^6.23.0", - "babel-plugin-transform-react-jsx": "^6.24.1", - "babel-plugin-transform-react-jsx-self": "^6.22.0", - "babel-plugin-transform-react-jsx-source": "^6.22.0", - "babel-preset-flow": "^6.23.0" - } - }, - "babel-preset-stage-0": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", - "integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=", - "dev": true, - "requires": { - "babel-plugin-transform-do-expressions": "^6.22.0", - "babel-plugin-transform-function-bind": "^6.22.0", - "babel-preset-stage-1": "^6.24.1" - } - }, - "babel-preset-stage-1": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", - "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=", - "dev": true, - "requires": { - "babel-plugin-transform-class-constructor-call": "^6.24.1", - "babel-plugin-transform-export-extensions": "^6.22.0", - "babel-preset-stage-2": "^6.24.1" - } - }, - "babel-preset-stage-2": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", - "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", - "dev": true, - "requires": { - "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-decorators": "^6.24.1", - "babel-preset-stage-3": "^6.24.1" - } - }, - "babel-preset-stage-3": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", - "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", - "dev": true, - "requires": { - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-generator-functions": "^6.24.1", - "babel-plugin-transform-async-to-generator": "^6.24.1", - "babel-plugin-transform-exponentiation-operator": "^6.24.1", - "babel-plugin-transform-object-rest-spread": "^6.22.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - } - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - }, - "dependencies": { - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - } - } - }, - "babelify": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/babelify/-/babelify-8.0.0.tgz", - "integrity": "sha512-xVr63fKEvMWUrrIbqlHYsMcc5Zdw4FSVesAHgkgajyCE1W8gbm9rbMakqavhxKvikGYMhEcqxTwB/gQmQ6lBtw==", - "dev": true - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", - "requires": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - } - }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true - }, - "bail": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.4.tgz", - "integrity": "sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", - "dev": true - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", - "dev": true - }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "dev": true, - "requires": { - "callsite": "1.0.0" - } - }, - "bfj": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz", - "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "check-types": "^8.0.3", - "hoopy": "^0.1.4", - "tryer": "^1.0.1" - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" - }, - "binaryextensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.2.0.tgz", - "integrity": "sha512-bHhs98rj/7i/RZpCSJ3uk55pLXOItjIrh2sRQZSM6OoktScX+LxJzvlU+FELp9j3TdcddTmmYArLSGptCTwjuw==", - "dev": true - }, - "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "dev": true, - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - }, - "blob": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", - "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "body": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", - "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", - "dev": true, - "requires": { - "continuable-cache": "^0.3.1", - "error": "^7.0.0", - "raw-body": "~1.1.0", - "safe-json-parse": "~1.0.1" - }, - "dependencies": { - "bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", - "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", - "dev": true - }, - "raw-body": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", - "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", - "dev": true, - "requires": { - "bytes": "1", - "string_decoder": "0.10" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-process-hrtime": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" - }, - "browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", - "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" - } - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.2.tgz", - "integrity": "sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001015", - "electron-to-chromium": "^1.3.322", - "node-releases": "^1.1.42" - } - }, - "browserstack": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.3.tgz", - "integrity": "sha512-AO+mECXsW4QcqC9bxwM29O7qWa7bJT94uBFzeb5brylIQwawuEziwq20dPYbins95GlWzOawgyDNdjYAo32EKg==", - "dev": true, - "requires": { - "https-proxy-agent": "^2.2.1" - } - }, - "browserstack-local": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.4.2.tgz", - "integrity": "sha512-fRaynjF0MvtyyfPRy2NFnVwxLyNtD28K/v9xRsIjUVf7xLc80NIm7Nfr3KXlFmWizhG91PL/UAOXlHkoxQjaNw==", - "dev": true, - "requires": { - "https-proxy-agent": "^2.2.1", - "is-running": "^2.0.0", - "ps-tree": "=1.1.1", - "temp-fs": "^0.9.9" - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz", - "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=" - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-shims": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "build": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/build/-/build-0.1.4.tgz", - "integrity": "sha1-cH/gJv/O3crL/c3zVur9pk8VEEY=", - "requires": { - "cssmin": "0.3.x", - "jsmin": "1.x", - "jxLoader": "*", - "moo-server": "*", - "promised-io": "*", - "timespan": "2.x", - "uglify-js": "1.x", - "walker": "1.x", - "winston": "*", - "wrench": "1.3.x" - }, - "dependencies": { - "uglify-js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.3.5.tgz", - "integrity": "sha1-S1v/+Rhu/7qoiOTJ6UvZ/EyUkp0=" - } - } - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cacheable-request": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", - "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", - "dev": true, - "requires": { - "clone-response": "1.0.2", - "get-stream": "3.0.0", - "http-cache-semantics": "3.8.1", - "keyv": "3.0.0", - "lowercase-keys": "1.0.0", - "normalize-url": "2.0.1", - "responselike": "1.0.2" - }, - "dependencies": { - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", - "dev": true - }, - "normalize-url": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", - "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", - "dev": true, - "requires": { - "prepend-http": "^2.0.0", - "query-string": "^5.0.1", - "sort-keys": "^2.0.0" - } - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "query-string": { - "version": "5.1.1", - "resolved": "http://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - } - } - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - }, - "dependencies": { - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - } - } - }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", - "dev": true - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - } - } - }, - "caniuse-lite": { - "version": "1.0.30001015", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001015.tgz", - "integrity": "sha512-/xL2AbW/XWHNu1gnIrO8UitBGoFthcsDgU9VLK1/dpsoxbaD5LscHozKze05R6WLsBvLhqv78dAPozMFQBYLbQ==", - "dev": true - }, - "capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "requires": { - "rsvp": "^4.8.4" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "ccount": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.4.tgz", - "integrity": "sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w==", - "dev": true - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "character-entities": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.3.tgz", - "integrity": "sha512-yB4oYSAa9yLcGyTbB4ItFwHw43QHdH129IJ5R+WvxOkWlyFnR5FAaBNnUq4mcxsTVZGh28bHoeTHMKXH1wZf3w==", - "dev": true - }, - "character-entities-html4": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.3.tgz", - "integrity": "sha512-SwnyZ7jQBCRHELk9zf2CN5AnGEc2nA+uKMZLHvcqhpPprjkYhiLn0DywMHgN5ttFZuITMATbh68M6VIVKwJbcg==", - "dev": true - }, - "character-entities-legacy": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.3.tgz", - "integrity": "sha512-YAxUpPoPwxYFsslbdKkhrGnXAtXoHNgYjlBM3WMXkWGTl5RsY3QmOyhwAgL8Nxm9l5LBThXGawxKPn68y6/fww==", - "dev": true - }, - "character-reference-invalid": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.3.tgz", - "integrity": "sha512-VOq6PRzQBam/8Jm6XBGk2fNEnHXAdGd6go0rtd4weAGECBamHDwwCQSOT12TACIYUZegUXnV6xBXqUssijtxIg==", - "dev": true - }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "check-types": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", - "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==", - "dev": true - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" - }, - "cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "collapse-white-space": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.5.tgz", - "integrity": "sha512-703bOOmytCYAX9cXYqoikYIx6twmFCXsnzRQheBcTG3nzKYBR4P/+wkYeH+Mvj7qUz8zZDtdyzbxfnEi/kYzRQ==", - "dev": true - }, - "collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", - "requires": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", - "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" - }, - "colornames": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", - "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=" - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" - }, - "colorspace": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", - "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", - "requires": { - "color": "3.0.x", - "text-hex": "1.0.x" - } - }, - "combine-lists": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", - "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", - "dev": true, - "requires": { - "lodash": "^4.5.0" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "comma-separated-tokens": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz", - "integrity": "sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ==", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "dev": true - }, - "compress-commons": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", - "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.1", - "crc32-stream": "^2.0.0", - "normalize-path": "^2.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "concat-with-sourcemaps": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", - "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - } - }, - "connect-livereload": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.6.1.tgz", - "integrity": "sha512-3R0kMOdL7CjJpU66fzAkCe6HNtd3AavCS4m+uW4KtJjrdGPT0SQEZieAYd+cm+lJoBznNQ4lqipYWkhBMgk00g==", - "dev": true - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "continuable-cache": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", - "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, - "copy-props": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", - "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", - "requires": { - "each-props": "^1.3.0", - "is-plain-object": "^2.0.1" - } - }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" - }, - "core-js-compat": { - "version": "3.4.8", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.4.8.tgz", - "integrity": "sha512-l3WTmnXHV2Sfu5VuD7EHE2w7y+K68+kULKt5RJg8ZJk3YhHF1qLD4O8v8AmNq+8vbOwnPFFDvds25/AoEvMqlQ==", - "dev": true, - "requires": { - "browserslist": "^4.8.2", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "coveralls": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.9.tgz", - "integrity": "sha512-nNBg3B1+4iDox5A5zqHKzUTiwl2ey4k2o0NEcVZYvl+GOSJdKBj4AJGKLv6h3SvWch7tABHePAQOSZWM9E2hMg==", - "dev": true, - "requires": { - "js-yaml": "^3.13.1", - "lcov-parse": "^1.0.0", - "log-driver": "^1.2.7", - "minimist": "^1.2.0", - "request": "^2.88.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "crc32-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", - "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", - "dev": true, - "requires": { - "crc": "^3.4.4", - "readable-stream": "^2.0.0" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "criteo-direct-rsa-validate": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/criteo-direct-rsa-validate/-/criteo-direct-rsa-validate-1.0.0.tgz", - "integrity": "sha512-BMstd/uhDJVd1zugn34VXlEcGl/ftN3cLS3ljudp/fWr3lq+ym6fUfXm3ru5c0G+rbio+7YFv7fkWjcK9A8z2w==", - "requires": { - "@types/crypto-js": "^3.1.43", - "@types/jest": "^24.0.23", - "@types/node": "^12.12.14", - "build": "^0.1.4", - "crypto-js": "^3.1.9-1", - "gulp": "^4.0.2", - "gulp-clean": "^0.4.0", - "gulp-concat": "^2.6.1", - "gulp-rename": "^1.4.0", - "gulp-typescript": "^6.0.0-alpha.1", - "gulp-uglify": "^3.0.2", - "jest": "^24.9.0", - "through2": "3.0.1", - "ts-jest": "^24.1.0", - "typescript": "^3.7.2" - }, - "dependencies": { - "arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", - "requires": { - "arr-flatten": "^1.0.1", - "array-slice": "^0.2.3" - } - }, - "arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=" - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=" - }, - "extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", - "requires": { - "kind-of": "^1.1.0" - } - }, - "gulp-clean": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/gulp-clean/-/gulp-clean-0.4.0.tgz", - "integrity": "sha512-DARK8rNMo4lHOFLGTiHEJdf19GuoBDHqGUaypz+fOhrvOs3iFO7ntdYtdpNxv+AzSJBx/JfypF0yEj9ks1IStQ==", - "requires": { - "fancy-log": "^1.3.2", - "plugin-error": "^0.1.2", - "rimraf": "^2.6.2", - "through2": "^2.0.3", - "vinyl": "^2.1.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=" - }, - "plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", - "requires": { - "ansi-cyan": "^0.1.1", - "ansi-red": "^0.1.1", - "arr-diff": "^1.0.1", - "arr-union": "^2.0.1", - "extend-shallow": "^1.1.2" - } - }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", - "requires": { - "readable-stream": "2 || 3" - } - } - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-js": { - "version": "3.1.9-1", - "resolved": "http://build-nexus.crto.in/repository/npm/crypto-js/-/crypto-js-3.1.9-1.tgz", - "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=" - }, - "css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "css-parse": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", - "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", - "dev": true, - "requires": { - "css": "^2.0.0" - } - }, - "css-value": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", - "integrity": "sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo=", - "dev": true - }, - "cssmin": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/cssmin/-/cssmin-0.3.2.tgz", - "integrity": "sha1-3c5MVHtRCuDVlKjx+/iq+OLFwA0=" - }, - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" - }, - "cssstyle": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", - "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", - "requires": { - "cssom": "0.3.x" - } - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", - "dev": true - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", - "requires": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" - }, - "dependencies": { - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - } - } - }, - "date-format": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz", - "integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg=", - "dev": true - }, - "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "debug-fabulous": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", - "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", - "dev": true, - "requires": { - "debug": "3.X", - "memoizee": "0.4.X", - "object-assign": "4.X" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "deepmerge": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.0.1.tgz", - "integrity": "sha512-VIPwiMJqJ13ZQfaCsIFnp5Me9tnjURiaIFxfz7EH0Ci0dTSQpZtSLrqOicXqEd/z2r+z+Klk9GzmnRsgpgbOsQ==", - "dev": true - }, - "default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "requires": { - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "default-require-extensions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", - "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", - "dev": true, - "requires": { - "strip-bom": "^2.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - } - } - }, - "default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "detab": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.2.tgz", - "integrity": "sha512-Q57yPrxScy816TTE1P/uLRXLDKjXhvYTbfxS/e6lPD+YrqghbsMlGB9nQzj/zVtSPaF0DFPSdO916EWO4sQUyQ==", - "dev": true, - "requires": { - "repeat-string": "^1.5.4" - } - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=" - }, - "detective": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", - "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", - "dev": true, - "requires": { - "acorn": "^5.2.1", - "defined": "^1.0.0" - } - }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", - "dev": true - }, - "diagnostics": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", - "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==", - "requires": { - "colorspace": "1.1.x", - "enabled": "1.0.x", - "kuler": "1.0.x" - } - }, - "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", - "dev": true - }, - "diff-sequences": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", - "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "disparity": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/disparity/-/disparity-2.0.0.tgz", - "integrity": "sha1-V92stHMkrl9Y0swNqIbbTOnutxg=", - "dev": true, - "requires": { - "ansi-styles": "^2.0.1", - "diff": "^1.3.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - } - } - }, - "dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "doctrine-temporary-fork": { - "version": "2.0.0-alpha-allowarrayindex", - "resolved": "https://registry.npmjs.org/doctrine-temporary-fork/-/doctrine-temporary-fork-2.0.0-alpha-allowarrayindex.tgz", - "integrity": "sha1-QAFahn6yfnWybIKLcVJPE3+J+fA=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "documentation": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/documentation/-/documentation-5.5.0.tgz", - "integrity": "sha512-Aod3HOI+8zMhwWztDlECRsDfJ8SFu4oADvipOLq3gnWKy4Cpg2oF5AWT+U6PcX85KuguDI6c+q+2YwYEx99B/A==", - "dev": true, - "requires": { - "ansi-html": "^0.0.7", - "babel-core": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-plugin-system-import-transformer": "3.1.0", - "babel-plugin-transform-decorators-legacy": "^1.3.4", - "babel-preset-env": "^1.6.1", - "babel-preset-react": "^6.24.1", - "babel-preset-stage-0": "^6.24.1", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babelify": "^8.0.0", - "babylon": "^6.18.0", - "chalk": "^2.3.0", - "chokidar": "^2.0.0", - "concat-stream": "^1.6.0", - "disparity": "^2.0.0", - "doctrine-temporary-fork": "2.0.0-alpha-allowarrayindex", - "get-port": "^3.2.0", - "git-url-parse": "^8.0.0", - "github-slugger": "1.2.0", - "glob": "^7.1.2", - "globals-docs": "^2.4.0", - "highlight.js": "^9.12.0", - "js-yaml": "^3.10.0", - "lodash": "^4.17.4", - "mdast-util-inject": "^1.1.0", - "micromatch": "^3.1.5", - "mime": "^1.4.1", - "module-deps-sortable": "4.0.6", - "parse-filepath": "^1.0.2", - "pify": "^3.0.0", - "read-pkg-up": "^3.0.0", - "remark": "^9.0.0", - "remark-html": "7.0.0", - "remark-reference-links": "^4.0.1", - "remark-toc": "^5.0.0", - "remote-origin-url": "0.4.0", - "shelljs": "^0.8.1", - "stream-array": "^1.1.2", - "strip-json-comments": "^2.0.1", - "tiny-lr": "^1.1.0", - "unist-builder": "^1.0.2", - "unist-util-visit": "^1.3.0", - "vfile": "^2.3.0", - "vfile-reporter": "^4.0.0", - "vfile-sort": "^2.1.0", - "vinyl": "^2.1.0", - "vinyl-fs": "^3.0.2", - "yargs": "^9.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", - "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "read-pkg-up": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^7.0.0" - }, - "dependencies": { - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - } - } - }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", - "dev": true, - "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", - "requires": { - "webidl-conversions": "^4.0.2" - } - }, - "dset": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/dset/-/dset-2.0.1.tgz", - "integrity": "sha512-nI29OZMRYq36hOcifB6HTjajNAAiBKSXsyWZrq+VniusseuP2OpNlTiYgsaNRSGvpyq5Wjbc2gQLyBdTyWqhnQ==" - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", - "dev": true - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "requires": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", - "dev": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "ejs": { - "version": "2.5.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.9.tgz", - "integrity": "sha512-GJCAeDBKfREgkBtgrYSf9hQy9kTb3helv0zGdzqhM7iAkW8FA/ZF97VQDbwFiwIT8MQLLOe5VlPZOEvZAqtUAQ==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.322", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz", - "integrity": "sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==", - "dev": true - }, - "elliptic": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", - "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true - }, - "enabled": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", - "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", - "requires": { - "env-variable": "0.0.x" - } - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "engine.io": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", - "integrity": "sha1-tgKBw1SEpw7gNR6g6/+D7IyVIqI=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "ws": "~3.3.1" - }, - "dependencies": { - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "engine.io-client": { - "version": "3.2.1", - "resolved": "http://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", - "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~3.3.1", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "engine.io-parser": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", - "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.5", - "has-binary2": "~1.0.2" - } - }, - "enhanced-resolve": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", - "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "object-assign": "^4.0.1", - "tapable": "^0.2.7" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "dev": true - }, - "env-variable": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz", - "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==" - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "error": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", - "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", - "dev": true, - "requires": { - "string-template": "~0.2.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.3.tgz", - "integrity": "sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es5-shim": { - "version": "4.5.13", - "resolved": "https://registry.npmjs.org/es5-shim/-/es5-shim-4.5.13.tgz", - "integrity": "sha512-xi6hh6gsvDE0MaW4Vp1lgNEBpVcCXRWfPXj5egDvtgLz4L9MEvNwYEMdJH+JJinWkwa8c3c3o5HduV7dB/e1Hw==", - "dev": true - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - }, - "dependencies": { - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - } - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "escodegen": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", - "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", - "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true - } - } - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", - "dev": true, - "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "eslint-config-standard": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", - "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", - "dev": true - }, - "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.5.0" - } - }, - "eslint-module-utils": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.0.tgz", - "integrity": "sha512-kCo8pZaNz2dsAW7nCUjuVoI11EBXXpIzfNxmaoLhXoRDOnqXLC4iSGVRdZPhOitfbdEfMEfKOiENaK6wDPZEGw==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.19.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.19.1.tgz", - "integrity": "sha512-x68131aKoCZlCae7rDXKSAQmbT5DQuManyXo2sK6fJJ0aK5CWAkv6A6HJZGgqC8IhjQxYPgo6/IY4Oz8AFsbBw==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "array.prototype.flat": "^1.2.1", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.1", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.0", - "read-pkg-up": "^2.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - } - } - }, - "eslint-plugin-node": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz", - "integrity": "sha512-xhPXrh0Vl/b7870uEbaumb2Q+LxaEcOQ3kS1jtIXanBAwpMre1l5q/l2l/hESYJGEFKuI78bp6Uw50hlpr7B+g==", - "dev": true, - "requires": { - "ignore": "^3.3.6", - "minimatch": "^3.0.4", - "resolve": "^1.3.3", - "semver": "5.3.0" - }, - "dependencies": { - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true - } - } - }, - "eslint-plugin-prebid": { - "version": "file:plugins/eslint", - "dev": true - }, - "eslint-plugin-promise": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz", - "integrity": "sha512-JiFL9UFR15NKpHyGii1ZcvmtIqa3UTwiDAGb8atSffe43qJ3+1czVGN6UtkklpcJ2DVnqvTMzEKRaJdBkAL2aQ==", - "dev": true - }, - "eslint-plugin-standard": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.1.0.tgz", - "integrity": "sha512-fVcdyuKRr0EZ4fjWl3c+gp1BANFJD1+RaWa2UPYfMZ6jCtp5RG00kSaXnK/dE5sYzt4kaWJ9qdxqUfc0d9kX0w==", - "dev": true - }, - "eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", - "dev": true - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "event-stream": { - "version": "3.3.4", - "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", - "dev": true, - "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - }, - "dependencies": { - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", - "dev": true - } - } - }, - "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", - "dev": true - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", - "dev": true - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - } - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" - }, - "expand-braces": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", - "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", - "dev": true, - "requires": { - "array-slice": "^0.2.3", - "array-unique": "^0.2.1", - "braces": "^0.1.2" - }, - "dependencies": { - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", - "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", - "dev": true, - "requires": { - "expand-range": "^0.1.0" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-range": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", - "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", - "dev": true, - "requires": { - "is-number": "^0.1.1", - "repeat-string": "^0.2.2" - }, - "dependencies": { - "is-number": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", - "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", - "dev": true - }, - "repeat-string": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", - "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", - "dev": true - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "expect": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", - "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", - "requires": { - "@jest/types": "^24.9.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.9.0" - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "dev": true, - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", - "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "faker": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/faker/-/faker-3.1.0.tgz", - "integrity": "sha1-D5CPr05uwCUk5UpX5DLFwBPgjJ8=", - "dev": true - }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "fecha": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", - "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" - }, - "fibers": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fibers/-/fibers-3.1.1.tgz", - "integrity": "sha512-dl3Ukt08rHVQfY8xGD0ODwyjwrRALtaghuqGH2jByYX1wpY+nAnRQjJ6Dbqq0DnVgNVQ9yibObzbF4IlPyiwPw==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fileset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", - "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", - "dev": true, - "requires": { - "glob": "^7.0.3", - "minimatch": "^3.0.3" - } - }, - "filesize": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", - "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", - "dev": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==" - }, - "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "follow-redirects": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", - "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", - "dev": true, - "requires": { - "debug": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "requires": { - "for-in": "^1.0.1" - } - }, - "foreachasync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz", - "integrity": "sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "fork-stream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz", - "integrity": "sha1-24Sfznf2cIpfjzhq5TOgkHtUrnA=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-access": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", - "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", - "dev": true, - "requires": { - "null-check": "^1.0.0" - } - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.6.4.tgz", - "integrity": "sha1-9G8MdbeEH40gCzNIzU1pHVoJnRU=", - "dev": true, - "requires": { - "jsonfile": "~1.0.1", - "mkdirp": "0.3.x", - "ncp": "~0.4.2", - "rimraf": "~2.2.0" - }, - "dependencies": { - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "dev": true - }, - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true - } - } - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - } - }, - "fs.extra": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fs.extra/-/fs.extra-1.3.2.tgz", - "integrity": "sha1-3QI/kwE77iRTHxszUUw3sg/ZM0k=", - "dev": true, - "requires": { - "fs-extra": "~0.6.1", - "mkdirp": "~0.3.5", - "walk": "^2.3.9" - }, - "dependencies": { - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "dev": true - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "optional": true - } - } - }, - "fun-hooks": { - "version": "0.9.7", - "resolved": "https://registry.npmjs.org/fun-hooks/-/fun-hooks-0.9.7.tgz", - "integrity": "sha512-2G0S9op/u+Ye/IJVPS++bs8oDuC/x7MpTKPkJ85U0PBfocJYd+f8WQRN1gqaCa2egKwjOOtXYVFcu0ksns+lWQ==", - "requires": { - "typescript-tuple": "^2.2.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", - "dev": true, - "requires": { - "globule": "^1.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", - "dev": true - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "git-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-2.1.0.tgz", - "integrity": "sha512-MJgwfcSd9qxgDyEYpRU/CDxNpUadrK80JHuEQDG4Urn0m7tpSOgCBrtiSIa9S9KH8Tbuo/TN8SSQmJBvsw1HkA==", - "dev": true, - "requires": { - "is-ssh": "^1.3.0", - "parse-url": "^3.0.2" - } - }, - "git-url-parse": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-8.3.1.tgz", - "integrity": "sha512-r/FxXIdfgdSO+V2zl4ZK1JGYkHT9nqVRSzom5WsYPLg3XzeBeKPl3R/6X9E9ZJRx/sE/dXwXtfl+Zp7YL8ktWQ==", - "dev": true, - "requires": { - "git-up": "^2.0.0", - "parse-domain": "^2.0.0" - } - }, - "github-slugger": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.0.tgz", - "integrity": "sha512-wIaa75k1vZhyPm9yWrD08A5Xnx/V+RmzGrpjQuLemGKSb77Qukiaei58Bogrl/LZSADDfPzKJX8jhLs4CRTl7Q==", - "dev": true, - "requires": { - "emoji-regex": ">=6.0.0 <=6.1.1" - }, - "dependencies": { - "emoji-regex": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", - "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=", - "dev": true - } - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - } - }, - "glob-watcher": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz", - "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==", - "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "object.defaults": "^1.1.0" - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "globals-docs": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/globals-docs/-/globals-docs-2.4.1.tgz", - "integrity": "sha512-qpPnUKkWnz8NESjrCvnlGklsgiQzlq+rcCxoG5uNQ+dNA7cFMCmn231slLAwS2N/PlkzZ3COL8CcS10jXmLHqg==", - "dev": true - }, - "globule": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", - "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", - "dev": true, - "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" - } - }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "requires": { - "sparkles": "^1.0.0" - } - }, - "got": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", - "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.7.0", - "cacheable-request": "^2.1.1", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "into-stream": "^3.1.0", - "is-retry-allowed": "^1.1.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "mimic-response": "^1.0.0", - "p-cancelable": "^0.4.0", - "p-timeout": "^2.0.1", - "pify": "^3.0.0", - "safe-buffer": "^5.1.1", - "timed-out": "^4.0.1", - "url-parse-lax": "^3.0.0", - "url-to-options": "^1.0.1" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" - }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" - }, - "gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", - "requires": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, - "gulp-cli": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz", - "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==", - "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.1.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.0.1", - "yargs": "^7.1.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "^1.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "^0.2.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" - }, - "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" - } - }, - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", - "requires": { - "camelcase": "^3.0.0" - } - } - } - }, - "gulp-clean": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/gulp-clean/-/gulp-clean-0.3.2.tgz", - "integrity": "sha1-o0fUc6zqQBgvk1WHpFGUFnGSgQI=", - "dev": true, - "requires": { - "gulp-util": "^2.2.14", - "rimraf": "^2.2.8", - "through2": "^0.4.2" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "dev": true - }, - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", - "dev": true - }, - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "dev": true, - "requires": { - "ansi-styles": "^1.1.0", - "escape-string-regexp": "^1.0.0", - "has-ansi": "^0.1.0", - "strip-ansi": "^0.3.0", - "supports-color": "^0.2.0" - } - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "gulp-util": { - "version": "2.2.20", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", - "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", - "dev": true, - "requires": { - "chalk": "^0.5.0", - "dateformat": "^1.0.7-1.2.3", - "lodash._reinterpolate": "^2.4.1", - "lodash.template": "^2.4.1", - "minimist": "^0.2.0", - "multipipe": "^0.1.0", - "through2": "^0.5.0", - "vinyl": "^0.2.1" - }, - "dependencies": { - "through2": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", - "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", - "dev": true, - "requires": { - "readable-stream": "~1.0.17", - "xtend": "~3.0.0" - } - } - } - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "dev": true, - "requires": { - "ansi-regex": "^0.2.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "minimist": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", - "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", - "dev": true - }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "dev": true, - "requires": { - "ansi-regex": "^0.2.1" - } - }, - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", - "dev": true - }, - "through2": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", - "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", - "dev": true, - "requires": { - "readable-stream": "~1.0.17", - "xtend": "~2.1.1" - }, - "dependencies": { - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "vinyl": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", - "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", - "dev": true, - "requires": { - "clone-stats": "~0.0.1" - } - }, - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } - } - }, - "gulp-concat": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", - "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", - "requires": { - "concat-with-sourcemaps": "^1.0.0", - "through2": "^2.0.0", - "vinyl": "^2.0.0" - } - }, - "gulp-connect": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/gulp-connect/-/gulp-connect-5.7.0.tgz", - "integrity": "sha1-fpJfXkw06/7fnzGFdpZuj+iEDVo=", - "dev": true, - "requires": { - "ansi-colors": "^2.0.5", - "connect": "^3.6.6", - "connect-livereload": "^0.6.0", - "fancy-log": "^1.3.2", - "map-stream": "^0.0.7", - "send": "^0.16.2", - "serve-index": "^1.9.1", - "serve-static": "^1.13.2", - "tiny-lr": "^1.1.1" - }, - "dependencies": { - "ansi-colors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-2.0.5.tgz", - "integrity": "sha1-XaN4Jf7z51872kf3YNZL/RDhXhA=", - "dev": true - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" - } - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true - } - } - }, - "gulp-eslint": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-4.0.2.tgz", - "integrity": "sha512-fcFUQzFsN6dJ6KZlG+qPOEkqfcevRUXgztkYCvhNvJeSvOicC8ucutN4qR/ID8LmNZx9YPIkBzazTNnVvbh8wg==", - "dev": true, - "requires": { - "eslint": "^4.0.0", - "fancy-log": "^1.3.2", - "plugin-error": "^1.0.0" - } - }, - "gulp-footer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/gulp-footer/-/gulp-footer-2.0.2.tgz", - "integrity": "sha512-HsG5VOgKHFRqZXnHGI6oGhPDg70p9pobM+dYOnjBZVLMQUHzLG6bfaPNRJ7XG707E+vWO3TfN0CND9UrYhk94g==", - "dev": true, - "requires": { - "lodash._reescape": "^3.0.0", - "lodash._reevaluate": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.template": "^3.6.2", - "map-stream": "0.0.7" - }, - "dependencies": { - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash.escape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", - "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", - "dev": true, - "requires": { - "lodash._root": "^3.0.0" - } - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "lodash.template": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", - "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", - "dev": true, - "requires": { - "lodash._basecopy": "^3.0.0", - "lodash._basetostring": "^3.0.0", - "lodash._basevalues": "^3.0.0", - "lodash._isiterateecall": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0", - "lodash.keys": "^3.0.0", - "lodash.restparam": "^3.0.0", - "lodash.templatesettings": "^3.0.0" - } - }, - "lodash.templatesettings": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", - "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0" - } - } - } - }, - "gulp-header": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-1.8.12.tgz", - "integrity": "sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==", - "dev": true, - "requires": { - "concat-with-sourcemaps": "*", - "lodash.template": "^4.4.0", - "through2": "^2.0.0" - }, - "dependencies": { - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - } - } - }, - "gulp-if": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/gulp-if/-/gulp-if-2.0.2.tgz", - "integrity": "sha1-pJe351cwBQQcqivIt92jyARE1ik=", - "dev": true, - "requires": { - "gulp-match": "^1.0.3", - "ternary-stream": "^2.0.1", - "through2": "^2.0.1" - } - }, - "gulp-js-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gulp-js-escape/-/gulp-js-escape-1.0.1.tgz", - "integrity": "sha1-HNRF+9AJ4Np2lZoDp/SbNWav+Gg=", - "dev": true, - "requires": { - "through2": "^0.6.3" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - } - } - }, - "gulp-match": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/gulp-match/-/gulp-match-1.1.0.tgz", - "integrity": "sha512-DlyVxa1Gj24DitY2OjEsS+X6tDpretuxD6wTfhXE/Rw2hweqc1f6D/XtsJmoiCwLWfXgR87W9ozEityPCVzGtQ==", - "dev": true, - "requires": { - "minimatch": "^3.0.3" - } - }, - "gulp-rename": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.4.0.tgz", - "integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==" - }, - "gulp-replace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.0.0.tgz", - "integrity": "sha512-lgdmrFSI1SdhNMXZQbrC75MOl1UjYWlOWNbNRnz+F/KHmgxt3l6XstBoAYIdadwETFyG/6i+vWUSCawdC3pqOw==", - "dev": true, - "requires": { - "istextorbinary": "2.2.1", - "readable-stream": "^2.0.1", - "replacestream": "^4.0.0" - } - }, - "gulp-shell": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/gulp-shell/-/gulp-shell-0.5.2.tgz", - "integrity": "sha1-pJWcoGUa0ce7/nCy0K27tOGuqY0=", - "dev": true, - "requires": { - "async": "^1.5.0", - "gulp-util": "^3.0.7", - "lodash": "^4.0.0", - "through2": "^2.0.0" - } - }, - "gulp-sourcemaps": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.5.tgz", - "integrity": "sha512-SYLBRzPTew8T5Suh2U8jCSDKY+4NARua4aqjj8HOysBh2tSgT9u4jc1FYirAdPx1akUxxDeK++fqw6Jg0LkQRg==", - "dev": true, - "requires": { - "@gulp-sourcemaps/identity-map": "1.X", - "@gulp-sourcemaps/map-sources": "1.X", - "acorn": "5.X", - "convert-source-map": "1.X", - "css": "2.X", - "debug-fabulous": "1.X", - "detect-newline": "2.X", - "graceful-fs": "4.X", - "source-map": "~0.6.0", - "strip-bom-string": "1.X", - "through2": "2.X" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "gulp-typescript": { - "version": "6.0.0-alpha.1", - "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-6.0.0-alpha.1.tgz", - "integrity": "sha512-KoT0TTfjfT7w3JItHkgFH1T/zK4oXWC+a8xxKfniRfVcA0Fa1bKrIhztYelYmb+95RB80OLMBreknYkdwzdi2Q==", - "requires": { - "ansi-colors": "^4.1.1", - "plugin-error": "^1.0.1", - "source-map": "^0.7.3", - "through2": "^3.0.1", - "vinyl": "^2.2.0", - "vinyl-fs": "^3.0.3" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", - "requires": { - "readable-stream": "2 || 3" - } - } - } - }, - "gulp-uglify": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz", - "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==", - "requires": { - "array-each": "^1.0.1", - "extend-shallow": "^3.0.2", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "isobject": "^3.0.1", - "make-error-cause": "^1.1.1", - "safe-buffer": "^5.1.2", - "through2": "^2.0.0", - "uglify-js": "^3.0.5", - "vinyl-sourcemaps-apply": "^0.2.0" - } - }, - "gulp-util": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", - "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", - "dev": true, - "requires": { - "array-differ": "^1.0.0", - "array-uniq": "^1.0.2", - "beeper": "^1.0.0", - "chalk": "^1.0.0", - "dateformat": "^2.0.0", - "fancy-log": "^1.1.0", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "lodash._reescape": "^3.0.0", - "lodash._reevaluate": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.template": "^3.0.0", - "minimist": "^1.1.0", - "multipipe": "^0.1.2", - "object-assign": "^3.0.0", - "replace-ext": "0.0.1", - "through2": "^2.0.0", - "vinyl": "^0.5.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "dateformat": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", - "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash.escape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", - "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", - "dev": true, - "requires": { - "lodash._root": "^3.0.0" - } - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "lodash.template": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", - "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", - "dev": true, - "requires": { - "lodash._basecopy": "^3.0.0", - "lodash._basetostring": "^3.0.0", - "lodash._basevalues": "^3.0.0", - "lodash._isiterateecall": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0", - "lodash.keys": "^3.0.0", - "lodash.restparam": "^3.0.0", - "lodash.templatesettings": "^3.0.0" - } - }, - "lodash.templatesettings": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", - "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0" - } - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "vinyl": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", - "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "requires": { - "glogg": "^1.0.0" - } - }, - "gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", - "dev": true, - "requires": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" - } - }, - "handlebars": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", - "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", - "dev": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "dev": true, - "requires": { - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - } - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", - "requires": { - "sparkles": "^1.0.0" - } - }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "dev": true, - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hast-util-is-element": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.0.3.tgz", - "integrity": "sha512-C62CVn7jbjp89yOhhy7vrkSaB7Vk906Gtcw/Ihd+Iufnq+2pwOZjdPmpzpKLWJXPJBMDX3wXg4FqmdOayPcewA==", - "dev": true - }, - "hast-util-sanitize": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-1.3.1.tgz", - "integrity": "sha512-AIeKHuHx0Wk45nSkGVa2/ujQYTksnDl8gmmKo/mwQi7ag7IBZ8cM3nJ2G86SajbjGP/HRpud6kMkPtcM2i0Tlw==", - "dev": true, - "requires": { - "xtend": "^4.0.1" - } - }, - "hast-util-to-html": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-3.1.0.tgz", - "integrity": "sha1-iCyZhJ5AEw6ZHAQuRW1FPZXDbP8=", - "dev": true, - "requires": { - "ccount": "^1.0.0", - "comma-separated-tokens": "^1.0.1", - "hast-util-is-element": "^1.0.0", - "hast-util-whitespace": "^1.0.0", - "html-void-elements": "^1.0.0", - "kebab-case": "^1.0.0", - "property-information": "^3.1.0", - "space-separated-tokens": "^1.0.0", - "stringify-entities": "^1.0.1", - "unist-util-is": "^2.0.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "unist-util-is": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", - "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==", - "dev": true - } - } - }, - "hast-util-whitespace": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.3.tgz", - "integrity": "sha512-AlkYiLTTwPOyxZ8axq2/bCwRUPjIPBfrHkXuCR92B38b3lSdU22R5F/Z4DL6a2kxWpekWq1w6Nj48tWat6GeRA==", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "highlight.js": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.17.0.tgz", - "integrity": "sha512-PyO7FK7z8ZC7FqBlmAxm4d+1DYaoS6+uaxt9KGkyP1AnmGRLnWmNod1yp9BFjUyHoDF00k+V57gF6X9ifY7f/A==", - "dev": true, - "requires": { - "handlebars": "^4.5.3" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", - "dev": true - }, - "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==" - }, - "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", - "requires": { - "whatwg-encoding": "^1.0.1" - } - }, - "html-void-elements": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.4.tgz", - "integrity": "sha512-yMk3naGPLrfvUV9TdDbuYXngh/TpHbA6TrOw3HL9kS8yhwx7i309BReNg7CbAJXGE+UMJ6je5OqJ7lC63o6YuQ==", - "dev": true - }, - "http-cache-semantics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", - "dev": true - }, - "http-proxy": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", - "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dev": true, - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "humanize-duration": { - "version": "3.15.3", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.15.3.tgz", - "integrity": "sha512-BMz6w8p3NVa6QP9wDtqUkXfwgBqDaZ5z/np0EYdoWrLqL849Onp6JWMXMhbHtuvO9jUThLN5H1ThRQ8dUWnYkA==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" - }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==" - }, - "into-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", - "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", - "dev": true, - "requires": { - "from2": "^2.1.1", - "p-is-promise": "^1.1.0" - } - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-alphabetical": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz", - "integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA==", - "dev": true - }, - "is-alphanumeric": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", - "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=", - "dev": true - }, - "is-alphanumerical": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.3.tgz", - "integrity": "sha512-A1IGAPO5AW9vSh7omxIlOGwIqEvpW/TA+DksVOPM5ODuxKlZS09+TEM1E3275lJqO2oJ38vDpeAL3DCIiHE6eA==", - "dev": true, - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==" - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" - }, - "is-decimal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.3.tgz", - "integrity": "sha512-bvLSwoDg2q6Gf+E2LEPiklHZxxiSi3XAh4Mav65mKqTfCO1HM3uBs24TjEH8iJX3bbDdLXKJXBTmGzuTUuAEjQ==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "is-docker": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-1.1.0.tgz", - "integrity": "sha1-8EN01O7lMQ6ajhE78UlUEeRhdqE=", - "dev": true - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hexadecimal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.3.tgz", - "integrity": "sha512-zxQ9//Q3D/34poZf8fiy3m3XVpbQc7ren15iKqrTtLPwkPD/t3Scy9Imp63FujULGxuK0ZlCwoo5xNpktFgbOA==", - "dev": true - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=" - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", - "dev": true - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "requires": { - "has": "^1.0.1" - } - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true - }, - "is-running": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-running/-/is-running-2.1.0.tgz", - "integrity": "sha1-MKc/9cw4VOT8JUkICen1q/jeCeA=", - "dev": true - }, - "is-ssh": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.1.tgz", - "integrity": "sha512-0eRIASHZt1E68/ixClI8bp2YK2wmBPVWEismTs6M+M099jKgrzl/3E976zIbImSIob48N2/XGe9y7ZiYdImSlg==", - "dev": true, - "requires": { - "protocols": "^1.1.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=" - }, - "is-whitespace-character": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz", - "integrity": "sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ==", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-word-character": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.3.tgz", - "integrity": "sha512-0wfcrFgOOOBdgRNT9H33xe6Zi6yhX/uoc4U8NBZGeQQB0ctU1dnlNTyL9JM2646bHDTpsDm1Brb3VPoCIMrd/A==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", - "dev": true, - "requires": { - "buffer-alloc": "^1.2.0" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "istanbul": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", - "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", - "dev": true, - "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "dev": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - } - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, - "istanbul-api": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.7.tgz", - "integrity": "sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==", - "dev": true, - "requires": { - "async": "^2.1.4", - "fileset": "^2.0.2", - "istanbul-lib-coverage": "^1.2.1", - "istanbul-lib-hook": "^1.2.2", - "istanbul-lib-instrument": "^1.10.2", - "istanbul-lib-report": "^1.1.5", - "istanbul-lib-source-maps": "^1.2.6", - "istanbul-reports": "^1.5.1", - "js-yaml": "^3.7.0", - "mkdirp": "^0.5.1", - "once": "^1.4.0" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", - "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", - "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", - "dev": true, - "requires": { - "babel-generator": "^6.18.0", - "babel-template": "^6.16.0", - "babel-traverse": "^6.18.0", - "babel-types": "^6.18.0", - "babylon": "^6.18.0", - "istanbul-lib-coverage": "^1.2.1", - "semver": "^5.3.0" - } - }, - "istanbul-lib-report": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz", - "integrity": "sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^1.2.1", - "mkdirp": "^0.5.1", - "path-parse": "^1.0.5", - "supports-color": "^3.1.2" - } - }, - "istanbul-lib-source-maps": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz", - "integrity": "sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==", - "dev": true, - "requires": { - "debug": "^3.1.0", - "istanbul-lib-coverage": "^1.2.1", - "mkdirp": "^0.5.1", - "rimraf": "^2.6.1", - "source-map": "^0.5.3" - } - }, - "istanbul-reports": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.5.1.tgz", - "integrity": "sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==", - "dev": true, - "requires": { - "handlebars": "^4.0.3" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "istanbul-instrumenter-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.1.tgz", - "integrity": "sha512-a5SPObZgS0jB/ixaKSMdn6n/gXSrK2S6q/UfRJBT3e6gQmVjwZROTODQsYW5ZNwOu78hG62Y3fWlebaVOL0C+w==", - "dev": true, - "requires": { - "convert-source-map": "^1.5.0", - "istanbul-lib-instrument": "^1.7.3", - "loader-utils": "^1.1.0", - "schema-utils": "^0.3.0" - }, - "dependencies": { - "istanbul-lib-coverage": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", - "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", - "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", - "dev": true, - "requires": { - "babel-generator": "^6.18.0", - "babel-template": "^6.16.0", - "babel-traverse": "^6.18.0", - "babel-types": "^6.18.0", - "babylon": "^6.18.0", - "istanbul-lib-coverage": "^1.2.1", - "semver": "^5.3.0" - } - } - } - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==" - }, - "istanbul-lib-hook": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz", - "integrity": "sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==", - "dev": true, - "requires": { - "append-transform": "^0.4.0" - } - }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", - "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "istanbul-reports": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", - "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", - "requires": { - "handlebars": "^4.1.2" - } - }, - "istextorbinary": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", - "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", - "dev": true, - "requires": { - "binaryextensions": "2", - "editions": "^1.3.3", - "textextensions": "2" - } - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", - "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", - "requires": { - "import-local": "^2.0.0", - "jest-cli": "^24.9.0" - }, - "dependencies": { - "jest-cli": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", - "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", - "requires": { - "@jest/core": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "import-local": "^2.0.0", - "is-ci": "^2.0.0", - "jest-config": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "prompts": "^2.0.1", - "realpath-native": "^1.1.0", - "yargs": "^13.3.0" - } - }, - "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" - } - } - } - }, - "jest-changed-files": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", - "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", - "requires": { - "@jest/types": "^24.9.0", - "execa": "^1.0.0", - "throat": "^4.0.0" - } - }, - "jest-config": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", - "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^24.9.0", - "@jest/types": "^24.9.0", - "babel-jest": "^24.9.0", - "chalk": "^2.0.1", - "glob": "^7.1.1", - "jest-environment-jsdom": "^24.9.0", - "jest-environment-node": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "micromatch": "^3.1.10", - "pretty-format": "^24.9.0", - "realpath-native": "^1.1.0" - } - }, - "jest-diff": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", - "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", - "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", - "requires": { - "detect-newline": "^2.1.0" - } - }, - "jest-each": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", - "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", - "requires": { - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-environment-jsdom": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", - "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0", - "jsdom": "^11.5.1" - } - }, - "jest-environment-node": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", - "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0" - } - }, - "jest-get-type": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==" - }, - "jest-haste-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", - "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", - "requires": { - "@jest/types": "^24.9.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.9.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", - "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "co": "^4.6.0", - "expect": "^24.9.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0", - "throat": "^4.0.0" - } - }, - "jest-leak-detector": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", - "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", - "requires": { - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-matcher-utils": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", - "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", - "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - } - }, - "jest-message-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", - "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - }, - "dependencies": { - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" - } - } - }, - "jest-mock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", - "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", - "requires": { - "@jest/types": "^24.9.0" - } - }, - "jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==" - }, - "jest-regex-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", - "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==" - }, - "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", - "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "jest-resolve-dependencies": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz", - "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==", - "requires": { - "@jest/types": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-snapshot": "^24.9.0" - } - }, - "jest-runner": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", - "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.4.2", - "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-docblock": "^24.3.0", - "jest-haste-map": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-leak-detector": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", - "source-map-support": "^0.5.6", - "throat": "^4.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } - } - }, - "jest-runtime": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", - "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/source-map": "^24.3.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "strip-bom": "^3.0.0", - "yargs": "^13.3.0" - }, - "dependencies": { - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" - }, - "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" - } - } - } - }, - "jest-serializer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", - "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==" - }, - "jest-snapshot": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", - "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "expect": "^24.9.0", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^24.9.0", - "semver": "^6.2.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "jest-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", - "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", - "requires": { - "@jest/console": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/source-map": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "jest-validate": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", - "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", - "requires": { - "@jest/types": "^24.9.0", - "camelcase": "^5.3.1", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "leven": "^3.1.0", - "pretty-format": "^24.9.0" - } - }, - "jest-watcher": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", - "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", - "requires": { - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", - "jest-util": "^24.9.0", - "string-length": "^2.0.0" - } - }, - "jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "jsdom": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", - "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", - "requires": { - "abab": "^2.0.0", - "acorn": "^5.5.3", - "acorn-globals": "^4.1.0", - "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": "^1.0.0", - "data-urls": "^1.0.0", - "domexception": "^1.0.1", - "escodegen": "^1.9.1", - "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.3.0", - "nwsapi": "^2.0.7", - "parse5": "4.0.0", - "pn": "^1.1.0", - "request": "^2.87.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.4", - "w3c-hr-time": "^1.0.1", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.1", - "ws": "^5.2.0", - "xml-name-validator": "^3.0.0" - } - }, - "jsencrypt": { - "version": "3.0.0-rc.1", - "resolved": "http://build-nexus.crto.in/repository/npm/jsencrypt/-/jsencrypt-3.0.0-rc.1.tgz", - "integrity": "sha512-gcvGaqerlUJy1Kq6tNgPYteVEoWNemu+9hBe2CdsCIz4rVcwjoTQ72iD1W76/PRMlnkzG0yVh7nwOOMOOUfKmg==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "jsmin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/jsmin/-/jsmin-1.0.1.tgz", - "integrity": "sha1-570NzWSWw79IYyNb9GGj2YqjuYw=" - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "json-loader": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", - "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", - "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", - "requires": { - "minimist": "^1.2.0" - } - }, - "jsonfile": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.0.1.tgz", - "integrity": "sha1-6l7+QLg2kLmGZ2FKc5L8YOhCwN0=", - "dev": true - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "just-clone": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/just-clone/-/just-clone-1.0.2.tgz", - "integrity": "sha1-v7P672WqEqMWBYcSlFwyb9jwFDQ=" - }, - "just-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", - "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=" - }, - "just-extend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", - "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", - "dev": true - }, - "jxLoader": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jxLoader/-/jxLoader-0.1.1.tgz", - "integrity": "sha1-ATTqUUTlM7WU/B/yX/GU4jXFPs0=", - "requires": { - "js-yaml": "0.3.x", - "moo-server": "1.3.x", - "promised-io": "*", - "walker": "1.x" - }, - "dependencies": { - "js-yaml": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-0.3.7.tgz", - "integrity": "sha1-1znY7oZGHlSzVNan19HyrZoWf2I=" - } - } - }, - "karma": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/karma/-/karma-3.1.4.tgz", - "integrity": "sha512-31Vo8Qr5glN+dZEVIpnPCxEGleqE0EY6CtC2X9TagRV3rRQ3SNrvfhddICkJgUK3AgqpeKSZau03QumTGhGoSw==", - "dev": true, - "requires": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "chokidar": "^2.0.3", - "colors": "^1.1.0", - "combine-lists": "^1.0.0", - "connect": "^3.6.0", - "core-js": "^2.2.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "expand-braces": "^0.1.1", - "flatted": "^2.0.0", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^4.17.5", - "log4js": "^3.0.0", - "mime": "^2.3.1", - "minimatch": "^3.0.2", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", - "socket.io": "2.1.1", - "source-map": "^0.6.1", - "tmp": "0.0.33", - "useragent": "2.3.0" - }, - "dependencies": { - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "karma-babel-preprocessor": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/karma-babel-preprocessor/-/karma-babel-preprocessor-6.0.1.tgz", - "integrity": "sha1-euHT5klQ2+EfQht0BAqwj7WmbCE=", - "dev": true, - "requires": { - "babel-core": "^6.0.0" - } - }, - "karma-browserstack-launcher": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/karma-browserstack-launcher/-/karma-browserstack-launcher-1.5.1.tgz", - "integrity": "sha512-zt9Ukow5A9WZHZXCFVO/h5kRsAdaZYeMNJK9Uan8v42amQXt3B/DZVxl24NCcAIxufKjW13UWd9iJ9knG9OCYw==", - "dev": true, - "requires": { - "browserstack": "~1.5.1", - "browserstack-local": "^1.3.7", - "q": "~1.5.0" - } - }, - "karma-chai": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", - "integrity": "sha1-vuWtQEAFF4Ea40u5RfdikJEIt5o=", - "dev": true - }, - "karma-chrome-launcher": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", - "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", - "dev": true, - "requires": { - "fs-access": "^1.0.0", - "which": "^1.2.1" - } - }, - "karma-coverage-istanbul-reporter": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-1.4.3.tgz", - "integrity": "sha1-O13/RmT6W41RlrmInj9hwforgNk=", - "dev": true, - "requires": { - "istanbul-api": "^1.3.1", - "minimatch": "^3.0.4" - } - }, - "karma-es5-shim": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/karma-es5-shim/-/karma-es5-shim-0.0.4.tgz", - "integrity": "sha1-zdADM8znfC5M4D46yT8vjs0fuVI=", - "dev": true, - "requires": { - "es5-shim": "^4.0.5" - } - }, - "karma-firefox-launcher": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.2.0.tgz", - "integrity": "sha512-j9Zp8M8+VLq1nI/5xZGfzeaEPtGQ/vk3G+Y8vpmFWLvKLNZ2TDjD6cu2dUu7lDbu1HXNgatsAX4jgCZTkR9qhQ==", - "dev": true, - "requires": { - "is-wsl": "^2.1.0" - }, - "dependencies": { - "is-wsl": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz", - "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", - "dev": true - } - } - }, - "karma-ie-launcher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/karma-ie-launcher/-/karma-ie-launcher-1.0.0.tgz", - "integrity": "sha1-SXmGhCxJAZA0bNifVJTKmDDG1Zw=", - "dev": true, - "requires": { - "lodash": "^4.6.1" - } - }, - "karma-mocha": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz", - "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=", - "dev": true, - "requires": { - "minimist": "1.2.0" - } - }, - "karma-mocha-reporter": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", - "integrity": "sha1-FRIAlejtgZGG5HoLAS8810GJVWA=", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "log-symbols": "^2.1.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "karma-opera-launcher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/karma-opera-launcher/-/karma-opera-launcher-1.0.0.tgz", - "integrity": "sha1-+lFihTGh0L6EstjcDX7iCfyP+Ro=", - "dev": true - }, - "karma-safari-launcher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/karma-safari-launcher/-/karma-safari-launcher-1.0.0.tgz", - "integrity": "sha1-lpgqLMR9BmquccVTursoMZEVos4=", - "dev": true - }, - "karma-script-launcher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/karma-script-launcher/-/karma-script-launcher-1.0.0.tgz", - "integrity": "sha1-zQF8TeXvCeWp2nkydhdhCN1LVC0=", - "dev": true - }, - "karma-sinon": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/karma-sinon/-/karma-sinon-1.0.5.tgz", - "integrity": "sha1-TjRD8oMP3s/2JNN0cWPxIX2qKpo=", - "dev": true - }, - "karma-sourcemap-loader": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz", - "integrity": "sha1-kTIsd/jxPUb+0GKwQuEAnUxFBdg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2" - } - }, - "karma-spec-reporter": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.31.tgz", - "integrity": "sha1-SDDccUihVcfXoYbmMjOaDYD63sM=", - "dev": true, - "requires": { - "colors": "^1.1.2" - } - }, - "karma-webpack": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-3.0.5.tgz", - "integrity": "sha512-nRudGJWstvVuA6Tbju9tyGUfXTtI1UXMXoRHVmM2/78D0q6s/Ye2IC157PKNDC15PWFGR0mVIRtWLAdcfsRJoA==", - "dev": true, - "requires": { - "async": "^2.0.0", - "babel-runtime": "^6.0.0", - "loader-utils": "^1.0.0", - "lodash": "^4.0.0", - "source-map": "^0.5.6", - "webpack-dev-middleware": "^2.0.6" - }, - "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - } - } - }, - "kebab-case": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/kebab-case/-/kebab-case-1.0.0.tgz", - "integrity": "sha1-P55JkK3K0MaGwOcB92RYaPdfkes=", - "dev": true - }, - "keyv": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", - "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" - }, - "kuler": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", - "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==", - "requires": { - "colornames": "^1.1.1" - } - }, - "last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", - "requires": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "requires": { - "readable-stream": "^2.0.5" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "lcov-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", - "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", - "dev": true - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", - "requires": { - "flush-write-stream": "^1.0.2" - } - }, - "left-pad": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", - "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "requires": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - } - }, - "livereload-js": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", - "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basetostring": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", - "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", - "dev": true - }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", - "dev": true - }, - "lodash._escapehtmlchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", - "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=", - "dev": true, - "requires": { - "lodash._htmlescapes": "~2.4.1" - } - }, - "lodash._escapestringchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", - "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._htmlescapes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", - "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "lodash._isnative": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", - "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=", - "dev": true - }, - "lodash._objecttypes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", - "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", - "dev": true - }, - "lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", - "dev": true - }, - "lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", - "dev": true - }, - "lodash._reinterpolate": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", - "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", - "dev": true - }, - "lodash._reunescapedhtml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", - "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=", - "dev": true, - "requires": { - "lodash._htmlescapes": "~2.4.1", - "lodash.keys": "~2.4.1" - } - }, - "lodash._root": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", - "dev": true - }, - "lodash._shimkeys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", - "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=", - "dev": true, - "requires": { - "lodash._objecttypes": "~2.4.1" - } - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", - "dev": true - }, - "lodash.defaults": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", - "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=", - "dev": true, - "requires": { - "lodash._objecttypes": "~2.4.1", - "lodash.keys": "~2.4.1" - } - }, - "lodash.escape": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", - "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", - "dev": true, - "requires": { - "lodash._escapehtmlchar": "~2.4.1", - "lodash._reunescapedhtml": "~2.4.1", - "lodash.keys": "~2.4.1" - } - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.isobject": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", - "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", - "dev": true, - "requires": { - "lodash._objecttypes": "~2.4.1" - } - }, - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "~2.4.1", - "lodash._shimkeys": "~2.4.1", - "lodash.isobject": "~2.4.1" - } - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" - }, - "lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", - "dev": true - }, - "lodash.some": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", - "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", - "dev": true - }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, - "lodash.template": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", - "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", - "dev": true, - "requires": { - "lodash._escapestringchar": "~2.4.1", - "lodash._reinterpolate": "~2.4.1", - "lodash.defaults": "~2.4.1", - "lodash.escape": "~2.4.1", - "lodash.keys": "~2.4.1", - "lodash.templatesettings": "~2.4.1", - "lodash.values": "~2.4.1" - } - }, - "lodash.templatesettings": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", - "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", - "dev": true, - "requires": { - "lodash._reinterpolate": "~2.4.1", - "lodash.escape": "~2.4.1" - } - }, - "lodash.values": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", - "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=", - "dev": true, - "requires": { - "lodash.keys": "~2.4.1" - } - }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "log4js": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.6.tgz", - "integrity": "sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ==", - "dev": true, - "requires": { - "circular-json": "^0.5.5", - "date-format": "^1.2.0", - "debug": "^3.1.0", - "rfdc": "^1.1.2", - "streamroller": "0.7.0" - }, - "dependencies": { - "circular-json": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", - "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "logform": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz", - "integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==", - "requires": { - "colors": "^1.2.1", - "fast-safe-stringify": "^2.0.4", - "fecha": "^2.3.3", - "ms": "^2.1.1", - "triple-beam": "^1.3.0" - } - }, - "loglevelnext": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz", - "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==", - "dev": true, - "requires": { - "es6-symbol": "^3.1.1", - "object.assign": "^4.1.0" - } - }, - "lolex": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", - "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", - "dev": true - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true - }, - "longest-streak": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.3.tgz", - "integrity": "sha512-9lz5IVdpwsKLMzQi0MQ+oD9EA0mIGcWYP7jXMTZVXP8D42PwuAk+M/HBFYQoxt1G5OR8m7aSIgb1UymfWGBWEw==", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", - "dev": true, - "requires": { - "es5-ext": "~0.10.2" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==" - }, - "make-error-cause": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", - "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=", - "requires": { - "make-error": "^1.2.0" - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "requires": { - "kind-of": "^6.0.2" - } - }, - "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "requires": { - "tmpl": "1.0.x" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" - } - }, - "markdown-escapes": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.3.tgz", - "integrity": "sha512-XUi5HJhhV5R74k8/0H2oCbCiYf/u4cO/rX8tnGkRvrqhsr5BRNU6Mg0yt/8UIx1iIS8220BNJsDb7XnILhLepw==", - "dev": true - }, - "markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", - "requires": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "dependencies": { - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mdast-util-compact": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", - "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", - "dev": true, - "requires": { - "unist-util-visit": "^1.1.0" - } - }, - "mdast-util-definitions": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-1.2.5.tgz", - "integrity": "sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA==", - "dev": true, - "requires": { - "unist-util-visit": "^1.0.0" - } - }, - "mdast-util-inject": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-inject/-/mdast-util-inject-1.1.0.tgz", - "integrity": "sha1-2wa4tYW+lZotzS+H9HK6m3VvNnU=", - "dev": true, - "requires": { - "mdast-util-to-string": "^1.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "foreachasync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz", + "integrity": "sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "fork-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz", + "integrity": "sha1-24Sfznf2cIpfjzhq5TOgkHtUrnA=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs-extra": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.6.4.tgz", + "integrity": "sha1-9G8MdbeEH40gCzNIzU1pHVoJnRU=", + "dev": true, + "requires": { + "jsonfile": "~1.0.1", + "mkdirp": "0.3.x", + "ncp": "~0.4.2", + "rimraf": "~2.2.0" + }, + "dependencies": { + "mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "dev": true + }, + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true } - }, - "mdast-util-to-hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-3.0.4.tgz", - "integrity": "sha512-/eIbly2YmyVgpJNo+bFLLMCI1XgolO/Ffowhf+pHDq3X4/V6FntC9sGQCDLM147eTS+uSXv5dRzJyFn+o0tazA==", - "dev": true, - "requires": { - "collapse-white-space": "^1.0.0", - "detab": "^2.0.0", - "mdast-util-definitions": "^1.2.0", - "mdurl": "^1.0.1", - "trim": "0.0.1", - "trim-lines": "^1.0.0", - "unist-builder": "^1.0.1", - "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.0", - "xtend": "^4.0.1" + } + }, + "fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + } + }, + "fs.extra": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fs.extra/-/fs.extra-1.3.2.tgz", + "integrity": "sha1-3QI/kwE77iRTHxszUUw3sg/ZM0k=", + "dev": true, + "requires": { + "fs-extra": "~0.6.1", + "mkdirp": "~0.3.5", + "walk": "^2.3.9" + }, + "dependencies": { + "mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "dev": true } - }, - "mdast-util-to-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.7.tgz", - "integrity": "sha512-P+gdtssCoHOX+eJUrrC30Sixqao86ZPlVjR5NEAoy0U79Pfxb1Y0Gntei0+GrnQD4T04X9xA8tcugp90cSmNow==", - "dev": true - }, - "mdast-util-toc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-3.1.0.tgz", - "integrity": "sha512-Za0hqL1PqWrvxGtA/3NH9D5nhGAUS9grMM4obEAz5+zsk1RIw/vWUchkaoDLNdrwk05A0CSC5eEXng36/1qE5w==", - "dev": true, - "requires": { - "github-slugger": "^1.2.1", - "mdast-util-to-string": "^1.0.5", - "unist-util-is": "^2.1.2", - "unist-util-visit": "^1.1.0" - }, - "dependencies": { - "emoji-regex": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", - "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=", - "dev": true - }, - "github-slugger": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.1.tgz", - "integrity": "sha512-SsZUjg/P03KPzQBt7OxJPasGw6NRO5uOgiZ5RGXVud5iSIZ0eNZeNp5rTwCxtavrRUa/A77j8mePVc5lEvk0KQ==", - "dev": true, - "requires": { - "emoji-regex": ">=6.0.0 <=6.1.1" - } - }, - "unist-util-is": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", - "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==", - "dev": true + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", + "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } - } - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "memoizee": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", - "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.45", - "es6-weak-map": "^2.0.2", - "event-emitter": "^0.3.5", - "is-promise": "^2.1", - "lru-queue": "0.1", - "next-tick": "1", - "timers-ext": "^0.1.5" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", - "dev": true - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" - }, - "mime-types": { - "version": "2.1.25", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", - "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", - "requires": { - "mime-db": "1.42.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } + }, + "chownr": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" } - } - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "dependencies": { - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } - } - }, - "module-deps-sortable": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/module-deps-sortable/-/module-deps-sortable-4.0.6.tgz", - "integrity": "sha1-ElGkuixEqS32mJvQKdoSGk8hCbA=", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "browser-resolve": "^1.7.0", - "concat-stream": "~1.5.0", - "defined": "^1.0.0", - "detective": "^4.0.0", - "duplexer2": "^0.1.2", - "inherits": "^2.0.1", - "parents": "^1.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.1.3", - "stream-combiner2": "^1.1.1", - "subarg": "^1.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "concat-stream": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", - "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "~2.0.0", - "typedarray": "~0.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - } - } - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } - } - }, - "moo-server": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/moo-server/-/moo-server-1.3.0.tgz", - "integrity": "sha1-XceVaVZaENbv7VQ5SR5p0jkuWPE=" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", - "dev": true, - "requires": { - "duplexer2": "0.0.2" - }, - "dependencies": { - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "dev": true, - "requires": { - "readable-stream": "~1.1.9" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" } - } - }, - "mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==" - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "ncp": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", - "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=", - "dev": true - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "nise": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.2.tgz", - "integrity": "sha512-/6RhOUlicRCbE9s+94qCUsyE+pKlVJ5AhIv+jEE7ESKwnbXqulKZ1FYU+XAtHHWE9TinYvAxDUJAb912PwPoWA==", - "dev": true, - "requires": { - "@sinonjs/formatio": "^3.2.1", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "lolex": "^4.1.0", - "path-to-regexp": "^1.7.0" - }, - "dependencies": { - "@sinonjs/formatio": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", - "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "lolex": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz", - "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==", - "dev": true - }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "requires": { - "isarray": "0.0.1" - } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" } - } - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" } - } - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" - }, - "node-notifier": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", - "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", - "requires": { - "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", - "shellwords": "^0.1.1", - "which": "^1.3.0" - } - }, - "node-releases": { - "version": "1.1.42", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.42.tgz", - "integrity": "sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA==", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" } - } - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } - }, - "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "requires": { - "once": "^1.3.2" - } - }, - "npm-install-package": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/npm-install-package/-/npm-install-package-2.1.0.tgz", - "integrity": "sha1-1+/jz816sAYUuJbqUxGdyaslkSU=", - "dev": true - }, - "npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "null-check": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", - "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" } - } - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - }, - "object-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", - "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - }, - "dependencies": { - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true } } - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "requires": { - "isobject": "^3.0.1" - } - }, - "object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.values": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", - "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "one-time": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", - "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "opener": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", - "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", - "dev": true - }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" } - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", - "requires": { - "readable-stream": "^2.0.1" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" } - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-cancelable": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", - "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", - "dev": true - }, - "p-each-series": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", - "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", - "requires": { - "p-reduce": "^1.0.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-is-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", - "dev": true - }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-reduce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", - "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=" - }, - "p-timeout": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", - "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", - "dev": true - }, - "parents": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", - "dev": true, - "requires": { - "path-platform": "~0.11.15" - } - }, - "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-domain": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/parse-domain/-/parse-domain-2.3.4.tgz", - "integrity": "sha512-LlFJJVTry4DD3Xa76CsVNP6MIu3JZ8GXd5HEEp38KSDGBCVsnccagAJ5YLy7uEEabvwtauQEQPcvXWgUGkJbMA==", - "dev": true, - "requires": { - "got": "^8.3.2", - "jest": "^24.9.0", - "mkdirp": "^0.5.1", - "npm-run-all": "^4.1.5" - } - }, - "parse-entities": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", - "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", - "dev": true, - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, - "parse-git-config": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-0.2.0.tgz", - "integrity": "sha1-Jygz/dFf6hRvt10zbSNrljtv9wY=", - "dev": true, - "requires": { - "ini": "^1.3.3" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" } - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==" - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" - }, - "parse-path": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-3.0.4.tgz", - "integrity": "sha512-wP70vtwv2DyrM2YoA7ZHVv4zIXa4P7dGgHlj+VwyXNDduLLVJ7NMY1zsFxjUUJ3DAwJLupGb1H5gMDDiNlJaxw==", - "dev": true, - "requires": { - "is-ssh": "^1.3.0", - "protocols": "^1.4.0" - } - }, - "parse-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-3.0.2.tgz", - "integrity": "sha1-YCeHpwY6eV1yuGcxl1BecvYGEL4=", - "dev": true, - "requires": { - "is-ssh": "^1.3.0", - "normalize-url": "^1.9.1", - "parse-path": "^3.0.1", - "protocols": "^1.4.0" - } - }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-platform": { - "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true } - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "dev": true, - "requires": { - "through": "~2.3" - } - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "pbkdf2-compat": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz", - "integrity": "sha1-tuDI+plJTZTgURV1gCpZpcFC8og=", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pidtree": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz", - "integrity": "sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "requires": { - "find-up": "^3.0.0" - } - }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" + } + }, + "fun-hooks": { + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/fun-hooks/-/fun-hooks-0.9.8.tgz", + "integrity": "sha512-FZUHodONJBOCCETXnHTSvqnz+pLZiN2ZqbOZsjXIqJRI8AbvTqOJzDTEeMfPzFf8rPuSZnD5EPcbl7yZsEQ/NA==", + "requires": { + "typescript-tuple": "^2.2.1" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "requires": { + "globule": "^1.0.0" + } + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "git-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-2.1.0.tgz", + "integrity": "sha512-MJgwfcSd9qxgDyEYpRU/CDxNpUadrK80JHuEQDG4Urn0m7tpSOgCBrtiSIa9S9KH8Tbuo/TN8SSQmJBvsw1HkA==", + "dev": true, + "requires": { + "is-ssh": "^1.3.0", + "parse-url": "^3.0.2" + } + }, + "git-url-parse": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-8.3.1.tgz", + "integrity": "sha512-r/FxXIdfgdSO+V2zl4ZK1JGYkHT9nqVRSzom5WsYPLg3XzeBeKPl3R/6X9E9ZJRx/sE/dXwXtfl+Zp7YL8ktWQ==", + "dev": true, + "requires": { + "git-up": "^2.0.0", + "parse-domain": "^2.0.0" + } + }, + "github-slugger": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.0.tgz", + "integrity": "sha512-wIaa75k1vZhyPm9yWrD08A5Xnx/V+RmzGrpjQuLemGKSb77Qukiaei58Bogrl/LZSADDfPzKJX8jhLs4CRTl7Q==", + "dev": true, + "requires": { + "emoji-regex": ">=6.0.0 <=6.1.1" + }, + "dependencies": { + "emoji-regex": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", + "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=", + "dev": true } - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", - "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" } - } - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promised-io": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/promised-io/-/promised-io-0.3.5.tgz", - "integrity": "sha1-StIXuzZYvKrplGsXqGaOzYUeE1Y=" - }, - "prompts": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.0.tgz", - "integrity": "sha512-NfbbPPg/74fT7wk2XYQ7hAIp9zJyZp5Fu19iRbORqqy1BhtrkZ0fPafBU+7bmn8ie69DpT0R6QpJIN2oisYjJg==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.3" - } - }, - "property-information": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-3.2.0.tgz", - "integrity": "sha1-/RSDyPusYYCPX+NZ52k6H0ilgzE=", - "dev": true - }, - "protocols": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.7.tgz", - "integrity": "sha512-Fx65lf9/YDn3hUX08XUc0J8rSux36rEsyiv21ZGUC1mOyeM3lTRpZLcrm8aAolzS4itwVfm7TAPyxC2E5zd6xg==", - "dev": true - }, - "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "ps-tree": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.1.tgz", - "integrity": "sha512-kef7fYYSKVqQffmzTMsVcUD1ObNJMp8sNSmHGlGKsZQyL/ht9MZKk86u0Rd1NhpTOAuhqwKCLLpktwkqz+MF8A==", - "dev": true, - "requires": { - "event-stream": "=3.3.4" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz", - "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" } } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true - }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dev": true, - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", - "dev": true - }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" } } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + } + }, + "glob-watcher": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz", + "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-done": "^1.2.0", + "chokidar": "^2.0.0", + "is-negated-glob": "^1.0.0", + "just-debounce": "^1.0.0", + "object.defaults": "^1.1.0" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globals-docs": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/globals-docs/-/globals-docs-2.4.1.tgz", + "integrity": "sha512-qpPnUKkWnz8NESjrCvnlGklsgiQzlq+rcCxoG5uNQ+dNA7cFMCmn231slLAwS2N/PlkzZ3COL8CcS10jXmLHqg==", + "dev": true + }, + "globule": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz", + "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==", + "dev": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.12", + "minimatch": "~3.0.2" + } + }, + "glogg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", + "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "dev": true, + "requires": { + "sparkles": "^1.0.0" + } + }, + "got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true + }, + "gulp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", + "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", + "dev": true, + "requires": { + "glob-watcher": "^5.0.3", + "gulp-cli": "^2.2.0", + "undertaker": "^1.2.1", + "vinyl-fs": "^3.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "realpath-native": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", - "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", - "requires": { - "util.promisify": "^1.0.0" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "requires": { - "resolve": "^1.1.6" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", - "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", - "dev": true, - "requires": { - "regenerate": "^1.4.0" - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - }, - "regenerator-transform": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", - "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", - "dev": true, - "requires": { - "private": "^0.1.6" - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp.prototype.flags": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", - "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", - "requires": { - "define-properties": "^1.1.2" - } - }, - "regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", - "dev": true - }, - "regexpu-core": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", - "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", - "dev": true, - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.1.0", - "regjsgen": "^0.5.0", - "regjsparser": "^0.6.0", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.1.0" - } - }, - "regjsgen": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", - "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", - "dev": true - }, - "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } - } - }, - "remark": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/remark/-/remark-9.0.0.tgz", - "integrity": "sha512-amw8rGdD5lHbMEakiEsllmkdBP+/KpjW/PRK6NSGPZKCQowh0BT4IWXDAkRMyG3SB9dKPXWMviFjNusXzXNn3A==", - "dev": true, - "requires": { - "remark-parse": "^5.0.0", - "remark-stringify": "^5.0.0", - "unified": "^6.0.0" - } - }, - "remark-html": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-7.0.0.tgz", - "integrity": "sha512-jqRzkZXCkM12gIY2ibMLTW41m7rfanliMTVQCFTezHJFsbH00YaTox/BX4gU+f/zCdzfhFJONtebFByvpMv37w==", - "dev": true, - "requires": { - "hast-util-sanitize": "^1.0.0", - "hast-util-to-html": "^3.0.0", - "mdast-util-to-hast": "^3.0.0", - "xtend": "^4.0.1" - } - }, - "remark-parse": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", - "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", - "dev": true, - "requires": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.1.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - } - }, - "remark-reference-links": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/remark-reference-links/-/remark-reference-links-4.0.4.tgz", - "integrity": "sha512-+2X8hwSQqxG4tvjYZNrTcEC+bXp8shQvwRGG6J/rnFTvBoU4G0BBviZoqKGZizLh/DG+0gSYhiDDWCqyxXW1iQ==", - "dev": true, - "requires": { - "unist-util-visit": "^1.0.0" - } - }, - "remark-slug": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-5.1.2.tgz", - "integrity": "sha512-DWX+Kd9iKycqyD+/B+gEFO3jjnt7Yg1O05lygYSNTe5i5PIxxxPjp5qPBDxPIzp5wreF7+1ROCwRgjEcqmzr3A==", - "dev": true, - "requires": { - "github-slugger": "^1.0.0", - "mdast-util-to-string": "^1.0.0", - "unist-util-visit": "^1.0.0" - } - }, - "remark-stringify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-5.0.0.tgz", - "integrity": "sha512-Ws5MdA69ftqQ/yhRF9XhVV29mhxbfGhbz0Rx5bQH+oJcNhhSM6nCu1EpLod+DjrFGrU0BMPs+czVmJZU7xiS7w==", - "dev": true, - "requires": { - "ccount": "^1.0.0", - "is-alphanumeric": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "longest-streak": "^2.0.1", - "markdown-escapes": "^1.0.0", - "markdown-table": "^1.1.0", - "mdast-util-compact": "^1.0.0", - "parse-entities": "^1.0.2", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "stringify-entities": "^1.0.1", - "unherit": "^1.0.4", - "xtend": "^4.0.1" - } - }, - "remark-toc": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/remark-toc/-/remark-toc-5.1.1.tgz", - "integrity": "sha512-vCPW4YOsm2CfyuScdktM9KDnJXVHJsd/ZeRtst+dnBU3B3KKvt8bc+bs5syJjyptAHfqo7H+5Uhz+2blWBfwow==", - "dev": true, - "requires": { - "mdast-util-toc": "^3.0.0", - "remark-slug": "^5.0.0" - } - }, - "remote-origin-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/remote-origin-url/-/remote-origin-url-0.4.0.tgz", - "integrity": "sha1-TT4pAvNOLTfRwmPYdxC3frQIajA=", - "dev": true, - "requires": { - "parse-git-config": "^0.2.0" - } - }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" - }, - "replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", - "requires": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - } - }, - "replacestream": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz", - "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.3", - "object-assign": "^4.0.1", - "readable-stream": "^2.0.2" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "gulp-cli": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz", + "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==", + "dev": true, + "requires": { + "ansi-colors": "^1.0.1", + "archy": "^1.0.0", + "array-sort": "^1.0.0", + "color-support": "^1.1.3", + "concat-stream": "^1.6.0", + "copy-props": "^2.0.1", + "fancy-log": "^1.3.2", + "gulplog": "^1.0.0", + "interpret": "^1.1.0", + "isobject": "^3.0.1", + "liftoff": "^3.1.0", + "matchdep": "^2.0.0", + "mute-stdout": "^1.0.0", + "pretty-hrtime": "^1.0.0", + "replace-homedir": "^1.0.0", + "semver-greatest-satisfied-range": "^1.1.0", + "v8flags": "^3.0.1", + "yargs": "^7.1.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } - } - }, - "request-promise": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz", - "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==", - "dev": true, - "requires": { - "bluebird": "^3.5.0", - "request-promise-core": "1.1.3", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", - "requires": { - "lodash": "^4.17.15" - } - }, - "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", - "requires": { - "request-promise-core": "1.1.3", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" } - } - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", - "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "requires": { - "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.0" + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "requires": { + "camelcase": "^3.0.0" } } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", - "requires": { - "value-or-function": "^3.0.0" + } + }, + "gulp-clean": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/gulp-clean/-/gulp-clean-0.3.2.tgz", + "integrity": "sha1-o0fUc6zqQBgvk1WHpFGUFnGSgQI=", + "dev": true, + "requires": { + "gulp-util": "^2.2.14", + "rimraf": "^2.2.8", + "through2": "^0.4.2" + }, + "dependencies": { + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "dev": true + }, + "ansi-styles": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", + "dev": true + }, + "chalk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "dev": true, + "requires": { + "ansi-styles": "^1.1.0", + "escape-string-regexp": "^1.0.0", + "has-ansi": "^0.1.0", + "strip-ansi": "^0.3.0", + "supports-color": "^0.2.0" + } + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "gulp-util": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", + "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", + "dev": true, + "requires": { + "chalk": "^0.5.0", + "dateformat": "^1.0.7-1.2.3", + "lodash._reinterpolate": "^2.4.1", + "lodash.template": "^2.4.1", + "minimist": "^0.2.0", + "multipipe": "^0.1.0", + "through2": "^0.5.0", + "vinyl": "^0.2.1" + }, + "dependencies": { + "through2": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", + "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", + "dev": true, + "requires": { + "readable-stream": "~1.0.17", + "xtend": "~3.0.0" + } + } + } + }, + "has-ansi": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", + "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", + "dev": true, + "requires": { + "ansi-regex": "^0.2.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "minimist": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", + "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", + "dev": true + }, + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "strip-ansi": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", + "dev": true, + "requires": { + "ansi-regex": "^0.2.1" + } + }, + "supports-color": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", + "dev": true + }, + "through2": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", + "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", + "dev": true, + "requires": { + "readable-stream": "~1.0.17", + "xtend": "~2.1.1" + }, + "dependencies": { + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "vinyl": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", + "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", + "dev": true, + "requires": { + "clone-stats": "~0.0.1" + } + }, + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", + "dev": true } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" + } + }, + "gulp-concat": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", + "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", + "dev": true, + "requires": { + "concat-with-sourcemaps": "^1.0.0", + "through2": "^2.0.0", + "vinyl": "^2.0.0" + } + }, + "gulp-connect": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/gulp-connect/-/gulp-connect-5.7.0.tgz", + "integrity": "sha512-8tRcC6wgXMLakpPw9M7GRJIhxkYdgZsXwn7n56BA2bQYGLR9NOPhMzx7js+qYDy6vhNkbApGKURjAw1FjY4pNA==", + "dev": true, + "requires": { + "ansi-colors": "^2.0.5", + "connect": "^3.6.6", + "connect-livereload": "^0.6.0", + "fancy-log": "^1.3.2", + "map-stream": "^0.0.7", + "send": "^0.16.2", + "serve-index": "^1.9.1", + "serve-static": "^1.13.2", + "tiny-lr": "^1.1.1" + }, + "dependencies": { + "ansi-colors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-2.0.5.tgz", + "integrity": "sha512-yAdfUZ+c2wetVNIFsNRn44THW+Lty6S5TwMpUfLA/UaGhiXbBv/F8E60/1hMLd0cnF/CDoWH8vzVaI5bAcHCjw==", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" + } + }, + "gulp-eslint": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-4.0.2.tgz", + "integrity": "sha512-fcFUQzFsN6dJ6KZlG+qPOEkqfcevRUXgztkYCvhNvJeSvOicC8ucutN4qR/ID8LmNZx9YPIkBzazTNnVvbh8wg==", + "dev": true, + "requires": { + "eslint": "^4.0.0", + "fancy-log": "^1.3.2", + "plugin-error": "^1.0.0" + } + }, + "gulp-footer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/gulp-footer/-/gulp-footer-2.0.2.tgz", + "integrity": "sha512-HsG5VOgKHFRqZXnHGI6oGhPDg70p9pobM+dYOnjBZVLMQUHzLG6bfaPNRJ7XG707E+vWO3TfN0CND9UrYhk94g==", + "dev": true, + "requires": { + "lodash._reescape": "^3.0.0", + "lodash._reevaluate": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.template": "^3.6.2", + "map-stream": "0.0.7" + }, + "dependencies": { + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, + "requires": { + "lodash._root": "^3.0.0" + } + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash._basetostring": "^3.0.0", + "lodash._basevalues": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0", + "lodash.keys": "^3.0.0", + "lodash.restparam": "^3.0.0", + "lodash.templatesettings": "^3.0.0" + } + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0" + } } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, - "rfdc": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz", - "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==", - "dev": true - }, - "rgb2hex": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.10.tgz", - "integrity": "sha512-vKz+kzolWbL3rke/xeTE2+6vHmZnNxGyDnaVW4OckntAIcc7DcZzWkQSfxMDwqHS8vhgySnIFyBUH7lIk6PxvQ==", - "dev": true - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "requires": { - "align-text": "^0.1.1" + } + }, + "gulp-header": { + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-1.8.12.tgz", + "integrity": "sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==", + "dev": true, + "requires": { + "concat-with-sourcemaps": "*", + "lodash.template": "^4.4.0", + "through2": "^2.0.0" + }, + "dependencies": { + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0" + } } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" + } + }, + "gulp-if": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/gulp-if/-/gulp-if-2.0.2.tgz", + "integrity": "sha1-pJe351cwBQQcqivIt92jyARE1ik=", + "dev": true, + "requires": { + "gulp-match": "^1.0.3", + "ternary-stream": "^2.0.1", + "through2": "^2.0.1" + } + }, + "gulp-js-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gulp-js-escape/-/gulp-js-escape-1.0.1.tgz", + "integrity": "sha1-HNRF+9AJ4Np2lZoDp/SbNWav+Gg=", + "dev": true, + "requires": { + "through2": "^0.6.3" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + } + }, + "gulp-match": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gulp-match/-/gulp-match-1.1.0.tgz", + "integrity": "sha512-DlyVxa1Gj24DitY2OjEsS+X6tDpretuxD6wTfhXE/Rw2hweqc1f6D/XtsJmoiCwLWfXgR87W9ozEityPCVzGtQ==", + "dev": true, + "requires": { + "minimatch": "^3.0.3" + } + }, + "gulp-replace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.0.0.tgz", + "integrity": "sha512-lgdmrFSI1SdhNMXZQbrC75MOl1UjYWlOWNbNRnz+F/KHmgxt3l6XstBoAYIdadwETFyG/6i+vWUSCawdC3pqOw==", + "dev": true, + "requires": { + "istextorbinary": "2.2.1", + "readable-stream": "^2.0.1", + "replacestream": "^4.0.0" + } + }, + "gulp-shell": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/gulp-shell/-/gulp-shell-0.5.2.tgz", + "integrity": "sha1-pJWcoGUa0ce7/nCy0K27tOGuqY0=", + "dev": true, + "requires": { + "async": "^1.5.0", + "gulp-util": "^3.0.7", + "lodash": "^4.0.0", + "through2": "^2.0.0" + } + }, + "gulp-sourcemaps": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.5.tgz", + "integrity": "sha512-SYLBRzPTew8T5Suh2U8jCSDKY+4NARua4aqjj8HOysBh2tSgT9u4jc1FYirAdPx1akUxxDeK++fqw6Jg0LkQRg==", + "dev": true, + "requires": { + "@gulp-sourcemaps/identity-map": "1.X", + "@gulp-sourcemaps/map-sources": "1.X", + "acorn": "5.X", + "convert-source-map": "1.X", + "css": "2.X", + "debug-fabulous": "1.X", + "detect-newline": "2.X", + "graceful-fs": "4.X", + "source-map": "~0.6.0", + "strip-bom-string": "1.X", + "through2": "2.X" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==" - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" + } + }, + "gulp-uglify": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz", + "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "extend-shallow": "^3.0.2", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "isobject": "^3.0.1", + "make-error-cause": "^1.1.1", + "safe-buffer": "^5.1.2", + "through2": "^2.0.0", + "uglify-js": "^3.0.5", + "vinyl-sourcemaps-apply": "^0.2.0" + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, + "requires": { + "array-differ": "^1.0.0", + "array-uniq": "^1.0.2", + "beeper": "^1.0.0", + "chalk": "^1.0.0", + "dateformat": "^2.0.0", + "fancy-log": "^1.1.0", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "lodash._reescape": "^3.0.0", + "lodash._reevaluate": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.template": "^3.0.0", + "minimist": "^1.1.0", + "multipipe": "^0.1.2", + "object-assign": "^3.0.0", + "replace-ext": "0.0.1", + "through2": "^2.0.0", + "vinyl": "^0.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "dateformat": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", + "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, + "requires": { + "lodash._root": "^3.0.0" + } + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash._basetostring": "^3.0.0", + "lodash._basevalues": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0", + "lodash.keys": "^3.0.0", + "lodash.restparam": "^3.0.0", + "lodash.templatesettings": "^3.0.0" + } + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0" + } + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true, + "requires": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + } } - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "*" + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "^1.0.0" + } + }, + "gzip-size": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", + "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "pify": "^4.0.1" + } + }, + "handlebars": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.3.tgz", + "integrity": "sha512-SRGwSYuNfx8DwHD/6InAPzD6RgeruWLT+B8e8a7gGs8FWgHzlExpTFMEq2IA6QpAfOClpKHy6+8IqTjeBCu6Kg==", + "dev": true, + "requires": { + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-json-parse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", - "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "requires": { - "ret": "~0.1.10" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", + "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "samsam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", - "dev": true - }, - "sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "requires": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", - "dev": true, - "requires": { - "ajv": "^5.0.0" + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "^1.0.0" + } + }, + "has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", - "requires": { - "sver-compat": "^1.5.0" + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hast-util-is-element": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.0.3.tgz", + "integrity": "sha512-C62CVn7jbjp89yOhhy7vrkSaB7Vk906Gtcw/Ihd+Iufnq+2pwOZjdPmpzpKLWJXPJBMDX3wXg4FqmdOayPcewA==", + "dev": true + }, + "hast-util-sanitize": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-1.3.1.tgz", + "integrity": "sha512-AIeKHuHx0Wk45nSkGVa2/ujQYTksnDl8gmmKo/mwQi7ag7IBZ8cM3nJ2G86SajbjGP/HRpud6kMkPtcM2i0Tlw==", + "dev": true, + "requires": { + "xtend": "^4.0.1" + } + }, + "hast-util-to-html": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-3.1.0.tgz", + "integrity": "sha1-iCyZhJ5AEw6ZHAQuRW1FPZXDbP8=", + "dev": true, + "requires": { + "ccount": "^1.0.0", + "comma-separated-tokens": "^1.0.1", + "hast-util-is-element": "^1.0.0", + "hast-util-whitespace": "^1.0.0", + "html-void-elements": "^1.0.0", + "kebab-case": "^1.0.0", + "property-information": "^3.1.0", + "space-separated-tokens": "^1.0.0", + "stringify-entities": "^1.0.1", + "unist-util-is": "^2.0.0", + "xtend": "^4.0.1" + }, + "dependencies": { + "unist-util-is": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", + "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==", + "dev": true } - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + }, + "hast-util-whitespace": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.3.tgz", + "integrity": "sha512-AlkYiLTTwPOyxZ8axq2/bCwRUPjIPBfrHkXuCR92B38b3lSdU22R5F/Z4DL6a2kxWpekWq1w6Nj48tWat6GeRA==", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "highlight.js": { + "version": "9.18.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz", + "integrity": "sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "html-escaper": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz", + "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==", + "dev": true + }, + "html-void-elements": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", + "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==", + "dev": true + }, + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-parser-js": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", + "dev": true + }, + "http-proxy": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", + "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dev": true, + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true + } + }, + "humanize-duration": { + "version": "3.15.3", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.15.3.tgz", + "integrity": "sha512-BMz6w8p3NVa6QP9wDtqUkXfwgBqDaZ5z/np0EYdoWrLqL849Onp6JWMXMhbHtuvO9jUThLN5H1ThRQ8dUWnYkA==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" } } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + } + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", + "dev": true, + "requires": { + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" + } + }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true + }, + "is-alphanumeric": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", + "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=", + "dev": true + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true - }, - "shelljs": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", - "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "requires": { - "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + }, + "is-docker": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-1.1.0.tgz", + "integrity": "sha1-8EN01O7lMQ6ajhE78UlUEeRhdqE=", + "dev": true + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true + }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" } } - }, - "sinon": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", - "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", - "dev": true, - "requires": { - "@sinonjs/formatio": "^2.0.0", - "diff": "^3.1.0", - "lodash.get": "^4.4.2", - "lolex": "^2.2.0", - "nise": "^1.2.0", - "supports-color": "^5.1.0", - "type-detect": "^4.0.5" - }, - "dependencies": { - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true + } + }, + "is-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "requires": { + "has": "^1.0.3" + } + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true + }, + "is-running": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-running/-/is-running-2.1.0.tgz", + "integrity": "sha1-MKc/9cw4VOT8JUkICen1q/jeCeA=", + "dev": true + }, + "is-ssh": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.1.tgz", + "integrity": "sha512-0eRIASHZt1E68/ixClI8bp2YK2wmBPVWEismTs6M+M099jKgrzl/3E976zIbImSIob48N2/XGe9y7ZiYdImSlg==", + "dev": true, + "requires": { + "protocols": "^1.1.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true + }, + "is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isbinaryfile": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", + "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", + "dev": true, + "requires": { + "buffer-alloc": "^1.2.0" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" } } - }, - "sisteransi": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.4.tgz", - "integrity": "sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig==", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } + } + }, + "istanbul-api": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.7.tgz", + "integrity": "sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==", + "dev": true, + "requires": { + "async": "^2.1.4", + "fileset": "^2.0.2", + "istanbul-lib-coverage": "^1.2.1", + "istanbul-lib-hook": "^1.2.2", + "istanbul-lib-instrument": "^1.10.2", + "istanbul-lib-report": "^1.1.5", + "istanbul-lib-source-maps": "^1.2.6", + "istanbul-reports": "^1.5.1", + "js-yaml": "^3.7.0", + "mkdirp": "^0.5.1", + "once": "^1.4.0" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", + "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", + "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", + "dev": true, + "requires": { + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.1", + "semver": "^5.3.0" + } + }, + "istanbul-lib-report": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz", + "integrity": "sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz", + "integrity": "sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" + } + }, + "istanbul-reports": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.5.1.tgz", + "integrity": "sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==", + "dev": true, + "requires": { + "handlebars": "^4.0.3" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" } } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } + } + }, + "istanbul-instrumenter-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.1.tgz", + "integrity": "sha512-a5SPObZgS0jB/ixaKSMdn6n/gXSrK2S6q/UfRJBT3e6gQmVjwZROTODQsYW5ZNwOu78hG62Y3fWlebaVOL0C+w==", + "dev": true, + "requires": { + "convert-source-map": "^1.5.0", + "istanbul-lib-instrument": "^1.7.3", + "loader-utils": "^1.1.0", + "schema-utils": "^0.3.0" + }, + "dependencies": { + "istanbul-lib-coverage": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", + "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", + "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", + "dev": true, + "requires": { + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.1", + "semver": "^5.3.0" } } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } + } + }, + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz", + "integrity": "sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==", + "dev": true, + "requires": { + "append-transform": "^0.4.0" + } + }, + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } - }, - "socket.io": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", - "integrity": "sha1-oGnF/qvuPmshSnW0DOBlLhz7mYA=", - "dev": true, - "requires": { - "debug": "~3.1.0", - "engine.io": "~3.2.0", - "has-binary2": "~1.0.2", - "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.1.1", - "socket.io-parser": "~3.2.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", - "dev": true, - "requires": { - "ms": "2.0.0" - } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" } } - }, - "socket.io-adapter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", - "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==", - "dev": true - }, - "socket.io-client": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", - "integrity": "sha1-3LOBA0NqtFeN2wJmOK4vIbYjZx8=", - "dev": true, - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "engine.io-client": "~3.2.0", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.2.0", - "to-array": "0.1.4" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", - "dev": true, - "requires": { - "ms": "2.0.0" - } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "socket.io-parser": { - "version": "3.2.0", - "resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", - "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true + } + }, + "istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0" + } + }, + "istextorbinary": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", + "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", + "dev": true, + "requires": { + "binaryextensions": "2", + "editions": "^1.3.3", + "textextensions": "2" + } + }, + "isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dev": true, + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, + "jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", + "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", + "dev": true, + "requires": { + "import-local": "^2.0.0", + "jest-cli": "^24.9.0" + }, + "dependencies": { + "jest-cli": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", + "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", + "dev": true, + "requires": { + "@jest/core": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "import-local": "^2.0.0", + "is-ci": "^2.0.0", + "jest-config": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "prompts": "^2.0.1", + "realpath-native": "^1.1.0", + "yargs": "^13.3.0" + } + }, + "yargs": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" } } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" + } + }, + "jest-changed-files": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", + "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "execa": "^1.0.0", + "throat": "^4.0.0" + } + }, + "jest-config": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", + "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^24.9.0", + "@jest/types": "^24.9.0", + "babel-jest": "^24.9.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^24.9.0", + "jest-environment-node": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.9.0", + "realpath-native": "^1.1.0" + } + }, + "jest-diff": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", + "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff-sequences": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" + } + }, + "jest-docblock": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", + "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", + "dev": true, + "requires": { + "detect-newline": "^2.1.0" + } + }, + "jest-each": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", + "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0" + } + }, + "jest-environment-jsdom": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", + "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0", + "jsdom": "^11.5.1" + } + }, + "jest-environment-node": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", + "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", + "dev": true, + "requires": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0" + } + }, + "jest-get-type": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", + "dev": true + }, + "jest-haste-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", + "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.9.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", + "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^24.9.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0", + "throat": "^4.0.0" + } + }, + "jest-leak-detector": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", + "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", + "dev": true, + "requires": { + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" + } + }, + "jest-matcher-utils": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", + "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" + } + }, + "jest-message-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + }, + "dependencies": { + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + } + }, + "jest-mock": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", + "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", + "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", + "dev": true + }, + "jest-regex-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", + "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", + "dev": true + }, + "jest-resolve": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", + "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" + } + }, + "jest-resolve-dependencies": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz", + "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-snapshot": "^24.9.0" + } + }, + "jest-runner": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", + "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.4.2", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-config": "^24.9.0", + "jest-docblock": "^24.3.0", + "jest-haste-map": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-leak-detector": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.6.0", + "source-map-support": "^0.5.6", + "throat": "^4.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } } - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" + } + }, + "jest-runtime": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", + "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/environment": "^24.9.0", + "@jest/source-map": "^24.3.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "strip-bom": "^3.0.0", + "yargs": "^13.3.0" + }, + "dependencies": { + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "yargs": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" + } } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" - }, - "space-separated-tokens": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.4.tgz", - "integrity": "sha512-UyhMSmeIqZrQn2UdjYpxEkwY9JUrn8pP+7L4f91zRzOQuI8MF1FGLfYU9DKCYeLdo7LXMxwrX5zKFy7eeeVHuA==", - "dev": true - }, - "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==" - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + } + }, + "jest-serializer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", + "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", + "dev": true + }, + "jest-snapshot": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", + "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "expect": "^24.9.0", + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^24.9.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + } + }, + "jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dev": true, + "requires": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" - }, - "split": { - "version": "0.3.3", - "resolved": "http://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", - "dev": true, - "requires": { - "through": "2" + } + }, + "jest-validate": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", + "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "camelcase": "^5.3.1", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "leven": "^3.1.0", + "pretty-format": "^24.9.0" + } + }, + "jest-watcher": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", + "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", + "dev": true, + "requires": { + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "jest-util": "^24.9.0", + "string-length": "^2.0.0" + } + }, + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" + } + }, + "jsencrypt": { + "version": "3.0.0-rc.1", + "resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.0.0-rc.1.tgz", + "integrity": "sha512-gcvGaqerlUJy1Kq6tNgPYteVEoWNemu+9hBe2CdsCIz4rVcwjoTQ72iD1W76/PRMlnkzG0yVh7nwOOMOOUfKmg==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.0.1.tgz", + "integrity": "sha1-6l7+QLg2kLmGZ2FKc5L8YOhCwN0=", + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "just-clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/just-clone/-/just-clone-1.0.2.tgz", + "integrity": "sha1-v7P672WqEqMWBYcSlFwyb9jwFDQ=" + }, + "just-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", + "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", + "dev": true + }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, + "karma": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-3.1.4.tgz", + "integrity": "sha512-31Vo8Qr5glN+dZEVIpnPCxEGleqE0EY6CtC2X9TagRV3rRQ3SNrvfhddICkJgUK3AgqpeKSZau03QumTGhGoSw==", + "dev": true, + "requires": { + "bluebird": "^3.3.0", + "body-parser": "^1.16.1", + "chokidar": "^2.0.3", + "colors": "^1.1.0", + "combine-lists": "^1.0.0", + "connect": "^3.6.0", + "core-js": "^2.2.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.0", + "expand-braces": "^0.1.1", + "flatted": "^2.0.0", + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "http-proxy": "^1.13.0", + "isbinaryfile": "^3.0.0", + "lodash": "^4.17.5", + "log4js": "^3.0.0", + "mime": "^2.3.1", + "minimatch": "^3.0.2", + "optimist": "^0.6.1", + "qjobs": "^1.1.4", + "range-parser": "^1.2.0", + "rimraf": "^2.6.0", + "safe-buffer": "^5.0.1", + "socket.io": "2.1.1", + "source-map": "^0.6.1", + "tmp": "0.0.33", + "useragent": "2.3.0" + }, + "dependencies": { + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" + } + }, + "karma-babel-preprocessor": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/karma-babel-preprocessor/-/karma-babel-preprocessor-6.0.1.tgz", + "integrity": "sha1-euHT5klQ2+EfQht0BAqwj7WmbCE=", + "dev": true, + "requires": { + "babel-core": "^6.0.0" + } + }, + "karma-browserstack-launcher": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/karma-browserstack-launcher/-/karma-browserstack-launcher-1.5.1.tgz", + "integrity": "sha512-zt9Ukow5A9WZHZXCFVO/h5kRsAdaZYeMNJK9Uan8v42amQXt3B/DZVxl24NCcAIxufKjW13UWd9iJ9knG9OCYw==", + "dev": true, + "requires": { + "browserstack": "~1.5.1", + "browserstack-local": "^1.3.7", + "q": "~1.5.0" + } + }, + "karma-chai": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", + "integrity": "sha1-vuWtQEAFF4Ea40u5RfdikJEIt5o=", + "dev": true + }, + "karma-chrome-launcher": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", + "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "dev": true, + "requires": { + "fs-access": "^1.0.0", + "which": "^1.2.1" + } + }, + "karma-coverage-istanbul-reporter": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-1.4.3.tgz", + "integrity": "sha1-O13/RmT6W41RlrmInj9hwforgNk=", + "dev": true, + "requires": { + "istanbul-api": "^1.3.1", + "minimatch": "^3.0.4" + } + }, + "karma-es5-shim": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/karma-es5-shim/-/karma-es5-shim-0.0.4.tgz", + "integrity": "sha1-zdADM8znfC5M4D46yT8vjs0fuVI=", + "dev": true, + "requires": { + "es5-shim": "^4.0.5" + } + }, + "karma-firefox-launcher": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.3.0.tgz", + "integrity": "sha512-Fi7xPhwrRgr+94BnHX0F5dCl1miIW4RHnzjIGxF8GaIEp7rNqX7LSi7ok63VXs3PS/5MQaQMhGxw+bvD+pibBQ==", + "dev": true, + "requires": { + "is-wsl": "^2.1.0" + }, + "dependencies": { + "is-wsl": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz", + "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", + "dev": true } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, - "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" - }, - "state-toggle": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.2.tgz", - "integrity": "sha512-8LpelPGR0qQM4PnfLiplOQNJcIN1/r2Gy0xKB2zKnIW2YzPMt2sR4I/+gtPjhN7Svh9kw+zqEg2SFwpBO9iNiw==", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } + } + }, + "karma-ie-launcher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/karma-ie-launcher/-/karma-ie-launcher-1.0.0.tgz", + "integrity": "sha1-SXmGhCxJAZA0bNifVJTKmDDG1Zw=", + "dev": true, + "requires": { + "lodash": "^4.6.1" + } + }, + "karma-mocha": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz", + "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=", + "dev": true, + "requires": { + "minimist": "1.2.0" + } + }, + "karma-mocha-reporter": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", + "integrity": "sha1-FRIAlejtgZGG5HoLAS8810GJVWA=", + "dev": true, + "requires": { + "chalk": "^2.1.0", + "log-symbols": "^2.1.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" } } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" - }, - "stream-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/stream-array/-/stream-array-1.1.2.tgz", - "integrity": "sha1-nl9zRfITfDDuO0mLkRToC1K7frU=", - "dev": true, - "requires": { - "readable-stream": "~2.1.0" - }, - "dependencies": { - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "readable-stream": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", - "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", - "dev": true, - "requires": { - "buffer-shims": "^1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + } + }, + "karma-opera-launcher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/karma-opera-launcher/-/karma-opera-launcher-1.0.0.tgz", + "integrity": "sha1-+lFihTGh0L6EstjcDX7iCfyP+Ro=", + "dev": true + }, + "karma-safari-launcher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/karma-safari-launcher/-/karma-safari-launcher-1.0.0.tgz", + "integrity": "sha1-lpgqLMR9BmquccVTursoMZEVos4=", + "dev": true + }, + "karma-script-launcher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/karma-script-launcher/-/karma-script-launcher-1.0.0.tgz", + "integrity": "sha1-zQF8TeXvCeWp2nkydhdhCN1LVC0=", + "dev": true + }, + "karma-sinon": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/karma-sinon/-/karma-sinon-1.0.5.tgz", + "integrity": "sha1-TjRD8oMP3s/2JNN0cWPxIX2qKpo=", + "dev": true + }, + "karma-sourcemap-loader": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz", + "integrity": "sha1-kTIsd/jxPUb+0GKwQuEAnUxFBdg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2" + } + }, + "karma-spec-reporter": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.31.tgz", + "integrity": "sha1-SDDccUihVcfXoYbmMjOaDYD63sM=", + "dev": true, + "requires": { + "colors": "^1.1.2" + } + }, + "karma-webpack": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-3.0.5.tgz", + "integrity": "sha512-nRudGJWstvVuA6Tbju9tyGUfXTtI1UXMXoRHVmM2/78D0q6s/Ye2IC157PKNDC15PWFGR0mVIRtWLAdcfsRJoA==", + "dev": true, + "requires": { + "async": "^2.0.0", + "babel-runtime": "^6.0.0", + "loader-utils": "^1.0.0", + "lodash": "^4.0.0", + "source-map": "^0.5.6", + "webpack-dev-middleware": "^2.0.6" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" } } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", - "dev": true, - "requires": { - "duplexer": "~0.1.1" - } - }, - "stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", - "dev": true, - "requires": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" - } - }, - "stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==" - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" + } + }, + "kebab-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/kebab-case/-/kebab-case-1.0.0.tgz", + "integrity": "sha1-P55JkK3K0MaGwOcB92RYaPdfkes=", + "dev": true + }, + "keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "last-run": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", + "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", + "dev": true, + "requires": { + "default-resolution": "^2.0.0", + "es6-weak-map": "^2.0.1" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "lcov-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", + "dev": true + }, + "lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, + "requires": { + "flush-write-stream": "^1.0.2" + } + }, + "left-pad": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "dev": true, + "requires": { + "leven": "^3.1.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "liftoff": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", + "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", + "dev": true, + "requires": { + "extend": "^3.0.0", + "findup-sync": "^3.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + } + }, + "livereload-js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", + "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true } - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" - }, - "streamroller": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", - "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", - "dev": true, - "requires": { - "date-format": "^1.2.0", - "debug": "^3.1.0", - "mkdirp": "^0.5.1", - "readable-stream": "^2.3.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" } } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true - }, - "string-length": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", - "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", - "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true + }, + "lodash._escapehtmlchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", + "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=", + "dev": true, + "requires": { + "lodash._htmlescapes": "~2.4.1" + } + }, + "lodash._escapestringchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", + "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._htmlescapes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", + "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash._isnative": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", + "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=", + "dev": true + }, + "lodash._objecttypes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", + "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", + "dev": true + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", + "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", + "dev": true + }, + "lodash._reunescapedhtml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", + "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=", + "dev": true, + "requires": { + "lodash._htmlescapes": "~2.4.1", + "lodash.keys": "~2.4.1" + } + }, + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + }, + "lodash._shimkeys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", + "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=", + "dev": true, + "requires": { + "lodash._objecttypes": "~2.4.1" + } + }, + "lodash.clone": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", + "dev": true + }, + "lodash.defaults": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", + "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=", + "dev": true, + "requires": { + "lodash._objecttypes": "~2.4.1", + "lodash.keys": "~2.4.1" + } + }, + "lodash.escape": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", + "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", + "dev": true, + "requires": { + "lodash._escapehtmlchar": "~2.4.1", + "lodash._reunescapedhtml": "~2.4.1", + "lodash.keys": "~2.4.1" + } + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.isobject": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", + "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", + "dev": true, + "requires": { + "lodash._objecttypes": "~2.4.1" + } + }, + "lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", + "dev": true, + "requires": { + "lodash._isnative": "~2.4.1", + "lodash._shimkeys": "~2.4.1", + "lodash.isobject": "~2.4.1" + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "lodash.template": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", + "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", + "dev": true, + "requires": { + "lodash._escapestringchar": "~2.4.1", + "lodash._reinterpolate": "~2.4.1", + "lodash.defaults": "~2.4.1", + "lodash.escape": "~2.4.1", + "lodash.keys": "~2.4.1", + "lodash.templatesettings": "~2.4.1", + "lodash.values": "~2.4.1" + } + }, + "lodash.templatesettings": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", + "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~2.4.1", + "lodash.escape": "~2.4.1" + } + }, + "lodash.values": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", + "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=", + "dev": true, + "requires": { + "lodash.keys": "~2.4.1" + } + }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "log4js": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.6.tgz", + "integrity": "sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ==", + "dev": true, + "requires": { + "circular-json": "^0.5.5", + "date-format": "^1.2.0", + "debug": "^3.1.0", + "rfdc": "^1.1.2", + "streamroller": "0.7.0" + }, + "dependencies": { + "circular-json": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", + "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } - }, - "string-template": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", - "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } + } + }, + "loglevelnext": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz", + "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==", + "dev": true, + "requires": { + "es6-symbol": "^3.1.1", + "object.assign": "^4.1.0" + } + }, + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", + "dev": true, + "requires": { + "es5-ext": "~0.10.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "make-error-cause": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", + "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=", + "dev": true, + "requires": { + "make-error": "^1.2.0" + } + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "dev": true + }, + "markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true + }, + "matchdep": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", + "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", + "dev": true, + "requires": { + "findup-sync": "^2.0.0", + "micromatch": "^3.0.4", + "resolve": "^1.4.0", + "stack-trace": "0.0.10" + }, + "dependencies": { + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" } } - }, - "string.prototype.padend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", - "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.4.3", - "function-bind": "^1.0.2" - } - }, - "string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "stringify-entities": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", - "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", - "dev": true, - "requires": { - "character-entities-html4": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" - }, - "strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" + } + }, + "math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdast-util-compact": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", + "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", + "dev": true, + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "mdast-util-definitions": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-1.2.5.tgz", + "integrity": "sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA==", + "dev": true, + "requires": { + "unist-util-visit": "^1.0.0" + } + }, + "mdast-util-inject": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-inject/-/mdast-util-inject-1.1.0.tgz", + "integrity": "sha1-2wa4tYW+lZotzS+H9HK6m3VvNnU=", + "dev": true, + "requires": { + "mdast-util-to-string": "^1.0.0" + } + }, + "mdast-util-to-hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-3.0.4.tgz", + "integrity": "sha512-/eIbly2YmyVgpJNo+bFLLMCI1XgolO/Ffowhf+pHDq3X4/V6FntC9sGQCDLM147eTS+uSXv5dRzJyFn+o0tazA==", + "dev": true, + "requires": { + "collapse-white-space": "^1.0.0", + "detab": "^2.0.0", + "mdast-util-definitions": "^1.2.0", + "mdurl": "^1.0.1", + "trim": "0.0.1", + "trim-lines": "^1.0.0", + "unist-builder": "^1.0.1", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.0", + "xtend": "^4.0.1" + } + }, + "mdast-util-to-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.7.tgz", + "integrity": "sha512-P+gdtssCoHOX+eJUrrC30Sixqao86ZPlVjR5NEAoy0U79Pfxb1Y0Gntei0+GrnQD4T04X9xA8tcugp90cSmNow==", + "dev": true + }, + "mdast-util-toc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-3.1.0.tgz", + "integrity": "sha512-Za0hqL1PqWrvxGtA/3NH9D5nhGAUS9grMM4obEAz5+zsk1RIw/vWUchkaoDLNdrwk05A0CSC5eEXng36/1qE5w==", + "dev": true, + "requires": { + "github-slugger": "^1.2.1", + "mdast-util-to-string": "^1.0.5", + "unist-util-is": "^2.1.2", + "unist-util-visit": "^1.1.0" + }, + "dependencies": { + "emoji-regex": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", + "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=", + "dev": true + }, + "github-slugger": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.1.tgz", + "integrity": "sha512-SsZUjg/P03KPzQBt7OxJPasGw6NRO5uOgiZ5RGXVud5iSIZ0eNZeNp5rTwCxtavrRUa/A77j8mePVc5lEvk0KQ==", + "dev": true, + "requires": { + "emoji-regex": ">=6.0.0 <=6.1.1" + } + }, + "unist-util-is": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", + "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==", + "dev": true } - }, - "sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", - "requires": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "memoizee": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", + "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.45", + "es6-weak-map": "^2.0.2", + "event-emitter": "^0.3.5", + "is-promise": "^2.1", + "lru-queue": "0.1", + "next-tick": "1", + "timers-ext": "^0.1.5" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } } - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" - }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", - "dev": true, - "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + }, + "mime-types": { + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "requires": { + "mime-db": "1.43.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" } } - }, - "tapable": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.9.tgz", - "integrity": "sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A==", - "dev": true - }, - "tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "dev": true, - "requires": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true } - }, - "temp-fs": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/temp-fs/-/temp-fs-0.9.9.tgz", - "integrity": "sha1-gHFzBDeHByDpQxUy/igUNk+IA9c=", - "dev": true, - "requires": { - "rimraf": "~2.5.2" - }, - "dependencies": { - "rimraf": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", - "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", - "dev": true, - "requires": { - "glob": "^7.0.5" - } + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" } - } - }, - "ternary-stream": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-2.1.1.tgz", - "integrity": "sha512-j6ei9hxSoyGlqTmoMjOm+QNvUKDOIY6bNl4Uh1lhBvl6yjPW2iLqxDUYyfDPZknQ4KdRziFl+ec99iT4l7g0cw==", - "dev": true, - "requires": { - "duplexify": "^3.5.0", - "fork-stream": "^0.0.4", - "merge-stream": "^1.0.0", - "through2": "^2.0.1" - }, - "dependencies": { - "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" } } - }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" - }, - "dependencies": { - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" + } + }, + "module-deps-sortable": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/module-deps-sortable/-/module-deps-sortable-4.0.6.tgz", + "integrity": "sha1-ElGkuixEqS32mJvQKdoSGk8hCbA=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "concat-stream": "~1.5.0", + "defined": "^1.0.0", + "detective": "^4.0.0", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.3", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~2.0.0", + "typedarray": "~0.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } } } + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true } - }, - "text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "textextensions": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.6.0.tgz", - "integrity": "sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ==", - "dev": true - }, - "throat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "~1.1.9" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" + } + }, + "mute-stdout": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", + "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "ncp": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", + "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "nise": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", + "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^5.0.1", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "@sinonjs/formatio": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", + "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + } } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" + } + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true } - }, - "timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dev": true, - "requires": { - "es5-ext": "~0.10.46", - "next-tick": "1" + } + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", + "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "dev": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^1.1.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, + "node-releases": { + "version": "1.1.49", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.49.tgz", + "integrity": "sha512-xH8t0LS0disN0mtRCh+eByxFPie+msJUBL/lJDBuap53QGiYPa9joh83K4pCZgWJ+2L4b9h88vCVdXQ60NO2bg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } - }, - "timespan": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", - "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=" - }, - "tiny-lr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", - "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", - "dev": true, - "requires": { - "body": "^5.1.0", - "debug": "^3.1.0", - "faye-websocket": "~0.10.0", - "livereload-js": "^2.3.0", - "object-assign": "^4.1.0", - "qs": "^6.4.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } + }, + "now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "dev": true, + "requires": { + "once": "^1.3.2" + } + }, + "npm-install-package": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/npm-install-package/-/npm-install-package-2.1.0.tgz", + "integrity": "sha1-1+/jz816sAYUuJbqUxGdyaslkSU=", + "dev": true + }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" } } - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" + }, + "object-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz", + "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + }, + "dependencies": { + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } } - }, - "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.reduce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", + "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "opener": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", + "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "dev": true + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true } - }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", + "dev": true + }, + "p-each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", + "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", + "dev": true, + "requires": { + "p-reduce": "^1.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "dev": true + }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-reduce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", + "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", + "dev": true + }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-domain": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/parse-domain/-/parse-domain-2.3.4.tgz", + "integrity": "sha512-LlFJJVTry4DD3Xa76CsVNP6MIu3JZ8GXd5HEEp38KSDGBCVsnccagAJ5YLy7uEEabvwtauQEQPcvXWgUGkJbMA==", + "dev": true, + "requires": { + "got": "^8.3.2", + "jest": "^24.9.0", + "mkdirp": "^0.5.1", + "npm-run-all": "^4.1.5" + } + }, + "parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "dev": true, + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-git-config": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-0.2.0.tgz", + "integrity": "sha1-Jygz/dFf6hRvt10zbSNrljtv9wY=", + "dev": true, + "requires": { + "ini": "^1.3.3" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parse-path": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-3.0.4.tgz", + "integrity": "sha512-wP70vtwv2DyrM2YoA7ZHVv4zIXa4P7dGgHlj+VwyXNDduLLVJ7NMY1zsFxjUUJ3DAwJLupGb1H5gMDDiNlJaxw==", + "dev": true, + "requires": { + "is-ssh": "^1.3.0", + "protocols": "^1.4.0" + } + }, + "parse-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-3.0.2.tgz", + "integrity": "sha1-YCeHpwY6eV1yuGcxl1BecvYGEL4=", + "dev": true, + "requires": { + "is-ssh": "^1.3.0", + "normalize-url": "^1.9.1", + "parse-path": "^3.0.1", + "protocols": "^1.4.0" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", - "requires": { - "through2": "^2.0.3" + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "dev": true, + "requires": { + "through": "~2.3" + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pbkdf2-compat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz", + "integrity": "sha1-tuDI+plJTZTgURV1gCpZpcFC8og=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pidtree": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz", + "integrity": "sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "dev": true, + "requires": { + "ansi-colors": "^1.0.1", + "arr-diff": "^4.0.0", + "arr-union": "^3.1.0", + "extend-shallow": "^3.0.2" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "dev": true, + "requires": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "prompts": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.0.tgz", + "integrity": "sha512-NfbbPPg/74fT7wk2XYQ7hAIp9zJyZp5Fu19iRbORqqy1BhtrkZ0fPafBU+7bmn8ie69DpT0R6QpJIN2oisYjJg==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.3" + } + }, + "property-information": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-3.2.0.tgz", + "integrity": "sha1-/RSDyPusYYCPX+NZ52k6H0ilgzE=", + "dev": true + }, + "protocols": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.7.tgz", + "integrity": "sha512-Fx65lf9/YDn3hUX08XUc0J8rSux36rEsyiv21ZGUC1mOyeM3lTRpZLcrm8aAolzS4itwVfm7TAPyxC2E5zd6xg==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "ps-tree": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", + "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", + "dev": true, + "requires": { + "event-stream": "=3.3.4" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } } - }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "requires": { - "punycode": "^2.1.0" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "dev": true + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "dev": true, + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true } - }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", - "dev": true - }, - "trim-lines": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-1.1.2.tgz", - "integrity": "sha512-3GOuyNeTqk3FAqc3jOJtw7FTjYl94XBR5aD9QnDbK/T4CA9sW/J0l9RoaRPE9wyPP7NF331qnHnvJFBJ+IDkmQ==", - "dev": true - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "trim-trailing-lines": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz", - "integrity": "sha512-MUjYItdrqqj2zpcHFTkMa9WAv4JHTI6gnRQGPFLrt5L9a6tRMiDnIqYl8JBvu2d2Tc3lWJKQwlGCp0K8AvCM+Q==", - "dev": true - }, - "triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "trough": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.4.tgz", - "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==", - "dev": true - }, - "tryer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", - "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", - "dev": true - }, - "ts-jest": { - "version": "24.2.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.2.0.tgz", - "integrity": "sha512-Yc+HLyldlIC9iIK8xEN7tV960Or56N49MDP7hubCZUeI7EbIOTsas6rXCMB4kQjLACJ7eDOF4xWEO5qumpKsag==", - "requires": { - "bs-logger": "0.x", - "buffer-from": "1.x", - "fast-json-stable-stringify": "2.x", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "mkdirp": "0.x", - "resolve": "1.x", - "semver": "^5.5", - "yargs-parser": "10.x" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" - }, - "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "requires": { - "camelcase": "^4.1.0" - } + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true } - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "realpath-native": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", + "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", + "dev": true, + "requires": { + "util.promisify": "^1.0.0" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "regenerator-transform": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", + "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", + "dev": true, + "requires": { + "private": "^0.1.6" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "regexpp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "dev": true + }, + "regexpu-core": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + }, + "regjsgen": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", + "dev": true + }, + "regjsparser": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.2.tgz", + "integrity": "sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "requires": { - "prelude-ls": "~1.1.2" + } + }, + "remark": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-9.0.0.tgz", + "integrity": "sha512-amw8rGdD5lHbMEakiEsllmkdBP+/KpjW/PRK6NSGPZKCQowh0BT4IWXDAkRMyG3SB9dKPXWMviFjNusXzXNn3A==", + "dev": true, + "requires": { + "remark-parse": "^5.0.0", + "remark-stringify": "^5.0.0", + "unified": "^6.0.0" + } + }, + "remark-html": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-7.0.0.tgz", + "integrity": "sha512-jqRzkZXCkM12gIY2ibMLTW41m7rfanliMTVQCFTezHJFsbH00YaTox/BX4gU+f/zCdzfhFJONtebFByvpMv37w==", + "dev": true, + "requires": { + "hast-util-sanitize": "^1.0.0", + "hast-util-to-html": "^3.0.0", + "mdast-util-to-hast": "^3.0.0", + "xtend": "^4.0.1" + } + }, + "remark-parse": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", + "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", + "dev": true, + "requires": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "remark-reference-links": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/remark-reference-links/-/remark-reference-links-4.0.4.tgz", + "integrity": "sha512-+2X8hwSQqxG4tvjYZNrTcEC+bXp8shQvwRGG6J/rnFTvBoU4G0BBviZoqKGZizLh/DG+0gSYhiDDWCqyxXW1iQ==", + "dev": true, + "requires": { + "unist-util-visit": "^1.0.0" + } + }, + "remark-slug": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-5.1.2.tgz", + "integrity": "sha512-DWX+Kd9iKycqyD+/B+gEFO3jjnt7Yg1O05lygYSNTe5i5PIxxxPjp5qPBDxPIzp5wreF7+1ROCwRgjEcqmzr3A==", + "dev": true, + "requires": { + "github-slugger": "^1.0.0", + "mdast-util-to-string": "^1.0.0", + "unist-util-visit": "^1.0.0" + } + }, + "remark-stringify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-5.0.0.tgz", + "integrity": "sha512-Ws5MdA69ftqQ/yhRF9XhVV29mhxbfGhbz0Rx5bQH+oJcNhhSM6nCu1EpLod+DjrFGrU0BMPs+czVmJZU7xiS7w==", + "dev": true, + "requires": { + "ccount": "^1.0.0", + "is-alphanumeric": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "longest-streak": "^2.0.1", + "markdown-escapes": "^1.0.0", + "markdown-table": "^1.1.0", + "mdast-util-compact": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "stringify-entities": "^1.0.1", + "unherit": "^1.0.4", + "xtend": "^4.0.1" + } + }, + "remark-toc": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/remark-toc/-/remark-toc-5.1.1.tgz", + "integrity": "sha512-vCPW4YOsm2CfyuScdktM9KDnJXVHJsd/ZeRtst+dnBU3B3KKvt8bc+bs5syJjyptAHfqo7H+5Uhz+2blWBfwow==", + "dev": true, + "requires": { + "mdast-util-toc": "^3.0.0", + "remark-slug": "^5.0.0" + } + }, + "remote-origin-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/remote-origin-url/-/remote-origin-url-0.4.0.tgz", + "integrity": "sha1-TT4pAvNOLTfRwmPYdxC3frQIajA=", + "dev": true, + "requires": { + "parse-git-config": "^0.2.0" + } + }, + "remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + } + }, + "remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, + "requires": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "replace-homedir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", + "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1", + "is-absolute": "^1.0.0", + "remove-trailing-separator": "^1.1.0" + } + }, + "replacestream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz", + "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.3", + "object-assign": "^4.0.1", + "readable-stream": "^2.0.2" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + } + }, + "request-promise": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz", + "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==", + "dev": true, + "requires": { + "bluebird": "^3.5.0", + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "request-promise-native": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "dev": true, + "requires": { + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "typescript": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz", - "integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==" - }, - "typescript-compare": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz", - "integrity": "sha512-8ja4j7pMHkfLJQO2/8tut7ub+J3Lw2S3061eJLFQcvs3tsmJKp8KG5NtpLn7KcY2w08edF74BSVN7qJS0U6oHA==", - "requires": { - "typescript-logic": "^0.0.0" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true } - }, - "typescript-logic": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/typescript-logic/-/typescript-logic-0.0.0.tgz", - "integrity": "sha512-zXFars5LUkI3zP492ls0VskH3TtdeHCqu0i7/duGt60i5IGPIpAHE/DWo5FqJ6EjQ15YKXrt+AETjv60Dat34Q==" - }, - "typescript-tuple": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/typescript-tuple/-/typescript-tuple-2.2.1.tgz", - "integrity": "sha512-Zcr0lbt8z5ZdEzERHAMAniTiIKerFCMgd7yjq1fPnDJ43et/k9twIFQMUYff9k5oXcsQ0WpvFcgzK2ZKASoW6Q==", - "requires": { - "typescript-compare": "^0.0.2" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, + "requires": { + "value-or-function": "^3.0.0" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rfdc": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz", + "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==", + "dev": true + }, + "rgb2hex": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.10.tgz", + "integrity": "sha512-vKz+kzolWbL3rke/xeTE2+6vHmZnNxGyDnaVW4OckntAIcc7DcZzWkQSfxMDwqHS8vhgySnIFyBUH7lIk6PxvQ==", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "*" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "dev": true, + "requires": { + "ajv": "^5.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "semver-greatest-satisfied-range": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", + "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", + "dev": true, + "requires": { + "sver-compat": "^1.5.0" + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" } - }, - "uglify-js": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.2.tgz", - "integrity": "sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA==", - "dev": true, - "requires": { - "commander": "~2.20.3", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true - }, - "uglifyjs-webpack-plugin": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", - "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", - "dev": true, - "requires": { - "source-map": "^0.5.6", - "uglify-js": "^2.8.29", - "webpack-sources": "^1.0.1" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - } - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" } } - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" - }, - "undertaker": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", - "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", - "requires": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - } - }, - "undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=" - }, - "unherit": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.2.tgz", - "integrity": "sha512-W3tMnpaMG7ZY6xe/moK04U9fBhi6wEiCYHUW5Mop/wQHf12+79EQGwxYejNdhEz2mkqkBlGwm7pxmgBKMVUj0w==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "xtend": "^4.0.1" - } - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", - "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", - "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", - "dev": true - }, - "unified": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", - "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", - "dev": true, - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^2.0.0", - "x-is-string": "^0.1.0" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "dev": true + }, + "shelljs": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", + "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "sinon": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", + "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^2.0.0", + "diff": "^3.1.0", + "lodash.get": "^4.4.2", + "lolex": "^2.2.0", + "nise": "^1.2.0", + "supports-color": "^5.1.0", + "type-detect": "^4.0.5" + }, + "dependencies": { + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true } - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" + } + }, + "sisteransi": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.4.tgz", + "integrity": "sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig==", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } } - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } } - }, - "unist-builder": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.4.tgz", - "integrity": "sha512-v6xbUPP7ILrT15fHGrNyHc1Xda8H3xVhP7/HAIotHOhVPjH5dCXA097C3Rry1Q2O+HbOLCao4hfPB+EYEjHgVg==", - "dev": true, - "requires": { - "object-assign": "^4.1.0" + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } } - }, - "unist-util-generated": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.5.tgz", - "integrity": "sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw==", - "dev": true - }, - "unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", - "dev": true - }, - "unist-util-position": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.0.4.tgz", - "integrity": "sha512-tWvIbV8goayTjobxDIr4zVTyG+Q7ragMSMeKC3xnPl9xzIc0+she8mxXLM3JVNDDsfARPbCd3XdzkyLdo7fF3g==", - "dev": true - }, - "unist-util-remove-position": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", - "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", - "dev": true, - "requires": { - "unist-util-visit": "^1.1.0" + } + }, + "socket.io": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", + "dev": true, + "requires": { + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.1.1", + "socket.io-parser": "~3.2.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } } - }, - "unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", - "dev": true - }, - "unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", - "dev": true, - "requires": { - "unist-util-visit-parents": "^2.0.0" + } + }, + "socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==", + "dev": true + }, + "socket.io-client": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.2.0", + "to-array": "0.1.4" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } } - }, - "unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", - "dev": true, - "requires": { - "unist-util-is": "^3.0.0" + } + }, + "socket.io-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "dev": true + }, + "sparkles": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "dev": true, + "requires": { + "through": "2" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true + }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "dev": true + }, + "state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" } } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "stream-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/stream-array/-/stream-array-1.1.2.tgz", + "integrity": "sha1-nl9zRfITfDDuO0mLkRToC1K7frU=", + "dev": true, + "requires": { + "readable-stream": "~2.1.0" + }, + "dependencies": { + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "readable-stream": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", + "dev": true, + "requires": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true } - }, - "url-join": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", - "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", - "dev": true - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - }, - "dependencies": { - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "dev": true, + "requires": { + "duplexer": "~0.1.1" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-exhaust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", + "dev": true + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "streamroller": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", + "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", + "dev": true, + "requires": { + "date-format": "^1.2.0", + "debug": "^3.1.0", + "mkdirp": "^0.5.1", + "readable-stream": "^2.3.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" - }, - "useragent": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", - "integrity": "sha1-IX+UOtVAyyEoZYqyP8lg9qiMmXI=", - "dev": true, - "requires": { - "lru-cache": "4.1.x", - "tmp": "0.0.x" - } - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, + "string-length": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", + "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", + "dev": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" + } + }, + "string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } } - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" - }, - "v8flags": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", - "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", - "requires": { - "homedir-polyfill": "^1.0.1" + } + }, + "string.prototype.padend": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.0.tgz", + "integrity": "sha512-3aIv8Ffdp8EZj8iLwREGpQaUZiPyrWrpzMBHvkiSW/bK/EGve9np07Vwy7IJ5waydpGXzQZu/F8Oze2/IWkBaA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringify-entities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", + "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", + "dev": true, + "requires": { + "character-entities-html4": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", + "dev": true, + "requires": { + "minimist": "^1.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "sver-compat": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", + "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", + "dev": true, + "requires": { + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + } + }, + "tapable": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.9.tgz", + "integrity": "sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A==", + "dev": true + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + } + }, + "temp-fs": { + "version": "0.9.9", + "resolved": "https://registry.npmjs.org/temp-fs/-/temp-fs-0.9.9.tgz", + "integrity": "sha1-gHFzBDeHByDpQxUy/igUNk+IA9c=", + "dev": true, + "requires": { + "rimraf": "~2.5.2" + }, + "dependencies": { + "rimraf": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", + "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", + "dev": true, + "requires": { + "glob": "^7.0.5" + } } - }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + } + }, + "ternary-stream": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-2.1.1.tgz", + "integrity": "sha512-j6ei9hxSoyGlqTmoMjOm+QNvUKDOIY6bNl4Uh1lhBvl6yjPW2iLqxDUYyfDPZknQ4KdRziFl+ec99iT4l7g0cw==", + "dev": true, + "requires": { + "duplexify": "^3.5.0", + "fork-stream": "^0.0.4", + "merge-stream": "^1.0.0", + "through2": "^2.0.1" + }, + "dependencies": { + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } } - }, - "vfile": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", - "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", - "dev": true, - "requires": { - "is-buffer": "^1.1.4", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" + } + }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + }, + "dependencies": { + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } } - }, - "vfile-location": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", - "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", - "dev": true - }, - "vfile-message": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", - "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", - "dev": true, - "requires": { - "unist-util-stringify-position": "^1.1.1" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "textextensions": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.6.0.tgz", + "integrity": "sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ==", + "dev": true + }, + "throat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", + "dev": true + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dev": true, + "requires": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, + "tiny-lr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", + "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", + "dev": true, + "requires": { + "body": "^5.1.0", + "debug": "^3.1.0", + "faye-websocket": "~0.10.0", + "livereload-js": "^2.3.0", + "object-assign": "^4.1.0", + "qs": "^6.4.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } - }, - "vfile-reporter": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-4.0.0.tgz", - "integrity": "sha1-6m8K4TQvSEFXOYXgX5QXNvJ96do=", - "dev": true, - "requires": { - "repeat-string": "^1.5.0", - "string-width": "^1.0.0", - "supports-color": "^4.1.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-statistics": "^1.1.0" - }, - "dependencies": { - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" } } - }, - "vfile-sort": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-2.2.1.tgz", - "integrity": "sha512-5dt7xEhC44h0uRQKhbM2JAe0z/naHphIZlMOygtMBM9Nn0pZdaX5fshhwWit9wvsuP8t/wp43nTDRRErO1WK8g==", - "dev": true - }, - "vfile-statistics": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.3.tgz", - "integrity": "sha512-CstaK/ebTz1W3Qp41Bt9Lj/2DmumFsCwC2sKahDNSPh0mPh7/UyMLCoU8ZBX34CRU0d61B4W41yIFsV0NKMZeA==", - "dev": true - }, - "vinyl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", - "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, + "requires": { + "through2": "^2.0.3" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "trim-lines": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-1.1.3.tgz", + "integrity": "sha512-E0ZosSWYK2mkSu+KEtQ9/KqarVjA9HztOSX+9FDdNacRAq29RRV6ZQNgob3iuW8Htar9vAfEa6yyt5qBAHZDBA==", + "dev": true + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "trim-trailing-lines": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz", + "integrity": "sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA==", + "dev": true + }, + "trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true + }, + "tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript-compare": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz", + "integrity": "sha512-8ja4j7pMHkfLJQO2/8tut7ub+J3Lw2S3061eJLFQcvs3tsmJKp8KG5NtpLn7KcY2w08edF74BSVN7qJS0U6oHA==", + "requires": { + "typescript-logic": "^0.0.0" + } + }, + "typescript-logic": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/typescript-logic/-/typescript-logic-0.0.0.tgz", + "integrity": "sha512-zXFars5LUkI3zP492ls0VskH3TtdeHCqu0i7/duGt60i5IGPIpAHE/DWo5FqJ6EjQ15YKXrt+AETjv60Dat34Q==" + }, + "typescript-tuple": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/typescript-tuple/-/typescript-tuple-2.2.1.tgz", + "integrity": "sha512-Zcr0lbt8z5ZdEzERHAMAniTiIKerFCMgd7yjq1fPnDJ43et/k9twIFQMUYff9k5oXcsQ0WpvFcgzK2ZKASoW6Q==", + "requires": { + "typescript-compare": "^0.0.2" + } + }, + "uglify-js": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.7.tgz", + "integrity": "sha512-FeSU+hi7ULYy6mn8PKio/tXsdSXN35lm4KgV2asx00kzrLU9Pi3oAslcJT70Jdj7PHX29gGUPOT6+lXGBbemhA==", + "dev": true, + "requires": { + "commander": "~2.20.3", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true + }, + "uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "dev": true, + "requires": { + "source-map": "^0.5.6", + "uglify-js": "^2.8.29", + "webpack-sources": "^1.0.1" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + } + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } } - }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" + } + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "undertaker": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", + "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "bach": "^1.0.0", + "collection-map": "^1.0.0", + "es6-weak-map": "^2.0.1", + "last-run": "^1.1.0", + "object.defaults": "^1.0.0", + "object.reduce": "^1.0.0", + "undertaker-registry": "^1.0.0" + } + }, + "undertaker-registry": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", + "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", + "dev": true + }, + "unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "dev": true, + "requires": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", + "dev": true + }, + "unified": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", + "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", + "dev": true, + "requires": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^2.0.0", + "x-is-string": "^0.1.0" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "requires": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "unist-builder": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.4.tgz", + "integrity": "sha512-v6xbUPP7ILrT15fHGrNyHc1Xda8H3xVhP7/HAIotHOhVPjH5dCXA097C3Rry1Q2O+HbOLCao4hfPB+EYEjHgVg==", + "dev": true, + "requires": { + "object-assign": "^4.1.0" + } + }, + "unist-util-generated": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.5.tgz", + "integrity": "sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw==", + "dev": true + }, + "unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true + }, + "unist-util-position": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.0.4.tgz", + "integrity": "sha512-tWvIbV8goayTjobxDIr4zVTyG+Q7ragMSMeKC3xnPl9xzIc0+she8mxXLM3JVNDDsfARPbCd3XdzkyLdo7fF3g==", + "dev": true + }, + "unist-util-remove-position": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "dev": true, + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "unist-util-stringify-position": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", + "dev": true + }, + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "requires": { + "unist-util-is": "^3.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } } } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true } - }, - "vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", - "requires": { - "source-map": "^0.5.1" - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "dev": true - }, - "w3c-hr-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", - "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", - "requires": { - "browser-process-hrtime": "^0.1.2" - } - }, - "walk": { - "version": "2.3.14", - "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.14.tgz", - "integrity": "sha512-5skcWAUmySj6hkBdH6B6+3ddMjVQYH5Qy9QGbPmN8kVmLteXk+yVXg+yfk1nbX30EYakahLrr8iPcCxJQSCBeg==", - "dev": true, - "requires": { - "foreachasync": "^3.0.0" - } - }, - "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "requires": { - "makeerror": "1.0.x" - } - }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "dev": true, - "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - } - }, - "wdio-browserstack-service": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/wdio-browserstack-service/-/wdio-browserstack-service-0.1.19.tgz", - "integrity": "sha512-ZAq20McWrQy80FQst+4cn1l5WRP9u+9DOKif2TarxYFzw/EmhdNg9TFcXBT5dxH+LcP5v47v7mXMmsO7B3+92Q==", - "dev": true, - "requires": { - "browserstack-local": "^1.3.7", - "request": "^2.81.0", - "request-promise": "^4.2.1" + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true } - }, - "wdio-concise-reporter": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/wdio-concise-reporter/-/wdio-concise-reporter-0.1.2.tgz", - "integrity": "sha1-+kmA768kszWfHqQz73thYxVDphQ=", - "dev": true - }, - "wdio-dot-reporter": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.10.tgz", - "integrity": "sha512-A0TCk2JdZEn3M1DSG9YYbNRcGdx/YRw19lTiRpgwzH4qqWkO/oRDZRmi3Snn4L2j54KKTfPalBhlOtc8fojVgg==", - "dev": true - }, - "wdio-mocha-framework": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/wdio-mocha-framework/-/wdio-mocha-framework-0.6.4.tgz", - "integrity": "sha512-GZsXwoW60/fkkfqZJR/ZAdiALaM+hW+BbnTT9x214qPR4Pe5XeyYxhJNEdyf0dNI9625cMdkyZYaWoFHN5zDcA==", - "dev": true, - "requires": { - "babel-runtime": "^6.23.0", - "mocha": "^5.2.0", - "wdio-sync": "0.7.3" + } + }, + "url-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, + "url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + }, + "dependencies": { + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true } - }, - "wdio-spec-reporter": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/wdio-spec-reporter/-/wdio-spec-reporter-0.1.5.tgz", - "integrity": "sha512-MqvgTow8hFwhFT47q67JwyJyeynKodGRQCxF7ijKPGfsaG1NLssbXYc0JhiL7SiAyxnQxII0UxzTCd3I6sEdkg==", - "dev": true, - "requires": { - "babel-runtime": "~6.26.0", - "chalk": "^2.3.0", - "humanize-duration": "~3.15.0" + } + }, + "url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "useragent": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", + "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", + "dev": true, + "requires": { + "lru-cache": "4.1.x", + "tmp": "0.0.x" + } + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "v8flags": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", + "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vfile": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", + "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", + "dev": true, + "requires": { + "is-buffer": "^1.1.4", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + } + }, + "vfile-location": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "dev": true + }, + "vfile-message": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", + "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "dev": true, + "requires": { + "unist-util-stringify-position": "^1.1.1" + } + }, + "vfile-reporter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-4.0.0.tgz", + "integrity": "sha1-6m8K4TQvSEFXOYXgX5QXNvJ96do=", + "dev": true, + "requires": { + "repeat-string": "^1.5.0", + "string-width": "^1.0.0", + "supports-color": "^4.1.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-statistics": "^1.1.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } } - }, - "wdio-sync": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/wdio-sync/-/wdio-sync-0.7.3.tgz", - "integrity": "sha512-ukASSHOQmOxaz5HTILR0jykqlHBtAPsBpMtwhpiG0aW9uc7SO7PF+E5LhVvTG4ypAh+UGmY3rTjohOsqDr39jw==", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "fibers": "^3.0.0", - "object.assign": "^4.0.3" + } + }, + "vfile-sort": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-2.2.1.tgz", + "integrity": "sha512-5dt7xEhC44h0uRQKhbM2JAe0z/naHphIZlMOygtMBM9Nn0pZdaX5fshhwWit9wvsuP8t/wp43nTDRRErO1WK8g==", + "dev": true + }, + "vfile-statistics": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.3.tgz", + "integrity": "sha512-CstaK/ebTz1W3Qp41Bt9Lj/2DmumFsCwC2sKahDNSPh0mPh7/UyMLCoU8ZBX34CRU0d61B4W41yIFsV0NKMZeA==", + "dev": true + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + }, + "vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "requires": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + } + }, + "vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, + "requires": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } } - }, - "webdriverio": { - "version": "4.14.4", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-4.14.4.tgz", - "integrity": "sha512-Knp2vzuzP5c5ybgLu+zTwy/l1Gh0bRP4zAr8NWcrStbuomm9Krn9oRF0rZucT6AyORpXinETzmeowFwIoo7mNA==", - "dev": true, - "requires": { - "archiver": "~2.1.0", - "babel-runtime": "^6.26.0", - "css-parse": "^2.0.0", - "css-value": "~0.0.1", - "deepmerge": "~2.0.1", - "ejs": "~2.5.6", - "gaze": "~1.1.2", - "glob": "~7.1.1", - "grapheme-splitter": "^1.0.2", - "inquirer": "~3.3.0", - "json-stringify-safe": "~5.0.1", - "mkdirp": "~0.5.1", - "npm-install-package": "~2.1.0", - "optimist": "~0.6.1", - "q": "~1.5.0", - "request": "^2.83.0", - "rgb2hex": "^0.1.9", - "safe-buffer": "~5.1.1", - "supports-color": "~5.0.0", - "url": "~0.11.0", - "wdio-dot-reporter": "~0.0.8", - "wgxpath": "~1.0.0" - }, - "dependencies": { - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "supports-color": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.0.1.tgz", - "integrity": "sha512-7FQGOlSQ+AQxBNXJpVDj8efTA/FtyB5wcNE1omXXJ0cq6jm1jjDwuROlYDbnzHqdNPqliWFhcioCWSyav+xBnA==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } + } + }, + "vinyl-sourcemaps-apply": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", + "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", + "dev": true, + "requires": { + "source-map": "^0.5.1" + } + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, + "requires": { + "browser-process-hrtime": "^0.1.2" + } + }, + "walk": { + "version": "2.3.14", + "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.14.tgz", + "integrity": "sha512-5skcWAUmySj6hkBdH6B6+3ddMjVQYH5Qy9QGbPmN8kVmLteXk+yVXg+yfk1nbX30EYakahLrr8iPcCxJQSCBeg==", + "dev": true, + "requires": { + "foreachasync": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "wdio-browserstack-service": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/wdio-browserstack-service/-/wdio-browserstack-service-0.1.19.tgz", + "integrity": "sha512-ZAq20McWrQy80FQst+4cn1l5WRP9u+9DOKif2TarxYFzw/EmhdNg9TFcXBT5dxH+LcP5v47v7mXMmsO7B3+92Q==", + "dev": true, + "requires": { + "browserstack-local": "^1.3.7", + "request": "^2.81.0", + "request-promise": "^4.2.1" + } + }, + "wdio-concise-reporter": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/wdio-concise-reporter/-/wdio-concise-reporter-0.1.2.tgz", + "integrity": "sha1-+kmA768kszWfHqQz73thYxVDphQ=", + "dev": true + }, + "wdio-dot-reporter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.10.tgz", + "integrity": "sha512-A0TCk2JdZEn3M1DSG9YYbNRcGdx/YRw19lTiRpgwzH4qqWkO/oRDZRmi3Snn4L2j54KKTfPalBhlOtc8fojVgg==", + "dev": true + }, + "wdio-mocha-framework": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/wdio-mocha-framework/-/wdio-mocha-framework-0.6.4.tgz", + "integrity": "sha512-GZsXwoW60/fkkfqZJR/ZAdiALaM+hW+BbnTT9x214qPR4Pe5XeyYxhJNEdyf0dNI9625cMdkyZYaWoFHN5zDcA==", + "dev": true, + "requires": { + "babel-runtime": "^6.23.0", + "mocha": "^5.2.0", + "wdio-sync": "0.7.3" + } + }, + "wdio-spec-reporter": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/wdio-spec-reporter/-/wdio-spec-reporter-0.1.5.tgz", + "integrity": "sha512-MqvgTow8hFwhFT47q67JwyJyeynKodGRQCxF7ijKPGfsaG1NLssbXYc0JhiL7SiAyxnQxII0UxzTCd3I6sEdkg==", + "dev": true, + "requires": { + "babel-runtime": "~6.26.0", + "chalk": "^2.3.0", + "humanize-duration": "~3.15.0" + } + }, + "wdio-sync": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/wdio-sync/-/wdio-sync-0.7.3.tgz", + "integrity": "sha512-ukASSHOQmOxaz5HTILR0jykqlHBtAPsBpMtwhpiG0aW9uc7SO7PF+E5LhVvTG4ypAh+UGmY3rTjohOsqDr39jw==", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "fibers": "^3.0.0", + "object.assign": "^4.0.3" + } + }, + "webdriverio": { + "version": "4.14.4", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-4.14.4.tgz", + "integrity": "sha512-Knp2vzuzP5c5ybgLu+zTwy/l1Gh0bRP4zAr8NWcrStbuomm9Krn9oRF0rZucT6AyORpXinETzmeowFwIoo7mNA==", + "dev": true, + "requires": { + "archiver": "~2.1.0", + "babel-runtime": "^6.26.0", + "css-parse": "^2.0.0", + "css-value": "~0.0.1", + "deepmerge": "~2.0.1", + "ejs": "~2.5.6", + "gaze": "~1.1.2", + "glob": "~7.1.1", + "grapheme-splitter": "^1.0.2", + "inquirer": "~3.3.0", + "json-stringify-safe": "~5.0.1", + "mkdirp": "~0.5.1", + "npm-install-package": "~2.1.0", + "optimist": "~0.6.1", + "q": "~1.5.0", + "request": "^2.83.0", + "rgb2hex": "^0.1.9", + "safe-buffer": "~5.1.1", + "supports-color": "~5.0.0", + "url": "~0.11.0", + "wdio-dot-reporter": "~0.0.8", + "wgxpath": "~1.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.0.1.tgz", + "integrity": "sha512-7FQGOlSQ+AQxBNXJpVDj8efTA/FtyB5wcNE1omXXJ0cq6jm1jjDwuROlYDbnzHqdNPqliWFhcioCWSyav+xBnA==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" } } - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "webpack": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.12.0.tgz", - "integrity": "sha512-Sw7MdIIOv/nkzPzee4o0EdvCuPmxT98+vVpIvwtcwcF1Q4SDSNp92vwcKc4REe7NItH9f1S4ra9FuQ7yuYZ8bQ==", - "dev": true, - "requires": { - "acorn": "^5.0.0", - "acorn-dynamic-import": "^2.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "async": "^2.1.2", - "enhanced-resolve": "^3.4.0", - "escope": "^3.6.0", - "interpret": "^1.0.0", - "json-loader": "^0.5.4", - "json5": "^0.5.1", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "mkdirp": "~0.5.0", - "node-libs-browser": "^2.0.0", - "source-map": "^0.5.3", - "supports-color": "^4.2.1", - "tapable": "^0.2.7", - "uglifyjs-webpack-plugin": "^0.4.6", - "watchpack": "^1.4.0", - "webpack-sources": "^1.0.1", - "yargs": "^8.0.2" - }, - "dependencies": { - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "webpack": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.12.0.tgz", + "integrity": "sha512-Sw7MdIIOv/nkzPzee4o0EdvCuPmxT98+vVpIvwtcwcF1Q4SDSNp92vwcKc4REe7NItH9f1S4ra9FuQ7yuYZ8bQ==", + "dev": true, + "requires": { + "acorn": "^5.0.0", + "acorn-dynamic-import": "^2.0.0", + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "async": "^2.1.2", + "enhanced-resolve": "^3.4.0", + "escope": "^3.6.0", + "interpret": "^1.0.0", + "json-loader": "^0.5.4", + "json5": "^0.5.1", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "mkdirp": "~0.5.0", + "node-libs-browser": "^2.0.0", + "source-map": "^0.5.3", + "supports-color": "^4.2.1", + "tapable": "^0.2.7", + "uglifyjs-webpack-plugin": "^0.4.6", + "watchpack": "^1.4.0", + "webpack-sources": "^1.0.1", + "yargs": "^8.0.2" + }, + "dependencies": { + "ajv": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", + "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" } } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", - "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "read-pkg-up": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^7.0.0" - } - }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } } - } - }, - "webpack-bundle-analyzer": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.6.0.tgz", - "integrity": "sha512-orUfvVYEfBMDXgEKAKVvab5iQ2wXneIEorGNsyuOyVYpjYrI7CUOhhXNDd3huMwQ3vNNWWlGP+hzflMFYNzi2g==", - "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-walk": "^6.1.1", - "bfj": "^6.1.1", - "chalk": "^2.4.1", - "commander": "^2.18.0", - "ejs": "^2.6.1", - "express": "^4.16.3", - "filesize": "^3.6.1", - "gzip-size": "^5.0.0", - "lodash": "^4.17.15", - "mkdirp": "^0.5.1", - "opener": "^1.5.1", - "ws": "^6.0.0" - }, - "dependencies": { - "acorn": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", - "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", - "dev": true - }, - "ejs": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", - "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", - "dev": true - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } } } + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } } - }, - "webpack-core": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", - "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", - "dev": true, - "requires": { - "source-list-map": "~0.1.7", - "source-map": "~0.4.1" - }, - "dependencies": { - "source-list-map": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", - "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", - "dev": true - }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } + } + }, + "webpack-bundle-analyzer": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.6.0.tgz", + "integrity": "sha512-orUfvVYEfBMDXgEKAKVvab5iQ2wXneIEorGNsyuOyVYpjYrI7CUOhhXNDd3huMwQ3vNNWWlGP+hzflMFYNzi2g==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-walk": "^6.1.1", + "bfj": "^6.1.1", + "chalk": "^2.4.1", + "commander": "^2.18.0", + "ejs": "^2.6.1", + "express": "^4.16.3", + "filesize": "^3.6.1", + "gzip-size": "^5.0.0", + "lodash": "^4.17.15", + "mkdirp": "^0.5.1", + "opener": "^1.5.1", + "ws": "^6.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", + "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", + "dev": true + }, + "ejs": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", + "dev": true + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" } } - }, - "webpack-dev-middleware": { - "version": "2.0.6", - "resolved": "http://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-2.0.6.tgz", - "integrity": "sha512-tj5LLD9r4tDuRIDa5Mu9lnY2qBBehAITv6A9irqXhw/HQquZgTx3BCd57zYbU2gMDnncA49ufK2qVQSbaKJwOw==", - "dev": true, - "requires": { - "loud-rejection": "^1.6.0", - "memory-fs": "~0.4.1", - "mime": "^2.1.0", - "path-is-absolute": "^1.0.0", - "range-parser": "^1.0.3", - "url-join": "^2.0.2", - "webpack-log": "^1.0.1" - }, - "dependencies": { - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "dev": true + } + }, + "webpack-core": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", + "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", + "dev": true, + "requires": { + "source-list-map": "~0.1.7", + "source-map": "~0.4.1" + }, + "dependencies": { + "source-list-map": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", + "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", + "dev": true + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" } } - }, - "webpack-log": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", - "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "log-symbols": "^2.1.0", - "loglevelnext": "^1.0.1", - "uuid": "^3.1.0" + } + }, + "webpack-dev-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-2.0.6.tgz", + "integrity": "sha512-tj5LLD9r4tDuRIDa5Mu9lnY2qBBehAITv6A9irqXhw/HQquZgTx3BCd57zYbU2gMDnncA49ufK2qVQSbaKJwOw==", + "dev": true, + "requires": { + "loud-rejection": "^1.6.0", + "memory-fs": "~0.4.1", + "mime": "^2.1.0", + "path-is-absolute": "^1.0.0", + "range-parser": "^1.0.3", + "url-join": "^2.0.2", + "webpack-log": "^1.0.1" + }, + "dependencies": { + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "dev": true } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + } + }, + "webpack-log": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", + "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", + "dev": true, + "requires": { + "chalk": "^2.1.0", + "log-symbols": "^2.1.0", + "loglevelnext": "^1.0.1", + "uuid": "^3.1.0" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } - }, - "webpack-stream": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/webpack-stream/-/webpack-stream-3.2.0.tgz", - "integrity": "sha1-Oh0WD7EdQXJ7fObzL3IkZPmLIYY=", - "dev": true, - "requires": { - "gulp-util": "^3.0.7", - "lodash.clone": "^4.3.2", - "lodash.some": "^4.2.2", - "memory-fs": "^0.3.0", - "through": "^2.3.8", - "vinyl": "^1.1.0", - "webpack": "^1.12.9" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "browserify-aes": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-0.4.0.tgz", - "integrity": "sha1-BnFJtmjfMcS1hTPgLQHoBthgjiw=", - "dev": true, - "requires": { - "inherits": "^2.0.1" - } - }, - "browserify-zlib": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", - "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", - "dev": true, - "requires": { - "pako": "~0.2.0" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" - } - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "crypto-browserify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.3.0.tgz", - "integrity": "sha1-ufx1u0oO1h3PHNXa6W6zDJw+UGw=", - "dev": true, - "requires": { - "browserify-aes": "0.4.0", - "pbkdf2-compat": "2.0.1", - "ripemd160": "0.2.0", - "sha.js": "2.2.6" - } - }, - "enhanced-resolve": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", - "integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.2.0", - "tapable": "^0.1.8" - }, - "dependencies": { - "memory-fs": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", - "integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=", - "dev": true - } - } - }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "https-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", - "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", - "dev": true - }, - "interpret": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-0.6.6.tgz", - "integrity": "sha1-/s16GOfOXKar+5U+H4YhOknxYls=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - }, - "memory-fs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.3.0.tgz", - "integrity": "sha1-e8xrYp46Q+hx1+Kaymrop/FcuyA=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "node-libs-browser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-0.7.0.tgz", - "integrity": "sha1-PicsCBnjCJNeJmdECNevDhSRuDs=", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.1.4", - "buffer": "^4.9.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "3.3.0", - "domain-browser": "^1.1.1", - "events": "^1.0.0", - "https-browserify": "0.0.1", - "os-browserify": "^0.2.0", - "path-browserify": "0.0.0", - "process": "^0.11.0", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.0.5", - "stream-browserify": "^2.0.1", - "stream-http": "^2.3.1", - "string_decoder": "^0.10.25", - "timers-browserify": "^2.0.2", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.10.3", - "vm-browserify": "0.0.4" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "os-browserify": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", - "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", - "dev": true - }, - "pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", - "dev": true - }, - "path-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "ripemd160": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-0.2.0.tgz", - "integrity": "sha1-K/GYveFnys+lHAqSjoS2i74XH84=", - "dev": true - }, - "sha.js": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.2.6.tgz", - "integrity": "sha1-F93t3F9yL7ZlAWWIlUYZd4ZzFbo=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - }, - "tapable": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", - "integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=", - "dev": true - }, - "uglify-js": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.7.5.tgz", - "integrity": "sha1-RhLAx7qu4rp8SH3kkErhIgefLKg=", - "dev": true, - "requires": { - "async": "~0.2.6", - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", - "dev": true - } - } - }, - "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - }, - "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true, - "requires": { - "indexof": "0.0.1" - } - }, - "watchpack": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-0.2.9.tgz", - "integrity": "sha1-Yuqkq15bo1/fwBgnVibjwPXj+ws=", - "dev": true, - "requires": { - "async": "^0.9.0", - "chokidar": "^1.0.0", - "graceful-fs": "^4.1.2" - }, - "dependencies": { - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", - "dev": true - } - } - }, - "webpack": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-1.15.0.tgz", - "integrity": "sha1-T/MfU9sDM55VFkqdRo7gMklo/pg=", - "dev": true, - "requires": { - "acorn": "^3.0.0", - "async": "^1.3.0", - "clone": "^1.0.2", - "enhanced-resolve": "~0.9.0", - "interpret": "^0.6.4", - "loader-utils": "^0.2.11", - "memory-fs": "~0.3.0", - "mkdirp": "~0.5.0", - "node-libs-browser": "^0.7.0", - "optimist": "~0.6.0", - "supports-color": "^3.1.0", - "tapable": "~0.1.8", - "uglify-js": "~2.7.3", - "watchpack": "^0.2.1", - "webpack-core": "~0.6.9" + } + }, + "webpack-stream": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/webpack-stream/-/webpack-stream-3.2.0.tgz", + "integrity": "sha1-Oh0WD7EdQXJ7fObzL3IkZPmLIYY=", + "dev": true, + "requires": { + "gulp-util": "^3.0.7", + "lodash.clone": "^4.3.2", + "lodash.some": "^4.2.2", + "memory-fs": "^0.3.0", + "through": "^2.3.8", + "vinyl": "^1.1.0", + "webpack": "^1.12.9" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "browserify-aes": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-0.4.0.tgz", + "integrity": "sha1-BnFJtmjfMcS1hTPgLQHoBthgjiw=", + "dev": true, + "requires": { + "inherits": "^2.0.1" + } + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true, + "requires": { + "pako": "~0.2.0" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "crypto-browserify": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.3.0.tgz", + "integrity": "sha1-ufx1u0oO1h3PHNXa6W6zDJw+UGw=", + "dev": true, + "requires": { + "browserify-aes": "0.4.0", + "pbkdf2-compat": "2.0.1", + "ripemd160": "0.2.0", + "sha.js": "2.2.6" + } + }, + "enhanced-resolve": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", + "integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.2.0", + "tapable": "^0.1.8" + }, + "dependencies": { + "memory-fs": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", + "integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=", + "dev": true } - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" + } + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "^2.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dev": true, + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "https-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", + "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", + "dev": true + }, + "interpret": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-0.6.6.tgz", + "integrity": "sha1-/s16GOfOXKar+5U+H4YhOknxYls=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + }, + "memory-fs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.3.0.tgz", + "integrity": "sha1-e8xrYp46Q+hx1+Kaymrop/FcuyA=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "node-libs-browser": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-0.7.0.tgz", + "integrity": "sha1-PicsCBnjCJNeJmdECNevDhSRuDs=", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.1.4", + "buffer": "^4.9.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "3.3.0", + "domain-browser": "^1.1.1", + "events": "^1.0.0", + "https-browserify": "0.0.1", + "os-browserify": "^0.2.0", + "path-browserify": "0.0.0", + "process": "^0.11.0", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.0.5", + "stream-browserify": "^2.0.1", + "stream-http": "^2.3.1", + "string_decoder": "^0.10.25", + "timers-browserify": "^2.0.2", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.10.3", + "vm-browserify": "0.0.4" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "os-browserify": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", + "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", + "dev": true + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "ripemd160": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-0.2.0.tgz", + "integrity": "sha1-K/GYveFnys+lHAqSjoS2i74XH84=", + "dev": true + }, + "sha.js": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.2.6.tgz", + "integrity": "sha1-F93t3F9yL7ZlAWWIlUYZd4ZzFbo=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + }, + "tapable": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", + "integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=", + "dev": true + }, + "uglify-js": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.7.5.tgz", + "integrity": "sha1-RhLAx7qu4rp8SH3kkErhIgefLKg=", + "dev": true, + "requires": { + "async": "~0.2.6", + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true } } - } - }, - "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", - "dev": true, - "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", - "dev": true - }, - "wgxpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wgxpath/-/wgxpath-1.0.0.tgz", - "integrity": "sha1-7vikudVYzEla06mit1FZfs2a9pA=", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" - }, - "whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "watchpack": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-0.2.9.tgz", + "integrity": "sha1-Yuqkq15bo1/fwBgnVibjwPXj+ws=", + "dev": true, + "requires": { + "async": "^0.9.0", + "chokidar": "^1.0.0", + "graceful-fs": "^4.1.2" + }, + "dependencies": { + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true } } + }, + "webpack": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-1.15.0.tgz", + "integrity": "sha1-T/MfU9sDM55VFkqdRo7gMklo/pg=", + "dev": true, + "requires": { + "acorn": "^3.0.0", + "async": "^1.3.0", + "clone": "^1.0.2", + "enhanced-resolve": "~0.9.0", + "interpret": "^0.6.4", + "loader-utils": "^0.2.11", + "memory-fs": "~0.3.0", + "mkdirp": "~0.5.0", + "node-libs-browser": "^0.7.0", + "optimist": "~0.6.0", + "supports-color": "^3.1.0", + "tapable": "~0.1.8", + "uglify-js": "~2.7.3", + "watchpack": "^0.2.1", + "webpack-core": "~0.6.9" + } + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "wrench": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/wrench/-/wrench-1.3.9.tgz", - "integrity": "sha1-bxPsNRRTF+spLKX2UxORskQRFBE=" - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "write-file-atomic": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", - "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "requires": { - "async-limiter": "~1.0.0" - } - }, - "x-is-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", - "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", - "dev": true - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" - }, - "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yargs": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.3.3.tgz", - "integrity": "sha1-BU3oth8i7v23IHBZ6u+da4P7kxo=", - "dev": true - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "dev": true - }, - "zip-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", - "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", - "dev": true, - "requires": { - "archiver-utils": "^1.3.0", - "compress-commons": "^1.2.0", - "lodash": "^4.8.0", - "readable-stream": "^2.0.0" + } + }, + "websocket-driver": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "dev": true + }, + "wgxpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wgxpath/-/wgxpath-1.0.0.tgz", + "integrity": "sha1-7vikudVYzEla06mit1FZfs2a9pA=", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } } } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", + "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", + "dev": true + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.3.3.tgz", + "integrity": "sha1-BU3oth8i7v23IHBZ6u+da4P7kxo=", + "dev": true + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + }, + "zip-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", + "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "dev": true, + "requires": { + "archiver-utils": "^1.3.0", + "compress-commons": "^1.2.0", + "lodash": "^4.8.0", + "readable-stream": "^2.0.0" + } } } - \ No newline at end of file +} diff --git a/package.json b/package.json index 3b7307bc581..bfbe2f2f8b3 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.8.0-pre", + "version": "3.7.1", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From a973ad501da7e010743a527b4c032e490275752c Mon Sep 17 00:00:00 2001 From: Jason Snellbaker Date: Thu, 13 Feb 2020 13:54:12 -0500 Subject: [PATCH 054/496] increment the pre version --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3e205ff2e30..cd48008ba20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.7.1", + "version": "3.8.0-pre", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index bfbe2f2f8b3..3b7307bc581 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.7.1", + "version": "3.8.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From aab8d6813c1175a407e1934a72beccedc3232a7c Mon Sep 17 00:00:00 2001 From: Hugo Duthil Date: Thu, 13 Feb 2020 20:59:48 +0100 Subject: [PATCH 055/496] Remove deprecated Criteo Rtus Module (#4835) This module is deprecated and should not be used anymore. The Criteo ID for Exchanges module should be used instead. It is available here --- modules/.submodules.json | 1 - modules/criteortusIdSystem.js | 106 ------------------- test/spec/modules/criteortusIdSystem_spec.js | 87 --------------- 3 files changed, 194 deletions(-) delete mode 100644 modules/criteortusIdSystem.js delete mode 100644 test/spec/modules/criteortusIdSystem_spec.js diff --git a/modules/.submodules.json b/modules/.submodules.json index 3572dc2e303..a6473a51200 100644 --- a/modules/.submodules.json +++ b/modules/.submodules.json @@ -4,7 +4,6 @@ "pubCommonIdSystem", "digiTrustIdSystem", "id5IdSystem", - "criteortusIdSystem", "parrableIdSystem", "britepoolIdSystem", "liveIntentIdSystem", diff --git a/modules/criteortusIdSystem.js b/modules/criteortusIdSystem.js deleted file mode 100644 index 8486bfae9f3..00000000000 --- a/modules/criteortusIdSystem.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * This module adds Criteo Real Time User Sync to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/criteortusIdSystem - * @requires module:modules/userId - */ - -import * as utils from '../src/utils' -import { ajax } from '../src/ajax'; -import { submodule } from '../src/hook'; - -const key = '__pbjs_criteo_rtus'; - -/** @type {Submodule} */ -export const criteortusIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: 'criteortus', - /** - * decode the stored id value for passing to bid requests - * @function - * @returns {{criteortus:Object}} - */ - decode() { - let uid = utils.getCookie(key); - try { - uid = JSON.parse(uid); - return { 'criteortus': uid }; - } catch (error) { - utils.logError('Error in parsing criteo rtus data', error); - } - }, - /** - * performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleParams} [configParams] - * @returns {IdResponse|undefined} - */ - getId(configParams) { - if (!configParams || !utils.isPlainObject(configParams.clientIdentifier)) { - utils.logError('User ID - Criteo rtus requires client identifier to be defined'); - return; - } - - let uid = utils.getCookie(key); - if (uid) { - return {id: uid}; - } else { - let userIds = {}; - const resp = function(callback) { - let bidders = Object.keys(configParams.clientIdentifier); - - function afterAllResponses() { - // criteo rtus user id expires in 1 hour - const expiresStr = (new Date(Date.now() + (60 * 60 * 1000))).toUTCString(); - utils.setCookie(key, JSON.stringify(userIds), expiresStr); - callback(userIds); - } - - const onResponse = utils.delayExecution(afterAllResponses, bidders.length); - - bidders.forEach((bidder) => { - let url = `https://gum.criteo.com/sync?c=${configParams.clientIdentifier[bidder]}&r=3`; - const getSuccessHandler = (bidder) => { - return function onSuccess(response) { - if (response) { - try { - response = JSON.parse(response); - userIds[bidder] = response; - onResponse(); - } catch (error) { - utils.logError(error); - } - } - } - } - - const getFailureHandler = (bidder) => { - return function onFailure(error) { - utils.logError(`Criteo RTUS server call failed for ${bidder}`, error); - onResponse(); - } - } - - ajax( - url, - { - success: getSuccessHandler(bidder), - error: getFailureHandler(bidder) - }, - undefined, - Object.assign({ - method: 'GET', - withCredentials: true - }) - ); - }) - }; - return {callback: resp}; - } - } -}; - -submodule('userId', criteortusIdSubmodule); diff --git a/test/spec/modules/criteortusIdSystem_spec.js b/test/spec/modules/criteortusIdSystem_spec.js deleted file mode 100644 index 6ceaa7aa953..00000000000 --- a/test/spec/modules/criteortusIdSystem_spec.js +++ /dev/null @@ -1,87 +0,0 @@ -import { criteortusIdSubmodule } from 'modules/criteortusIdSystem'; -import * as utils from 'src/utils'; -import { server } from 'test/mocks/xhr'; - -describe('Criteo RTUS', function() { - let xhr; - let requests; - let getCookieStub; - let logErrorStub; - - beforeEach(function () { - getCookieStub = sinon.stub(utils, 'getCookie'); - logErrorStub = sinon.stub(utils, 'logError'); - }); - - afterEach(function () { - getCookieStub.restore(); - logErrorStub.restore(); - }); - - it('should log error when configParams are not passed', function() { - criteortusIdSubmodule.getId(); - expect(logErrorStub.calledOnce).to.be.true; - }) - - it('should call criteo endpoint to get user id', function() { - getCookieStub.returns(null); - let configParams = { - clientIdentifier: { - 'sampleBidder': 1 - } - } - - let response = { 'status': 'ok', 'userid': 'sample-userid' } - let callBackSpy = sinon.spy(); - const idResp = criteortusIdSubmodule.getId(configParams); - const submoduleCallback = idResp.callback; - submoduleCallback(callBackSpy); - server.requests[0].respond( - 200, - { 'Content-Type': 'text/plain' }, - JSON.stringify(response) - ); - expect(callBackSpy.calledOnce).to.be.true; - expect(callBackSpy.calledWith({'sampleBidder': response})).to.be.true; - }) - - it('should get uid from cookie and not call endpoint', function() { - let response = {'appnexus': {'status': 'ok', 'userid': 'sample-userid'}} - getCookieStub.returns(JSON.stringify(response)); - let configParams = { - clientIdentifier: { - 'sampleBidder': 1 - } - } - let uid = criteortusIdSubmodule.getId(configParams); - expect(server.requests.length).to.equal(0); - }) - - it('should call criteo endpoint for multiple bidders', function() { - getCookieStub.returns(null); - let configParams = { - clientIdentifier: { - 'sampleBidder': 1, - 'sampleBidder2': 2 - } - } - - let response = { 'status': 'ok', 'userid': 'sample-userid' } - let callBackSpy = sinon.spy(); - const idResp = criteortusIdSubmodule.getId(configParams); - const submoduleCallback = idResp.callback; - submoduleCallback(callBackSpy); - server.requests[0].respond( - 200, - { 'Content-Type': 'text/plain' }, - JSON.stringify(response) - ); - expect(callBackSpy.calledOnce).to.be.false; - server.requests[1].respond( - 200, - { 'Content-Type': 'text/plain' }, - JSON.stringify(response) - ); - expect(callBackSpy.calledOnce).to.be.true; - }) -}); From 3c68054099d0ee815deaedf0f59acf83d956880e Mon Sep 17 00:00:00 2001 From: OneTagDevOps <38786435+OneTagDevOps@users.noreply.github.com> Date: Fri, 14 Feb 2020 18:28:09 +0100 Subject: [PATCH 056/496] onetagBidAdapter: added CCPA support (#4857) * Aggiunge il passaggio della stringa di privacy ccpa * Cambia nome variabile us privacy in getUserSyncs --- modules/onetagBidAdapter.js | 14 +++++++++++--- test/spec/modules/onetagBidAdapter_spec.js | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/modules/onetagBidAdapter.js b/modules/onetagBidAdapter.js index 77c257fd7fb..9c4f7ea09b6 100644 --- a/modules/onetagBidAdapter.js +++ b/modules/onetagBidAdapter.js @@ -53,6 +53,10 @@ function buildRequests(validBidRequests, bidderRequest) { }; } + if (bidderRequest && bidderRequest.uspConsent) { + payload.usPrivacy = bidderRequest.uspConsent; + } + const payloadString = JSON.stringify(payload); return { @@ -63,7 +67,7 @@ function buildRequests(validBidRequests, bidderRequest) { } function interpretResponse(serverResponse, request) { - var body = serverResponse.body; + let body = serverResponse.body; const bids = []; if (typeof serverResponse === 'string') { @@ -104,7 +108,7 @@ function interpretResponse(serverResponse, request) { * @returns {{location: *, referrer: (*|string), masked: *, wWidth: (*|Number), wHeight: (*|Number), sWidth, sHeight, date: string, timeOffset: number}} */ function getPageInfo() { - var w, d, l, r, m, p, e, t, s; + let w, d, l, r, m, p, e, t, s; for (w = window, d = w.document, l = d.location.href, r = d.referrer, m = 0, e = encodeURIComponent, t = new Date(), s = screen; w !== w.parent;) { try { p = w.parent; l = p.location.href; r = p.document.referrer; w = p; @@ -170,7 +174,7 @@ function requestsToBids(bid) { return toRet; } -function getUserSyncs(syncOptions, serverResponses, gdprConsent) { +function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) { const syncs = []; if (syncOptions.iframeEnabled) { const rnd = new Date().getTime(); @@ -183,6 +187,10 @@ function getUserSyncs(syncOptions, serverResponses, gdprConsent) { } } + if (uspConsent && typeof uspConsent === 'string') { + params += '&us_privacy=' + uspConsent; + } + syncs.push({ type: 'iframe', url: USER_SYNC_ENDPOINT + params diff --git a/test/spec/modules/onetagBidAdapter_spec.js b/test/spec/modules/onetagBidAdapter_spec.js index 93284566069..9a6a8697651 100644 --- a/test/spec/modules/onetagBidAdapter_spec.js +++ b/test/spec/modules/onetagBidAdapter_spec.js @@ -113,6 +113,21 @@ describe('onetag', function () { expect(payload.gdprConsent.consentString).to.exist.and.to.equal(consentString); expect(payload.gdprConsent.consentRequired).to.exist.and.to.be.true; }); + it('should send us privacy string', function () { + let consentString = 'us_foo'; + let bidderRequest = { + 'bidderCode': 'onetag', + 'auctionId': '1d1a030790a475', + 'bidderRequestId': '22edbae2733bf6', + 'timeout': 3000, + 'uspConsent': consentString + }; + let serverRequest = spec.buildRequests([bid], bidderRequest); + const payload = JSON.parse(serverRequest.data); + + expect(payload.usPrivacy).to.exist; + expect(payload.usPrivacy).to.exist.and.to.equal(consentString); + }); }); describe('interpretResponse', function () { const resObject = { @@ -204,5 +219,12 @@ describe('onetag', function () { expect(syncs[0].url).to.include(sync_endpoint); expect(syncs[0].url).to.not.match(/(?:[?&](?:gdpr_consent=([^&]*)|gdpr=([^&]*)))+$/); }); + it('Should send us privacy string', function () { + let usConsentString = 'us_foo'; + const syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, {}, usConsentString); + expect(syncs[0].type).to.equal('iframe'); + expect(syncs[0].url).to.include(sync_endpoint); + expect(syncs[0].url).to.match(/(?:[?&](?:us_privacy=us_foo(?:[&][^&]*)*))+$/); + }); }); }); From 5b53b378e8791b32419aed723846c9ead6de5499 Mon Sep 17 00:00:00 2001 From: RAJKUMAR NATARAJAN Date: Sun, 16 Feb 2020 03:07:13 -0500 Subject: [PATCH 057/496] Implemented schain support for prebid and updated documentation examples for prebid3.0 (#4844) * Implemented schain support for prebid and updated documentation examples for prebid 3.0 * fix build failure --- modules/synacormediaBidAdapter.js | 9 ++ modules/synacormediaBidAdapter.md | 8 +- .../modules/synacormediaBidAdapter_spec.js | 92 +++++++++++++++++++ 3 files changed, 106 insertions(+), 3 deletions(-) diff --git a/modules/synacormediaBidAdapter.js b/modules/synacormediaBidAdapter.js index 3064ac2063b..3412d2fd417 100644 --- a/modules/synacormediaBidAdapter.js +++ b/modules/synacormediaBidAdapter.js @@ -44,6 +44,15 @@ export const spec = { }, imp: [] }; + + if (bidderRequest.bids != undefined && bidderRequest.bids[0] != undefined) { + const schain = bidderRequest.bids[0].schain; + if (schain) { + openRtbBidRequest.source = {}; + openRtbBidRequest.source.ext = { schain }; + } + } + let seatId = null; validBidReqs.forEach((bid, i) => { diff --git a/modules/synacormediaBidAdapter.md b/modules/synacormediaBidAdapter.md index 3a00aa45fed..857cf15d240 100644 --- a/modules/synacormediaBidAdapter.md +++ b/modules/synacormediaBidAdapter.md @@ -24,9 +24,11 @@ https://track.technoratimedia.com/openrtb/tags?ID=%%PATTERN:hb_cache_id_synacorm ``` var adUnits = [{ code: 'test-div', - sizes: [ - [300, 250] - ], + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, bids: [{ bidder: "synacormedia", params: { diff --git a/test/spec/modules/synacormediaBidAdapter_spec.js b/test/spec/modules/synacormediaBidAdapter_spec.js index 918e4e394bd..41194cbdf51 100644 --- a/test/spec/modules/synacormediaBidAdapter_spec.js +++ b/test/spec/modules/synacormediaBidAdapter_spec.js @@ -535,6 +535,98 @@ describe('synacormediaBidAdapter ', function () { }); }); + describe('Bid Requests with schain object ', function() { + let validBidReq = { + bidder: 'synacormedia', + params: { + seatId: 'prebid', + placementId: 'demo1', + pos: 1, + video: {} + }, + renderer: { + url: '../syncOutstreamPlayer.js' + }, + mediaTypes: { + video: { + playerSize: [[300, 250]], + context: 'outstream' + } + }, + adUnitCode: 'div-1', + transactionId: '0869f34e-090b-4b20-84ee-46ff41405a39', + sizes: [[300, 250]], + bidId: '22b3a2268d9f0e', + bidderRequestId: '1d195910597e13', + auctionId: '3375d336-2aea-4ee7-804c-6d26b621ad20', + src: 'client', + bidRequestsCount: 1, + bidderRequestsCount: 1, + bidderWinsCount: 0 + }; + let bidderRequest = { + refererInfo: { + referer: 'http://localhost:9999/' + }, + bidderCode: 'synacormedia', + auctionId: 'f8a75621-d672-4cbb-9275-3db7d74fb110', + bidderRequestId: '16d438671bfbec', + bids: [ + { + bidder: 'synacormedia', + params: { + seatId: 'prebid', + placementId: 'demo1', + pos: 1, + video: {} + }, + renderer: { + url: '../syncOutstreamPlayer.js' + }, + mediaTypes: { + video: { + playerSize: [[300, 250]], + context: 'outstream' + } + }, + adUnitCode: 'div-1', + sizes: [[300, 250]], + bidId: '211c0236bb8f4e', + bidderRequestId: '16d438671bfbec', + auctionId: 'f8a75621-d672-4cbb-9275-3db7d74fb110', + src: 'client', + bidRequestsCount: 1, + bidderRequestsCount: 1, + bidderWinsCount: 0, + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + hp: 1 + } + ] + } + } + ], + auctionStart: 1580310345205, + timeout: 1000, + start: 1580310345211 + }; + + it('should return valid bid request with schain object', function () { + let req = spec.buildRequests([validBidReq], bidderRequest); + expect(req).to.have.property('method', 'POST'); + expect(req).to.have.property('url'); + expect(req.url).to.contain('//prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$'); + expect(req.data).to.have.property('source'); + expect(req.data.source).to.have.property('ext'); + expect(req.data.source.ext).to.have.property('schain'); + }); + }); + describe('interpretResponse', function () { let bidResponse = { id: '10865933907263896~9998~0', From 05c19b5f1d138e6e45d4e819c5d26d77af41bb3c Mon Sep 17 00:00:00 2001 From: susyt Date: Sun, 16 Feb 2020 16:39:25 -0800 Subject: [PATCH 058/496] GumGum: adds support for video (#4848) * pass us privacy consent string to request * passes bid response currency * adds test for passing bid response currency * implements video support * fix linting --- modules/gumgumBidAdapter.js | 64 +++++++++++++++++++--- test/spec/modules/gumgumBidAdapter_spec.js | 34 +++++++++++- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index 894e3ac1b0c..208772f6834 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -1,6 +1,7 @@ import * as utils from '../src/utils' import { config } from '../src/config' +import { BANNER, VIDEO } from '../src/mediaTypes'; import includes from 'core-js/library/fn/array/includes'; import { registerBidder } from '../src/adapters/bidderFactory' @@ -8,6 +9,7 @@ const BIDDER_CODE = 'gumgum' const ALIAS_BIDDER_CODE = ['gg'] const BID_ENDPOINT = `https://g2.gumgum.com/hbid/imp` const DT_CREDENTIALS = { member: 'YcXr87z2lpbB' } +const SUPPORTED_MEDIA_TYPES = [BANNER, VIDEO] const TIME_TO_LIVE = 60 let browserParams = {}; @@ -23,7 +25,7 @@ function _getBrowserParams(topWindowUrl) { function getNetworkSpeed () { const connection = window.navigator && (window.navigator.connection || window.navigator.mozConnection || window.navigator.webkitConnection) const Mbps = connection && (connection.downlink || connection.bandwidth) - return Mbps ? Math.round(Mbps * 1024) : null // 1 megabit -> 1024 kilobits + return Mbps ? Math.round(Mbps * 1024) : null } function getOgURL () { let ogURL = '' @@ -136,6 +138,7 @@ function isBidRequestValid (bid) { case !!(params.inScreen): break; case !!(params.inSlot): break; case !!(params.ICV): break; + case !!(params.video): break; default: utils.logWarn(`[GumGum] No product selected for the placement ${adUnitCode}, please check your implementation.`); return false; @@ -149,6 +152,41 @@ function isBidRequestValid (bid) { return true; } +/** + * Renames vid params from mediatypes.video keys + * @param {Object} attributes + * @returns {Object} + */ +function _getVidParams (attributes) { + const { + minduration: mind, + maxduration: maxd, + linearity: li, + startdelay: sd, + placement: pt, + protocols = [], + playerSize = [] + } = attributes; + const sizes = utils.parseSizesInput(playerSize); + const [viw, vih] = sizes[0] && sizes[0].split('x'); + let pr = ''; + + if (protocols.length) { + pr = protocols.join(','); + } + + return { + mind, + maxd, + li, + sd, + pt, + pr, + viw, + vih + }; +} + /** * Make a server request from the list of BidRequests. * @@ -159,20 +197,22 @@ function buildRequests (validBidRequests, bidderRequest) { const bids = []; const gdprConsent = bidderRequest && bidderRequest.gdprConsent; const uspConsent = bidderRequest && bidderRequest.uspConsent; + const timeout = config.getConfig('bidderTimeout'); + const topWindowUrl = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer; utils._each(validBidRequests, bidRequest => { - const timeout = config.getConfig('bidderTimeout'); const { bidId, + mediaTypes = {}, params = {}, schain, transactionId, userId = {} } = bidRequest; - const data = {}; - const sizes = bidRequest.mediaTypes && bidRequest.mediaTypes.banner && bidRequest.mediaTypes.banner.sizes; - const topWindowUrl = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer; + const bannerSizes = mediaTypes.banner && mediaTypes.banner.sizes; + let data = {}; + if (pageViewId) { - data.pv = pageViewId + data.pv = pageViewId; } if (params.bidfloor) { data.fp = params.bidfloor; @@ -193,6 +233,12 @@ function buildRequests (validBidRequests, bidderRequest) { data.ni = parseInt(params.ICV, 10); data.pi = 5; } + if (params.video) { + data = Object.assign(data, _getVidParams(mediaTypes.video)); + data.t = params.video; + data.pi = 7; + } + if (gdprConsent) { data.gdprApplies = gdprConsent.gdprApplies ? 1 : 0; } @@ -212,7 +258,7 @@ function buildRequests (validBidRequests, bidderRequest) { tId: transactionId, pi: data.pi, selector: params.selector, - sizes: sizes || bidRequest.sizes, + sizes: bannerSizes || bidRequest.sizes, url: BID_ENDPOINT, method: 'GET', data: Object.assign(data, _getBrowserParams(topWindowUrl), _getDigiTrustQueryParams(userId), _getTradeDeskIDParam(userId)) @@ -271,6 +317,7 @@ function interpretResponse (serverResponse, bidRequest) { bidResponses.push({ // dealId: DEAL_ID, // referrer: REFERER, + ...(product === 7 && { vastXml: markup }), ad: wrapper ? getWrapperCode(wrapper, Object.assign({}, serverResponseBody, { bidRequest })) : markup, cpm: isTestUnit ? 0.1 : cpm, creativeId, @@ -314,6 +361,7 @@ export const spec = { isBidRequestValid, buildRequests, interpretResponse, - getUserSyncs + getUserSyncs, + supportedMediaTypes: SUPPORTED_MEDIA_TYPES } registerBidder(spec) diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index f98d8bf306e..fb4c1bf7b30 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -106,7 +106,7 @@ describe('gumgumAdapter', function () { expect(request.method).to.equal('GET'); expect(request.id).to.equal('30b31c1838de1e'); }); - it('should correctly set the request paramters depending on params field', function () { + it('should set t and fp parameters in bid request if inScreen request param is found', function () { const request = Object.assign({}, bidRequests[0]); delete request.params; request.params = { @@ -129,7 +129,7 @@ describe('gumgumAdapter', function () { expect(bidRequest.data.pubId).to.equal(request.params.inScreenPubID); expect(bidRequest.data).to.not.include.any.keys('t'); }); - it('should correctly set the request paramters depending on params field', function () { + it('should set a ni parameter in bid request if ICV request param is found', function () { const request = Object.assign({}, bidRequests[0]); delete request.params; request.params = { @@ -139,6 +139,36 @@ describe('gumgumAdapter', function () { expect(bidRequest.data.pi).to.equal(5); expect(bidRequest.data).to.include.any.keys('ni'); }); + it('should add parameters associated with video if video request param is found', function () { + const videoVals = { + playerSize: [640, 480], + context: 'instream', + minduration: 1, + maxduration: 2, + linearity: 1, + startdelay: 1, + placement: 123456, + protocols: [1, 2] + }; + const request = Object.assign({}, bidRequests[0]); + delete request.params; + request.mediaTypes = { + video: videoVals + }; + request.params = { + 'video': '10433395' + }; + const bidRequest = spec.buildRequests([request])[0]; + expect(bidRequest.data.pi).to.eq(7); + expect(bidRequest.data.mind).to.eq(videoVals.minduration); + expect(bidRequest.data.maxd).to.eq(videoVals.maxduration); + expect(bidRequest.data.li).to.eq(videoVals.linearity); + expect(bidRequest.data.sd).to.eq(videoVals.startdelay); + expect(bidRequest.data.pt).to.eq(videoVals.placement); + expect(bidRequest.data.pr).to.eq(videoVals.protocols.join(',')); + expect(bidRequest.data.viw).to.eq(videoVals.playerSize[0].toString()); + expect(bidRequest.data.vih).to.eq(videoVals.playerSize[1].toString()); + }); it('should not add additional parameters depending on params field', function () { const request = spec.buildRequests(bidRequests)[0]; expect(request.data).to.not.include.any.keys('ni'); From d30b0a64ab90d7e85c62ef0d1dd7fbac78bf16c6 Mon Sep 17 00:00:00 2001 From: RAJKUMAR NATARAJAN Date: Wed, 19 Feb 2020 06:28:09 -0500 Subject: [PATCH 059/496] minor code changes for schain implementation (#4870) --- modules/synacormediaBidAdapter.js | 11 ++++------- test/spec/modules/synacormediaBidAdapter_spec.js | 13 ++++++++++++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/modules/synacormediaBidAdapter.js b/modules/synacormediaBidAdapter.js index 3412d2fd417..3879d676d99 100644 --- a/modules/synacormediaBidAdapter.js +++ b/modules/synacormediaBidAdapter.js @@ -45,12 +45,9 @@ export const spec = { imp: [] }; - if (bidderRequest.bids != undefined && bidderRequest.bids[0] != undefined) { - const schain = bidderRequest.bids[0].schain; - if (schain) { - openRtbBidRequest.source = {}; - openRtbBidRequest.source.ext = { schain }; - } + const schain = validBidReqs[0].schain; + if (schain) { + openRtbBidRequest.source = { ext: { schain } }; } let seatId = null; @@ -67,7 +64,7 @@ export const spec = { if (isNaN(bidFloor)) { logWarn(`Synacormedia: there is an invalid bid floor: ${bid.params.bidfloor}`); } - let pos = parseInt(bid.params.pos); + let pos = parseInt(bid.params.pos, 10); if (isNaN(pos)) { logWarn(`Synacormedia: there is an invalid POS: ${bid.params.pos}`); pos = 0; diff --git a/test/spec/modules/synacormediaBidAdapter_spec.js b/test/spec/modules/synacormediaBidAdapter_spec.js index 41194cbdf51..4f59fdd19e0 100644 --- a/test/spec/modules/synacormediaBidAdapter_spec.js +++ b/test/spec/modules/synacormediaBidAdapter_spec.js @@ -562,7 +562,18 @@ describe('synacormediaBidAdapter ', function () { src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, - bidderWinsCount: 0 + bidderWinsCount: 0, + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + hp: 1 + } + ] + } }; let bidderRequest = { refererInfo: { From a76a84d47bdc8bc117291cc137e27688d6b70964 Mon Sep 17 00:00:00 2001 From: vincentproxistore <56686565+vincentproxistore@users.noreply.github.com> Date: Wed, 19 Feb 2020 13:10:41 +0100 Subject: [PATCH 060/496] use all request id (#4849) --- modules/proxistoreBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/proxistoreBidAdapter.js b/modules/proxistoreBidAdapter.js index 32e6daf3096..f9c3a0f3cc0 100644 --- a/modules/proxistoreBidAdapter.js +++ b/modules/proxistoreBidAdapter.js @@ -9,7 +9,7 @@ function _mapSizes(sizes) { function _createServerRequest(bidRequests, bidderRequest) { const payload = { - bidId: bidRequests.map(req => req.bidId)[0], + bidId: bidRequests.map(req => req.bidId), auctionId: bidRequests[0].auctionId, transactionId: bidRequests[0].transactionId, sizes: _mapSizes(bidRequests.map(x => x.sizes)), From 7df057b270cb3d68a2725661f725a3baa0cfd14a Mon Sep 17 00:00:00 2001 From: SmartyAdman <59048845+SmartyAdman@users.noreply.github.com> Date: Wed, 19 Feb 2020 20:48:51 +0200 Subject: [PATCH 061/496] Restore adman bidadapter (#4839) * Add Adman bid adapter * Add supportedMediaTypes property * Update ADman Media bidder adapter * Remove console.log * Fix typo * revert package-json.lock * Delete package-lock.json * back to original package-lock.json * catch pbjs error * catch pbjs error * catch pbjs error * log * remove eu url * remove eu url * remove eu url * remove eu url * remove eu url Co-authored-by: mkatogi Co-authored-by: minokem <48562317+minokem@users.noreply.github.com> Co-authored-by: ADman Media --- modules/admanBidAdapter.js | 107 ++++++++++ modules/admanBidAdapter.md | 88 ++++++--- test/spec/modules/admanBidAdapter_spec.js | 231 ++++++++++++++++++++++ 3 files changed, 399 insertions(+), 27 deletions(-) create mode 100644 modules/admanBidAdapter.js create mode 100644 test/spec/modules/admanBidAdapter_spec.js diff --git a/modules/admanBidAdapter.js b/modules/admanBidAdapter.js new file mode 100644 index 00000000000..1ab545613ec --- /dev/null +++ b/modules/admanBidAdapter.js @@ -0,0 +1,107 @@ +import {registerBidder} from '../src/adapters/bidderFactory'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils'; + +const BIDDER_CODE = 'adman'; +const AD_URL = 'https://pub.admanmedia.com/?c=o&m=multi'; +const URL_SYNC = 'https://pub.admanmedia.com/?c=o&m=sync'; + +function isBidResponseValid(bid) { + if (!bid.requestId || !bid.cpm || !bid.creativeId || + !bid.ttl || !bid.currency) { + return false; + } + switch (bid['mediaType']) { + case BANNER: + return Boolean(bid.width && bid.height && bid.ad); + case VIDEO: + return Boolean(bid.vastUrl); + case NATIVE: + return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); + default: + return false; + } +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid: (bid) => { + return Boolean(bid.bidId && bid.params && !isNaN(bid.params.placementId)); + }, + + buildRequests: (validBidRequests = [], bidderRequest) => { + let winTop = window; + let location; + try { + location = new URL(bidderRequest.refererInfo.referer) + winTop = window.top; + } catch (e) { + location = winTop.location; + utils.logMessage(e); + }; + let placements = []; + let request = { + 'deviceWidth': winTop.screen.width, + 'deviceHeight': winTop.screen.height, + 'language': (navigator && navigator.language) ? navigator.language : '', + 'secure': 1, + 'host': location.host, + 'page': location.pathname, + 'placements': placements + }; + request.language.indexOf('-') != -1 && (request.language = request.language.split('-')[0]) + if (bidderRequest) { + if (bidderRequest.uspConsent) { + request.ccpa = bidderRequest.uspConsent; + } + if (bidderRequest.gdprConsent) { + request.gdpr = bidderRequest.gdprConsent + } + } + const len = validBidRequests.length; + + for (let i = 0; i < len; i++) { + let bid = validBidRequests[i]; + let traff = bid.params.traffic || BANNER + + placements.push({ + placementId: bid.params.placementId, + bidId: bid.bidId, + sizes: bid.mediaTypes && bid.mediaTypes[traff] && bid.mediaTypes[traff].sizes ? bid.mediaTypes[traff].sizes : [], + traffic: traff + }); + if (bid.schain) { + placements.schain = bid.schain; + } + } + return { + method: 'POST', + url: AD_URL, + data: request + }; + }, + + interpretResponse: (serverResponse) => { + let response = []; + serverResponse = serverResponse.body; + for (let i = 0; i < serverResponse.length; i++) { + let resItem = serverResponse[i]; + if (isBidResponseValid(resItem)) { + response.push(resItem); + } + } + return response; + }, + + getUserSyncs: (syncOptions, serverResponses) => { + return [{ + type: 'image', + url: URL_SYNC + }]; + } + +}; + +registerBidder(spec); diff --git a/modules/admanBidAdapter.md b/modules/admanBidAdapter.md index 900c828ea5c..07a268af489 100644 --- a/modules/admanBidAdapter.md +++ b/modules/admanBidAdapter.md @@ -1,35 +1,69 @@ # Overview -**Module Name**: Adman Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: prebid@admanmedia.com +``` +Module Name: adman Bidder Adapter +Module Type: Bidder Adapter +``` # Description -Use `adman` as bidder. +Module that connects to AdmanMedia' demand sources -`id` is required and must be 8 alphanumeric characters. - -## AdUnits configuration example +# Test Parameters ``` - var adUnits = [{ - code: 'test-div', - sizes: [[300, 250]], - bids: [{ - bidder: 'adman', - params: { - id: 1234asdf - } - }] - },{ - code: 'test-div, - sizes: [[600, 338]], - bids: [{ - bidder: 'adman', - params: { - id: asdf1234 - } - }] - }]; + var adUnits = [ + // Will return static native ad. Assets are stored through user UI for each placement separetly + { + code: 'placementId_0', + mediaTypes: { + native: {} + }, + bids: [ + { + bidder: 'adman', + params: { + placementId: 0, + traffic: 'native' + } + } + ] + }, + // Will return static test banner + { + code: 'placementId_0', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [ + { + bidder: 'adman', + params: { + placementId: 0, + traffic: 'banner' + } + } + ] + }, + // Will return test vast xml. All video params are stored under placement in publishers UI + { + code: 'placementId_0', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream' + } + }, + bids: [ + { + bidder: 'adman', + params: { + placementId: 0, + traffic: 'video' + } + } + ] + } + ]; ``` - diff --git a/test/spec/modules/admanBidAdapter_spec.js b/test/spec/modules/admanBidAdapter_spec.js new file mode 100644 index 00000000000..c39809b3b4f --- /dev/null +++ b/test/spec/modules/admanBidAdapter_spec.js @@ -0,0 +1,231 @@ +import {expect} from 'chai'; +import {spec} from '../../../modules/admanBidAdapter'; + +describe('AdmanMediaBidAdapter', function () { + let bid = { + bidId: '23fhj33i987f', + bidder: 'adman', + params: { + placementId: 0, + traffic: 'banner' + } + }; + + describe('isBidRequestValid', function () { + it('Should return true if there are bidId, params and placementId parameters present', function () { + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + it('Should return false if at least one of parameters is not present', function () { + delete bid.params.placementId; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests([bid]); + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + it('Returns valid URL', function () { + expect(serverRequest.url).to.equal('https://pub.admanmedia.com/?c=o&m=multi'); + }); + it('Returns valid data if array of bids is valid', function () { + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.language).to.be.a('string'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + let placement = data['placements'][0]; + expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes'); + expect(placement.placementId).to.equal(0); + expect(placement.bidId).to.equal('23fhj33i987f'); + expect(placement.traffic).to.equal('banner'); + }); + it('Returns empty data if no valid requests are passed', function () { + serverRequest = spec.buildRequests([]); + let data = serverRequest.data; + expect(data.placements).to.be.an('array').that.is.empty; + }); + }); + describe('interpretResponse', function () { + it('Should interpret banner response', function () { + const banner = { + body: [{ + mediaType: 'banner', + width: 300, + height: 250, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let bannerResponses = spec.interpretResponse(banner); + expect(bannerResponses).to.be.an('array').that.is.not.empty; + let dataItem = bannerResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.width).to.equal(300); + expect(dataItem.height).to.equal(250); + expect(dataItem.ad).to.equal('Test'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret video response', function () { + const video = { + body: [{ + vastUrl: 'test.com', + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let videoResponses = spec.interpretResponse(video); + expect(videoResponses).to.be.an('array').that.is.not.empty; + + let dataItem = videoResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.5); + expect(dataItem.vastUrl).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret native response', function () { + const native = { + body: [{ + mediaType: 'native', + native: { + clickUrl: 'test.com', + title: 'Test', + image: 'test.com', + impressionTrackers: ['test.com'], + }, + ttl: 120, + cpm: 0.4, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let nativeResponses = spec.interpretResponse(native); + expect(nativeResponses).to.be.an('array').that.is.not.empty; + + let dataItem = nativeResponses[0]; + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); + expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.native.clickUrl).to.equal('test.com'); + expect(dataItem.native.title).to.equal('Test'); + expect(dataItem.native.image).to.equal('test.com'); + expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; + expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should return an empty array if invalid banner response is passed', function () { + const invBanner = { + body: [{ + width: 300, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + + let serverResponses = spec.interpretResponse(invBanner); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid video response is passed', function () { + const invVideo = { + body: [{ + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invVideo); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid native response is passed', function () { + const invNative = { + body: [{ + mediaType: 'native', + clickUrl: 'test.com', + title: 'Test', + impressionTrackers: ['test.com'], + ttl: 120, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let serverResponses = spec.interpretResponse(invNative); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid response is passed', function () { + const invalid = { + body: [{ + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invalid); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); + describe('getUserSyncs', function () { + let userSync = spec.getUserSyncs(); + it('Returns valid URL and type', function () { + expect(userSync).to.be.an('array').with.lengthOf(1); + expect(userSync[0].type).to.exist; + expect(userSync[0].url).to.exist; + expect(userSync[0].type).to.be.equal('image'); + expect(userSync[0].url).to.be.equal('https://pub.admanmedia.com/?c=o&m=sync'); + }); + }); +}); From 7279255448c282575fbfb21791f687f388fa0695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9onard=20Labat?= Date: Wed, 19 Feb 2020 19:58:48 +0100 Subject: [PATCH 062/496] Updating criteo-direct-rsa-validate to 1.1.0 to fix issue #4851 (#4852) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b7307bc581..7bcce9cb943 100755 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "dependencies": { "babel-plugin-transform-object-assign": "^6.22.0", "core-js": "^2.4.1", - "criteo-direct-rsa-validate": "^1.0.0", + "criteo-direct-rsa-validate": "^1.1.0", "crypto-js": "^3.1.9-1", "deep-equal": "^1.0.1", "dlv": "1.1.3", From 3662ee3b2bdf764b41d1dab39e406c33294f8e0f Mon Sep 17 00:00:00 2001 From: msm0504 <51493331+msm0504@users.noreply.github.com> Date: Wed, 19 Feb 2020 15:41:48 -0500 Subject: [PATCH 063/496] Standardizing First Party Data (#4472) * Add microadBidAdapter * Remove unnecessary encodeURIComponent from microadBidAdapter * Submit Advangelists Prebid Adapter * Submit Advangelists Prebid Adapter 1.1 * Correct procudtion endpoint for prebid * analytics update with wrapper name * reverted error merge * update changed default value of netRevenue to true * Support user and context first party data in rubicon and prebid server adapters * Place user and context within fpd object * Separate global and bidder-specific first party data * Repeat FPD for each bidder when sending to PBS Co-authored-by: Isaac A. Dettman --- modules/prebidServerBidAdapter/index.js | 35 ++++++++ modules/rubiconBidAdapter.js | 58 +++++++++---- .../modules/prebidServerBidAdapter_spec.js | 46 +++++++++- test/spec/modules/rubiconBidAdapter_spec.js | 83 +++++++++++++++++++ 4 files changed, 206 insertions(+), 16 deletions(-) diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js index 3f7687479ec..8f7727a61aa 100644 --- a/modules/prebidServerBidAdapter/index.js +++ b/modules/prebidServerBidAdapter/index.js @@ -287,6 +287,32 @@ function _appendSiteAppDevice(request, pageUrl) { } } +function addBidderFirstPartyDataToRequest(request) { + const bidderConfig = config.getBidderConfig(); + const fpdConfigs = Object.keys(bidderConfig).reduce((acc, bidder) => { + const currBidderConfig = bidderConfig[bidder]; + if (currBidderConfig.fpd) { + const fpd = {}; + if (currBidderConfig.fpd.context) { + fpd.site = currBidderConfig.fpd.context; + } + if (currBidderConfig.fpd.user) { + fpd.user = currBidderConfig.fpd.user; + } + + acc.push({ + bidders: [ bidder ], + config: { fpd } + }); + } + return acc; + }, []); + + if (fpdConfigs.length) { + utils.deepSetValue(request, 'ext.prebid.bidderconfig', fpdConfigs); + } +} + // https://iabtechlab.com/wp-content/uploads/2016/07/OpenRTB-Native-Ads-Specification-Final-1.2.pdf#page=40 let nativeDataIdMap = { sponsoredBy: 1, // sponsored @@ -661,6 +687,15 @@ const OPEN_RTB_PROTOCOL = { utils.deepSetValue(request, 'regs.coppa', 1); } + const commonFpd = getConfig('fpd') || {}; + if (commonFpd.context) { + utils.deepSetValue(request, 'site.ext.data', commonFpd.context); + } + if (commonFpd.user) { + utils.deepSetValue(request, 'user.ext.data', commonFpd.user); + } + addBidderFirstPartyDataToRequest(request); + return request; }, diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index 801bbc3dd8c..34fdb76fcef 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -268,6 +268,27 @@ export const spec = { utils.deepSetValue(data, 'source.ext.schain', bidRequest.schain); } + const siteData = Object.assign({}, bidRequest.params.inventory, config.getConfig('fpd.context')); + const userData = Object.assign({}, bidRequest.params.visitor, config.getConfig('fpd.user')); + if (!utils.isEmpty(siteData) || !utils.isEmpty(userData)) { + const bidderData = { + bidders: [ bidderRequest.bidderCode ], + config: { + fpd: {} + } + }; + + if (!utils.isEmpty(siteData)) { + bidderData.config.fpd.site = siteData; + } + + if (!utils.isEmpty(userData)) { + bidderData.config.fpd.user = userData; + } + + utils.deepSetValue(data, 'ext.prebid.bidderconfig.0', bidderData); + } + /** * Prebid AdSlot * @type {(string|undefined)} @@ -448,7 +469,6 @@ export const spec = { 'x_source.tid': bidRequest.transactionId, 'x_source.pchain': params.pchain, 'p_screen_res': _getScreenResolution(), - 'kw': Array.isArray(params.keywords) ? params.keywords.join(',') : '', 'tk_user_key': params.userId, 'p_geo.latitude': isNaN(parseFloat(latitude)) ? undefined : parseFloat(latitude).toFixed(4), 'p_geo.longitude': isNaN(parseFloat(longitude)) ? undefined : parseFloat(longitude).toFixed(4), @@ -487,22 +507,30 @@ export const spec = { } // visitor properties - if (params.visitor !== null && typeof params.visitor === 'object') { - Object.keys(params.visitor).forEach((key) => { - if (params.visitor[key] != null) { - data[`tg_v.${key}`] = params.visitor[key].toString(); // initialize array; - } - }); - } + const visitorData = Object.assign({}, params.visitor, config.getConfig('fpd.user')); + Object.keys(visitorData).forEach((key) => { + if (visitorData[key] != null && key !== 'keywords') { + data[`tg_v.${key}`] = typeof visitorData[key] === 'object' && !Array.isArray(visitorData[key]) + ? JSON.stringify(visitorData[key]) + : visitorData[key].toString(); // initialize array; + } + }); // inventory properties - if (params.inventory !== null && typeof params.inventory === 'object') { - Object.keys(params.inventory).forEach((key) => { - if (params.inventory[key] != null) { - data[`tg_i.${key}`] = params.inventory[key].toString(); - } - }); - } + const inventoryData = Object.assign({}, params.inventory, config.getConfig('fpd.context')); + Object.keys(inventoryData).forEach((key) => { + if (inventoryData[key] != null && key !== 'keywords') { + data[`tg_i.${key}`] = typeof inventoryData[key] === 'object' && !Array.isArray(inventoryData[key]) + ? JSON.stringify(inventoryData[key]) + : inventoryData[key].toString(); + } + }); + + // keywords + const keywords = (params.keywords || []).concat( + utils.deepAccess(config.getConfig('fpd.user'), 'keywords') || [], + utils.deepAccess(config.getConfig('fpd.context'), 'keywords') || []); + data.kw = keywords.length ? keywords.join(',') : ''; /** * Prebid AdSlot diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index 1253098a399..bc655c6e432 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -1309,7 +1309,51 @@ describe('S2S Adapter', function () { adapter.callBids(REQUEST, bidRequests, addBidResponse, done, ajax); const parsedRequestBody = JSON.parse(server.requests[0].requestBody); expect(parsedRequestBody.source.ext.schain).to.deep.equal(schainObject); - }) + }); + + it('passes first party data in request', () => { + const s2sBidRequest = utils.deepClone(REQUEST); + const bidRequests = utils.deepClone(BID_REQUESTS); + + const commonContext = { + keywords: ['power tools'], + search: 'drill' + }; + const commonUser = { + keywords: ['a', 'b'], + gender: 'M' + }; + + const context = { + content: { userrating: 4 }, + data: { + pageType: 'article', + category: 'tools' + } + }; + const user = { + yob: '1984', + geo: { country: 'ca' }, + data: { + registered: true, + interests: ['cars'] + } + }; + const allowedBidders = [ 'rubicon', 'appnexus' ]; + + const expected = allowedBidders.map(bidder => ({ + bidders: [ bidder ], + config: { fpd: { site: context, user } } + })); + + config.setConfig({ fpd: { context: commonContext, user: commonUser } }); + config.setBidderConfig({ bidders: allowedBidders, config: { fpd: { context, user } } }); + adapter.callBids(s2sBidRequest, bidRequests, addBidResponse, done, ajax); + const parsedRequestBody = JSON.parse(server.requests[0].requestBody); + expect(parsedRequestBody.ext.prebid.bidderconfig).to.deep.equal(expected); + expect(parsedRequestBody.site.ext.data).to.deep.equal(commonContext); + expect(parsedRequestBody.user.ext.data).to.deep.equal(commonUser); + }); describe('pbAdSlot config', function () { it('should not send \"imp.ext.context.data.adslot\" if \"fpd.context\" is undefined', function () { diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 2413f2703f9..66f1dd0a989 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -980,6 +980,51 @@ describe('the rubicon adapter', function () { expect(data[key]).to.equal(value); }); }); + + it('should use first party data from getConfig over the bid params, if present', () => { + const context = { + keywords: ['e', 'f'], + rating: '4-star' + }; + const user = { + keywords: ['d'], + gender: 'M', + yob: '1984', + geo: { country: 'ca' } + }; + + sandbox.stub(config, 'getConfig').callsFake(key => { + const config = { + fpd: { + context, + user + } + }; + return utils.deepAccess(config, key); + }); + + const expectedQuery = { + 'kw': 'a,b,c,d,e,f', + 'tg_v.ucat': 'new', + 'tg_v.lastsearch': 'iphone', + 'tg_v.likes': 'sports,video games', + 'tg_v.gender': 'M', + 'tg_v.yob': '1984', + 'tg_v.geo': '{"country":"ca"}', + 'tg_i.rating': '4-star', + 'tg_i.prodtype': 'tech,mobile', + }; + + // get the built request + let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); + let data = parseQuery(request.data); + + // make sure that tg_v, tg_i, and kw values are correct + Object.keys(expectedQuery).forEach(key => { + let value = expectedQuery[key]; + expect(data[key]).to.deep.equal(value); + }); + }); }); describe('singleRequest config', function () { @@ -1641,6 +1686,44 @@ describe('the rubicon adapter', function () { expect(request.data.regs.coppa).to.equal(1); }); + it('should include first party data', () => { + createVideoBidderRequest(); + + const context = { + keywords: ['e', 'f'], + rating: '4-star' + }; + const user = { + keywords: ['d'], + gender: 'M', + yob: '1984', + geo: { country: 'ca' } + }; + + sandbox.stub(config, 'getConfig').callsFake(key => { + const config = { + fpd: { + context, + user + } + }; + return utils.deepAccess(config, key); + }); + + const expected = [{ + bidders: [ 'rubicon' ], + config: { + fpd: { + site: Object.assign({}, bidderRequest.bids[0].params.inventory, context), + user: Object.assign({}, bidderRequest.bids[0].params.visitor, user) + } + } + }]; + + const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); + expect(request.data.ext.prebid.bidderconfig).to.deep.equal(expected); + }); + it('should include storedAuctionResponse in video bid request', function () { createVideoBidderRequest(); From 407dc9236bef4632f8520c498dd255c94abb9dd7 Mon Sep 17 00:00:00 2001 From: David Andersen Date: Wed, 19 Feb 2020 15:59:26 -0500 Subject: [PATCH 064/496] TripleLift COPPA support (#4850) * Add COPPA support * Modify test --- modules/tripleliftBidAdapter.js | 5 +++++ test/spec/modules/tripleliftBidAdapter_spec.js | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/modules/tripleliftBidAdapter.js b/modules/tripleliftBidAdapter.js index 8cd1dda1120..9c20e36caec 100644 --- a/modules/tripleliftBidAdapter.js +++ b/modules/tripleliftBidAdapter.js @@ -1,6 +1,7 @@ import { BANNER } from '../src/mediaTypes'; import { registerBidder } from '../src/adapters/bidderFactory'; import * as utils from '../src/utils'; +import { config } from '../src/config'; const BIDDER_CODE = 'triplelift'; const STR_ENDPOINT = 'https://tlx.3lift.com/header/auction?'; @@ -46,6 +47,10 @@ export const tripleliftAdapterSpec = { tlCall = utils.tryAppendQueryString(tlCall, 'us_privacy', bidderRequest.uspConsent); } + if (config.getConfig('coppa') === true) { + tlCall = utils.tryAppendQueryString(tlCall, 'coppa', true); + } + if (tlCall.lastIndexOf('&') === tlCall.length - 1) { tlCall = tlCall.substring(0, tlCall.length - 1); } diff --git a/test/spec/modules/tripleliftBidAdapter_spec.js b/test/spec/modules/tripleliftBidAdapter_spec.js index fc8608f522a..6642e59d7c3 100644 --- a/test/spec/modules/tripleliftBidAdapter_spec.js +++ b/test/spec/modules/tripleliftBidAdapter_spec.js @@ -2,6 +2,7 @@ import { expect } from 'chai'; import { tripleliftAdapterSpec } from 'modules/tripleliftBidAdapter'; import { newBidder } from 'src/adapters/bidderFactory'; import { deepClone } from 'src/utils'; +import { config } from 'src/config'; import prebid from '../../../package.json'; const ENDPOINT = 'https://tlx.3lift.com/header/auction?'; @@ -273,6 +274,20 @@ describe('triplelift adapter', function () { const url = request.url; expect(url).to.match(/(\?|&)us_privacy=1YYY/); }); + it('should return coppa param when COPPA config is set to true', function() { + sinon.stub(config, 'getConfig').withArgs('coppa').returns(true); + const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); + config.getConfig.restore(); + const url = request.url; + expect(url).to.match(/(\?|&)coppa=true/); + }); + it('should not return coppa param when COPPA config is set to false', function() { + sinon.stub(config, 'getConfig').withArgs('coppa').returns(false); + const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); + config.getConfig.restore(); + const url = request.url; + expect(url).not.to.match(/(\?|&)coppa=/); + }); it('should return schain when present', function() { const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); const { data: payload } = request; From 1b0dfc2052baf395b6d2893898bb7bb5e42040ea Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Wed, 19 Feb 2020 16:50:24 -0700 Subject: [PATCH 065/496] Require file extensions in requires and imports (#4876) * require extensions in imports * fix extensions in new bid adapter * add explicit extensions for requires as well as imports * update prebid linter to check file extensions as well --- .eslintrc.js | 4 +- modules/1ad4goodBidAdapter.js | 10 +- modules/33acrossBidAdapter.js | 6 +- modules/aardvarkBidAdapter.js | 4 +- modules/ablidaBidAdapter.js | 6 +- modules/adagioAnalyticsAdapter.js | 6 +- modules/adagioBidAdapter.js | 12 +- modules/adbutlerBidAdapter.js | 6 +- modules/adfinityBidAdapter.js | 6 +- modules/adformBidAdapter.js | 10 +- modules/adformOpenRTBBidAdapter.js | 8 +- modules/adgenerationBidAdapter.js | 8 +- modules/adheseBidAdapter.js | 4 +- modules/adkernelAdnAnalyticsAdapter.js | 10 +- modules/adkernelAdnBidAdapter.js | 8 +- modules/adkernelBidAdapter.js | 12 +- modules/adliveBidAdapter.js | 6 +- modules/admanBidAdapter.js | 6 +- modules/admaticBidAdapter.js | 4 +- modules/admediaBidAdapter.js | 4 +- modules/admixerBidAdapter.js | 4 +- modules/adoceanBidAdapter.js | 4 +- modules/adomikAnalyticsAdapter.js | 10 +- modules/adpod.js | 24 +- modules/adponeBidAdapter.js | 6 +- modules/adspendBidAdapter.js | 10 +- modules/adtelligentBidAdapter.js | 10 +- modules/aduptechBidAdapter.js | 6 +- modules/advangelistsBidAdapter.js | 14 +- modules/advenueBidAdapter.js | 6 +- modules/advertlyBidAdapter.js | 12 +- modules/adxcgAnalyticsAdapter.js | 10 +- modules/adxcgBidAdapter.js | 12 +- modules/adxpremiumAnalyticsAdapter.js | 8 +- modules/adyoulikeBidAdapter.js | 10 +- modules/ajaBidAdapter.js | 8 +- modules/aniviewBidAdapter.js | 6 +- modules/aolBidAdapter.js | 6 +- modules/appierAnalyticsAdapter.js | 10 +- modules/appierBidAdapter.js | 6 +- modules/appnexusAnalyticsAdapter.js | 4 +- modules/appnexusBidAdapter.js | 18 +- modules/astraoneBidAdapter.js | 6 +- modules/atomxBidAdapter.js | 4 +- modules/audienceNetworkBidAdapter.js | 10 +- modules/audiencerunBidAdapter.js | 8 +- modules/beachfrontBidAdapter.js | 16 +- modules/betweenBidAdapter.js | 2 +- modules/bidfluenceBidAdapter.js | 4 +- modules/bidglassBidAdapter.js | 268 +++--- modules/bidphysicsBidAdapter.js | 6 +- modules/bridgewellBidAdapter.js | 8 +- modules/brightcomBidAdapter.js | 10 +- modules/britepoolIdSystem.js | 6 +- modules/browsiRtdProvider.js | 8 +- modules/bucksenseBidAdapter.js | 6 +- modules/buzzoolaBidAdapter.js | 10 +- modules/byplayBidAdapter.js | 8 +- modules/c1xBidAdapter.js | 6 +- modules/categoryTranslation.js | 10 +- modules/ccxBidAdapter.js | 6 +- modules/cedatoBidAdapter.js | 6 +- modules/cleanmedianetBidAdapter.js | 10 +- modules/clickforceBidAdapter.js | 6 +- modules/coinzillaBidAdapter.js | 6 +- modules/collectcentBidAdapter.js | 6 +- modules/colossussspBidAdapter.js | 6 +- modules/consentManagement.js | 10 +- modules/consentManagementUsp.js | 6 +- modules/consumableBidAdapter.js | 4 +- modules/conversantBidAdapter.js | 6 +- modules/cosmosBidAdapter.js | 6 +- modules/cpmstarBidAdapter.js | 6 +- modules/criteoBidAdapter.js | 16 +- modules/criteoIdSystem.js | 10 +- modules/currency.js | 10 +- modules/dailyhuntBidAdapter.js | 6 +- modules/datablocksAnalyticsAdapter.js | 4 +- modules/datablocksBidAdapter.js | 8 +- modules/deepintentBidAdapter.js | 6 +- modules/dfpAdServerVideo.js | 14 +- modules/digiTrustIdSystem.js | 6 +- modules/districtmDMXBidAdapter.js | 6 +- modules/djaxBidAdapter.js | 12 +- modules/dspxBidAdapter.js | 6 +- modules/ebdrBidAdapter.js | 6 +- modules/emoteevBidAdapter.js | 10 +- modules/emx_digitalBidAdapter.js | 12 +- modules/envivoBidAdapter.js | 12 +- modules/eplanningAnalyticsAdapter.js | 8 +- modules/eplanningBidAdapter.js | 4 +- modules/etargetBidAdapter.js | 4 +- modules/express.js | 2 +- modules/feedadBidAdapter.js | 8 +- modules/fidelityBidAdapter.js | 4 +- modules/fintezaAnalyticsAdapter.js | 10 +- modules/fluctBidAdapter.js | 4 +- modules/freeWheelAdserverVideo.js | 4 +- modules/freewheel-sspBidAdapter.js | 770 +++++++++--------- modules/gammaBidAdapter.js | 2 +- modules/gamoshiBidAdapter.js | 10 +- modules/getintentBidAdapter.js | 4 +- modules/googleAnalyticsAdapter.js | 6 +- modules/gridBidAdapter.js | 8 +- modules/gumgumBidAdapter.js | 10 +- modules/hpmdnetworkBidAdapter.js | 4 +- modules/iasBidAdapter.js | 4 +- modules/id5IdSystem.js | 6 +- modules/identityLinkIdSystem.js | 2 +- modules/imonomyBidAdapter.js | 4 +- modules/improvedigitalBidAdapter.js | 8 +- modules/innityBidAdapter.js | 4 +- modules/inskinBidAdapter.js | 4 +- modules/invibesBidAdapter.js | 4 +- modules/invisiblyAnalyticsAdapter.js | 8 +- modules/ixBidAdapter.js | 12 +- modules/jcmBidAdapter.js | 4 +- modules/justpremiumBidAdapter.js | 4 +- modules/kargoAnalyticsAdapter.js | 4 +- modules/kargoBidAdapter.js | 6 +- modules/komoonaBidAdapter.js | 4 +- modules/konduitWrapper.js | 10 +- modules/lemmaBidAdapter.js | 6 +- modules/liveIntentIdSystem.js | 6 +- modules/livewrappedAnalyticsAdapter.js | 8 +- modules/livewrappedBidAdapter.js | 10 +- modules/liveyieldAnalyticsAdapter.js | 6 +- modules/lkqdBidAdapter.js | 6 +- modules/lockerdomeBidAdapter.js | 6 +- modules/logicadBidAdapter.js | 4 +- modules/loopmeBidAdapter.js | 8 +- modules/madvertiseBidAdapter.js | 6 +- modules/mantisBidAdapter.js | 2 +- modules/marsmediaAnalyticsAdapter.js | 6 +- modules/marsmediaBidAdapter.js | 6 +- modules/meazyBidAdapter.js | 6 +- modules/medianetBidAdapter.js | 12 +- modules/mgidBidAdapter.js | 10 +- modules/microadBidAdapter.js | 4 +- modules/mobfoxBidAdapter.js | 2 +- modules/mobsmartBidAdapter.js | 4 +- modules/my6senseBidAdapter.js | 4 +- modules/mytargetBidAdapter.js | 8 +- modules/nafdigitalBidAdapter.js | 10 +- modules/nanointeractiveBidAdapter.js | 6 +- modules/nasmediaAdmixerBidAdapter.js | 4 +- modules/newborntownWebBidAdapter.js | 6 +- modules/nextMillenniumBidAdapter.js | 6 +- modules/nobidBidAdapter.js | 6 +- modules/oneVideoBidAdapter.js | 4 +- modules/onetagBidAdapter.js | 2 +- modules/open8BidAdapter.js | 10 +- modules/openxAnalyticsAdapter.js | 10 +- modules/openxBidAdapter.js | 10 +- modules/optimeraBidAdapter.js | 4 +- modules/orbidderBidAdapter.js | 6 +- modules/otmBidAdapter.js | 4 +- modules/outconBidAdapter.js | 2 +- modules/ozoneBidAdapter.js | 12 +- modules/padsquadBidAdapter.js | 6 +- modules/papyrusBidAdapter.js | 4 +- modules/parrableIdSystem.js | 6 +- modules/piximediaBidAdapter.js | 4 +- modules/playgroundxyzBidAdapter.js | 6 +- modules/prebidServerBidAdapter/index.js | 28 +- modules/prebidmanagerAnalyticsAdapter.js | 8 +- modules/projectLimeLightBidAdapter.js | 8 +- modules/proxistoreBidAdapter.js | 2 +- modules/pubCommonId.js | 8 +- modules/pubCommonIdSystem.js | 6 +- modules/pubmaticBidAdapter.js | 8 +- modules/pubwiseAnalyticsAdapter.js | 8 +- modules/pulsepointAnalyticsAdapter.js | 4 +- modules/pulsepointBidAdapter.js | 6 +- modules/quantcastBidAdapter.js | 8 +- modules/quantumBidAdapter.js | 6 +- modules/radsBidAdapter.js | 8 +- modules/readpeakBidAdapter.js | 10 +- modules/realvuAnalyticsAdapter.js | 4 +- modules/reklamstoreBidAdapter.js | 6 +- modules/reloadBidAdapter.js | 4 +- modules/resultsmediaBidAdapter.js | 6 +- modules/revcontentBidAdapter.js | 6 +- modules/rhythmoneBidAdapter.js | 6 +- modules/richaudienceBidAdapter.js | 8 +- modules/rivrAnalyticsAdapter.js | 8 +- modules/roxotAnalyticsAdapter.js | 10 +- modules/rtbdemandBidAdapter.js | 4 +- modules/rtbhouseBidAdapter.js | 8 +- modules/rtbsolutionsBidAdapter.js | 6 +- modules/rtdModule/index.js | 8 +- modules/rubiconAnalyticsAdapter.js | 10 +- modules/rubiconBidAdapter.js | 10 +- modules/s2sTesting.js | 4 +- modules/scaleableAnalyticsAdapter.js | 8 +- modules/schain.js | 6 +- modules/seedingAllianceBidAdapter.js | 8 +- modules/seedtagBidAdapter.js | 6 +- modules/segmentoBidAdapter.js | 2 +- modules/sekindoUMBidAdapter.js | 4 +- modules/sharethroughAnalyticsAdapter.js | 6 +- modules/sharethroughBidAdapter.js | 2 +- modules/showheroes-bsBidAdapter.js | 12 +- modules/sigmoidAnalyticsAdapter.js | 8 +- modules/slimcutBidAdapter.js | 6 +- modules/smartadserverBidAdapter.js | 8 +- modules/smartrtbBidAdapter.js | 6 +- modules/smartyadsBidAdapter.js | 6 +- modules/smilewantedBidAdapter.js | 10 +- modules/smmsBidAdapter.js | 4 +- modules/somoBidAdapter.js | 8 +- modules/sonobiAnalyticsAdapter.js | 8 +- modules/sonobiBidAdapter.js | 12 +- modules/sortableAnalyticsAdapter.js | 12 +- modules/sovrnAnalyticsAdapter.js | 14 +- modules/sovrnBidAdapter.js | 8 +- modules/spotxBidAdapter.js | 8 +- modules/staqAnalyticsAdapter.js | 12 +- modules/stvBidAdapter.js | 8 +- modules/sublimeBidAdapter.js | 4 +- modules/synacormediaBidAdapter.js | 8 +- modules/taphypeBidAdapter.js | 2 +- modules/teadsBidAdapter.js | 4 +- modules/telariaBidAdapter.js | 10 +- modules/theAdxBidAdapter.js | 8 +- modules/timBidAdapter.js | 6 +- modules/topRTBBidAdapter.js | 6 +- modules/tpmnBidAdapter.js | 8 +- modules/tribeosBidAdapter.js | 8 +- modules/trionBidAdapter.js | 4 +- modules/tripleliftBidAdapter.js | 8 +- modules/trustxBidAdapter.js | 8 +- modules/turktelekomBidAdapter.js | 8 +- modules/ucfunnelAnalyticsAdapter.js | 10 +- modules/ucfunnelBidAdapter.js | 4 +- modules/underdogmediaBidAdapter.js | 6 +- modules/undertoneBidAdapter.js | 4 +- modules/unifiedIdSystem.js | 6 +- modules/unrulyBidAdapter.js | 8 +- modules/userId/index.js | 14 +- modules/userIdTargeting.js | 8 +- modules/viBidAdapter.js | 4 +- modules/vidazooBidAdapter.js | 6 +- modules/videoNowBidAdapter.js | 8 +- modules/videoreachBidAdapter.js | 4 +- modules/viewdeosDXBidAdapter.js | 10 +- modules/visxBidAdapter.js | 6 +- modules/vmgBidAdapter.js | 2 +- modules/vrtcalBidAdapter.js | 6 +- modules/vubleBidAdapter.js | 6 +- modules/widespaceBidAdapter.js | 10 +- modules/xhbBidAdapter.js | 12 +- modules/yieldlabBidAdapter.js | 10 +- modules/yieldmoBidAdapter.js | 4 +- modules/yieldoneAnalyticsAdapter.js | 12 +- modules/yieldoneBidAdapter.js | 10 +- modules/yuktamediaAnalyticsAdapter.js | 10 +- plugins/eslint/validateImports.js | 8 + src/AnalyticsAdapter.js | 8 +- src/Renderer.js | 6 +- src/adServerManager.js | 4 +- src/adUnits.js | 2 +- src/adapterManager.js | 24 +- src/adapters/analytics/example.js | 2 +- src/adapters/analytics/example2.js | 4 +- src/adapters/bidderFactory.js | 26 +- src/adloader.js | 4 +- src/adserver.js | 4 +- src/ajax.js | 6 +- src/auction.js | 30 +- src/auctionManager.js | 6 +- src/config.js | 18 +- src/cpmBucketManager.js | 4 +- src/debugging.js | 8 +- src/events.js | 4 +- src/hook.js | 2 +- src/native.js | 4 +- src/prebid.js | 28 +- src/refererDetection.js | 2 +- src/secureCreatives.js | 14 +- src/sizeMapping.js | 6 +- src/targeting.js | 14 +- src/userSync.js | 6 +- src/utils.js | 10 +- src/video.js | 10 +- src/videoCache.js | 4 +- test/mocks/adloaderStub.js | 2 +- test/mocks/videoCacheStub.js | 2 +- test/spec/AnalyticsAdapter_spec.js | 4 +- test/spec/adloader_spec.js | 4 +- test/spec/aliasBidder_spec.js | 2 +- test/spec/auctionmanager_spec.js | 20 +- test/spec/config_spec.js | 2 +- test/spec/cpmBucketManager_spec.js | 2 +- test/spec/debugging_spec.js | 6 +- test/spec/integration/faker/fixtures.js | 2 +- test/spec/integration/faker/googletag.js | 2 +- test/spec/modules/1ad4goodBidAdapter_spec.js | 10 +- test/spec/modules/33acrossBidAdapter_spec.js | 6 +- test/spec/modules/aardvarkBidAdapter_spec.js | 4 +- test/spec/modules/ablidaBidAdapter_spec.js | 4 +- .../modules/adagioAnalyticsAdapter_spec.js | 4 +- test/spec/modules/adagioBidAdapter_spec.js | 6 +- test/spec/modules/adbutlerBidAdapter_spec.js | 2 +- test/spec/modules/adfinityBidAdapter_spec.js | 2 +- test/spec/modules/adformBidAdapter_spec.js | 8 +- .../modules/adformOpenRTBBidAdapter_spec.js | 8 +- .../modules/adgenerationBidAdapter_spec.js | 8 +- test/spec/modules/adheseBidAdapter_spec.js | 2 +- .../spec/modules/adkernelAdnAnalytics_spec.js | 4 +- .../modules/adkernelAdnBidAdapter_spec.js | 2 +- test/spec/modules/adkernelBidAdapter_spec.js | 4 +- test/spec/modules/adliveBidAdapter_spec.js | 2 +- test/spec/modules/admanBidAdapter_spec.js | 2 +- test/spec/modules/admediaBidAdapter_spec.js | 2 +- test/spec/modules/admixerBidAdapter_spec.js | 4 +- test/spec/modules/adoceanBidAdapter_spec.js | 4 +- .../modules/adomikAnalyticsAdapter_spec.js | 2 +- test/spec/modules/adpod_spec.js | 12 +- test/spec/modules/adponeBidAdapter_spec.js | 6 +- .../modules/adtelligentBidAdapter_spec.js | 4 +- test/spec/modules/aduptechBidAdapter_spec.js | 4 +- .../modules/advangelistsBidAdapter_spec.js | 4 +- test/spec/modules/advenueBidAdapter_spec.js | 2 +- test/spec/modules/advertlyBidAdapter_spec.js | 2 +- .../modules/adxcgAnalyticsAdapter_spec.js | 4 +- test/spec/modules/adxcgBidAdapter_spec.js | 6 +- test/spec/modules/adyoulikeBidAdapter_spec.js | 6 +- test/spec/modules/ajaBidAdapter_spec.js | 4 +- test/spec/modules/aniviewBidAdapter_spec.js | 4 +- test/spec/modules/aolBidAdapter_spec.js | 6 +- .../modules/appierAnalyticsAdapter_spec.js | 2 +- test/spec/modules/appierBidAdapter_spec.js | 6 +- test/spec/modules/appnexusBidAdapter_spec.js | 12 +- test/spec/modules/astraoneBidAdapter_spec.js | 2 +- test/spec/modules/atomxBidAdapter_spec.js | 2 +- .../modules/audienceNetworkBidAdapter_spec.js | 4 +- .../modules/audiencerunBidAdapter_spec.js | 4 +- .../spec/modules/beachfrontBidAdapter_spec.js | 4 +- test/spec/modules/betweenBidAdapter_spec.js | 2 +- .../spec/modules/bidfluenceBidAdapter_spec.js | 228 +++--- test/spec/modules/bidglassAdapter_spec.js | 4 +- .../spec/modules/bidphysicsBidAdapter_spec.js | 2 +- .../spec/modules/bridgewellBidAdapter_spec.js | 4 +- test/spec/modules/brightcomBidAdapter_spec.js | 6 +- test/spec/modules/britepoolIdSystem_spec.js | 2 +- test/spec/modules/bucksenseBidAdapter_spec.js | 2 +- test/spec/modules/buzzoolaBidAdapter_spec.js | 8 +- test/spec/modules/byplayBidAdapter_spec.js | 6 +- test/spec/modules/c1xBidAdapter_spec.js | 4 +- test/spec/modules/categoryTranslation_spec.js | 6 +- test/spec/modules/ccxBidAdapter_spec.js | 4 +- test/spec/modules/cedatoBidAdapter_spec.js | 2 +- .../modules/cleanmedianetBidAdapter_spec.js | 6 +- .../spec/modules/clickforceBidAdapter_spec.js | 4 +- test/spec/modules/coinzillaBidAdapter_spec.js | 4 +- .../modules/collectcentBidAdapter_spec.js | 2 +- .../modules/colossussspBidAdapter_spec.js | 2 +- .../spec/modules/consentManagementUsp_spec.js | 8 +- test/spec/modules/consentManagement_spec.js | 8 +- .../spec/modules/consumableBidAdapter_spec.js | 4 +- .../spec/modules/conversantBidAdapter_spec.js | 4 +- test/spec/modules/cosmosBidAdapter_spec.js | 4 +- test/spec/modules/cpmstarBidAdapter_spec.js | 4 +- test/spec/modules/criteoBidAdapter_spec.js | 10 +- test/spec/modules/criteoIdSystem_spec.js | 8 +- test/spec/modules/currency_spec.js | 4 +- test/spec/modules/dailyhuntBidAdapter_spec.js | 2 +- .../spec/modules/datablocksBidAdapter_spec.js | 2 +- .../spec/modules/deepintentBidAdapter_spec.js | 4 +- test/spec/modules/dfpAdServerVideo_spec.js | 18 +- test/spec/modules/digitrustIdSystem_spec.js | 2 +- .../modules/districtmDmxBidAdapter_spec.js | 2 +- test/spec/modules/djaxBidAdapter_spec.js | 2 +- test/spec/modules/dspxBidAdapter_spec.js | 4 +- test/spec/modules/ebdrBidAdapter_spec.js | 6 +- test/spec/modules/emoteevBidAdapter_spec.js | 8 +- .../modules/emx_digitalBidAdapter_spec.js | 6 +- test/spec/modules/envivoBidAdapter_spec.js | 2 +- .../modules/eplanningAnalyticsAdapter_spec.js | 8 +- test/spec/modules/eplanningBidAdapter_spec.js | 6 +- test/spec/modules/etargetBidAdapter_spec.js | 6 +- test/spec/modules/feedadBidAdapter_spec.js | 6 +- test/spec/modules/fidelityBidAdapter_spec.js | 4 +- .../modules/fintezaAnalyticsAdapter_spec.js | 8 +- test/spec/modules/fluctBidAdapter_spec.js | 6 +- .../modules/freeWheelAdserverVideo_spec.js | 8 +- .../modules/freewheel-sspBidAdapter_spec.js | 4 +- test/spec/modules/gammaBidAdapter_spec.js | 4 +- test/spec/modules/gamoshiBidAdapter_spec.js | 6 +- test/spec/modules/getintentBidAdapter_spec.js | 2 +- .../modules/googleAnalyticsAdapter_spec.js | 2 +- test/spec/modules/gridBidAdapter_spec.js | 4 +- test/spec/modules/gumgumBidAdapter_spec.js | 4 +- .../modules/hpmdnetworkBidAdapter_spec.js | 2 +- test/spec/modules/iasBidAdapter_spec.js | 2 +- test/spec/modules/imonomyBidAdapter_spec.js | 2 +- .../modules/improvedigitalBidAdapter_spec.js | 6 +- test/spec/modules/innityBidAdapter_spec.js | 2 +- test/spec/modules/inskinBidAdapter_spec.js | 4 +- test/spec/modules/invibesBidAdapter_spec.js | 2 +- .../modules/invisiblyAnalyticsAdapter_spec.js | 4 +- test/spec/modules/ixBidAdapter_spec.js | 8 +- test/spec/modules/jcmBidAdapter_spec.js | 4 +- .../modules/justpremiumBidAdapter_spec.js | 2 +- test/spec/modules/kargoBidAdapter_spec.js | 4 +- test/spec/modules/komoonaBidAdapter_spec.js | 2 +- test/spec/modules/konduitWrapper_spec.js | 6 +- test/spec/modules/lemmaBidAdapter_spec.js | 4 +- test/spec/modules/liveIntentIdSystem_spec.js | 6 +- .../livewrappedAnalyticsAdapter_spec.js | 6 +- .../modules/livewrappedBidAdapter_spec.js | 8 +- .../modules/liveyieldAnalyticsAdapter_spec.js | 2 +- test/spec/modules/lkqdBidAdapter_spec.js | 4 +- .../spec/modules/lockerdomeBidAdapter_spec.js | 4 +- test/spec/modules/logicadBidAdapter_spec.js | 4 +- test/spec/modules/loopmeBidAdapter_spec.js | 4 +- .../spec/modules/madvertiseBidAdapter_spec.js | 6 +- test/spec/modules/mantisBidAdapter_spec.js | 4 +- test/spec/modules/marsmediaBidAdapter_spec.js | 4 +- test/spec/modules/meazyBidAdapter_spec.js | 6 +- test/spec/modules/medianetBidAdapter_spec.js | 4 +- test/spec/modules/mgidBidAdapter_spec.js | 6 +- test/spec/modules/microadBidAdapter_spec.js | 4 +- test/spec/modules/mobsmartBidAdapter_spec.js | 2 +- test/spec/modules/my6senseBidAdapter_spec.js | 2 +- test/spec/modules/mytargetBidAdapter_spec.js | 4 +- .../spec/modules/nafdigitalBidAdapter_spec.js | 6 +- .../modules/nanointeractiveBidAdapter_spec.js | 4 +- .../modules/nasmediaAdmixerBidAdapter_spec.js | 4 +- .../modules/newborntownWebBidAdapter_spec.js | 2 +- .../modules/nextMillenniumBidAdapter_spec.js | 2 +- test/spec/modules/nobidBidAdapter_spec.js | 6 +- test/spec/modules/oneVideoBidAdapter_spec.js | 6 +- test/spec/modules/onetagBidAdapter_spec.js | 2 +- test/spec/modules/open8BidAdapter_spec.js | 4 +- .../modules/openxAnalyticsAdapter_spec.js | 10 +- test/spec/modules/openxBidAdapter_spec.js | 10 +- test/spec/modules/optimeraBidAdapter_spec.js | 4 +- test/spec/modules/orbidderBidAdapter_spec.js | 8 +- test/spec/modules/otmBidAdapter_spec.js | 2 +- test/spec/modules/outconBidAdapter_spec.js | 2 +- test/spec/modules/ozoneBidAdapter_spec.js | 10 +- test/spec/modules/padsquadBidAdapter_spec.js | 2 +- test/spec/modules/papyrusBidAdapter_spec.js | 2 +- test/spec/modules/parrableIdSystem_spec.js | 6 +- test/spec/modules/piximediaBidAdapter_spec.js | 2 +- .../modules/playgroundxyzBidAdapter_spec.js | 6 +- .../modules/prebidServerBidAdapter_spec.js | 14 +- .../prebidmanagerAnalyticsAdapter_spec.js | 4 +- .../projectLimeLightBidAdapter_spec.js | 2 +- test/spec/modules/pubCommonId_spec.js | 10 +- test/spec/modules/pubmaticBidAdapter_spec.js | 6 +- .../modules/pubwiseAnalyticsAdapter_spec.js | 2 +- .../spec/modules/pulsepointBidAdapter_spec.js | 4 +- test/spec/modules/quantcastBidAdapter_spec.js | 6 +- test/spec/modules/quantumBidAdapter_spec.js | 4 +- test/spec/modules/radsBidAdapter_spec.js | 4 +- test/spec/modules/readpeakBidAdapter_spec.js | 6 +- test/spec/modules/realTimeModule_spec.js | 8 +- .../modules/realvuAnalyticsAdapter_spec.js | 2 +- .../modules/reklamstoreBidAdapter_spec.js | 2 +- test/spec/modules/reloadBidAdapter_spec.js | 2 +- .../modules/resultsmediaBidAdapter_spec.js | 4 +- .../spec/modules/revcontentBidAdapter_spec.js | 8 +- test/spec/modules/rhythmoneBidAdapter_spec.js | 4 +- .../modules/richaudienceBidAdapter_spec.js | 6 +- .../spec/modules/rivrAnalyticsAdapter_spec.js | 10 +- .../modules/roxotAnalyticsAdapter_spec.js | 4 +- test/spec/modules/rtbdemandBidAdapter_spec.js | 4 +- test/spec/modules/rtbhouseBidAdapter_spec.js | 4 +- .../modules/rtbsolutionsBidAdapter_spec.js | 2 +- .../modules/rubiconAnalyticsAdapter_spec.js | 10 +- test/spec/modules/rubiconBidAdapter_spec.js | 14 +- test/spec/modules/s2sTesting_spec.js | 4 +- .../modules/scaleableAnalyticsAdapter_spec.js | 6 +- test/spec/modules/schain_spec.js | 6 +- .../modules/seedingAllianceAdapter_spec.js | 8 +- test/spec/modules/seedtagBidAdapter_spec.js | 2 +- test/spec/modules/segmentoBidAdapter_spec.js | 2 +- test/spec/modules/sekindoUMBidAdapter_spec.js | 4 +- test/spec/modules/shareUserIds_spec.js | 2 +- .../modules/sharethroughBidAdapter_spec.js | 4 +- .../modules/showheroes-bsBidAdapter_spec.js | 6 +- .../modules/sigmoidAnalyticsAdapter_spec.js | 2 +- test/spec/modules/slimcutBidAdapter_spec.js | 4 +- .../modules/smartadserverBidAdapter_spec.js | 10 +- test/spec/modules/smartrtbBidAdapter_spec.js | 4 +- test/spec/modules/smartyadsBidAdapter_spec.js | 2 +- .../modules/smilewantedBidAdapter_spec.js | 10 +- test/spec/modules/smmsBidAdapter_spec.js | 4 +- test/spec/modules/somoBidAdapter_spec.js | 4 +- .../modules/sonobiAnalyticsAdapter_spec.js | 4 +- test/spec/modules/sonobiBidAdapter_spec.js | 6 +- .../modules/sortableAnalyticsAdapter_spec.js | 8 +- .../modules/sovrnAnalyticsAdapter_spec.js | 8 +- test/spec/modules/sovrnBidAdapter_spec.js | 4 +- test/spec/modules/spotxBidAdapter_spec.js | 2 +- .../spec/modules/staqAnalyticsAdapter_spec.js | 4 +- test/spec/modules/stvBidAdapter_spec.js | 4 +- test/spec/modules/sublimeBidAdapter_spec.js | 4 +- .../modules/synacormediaBidAdapter_spec.js | 4 +- test/spec/modules/taphypeBidAdapter_spec.js | 2 +- test/spec/modules/teadsBidAdapter_spec.js | 4 +- test/spec/modules/telariaBidAdapter_spec.js | 6 +- test/spec/modules/theAdxBidAdapter_spec.js | 4 +- test/spec/modules/timBidAdapter_spec.js | 2 +- test/spec/modules/topRTBBidAdapter_spec.js | 2 +- test/spec/modules/tpmnBidAdapter_spec.js | 2 +- test/spec/modules/tribeosBidAdapter_spec.js | 2 +- test/spec/modules/trionBidAdapter_spec.js | 4 +- .../spec/modules/tripleliftBidAdapter_spec.js | 8 +- test/spec/modules/trustxBidAdapter_spec.js | 4 +- .../modules/turktelekomBidAdapter_spec.js | 4 +- .../modules/ucfunnelAnalyticsAdapter_spec.js | 2 +- test/spec/modules/ucfunnelBidAdapter_spec.js | 4 +- .../modules/underdogmediaBidAdapter_spec.js | 2 +- test/spec/modules/undertoneBidAdapter_spec.js | 2 +- test/spec/modules/unrulyBidAdapter_spec.js | 10 +- test/spec/modules/userId_spec.js | 20 +- test/spec/modules/viBidAdapter_spec.js | 2 +- test/spec/modules/vidazooBidAdapter_spec.js | 4 +- test/spec/modules/videoNowBidAdapter_spec.js | 6 +- .../spec/modules/videoreachBidAdapter_spec.js | 4 +- .../spec/modules/viewdeosDXBidAdapter_spec.js | 4 +- test/spec/modules/visxBidAdapter_spec.js | 6 +- test/spec/modules/vmgBidAdapter_spec.js | 4 +- test/spec/modules/vrtcalBidAdapter_spec.js | 2 +- test/spec/modules/vubleBidAdapter_spec.js | 4 +- test/spec/modules/widespaceBidAdapter_spec.js | 4 +- test/spec/modules/xhbBidAdapter_spec.js | 6 +- test/spec/modules/yieldlabBidAdapter_spec.js | 4 +- test/spec/modules/yieldmoBidAdapter_spec.js | 6 +- .../modules/yieldoneAnalyticsAdapter_spec.js | 4 +- test/spec/modules/yieldoneBidAdapter_spec.js | 4 +- .../yuktamediaAnalyticsAdaptor_spec.js | 6 +- test/spec/native_spec.js | 2 +- test/spec/refererDetection_spec.js | 2 +- test/spec/renderer_spec.js | 6 +- test/spec/sizeMapping_spec.js | 4 +- test/spec/unit/adServerManager_spec.js | 4 +- test/spec/unit/adUnits_spec.js | 2 +- test/spec/unit/core/adapterManager_spec.js | 18 +- test/spec/unit/core/bidderFactory_spec.js | 14 +- test/spec/unit/core/targeting_spec.js | 10 +- test/spec/unit/pbjs_api_spec.js | 16 +- test/spec/unit/secureCreatives_spec.js | 4 +- test/spec/url_spec.js | 2 +- test/spec/userSync_spec.js | 2 +- test/spec/utils_spec.js | 4 +- test/spec/videoCache_spec.js | 7 +- test/spec/video_spec.js | 2 +- 552 files changed, 2317 insertions(+), 2308 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 65019123c2e..74948bb8bad 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,7 +15,8 @@ module.exports = { }, "extends": "standard", "plugins": [ - "prebid" + "prebid", + "import" ], "globals": { "$$PREBID_GLOBAL$$": false @@ -27,6 +28,7 @@ module.exports = { "comma-dangle": "off", "semi": "off", "space-before-function-paren": "off", + "import/extensions": ["error", "ignorePackages"], // Exceptions below this line are temporary, so that eslint can be added into the CI process. // Violations of these styles should be fixed, and the exceptions removed over time. diff --git a/modules/1ad4goodBidAdapter.js b/modules/1ad4goodBidAdapter.js index 26057b5e2b2..560808b368f 100644 --- a/modules/1ad4goodBidAdapter.js +++ b/modules/1ad4goodBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; -import find from 'core-js/library/fn/array/find'; -import includes from 'core-js/library/fn/array/includes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js/library/fn/array/includes.js'; const BIDDER_CODE = '1ad4good'; const URL = 'https://hb.1ad4good.org/prebid'; diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js index 772fc360c17..95524190e74 100644 --- a/modules/33acrossBidAdapter.js +++ b/modules/33acrossBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = '33across'; const END_POINT = 'https://ssc.33across.com/api/v1/hb'; diff --git a/modules/aardvarkBidAdapter.js b/modules/aardvarkBidAdapter.js index 79e82e1ff90..848a6672022 100644 --- a/modules/aardvarkBidAdapter.js +++ b/modules/aardvarkBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'aardvark'; const DEFAULT_ENDPOINT = 'bidder.rtk.io'; diff --git a/modules/ablidaBidAdapter.js b/modules/ablidaBidAdapter.js index 33642a1ac9e..ad507c18b24 100644 --- a/modules/ablidaBidAdapter.js +++ b/modules/ablidaBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'ablida'; const ENDPOINT_URL = 'https://bidder.ablida.net/prebid'; diff --git a/modules/adagioAnalyticsAdapter.js b/modules/adagioAnalyticsAdapter.js index 32b9f0d1b0c..fd7a742d9e7 100644 --- a/modules/adagioAnalyticsAdapter.js +++ b/modules/adagioAnalyticsAdapter.js @@ -2,10 +2,10 @@ * Analytics Adapter for Adagio */ -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; import CONSTANTS from '../src/constants.json'; -import * as utils from '../src/utils'; +import * as utils from '../src/utils.js'; const emptyUrl = ''; const analyticsType = 'endpoint'; diff --git a/modules/adagioBidAdapter.js b/modules/adagioBidAdapter.js index 4b7ad755655..3bf5eb5d34d 100644 --- a/modules/adagioBidAdapter.js +++ b/modules/adagioBidAdapter.js @@ -1,9 +1,9 @@ -import find from 'core-js/library/fn/array/find'; -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { loadExternalScript } from '../src/adloader' -import JSEncrypt from 'jsencrypt/bin/jsencrypt'; -import sha256 from 'crypto-js/sha256'; +import find from 'core-js/library/fn/array/find.js'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { loadExternalScript } from '../src/adloader.js' +import JSEncrypt from 'jsencrypt/bin/jsencrypt.js'; +import sha256 from 'crypto-js/sha256.js'; const BIDDER_CODE = 'adagio'; const VERSION = '2.1.0'; diff --git a/modules/adbutlerBidAdapter.js b/modules/adbutlerBidAdapter.js index a08574c2044..47162aa2445 100644 --- a/modules/adbutlerBidAdapter.js +++ b/modules/adbutlerBidAdapter.js @@ -1,8 +1,8 @@ 'use strict'; -import * as utils from '../src/utils'; -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'adbutler'; diff --git a/modules/adfinityBidAdapter.js b/modules/adfinityBidAdapter.js index 7544f062efd..34407e015db 100644 --- a/modules/adfinityBidAdapter.js +++ b/modules/adfinityBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'adfinity'; const AD_URL = 'https://stat.adfinity.pro/?c=o&m=multi'; diff --git a/modules/adformBidAdapter.js b/modules/adformBidAdapter.js index 7ffd79328b1..d2e8a570b8a 100644 --- a/modules/adformBidAdapter.js +++ b/modules/adformBidAdapter.js @@ -1,10 +1,10 @@ 'use strict'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; -import { BANNER, VIDEO } from '../src/mediaTypes'; -import { Renderer } from '../src/Renderer'; -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; +import * as utils from '../src/utils.js'; const OUTSTREAM_RENDERER_URL = 'https://s2.adform.net/banners/scripts/video/outstream/render.js'; diff --git a/modules/adformOpenRTBBidAdapter.js b/modules/adformOpenRTBBidAdapter.js index a936c39d625..9e3325fad0a 100644 --- a/modules/adformOpenRTBBidAdapter.js +++ b/modules/adformOpenRTBBidAdapter.js @@ -3,12 +3,12 @@ import { registerBidder -} from '../src/adapters/bidderFactory'; +} from '../src/adapters/bidderFactory.js'; import { NATIVE -} from '../src/mediaTypes'; -import * as utils from '../src/utils'; -import { config } from '../src/config'; +} from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'adformOpenRTB'; const NATIVE_ASSET_IDS = { 0: 'title', 2: 'icon', 3: 'image', 5: 'sponsoredBy', 4: 'body', 1: 'cta' }; diff --git a/modules/adgenerationBidAdapter.js b/modules/adgenerationBidAdapter.js index 0a8466ce477..7f92ab483f6 100644 --- a/modules/adgenerationBidAdapter.js +++ b/modules/adgenerationBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER, NATIVE} from '../src/mediaTypes'; -import {config} from '../src/config'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER, NATIVE} from '../src/mediaTypes.js'; +import {config} from '../src/config.js'; const ADG_BIDDER_CODE = 'adgeneration'; export const spec = { diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js index 445c9956410..2d12f4cdbc2 100644 --- a/modules/adheseBidAdapter.js +++ b/modules/adheseBidAdapter.js @@ -1,7 +1,7 @@ 'use strict'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'adhese'; const USER_SYNC_BASE_URL = 'https://user-sync.adhese.com/iframe/user_sync.html'; diff --git a/modules/adkernelAdnAnalyticsAdapter.js b/modules/adkernelAdnAnalyticsAdapter.js index cf53ef6c8e7..686ad0740a7 100644 --- a/modules/adkernelAdnAnalyticsAdapter.js +++ b/modules/adkernelAdnAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import adapter from '../src/AnalyticsAdapter'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; -import {parse} from '../src/url'; -import * as utils from '../src/utils'; -import {ajax} from '../src/ajax'; +import adapterManager from '../src/adapterManager.js'; +import {parse} from '../src/url.js'; +import * as utils from '../src/utils.js'; +import {ajax} from '../src/ajax.js'; const ANALYTICS_VERSION = '1.0.1'; const DEFAULT_QUEUE_TIMEOUT = 4000; diff --git a/modules/adkernelAdnBidAdapter.js b/modules/adkernelAdnBidAdapter.js index 36689c24b9a..25a7f2f4abc 100644 --- a/modules/adkernelAdnBidAdapter.js +++ b/modules/adkernelAdnBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER, VIDEO} from '../src/mediaTypes'; -import {parse as parseUrl} from '../src/url'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import {parse as parseUrl} from '../src/url.js'; const DEFAULT_ADKERNEL_DSP_DOMAIN = 'tag.adkernel.com'; const DEFAULT_MIMES = ['video/mp4', 'video/webm', 'application/x-shockwave-flash', 'application/javascript']; diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index 64e70727cf9..18c60c3e438 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -1,9 +1,9 @@ -import * as utils from '../src/utils'; -import { BANNER, VIDEO } from '../src/mediaTypes'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import find from 'core-js/library/fn/array/find'; -import includes from 'core-js/library/fn/array/includes'; -import {parse as parseUrl} from '../src/url'; +import * as utils from '../src/utils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import {parse as parseUrl} from '../src/url.js'; /* * In case you're AdKernel whitelable platform's client who needs branded adapter to diff --git a/modules/adliveBidAdapter.js b/modules/adliveBidAdapter.js index cb3d9579832..4c703628c4d 100644 --- a/modules/adliveBidAdapter.js +++ b/modules/adliveBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'adlive'; const ENDPOINT_URL = 'https://api.publishers.adlive.io/get?pbjs=1'; diff --git a/modules/admanBidAdapter.js b/modules/admanBidAdapter.js index 1ab545613ec..5dc3412ee66 100644 --- a/modules/admanBidAdapter.js +++ b/modules/admanBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'adman'; const AD_URL = 'https://pub.admanmedia.com/?c=o&m=multi'; diff --git a/modules/admaticBidAdapter.js b/modules/admaticBidAdapter.js index c0f32319d79..d46c01f7f48 100644 --- a/modules/admaticBidAdapter.js +++ b/modules/admaticBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'admatic'; const ENDPOINT_URL = 'https://ads4.admatic.com.tr/prebid/v3/bidrequest'; diff --git a/modules/admediaBidAdapter.js b/modules/admediaBidAdapter.js index d6d7044a371..0a9e510843c 100644 --- a/modules/admediaBidAdapter.js +++ b/modules/admediaBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'admedia'; const ENDPOINT_URL = 'https://prebid.admedia.com/bidder/'; diff --git a/modules/admixerBidAdapter.js b/modules/admixerBidAdapter.js index 0818c6c8281..e8a27a033b4 100644 --- a/modules/admixerBidAdapter.js +++ b/modules/admixerBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'admixer'; const ALIASES = ['go2net']; diff --git a/modules/adoceanBidAdapter.js b/modules/adoceanBidAdapter.js index 9a09cfffdde..2b14876fe6f 100644 --- a/modules/adoceanBidAdapter.js +++ b/modules/adoceanBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'adocean'; diff --git a/modules/adomikAnalyticsAdapter.js b/modules/adomikAnalyticsAdapter.js index 6551634f97d..ec5923ea0f8 100644 --- a/modules/adomikAnalyticsAdapter.js +++ b/modules/adomikAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import adapter from '../src/AnalyticsAdapter'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; -import { logInfo } from '../src/utils'; -import find from 'core-js/library/fn/array/find'; -import findIndex from 'core-js/library/fn/array/find-index'; +import adapterManager from '../src/adapterManager.js'; +import { logInfo } from '../src/utils.js'; +import find from 'core-js/library/fn/array/find.js'; +import findIndex from 'core-js/library/fn/array/find-index.js'; // Events used in adomik analytics adapter const auctionInit = CONSTANTS.EVENTS.AUCTION_INIT; diff --git a/modules/adpod.js b/modules/adpod.js index 8c352b67d04..46f7f80d47e 100644 --- a/modules/adpod.js +++ b/modules/adpod.js @@ -12,20 +12,20 @@ * module that designed to support adpod video type ads. This import process allows this module to effectively act as a sub-module. */ -import * as utils from '../src/utils'; -import { addBidToAuction, doCallbacksIfTimedout, AUCTION_IN_PROGRESS, callPrebidCache, getPriceByGranularity, getPriceGranularity } from '../src/auction'; -import { checkAdUnitSetup } from '../src/prebid'; -import { checkVideoBidSetup } from '../src/video'; -import { setupBeforeHookFnOnce, module } from '../src/hook'; -import { store } from '../src/videoCache'; -import { config } from '../src/config'; -import { ADPOD } from '../src/mediaTypes'; -import Set from 'core-js/library/fn/set'; -import find from 'core-js/library/fn/array/find'; -import { auctionManager } from '../src/auctionManager'; +import * as utils from '../src/utils.js'; +import { addBidToAuction, doCallbacksIfTimedout, AUCTION_IN_PROGRESS, callPrebidCache, getPriceByGranularity, getPriceGranularity } from '../src/auction.js'; +import { checkAdUnitSetup } from '../src/prebid.js'; +import { checkVideoBidSetup } from '../src/video.js'; +import { setupBeforeHookFnOnce, module } from '../src/hook.js'; +import { store } from '../src/videoCache.js'; +import { config } from '../src/config.js'; +import { ADPOD } from '../src/mediaTypes.js'; +import Set from 'core-js/library/fn/set.js'; +import find from 'core-js/library/fn/array/find.js'; +import { auctionManager } from '../src/auctionManager.js'; import CONSTANTS from '../src/constants.json'; -const from = require('core-js/library/fn/array/from'); +const from = require('core-js/library/fn/array/from.js'); const TARGETING_KEY_PB_CAT_DUR = 'hb_pb_cat_dur'; const TARGETING_KEY_CACHE_ID = 'hb_cache_id'; diff --git a/modules/adponeBidAdapter.js b/modules/adponeBidAdapter.js index caa4f7622cd..f128785afff 100644 --- a/modules/adponeBidAdapter.js +++ b/modules/adponeBidAdapter.js @@ -1,6 +1,6 @@ -import {BANNER} from '../src/mediaTypes'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {triggerPixel} from '../src/utils'; +import {BANNER} from '../src/mediaTypes.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {triggerPixel} from '../src/utils.js'; const ADPONE_CODE = 'adpone'; const ADPONE_ENDPOINT = 'https://rtb.adpone.com/bid-request'; diff --git a/modules/adspendBidAdapter.js b/modules/adspendBidAdapter.js index d96ae20f895..55878a36ac1 100644 --- a/modules/adspendBidAdapter.js +++ b/modules/adspendBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import { ajax } from '../src/ajax' -import { config } from '../src/config'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { ajax } from '../src/ajax.js' +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'adspend'; const BID_URL = 'https://rtb.com.ru/headerbidding-bid'; diff --git a/modules/adtelligentBidAdapter.js b/modules/adtelligentBidAdapter.js index fcaf09cc496..2d3162b435d 100644 --- a/modules/adtelligentBidAdapter.js +++ b/modules/adtelligentBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {VIDEO, BANNER} from '../src/mediaTypes'; -import {Renderer} from '../src/Renderer'; -import find from 'core-js/library/fn/array/find'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {VIDEO, BANNER} from '../src/mediaTypes.js'; +import {Renderer} from '../src/Renderer.js'; +import find from 'core-js/library/fn/array/find.js'; const URL = 'https://ghb.adtelligent.com/auction/'; const OUTSTREAM_SRC = 'https://player.adtelligent.com/outstream-unit/2.01/outstream.min.js'; diff --git a/modules/aduptechBidAdapter.js b/modules/aduptechBidAdapter.js index 7d5e018508a..d5b348ee29b 100644 --- a/modules/aduptechBidAdapter.js +++ b/modules/aduptechBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes' -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js' +import * as utils from '../src/utils.js'; export const BIDDER_CODE = 'aduptech'; export const PUBLISHER_PLACEHOLDER = '{PUBLISHER}'; diff --git a/modules/advangelistsBidAdapter.js b/modules/advangelistsBidAdapter.js index bb6cc3d9071..b3064568d3a 100644 --- a/modules/advangelistsBidAdapter.js +++ b/modules/advangelistsBidAdapter.js @@ -1,10 +1,10 @@ -import * as utils from '../src/utils'; -import { parse as parseUrl } from '../src/url'; -import { config } from '../src/config'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { VIDEO, BANNER } from '../src/mediaTypes'; -import find from 'core-js/library/fn/array/find'; -import includes from 'core-js/library/fn/array/includes'; +import * as utils from '../src/utils.js'; +import { parse as parseUrl } from '../src/url.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; +import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js/library/fn/array/includes.js'; const ADAPTER_VERSION = '1.0'; const BIDDER_CODE = 'advangelists'; diff --git a/modules/advenueBidAdapter.js b/modules/advenueBidAdapter.js index 567f60b6123..d7fa614b0a7 100644 --- a/modules/advenueBidAdapter.js +++ b/modules/advenueBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'advenue'; const URL_MULTI = 'https://ssp.advenuemedia.co.uk/?c=o&m=multi'; diff --git a/modules/advertlyBidAdapter.js b/modules/advertlyBidAdapter.js index 6806aaff18b..973b6dd0742 100755 --- a/modules/advertlyBidAdapter.js +++ b/modules/advertlyBidAdapter.js @@ -1,9 +1,9 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; -import * as utils from '../src/utils'; -import {BANNER, VIDEO} from '../src/mediaTypes'; -import { ajax } from '../src/ajax'; -import {Renderer} from '../src/Renderer'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import * as utils from '../src/utils.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { ajax } from '../src/ajax.js'; +import {Renderer} from '../src/Renderer.js'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BIDDER_CODE = 'advertly'; diff --git a/modules/adxcgAnalyticsAdapter.js b/modules/adxcgAnalyticsAdapter.js index 58792cf2675..01baa0ebd46 100644 --- a/modules/adxcgAnalyticsAdapter.js +++ b/modules/adxcgAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import { ajax } from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import { ajax } from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; import CONSTANTS from '../src/constants.json'; -import * as url from '../src/url'; -import * as utils from '../src/utils'; +import * as url from '../src/url.js'; +import * as utils from '../src/utils.js'; /** * Analytics adapter from adxcg.com diff --git a/modules/adxcgBidAdapter.js b/modules/adxcgBidAdapter.js index 5e460217e8a..37690c66d58 100644 --- a/modules/adxcgBidAdapter.js +++ b/modules/adxcgBidAdapter.js @@ -1,9 +1,9 @@ -import { config } from '../src/config' -import * as utils from '../src/utils' -import * as url from '../src/url' -import { registerBidder } from '../src/adapters/bidderFactory' -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes' -import includes from 'core-js/library/fn/array/includes' +import { config } from '../src/config.js' +import * as utils from '../src/utils.js' +import * as url from '../src/url.js' +import { registerBidder } from '../src/adapters/bidderFactory.js' +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js' +import includes from 'core-js/library/fn/array/includes.js' /** * Adapter for requesting bids from adxcg.net diff --git a/modules/adxpremiumAnalyticsAdapter.js b/modules/adxpremiumAnalyticsAdapter.js index 2224759dc6a..201aab1db03 100644 --- a/modules/adxpremiumAnalyticsAdapter.js +++ b/modules/adxpremiumAnalyticsAdapter.js @@ -1,8 +1,8 @@ -import { ajax } from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import { ajax } from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; import CONSTANTS from '../src/constants.json'; -import * as utils from '../src/utils'; +import * as utils from '../src/utils.js'; const analyticsType = 'endpoint'; const url = 'https://adxpremium.services/graphql'; diff --git a/modules/adyoulikeBidAdapter.js b/modules/adyoulikeBidAdapter.js index df37b3f2e3e..7e591b3901c 100644 --- a/modules/adyoulikeBidAdapter.js +++ b/modules/adyoulikeBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import { format } from '../src/url'; -// import { config } from '../src/config'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import find from 'core-js/library/fn/array/find'; +import * as utils from '../src/utils.js'; +import { format } from '../src/url.js'; +// import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import find from 'core-js/library/fn/array/find.js'; const VERSION = '1.0'; const BIDDER_CODE = 'adyoulike'; diff --git a/modules/ajaBidAdapter.js b/modules/ajaBidAdapter.js index de88198f48a..ce4196fe249 100644 --- a/modules/ajaBidAdapter.js +++ b/modules/ajaBidAdapter.js @@ -1,7 +1,7 @@ -import { Renderer } from '../src/Renderer'; -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { VIDEO, BANNER, NATIVE } from '../src/mediaTypes'; +import { Renderer } from '../src/Renderer.js'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO, BANNER, NATIVE } from '../src/mediaTypes.js'; const BIDDER_CODE = 'aja'; const URL = 'https://ad.as.amanad.adtdp.com/v2/prebid'; diff --git a/modules/aniviewBidAdapter.js b/modules/aniviewBidAdapter.js index ebc2556eac9..2978117e350 100644 --- a/modules/aniviewBidAdapter.js +++ b/modules/aniviewBidAdapter.js @@ -1,6 +1,6 @@ -import { VIDEO } from '../src/mediaTypes'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { Renderer } from '../src/Renderer'; +import { VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; const BIDDER_CODE = 'aniview'; const TTL = 600; diff --git a/modules/aolBidAdapter.js b/modules/aolBidAdapter.js index ec7f5fa618e..d5fb2970628 100644 --- a/modules/aolBidAdapter.js +++ b/modules/aolBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const AOL_BIDDERS_CODES = { AOL: 'aol', diff --git a/modules/appierAnalyticsAdapter.js b/modules/appierAnalyticsAdapter.js index bb4a0944af8..afcf63ef2c1 100644 --- a/modules/appierAnalyticsAdapter.js +++ b/modules/appierAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import {ajax} from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; +import {ajax} from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; -import {getGlobal} from '../src/prebidGlobal'; -import {logError, logInfo, deepClone} from '../src/utils'; +import adapterManager from '../src/adapterManager.js'; +import {getGlobal} from '../src/prebidGlobal.js'; +import {logError, logInfo, deepClone} from '../src/utils.js'; const analyticsType = 'endpoint'; diff --git a/modules/appierBidAdapter.js b/modules/appierBidAdapter.js index a8e05f8edac..660820daca3 100644 --- a/modules/appierBidAdapter.js +++ b/modules/appierBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; -import { config } from '../src/config'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; export const ADAPTER_VERSION = '1.0.0'; const SUPPORTED_AD_TYPES = [BANNER]; diff --git a/modules/appnexusAnalyticsAdapter.js b/modules/appnexusAnalyticsAdapter.js index f0f5ece26e8..d697d31cdd3 100644 --- a/modules/appnexusAnalyticsAdapter.js +++ b/modules/appnexusAnalyticsAdapter.js @@ -2,8 +2,8 @@ * appnexus.js - AppNexus Prebid Analytics Adapter */ -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; var appnexusAdapter = adapter({ global: 'AppNexusPrebidAnalytics', diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 03ed4313353..0334479b716 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -1,12 +1,12 @@ -import { Renderer } from '../src/Renderer'; -import * as utils from '../src/utils'; -import { config } from '../src/config'; -import { registerBidder, getIabSubCategory } from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO, ADPOD } from '../src/mediaTypes'; -import { auctionManager } from '../src/auctionManager'; -import find from 'core-js/library/fn/array/find'; -import includes from 'core-js/library/fn/array/includes'; -import { OUTSTREAM, INSTREAM } from '../src/video'; +import { Renderer } from '../src/Renderer.js'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; +import { registerBidder, getIabSubCategory } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO, ADPOD } from '../src/mediaTypes.js'; +import { auctionManager } from '../src/auctionManager.js'; +import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import { OUTSTREAM, INSTREAM } from '../src/video.js'; const BIDDER_CODE = 'appnexus'; const URL = 'https://ib.adnxs.com/ut/v3/prebid'; diff --git a/modules/astraoneBidAdapter.js b/modules/astraoneBidAdapter.js index efff699b0dc..7e98c1022d2 100644 --- a/modules/astraoneBidAdapter.js +++ b/modules/astraoneBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils' -import { registerBidder } from '../src/adapters/bidderFactory' -import { BANNER } from '../src/mediaTypes' +import * as utils from '../src/utils.js' +import { registerBidder } from '../src/adapters/bidderFactory.js' +import { BANNER } from '../src/mediaTypes.js' const BIDDER_CODE = 'astraone'; const SSP_ENDPOINT = 'https://ssp.astraone.io/auction/prebid'; diff --git a/modules/atomxBidAdapter.js b/modules/atomxBidAdapter.js index 86ad02cfd9a..e9f15218c4c 100644 --- a/modules/atomxBidAdapter.js +++ b/modules/atomxBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'atomx'; diff --git a/modules/audienceNetworkBidAdapter.js b/modules/audienceNetworkBidAdapter.js index 04a9cced94c..54a50af4269 100644 --- a/modules/audienceNetworkBidAdapter.js +++ b/modules/audienceNetworkBidAdapter.js @@ -1,11 +1,11 @@ /** * @file AudienceNetwork adapter. */ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { formatQS } from '../src/url'; -import { generateUUID, deepAccess, convertTypes } from '../src/utils'; -import findIndex from 'core-js/library/fn/array/find-index'; -import includes from 'core-js/library/fn/array/includes'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { formatQS } from '../src/url.js'; +import { generateUUID, deepAccess, convertTypes } from '../src/utils.js'; +import findIndex from 'core-js/library/fn/array/find-index.js'; +import includes from 'core-js/library/fn/array/includes.js'; const code = 'audienceNetwork'; const currency = 'USD'; diff --git a/modules/audiencerunBidAdapter.js b/modules/audiencerunBidAdapter.js index 83e805d8eb5..b90471ee21a 100644 --- a/modules/audiencerunBidAdapter.js +++ b/modules/audiencerunBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { config } from '../src/config'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'audiencerun'; const ENDPOINT_URL = 'https://d.audiencerun.com/prebid'; diff --git a/modules/beachfrontBidAdapter.js b/modules/beachfrontBidAdapter.js index 3a9dedcd4d9..bbb4ae35729 100644 --- a/modules/beachfrontBidAdapter.js +++ b/modules/beachfrontBidAdapter.js @@ -1,11 +1,11 @@ -import * as utils from '../src/utils'; -import { parse as parseUrl } from '../src/url'; -import { config } from '../src/config'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { Renderer } from '../src/Renderer'; -import { VIDEO, BANNER } from '../src/mediaTypes'; -import find from 'core-js/library/fn/array/find'; -import includes from 'core-js/library/fn/array/includes'; +import * as utils from '../src/utils.js'; +import { parse as parseUrl } from '../src/url.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; +import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js/library/fn/array/includes.js'; const ADAPTER_VERSION = '1.9'; const ADAPTER_NAME = 'BFIO_PREBID'; diff --git a/modules/betweenBidAdapter.js b/modules/betweenBidAdapter.js index a67af0feb1a..5ad78a6bdc6 100644 --- a/modules/betweenBidAdapter.js +++ b/modules/betweenBidAdapter.js @@ -1,4 +1,4 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'between'; diff --git a/modules/bidfluenceBidAdapter.js b/modules/bidfluenceBidAdapter.js index c6adc2897b0..6857a0f833f 100644 --- a/modules/bidfluenceBidAdapter.js +++ b/modules/bidfluenceBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'bidfluence'; function stdTimezoneOffset(t) { diff --git a/modules/bidglassBidAdapter.js b/modules/bidglassBidAdapter.js index 553a52b25f4..6db35f184ca 100644 --- a/modules/bidglassBidAdapter.js +++ b/modules/bidglassBidAdapter.js @@ -1,134 +1,134 @@ -import * as utils from '../src/utils'; -// import {config} from 'src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; - -const BIDDER_CODE = 'bidglass'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['bg'], // short code - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!(bid.params.adUnitId && !isNaN(parseFloat(bid.params.adUnitId)) && isFinite(bid.params.adUnitId)); - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - /* - Sample array entry for validBidRequests[]: - [{ - "bidder": "bidglass", - "bidId": "51ef8751f9aead", - "params": { - "adUnitId": 11, - ... - }, - "adUnitCode": "div-gpt-ad-1460505748561-0", - "transactionId": "d7b773de-ceaa-484d-89ca-d9f51b8d61ec", - "sizes": [[320,50],[300,250],[300,600]], - "bidderRequestId": "418b37f85e772c", - "auctionId": "18fd8b8b0bd757", - "bidRequestsCount": 1 - }] - */ - - let imps = []; - let getReferer = function() { - return window === window.top ? window.location.href : window.parent === window.top ? document.referrer : null; - }; - let getOrigins = function() { - var ori = ['https://' + window.location.hostname]; - - if (window.location.ancestorOrigins) { - for (var i = 0; i < window.location.ancestorOrigins.length; i++) { - ori.push(window.location.ancestorOrigins[i]); - } - } else if (window !== window.top) { - // Derive the parent origin - var parts = document.referrer.split('/'); - - ori.push('https://' + parts[2]); - - if (window.parent !== window.top) { - // Additional unknown origins exist - ori.push('null'); - } - } - - return ori; - }; - - utils._each(validBidRequests, function(bid) { - bid.sizes = ((utils.isArray(bid.sizes) && utils.isArray(bid.sizes[0])) ? bid.sizes : [bid.sizes]); - bid.sizes = bid.sizes.filter(size => utils.isArray(size)); - - // Stuff to send: [bid id, sizes, adUnitId] - imps.push({ - bidId: bid.bidId, - sizes: bid.sizes, - adUnitId: utils.getBidIdParameter('adUnitId', bid.params) - }); - }); - - // Stuff to send: page URL - const bidReq = { - reqId: utils.getUniqueIdentifierStr(), - imps: imps, - ref: getReferer(), - ori: getOrigins() - }; - - let url = 'https://bid.glass/ad/hb.php?' + - `src=$$REPO_AND_VERSION$$`; - - return { - method: 'POST', - url: url, - data: JSON.stringify(bidReq), - options: { - contentType: 'text/plain', - withCredentials: false - } - } - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {ServerResponse} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse) { - const bidResponses = []; - - utils._each(serverResponse.body.bidResponses, function(bid) { - bidResponses.push({ - requestId: bid.requestId, - cpm: parseFloat(bid.cpm), - width: parseInt(bid.width, 10), - height: parseInt(bid.height, 10), - creativeId: bid.creativeId, - dealId: bid.dealId || null, - currency: bid.currency || 'USD', - mediaType: bid.mediaType || 'banner', - netRevenue: true, - ttl: bid.ttl || 10, - ad: bid.ad - }); - }); - - return bidResponses; - } - -} - -registerBidder(spec); +import * as utils from '../src/utils.js'; +// import {config} from 'src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; + +const BIDDER_CODE = 'bidglass'; + +export const spec = { + code: BIDDER_CODE, + aliases: ['bg'], // short code + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function(bid) { + return !!(bid.params.adUnitId && !isNaN(parseFloat(bid.params.adUnitId)) && isFinite(bid.params.adUnitId)); + }, + /** + * Make a server request from the list of BidRequests. + * + * @param {validBidRequests[]} - an array of bids + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function(validBidRequests, bidderRequest) { + /* + Sample array entry for validBidRequests[]: + [{ + "bidder": "bidglass", + "bidId": "51ef8751f9aead", + "params": { + "adUnitId": 11, + ... + }, + "adUnitCode": "div-gpt-ad-1460505748561-0", + "transactionId": "d7b773de-ceaa-484d-89ca-d9f51b8d61ec", + "sizes": [[320,50],[300,250],[300,600]], + "bidderRequestId": "418b37f85e772c", + "auctionId": "18fd8b8b0bd757", + "bidRequestsCount": 1 + }] + */ + + let imps = []; + let getReferer = function() { + return window === window.top ? window.location.href : window.parent === window.top ? document.referrer : null; + }; + let getOrigins = function() { + var ori = ['https://' + window.location.hostname]; + + if (window.location.ancestorOrigins) { + for (var i = 0; i < window.location.ancestorOrigins.length; i++) { + ori.push(window.location.ancestorOrigins[i]); + } + } else if (window !== window.top) { + // Derive the parent origin + var parts = document.referrer.split('/'); + + ori.push('https://' + parts[2]); + + if (window.parent !== window.top) { + // Additional unknown origins exist + ori.push('null'); + } + } + + return ori; + }; + + utils._each(validBidRequests, function(bid) { + bid.sizes = ((utils.isArray(bid.sizes) && utils.isArray(bid.sizes[0])) ? bid.sizes : [bid.sizes]); + bid.sizes = bid.sizes.filter(size => utils.isArray(size)); + + // Stuff to send: [bid id, sizes, adUnitId] + imps.push({ + bidId: bid.bidId, + sizes: bid.sizes, + adUnitId: utils.getBidIdParameter('adUnitId', bid.params) + }); + }); + + // Stuff to send: page URL + const bidReq = { + reqId: utils.getUniqueIdentifierStr(), + imps: imps, + ref: getReferer(), + ori: getOrigins() + }; + + let url = 'https://bid.glass/ad/hb.php?' + + `src=$$REPO_AND_VERSION$$`; + + return { + method: 'POST', + url: url, + data: JSON.stringify(bidReq), + options: { + contentType: 'text/plain', + withCredentials: false + } + } + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {ServerResponse} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function(serverResponse) { + const bidResponses = []; + + utils._each(serverResponse.body.bidResponses, function(bid) { + bidResponses.push({ + requestId: bid.requestId, + cpm: parseFloat(bid.cpm), + width: parseInt(bid.width, 10), + height: parseInt(bid.height, 10), + creativeId: bid.creativeId, + dealId: bid.dealId || null, + currency: bid.currency || 'USD', + mediaType: bid.mediaType || 'banner', + netRevenue: true, + ttl: bid.ttl || 10, + ad: bid.ad + }); + }); + + return bidResponses; + } + +} + +registerBidder(spec); diff --git a/modules/bidphysicsBidAdapter.js b/modules/bidphysicsBidAdapter.js index cdf30e670fc..b6b5690ede5 100644 --- a/modules/bidphysicsBidAdapter.js +++ b/modules/bidphysicsBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -import * as utils from '../src/utils'; -import {BANNER} from '../src/mediaTypes'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; +import {BANNER} from '../src/mediaTypes.js'; const ENDPOINT_URL = 'https://exchange.bidphysics.com/auction'; diff --git a/modules/bridgewellBidAdapter.js b/modules/bridgewellBidAdapter.js index a988fad1478..1c09cfc3624 100644 --- a/modules/bridgewellBidAdapter.js +++ b/modules/bridgewellBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE } from '../src/mediaTypes'; -import find from 'core-js/library/fn/array/find'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import find from 'core-js/library/fn/array/find.js'; const BIDDER_CODE = 'bridgewell'; const REQUEST_ENDPOINT = 'https://prebid.scupio.com/recweb/prebid.aspx?cb=' + Math.random(); diff --git a/modules/brightcomBidAdapter.js b/modules/brightcomBidAdapter.js index 862933d076b..0a418406d4f 100644 --- a/modules/brightcomBidAdapter.js +++ b/modules/brightcomBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import * as url from '../src/url'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; -import { config } from '../src/config'; +import * as utils from '../src/utils.js'; +import * as url from '../src/url.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'brightcom'; const URL = 'https://brightcombid.marphezis.com/hb'; diff --git a/modules/britepoolIdSystem.js b/modules/britepoolIdSystem.js index ecea6bd3686..17a39e96aad 100644 --- a/modules/britepoolIdSystem.js +++ b/modules/britepoolIdSystem.js @@ -5,9 +5,9 @@ * @requires module:modules/userId */ -import * as utils from '../src/utils' -import {ajax} from '../src/ajax'; -import {submodule} from '../src/hook'; +import * as utils from '../src/utils.js' +import {ajax} from '../src/ajax.js'; +import {submodule} from '../src/hook.js'; /** @type {Submodule} */ export const britepoolIdSubmodule = { diff --git a/modules/browsiRtdProvider.js b/modules/browsiRtdProvider.js index e2bd208f32f..d3fe3176cda 100644 --- a/modules/browsiRtdProvider.js +++ b/modules/browsiRtdProvider.js @@ -18,10 +18,10 @@ */ import {config} from '../src/config.js'; -import * as utils from '../src/utils'; -import {submodule} from '../src/hook'; -import {ajaxBuilder} from '../src/ajax'; -import {loadExternalScript} from '../src/adloader'; +import * as utils from '../src/utils.js'; +import {submodule} from '../src/hook.js'; +import {ajaxBuilder} from '../src/ajax.js'; +import {loadExternalScript} from '../src/adloader.js'; /** @type {string} */ const MODULE_NAME = 'realTimeData'; diff --git a/modules/bucksenseBidAdapter.js b/modules/bucksenseBidAdapter.js index 12a9e287f38..cb2eabbe774 100644 --- a/modules/bucksenseBidAdapter.js +++ b/modules/bucksenseBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const WHO = 'BKSHBID-005'; const BIDDER_CODE = 'bucksense'; diff --git a/modules/buzzoolaBidAdapter.js b/modules/buzzoolaBidAdapter.js index da2a3b30c2e..f87607657c3 100644 --- a/modules/buzzoolaBidAdapter.js +++ b/modules/buzzoolaBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER, VIDEO} from '../src/mediaTypes'; -import {Renderer} from '../src/Renderer'; -import {OUTSTREAM} from '../src/video'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import {Renderer} from '../src/Renderer.js'; +import {OUTSTREAM} from '../src/video.js'; const BIDDER_CODE = 'buzzoola'; const ENDPOINT = 'https://exchange.buzzoola.com/ssp/prebidjs'; diff --git a/modules/byplayBidAdapter.js b/modules/byplayBidAdapter.js index e354af61eaa..b5156e4bd99 100644 --- a/modules/byplayBidAdapter.js +++ b/modules/byplayBidAdapter.js @@ -1,7 +1,7 @@ -import { config } from '../src/config'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { Renderer } from '../src/Renderer'; -import { VIDEO } from '../src/mediaTypes'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'byplay'; const ENDPOINT_URL = 'https://prebid.byplay.net/bidder'; diff --git a/modules/c1xBidAdapter.js b/modules/c1xBidAdapter.js index 9364ef2256a..8e1f1487ba7 100644 --- a/modules/c1xBidAdapter.js +++ b/modules/c1xBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import * as utils from '../src/utils'; -import { userSync } from '../src/userSync'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; +import { userSync } from '../src/userSync.js'; const BIDDER_CODE = 'c1x'; const URL = 'https://ht.c1exchange.com/ht'; diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index 091b16c8211..722fc59c921 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -11,11 +11,11 @@ * If publisher has not defined translation file than prebid will use default prebid translation file provided here //cdn.jsdelivr.net/gh/prebid/category-mapping-file@1/freewheel-mapping.json */ -import { config } from '../src/config'; -import { setupBeforeHookFnOnce, hook } from '../src/hook'; -import { ajax } from '../src/ajax'; -import { timestamp, logError, setDataInLocalStorage, getDataFromLocalStorage } from '../src/utils'; -import { addBidResponse } from '../src/auction'; +import { config } from '../src/config.js'; +import { setupBeforeHookFnOnce, hook } from '../src/hook.js'; +import { ajax } from '../src/ajax.js'; +import { timestamp, logError, setDataInLocalStorage, getDataFromLocalStorage } from '../src/utils.js'; +import { addBidResponse } from '../src/auction.js'; const DEFAULT_TRANSLATION_FILE_URL = 'https://cdn.jsdelivr.net/gh/prebid/category-mapping-file@1/freewheel-mapping.json'; const DEFAULT_IAB_TO_FW_MAPPING_KEY = 'iabToFwMappingkey'; diff --git a/modules/ccxBidAdapter.js b/modules/ccxBidAdapter.js index 90eb7e7ed9f..5532ec6ca1e 100644 --- a/modules/ccxBidAdapter.js +++ b/modules/ccxBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils' -import { registerBidder } from '../src/adapters/bidderFactory' -import { config } from '../src/config' +import * as utils from '../src/utils.js' +import { registerBidder } from '../src/adapters/bidderFactory.js' +import { config } from '../src/config.js' const BIDDER_CODE = 'ccx' const BID_URL = 'https://delivery.clickonometrics.pl/ortb/prebid/bid' const SUPPORTED_VIDEO_PROTOCOLS = [2, 3, 5, 6] diff --git a/modules/cedatoBidAdapter.js b/modules/cedatoBidAdapter.js index 7d2edecd3b5..72377b2dfdb 100644 --- a/modules/cedatoBidAdapter.js +++ b/modules/cedatoBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'cedato'; const BID_URL = 'https://h.cedatoplayer.com/hb'; diff --git a/modules/cleanmedianetBidAdapter.js b/modules/cleanmedianetBidAdapter.js index 97452e987bc..a8f37450d68 100644 --- a/modules/cleanmedianetBidAdapter.js +++ b/modules/cleanmedianetBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {config} from '../src/config'; -import {Renderer} from '../src/Renderer'; -import {BANNER, VIDEO} from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {config} from '../src/config.js'; +import {Renderer} from '../src/Renderer.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; export const helper = { getTopWindowDomain: function (url) { diff --git a/modules/clickforceBidAdapter.js b/modules/clickforceBidAdapter.js index 43ef76cc931..eb73033e2d0 100644 --- a/modules/clickforceBidAdapter.js +++ b/modules/clickforceBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER, NATIVE} from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER, NATIVE} from '../src/mediaTypes.js'; const BIDDER_CODE = 'clickforce'; const ENDPOINT_URL = 'https://ad.doublemax.net/adserver/prebid.json?cb=' + new Date().getTime() + '&hb=1&ver=1.21'; diff --git a/modules/coinzillaBidAdapter.js b/modules/coinzillaBidAdapter.js index 26ea7bb71e1..240a3f1fcde 100644 --- a/modules/coinzillaBidAdapter.js +++ b/modules/coinzillaBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'coinzilla'; const ENDPOINT_URL = 'https://request.czilladx.com/serve/request.php'; diff --git a/modules/collectcentBidAdapter.js b/modules/collectcentBidAdapter.js index f7f5f3ef0c4..add3e06430d 100644 --- a/modules/collectcentBidAdapter.js +++ b/modules/collectcentBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'collectcent'; const URL_MULTI = 'https://publishers.motionspots.com/?c=o&m=multi'; diff --git a/modules/colossussspBidAdapter.js b/modules/colossussspBidAdapter.js index adcd5df9fb6..cf4d306e686 100644 --- a/modules/colossussspBidAdapter.js +++ b/modules/colossussspBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'colossusssp'; const G_URL = 'https://colossusssp.com/?c=o&m=multi'; diff --git a/modules/consentManagement.js b/modules/consentManagement.js index d5703c1a784..f098effdb08 100644 --- a/modules/consentManagement.js +++ b/modules/consentManagement.js @@ -4,11 +4,11 @@ * and make it available for any GDPR supported adapters to read/pass this information to * their system. */ -import * as utils from '../src/utils'; -import { config } from '../src/config'; -import { gdprDataHandler } from '../src/adapterManager'; -import includes from 'core-js/library/fn/array/includes'; -import strIncludes from 'core-js/library/fn/string/includes'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; +import { gdprDataHandler } from '../src/adapterManager.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import strIncludes from 'core-js/library/fn/string/includes.js'; const DEFAULT_CMP = 'iab'; const DEFAULT_CONSENT_TIMEOUT = 10000; diff --git a/modules/consentManagementUsp.js b/modules/consentManagementUsp.js index 35853ff05a6..1a5879a40ff 100644 --- a/modules/consentManagementUsp.js +++ b/modules/consentManagementUsp.js @@ -4,9 +4,9 @@ * information and make it available for any USP (CCPA) supported adapters to * read/pass this information to their system. */ -import * as utils from '../src/utils'; -import { config } from '../src/config'; -import { uspDataHandler } from '../src/adapterManager'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; +import { uspDataHandler } from '../src/adapterManager.js'; const DEFAULT_CONSENT_API = 'iab'; const DEFAULT_CONSENT_TIMEOUT = 50; diff --git a/modules/consumableBidAdapter.js b/modules/consumableBidAdapter.js index 18545cbc319..8eb56f7d0c2 100644 --- a/modules/consumableBidAdapter.js +++ b/modules/consumableBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'consumable'; diff --git a/modules/conversantBidAdapter.js b/modules/conversantBidAdapter.js index bb11b1f87cb..2f078716466 100644 --- a/modules/conversantBidAdapter.js +++ b/modules/conversantBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'conversant'; const URL = 'https://web.hb.ad.cpe.dotomi.com/s2s/header/24'; diff --git a/modules/cosmosBidAdapter.js b/modules/cosmosBidAdapter.js index f3a8979165b..73ee5c223b3 100644 --- a/modules/cosmosBidAdapter.js +++ b/modules/cosmosBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'cosmos'; const BID_ENDPOINT = 'https://bid.cosmoshq.com/openrtb2/bids'; diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js index 8d2ec31a2c6..6146e704448 100644 --- a/modules/cpmstarBidAdapter.js +++ b/modules/cpmstarBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import {VIDEO, BANNER} from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import {VIDEO, BANNER} from '../src/mediaTypes.js'; const BIDDER_CODE = 'cpmstar'; diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js index 4f88ea9b585..b1b1cc75745 100644 --- a/modules/criteoBidAdapter.js +++ b/modules/criteoBidAdapter.js @@ -1,11 +1,11 @@ -import { loadExternalScript } from '../src/adloader'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; -import { parse } from '../src/url'; -import * as utils from '../src/utils'; -import find from 'core-js/library/fn/array/find'; -import { verify } from 'criteo-direct-rsa-validate/build/verify'; +import { loadExternalScript } from '../src/adloader.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { parse } from '../src/url.js'; +import * as utils from '../src/utils.js'; +import find from 'core-js/library/fn/array/find.js'; +import { verify } from 'criteo-direct-rsa-validate/build/verify.js'; export const ADAPTER_VERSION = 26; const BIDDER_CODE = 'criteo'; diff --git a/modules/criteoIdSystem.js b/modules/criteoIdSystem.js index fe89de5d341..469532e4aa7 100644 --- a/modules/criteoIdSystem.js +++ b/modules/criteoIdSystem.js @@ -5,11 +5,11 @@ * @requires module:modules/userId */ -import * as utils from '../src/utils' -import * as ajax from '../src/ajax' -import * as urlLib from '../src/url' -import { getRefererInfo } from '../src/refererDetection' -import { submodule } from '../src/hook'; +import * as utils from '../src/utils.js' +import * as ajax from '../src/ajax.js' +import * as urlLib from '../src/url.js' +import { getRefererInfo } from '../src/refererDetection.js' +import { submodule } from '../src/hook.js'; const bididStorageKey = 'cto_bidid'; const bundleStorageKey = 'cto_bundle'; diff --git a/modules/currency.js b/modules/currency.js index 28e033fb1a2..84ca5e42783 100644 --- a/modules/currency.js +++ b/modules/currency.js @@ -1,8 +1,8 @@ -import { createBid } from '../src/bidfactory'; -import { STATUS } from '../src/constants'; -import { ajax } from '../src/ajax'; -import * as utils from '../src/utils'; -import { config } from '../src/config'; +import { createBid } from '../src/bidfactory.js'; +import { STATUS } from '../src/constants.json'; +import { ajax } from '../src/ajax.js'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; import { getHook } from '../src/hook.js'; const DEFAULT_CURRENCY_RATE_URL = 'https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json?date=$$TODAY$$'; diff --git a/modules/dailyhuntBidAdapter.js b/modules/dailyhuntBidAdapter.js index bcad7679c4f..5b28f086938 100644 --- a/modules/dailyhuntBidAdapter.js +++ b/modules/dailyhuntBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import * as mediaTypes from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import * as mediaTypes from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'dailyhunt'; const BIDDER_ALIAS = 'dh'; diff --git a/modules/datablocksAnalyticsAdapter.js b/modules/datablocksAnalyticsAdapter.js index 76dd490180b..5e977155284 100644 --- a/modules/datablocksAnalyticsAdapter.js +++ b/modules/datablocksAnalyticsAdapter.js @@ -2,8 +2,8 @@ * Analytics Adapter for Datablocks */ -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; var datablocksAdapter = adapter({ global: 'datablocksAnalytics', diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js index cbad3ac910c..32b18592417 100644 --- a/modules/datablocksBidAdapter.js +++ b/modules/datablocksBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; -import { parse as parseUrl } from '../src/url'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { parse as parseUrl } from '../src/url.js'; const NATIVE_MAP = { 'body': 2, 'body2': 10, diff --git a/modules/deepintentBidAdapter.js b/modules/deepintentBidAdapter.js index ace4bcb5ae2..44acd526037 100644 --- a/modules/deepintentBidAdapter.js +++ b/modules/deepintentBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER} from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER} from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'deepintent'; const BIDDER_ENDPOINT = 'https://prebid.deepintent.com/prebid'; const USER_SYNC_URL = 'https://cdn.deepintent.com/syncpixel.html'; diff --git a/modules/dfpAdServerVideo.js b/modules/dfpAdServerVideo.js index c3f867308d1..426da05efcf 100644 --- a/modules/dfpAdServerVideo.js +++ b/modules/dfpAdServerVideo.js @@ -2,13 +2,13 @@ * This module adds [DFP support]{@link https://www.doubleclickbygoogle.com/} for Video to Prebid. */ -import { registerVideoSupport } from '../src/adServerManager'; -import { targeting } from '../src/targeting'; -import { formatQS, format as buildUrl, parse } from '../src/url'; -import { deepAccess, isEmpty, logError, parseSizesInput } from '../src/utils'; -import { config } from '../src/config'; -import { getHook, submodule } from '../src/hook'; -import { auctionManager } from '../src/auctionManager'; +import { registerVideoSupport } from '../src/adServerManager.js'; +import { targeting } from '../src/targeting.js'; +import { formatQS, format as buildUrl, parse } from '../src/url.js'; +import { deepAccess, isEmpty, logError, parseSizesInput } from '../src/utils.js'; +import { config } from '../src/config.js'; +import { getHook, submodule } from '../src/hook.js'; +import { auctionManager } from '../src/auctionManager.js'; /** * @typedef {Object} DfpVideoParams diff --git a/modules/digiTrustIdSystem.js b/modules/digiTrustIdSystem.js index fd2b96cb31a..70d23d8df23 100644 --- a/modules/digiTrustIdSystem.js +++ b/modules/digiTrustIdSystem.js @@ -9,9 +9,9 @@ * @requires module:modules/userId */ -import * as utils from '../src/utils' -import { ajax } from '../src/ajax'; -import { submodule } from '../src/hook'; +import * as utils from '../src/utils.js' +import { ajax } from '../src/ajax.js'; +import { submodule } from '../src/hook.js'; var fallbackTimeout = 1550; // timeout value that allows userId system to execute first var fallbackTimer = 0; // timer Id for fallback init so we don't double call diff --git a/modules/districtmDMXBidAdapter.js b/modules/districtmDMXBidAdapter.js index 772508e02d8..fac275a229b 100644 --- a/modules/districtmDMXBidAdapter.js +++ b/modules/districtmDMXBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import {config} from '../src/config'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import {config} from '../src/config.js'; const BIDDER_CODE = 'districtmDMX'; diff --git a/modules/djaxBidAdapter.js b/modules/djaxBidAdapter.js index 80975f0929a..ffaf61a3f15 100644 --- a/modules/djaxBidAdapter.js +++ b/modules/djaxBidAdapter.js @@ -1,9 +1,9 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; -import * as utils from '../src/utils'; -import {BANNER, VIDEO} from '../src/mediaTypes'; -import { ajax } from '../src/ajax'; -import {Renderer} from '../src/Renderer'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import * as utils from '../src/utils.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { ajax } from '../src/ajax.js'; +import {Renderer} from '../src/Renderer.js'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BIDDER_CODE = 'djax'; diff --git a/modules/dspxBidAdapter.js b/modules/dspxBidAdapter.js index 4954347d288..0bde2b6ec10 100644 --- a/modules/dspxBidAdapter.js +++ b/modules/dspxBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'dspx'; const ENDPOINT_URL = 'https://buyer.dspx.tv/request/'; diff --git a/modules/ebdrBidAdapter.js b/modules/ebdrBidAdapter.js index d8af215f96a..c30c10d8a90 100644 --- a/modules/ebdrBidAdapter.js +++ b/modules/ebdrBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { VIDEO, BANNER } from '../src/mediaTypes'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'ebdr'; export const spec = { code: BIDDER_CODE, diff --git a/modules/emoteevBidAdapter.js b/modules/emoteevBidAdapter.js index fb62e4381e3..254373b354a 100644 --- a/modules/emoteevBidAdapter.js +++ b/modules/emoteevBidAdapter.js @@ -14,8 +14,8 @@ * @author Emoteev Engineering . */ -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER} from '../src/mediaTypes'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER} from '../src/mediaTypes.js'; import { triggerPixel, getUniqueIdentifierStr, @@ -25,9 +25,9 @@ import { isInteger, getParameterByName, getCookie -} from '../src/utils'; -import {config} from '../src/config'; -import * as url from '../src/url'; +} from '../src/utils.js'; +import {config} from '../src/config.js'; +import * as url from '../src/url.js'; export const BIDDER_CODE = 'emoteev'; diff --git a/modules/emx_digitalBidAdapter.js b/modules/emx_digitalBidAdapter.js index 60e3de4adcd..22a7bb6f643 100644 --- a/modules/emx_digitalBidAdapter.js +++ b/modules/emx_digitalBidAdapter.js @@ -1,9 +1,9 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; -import { Renderer } from '../src/Renderer'; -import includes from 'core-js/library/fn/array/includes'; -import {parse as parseUrl} from '../src/url'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import {parse as parseUrl} from '../src/url.js'; const BIDDER_CODE = 'emx_digital'; const ENDPOINT = 'hb.emxdgt.com'; diff --git a/modules/envivoBidAdapter.js b/modules/envivoBidAdapter.js index 41bfda7c071..b9c80ffd468 100644 --- a/modules/envivoBidAdapter.js +++ b/modules/envivoBidAdapter.js @@ -1,9 +1,9 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; -import * as utils from '../src/utils'; -import {BANNER, VIDEO} from '../src/mediaTypes'; -import { ajax } from '../src/ajax'; -import {Renderer} from '../src/Renderer'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import * as utils from '../src/utils.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { ajax } from '../src/ajax.js'; +import {Renderer} from '../src/Renderer.js'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BIDDER_CODE = 'envivo'; diff --git a/modules/eplanningAnalyticsAdapter.js b/modules/eplanningAnalyticsAdapter.js index 21ecddfbc3a..08db2f2ca9d 100644 --- a/modules/eplanningAnalyticsAdapter.js +++ b/modules/eplanningAnalyticsAdapter.js @@ -1,7 +1,7 @@ -import {ajax} from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; -import * as utils from '../src/utils'; +import {ajax} from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; +import * as utils from '../src/utils.js'; const CONSTANTS = require('../src/constants.json'); diff --git a/modules/eplanningBidAdapter.js b/modules/eplanningBidAdapter.js index 219192b6406..b7747c93086 100644 --- a/modules/eplanningBidAdapter.js +++ b/modules/eplanningBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'eplanning'; const rnd = Math.random(); diff --git a/modules/etargetBidAdapter.js b/modules/etargetBidAdapter.js index ad341a136b1..5e07561044a 100644 --- a/modules/etargetBidAdapter.js +++ b/modules/etargetBidAdapter.js @@ -1,7 +1,7 @@ 'use strict'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'etarget'; const countryMap = { diff --git a/modules/express.js b/modules/express.js index e5ea22fe272..f4a76daefdf 100644 --- a/modules/express.js +++ b/modules/express.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; +import * as utils from '../src/utils.js'; const MODULE_NAME = 'express'; diff --git a/modules/feedadBidAdapter.js b/modules/feedadBidAdapter.js index 1e995ee8914..3992f2db5e0 100644 --- a/modules/feedadBidAdapter.js +++ b/modules/feedadBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER, VIDEO} from '../src/mediaTypes'; -import {ajax} from '../src/ajax'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import {ajax} from '../src/ajax.js'; /** * Version of the FeedAd bid adapter diff --git a/modules/fidelityBidAdapter.js b/modules/fidelityBidAdapter.js index f27c71d2712..a0589986af3 100644 --- a/modules/fidelityBidAdapter.js +++ b/modules/fidelityBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'fidelity'; const BIDDER_SERVER = 'x.fidelity-media.com'; diff --git a/modules/fintezaAnalyticsAdapter.js b/modules/fintezaAnalyticsAdapter.js index a1376c28427..f6fcd9c6ca4 100644 --- a/modules/fintezaAnalyticsAdapter.js +++ b/modules/fintezaAnalyticsAdapter.js @@ -1,8 +1,8 @@ -import { ajax } from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; -import * as utils from '../src/utils'; -import { parse as parseURL } from '../src/url'; +import { ajax } from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; +import * as utils from '../src/utils.js'; +import { parse as parseURL } from '../src/url.js'; const CONSTANTS = require('../src/constants.json'); diff --git a/modules/fluctBidAdapter.js b/modules/fluctBidAdapter.js index 6e09d9368b5..420fe04ddcb 100644 --- a/modules/fluctBidAdapter.js +++ b/modules/fluctBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'fluct'; const END_POINT = 'https://hb.adingo.jp/prebid'; diff --git a/modules/freeWheelAdserverVideo.js b/modules/freeWheelAdserverVideo.js index 03217b1165d..cb4bd938373 100644 --- a/modules/freeWheelAdserverVideo.js +++ b/modules/freeWheelAdserverVideo.js @@ -2,8 +2,8 @@ * This module adds Freewheel support for Video to Prebid. */ -import { registerVideoSupport } from '../src/adServerManager'; -import { getHook, submodule } from '../src/hook'; +import { registerVideoSupport } from '../src/adServerManager.js'; +import { getHook, submodule } from '../src/hook.js'; export const adpodUtils = {}; export function notifyTranslationModule(fn) { diff --git a/modules/freewheel-sspBidAdapter.js b/modules/freewheel-sspBidAdapter.js index 11173973b4f..69668aa288b 100644 --- a/modules/freewheel-sspBidAdapter.js +++ b/modules/freewheel-sspBidAdapter.js @@ -1,385 +1,385 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; - -const BIDDER_CODE = 'freewheel-ssp'; - -const PROTOCOL = getProtocol(); -const FREEWHEEL_ADSSETUP = PROTOCOL + '://ads.stickyadstv.com/www/delivery/swfIndex.php'; -const MUSTANG_URL = PROTOCOL + '://cdn.stickyadstv.com/mustang/mustang.min.js'; -const PRIMETIME_URL = PROTOCOL + '://cdn.stickyadstv.com/prime-time/'; -const USER_SYNC_URL = PROTOCOL + '://ads.stickyadstv.com/auto-user-sync'; - -function getProtocol() { - return 'https'; -} - -function isValidUrl(str) { - if (!str) { - return false; - } - - // regExp for url validation - var pattern = /^(https?|ftp|file):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/; - return pattern.test(str); -} - -function getBiggerSize(array) { - var result = [0, 0]; - for (var i = 0; i < array.length; i++) { - if (array[i][0] * array[i][1] > result[0] * result[1]) { - result = array[i]; - } - } - return result; -} - -function getBiggerSizeWithLimit(array, minSizeLimit, maxSizeLimit) { - var minSize = minSizeLimit || [0, 0]; - var maxSize = maxSizeLimit || [Number.MAX_VALUE, Number.MAX_VALUE]; - var candidates = []; - - for (var i = 0; i < array.length; i++) { - if (array[i][0] * array[i][1] >= minSize[0] * minSize[1] && array[i][0] * array[i][1] <= maxSize[0] * maxSize[1]) { - candidates.push(array[i]); - } - } - - return getBiggerSize(candidates); -} - -/* -* read the pricing extension with this format: 1.0000 -* @return {object} pricing data in format: {currency: "EUR", price:"1.000"} -*/ -function getPricing(xmlNode) { - var pricingExtNode; - var princingData = {}; - - var extensions = xmlNode.querySelectorAll('Extension'); - // Nodelist.forEach is not supported in IE and Edge - // Workaround given here https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10638731/ - Array.prototype.forEach.call(extensions, function(node) { - if (node.getAttribute('type') === 'StickyPricing') { - pricingExtNode = node; - } - }); - - if (pricingExtNode) { - var priceNode = pricingExtNode.querySelector('Price'); - princingData = { - currency: priceNode.getAttribute('currency'), - price: priceNode.textContent || priceNode.innerText - }; - } else { - utils.logWarn('PREBID - ' + BIDDER_CODE + ': Can\'t get pricing data. Is price awareness enabled?'); - } - - return princingData; -} - -function hashcode(inputString) { - var hash = 0; - var char; - if (inputString.length == 0) return hash; - for (var i = 0; i < inputString.length; i++) { - char = inputString.charCodeAt(i); - hash = ((hash << 5) - hash) + char; - hash = hash & hash; // Convert to 32bit integer - } - return hash; -} - -function getCreativeId(xmlNode) { - var creaId = ''; - var adNodes = xmlNode.querySelectorAll('Ad'); - // Nodelist.forEach is not supported in IE and Edge - // Workaround given here https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10638731/ - Array.prototype.forEach.call(adNodes, function(el) { - creaId += '[' + el.getAttribute('id') + ']'; - }); - - return creaId; -} - -/** -* returns the top most accessible window -*/ -function getTopMostWindow() { - var res = window; - - try { - while (top !== res) { - if (res.parent.location.href.length) { res = res.parent; } - } - } catch (e) {} - - return res; -} - -function getComponentId(inputFormat) { - var component = 'mustang'; // default component id - - if (inputFormat && inputFormat !== 'inbanner') { - // format identifiers are equals to their component ids. - component = inputFormat; - } - - return component; -} - -function getAPIName(componentId) { - componentId = componentId || ''; - - // remove dash in componentId to get API name - return componentId.replace('-', ''); -} - -function formatAdHTML(bid, size) { - var integrationType = bid.params.format; - - var divHtml = '
'; - - var script = ''; - var libUrl = ''; - if (integrationType && integrationType !== 'inbanner') { - libUrl = PRIMETIME_URL + getComponentId(bid.params.format) + '.min.js'; - script = getOutstreamScript(bid, size); - } else { - libUrl = MUSTANG_URL; - script = getInBannerScript(bid, size); - } - - return divHtml + - ''; -} - -var getInBannerScript = function(bid, size) { - return 'var config = {' + - ' preloadedVast:vast,' + - ' autoPlay:true' + - ' };' + - ' var ad = new window.com.stickyadstv.vpaid.Ad(document.getElementById("freewheelssp_prebid_target"),config);' + - ' (new window.com.stickyadstv.tools.ASLoader(' + bid.params.zoneId + ', \'' + getComponentId(bid.params.format) + '\')).registerEvents(ad);' + - ' ad.initAd(' + size[0] + ',' + size[1] + ',"",0,"","");'; -}; - -var getOutstreamScript = function(bid) { - var config = bid.params; - - // default placement if no placement is set - if (!config.hasOwnProperty('domId') && !config.hasOwnProperty('auto') && !config.hasOwnProperty('p') && !config.hasOwnProperty('article')) { - if (config.format === 'intext-roll') { - config.iframeMode = 'dfp'; - } else { - config.domId = 'freewheelssp_prebid_target'; - } - } - - var script = 'var config = {' + - ' preloadedVast:vast,' + - ' ASLoader:new window.com.stickyadstv.tools.ASLoader(' + bid.params.zoneId + ', \'' + getComponentId(bid.params.format) + '\')'; - - for (var key in config) { - // dont' send format parameter - // neither zone nor vastUrlParams value as Vast is already loaded - if (config.hasOwnProperty(key) && key !== 'format' && key !== 'zone' && key !== 'zoneId' && key !== 'vastUrlParams') { - script += ',' + key + ':"' + config[key] + '"'; - } - } - script += '};' + - - 'window.com.stickyadstv.' + getAPIName(bid.params.format) + '.start(config);'; - - return script; -}; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: ['banner', 'video'], - aliases: ['stickyadstv'], // former name for freewheel-ssp - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!(bid.params.zoneId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(bidRequests, bidderRequest) { - // var currency = config.getConfig(currency); - - var currentBidRequest = bidRequests[0]; - if (bidRequests.length > 1) { - utils.logMessage('Prebid.JS - freewheel bid adapter: only one ad unit is required.'); - } - - var zone = currentBidRequest.params.zoneId; - var timeInMillis = new Date().getTime(); - var keyCode = hashcode(zone + '' + timeInMillis); - var requestParams = { - reqType: 'AdsSetup', - protocolVersion: '2.0', - zoneId: zone, - componentId: getComponentId(currentBidRequest.params.format), - timestamp: timeInMillis, - pKey: keyCode - }; - - // Add GDPR flag and consent string - if (bidderRequest && bidderRequest.gdprConsent) { - requestParams._fw_gdpr_consent = bidderRequest.gdprConsent.consentString; - - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { - requestParams._fw_gdpr = bidderRequest.gdprConsent.gdprApplies; - } - } - - if (currentBidRequest.params.gdpr_consented_providers) { - requestParams._fw_gdpr_consented_providers = currentBidRequest.params.gdpr_consented_providers; - } - - // Add CCPA consent string - if (bidderRequest && bidderRequest.uspConsent) { - requestParams._fw_us_privacy = bidderRequest.uspConsent; - } - - var vastParams = currentBidRequest.params.vastUrlParams; - if (typeof vastParams === 'object') { - for (var key in vastParams) { - if (vastParams.hasOwnProperty(key)) { - requestParams[key] = vastParams[key]; - } - } - } - - var location = (bidderRequest && bidderRequest.refererInfo) ? bidderRequest.refererInfo.referer : getTopMostWindow().location.href; - if (isValidUrl(location)) { - requestParams.loc = location; - } - - var playerSize = []; - if (currentBidRequest.mediaTypes.video && currentBidRequest.mediaTypes.video.playerSize) { - // If mediaTypes is video, get size from mediaTypes.video.playerSize per http://prebid.org/blog/pbjs-3 - playerSize = currentBidRequest.mediaTypes.video.playerSize; - } else if (currentBidRequest.mediaTypes.banner.sizes) { - // If mediaTypes is banner, get size from mediaTypes.banner.sizes per http://prebid.org/blog/pbjs-3 - playerSize = getBiggerSizeWithLimit(currentBidRequest.mediaTypes.banner.sizes, currentBidRequest.mediaTypes.banner.minSizeLimit, currentBidRequest.mediaTypes.banner.maxSizeLimit); - } else { - // Backward compatible code, in case size still pass by sizes in bid request - playerSize = getBiggerSize(currentBidRequest.sizes); - } - - if (playerSize[0] > 0 || playerSize[1] > 0) { - requestParams.playerSize = playerSize[0] + 'x' + playerSize[1]; - } - - return { - method: 'GET', - url: FREEWHEEL_ADSSETUP, - data: requestParams, - bidRequest: currentBidRequest - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param {object} request: the built request object containing the initial bidRequest. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, request) { - var bidrequest = request.bidRequest; - var playerSize = []; - if (bidrequest.mediaTypes.video && bidrequest.mediaTypes.video.playerSize) { - // If mediaTypes is video, get size from mediaTypes.video.playerSize per http://prebid.org/blog/pbjs-3 - playerSize = bidrequest.mediaTypes.video.playerSize; - } else if (bidrequest.mediaTypes.banner.sizes) { - // If mediaTypes is banner, get size from mediaTypes.banner.sizes per http://prebid.org/blog/pbjs-3 - playerSize = getBiggerSizeWithLimit(bidrequest.mediaTypes.banner.sizes, bidrequest.mediaTypes.banner.minSizeLimit, bidrequest.mediaTypes.banner.maxSizeLimit); - } else { - // Backward compatible code, in case size still pass by sizes in bid request - playerSize = getBiggerSize(bidrequest.sizes); - } - - if (typeof serverResponse == 'object' && typeof serverResponse.body == 'string') { - serverResponse = serverResponse.body; - } - - var xmlDoc; - try { - var parser = new DOMParser(); - xmlDoc = parser.parseFromString(serverResponse, 'application/xml'); - } catch (err) { - utils.logWarn('Prebid.js - ' + BIDDER_CODE + ' : ' + err); - return; - } - - const princingData = getPricing(xmlDoc); - const creativeId = getCreativeId(xmlDoc); - - const topWin = getTopMostWindow(); - if (!topWin.freewheelssp_cache) { - topWin.freewheelssp_cache = {}; - } - topWin.freewheelssp_cache[bidrequest.adUnitCode] = serverResponse; - - const bidResponses = []; - - if (princingData.price) { - const bidResponse = { - requestId: bidrequest.bidId, - cpm: princingData.price, - width: playerSize[0], - height: playerSize[1], - creativeId: creativeId, - currency: princingData.currency, - netRevenue: true, - ttl: 360 - }; - bidResponse.ad = formatAdHTML(bidrequest, playerSize); - bidResponses.push(bidResponse); - } - - return bidResponses; - }, - - getUserSyncs: function(syncOptions) { - if (syncOptions && syncOptions.pixelEnabled) { - return [{ - type: 'image', - url: USER_SYNC_URL - }]; - } else { - return []; - } - }, - -} -registerBidder(spec); +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; + +const BIDDER_CODE = 'freewheel-ssp'; + +const PROTOCOL = getProtocol(); +const FREEWHEEL_ADSSETUP = PROTOCOL + '://ads.stickyadstv.com/www/delivery/swfIndex.php'; +const MUSTANG_URL = PROTOCOL + '://cdn.stickyadstv.com/mustang/mustang.min.js'; +const PRIMETIME_URL = PROTOCOL + '://cdn.stickyadstv.com/prime-time/'; +const USER_SYNC_URL = PROTOCOL + '://ads.stickyadstv.com/auto-user-sync'; + +function getProtocol() { + return 'https'; +} + +function isValidUrl(str) { + if (!str) { + return false; + } + + // regExp for url validation + var pattern = /^(https?|ftp|file):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/; + return pattern.test(str); +} + +function getBiggerSize(array) { + var result = [0, 0]; + for (var i = 0; i < array.length; i++) { + if (array[i][0] * array[i][1] > result[0] * result[1]) { + result = array[i]; + } + } + return result; +} + +function getBiggerSizeWithLimit(array, minSizeLimit, maxSizeLimit) { + var minSize = minSizeLimit || [0, 0]; + var maxSize = maxSizeLimit || [Number.MAX_VALUE, Number.MAX_VALUE]; + var candidates = []; + + for (var i = 0; i < array.length; i++) { + if (array[i][0] * array[i][1] >= minSize[0] * minSize[1] && array[i][0] * array[i][1] <= maxSize[0] * maxSize[1]) { + candidates.push(array[i]); + } + } + + return getBiggerSize(candidates); +} + +/* +* read the pricing extension with this format: 1.0000 +* @return {object} pricing data in format: {currency: "EUR", price:"1.000"} +*/ +function getPricing(xmlNode) { + var pricingExtNode; + var princingData = {}; + + var extensions = xmlNode.querySelectorAll('Extension'); + // Nodelist.forEach is not supported in IE and Edge + // Workaround given here https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10638731/ + Array.prototype.forEach.call(extensions, function(node) { + if (node.getAttribute('type') === 'StickyPricing') { + pricingExtNode = node; + } + }); + + if (pricingExtNode) { + var priceNode = pricingExtNode.querySelector('Price'); + princingData = { + currency: priceNode.getAttribute('currency'), + price: priceNode.textContent || priceNode.innerText + }; + } else { + utils.logWarn('PREBID - ' + BIDDER_CODE + ': Can\'t get pricing data. Is price awareness enabled?'); + } + + return princingData; +} + +function hashcode(inputString) { + var hash = 0; + var char; + if (inputString.length == 0) return hash; + for (var i = 0; i < inputString.length; i++) { + char = inputString.charCodeAt(i); + hash = ((hash << 5) - hash) + char; + hash = hash & hash; // Convert to 32bit integer + } + return hash; +} + +function getCreativeId(xmlNode) { + var creaId = ''; + var adNodes = xmlNode.querySelectorAll('Ad'); + // Nodelist.forEach is not supported in IE and Edge + // Workaround given here https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10638731/ + Array.prototype.forEach.call(adNodes, function(el) { + creaId += '[' + el.getAttribute('id') + ']'; + }); + + return creaId; +} + +/** +* returns the top most accessible window +*/ +function getTopMostWindow() { + var res = window; + + try { + while (top !== res) { + if (res.parent.location.href.length) { res = res.parent; } + } + } catch (e) {} + + return res; +} + +function getComponentId(inputFormat) { + var component = 'mustang'; // default component id + + if (inputFormat && inputFormat !== 'inbanner') { + // format identifiers are equals to their component ids. + component = inputFormat; + } + + return component; +} + +function getAPIName(componentId) { + componentId = componentId || ''; + + // remove dash in componentId to get API name + return componentId.replace('-', ''); +} + +function formatAdHTML(bid, size) { + var integrationType = bid.params.format; + + var divHtml = '
'; + + var script = ''; + var libUrl = ''; + if (integrationType && integrationType !== 'inbanner') { + libUrl = PRIMETIME_URL + getComponentId(bid.params.format) + '.min.js'; + script = getOutstreamScript(bid, size); + } else { + libUrl = MUSTANG_URL; + script = getInBannerScript(bid, size); + } + + return divHtml + + ''; +} + +var getInBannerScript = function(bid, size) { + return 'var config = {' + + ' preloadedVast:vast,' + + ' autoPlay:true' + + ' };' + + ' var ad = new window.com.stickyadstv.vpaid.Ad(document.getElementById("freewheelssp_prebid_target"),config);' + + ' (new window.com.stickyadstv.tools.ASLoader(' + bid.params.zoneId + ', \'' + getComponentId(bid.params.format) + '\')).registerEvents(ad);' + + ' ad.initAd(' + size[0] + ',' + size[1] + ',"",0,"","");'; +}; + +var getOutstreamScript = function(bid) { + var config = bid.params; + + // default placement if no placement is set + if (!config.hasOwnProperty('domId') && !config.hasOwnProperty('auto') && !config.hasOwnProperty('p') && !config.hasOwnProperty('article')) { + if (config.format === 'intext-roll') { + config.iframeMode = 'dfp'; + } else { + config.domId = 'freewheelssp_prebid_target'; + } + } + + var script = 'var config = {' + + ' preloadedVast:vast,' + + ' ASLoader:new window.com.stickyadstv.tools.ASLoader(' + bid.params.zoneId + ', \'' + getComponentId(bid.params.format) + '\')'; + + for (var key in config) { + // dont' send format parameter + // neither zone nor vastUrlParams value as Vast is already loaded + if (config.hasOwnProperty(key) && key !== 'format' && key !== 'zone' && key !== 'zoneId' && key !== 'vastUrlParams') { + script += ',' + key + ':"' + config[key] + '"'; + } + } + script += '};' + + + 'window.com.stickyadstv.' + getAPIName(bid.params.format) + '.start(config);'; + + return script; +}; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: ['banner', 'video'], + aliases: ['stickyadstv'], // former name for freewheel-ssp + /** + * Determines whether or not the given bid request is valid. + * + * @param {object} bid The bid to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function(bid) { + return !!(bid.params.zoneId); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function(bidRequests, bidderRequest) { + // var currency = config.getConfig(currency); + + var currentBidRequest = bidRequests[0]; + if (bidRequests.length > 1) { + utils.logMessage('Prebid.JS - freewheel bid adapter: only one ad unit is required.'); + } + + var zone = currentBidRequest.params.zoneId; + var timeInMillis = new Date().getTime(); + var keyCode = hashcode(zone + '' + timeInMillis); + var requestParams = { + reqType: 'AdsSetup', + protocolVersion: '2.0', + zoneId: zone, + componentId: getComponentId(currentBidRequest.params.format), + timestamp: timeInMillis, + pKey: keyCode + }; + + // Add GDPR flag and consent string + if (bidderRequest && bidderRequest.gdprConsent) { + requestParams._fw_gdpr_consent = bidderRequest.gdprConsent.consentString; + + if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { + requestParams._fw_gdpr = bidderRequest.gdprConsent.gdprApplies; + } + } + + if (currentBidRequest.params.gdpr_consented_providers) { + requestParams._fw_gdpr_consented_providers = currentBidRequest.params.gdpr_consented_providers; + } + + // Add CCPA consent string + if (bidderRequest && bidderRequest.uspConsent) { + requestParams._fw_us_privacy = bidderRequest.uspConsent; + } + + var vastParams = currentBidRequest.params.vastUrlParams; + if (typeof vastParams === 'object') { + for (var key in vastParams) { + if (vastParams.hasOwnProperty(key)) { + requestParams[key] = vastParams[key]; + } + } + } + + var location = (bidderRequest && bidderRequest.refererInfo) ? bidderRequest.refererInfo.referer : getTopMostWindow().location.href; + if (isValidUrl(location)) { + requestParams.loc = location; + } + + var playerSize = []; + if (currentBidRequest.mediaTypes.video && currentBidRequest.mediaTypes.video.playerSize) { + // If mediaTypes is video, get size from mediaTypes.video.playerSize per http://prebid.org/blog/pbjs-3 + playerSize = currentBidRequest.mediaTypes.video.playerSize; + } else if (currentBidRequest.mediaTypes.banner.sizes) { + // If mediaTypes is banner, get size from mediaTypes.banner.sizes per http://prebid.org/blog/pbjs-3 + playerSize = getBiggerSizeWithLimit(currentBidRequest.mediaTypes.banner.sizes, currentBidRequest.mediaTypes.banner.minSizeLimit, currentBidRequest.mediaTypes.banner.maxSizeLimit); + } else { + // Backward compatible code, in case size still pass by sizes in bid request + playerSize = getBiggerSize(currentBidRequest.sizes); + } + + if (playerSize[0] > 0 || playerSize[1] > 0) { + requestParams.playerSize = playerSize[0] + 'x' + playerSize[1]; + } + + return { + method: 'GET', + url: FREEWHEEL_ADSSETUP, + data: requestParams, + bidRequest: currentBidRequest + }; + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @param {object} request: the built request object containing the initial bidRequest. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function(serverResponse, request) { + var bidrequest = request.bidRequest; + var playerSize = []; + if (bidrequest.mediaTypes.video && bidrequest.mediaTypes.video.playerSize) { + // If mediaTypes is video, get size from mediaTypes.video.playerSize per http://prebid.org/blog/pbjs-3 + playerSize = bidrequest.mediaTypes.video.playerSize; + } else if (bidrequest.mediaTypes.banner.sizes) { + // If mediaTypes is banner, get size from mediaTypes.banner.sizes per http://prebid.org/blog/pbjs-3 + playerSize = getBiggerSizeWithLimit(bidrequest.mediaTypes.banner.sizes, bidrequest.mediaTypes.banner.minSizeLimit, bidrequest.mediaTypes.banner.maxSizeLimit); + } else { + // Backward compatible code, in case size still pass by sizes in bid request + playerSize = getBiggerSize(bidrequest.sizes); + } + + if (typeof serverResponse == 'object' && typeof serverResponse.body == 'string') { + serverResponse = serverResponse.body; + } + + var xmlDoc; + try { + var parser = new DOMParser(); + xmlDoc = parser.parseFromString(serverResponse, 'application/xml'); + } catch (err) { + utils.logWarn('Prebid.js - ' + BIDDER_CODE + ' : ' + err); + return; + } + + const princingData = getPricing(xmlDoc); + const creativeId = getCreativeId(xmlDoc); + + const topWin = getTopMostWindow(); + if (!topWin.freewheelssp_cache) { + topWin.freewheelssp_cache = {}; + } + topWin.freewheelssp_cache[bidrequest.adUnitCode] = serverResponse; + + const bidResponses = []; + + if (princingData.price) { + const bidResponse = { + requestId: bidrequest.bidId, + cpm: princingData.price, + width: playerSize[0], + height: playerSize[1], + creativeId: creativeId, + currency: princingData.currency, + netRevenue: true, + ttl: 360 + }; + bidResponse.ad = formatAdHTML(bidrequest, playerSize); + bidResponses.push(bidResponse); + } + + return bidResponses; + }, + + getUserSyncs: function(syncOptions) { + if (syncOptions && syncOptions.pixelEnabled) { + return [{ + type: 'image', + url: USER_SYNC_URL + }]; + } else { + return []; + } + }, + +} +registerBidder(spec); diff --git a/modules/gammaBidAdapter.js b/modules/gammaBidAdapter.js index 71dee0936eb..5fd3c56b2c6 100644 --- a/modules/gammaBidAdapter.js +++ b/modules/gammaBidAdapter.js @@ -1,4 +1,4 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const ENDPOINT = 'https://hb.gammaplatform.com'; const ENDPOINT_USERSYNC = 'https://cm-supply-web.gammaplatform.com'; diff --git a/modules/gamoshiBidAdapter.js b/modules/gamoshiBidAdapter.js index f41c17d5bc7..e052e31cf40 100644 --- a/modules/gamoshiBidAdapter.js +++ b/modules/gamoshiBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {config} from '../src/config'; -import {Renderer} from '../src/Renderer'; -import {BANNER, VIDEO} from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {config} from '../src/config.js'; +import {Renderer} from '../src/Renderer.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; const ENDPOINTS = { 'gamoshi': 'https://rtb.gamoshi.io' diff --git a/modules/getintentBidAdapter.js b/modules/getintentBidAdapter.js index e1652602951..134dd0b4fc9 100644 --- a/modules/getintentBidAdapter.js +++ b/modules/getintentBidAdapter.js @@ -1,5 +1,5 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { isInteger } from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { isInteger } from '../src/utils.js'; const BIDDER_CODE = 'getintent'; const IS_NET_REVENUE = true; diff --git a/modules/googleAnalyticsAdapter.js b/modules/googleAnalyticsAdapter.js index 2e569cd7ba1..a8fc83ae62e 100644 --- a/modules/googleAnalyticsAdapter.js +++ b/modules/googleAnalyticsAdapter.js @@ -2,10 +2,10 @@ * ga.js - analytics adapter for google analytics */ -var events = require('../src/events'); -var utils = require('../src/utils'); +var events = require('../src/events.js'); +var utils = require('../src/utils.js'); var CONSTANTS = require('../src/constants.json'); -var adapterManager = require('../src/adapterManager').default; +var adapterManager = require('../src/adapterManager.js').default; var BID_REQUESTED = CONSTANTS.EVENTS.BID_REQUESTED; var BID_TIMEOUT = CONSTANTS.EVENTS.BID_TIMEOUT; diff --git a/modules/gridBidAdapter.js b/modules/gridBidAdapter.js index 33c4bea23a4..e19d8cc68a7 100644 --- a/modules/gridBidAdapter.js +++ b/modules/gridBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { Renderer } from '../src/Renderer'; -import { VIDEO, BANNER } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'grid'; const ENDPOINT_URL = 'https://grid.bidswitch.net/hb'; diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index 208772f6834..baa79ecfe04 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -1,9 +1,9 @@ -import * as utils from '../src/utils' +import * as utils from '../src/utils.js' -import { config } from '../src/config' -import { BANNER, VIDEO } from '../src/mediaTypes'; -import includes from 'core-js/library/fn/array/includes'; -import { registerBidder } from '../src/adapters/bidderFactory' +import { config } from '../src/config.js' +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js' const BIDDER_CODE = 'gumgum' const ALIAS_BIDDER_CODE = ['gg'] diff --git a/modules/hpmdnetworkBidAdapter.js b/modules/hpmdnetworkBidAdapter.js index 2642a0c9f65..5cc28ab6362 100644 --- a/modules/hpmdnetworkBidAdapter.js +++ b/modules/hpmdnetworkBidAdapter.js @@ -1,5 +1,5 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'hpmdnetwork'; const BIDDER_CODE_ALIAS = 'hpmd'; diff --git a/modules/iasBidAdapter.js b/modules/iasBidAdapter.js index 3115daeb56b..733c123e769 100644 --- a/modules/iasBidAdapter.js +++ b/modules/iasBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'ias'; diff --git a/modules/id5IdSystem.js b/modules/id5IdSystem.js index 6ed56b89d6d..32617d2f328 100644 --- a/modules/id5IdSystem.js +++ b/modules/id5IdSystem.js @@ -5,9 +5,9 @@ * @requires module:modules/userId */ -import * as utils from '../src/utils' -import {ajax} from '../src/ajax'; -import {submodule} from '../src/hook'; +import * as utils from '../src/utils.js' +import {ajax} from '../src/ajax.js'; +import {submodule} from '../src/hook.js'; /** @type {Submodule} */ export const id5IdSubmodule = { diff --git a/modules/identityLinkIdSystem.js b/modules/identityLinkIdSystem.js index ffbfe466035..a5b93a7f0ee 100644 --- a/modules/identityLinkIdSystem.js +++ b/modules/identityLinkIdSystem.js @@ -7,7 +7,7 @@ import * as utils from '../src/utils.js' import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook'; +import {submodule} from '../src/hook.js'; /** @type {Submodule} */ export const identityLinkSubmodule = { diff --git a/modules/imonomyBidAdapter.js b/modules/imonomyBidAdapter.js index 91086c2dd32..b9205943f65 100644 --- a/modules/imonomyBidAdapter.js +++ b/modules/imonomyBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'imonomy'; const ENDPOINT = 'https://b.imonomy.com/openrtb/hb/00000'; diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index 4e43b137c9f..6d9aa5d159c 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'improvedigital'; diff --git a/modules/innityBidAdapter.js b/modules/innityBidAdapter.js index ca281cd746b..aae79818daf 100644 --- a/modules/innityBidAdapter.js +++ b/modules/innityBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'innity'; const ENDPOINT = 'https://as.innity.com/synd/'; diff --git a/modules/inskinBidAdapter.js b/modules/inskinBidAdapter.js index 28b533ec917..a89a1b20219 100644 --- a/modules/inskinBidAdapter.js +++ b/modules/inskinBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'inskin'; diff --git a/modules/invibesBidAdapter.js b/modules/invibesBidAdapter.js index 985cbf3100e..a1942400396 100644 --- a/modules/invibesBidAdapter.js +++ b/modules/invibesBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const CONSTANTS = { BIDDER_CODE: 'invibes', diff --git a/modules/invisiblyAnalyticsAdapter.js b/modules/invisiblyAnalyticsAdapter.js index e3bcb39ec4c..bb193c16d80 100644 --- a/modules/invisiblyAnalyticsAdapter.js +++ b/modules/invisiblyAnalyticsAdapter.js @@ -1,15 +1,15 @@ /** * invisiblyAdapterAdapter.js - analytics adapter for Invisibly */ -import { ajaxBuilder } from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import { ajaxBuilder } from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; const DEFAULT_EVENT_URL = 'https://api.pymx5.com/v1/' + 'sites/events'; const analyticsType = 'endpoint'; const analyticsName = 'Invisibly Analytics Adapter:'; -const utils = require('../src/utils'); +const utils = require('../src/utils.js'); const CONSTANTS = require('../src/constants.json'); const ajax = ajaxBuilder(0); diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 938f403f756..18e9dc5bddb 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -1,9 +1,9 @@ -import * as utils from '../src/utils'; -import { BANNER, VIDEO } from '../src/mediaTypes'; -import { config } from '../src/config'; -import find from 'core-js/library/fn/array/find'; -import isInteger from 'core-js/library/fn/number/is-integer'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import find from 'core-js/library/fn/array/find.js'; +import isInteger from 'core-js/library/fn/number/is-integer.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'ix'; const SECURE_BID_URL = 'https://as-sec.casalemedia.com/cygnus'; diff --git a/modules/jcmBidAdapter.js b/modules/jcmBidAdapter.js index 6ba53020b68..c8d2f8bdd52 100644 --- a/modules/jcmBidAdapter.js +++ b/modules/jcmBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'jcm'; const URL = 'https://media.adfrontiers.com/pq' diff --git a/modules/justpremiumBidAdapter.js b/modules/justpremiumBidAdapter.js index 10a301a522c..7bd32531ccd 100644 --- a/modules/justpremiumBidAdapter.js +++ b/modules/justpremiumBidAdapter.js @@ -1,5 +1,5 @@ -import { registerBidder } from '../src/adapters/bidderFactory' -import { deepAccess } from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js' +import { deepAccess } from '../src/utils.js'; const BIDDER_CODE = 'justpremium' const ENDPOINT_URL = 'https://pre.ads.justpremium.com/v/2.0/t/xhr' diff --git a/modules/kargoAnalyticsAdapter.js b/modules/kargoAnalyticsAdapter.js index bd0d4f9a1e7..83c20846c0d 100644 --- a/modules/kargoAnalyticsAdapter.js +++ b/modules/kargoAnalyticsAdapter.js @@ -1,5 +1,5 @@ -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; var kargoAdapter = adapter({ analyticsType: 'endpoint', diff --git a/modules/kargoBidAdapter.js b/modules/kargoBidAdapter.js index b7795927493..c0e27518bd9 100644 --- a/modules/kargoBidAdapter.js +++ b/modules/kargoBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'kargo'; const HOST = 'https://krk.kargo.com'; const SYNC = 'https://crb.kargo.com/api/v1/initsyncrnd/{UUID}?seed={SEED}&idx={INDEX}'; diff --git a/modules/komoonaBidAdapter.js b/modules/komoonaBidAdapter.js index f7531d2b6ca..6adc0eb1984 100644 --- a/modules/komoonaBidAdapter.js +++ b/modules/komoonaBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'komoona'; const ENDPOINT = 'https://bidder.komoona.com/v1/GetSBids'; diff --git a/modules/konduitWrapper.js b/modules/konduitWrapper.js index c155720c606..c4cb4c8ff81 100644 --- a/modules/konduitWrapper.js +++ b/modules/konduitWrapper.js @@ -1,8 +1,8 @@ -import { registerVideoSupport } from '../src/adServerManager'; -import { targeting } from '../src/targeting'; -import { format as buildUrl } from '../src/url'; -import * as utils from '../src/utils'; -import { config } from '../src/config'; +import { registerVideoSupport } from '../src/adServerManager.js'; +import { targeting } from '../src/targeting.js'; +import { format as buildUrl } from '../src/url.js'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; const MODULE_NAME = 'Konduit'; diff --git a/modules/lemmaBidAdapter.js b/modules/lemmaBidAdapter.js index b27cfdcb134..1ad660e5916 100644 --- a/modules/lemmaBidAdapter.js +++ b/modules/lemmaBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; var BIDDER_CODE = 'lemma'; var LOG_WARN_PREFIX = 'LEMMA: '; diff --git a/modules/liveIntentIdSystem.js b/modules/liveIntentIdSystem.js index 5652357569d..ffbbc71ead4 100644 --- a/modules/liveIntentIdSystem.js +++ b/modules/liveIntentIdSystem.js @@ -4,9 +4,9 @@ * @module modules/liveIntentIdSystem * @requires module:modules/userId */ -import * as utils from '../src/utils' -import {ajax} from '../src/ajax'; -import {submodule} from '../src/hook'; +import * as utils from '../src/utils.js' +import {ajax} from '../src/ajax.js'; +import {submodule} from '../src/hook.js'; const MODULE_NAME = 'liveIntentId'; const LIVE_CONNECT_DUID_KEY = '_li_duid'; diff --git a/modules/livewrappedAnalyticsAdapter.js b/modules/livewrappedAnalyticsAdapter.js index 75d4e90fded..47f7f60d141 100644 --- a/modules/livewrappedAnalyticsAdapter.js +++ b/modules/livewrappedAnalyticsAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import {ajax} from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; +import * as utils from '../src/utils.js'; +import {ajax} from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; +import adapterManager from '../src/adapterManager.js'; const ANALYTICSTYPE = 'endpoint'; const URL = 'https://lwadm.com/analytics/10'; diff --git a/modules/livewrappedBidAdapter.js b/modules/livewrappedBidAdapter.js index 4dfd25c1fcd..0e478869b53 100644 --- a/modules/livewrappedBidAdapter.js +++ b/modules/livewrappedBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; -import find from 'core-js/library/fn/array/find'; -import { BANNER, NATIVE } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import find from 'core-js/library/fn/array/find.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; const BIDDER_CODE = 'livewrapped'; export const URL = 'https://lwadm.com/ad'; diff --git a/modules/liveyieldAnalyticsAdapter.js b/modules/liveyieldAnalyticsAdapter.js index 75e06dd56a2..d80a7067f2e 100644 --- a/modules/liveyieldAnalyticsAdapter.js +++ b/modules/liveyieldAnalyticsAdapter.js @@ -1,7 +1,7 @@ -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; import CONSTANTS from '../src/constants.json'; -import * as utils from '../src/utils'; +import * as utils from '../src/utils.js'; const { EVENTS: { BID_REQUESTED, BID_TIMEOUT, BID_RESPONSE, BID_WON } diff --git a/modules/lkqdBidAdapter.js b/modules/lkqdBidAdapter.js index 8c10b5b0269..51d5c48e1fc 100644 --- a/modules/lkqdBidAdapter.js +++ b/modules/lkqdBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'lkqd'; const BID_TTL_DEFAULT = 300; diff --git a/modules/lockerdomeBidAdapter.js b/modules/lockerdomeBidAdapter.js index ce9deedd160..80c40b39f9a 100644 --- a/modules/lockerdomeBidAdapter.js +++ b/modules/lockerdomeBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {BANNER} from '../src/mediaTypes'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {BANNER} from '../src/mediaTypes.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; export const spec = { code: 'lockerdome', diff --git a/modules/logicadBidAdapter.js b/modules/logicadBidAdapter.js index 65d765c30a3..74c00ee39d6 100644 --- a/modules/logicadBidAdapter.js +++ b/modules/logicadBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER} from '../src/mediaTypes'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER} from '../src/mediaTypes.js'; const BIDDER_CODE = 'logicad'; const ENDPOINT_URL = 'https://pb.ladsp.com/adrequest/prebid'; diff --git a/modules/loopmeBidAdapter.js b/modules/loopmeBidAdapter.js index dd0c7e38553..c0112bc174a 100644 --- a/modules/loopmeBidAdapter.js +++ b/modules/loopmeBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; -import { Renderer } from '../src/Renderer'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; const LOOPME_ENDPOINT = 'https://loopme.me/api/hb'; diff --git a/modules/madvertiseBidAdapter.js b/modules/madvertiseBidAdapter.js index 4764607726e..d0cafbfd6b8 100644 --- a/modules/madvertiseBidAdapter.js +++ b/modules/madvertiseBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; // use protocol relative urls for http or https const MADVERTISE_ENDPOINT = 'https://mobile.mng-ads.com/'; diff --git a/modules/mantisBidAdapter.js b/modules/mantisBidAdapter.js index c478d059e41..ecd18497283 100644 --- a/modules/mantisBidAdapter.js +++ b/modules/mantisBidAdapter.js @@ -1,4 +1,4 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; function inIframe() { try { diff --git a/modules/marsmediaAnalyticsAdapter.js b/modules/marsmediaAnalyticsAdapter.js index aef8a5c8c43..12c333631a2 100644 --- a/modules/marsmediaAnalyticsAdapter.js +++ b/modules/marsmediaAnalyticsAdapter.js @@ -1,6 +1,6 @@ -import {ajax} from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import {ajax} from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; /**** * Mars Media Analytics diff --git a/modules/marsmediaBidAdapter.js b/modules/marsmediaBidAdapter.js index 87b6eb5e660..146e1495782 100644 --- a/modules/marsmediaBidAdapter.js +++ b/modules/marsmediaBidAdapter.js @@ -1,8 +1,8 @@ 'use strict'; -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; function MarsmediaAdapter() { this.code = 'marsmedia'; diff --git a/modules/meazyBidAdapter.js b/modules/meazyBidAdapter.js index 0903052c043..9640210cc12 100644 --- a/modules/meazyBidAdapter.js +++ b/modules/meazyBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'meazy'; const PREBID_ENDPOINT = 'rtb-filter.meazy.co'; diff --git a/modules/medianetBidAdapter.js b/modules/medianetBidAdapter.js index 69f61b40936..5a7133001bf 100644 --- a/modules/medianetBidAdapter.js +++ b/modules/medianetBidAdapter.js @@ -1,9 +1,9 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import * as utils from '../src/utils'; -import { config } from '../src/config'; -import * as url from '../src/url'; -import { BANNER, NATIVE } from '../src/mediaTypes'; -import { getRefererInfo } from '../src/refererDetection'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; +import * as url from '../src/url.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { getRefererInfo } from '../src/refererDetection.js'; const BIDDER_CODE = 'medianet'; const BID_URL = 'https://prebid.media.net/rtb/prebid'; diff --git a/modules/mgidBidAdapter.js b/modules/mgidBidAdapter.js index 2a981a5720f..4d4c36fcbda 100644 --- a/modules/mgidBidAdapter.js +++ b/modules/mgidBidAdapter.js @@ -1,8 +1,8 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -import * as utils from '../src/utils'; -import * as urlUtils from '../src/url'; -import {BANNER, NATIVE} from '../src/mediaTypes'; -import {config} from '../src/config'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; +import * as urlUtils from '../src/url.js'; +import {BANNER, NATIVE} from '../src/mediaTypes.js'; +import {config} from '../src/config.js'; const DEFAULT_CUR = 'USD'; const BIDDER_CODE = 'mgid'; const ENDPOINT_URL = 'https://prebid.mgid.com/prebid/'; diff --git a/modules/microadBidAdapter.js b/modules/microadBidAdapter.js index 0d4da3e72f7..9611946b495 100644 --- a/modules/microadBidAdapter.js +++ b/modules/microadBidAdapter.js @@ -1,5 +1,5 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'microad'; diff --git a/modules/mobfoxBidAdapter.js b/modules/mobfoxBidAdapter.js index 961cb97e8da..7c356e71089 100644 --- a/modules/mobfoxBidAdapter.js +++ b/modules/mobfoxBidAdapter.js @@ -1,4 +1,4 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const utils = require('../src/utils.js'); const BIDDER_CODE = 'mobfox'; diff --git a/modules/mobsmartBidAdapter.js b/modules/mobsmartBidAdapter.js index ba02aef38ef..e5ff38ec69a 100644 --- a/modules/mobsmartBidAdapter.js +++ b/modules/mobsmartBidAdapter.js @@ -1,5 +1,5 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'mobsmart'; const ENDPOINT = 'https://prebid.mobsmart.net/prebid/endpoint'; diff --git a/modules/my6senseBidAdapter.js b/modules/my6senseBidAdapter.js index 29a593fc467..018baa37461 100644 --- a/modules/my6senseBidAdapter.js +++ b/modules/my6senseBidAdapter.js @@ -1,6 +1,6 @@ -import { BANNER, NATIVE } from '../src/mediaTypes'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; -const {registerBidder} = require('../src/adapters/bidderFactory'); +const {registerBidder} = require('../src/adapters/bidderFactory.js'); const BIDDER_CODE = 'my6sense'; const END_POINT = 'https://hb.mynativeplatform.com/pub2/web/v1.15.0/hbwidget.json'; const END_POINT_METHOD = 'POST'; diff --git a/modules/mytargetBidAdapter.js b/modules/mytargetBidAdapter.js index 005ef9e6a20..24ad488d382 100644 --- a/modules/mytargetBidAdapter.js +++ b/modules/mytargetBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import * as url from '../src/url'; -import { config } from '../src/config'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import * as url from '../src/url.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'mytarget'; const BIDDER_URL = 'https://ad.mail.ru/hbid_prebid/'; diff --git a/modules/nafdigitalBidAdapter.js b/modules/nafdigitalBidAdapter.js index 7bbfd8b38dd..2be845d6fdd 100644 --- a/modules/nafdigitalBidAdapter.js +++ b/modules/nafdigitalBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import * as url from '../src/url'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; -import { config } from '../src/config'; +import * as utils from '../src/utils.js'; +import * as url from '../src/url.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'nafdigital'; const URL = 'https://nafdigitalbidder.com/hb'; diff --git a/modules/nanointeractiveBidAdapter.js b/modules/nanointeractiveBidAdapter.js index 13944cd5a35..caf23627cff 100644 --- a/modules/nanointeractiveBidAdapter.js +++ b/modules/nanointeractiveBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; export const BIDDER_CODE = 'nanointeractive'; export const END_POINT_URL = 'https://ad.audiencemanager.de'; diff --git a/modules/nasmediaAdmixerBidAdapter.js b/modules/nasmediaAdmixerBidAdapter.js index 2edb5e5794e..fd7a7baa58a 100644 --- a/modules/nasmediaAdmixerBidAdapter.js +++ b/modules/nasmediaAdmixerBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER} from '../src/mediaTypes'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER} from '../src/mediaTypes.js'; const ADMIXER_ENDPOINT = 'https://adn.admixer.co.kr:10443/prebid/ad_req'; const BIDDER_CODE = 'nasmediaAdmixer'; diff --git a/modules/newborntownWebBidAdapter.js b/modules/newborntownWebBidAdapter.js index 103fac7ba6a..818c179374c 100644 --- a/modules/newborntownWebBidAdapter.js +++ b/modules/newborntownWebBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER, NATIVE} from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER, NATIVE} from '../src/mediaTypes.js'; const BIDDER_CODE = 'newborntownWeb'; const REQUEST_URL = 'https://us-west.solortb.com/adx/api/rtb?from=4' diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 8093f6e8f7c..af1f0562ba4 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'nextMillennium'; const HOST = 'https://brainlyads.com'; diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index 63c54b998c4..cce79efead0 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'nobid'; window.nobidVersion = '1.2.1'; window.nobid = window.nobid || {}; diff --git a/modules/oneVideoBidAdapter.js b/modules/oneVideoBidAdapter.js index 792784cb7ac..9d3fabcd3b6 100644 --- a/modules/oneVideoBidAdapter.js +++ b/modules/oneVideoBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'oneVideo'; export const spec = { code: 'oneVideo', diff --git a/modules/onetagBidAdapter.js b/modules/onetagBidAdapter.js index 9c4f7ea09b6..d6ed19c4af5 100644 --- a/modules/onetagBidAdapter.js +++ b/modules/onetagBidAdapter.js @@ -1,6 +1,6 @@ 'use strict'; -const { registerBidder } = require('../src/adapters/bidderFactory'); +const { registerBidder } = require('../src/adapters/bidderFactory.js'); const ENDPOINT = 'https://onetag-sys.com/prebid-request'; const USER_SYNC_ENDPOINT = 'https://onetag-sys.com/usync/'; diff --git a/modules/open8BidAdapter.js b/modules/open8BidAdapter.js index eb2d71c6bd6..744cce2b5f9 100644 --- a/modules/open8BidAdapter.js +++ b/modules/open8BidAdapter.js @@ -1,8 +1,8 @@ -import { Renderer } from '../src/Renderer'; -import {ajax} from '../src/ajax'; -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { VIDEO, BANNER } from '../src/mediaTypes'; +import { Renderer } from '../src/Renderer.js'; +import {ajax} from '../src/ajax.js'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'open8'; const URL = 'https://as.vt.open8.com/v1/control/prebid'; diff --git a/modules/openxAnalyticsAdapter.js b/modules/openxAnalyticsAdapter.js index 68d2670800d..7addfe68bc6 100644 --- a/modules/openxAnalyticsAdapter.js +++ b/modules/openxAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import adapter from '../src/AnalyticsAdapter'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; -import { config } from '../src/config'; -import { ajax } from '../src/ajax'; -import * as utils from '../src/utils'; +import adapterManager from '../src/adapterManager.js'; +import { config } from '../src/config.js'; +import { ajax } from '../src/ajax.js'; +import * as utils from '../src/utils.js'; const { EVENTS: { AUCTION_INIT, BID_REQUESTED, BID_RESPONSE, BID_TIMEOUT, BID_WON } diff --git a/modules/openxBidAdapter.js b/modules/openxBidAdapter.js index 83aba250146..a895e64b897 100644 --- a/modules/openxBidAdapter.js +++ b/modules/openxBidAdapter.js @@ -1,8 +1,8 @@ -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import * as utils from '../src/utils'; -import {BANNER, VIDEO} from '../src/mediaTypes'; -import {parse} from '../src/url'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import {parse} from '../src/url.js'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BIDDER_CODE = 'openx'; diff --git a/modules/optimeraBidAdapter.js b/modules/optimeraBidAdapter.js index bc4407ababa..b470e901ec6 100644 --- a/modules/optimeraBidAdapter.js +++ b/modules/optimeraBidAdapter.js @@ -1,5 +1,5 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { deepAccess } from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { deepAccess } from '../src/utils.js'; const BIDDER_CODE = 'optimera'; const SCORES_BASE_URL = 'https://dyv1bugovvq1g.cloudfront.net/'; diff --git a/modules/orbidderBidAdapter.js b/modules/orbidderBidAdapter.js index a3ed3e3f74d..d3607c2b882 100644 --- a/modules/orbidderBidAdapter.js +++ b/modules/orbidderBidAdapter.js @@ -1,6 +1,6 @@ -import {detectReferer} from '../src/refererDetection'; -import {ajax} from '../src/ajax'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import {detectReferer} from '../src/refererDetection.js'; +import {ajax} from '../src/ajax.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; export const spec = { code: 'orbidder', diff --git a/modules/otmBidAdapter.js b/modules/otmBidAdapter.js index ddb4d356f5c..23f6d434ae1 100644 --- a/modules/otmBidAdapter.js +++ b/modules/otmBidAdapter.js @@ -1,5 +1,5 @@ -import {BANNER} from '../src/mediaTypes'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import {BANNER} from '../src/mediaTypes.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; export const spec = { code: 'otm', diff --git a/modules/outconBidAdapter.js b/modules/outconBidAdapter.js index b636c18cf88..0c3ac90172a 100644 --- a/modules/outconBidAdapter.js +++ b/modules/outconBidAdapter.js @@ -1,4 +1,4 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'outcon'; diff --git a/modules/ozoneBidAdapter.js b/modules/ozoneBidAdapter.js index 749843a9a79..f30b33fe2dd 100644 --- a/modules/ozoneBidAdapter.js +++ b/modules/ozoneBidAdapter.js @@ -1,9 +1,9 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; -import {config} from '../src/config'; -import {getPriceBucketString} from '../src/cpmBucketManager'; -import { Renderer } from '../src/Renderer'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import {config} from '../src/config.js'; +import {getPriceBucketString} from '../src/cpmBucketManager.js'; +import { Renderer } from '../src/Renderer.js'; const BIDDER_CODE = 'ozone'; diff --git a/modules/padsquadBidAdapter.js b/modules/padsquadBidAdapter.js index 52e1147fe78..088cac265b9 100644 --- a/modules/padsquadBidAdapter.js +++ b/modules/padsquadBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -import * as utils from '../src/utils'; -import {BANNER} from '../src/mediaTypes'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; +import {BANNER} from '../src/mediaTypes.js'; const ENDPOINT_URL = 'https://x.padsquad.com/auction'; diff --git a/modules/papyrusBidAdapter.js b/modules/papyrusBidAdapter.js index 490dcb46909..a27c5cf618a 100644 --- a/modules/papyrusBidAdapter.js +++ b/modules/papyrusBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const PAPYRUS_ENDPOINT = 'https://prebid.papyrus.global'; const PAPYRUS_CODE = 'papyrus'; diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js index e8ad7f9acc1..bc900d11e0b 100644 --- a/modules/parrableIdSystem.js +++ b/modules/parrableIdSystem.js @@ -5,9 +5,9 @@ * @requires module:modules/userId */ -import * as utils from '../src/utils' -import {ajax} from '../src/ajax'; -import {submodule} from '../src/hook'; +import * as utils from '../src/utils.js' +import {ajax} from '../src/ajax.js'; +import {submodule} from '../src/hook.js'; const PARRABLE_URL = 'https://h.parrable.com/prebid'; diff --git a/modules/piximediaBidAdapter.js b/modules/piximediaBidAdapter.js index 635b946d724..2617cc8fe42 100644 --- a/modules/piximediaBidAdapter.js +++ b/modules/piximediaBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'piximedia'; const ENDPOINT = 'https://ad.piximedia.com/prebid'; diff --git a/modules/playgroundxyzBidAdapter.js b/modules/playgroundxyzBidAdapter.js index 0132b6a13d6..8373699acf1 100644 --- a/modules/playgroundxyzBidAdapter.js +++ b/modules/playgroundxyzBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'playgroundxyz'; const URL = 'https://ads.playground.xyz/host-config/prebid?v=2'; diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js index 8f7727a61aa..2ad31bda2ee 100644 --- a/modules/prebidServerBidAdapter/index.js +++ b/modules/prebidServerBidAdapter/index.js @@ -1,17 +1,17 @@ -import Adapter from '../../src/adapter'; -import { createBid } from '../../src/bidfactory'; -import * as utils from '../../src/utils'; -import { STATUS, S2S, EVENTS } from '../../src/constants'; -import adapterManager from '../../src/adapterManager'; -import { config } from '../../src/config'; -import { VIDEO, NATIVE } from '../../src/mediaTypes'; -import { processNativeAdUnitParams } from '../../src/native'; -import { isValid } from '../../src/adapters/bidderFactory'; -import events from '../../src/events'; -import includes from 'core-js/library/fn/array/includes'; +import Adapter from '../../src/adapter.js'; +import { createBid } from '../../src/bidfactory.js'; +import * as utils from '../../src/utils.js'; +import { STATUS, S2S, EVENTS } from '../../src/constants.json'; +import adapterManager from '../../src/adapterManager.js'; +import { config } from '../../src/config.js'; +import { VIDEO, NATIVE } from '../../src/mediaTypes.js'; +import { processNativeAdUnitParams } from '../../src/native.js'; +import { isValid } from '../../src/adapters/bidderFactory.js'; +import events from '../../src/events.js'; +import includes from 'core-js/library/fn/array/includes.js'; import { S2S_VENDORS } from './config.js'; -import { ajax } from '../../src/ajax'; -import find from 'core-js/library/fn/array/find'; +import { ajax } from '../../src/ajax.js'; +import find from 'core-js/library/fn/array/find.js'; const getConfig = config.getConfig; @@ -744,7 +744,7 @@ const OPEN_RTB_PROTOCOL = { bidObject.playerHeight = sizes[0]; bidObject.playerWidth = sizes[1]; - // try to get cache values from 'response.ext.prebid.cache' + // try to get cache values from 'response.ext.prebid.cache.js' // else try 'bid.ext.prebid.targeting' as fallback if (bid.ext.prebid.cache && typeof bid.ext.prebid.cache.vastXml === 'object' && bid.ext.prebid.cache.vastXml.cacheId && bid.ext.prebid.cache.vastXml.url) { bidObject.videoCacheKey = bid.ext.prebid.cache.vastXml.cacheId; diff --git a/modules/prebidmanagerAnalyticsAdapter.js b/modules/prebidmanagerAnalyticsAdapter.js index f3474abe95a..b8112628cb6 100644 --- a/modules/prebidmanagerAnalyticsAdapter.js +++ b/modules/prebidmanagerAnalyticsAdapter.js @@ -1,6 +1,6 @@ -import {ajaxBuilder} from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import {ajaxBuilder} from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; /** * prebidmanagerAnalyticsAdapter.js - analytics adapter for prebidmanager @@ -9,7 +9,7 @@ const DEFAULT_EVENT_URL = 'https://endpoint.prebidmanager.com/endpoint' const analyticsType = 'endpoint'; const analyticsName = 'Prebid Manager Analytics: '; -var utils = require('../src/utils'); +var utils = require('../src/utils.js'); var CONSTANTS = require('../src/constants.json'); let ajax = ajaxBuilder(0); diff --git a/modules/projectLimeLightBidAdapter.js b/modules/projectLimeLightBidAdapter.js index 2b80538a064..f2ff77f6229 100644 --- a/modules/projectLimeLightBidAdapter.js +++ b/modules/projectLimeLightBidAdapter.js @@ -1,7 +1,7 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; -import {ajax} from '../src/ajax'; -import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import {ajax} from '../src/ajax.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'project-limelight'; const URL = 'https://ads.project-limelight.com/hb'; diff --git a/modules/proxistoreBidAdapter.js b/modules/proxistoreBidAdapter.js index f9c3a0f3cc0..a399a906402 100644 --- a/modules/proxistoreBidAdapter.js +++ b/modules/proxistoreBidAdapter.js @@ -1,4 +1,4 @@ -const { registerBidder } = require('../src/adapters/bidderFactory'); +const { registerBidder } = require('../src/adapters/bidderFactory.js'); const BIDDER_CODE = 'proxistore'; const PROXISTORE_VENDOR_ID = 418; diff --git a/modules/pubCommonId.js b/modules/pubCommonId.js index 038ad3bef2f..ec8776e5739 100644 --- a/modules/pubCommonId.js +++ b/modules/pubCommonId.js @@ -3,10 +3,10 @@ * stored in the page's domain. When the module is included, an id is generated if needed, * persisted as a cookie, and automatically appended to all the bidRequest as bid.crumbs.pubcid. */ -import * as utils from '../src/utils' -import { config } from '../src/config'; -import events from '../src/events'; -import * as url from '../src/url'; +import * as utils from '../src/utils.js' +import { config } from '../src/config.js'; +import events from '../src/events.js'; +import * as url from '../src/url.js'; import CONSTANTS from '../src/constants.json'; const ID_NAME = '_pubcid'; diff --git a/modules/pubCommonIdSystem.js b/modules/pubCommonIdSystem.js index 42a52c2b010..239c6ea3ea7 100644 --- a/modules/pubCommonIdSystem.js +++ b/modules/pubCommonIdSystem.js @@ -5,9 +5,9 @@ * @requires module:modules/userId */ -import * as utils from '../src/utils'; -import * as url from '../src/url'; -import {submodule} from '../src/hook'; +import * as utils from '../src/utils.js'; +import * as url from '../src/url.js'; +import {submodule} from '../src/hook.js'; const PUB_COMMON_ID = 'PublisherCommonId'; diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 6da7ed78c67..e2bf57bc5a6 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes'; -import {config} from '../src/config'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js'; +import {config} from '../src/config.js'; const BIDDER_CODE = 'pubmatic'; const LOG_WARN_PREFIX = 'PubMatic: '; diff --git a/modules/pubwiseAnalyticsAdapter.js b/modules/pubwiseAnalyticsAdapter.js index d3e596d91eb..8a93ace8ba5 100644 --- a/modules/pubwiseAnalyticsAdapter.js +++ b/modules/pubwiseAnalyticsAdapter.js @@ -1,8 +1,8 @@ -import {ajax} from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import {ajax} from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; import CONSTANTS from '../src/constants.json'; -const utils = require('../src/utils'); +const utils = require('../src/utils.js'); /**** * PubWise.io Analytics diff --git a/modules/pulsepointAnalyticsAdapter.js b/modules/pulsepointAnalyticsAdapter.js index fe5b48b6d00..375a817f257 100644 --- a/modules/pulsepointAnalyticsAdapter.js +++ b/modules/pulsepointAnalyticsAdapter.js @@ -2,8 +2,8 @@ * pulsepoint.js - Analytics Adapter for PulsePoint */ -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; var pulsepointAdapter = adapter({ global: 'PulsePointPrebidAnalytics', diff --git a/modules/pulsepointBidAdapter.js b/modules/pulsepointBidAdapter.js index b898618673e..cbe37e66cd7 100644 --- a/modules/pulsepointBidAdapter.js +++ b/modules/pulsepointBidAdapter.js @@ -1,7 +1,7 @@ /* eslint dot-notation:0, quote-props:0 */ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { Renderer } from '../src/Renderer'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; const NATIVE_DEFAULTS = { TITLE_LEN: 100, diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js index 93f8e398a9d..854d68d5b07 100644 --- a/modules/quantcastBidAdapter.js +++ b/modules/quantcastBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { ajax } from '../src/ajax'; -import { config } from '../src/config'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'quantcast'; const DEFAULT_BID_FLOOR = 0.0000000001; diff --git a/modules/quantumBidAdapter.js b/modules/quantumBidAdapter.js index 729150b8b08..f5da6e022f1 100644 --- a/modules/quantumBidAdapter.js +++ b/modules/quantumBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { BANNER, NATIVE } from '../src/mediaTypes'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'quantum'; const ENDPOINT_URL = 'https://s.sspqns.com/hb'; diff --git a/modules/radsBidAdapter.js b/modules/radsBidAdapter.js index 026dc3c4af6..1f07cc07b91 100644 --- a/modules/radsBidAdapter.js +++ b/modules/radsBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'rads'; const ENDPOINT_URL = 'https://rads.recognified.net/md.request.php'; diff --git a/modules/readpeakBidAdapter.js b/modules/readpeakBidAdapter.js index e9fd3c42312..56006aea144 100644 --- a/modules/readpeakBidAdapter.js +++ b/modules/readpeakBidAdapter.js @@ -1,8 +1,8 @@ -import { logError, replaceAuctionPrice } from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; -import { NATIVE } from '../src/mediaTypes'; -import { parse as parseUrl } from '../src/url'; +import { logError, replaceAuctionPrice } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { NATIVE } from '../src/mediaTypes.js'; +import { parse as parseUrl } from '../src/url.js'; export const ENDPOINT = 'https://app.readpeak.com/header/prebid'; diff --git a/modules/realvuAnalyticsAdapter.js b/modules/realvuAnalyticsAdapter.js index 45d7babc19b..bacc7f17ca3 100644 --- a/modules/realvuAnalyticsAdapter.js +++ b/modules/realvuAnalyticsAdapter.js @@ -1,6 +1,6 @@ // RealVu Analytics Adapter -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; import CONSTANTS from '../src/constants.json'; const utils = require('../src/utils.js'); diff --git a/modules/reklamstoreBidAdapter.js b/modules/reklamstoreBidAdapter.js index 02a94836836..3d78cf95978 100644 --- a/modules/reklamstoreBidAdapter.js +++ b/modules/reklamstoreBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'reklamstore'; const ENDPOINT_URL = 'https://ads.rekmob.com/m/prebid'; diff --git a/modules/reloadBidAdapter.js b/modules/reloadBidAdapter.js index d99de5d6c53..56d925bc2fe 100644 --- a/modules/reloadBidAdapter.js +++ b/modules/reloadBidAdapter.js @@ -1,8 +1,8 @@ import { registerBidder } - from '../src/adapters/bidderFactory'; -import * as utils from '../src/utils'; + from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'reload'; const VERSION_ADAPTER = '1.10'; export const spec = { diff --git a/modules/resultsmediaBidAdapter.js b/modules/resultsmediaBidAdapter.js index 5d9934c51e4..beb9991e1e2 100644 --- a/modules/resultsmediaBidAdapter.js +++ b/modules/resultsmediaBidAdapter.js @@ -1,8 +1,8 @@ 'use strict'; -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; function ResultsmediaAdapter() { this.code = 'resultsmedia'; diff --git a/modules/revcontentBidAdapter.js b/modules/revcontentBidAdapter.js index ee8ed5f08a9..270302fd617 100644 --- a/modules/revcontentBidAdapter.js +++ b/modules/revcontentBidAdapter.js @@ -1,9 +1,9 @@ // jshint esversion: 6, es3: false, node: true 'use strict'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import * as utils from '../src/utils'; -import {ajax} from '../src/ajax'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; +import {ajax} from '../src/ajax.js'; const BIDDER_CODE = 'revcontent'; const NATIVE_PARAMS = { diff --git a/modules/rhythmoneBidAdapter.js b/modules/rhythmoneBidAdapter.js index f7102e4be5a..1acbcfd0463 100644 --- a/modules/rhythmoneBidAdapter.js +++ b/modules/rhythmoneBidAdapter.js @@ -1,8 +1,8 @@ 'use strict'; -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; function RhythmOneBidAdapter() { this.code = 'rhythmone'; diff --git a/modules/richaudienceBidAdapter.js b/modules/richaudienceBidAdapter.js index 371708ef687..4cafaa79468 100755 --- a/modules/richaudienceBidAdapter.js +++ b/modules/richaudienceBidAdapter.js @@ -1,7 +1,7 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -import {config} from '../src/config'; -import {BANNER, VIDEO} from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {config} from '../src/config.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'richaudience'; let REFERER = ''; diff --git a/modules/rivrAnalyticsAdapter.js b/modules/rivrAnalyticsAdapter.js index e1cfa5c70bc..279b1b13051 100644 --- a/modules/rivrAnalyticsAdapter.js +++ b/modules/rivrAnalyticsAdapter.js @@ -1,7 +1,7 @@ -import {ajax} from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; -import * as utils from '../src/utils'; +import {ajax} from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; +import * as utils from '../src/utils.js'; const analyticsType = 'endpoint'; diff --git a/modules/roxotAnalyticsAdapter.js b/modules/roxotAnalyticsAdapter.js index 45bcbc55947..814a2c0d1ad 100644 --- a/modules/roxotAnalyticsAdapter.js +++ b/modules/roxotAnalyticsAdapter.js @@ -1,10 +1,10 @@ -import adapter from '../src/AnalyticsAdapter'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; -import includes from 'core-js/library/fn/array/includes'; -import {ajaxBuilder} from '../src/ajax'; +import adapterManager from '../src/adapterManager.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import {ajaxBuilder} from '../src/ajax.js'; -const utils = require('../src/utils'); +const utils = require('../src/utils.js'); let ajax = ajaxBuilder(0); const DEFAULT_EVENT_URL = 'pa.rxthdr.com/v3'; diff --git a/modules/rtbdemandBidAdapter.js b/modules/rtbdemandBidAdapter.js index ac8e639ff03..be5fb39f53a 100644 --- a/modules/rtbdemandBidAdapter.js +++ b/modules/rtbdemandBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'rtbdemand'; const BIDDER_SERVER = 'bidding.rtbdemand.com'; diff --git a/modules/rtbhouseBidAdapter.js b/modules/rtbhouseBidAdapter.js index 36c08fc8626..b0d7c0e04de 100644 --- a/modules/rtbhouseBidAdapter.js +++ b/modules/rtbhouseBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { BANNER, NATIVE } from '../src/mediaTypes'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import includes from 'core-js/library/fn/array/includes'; +import * as utils from '../src/utils.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import includes from 'core-js/library/fn/array/includes.js'; const BIDDER_CODE = 'rtbhouse'; const REGIONS = ['prebid-eu', 'prebid-us', 'prebid-asia']; diff --git a/modules/rtbsolutionsBidAdapter.js b/modules/rtbsolutionsBidAdapter.js index ad75b9de25a..244ab8a4eba 100644 --- a/modules/rtbsolutionsBidAdapter.js +++ b/modules/rtbsolutionsBidAdapter.js @@ -1,6 +1,6 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import * as utils from '../src/utils'; -import { ajax } from '../src/ajax'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; const BIDDER_CODE = 'rtbsolutions'; const ENDPOINT_URL = 'https://dsp-eu-lb.rtbsolutions.pro/bid/hb'; diff --git a/modules/rtdModule/index.js b/modules/rtdModule/index.js index 3136d20ab13..cff09fbd4fb 100644 --- a/modules/rtdModule/index.js +++ b/modules/rtdModule/index.js @@ -54,11 +54,11 @@ * @type {number} */ -import {getGlobal} from '../../src/prebidGlobal'; +import {getGlobal} from '../../src/prebidGlobal.js'; import {config} from '../../src/config.js'; -import {targeting} from '../../src/targeting'; -import {getHook, module} from '../../src/hook'; -import * as utils from '../../src/utils'; +import {targeting} from '../../src/targeting.js'; +import {getHook, module} from '../../src/hook.js'; +import * as utils from '../../src/utils.js'; /** @type {string} */ const MODULE_NAME = 'realTimeData'; diff --git a/modules/rubiconAnalyticsAdapter.js b/modules/rubiconAnalyticsAdapter.js index 9c57e956b78..817779dbb64 100644 --- a/modules/rubiconAnalyticsAdapter.js +++ b/modules/rubiconAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; import CONSTANTS from '../src/constants.json'; -import { ajax } from '../src/ajax'; -import { config } from '../src/config'; -import * as utils from '../src/utils'; +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import * as utils from '../src/utils.js'; const { EVENTS: { diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index 34fdb76fcef..cc516567f6b 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {config} from '../src/config'; -import {BANNER, VIDEO} from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {config} from '../src/config.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; const DEFAULT_INTEGRATION = 'pbjs_lite'; @@ -638,7 +638,7 @@ export const spec = { bidObject.adserverTargeting = extPrebidTargeting; } - // try to get cache values from 'response.ext.prebid.cache' + // try to get cache values from 'response.ext.prebid.cache.js' // else try 'bid.ext.prebid.targeting' as fallback if (bid.ext.prebid.cache && typeof bid.ext.prebid.cache.vastXml === 'object' && bid.ext.prebid.cache.vastXml.cacheId && bid.ext.prebid.cache.vastXml.url) { bidObject.videoCacheKey = bid.ext.prebid.cache.vastXml.cacheId; diff --git a/modules/s2sTesting.js b/modules/s2sTesting.js index eccc3aa1f8a..98b3b86671c 100644 --- a/modules/s2sTesting.js +++ b/modules/s2sTesting.js @@ -1,5 +1,5 @@ -import { config } from '../src/config'; -import { setS2STestingModule } from '../src/adapterManager'; +import { config } from '../src/config.js'; +import { setS2STestingModule } from '../src/adapterManager.js'; let s2sTesting = {}; diff --git a/modules/scaleableAnalyticsAdapter.js b/modules/scaleableAnalyticsAdapter.js index 2fcc5943ae4..955a08c065a 100644 --- a/modules/scaleableAnalyticsAdapter.js +++ b/modules/scaleableAnalyticsAdapter.js @@ -1,10 +1,10 @@ /* COPYRIGHT SCALEABLE LLC 2019 */ -import { ajax } from '../src/ajax'; +import { ajax } from '../src/ajax.js'; import CONSTANTS from '../src/constants.json'; -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; -import * as utils from '../src/utils'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; +import * as utils from '../src/utils.js'; // Object.entries polyfill const entries = Object.entries || function(obj) { diff --git a/modules/schain.js b/modules/schain.js index b14e09bff11..d409e74df48 100644 --- a/modules/schain.js +++ b/modules/schain.js @@ -1,6 +1,6 @@ -import { config } from '../src/config'; -import adapterManager from '../src/adapterManager'; -import { isNumber, isStr, isArray, isPlainObject, hasOwn, logError, isInteger, _each, logWarn } from '../src/utils'; +import { config } from '../src/config.js'; +import adapterManager from '../src/adapterManager.js'; +import { isNumber, isStr, isArray, isPlainObject, hasOwn, logError, isInteger, _each, logWarn } from '../src/utils.js'; // https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md diff --git a/modules/seedingAllianceBidAdapter.js b/modules/seedingAllianceBidAdapter.js index 54f161287bd..b6acd7214a2 100755 --- a/modules/seedingAllianceBidAdapter.js +++ b/modules/seedingAllianceBidAdapter.js @@ -1,10 +1,10 @@ // jshint esversion: 6, es3: false, node: true 'use strict'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { NATIVE } from '../src/mediaTypes'; -import * as utils from '../src/utils'; -import { config } from '../src/config'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { NATIVE } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'seedingAlliance'; const DEFAULT_CUR = 'EUR'; diff --git a/modules/seedtagBidAdapter.js b/modules/seedtagBidAdapter.js index 845d8ffec9d..018339fabe4 100644 --- a/modules/seedtagBidAdapter.js +++ b/modules/seedtagBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils' -import { registerBidder } from '../src/adapters/bidderFactory' -import { VIDEO, BANNER } from '../src/mediaTypes' +import * as utils from '../src/utils.js' +import { registerBidder } from '../src/adapters/bidderFactory.js' +import { VIDEO, BANNER } from '../src/mediaTypes.js' const BIDDER_CODE = 'seedtag'; const SEEDTAG_ALIAS = 'st'; diff --git a/modules/segmentoBidAdapter.js b/modules/segmentoBidAdapter.js index bb6fdfec413..a042bdf4942 100644 --- a/modules/segmentoBidAdapter.js +++ b/modules/segmentoBidAdapter.js @@ -1,4 +1,4 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'segmento'; const URL = 'https://prebid-bidder.rutarget.ru/bid'; diff --git a/modules/sekindoUMBidAdapter.js b/modules/sekindoUMBidAdapter.js index ad4da7a06cb..bea25173747 100644 --- a/modules/sekindoUMBidAdapter.js +++ b/modules/sekindoUMBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; export const spec = { code: 'sekindoUM', supportedMediaTypes: ['banner', 'video'], diff --git a/modules/sharethroughAnalyticsAdapter.js b/modules/sharethroughAnalyticsAdapter.js index d32000373d2..5147b2a4275 100644 --- a/modules/sharethroughAnalyticsAdapter.js +++ b/modules/sharethroughAnalyticsAdapter.js @@ -1,6 +1,6 @@ -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; -const utils = require('../src/utils'); +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; +const utils = require('../src/utils.js'); const emptyUrl = ''; const analyticsType = 'endpoint'; diff --git a/modules/sharethroughBidAdapter.js b/modules/sharethroughBidAdapter.js index e86f8d518bc..4c73cb2c28f 100644 --- a/modules/sharethroughBidAdapter.js +++ b/modules/sharethroughBidAdapter.js @@ -1,4 +1,4 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const VERSION = '3.2.0'; const BIDDER_CODE = 'sharethrough'; diff --git a/modules/showheroes-bsBidAdapter.js b/modules/showheroes-bsBidAdapter.js index 05ea2eb53de..2ae7cc56c0f 100644 --- a/modules/showheroes-bsBidAdapter.js +++ b/modules/showheroes-bsBidAdapter.js @@ -1,9 +1,9 @@ -import * as utils from '../src/utils'; -import { config } from '../src/config'; -import { Renderer } from '../src/Renderer'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { VIDEO, BANNER } from '../src/mediaTypes'; -import { loadExternalScript } from '../src/adloader'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; +import { Renderer } from '../src/Renderer.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; +import { loadExternalScript } from '../src/adloader.js'; const PROD_ENDPOINT = 'https://bs1.showheroes.com/api/v1/bid'; const STAGE_ENDPOINT = 'https://bid-service.stage.showheroes.com/api/v1/bid'; diff --git a/modules/sigmoidAnalyticsAdapter.js b/modules/sigmoidAnalyticsAdapter.js index 95206fd2ea3..c20afbf9bfe 100644 --- a/modules/sigmoidAnalyticsAdapter.js +++ b/modules/sigmoidAnalyticsAdapter.js @@ -1,11 +1,11 @@ /* Sigmoid Analytics Adapter for prebid.js v1.1.0-pre Updated : 2018-03-28 */ -import includes from 'core-js/library/fn/array/includes'; -import adapter from '../src/AnalyticsAdapter'; +import includes from 'core-js/library/fn/array/includes.js'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; +import adapterManager from '../src/adapterManager.js'; -const utils = require('../src/utils'); +const utils = require('../src/utils.js'); const url = 'https://kinesis.us-east-1.amazonaws.com/'; const analyticsType = 'endpoint'; diff --git a/modules/slimcutBidAdapter.js b/modules/slimcutBidAdapter.js index 2aa75853301..d717f3a88bd 100644 --- a/modules/slimcutBidAdapter.js +++ b/modules/slimcutBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { ajax } from '../src/ajax'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ajax } from '../src/ajax.js'; const BIDDER_CODE = 'slimcut'; const ENDPOINT_URL = 'https://sb.freeskreen.com/pbr'; diff --git a/modules/smartadserverBidAdapter.js b/modules/smartadserverBidAdapter.js index 1e14195d38a..bddde2afd70 100644 --- a/modules/smartadserverBidAdapter.js +++ b/modules/smartadserverBidAdapter.js @@ -1,14 +1,14 @@ -import * as utils from '../src/utils'; +import * as utils from '../src/utils.js'; import { BANNER, VIDEO -} from '../src/mediaTypes'; +} from '../src/mediaTypes.js'; import { config -} from '../src/config'; +} from '../src/config.js'; import { registerBidder -} from '../src/adapters/bidderFactory'; +} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'smartadserver'; export const spec = { code: BIDDER_CODE, diff --git a/modules/smartrtbBidAdapter.js b/modules/smartrtbBidAdapter.js index 43304aa50c0..12d5a0ae7da 100644 --- a/modules/smartrtbBidAdapter.js +++ b/modules/smartrtbBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { config } from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'smartrtb'; function getDomain () { diff --git a/modules/smartyadsBidAdapter.js b/modules/smartyadsBidAdapter.js index 7737b805158..ff60d08e48b 100644 --- a/modules/smartyadsBidAdapter.js +++ b/modules/smartyadsBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; -import * as utils from '../src/utils'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'smartyads'; const AD_URL = 'https://ssp-nj.webtradehub.com/?c=o&m=multi'; diff --git a/modules/smilewantedBidAdapter.js b/modules/smilewantedBidAdapter.js index ed7e02a51a8..f965310abdd 100644 --- a/modules/smilewantedBidAdapter.js +++ b/modules/smilewantedBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import { Renderer } from '../src/Renderer'; -import { config } from '../src/config'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { Renderer } from '../src/Renderer.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; export const spec = { code: 'smilewanted', diff --git a/modules/smmsBidAdapter.js b/modules/smmsBidAdapter.js index 2f856d0f96e..670caebe61b 100644 --- a/modules/smmsBidAdapter.js +++ b/modules/smmsBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'smms'; const ENDPOINT_BANNER = 'https://bidder.mediams.mb.softbank.jp/api/v1/prebid/banner'; diff --git a/modules/somoBidAdapter.js b/modules/somoBidAdapter.js index e043ad83f7b..298b1c3050e 100644 --- a/modules/somoBidAdapter.js +++ b/modules/somoBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import includes from 'core-js/library/fn/array/includes'; -import {BANNER, VIDEO} from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; const VIDEO_TARGETING = ['mimes', 'minduration', 'maxduration', 'protocols', 'startdelay', 'linearity', 'skip', 'delivery', diff --git a/modules/sonobiAnalyticsAdapter.js b/modules/sonobiAnalyticsAdapter.js index ab110cb4d01..d69276e915c 100644 --- a/modules/sonobiAnalyticsAdapter.js +++ b/modules/sonobiAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import adapter from '../src/AnalyticsAdapter'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; -import {ajaxBuilder} from '../src/ajax'; +import adapterManager from '../src/adapterManager.js'; +import {ajaxBuilder} from '../src/ajax.js'; -const utils = require('../src/utils'); +const utils = require('../src/utils.js'); let ajax = ajaxBuilder(0); const DEFAULT_EVENT_URL = 'apex.go.sonobi.com/keymaker'; diff --git a/modules/sonobiBidAdapter.js b/modules/sonobiBidAdapter.js index 65565a0d962..5a43ea0b5c9 100644 --- a/modules/sonobiBidAdapter.js +++ b/modules/sonobiBidAdapter.js @@ -1,9 +1,9 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { parseSizesInput, logError, generateUUID, isEmpty, deepAccess, logWarn, logMessage } from '../src/utils'; -import { BANNER, VIDEO } from '../src/mediaTypes'; -import { config } from '../src/config'; -import { Renderer } from '../src/Renderer'; -import { userSync } from '../src/userSync'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { parseSizesInput, logError, generateUUID, isEmpty, deepAccess, logWarn, logMessage } from '../src/utils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { Renderer } from '../src/Renderer.js'; +import { userSync } from '../src/userSync.js'; const BIDDER_CODE = 'sonobi'; const STR_ENDPOINT = 'https://apex.go.sonobi.com/trinity.json'; diff --git a/modules/sortableAnalyticsAdapter.js b/modules/sortableAnalyticsAdapter.js index 17458065f9a..73ce1393c23 100644 --- a/modules/sortableAnalyticsAdapter.js +++ b/modules/sortableAnalyticsAdapter.js @@ -1,10 +1,10 @@ -import adapter from '../src/AnalyticsAdapter'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; -import * as utils from '../src/utils'; -import {ajax} from '../src/ajax'; -import {getGlobal} from '../src/prebidGlobal'; -import { config } from '../src/config'; +import adapterManager from '../src/adapterManager.js'; +import * as utils from '../src/utils.js'; +import {ajax} from '../src/ajax.js'; +import {getGlobal} from '../src/prebidGlobal.js'; +import { config } from '../src/config.js'; const DEFAULT_PROTOCOL = 'https'; const DEFAULT_HOST = 'pa.deployads.com'; diff --git a/modules/sovrnAnalyticsAdapter.js b/modules/sovrnAnalyticsAdapter.js index bfbad937206..8a712680dac 100644 --- a/modules/sovrnAnalyticsAdapter.js +++ b/modules/sovrnAnalyticsAdapter.js @@ -1,11 +1,11 @@ -import adapter from '../src/AnalyticsAdapter' -import adaptermanager from '../src/adapterManager' +import adapter from '../src/AnalyticsAdapter.js' +import adaptermanager from '../src/adapterManager.js' import CONSTANTS from '../src/constants.json' -import {ajaxBuilder} from '../src/ajax' -import * as utils from '../src/utils' -import {config} from '../src/config' -import find from 'core-js/library/fn/array/find' -import includes from 'core-js/library/fn/array/includes' +import {ajaxBuilder} from '../src/ajax.js' +import * as utils from '../src/utils.js' +import {config} from '../src/config.js' +import find from 'core-js/library/fn/array/find.js' +import includes from 'core-js/library/fn/array/includes.js' const ajax = ajaxBuilder(0) diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js index 5cd76981e8d..ee3eba90f04 100644 --- a/modules/sovrnBidAdapter.js +++ b/modules/sovrnBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils' -import {parse} from '../src/url' -import { registerBidder } from '../src/adapters/bidderFactory' -import { BANNER } from '../src/mediaTypes' +import * as utils from '../src/utils.js' +import {parse} from '../src/url.js' +import { registerBidder } from '../src/adapters/bidderFactory.js' +import { BANNER } from '../src/mediaTypes.js' export const spec = { code: 'sovrn', diff --git a/modules/spotxBidAdapter.js b/modules/spotxBidAdapter.js index 8e62c276e5e..fe42523e737 100644 --- a/modules/spotxBidAdapter.js +++ b/modules/spotxBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import { Renderer } from '../src/Renderer'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import { Renderer } from '../src/Renderer.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'spotx'; const URL = 'https://search.spotxchange.com/openrtb/2.3/dados/'; diff --git a/modules/staqAnalyticsAdapter.js b/modules/staqAnalyticsAdapter.js index eeeef700a7e..898c0cf02fb 100644 --- a/modules/staqAnalyticsAdapter.js +++ b/modules/staqAnalyticsAdapter.js @@ -1,10 +1,10 @@ -import adapter from '../src/AnalyticsAdapter'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; -import { getRefererInfo } from '../src/refererDetection'; -import { parse } from '../src/url'; -import * as utils from '../src/utils'; -import { ajax } from '../src/ajax'; +import adapterManager from '../src/adapterManager.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { parse } from '../src/url.js'; +import * as utils from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; const ANALYTICS_VERSION = '1.0.0'; const DEFAULT_QUEUE_TIMEOUT = 4000; diff --git a/modules/stvBidAdapter.js b/modules/stvBidAdapter.js index b8fb58c0ab3..2200e01b089 100644 --- a/modules/stvBidAdapter.js +++ b/modules/stvBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'stv'; const VADS_ENDPOINT_URL = 'https://ads.smartstream.tv/r/'; diff --git a/modules/sublimeBidAdapter.js b/modules/sublimeBidAdapter.js index fce3df7675b..63f851c5b4d 100644 --- a/modules/sublimeBidAdapter.js +++ b/modules/sublimeBidAdapter.js @@ -1,5 +1,5 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'sublime'; const DEFAULT_BID_HOST = 'pbjs.sskzlabs.com'; diff --git a/modules/synacormediaBidAdapter.js b/modules/synacormediaBidAdapter.js index 3879d676d99..ae2fd91cb6f 100644 --- a/modules/synacormediaBidAdapter.js +++ b/modules/synacormediaBidAdapter.js @@ -1,9 +1,9 @@ 'use strict'; -import { getAdUnitSizes, logWarn } from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, VIDEO } from '../src/mediaTypes'; -import includes from 'core-js/library/fn/array/includes'; +import { getAdUnitSizes, logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import includes from 'core-js/library/fn/array/includes.js'; const BID_HOST = 'https://prebid.technoratimedia.com'; const USER_SYNC_HOST = 'https://ad-cdn.technoratimedia.com'; diff --git a/modules/taphypeBidAdapter.js b/modules/taphypeBidAdapter.js index 63224596e3d..65c5a728127 100644 --- a/modules/taphypeBidAdapter.js +++ b/modules/taphypeBidAdapter.js @@ -1,4 +1,4 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; export const spec = { code: 'taphype', diff --git a/modules/teadsBidAdapter.js b/modules/teadsBidAdapter.js index c35c0df2d05..c0f11dc4639 100644 --- a/modules/teadsBidAdapter.js +++ b/modules/teadsBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -const utils = require('../src/utils'); +import {registerBidder} from '../src/adapters/bidderFactory.js'; +const utils = require('../src/utils.js'); const BIDDER_CODE = 'teads'; const ENDPOINT_URL = 'https://a.teads.tv/hb/bid-request'; const gdprStatus = { diff --git a/modules/telariaBidAdapter.js b/modules/telariaBidAdapter.js index efd9343c31b..74c97f34b74 100644 --- a/modules/telariaBidAdapter.js +++ b/modules/telariaBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import {createBid as createBidFactory} from '../src/bidfactory'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {VIDEO} from '../src/mediaTypes'; -import {STATUS} from '../src/constants'; +import * as utils from '../src/utils.js'; +import {createBid as createBidFactory} from '../src/bidfactory.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {VIDEO} from '../src/mediaTypes.js'; +import {STATUS} from '../src/constants.json'; const BIDDER_CODE = 'telaria'; const DOMAIN = 'tremorhub.com'; diff --git a/modules/theAdxBidAdapter.js b/modules/theAdxBidAdapter.js index 61dfec86662..5306b89a5da 100644 --- a/modules/theAdxBidAdapter.js +++ b/modules/theAdxBidAdapter.js @@ -1,15 +1,15 @@ -import * as utils from '../src/utils'; +import * as utils from '../src/utils.js'; import { BANNER, NATIVE, VIDEO -} from '../src/mediaTypes'; +} from '../src/mediaTypes.js'; import { registerBidder -} from '../src/adapters/bidderFactory'; +} from '../src/adapters/bidderFactory.js'; import { parse as parseUrl -} from '../src/url'; +} from '../src/url.js'; const BIDDER_CODE = 'theadx'; const ENDPOINT_URL = 'https://ssp.theadx.com/request'; diff --git a/modules/timBidAdapter.js b/modules/timBidAdapter.js index b615140ce7c..68c711f9935 100644 --- a/modules/timBidAdapter.js +++ b/modules/timBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import * as bidfactory from '../src/bidfactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import * as bidfactory from '../src/bidfactory.js'; var CONSTANTS = require('../src/constants.json'); const BIDDER_CODE = 'tim'; diff --git a/modules/topRTBBidAdapter.js b/modules/topRTBBidAdapter.js index 783d4008b33..c93bd8ccaac 100644 --- a/modules/topRTBBidAdapter.js +++ b/modules/topRTBBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER, VIDEO} from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; const BIDDER_CODE = 'topRTB'; const ENDPOINT_URL = 'https://ssp.toprtb.com/ssp/rest/ReqAd?ref=www.google.com&hbid=0&adUnitId='; diff --git a/modules/tpmnBidAdapter.js b/modules/tpmnBidAdapter.js index 081638c0adb..d80c87987fa 100644 --- a/modules/tpmnBidAdapter.js +++ b/modules/tpmnBidAdapter.js @@ -1,8 +1,8 @@ /* eslint-disable no-tabs */ -import { registerBidder } from '../src/adapters/bidderFactory'; -import * as utils from '../src/utils'; -import { BANNER } from '../src/mediaTypes'; -import {parse as parseUrl} from '../src/url'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; +import { BANNER } from '../src/mediaTypes.js'; +import {parse as parseUrl} from '../src/url.js'; export const ADAPTER_VERSION = '1'; const SUPPORTED_AD_TYPES = [BANNER]; diff --git a/modules/tribeosBidAdapter.js b/modules/tribeosBidAdapter.js index 50e062e6580..201e71ad2d1 100644 --- a/modules/tribeosBidAdapter.js +++ b/modules/tribeosBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import * as bidfactory from '../src/bidfactory'; -import {BANNER} from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import * as bidfactory from '../src/bidfactory.js'; +import {BANNER} from '../src/mediaTypes.js'; var CONSTANTS = require('../src/constants.json'); const BIDDER_CODE = 'tribeos'; diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index 70889d8d14c..c7491ab030b 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BID_REQUEST_BASE_URL = 'https://in-appadvertising.com/api/bidRequest'; const USER_SYNC_URL = 'https://in-appadvertising.com/api/userSync.html'; diff --git a/modules/tripleliftBidAdapter.js b/modules/tripleliftBidAdapter.js index 9c20e36caec..f232915f8f2 100644 --- a/modules/tripleliftBidAdapter.js +++ b/modules/tripleliftBidAdapter.js @@ -1,7 +1,7 @@ -import { BANNER } from '../src/mediaTypes'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import * as utils from '../src/utils'; -import { config } from '../src/config'; +import { BANNER } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'triplelift'; const STR_ENDPOINT = 'https://tlx.3lift.com/header/auction?'; diff --git a/modules/trustxBidAdapter.js b/modules/trustxBidAdapter.js index 1e7b9ef5ef4..f412fa21a05 100644 --- a/modules/trustxBidAdapter.js +++ b/modules/trustxBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { Renderer } from '../src/Renderer'; -import { VIDEO, BANNER } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'trustx'; const ENDPOINT_URL = 'https://sofia.trustx.org/hb'; diff --git a/modules/turktelekomBidAdapter.js b/modules/turktelekomBidAdapter.js index cfb1c24052a..852e557290c 100644 --- a/modules/turktelekomBidAdapter.js +++ b/modules/turktelekomBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { Renderer } from '../src/Renderer'; -import { VIDEO, BANNER } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'turktelekom'; const ENDPOINT_URL = 'https://ssp.programattik.com/hb'; diff --git a/modules/ucfunnelAnalyticsAdapter.js b/modules/ucfunnelAnalyticsAdapter.js index 525d1bdf615..7a471a1d3b4 100644 --- a/modules/ucfunnelAnalyticsAdapter.js +++ b/modules/ucfunnelAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import {ajax} from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; +import {ajax} from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; -import {getGlobal} from '../src/prebidGlobal'; -import {logError, logInfo, deepClone} from '../src/utils'; +import adapterManager from '../src/adapterManager.js'; +import {getGlobal} from '../src/prebidGlobal.js'; +import {logError, logInfo, deepClone} from '../src/utils.js'; const analyticsType = 'endpoint'; diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index e2c642862fd..505f3f89832 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js'; const VER = 'ADGENT_PREBID-2018011501'; const BIDDER_CODE = 'ucfunnel'; diff --git a/modules/underdogmediaBidAdapter.js b/modules/underdogmediaBidAdapter.js index 0ad11fe7fd6..d6ccafe7174 100644 --- a/modules/underdogmediaBidAdapter.js +++ b/modules/underdogmediaBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import { config } from '../src/config'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'underdogmedia'; const UDM_ADAPTER_VERSION = '3.5V'; const UDM_VENDOR_ID = '159'; diff --git a/modules/undertoneBidAdapter.js b/modules/undertoneBidAdapter.js index 0daa6d83e26..a253c6aae5f 100644 --- a/modules/undertoneBidAdapter.js +++ b/modules/undertoneBidAdapter.js @@ -2,8 +2,8 @@ * Adapter to send bids to Undertone */ -import * as urlUtils from '../src/url'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as urlUtils from '../src/url.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'undertone'; const URL = 'https://hb.undertone.com/hb'; diff --git a/modules/unifiedIdSystem.js b/modules/unifiedIdSystem.js index 12aa646a5d9..458aff4cf8b 100644 --- a/modules/unifiedIdSystem.js +++ b/modules/unifiedIdSystem.js @@ -5,9 +5,9 @@ * @requires module:modules/userId */ -import * as utils from '../src/utils' -import {ajax} from '../src/ajax'; -import {submodule} from '../src/hook' +import * as utils from '../src/utils.js' +import {ajax} from '../src/ajax.js'; +import {submodule} from '../src/hook.js' const MODULE_NAME = 'unifiedId'; diff --git a/modules/unrulyBidAdapter.js b/modules/unrulyBidAdapter.js index 580357a1978..15fe0fefe8b 100644 --- a/modules/unrulyBidAdapter.js +++ b/modules/unrulyBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils' -import { Renderer } from '../src/Renderer' -import { registerBidder } from '../src/adapters/bidderFactory' -import { VIDEO } from '../src/mediaTypes' +import * as utils from '../src/utils.js' +import { Renderer } from '../src/Renderer.js' +import { registerBidder } from '../src/adapters/bidderFactory.js' +import { VIDEO } from '../src/mediaTypes.js' function configureUniversalTag (exchangeRenderer) { if (!exchangeRenderer.config) throw new Error('UnrulyBidAdapter: Missing renderer config.') diff --git a/modules/userId/index.js b/modules/userId/index.js index cbe5e4de55f..ac2ae14cdb0 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -96,14 +96,14 @@ * @property {(function|undefined)} callback - function that will return an id */ -import find from 'core-js/library/fn/array/find'; -import {config} from '../../src/config'; -import events from '../../src/events'; -import * as utils from '../../src/utils'; -import {getGlobal} from '../../src/prebidGlobal'; -import {gdprDataHandler} from '../../src/adapterManager'; +import find from 'core-js/library/fn/array/find.js'; +import {config} from '../../src/config.js'; +import events from '../../src/events.js'; +import * as utils from '../../src/utils.js'; +import {getGlobal} from '../../src/prebidGlobal.js'; +import {gdprDataHandler} from '../../src/adapterManager.js'; import CONSTANTS from '../../src/constants.json'; -import {module} from '../../src/hook'; +import {module} from '../../src/hook.js'; const MODULE_NAME = 'User ID'; const COOKIE = 'cookie'; diff --git a/modules/userIdTargeting.js b/modules/userIdTargeting.js index 2a19bd62fbb..3ed8b2a14b5 100644 --- a/modules/userIdTargeting.js +++ b/modules/userIdTargeting.js @@ -1,8 +1,8 @@ -import {config} from '../src/config'; -import {getGlobal} from '../src/prebidGlobal'; +import {config} from '../src/config.js'; +import {getGlobal} from '../src/prebidGlobal.js'; import CONSTANTS from '../src/constants.json'; -import events from '../src/events'; -import { isStr, isPlainObject, isBoolean, isFn, hasOwn, logInfo } from '../src/utils'; +import events from '../src/events.js'; +import { isStr, isPlainObject, isBoolean, isFn, hasOwn, logInfo } from '../src/utils.js'; const MODULE_NAME = 'userIdTargeting'; const GAM = 'GAM'; diff --git a/modules/viBidAdapter.js b/modules/viBidAdapter.js index 8d8cb06e47e..4a09a2d2fc1 100644 --- a/modules/viBidAdapter.js +++ b/modules/viBidAdapter.js @@ -1,5 +1,5 @@ -import { registerBidder } from '../src/adapters/bidderFactory'; -import * as mediaTypes from '../src/mediaTypes'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import * as mediaTypes from '../src/mediaTypes.js'; export function get(path, obj, notFound) { path = typeof path === 'string' ? path.split('.') : path; diff --git a/modules/vidazooBidAdapter.js b/modules/vidazooBidAdapter.js index 4c1abd1c390..b3ab8a4d275 100644 --- a/modules/vidazooBidAdapter.js +++ b/modules/vidazooBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER} from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER} from '../src/mediaTypes.js'; export const URL = 'https://prebid.cootlogix.com'; const BIDDER_CODE = 'vidazoo'; const CURRENCY = 'USD'; diff --git a/modules/videoNowBidAdapter.js b/modules/videoNowBidAdapter.js index 5c5d0893248..b391af08d49 100644 --- a/modules/videoNowBidAdapter.js +++ b/modules/videoNowBidAdapter.js @@ -1,7 +1,7 @@ -import * as utils from '../src/utils' -import { registerBidder } from '../src/adapters/bidderFactory' -import { BANNER } from '../src/mediaTypes' -import { loadExternalScript } from '../src/adloader' +import * as utils from '../src/utils.js' +import { registerBidder } from '../src/adapters/bidderFactory.js' +import { BANNER } from '../src/mediaTypes.js' +import { loadExternalScript } from '../src/adloader.js' const RTB_URL = 'https://bidder.videonow.ru/prebid' diff --git a/modules/videoreachBidAdapter.js b/modules/videoreachBidAdapter.js index 8de32633eb0..710920c54fc 100644 --- a/modules/videoreachBidAdapter.js +++ b/modules/videoreachBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -const utils = require('../src/utils'); +import {registerBidder} from '../src/adapters/bidderFactory.js'; +const utils = require('../src/utils.js'); const BIDDER_CODE = 'videoreach'; const ENDPOINT_URL = 'https://a.videoreach.com/hb/'; diff --git a/modules/viewdeosDXBidAdapter.js b/modules/viewdeosDXBidAdapter.js index 2267c3a090a..fb028fca8c8 100644 --- a/modules/viewdeosDXBidAdapter.js +++ b/modules/viewdeosDXBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {VIDEO, BANNER} from '../src/mediaTypes'; -import {Renderer} from '../src/Renderer'; -import findIndex from 'core-js/library/fn/array/find-index'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {VIDEO, BANNER} from '../src/mediaTypes.js'; +import {Renderer} from '../src/Renderer.js'; +import findIndex from 'core-js/library/fn/array/find-index.js'; const URL = 'https://ghb.sync.viewdeos.com/auction/'; const OUTSTREAM_SRC = 'https://player.sync.viewdeos.com/outstream-unit/2.01/outstream.min.js'; diff --git a/modules/visxBidAdapter.js b/modules/visxBidAdapter.js index b043d2b7709..75011ddad03 100644 --- a/modules/visxBidAdapter.js +++ b/modules/visxBidAdapter.js @@ -1,6 +1,6 @@ -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { config } from '../src/config'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'visx'; const ENDPOINT_URL = 'https://t.visx.net/hb'; const TIME_TO_LIVE = 360; diff --git a/modules/vmgBidAdapter.js b/modules/vmgBidAdapter.js index 2bed62c5d67..57a812ec466 100644 --- a/modules/vmgBidAdapter.js +++ b/modules/vmgBidAdapter.js @@ -1,4 +1,4 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'vmg'; const ENDPOINT = 'https://predict.vmg.nyc'; diff --git a/modules/vrtcalBidAdapter.js b/modules/vrtcalBidAdapter.js index 139f985ed67..ff24803f688 100644 --- a/modules/vrtcalBidAdapter.js +++ b/modules/vrtcalBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory'; -import { BANNER } from '../src/mediaTypes'; -import {ajax} from '../src/ajax'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import {ajax} from '../src/ajax.js'; export const spec = { code: 'vrtcal', diff --git a/modules/vubleBidAdapter.js b/modules/vubleBidAdapter.js index 75ad4308db6..d14f24e9993 100644 --- a/modules/vubleBidAdapter.js +++ b/modules/vubleBidAdapter.js @@ -1,8 +1,8 @@ // Vuble Adapter -import * as utils from '../src/utils'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { Renderer } from '../src/Renderer'; +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; const BIDDER_CODE = 'vuble'; diff --git a/modules/widespaceBidAdapter.js b/modules/widespaceBidAdapter.js index a93c8fba0a0..486926f1889 100644 --- a/modules/widespaceBidAdapter.js +++ b/modules/widespaceBidAdapter.js @@ -1,12 +1,12 @@ -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; import { cookiesAreEnabled, parseQueryStringParameters, parseSizesInput -} from '../src/utils'; -import includes from 'core-js/library/fn/array/includes'; -import find from 'core-js/library/fn/array/find'; +} from '../src/utils.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js/library/fn/array/find.js'; const BIDDER_CODE = 'widespace'; const WS_ADAPTER_VERSION = '2.0.1'; diff --git a/modules/xhbBidAdapter.js b/modules/xhbBidAdapter.js index 8660889786e..0f7669f6eeb 100644 --- a/modules/xhbBidAdapter.js +++ b/modules/xhbBidAdapter.js @@ -1,9 +1,9 @@ -import { Renderer } from '../src/Renderer'; -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; -import find from 'core-js/library/fn/array/find'; -import includes from 'core-js/library/fn/array/includes'; +import { Renderer } from '../src/Renderer.js'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js/library/fn/array/includes.js'; const BIDDER_CODE = 'xhb'; const URL = 'https://ib.adnxs.com/ut/v3/prebid'; diff --git a/modules/yieldlabBidAdapter.js b/modules/yieldlabBidAdapter.js index 9af3de24cb1..373c23b12e5 100644 --- a/modules/yieldlabBidAdapter.js +++ b/modules/yieldlabBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils' -import { registerBidder } from '../src/adapters/bidderFactory' -import find from 'core-js/library/fn/array/find' -import { VIDEO, BANNER } from '../src/mediaTypes' -import { Renderer } from '../src/Renderer' +import * as utils from '../src/utils.js' +import { registerBidder } from '../src/adapters/bidderFactory.js' +import find from 'core-js/library/fn/array/find.js' +import { VIDEO, BANNER } from '../src/mediaTypes.js' +import { Renderer } from '../src/Renderer.js' const ENDPOINT = 'https://ad.yieldlab.net' const BIDDER_CODE = 'yieldlab' diff --git a/modules/yieldmoBidAdapter.js b/modules/yieldmoBidAdapter.js index ccf565df5da..7a33dd0db91 100644 --- a/modules/yieldmoBidAdapter.js +++ b/modules/yieldmoBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'yieldmo'; const CURRENCY = 'USD'; diff --git a/modules/yieldoneAnalyticsAdapter.js b/modules/yieldoneAnalyticsAdapter.js index 07aca207b4c..b3f89610b72 100644 --- a/modules/yieldoneAnalyticsAdapter.js +++ b/modules/yieldoneAnalyticsAdapter.js @@ -1,10 +1,10 @@ -import {ajax} from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; +import {ajax} from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager'; -import { targeting } from '../src/targeting'; -import { auctionManager } from '../src/auctionManager'; -import * as utils from '../src/utils'; +import adapterManager from '../src/adapterManager.js'; +import { targeting } from '../src/targeting.js'; +import { auctionManager } from '../src/auctionManager.js'; +import * as utils from '../src/utils.js'; const ANALYTICS_CODE = 'yieldone'; const analyticsType = 'endpoint'; diff --git a/modules/yieldoneBidAdapter.js b/modules/yieldoneBidAdapter.js index 27e8a381a46..97cce3cbd69 100644 --- a/modules/yieldoneBidAdapter.js +++ b/modules/yieldoneBidAdapter.js @@ -1,8 +1,8 @@ -import * as utils from '../src/utils'; -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import { Renderer } from '../src/Renderer'; -import { BANNER, VIDEO } from '../src/mediaTypes'; +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'yieldone'; const ENDPOINT_URL = 'https://y.one.impact-ad.jp/h_bid'; diff --git a/modules/yuktamediaAnalyticsAdapter.js b/modules/yuktamediaAnalyticsAdapter.js index e961933d018..268f31ea402 100644 --- a/modules/yuktamediaAnalyticsAdapter.js +++ b/modules/yuktamediaAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import { ajax } from '../src/ajax'; -import adapter from '../src/AnalyticsAdapter'; -import adapterManager from '../src/adapterManager'; +import { ajax } from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; import CONSTANTS from '../src/constants.json'; -import * as url from '../src/url'; -import * as utils from '../src/utils'; +import * as url from '../src/url.js'; +import * as utils from '../src/utils.js'; const emptyUrl = ''; const analyticsType = 'endpoint'; diff --git a/plugins/eslint/validateImports.js b/plugins/eslint/validateImports.js index 193455a47fd..a39bf9b26d5 100644 --- a/plugins/eslint/validateImports.js +++ b/plugins/eslint/validateImports.js @@ -31,6 +31,14 @@ function flagErrors(context, node, importPath) { ) { context.report(node, `import "${importPath}" cannot require module entry point`); } + + // don't allow extension-less local imports + if ( + !importPath.match(/^\w+/) && + !['.js', '.json'].includes(path.extname(absImportPath)) + ) { + context.report(node, `import "${importPath}" should include extension as .js or .json`); + } } } diff --git a/src/AnalyticsAdapter.js b/src/AnalyticsAdapter.js index 16d56725e39..f3297412a35 100644 --- a/src/AnalyticsAdapter.js +++ b/src/AnalyticsAdapter.js @@ -1,8 +1,8 @@ -import CONSTANTS from './constants'; -import { ajax } from './ajax'; +import CONSTANTS from './constants.json'; +import { ajax } from './ajax.js'; -const events = require('./events'); -const utils = require('./utils'); +const events = require('./events.js'); +const utils = require('./utils.js'); const { EVENTS: { diff --git a/src/Renderer.js b/src/Renderer.js index f35e9fe354d..2efe717eca4 100644 --- a/src/Renderer.js +++ b/src/Renderer.js @@ -1,6 +1,6 @@ -import { loadExternalScript } from './adloader'; -import * as utils from './utils'; -import find from 'core-js/library/fn/array/find'; +import { loadExternalScript } from './adloader.js'; +import * as utils from './utils.js'; +import find from 'core-js/library/fn/array/find.js'; const moduleCode = 'outstream'; /** diff --git a/src/adServerManager.js b/src/adServerManager.js index 11ce087903d..af8fe34920e 100644 --- a/src/adServerManager.js +++ b/src/adServerManager.js @@ -1,5 +1,5 @@ -import { getGlobal } from './prebidGlobal'; -import { logWarn } from './utils'; +import { getGlobal } from './prebidGlobal.js'; +import { logWarn } from './utils.js'; const prebid = getGlobal(); diff --git a/src/adUnits.js b/src/adUnits.js index aa88cf6eac5..cdac649c5b8 100644 --- a/src/adUnits.js +++ b/src/adUnits.js @@ -1,4 +1,4 @@ -import { deepAccess } from './utils'; +import { deepAccess } from './utils.js'; let adUnits = {}; diff --git a/src/adapterManager.js b/src/adapterManager.js index dfed67eaed4..134c21e5d7c 100644 --- a/src/adapterManager.js +++ b/src/adapterManager.js @@ -1,20 +1,20 @@ /** @module adaptermanger */ -import { flatten, getBidderCodes, getDefinedParams, shuffle, timestamp, getBidderRequest, bind } from './utils'; -import { getLabels, resolveStatus } from './sizeMapping'; -import { processNativeAdUnitParams, nativeAdapters } from './native'; -import { newBidder } from './adapters/bidderFactory'; -import { ajaxBuilder } from './ajax'; -import { config, RANDOM } from './config'; -import { hook } from './hook'; -import includes from 'core-js/library/fn/array/includes'; -import find from 'core-js/library/fn/array/find'; -import { adunitCounter } from './adUnits'; -import { getRefererInfo } from './refererDetection'; +import { flatten, getBidderCodes, getDefinedParams, shuffle, timestamp, getBidderRequest, bind } from './utils.js'; +import { getLabels, resolveStatus } from './sizeMapping.js'; +import { processNativeAdUnitParams, nativeAdapters } from './native.js'; +import { newBidder } from './adapters/bidderFactory.js'; +import { ajaxBuilder } from './ajax.js'; +import { config, RANDOM } from './config.js'; +import { hook } from './hook.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js/library/fn/array/find.js'; +import { adunitCounter } from './adUnits.js'; +import { getRefererInfo } from './refererDetection.js'; var utils = require('./utils.js'); var CONSTANTS = require('./constants.json'); -var events = require('./events'); +var events = require('./events.js'); let s2sTestingModule; // store s2sTesting module if it's loaded let adapterManager = {}; diff --git a/src/adapters/analytics/example.js b/src/adapters/analytics/example.js index 37ef0ff8fe3..1321612b688 100644 --- a/src/adapters/analytics/example.js +++ b/src/adapters/analytics/example.js @@ -2,7 +2,7 @@ * example.js - analytics adapter for Example Analytics Library example */ -import adapter from '../../AnalyticsAdapter'; +import adapter from '../../AnalyticsAdapter.js'; export default adapter( { diff --git a/src/adapters/analytics/example2.js b/src/adapters/analytics/example2.js index b04e8874e48..55d34697b8c 100644 --- a/src/adapters/analytics/example2.js +++ b/src/adapters/analytics/example2.js @@ -1,10 +1,10 @@ -import { ajax } from '../../../src/ajax'; +import { ajax } from '../../../src/ajax.js'; /** * example2.js - analytics adapter for Example2 Analytics Endpoint example */ -import adapter from '../../AnalyticsAdapter'; +import adapter from '../../AnalyticsAdapter.js'; const url = 'https://httpbin.org/post'; const analyticsType = 'endpoint'; diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index b61aaa96169..64bfe27c0c5 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -1,17 +1,17 @@ -import Adapter from '../adapter'; -import adapterManager from '../adapterManager'; -import { config } from '../config'; -import { createBid } from '../bidfactory'; -import { userSync } from '../userSync'; -import { nativeBidIsValid } from '../native'; -import { isValidVideoBid } from '../video'; +import Adapter from '../adapter.js'; +import adapterManager from '../adapterManager.js'; +import { config } from '../config.js'; +import { createBid } from '../bidfactory.js'; +import { userSync } from '../userSync.js'; +import { nativeBidIsValid } from '../native.js'; +import { isValidVideoBid } from '../video.js'; import CONSTANTS from '../constants.json'; -import events from '../events'; -import includes from 'core-js/library/fn/array/includes'; -import { ajax } from '../ajax'; -import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, setDataInLocalStorage, getDataFromLocalStorage, deepAccess, isArray } from '../utils'; -import { ADPOD } from '../mediaTypes'; -import { getHook } from '../hook'; +import events from '../events.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import { ajax } from '../ajax.js'; +import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, setDataInLocalStorage, getDataFromLocalStorage, deepAccess, isArray } from '../utils.js'; +import { ADPOD } from '../mediaTypes.js'; +import { getHook } from '../hook.js'; /** * This file aims to support Adapters during the Prebid 0.x -> 1.x transition. diff --git a/src/adloader.js b/src/adloader.js index 22bfe0ef4f2..ce21d763797 100644 --- a/src/adloader.js +++ b/src/adloader.js @@ -1,5 +1,5 @@ -import includes from 'core-js/library/fn/array/includes'; -import * as utils from './utils'; +import includes from 'core-js/library/fn/array/includes.js'; +import * as utils from './utils.js'; const _requestCache = {}; // The below list contains modules or vendors whom Prebid allows to load external JS. diff --git a/src/adserver.js b/src/adserver.js index 1341e9166da..c189037a9da 100644 --- a/src/adserver.js +++ b/src/adserver.js @@ -1,5 +1,5 @@ -import { formatQS } from './url'; -import { targeting } from './targeting'; +import { formatQS } from './url.js'; +import { targeting } from './targeting.js'; // Adserver parent class const AdServer = function(attr) { diff --git a/src/ajax.js b/src/ajax.js index a9ec75b30ee..16f7b365092 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -1,7 +1,7 @@ -import {parse as parseURL, format as formatURL} from './url'; -import { config } from './config'; +import {parse as parseURL, format as formatURL} from './url.js'; +import { config } from './config.js'; -var utils = require('./utils'); +var utils = require('./utils.js'); const XHR_DONE = 4; diff --git a/src/auction.js b/src/auction.js index 1880a9ac8d7..628c164a537 100644 --- a/src/auction.js +++ b/src/auction.js @@ -57,23 +57,23 @@ * @property {function(): void} callBids - sends requests to all adapters for bids */ -import {flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue} from './utils'; -import { parse as parseURL } from './url'; -import { getPriceBucketString } from './cpmBucketManager'; -import { getNativeTargeting } from './native'; -import { getCacheUrl, store } from './videoCache'; -import { Renderer } from './Renderer'; -import { config } from './config'; -import { userSync } from './userSync'; -import { hook } from './hook'; -import find from 'core-js/library/fn/array/find'; -import { OUTSTREAM } from './video'; -import { VIDEO } from './mediaTypes'; +import {flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue} from './utils.js'; +import { parse as parseURL } from './url.js'; +import { getPriceBucketString } from './cpmBucketManager.js'; +import { getNativeTargeting } from './native.js'; +import { getCacheUrl, store } from './videoCache.js'; +import { Renderer } from './Renderer.js'; +import { config } from './config.js'; +import { userSync } from './userSync.js'; +import { hook } from './hook.js'; +import find from 'core-js/library/fn/array/find.js'; +import { OUTSTREAM } from './video.js'; +import { VIDEO } from './mediaTypes.js'; const { syncUsers } = userSync; -const utils = require('./utils'); -const adapterManager = require('./adapterManager').default; -const events = require('./events'); +const utils = require('./utils.js'); +const adapterManager = require('./adapterManager.js').default; +const events = require('./events.js'); const CONSTANTS = require('./constants.json'); export const AUCTION_STARTED = 'started'; diff --git a/src/auctionManager.js b/src/auctionManager.js index 219a5e55805..bf95f0ab05e 100644 --- a/src/auctionManager.js +++ b/src/auctionManager.js @@ -16,9 +16,9 @@ * @property {function(): Object} getStandardBidderAdServerTargeting - returns standard bidder targeting for all the adapters. Refer http://prebid.org/dev-docs/publisher-api-reference.html#module_pbjs.bidderSettings for more details */ -import { uniques, flatten, logWarn } from './utils'; -import { newAuction, getStandardBidderSettings, AUCTION_COMPLETED } from './auction'; -import find from 'core-js/library/fn/array/find'; +import { uniques, flatten, logWarn } from './utils.js'; +import { newAuction, getStandardBidderSettings, AUCTION_COMPLETED } from './auction.js'; +import find from 'core-js/library/fn/array/find.js'; const CONSTANTS = require('./constants.json'); diff --git a/src/config.js b/src/config.js index 19a582e86d5..41056ced591 100644 --- a/src/config.js +++ b/src/config.js @@ -12,15 +12,15 @@ * @property {(string|Object)} [video-outstream] */ -import { isValidPriceConfig } from './cpmBucketManager'; -import find from 'core-js/library/fn/array/find'; -import includes from 'core-js/library/fn/array/includes'; -import Set from 'core-js/library/fn/set'; -import { parseQS } from './url'; - -const from = require('core-js/library/fn/array/from'); -const utils = require('./utils'); -const CONSTANTS = require('./constants'); +import { isValidPriceConfig } from './cpmBucketManager.js'; +import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import Set from 'core-js/library/fn/set.js'; +import { parseQS } from './url.js'; + +const from = require('core-js/library/fn/array/from.js'); +const utils = require('./utils.js'); +const CONSTANTS = require('./constants.json'); const DEFAULT_DEBUG = (parseQS(window.location.search)[CONSTANTS.DEBUG_MODE] || '').toUpperCase() === 'TRUE'; const DEFAULT_BIDDER_TIMEOUT = 3000; diff --git a/src/cpmBucketManager.js b/src/cpmBucketManager.js index 24586988a13..2f0ae4312e9 100644 --- a/src/cpmBucketManager.js +++ b/src/cpmBucketManager.js @@ -1,5 +1,5 @@ -import find from 'core-js/library/fn/array/find'; -const utils = require('./utils'); +import find from 'core-js/library/fn/array/find.js'; +const utils = require('./utils.js'); const _defaultPrecision = 2; const _lgPriceConfig = { diff --git a/src/debugging.js b/src/debugging.js index 786ede6fe4d..dc479f74674 100644 --- a/src/debugging.js +++ b/src/debugging.js @@ -1,7 +1,7 @@ -import { config } from './config'; -import { logMessage as utilsLogMessage, logWarn as utilsLogWarn } from './utils'; -import { addBidderRequests, addBidResponse } from './auction'; +import { config } from './config.js'; +import { logMessage as utilsLogMessage, logWarn as utilsLogWarn } from './utils.js'; +import { addBidderRequests, addBidResponse } from './auction.js'; const OVERRIDE_KEY = '$$PREBID_GLOBAL$$:debugging'; @@ -74,7 +74,7 @@ export function bidderExcluded(bidders, bidderCode) { */ export function applyBidOverrides(overrideObj, bidObj, bidType) { return Object.keys(overrideObj).filter(key => (['adUnitCode', 'bidder'].indexOf(key) === -1)).reduce(function(result, key) { - logMessage(`bidder overrides changed '${result.adUnitCode}/${result.bidderCode}' ${bidType}.${key} from '${result[key]}' to '${overrideObj[key]}'`); + logMessage(`bidder overrides changed '${result.adUnitCode}/${result.bidderCode}' ${bidType}.${key} from '${result[key]}.js' to '${overrideObj[key]}'`); result[key] = overrideObj[key]; return result; }, bidObj); diff --git a/src/events.js b/src/events.js index 6ef3f7a46cb..2d99ed4c561 100644 --- a/src/events.js +++ b/src/events.js @@ -1,8 +1,8 @@ /** * events.js */ -var utils = require('./utils'); -var CONSTANTS = require('./constants'); +var utils = require('./utils.js'); +var CONSTANTS = require('./constants.json'); var slice = Array.prototype.slice; var push = Array.prototype.push; diff --git a/src/hook.js b/src/hook.js index 220e1c39111..9050bf2f7dc 100644 --- a/src/hook.js +++ b/src/hook.js @@ -1,5 +1,5 @@ -import funHooks from 'fun-hooks/no-eval'; +import funHooks from 'fun-hooks/no-eval/index.js'; export let hook = funHooks({ ready: funHooks.SYNC | funHooks.ASYNC | funHooks.QUEUE diff --git a/src/native.js b/src/native.js index 6252eb133b3..0d8461a5b6f 100644 --- a/src/native.js +++ b/src/native.js @@ -1,5 +1,5 @@ -import { deepAccess, getBidRequest, getKeyByValue, insertHtmlIntoIframe, logError, triggerPixel } from './utils'; -import includes from 'core-js/library/fn/array/includes'; +import { deepAccess, getBidRequest, getKeyByValue, insertHtmlIntoIframe, logError, triggerPixel } from './utils.js'; +import includes from 'core-js/library/fn/array/includes.js'; const CONSTANTS = require('./constants.json'); diff --git a/src/prebid.js b/src/prebid.js index f1ead426496..e9fd0b299a8 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -1,24 +1,24 @@ /** @module pbjs */ -import { getGlobal } from './prebidGlobal'; -import { flatten, uniques, isGptPubadsDefined, adUnitsFilter, isArrayOfNums } from './utils'; -import { listenMessagesFromCreative } from './secureCreatives'; +import { getGlobal } from './prebidGlobal.js'; +import { flatten, uniques, isGptPubadsDefined, adUnitsFilter, isArrayOfNums } from './utils.js'; +import { listenMessagesFromCreative } from './secureCreatives.js'; import { userSync } from './userSync.js'; -import { config } from './config'; -import { auctionManager } from './auctionManager'; -import { targeting } from './targeting'; -import { hook } from './hook'; -import { sessionLoader } from './debugging'; -import includes from 'core-js/library/fn/array/includes'; -import { adunitCounter } from './adUnits'; -import { isRendererRequired, executeRenderer } from './Renderer'; -import { createBid } from './bidfactory'; +import { config } from './config.js'; +import { auctionManager } from './auctionManager.js'; +import { targeting } from './targeting.js'; +import { hook } from './hook.js'; +import { sessionLoader } from './debugging.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import { adunitCounter } from './adUnits.js'; +import { isRendererRequired, executeRenderer } from './Renderer.js'; +import { createBid } from './bidfactory.js'; const $$PREBID_GLOBAL$$ = getGlobal(); const CONSTANTS = require('./constants.json'); const utils = require('./utils.js'); -const adapterManager = require('./adapterManager').default; -const events = require('./events'); +const adapterManager = require('./adapterManager.js').default; +const events = require('./events.js'); const { triggerUserSyncs } = userSync; /* private variables */ diff --git a/src/refererDetection.js b/src/refererDetection.js index 2acb0b68716..60198678666 100644 --- a/src/refererDetection.js +++ b/src/refererDetection.js @@ -8,7 +8,7 @@ * Canonical URL which refers to an HTML link element, with the attribute of rel="canonical", found in the element of your webpage */ -import { logWarn } from './utils'; +import { logWarn } from './utils.js'; export function detectReferer(win) { /** diff --git a/src/secureCreatives.js b/src/secureCreatives.js index 88e0bc44f87..fb0d7e2bc9c 100644 --- a/src/secureCreatives.js +++ b/src/secureCreatives.js @@ -3,13 +3,13 @@ access to a publisher page from creative payloads. */ -import events from './events'; -import { fireNativeTrackers, getAssetMessage } from './native'; -import { EVENTS } from './constants'; -import { isSlotMatchingAdUnitCode, logWarn, replaceAuctionPrice } from './utils'; -import { auctionManager } from './auctionManager'; -import find from 'core-js/library/fn/array/find'; -import { isRendererRequired, executeRenderer } from './Renderer'; +import events from './events.js'; +import { fireNativeTrackers, getAssetMessage } from './native.js'; +import { EVENTS } from './constants.json'; +import { isSlotMatchingAdUnitCode, logWarn, replaceAuctionPrice } from './utils.js'; +import { auctionManager } from './auctionManager.js'; +import find from 'core-js/library/fn/array/find.js'; +import { isRendererRequired, executeRenderer } from './Renderer.js'; const BID_WON = EVENTS.BID_WON; diff --git a/src/sizeMapping.js b/src/sizeMapping.js index a549ca89d97..ff54ff8f251 100644 --- a/src/sizeMapping.js +++ b/src/sizeMapping.js @@ -1,6 +1,6 @@ -import { config } from './config'; -import {logWarn, isPlainObject, deepAccess, deepClone, getWindowTop} from './utils'; -import includes from 'core-js/library/fn/array/includes'; +import { config } from './config.js'; +import {logWarn, isPlainObject, deepAccess, deepClone, getWindowTop} from './utils.js'; +import includes from 'core-js/library/fn/array/includes.js'; let sizeConfig = []; diff --git a/src/targeting.js b/src/targeting.js index 7c24fdf59f4..bc2ee08eafd 100644 --- a/src/targeting.js +++ b/src/targeting.js @@ -1,10 +1,10 @@ -import { uniques, isGptPubadsDefined, getHighestCpm, getOldestHighestCpmBid, groupBy, isAdUnitCodeMatchingSlot, timestamp, deepAccess, deepClone, logError, logWarn, logInfo } from './utils'; -import { config } from './config'; -import { NATIVE_TARGETING_KEYS } from './native'; -import { auctionManager } from './auctionManager'; -import { sizeSupported } from './sizeMapping'; -import { ADPOD } from './mediaTypes'; -import includes from 'core-js/library/fn/array/includes'; +import { uniques, isGptPubadsDefined, getHighestCpm, getOldestHighestCpmBid, groupBy, isAdUnitCodeMatchingSlot, timestamp, deepAccess, deepClone, logError, logWarn, logInfo } from './utils.js'; +import { config } from './config.js'; +import { NATIVE_TARGETING_KEYS } from './native.js'; +import { auctionManager } from './auctionManager.js'; +import { sizeSupported } from './sizeMapping.js'; +import { ADPOD } from './mediaTypes.js'; +import includes from 'core-js/library/fn/array/includes.js'; const utils = require('./utils.js'); var CONSTANTS = require('./constants.json'); diff --git a/src/userSync.js b/src/userSync.js index fb5f4172a0d..6f23d915883 100644 --- a/src/userSync.js +++ b/src/userSync.js @@ -1,6 +1,6 @@ -import * as utils from './utils'; -import { config } from './config'; -import includes from 'core-js/library/fn/array/includes'; +import * as utils from './utils.js'; +import { config } from './config.js'; +import includes from 'core-js/library/fn/array/includes.js'; // Set userSync default values config.setDefaults({ diff --git a/src/utils.js b/src/utils.js index d3f37e5c7b5..b4b37d400bf 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,11 +1,11 @@ -import { config } from './config'; +import { config } from './config.js'; import clone from 'just-clone'; -import find from 'core-js/library/fn/array/find'; -import includes from 'core-js/library/fn/array/includes'; +import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js/library/fn/array/includes.js'; -const CONSTANTS = require('./constants'); +const CONSTANTS = require('./constants.json'); -export { default as deepAccess } from 'dlv/index'; +export { default as deepAccess } from 'dlv'; export { default as deepSetValue } from 'dset'; var tArr = 'Array'; diff --git a/src/video.js b/src/video.js index 57f44a76764..c3deb73ad4d 100644 --- a/src/video.js +++ b/src/video.js @@ -1,8 +1,8 @@ -import adapterManager from './adapterManager'; -import { getBidRequest, deepAccess, logError } from './utils'; -import { config } from '../src/config'; -import includes from 'core-js/library/fn/array/includes'; -import { hook } from './hook'; +import adapterManager from './adapterManager.js'; +import { getBidRequest, deepAccess, logError } from './utils.js'; +import { config } from '../src/config.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import { hook } from './hook.js'; const VIDEO_MEDIA_TYPE = 'video'; export const OUTSTREAM = 'outstream'; diff --git a/src/videoCache.js b/src/videoCache.js index 4a715cb1fe3..46bf74ee553 100644 --- a/src/videoCache.js +++ b/src/videoCache.js @@ -9,8 +9,8 @@ * This trickery helps integrate with ad servers, which set character limits on request params. */ -import { ajax } from './ajax'; -import { config } from '../src/config'; +import { ajax } from './ajax.js'; +import { config } from '../src/config.js'; /** * @typedef {object} CacheableUrlBid diff --git a/test/mocks/adloaderStub.js b/test/mocks/adloaderStub.js index 41e258d902d..b52ca5e9280 100644 --- a/test/mocks/adloaderStub.js +++ b/test/mocks/adloaderStub.js @@ -1,5 +1,5 @@ -import * as adloader from 'src/adloader'; +import * as adloader from 'src/adloader.js'; // this export is for adloader's tests against actual implementation export let loadExternalScript = adloader.loadExternalScript; diff --git a/test/mocks/videoCacheStub.js b/test/mocks/videoCacheStub.js index 39f5d67b6a9..7ce899cae35 100644 --- a/test/mocks/videoCacheStub.js +++ b/test/mocks/videoCacheStub.js @@ -1,4 +1,4 @@ -import * as videoCache from 'src/videoCache'; +import * as videoCache from 'src/videoCache.js'; /** * Function which can be called from unit tests to stub out the video cache. diff --git a/test/spec/AnalyticsAdapter_spec.js b/test/spec/AnalyticsAdapter_spec.js index 2ede81538c1..4afa430f81e 100644 --- a/test/spec/AnalyticsAdapter_spec.js +++ b/test/spec/AnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import events from 'src/events'; +import events from 'src/events.js'; import CONSTANTS from 'src/constants.json'; -import { server } from 'test/mocks/xhr'; +import { server } from 'test/mocks/xhr.js'; const REQUEST_BIDS = CONSTANTS.EVENTS.REQUEST_BIDS; const BID_REQUESTED = CONSTANTS.EVENTS.BID_REQUESTED; diff --git a/test/spec/adloader_spec.js b/test/spec/adloader_spec.js index 31ebeb23900..0c46cd2f171 100644 --- a/test/spec/adloader_spec.js +++ b/test/spec/adloader_spec.js @@ -1,5 +1,5 @@ -import * as utils from 'src/utils'; -import * as adLoader from 'test/mocks/adloaderStub'; +import * as utils from 'src/utils.js'; +import * as adLoader from 'test/mocks/adloaderStub.js'; describe('adLoader', function () { let utilsinsertElementStub; diff --git a/test/spec/aliasBidder_spec.js b/test/spec/aliasBidder_spec.js index 61a654dcb90..771d7fcdd46 100644 --- a/test/spec/aliasBidder_spec.js +++ b/test/spec/aliasBidder_spec.js @@ -1,4 +1,4 @@ -import { pbjsTestOnly } from 'test/helpers/pbjs-test-only'; +import { pbjsTestOnly } from 'test/helpers/pbjs-test-only.js'; describe('Publisher API _ Alias Bidder', function () { var assert = require('chai').assert; diff --git a/test/spec/auctionmanager_spec.js b/test/spec/auctionmanager_spec.js index a8e5c446db8..3ec3d67e448 100644 --- a/test/spec/auctionmanager_spec.js +++ b/test/spec/auctionmanager_spec.js @@ -1,14 +1,14 @@ -import { getKeyValueTargetingPairs, auctionCallbacks, AUCTION_COMPLETED } from 'src/auction'; +import { getKeyValueTargetingPairs, auctionCallbacks, AUCTION_COMPLETED } from 'src/auction.js'; import CONSTANTS from 'src/constants.json'; -import { adjustBids, getMediaTypeGranularity } from 'src/auction'; -import * as auctionModule from 'src/auction'; -import { registerBidder } from 'src/adapters/bidderFactory'; -import { createBid } from 'src/bidfactory'; -import { config } from 'src/config'; -import * as store from 'src/videoCache'; -import * as ajaxLib from 'src/ajax'; -import find from 'core-js/library/fn/array/find'; -import { server } from 'test/mocks/xhr'; +import { adjustBids, getMediaTypeGranularity } from 'src/auction.js'; +import * as auctionModule from 'src/auction.js'; +import { registerBidder } from 'src/adapters/bidderFactory.js'; +import { createBid } from 'src/bidfactory.js'; +import { config } from 'src/config.js'; +import * as store from 'src/videoCache.js'; +import * as ajaxLib from 'src/ajax.js'; +import find from 'core-js/library/fn/array/find.js'; +import { server } from 'test/mocks/xhr.js'; var assert = require('assert'); diff --git a/test/spec/config_spec.js b/test/spec/config_spec.js index 990add9b134..3bb184365ff 100644 --- a/test/spec/config_spec.js +++ b/test/spec/config_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { assert } from 'chai'; -import { newConfig } from 'src/config'; +import { newConfig } from 'src/config.js'; const utils = require('src/utils'); diff --git a/test/spec/cpmBucketManager_spec.js b/test/spec/cpmBucketManager_spec.js index 0d83687bf2e..0b8635a4e3b 100644 --- a/test/spec/cpmBucketManager_spec.js +++ b/test/spec/cpmBucketManager_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import {getPriceBucketString, isValidPriceConfig} from 'src/cpmBucketManager'; +import {getPriceBucketString, isValidPriceConfig} from 'src/cpmBucketManager.js'; let cpmFixtures = require('test/fixtures/cpmInputsOutputs.json'); describe('cpmBucketManager', function () { diff --git a/test/spec/debugging_spec.js b/test/spec/debugging_spec.js index b71d0141790..bf49a579cbd 100644 --- a/test/spec/debugging_spec.js +++ b/test/spec/debugging_spec.js @@ -1,8 +1,8 @@ import { expect } from 'chai'; -import { sessionLoader, addBidResponseHook, addBidderRequestsHook, getConfig, disableOverrides, addBidResponseBound, addBidderRequestsBound } from 'src/debugging'; -import { addBidResponse, addBidderRequests } from 'src/auction'; -import { config } from 'src/config'; +import { sessionLoader, addBidResponseHook, addBidderRequestsHook, getConfig, disableOverrides, addBidResponseBound, addBidderRequestsBound } from 'src/debugging.js'; +import { addBidResponse, addBidderRequests } from 'src/auction.js'; +import { config } from 'src/config.js'; describe('bid overrides', function () { let sandbox; diff --git a/test/spec/integration/faker/fixtures.js b/test/spec/integration/faker/fixtures.js index 643b531ad42..a11bd126d61 100644 --- a/test/spec/integration/faker/fixtures.js +++ b/test/spec/integration/faker/fixtures.js @@ -1,5 +1,5 @@ import faker from 'faker'; -import { makeSlot } from './googletag'; +import { makeSlot } from './googletag.js'; export function makeAdSlot(overrides = {}) { return Object.assign(makeSlot( diff --git a/test/spec/integration/faker/googletag.js b/test/spec/integration/faker/googletag.js index b043b5321cb..a0ce04402f7 100644 --- a/test/spec/integration/faker/googletag.js +++ b/test/spec/integration/faker/googletag.js @@ -1,5 +1,5 @@ import faker from 'faker'; -import { randomFive } from './fixtures'; +import { randomFive } from './fixtures.js'; var Slot = function Slot({ code, divId }) { code = code || `ad-slot-code-${randomFive()}`; diff --git a/test/spec/modules/1ad4goodBidAdapter_spec.js b/test/spec/modules/1ad4goodBidAdapter_spec.js index 316a5c13233..b9cd86a4cf7 100644 --- a/test/spec/modules/1ad4goodBidAdapter_spec.js +++ b/test/spec/modules/1ad4goodBidAdapter_spec.js @@ -1,9 +1,9 @@ import { expect } from 'chai'; -import { spec } from 'modules/1ad4goodBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import * as bidderFactory from 'src/adapters/bidderFactory'; -import { deepClone } from 'src/utils'; -import { config } from 'src/config'; +import { spec } from 'modules/1ad4goodBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import * as bidderFactory from 'src/adapters/bidderFactory.js'; +import { deepClone } from 'src/utils.js'; +import { config } from 'src/config.js'; const ENDPOINT = 'https://hb.1ad4good.org/prebid'; diff --git a/test/spec/modules/33acrossBidAdapter_spec.js b/test/spec/modules/33acrossBidAdapter_spec.js index 80cd56d3255..d27cc99b5bc 100644 --- a/test/spec/modules/33acrossBidAdapter_spec.js +++ b/test/spec/modules/33acrossBidAdapter_spec.js @@ -1,9 +1,9 @@ import { expect } from 'chai'; -import * as utils from 'src/utils'; -import { config } from 'src/config'; +import * as utils from 'src/utils.js'; +import { config } from 'src/config.js'; -import { spec } from 'modules/33acrossBidAdapter'; +import { spec } from 'modules/33acrossBidAdapter.js'; describe('33acrossBidAdapter:', function () { const BIDDER_CODE = '33across'; diff --git a/test/spec/modules/aardvarkBidAdapter_spec.js b/test/spec/modules/aardvarkBidAdapter_spec.js index 324607f825e..9671f961407 100644 --- a/test/spec/modules/aardvarkBidAdapter_spec.js +++ b/test/spec/modules/aardvarkBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import * as utils from 'src/utils'; -import { spec, resetUserSync } from 'modules/aardvarkBidAdapter'; +import * as utils from 'src/utils.js'; +import { spec, resetUserSync } from 'modules/aardvarkBidAdapter.js'; describe('aardvarkAdapterTest', function () { describe('forming valid bidRequests', function () { diff --git a/test/spec/modules/ablidaBidAdapter_spec.js b/test/spec/modules/ablidaBidAdapter_spec.js index 8e0424aee23..ca4fd4ab0be 100644 --- a/test/spec/modules/ablidaBidAdapter_spec.js +++ b/test/spec/modules/ablidaBidAdapter_spec.js @@ -1,6 +1,6 @@ import {assert, expect} from 'chai'; -import {spec} from 'modules/ablidaBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {spec} from 'modules/ablidaBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; const ENDPOINT_URL = 'https://bidder.ablida.net/prebid'; diff --git a/test/spec/modules/adagioAnalyticsAdapter_spec.js b/test/spec/modules/adagioAnalyticsAdapter_spec.js index e643dd8a1a7..aee85412104 100644 --- a/test/spec/modules/adagioAnalyticsAdapter_spec.js +++ b/test/spec/modules/adagioAnalyticsAdapter_spec.js @@ -1,6 +1,6 @@ -import adagioAnalyticsAdapter from 'modules/adagioAnalyticsAdapter'; +import adagioAnalyticsAdapter from 'modules/adagioAnalyticsAdapter.js'; import { expect } from 'chai'; -import * as utils from 'src/utils'; +import * as utils from 'src/utils.js'; let adapterManager = require('src/adapterManager').default; let events = require('src/events'); diff --git a/test/spec/modules/adagioBidAdapter_spec.js b/test/spec/modules/adagioBidAdapter_spec.js index 3ba1a24eaaf..d552f08543e 100644 --- a/test/spec/modules/adagioBidAdapter_spec.js +++ b/test/spec/modules/adagioBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { getAdagioScript, spec } from 'modules/adagioBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import * as utils from 'src/utils'; +import { getAdagioScript, spec } from 'modules/adagioBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import * as utils from 'src/utils.js'; describe('adagioAdapter', () => { let utilsMock; diff --git a/test/spec/modules/adbutlerBidAdapter_spec.js b/test/spec/modules/adbutlerBidAdapter_spec.js index 4f62d6206b4..a9b56ade79e 100644 --- a/test/spec/modules/adbutlerBidAdapter_spec.js +++ b/test/spec/modules/adbutlerBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from 'modules/adbutlerBidAdapter'; +import {spec} from 'modules/adbutlerBidAdapter.js'; describe('AdButler adapter', function () { let bidRequests; diff --git a/test/spec/modules/adfinityBidAdapter_spec.js b/test/spec/modules/adfinityBidAdapter_spec.js index bc2d806a1c3..479a2303dd5 100644 --- a/test/spec/modules/adfinityBidAdapter_spec.js +++ b/test/spec/modules/adfinityBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from '../../../modules/adfinityBidAdapter'; +import {spec} from '../../../modules/adfinityBidAdapter.js'; describe('AdfinityAdapter', function () { let bid = { diff --git a/test/spec/modules/adformBidAdapter_spec.js b/test/spec/modules/adformBidAdapter_spec.js index bb3e99173f7..8b7ecb3f9a7 100644 --- a/test/spec/modules/adformBidAdapter_spec.js +++ b/test/spec/modules/adformBidAdapter_spec.js @@ -1,8 +1,8 @@ import {assert, expect} from 'chai'; -import * as url from 'src/url'; -import {spec} from 'modules/adformBidAdapter'; -import { BANNER, VIDEO } from 'src/mediaTypes'; -import { config } from 'src/config'; +import * as url from 'src/url.js'; +import {spec} from 'modules/adformBidAdapter.js'; +import { BANNER, VIDEO } from 'src/mediaTypes.js'; +import { config } from 'src/config.js'; describe('Adform adapter', function () { let serverResponse, bidRequest, bidResponses; diff --git a/test/spec/modules/adformOpenRTBBidAdapter_spec.js b/test/spec/modules/adformOpenRTBBidAdapter_spec.js index b0ce0f59a88..caa2fc56208 100644 --- a/test/spec/modules/adformOpenRTBBidAdapter_spec.js +++ b/test/spec/modules/adformOpenRTBBidAdapter_spec.js @@ -1,9 +1,9 @@ // jshint esversion: 6, es3: false, node: true import {assert, expect} from 'chai'; -import * as url from 'src/url'; -import {spec} from 'modules/adformOpenRTBBidAdapter'; -import { NATIVE } from 'src/mediaTypes'; -import { config } from 'src/config'; +import * as url from 'src/url.js'; +import {spec} from 'modules/adformOpenRTBBidAdapter.js'; +import { NATIVE } from 'src/mediaTypes.js'; +import { config } from 'src/config.js'; describe('AdformOpenRTB adapter', function () { let serverResponse, bidRequest, bidResponses; diff --git a/test/spec/modules/adgenerationBidAdapter_spec.js b/test/spec/modules/adgenerationBidAdapter_spec.js index 6483272df21..927e7910723 100644 --- a/test/spec/modules/adgenerationBidAdapter_spec.js +++ b/test/spec/modules/adgenerationBidAdapter_spec.js @@ -1,8 +1,8 @@ import {expect} from 'chai'; -import {spec} from 'modules/adgenerationBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; -import {NATIVE} from 'src/mediaTypes'; -import {config} from 'src/config'; +import {spec} from 'modules/adgenerationBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; +import {NATIVE} from 'src/mediaTypes.js'; +import {config} from 'src/config.js'; import prebid from '../../../package.json'; describe('AdgenerationAdapter', function () { diff --git a/test/spec/modules/adheseBidAdapter_spec.js b/test/spec/modules/adheseBidAdapter_spec.js index 32658e2bb27..81f2a66425f 100644 --- a/test/spec/modules/adheseBidAdapter_spec.js +++ b/test/spec/modules/adheseBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from 'modules/adheseBidAdapter'; +import {spec} from 'modules/adheseBidAdapter.js'; const BID_ID = 456; const TTL = 360; diff --git a/test/spec/modules/adkernelAdnAnalytics_spec.js b/test/spec/modules/adkernelAdnAnalytics_spec.js index 26fd13afd1f..e7ef831080c 100644 --- a/test/spec/modules/adkernelAdnAnalytics_spec.js +++ b/test/spec/modules/adkernelAdnAnalytics_spec.js @@ -1,6 +1,6 @@ -import analyticsAdapter, {ExpiringQueue, getUmtSource, storage} from 'modules/adkernelAdnAnalyticsAdapter'; +import analyticsAdapter, {ExpiringQueue, getUmtSource, storage} from 'modules/adkernelAdnAnalyticsAdapter.js'; import {expect} from 'chai'; -import adapterManager from 'src/adapterManager'; +import adapterManager from 'src/adapterManager.js'; import CONSTANTS from 'src/constants.json'; const events = require('../../../src/events'); diff --git a/test/spec/modules/adkernelAdnBidAdapter_spec.js b/test/spec/modules/adkernelAdnBidAdapter_spec.js index 4c84790cb40..3d3e64aeec9 100644 --- a/test/spec/modules/adkernelAdnBidAdapter_spec.js +++ b/test/spec/modules/adkernelAdnBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from 'modules/adkernelAdnBidAdapter'; +import {spec} from 'modules/adkernelAdnBidAdapter.js'; describe('AdkernelAdn adapter', function () { const bid1_pub1 = { diff --git a/test/spec/modules/adkernelBidAdapter_spec.js b/test/spec/modules/adkernelBidAdapter_spec.js index b5c64f3fa49..3ae37592f1e 100644 --- a/test/spec/modules/adkernelBidAdapter_spec.js +++ b/test/spec/modules/adkernelBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/adkernelBidAdapter'; -import * as utils from 'src/utils'; +import {spec} from 'modules/adkernelBidAdapter.js'; +import * as utils from 'src/utils.js'; describe('Adkernel adapter', function () { const bid1_zone1 = { diff --git a/test/spec/modules/adliveBidAdapter_spec.js b/test/spec/modules/adliveBidAdapter_spec.js index 0048fc028b8..ddf8f82f20f 100644 --- a/test/spec/modules/adliveBidAdapter_spec.js +++ b/test/spec/modules/adliveBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/adliveBidAdapter'; +import { spec } from 'modules/adliveBidAdapter.js'; describe('adliveBidAdapterTests', function() { let bidRequestData = { diff --git a/test/spec/modules/admanBidAdapter_spec.js b/test/spec/modules/admanBidAdapter_spec.js index c39809b3b4f..f3212dec2f5 100644 --- a/test/spec/modules/admanBidAdapter_spec.js +++ b/test/spec/modules/admanBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from '../../../modules/admanBidAdapter'; +import {spec} from '../../../modules/admanBidAdapter.js'; describe('AdmanMediaBidAdapter', function () { let bid = { diff --git a/test/spec/modules/admediaBidAdapter_spec.js b/test/spec/modules/admediaBidAdapter_spec.js index 78228b85bff..5dc7b9a02a8 100644 --- a/test/spec/modules/admediaBidAdapter_spec.js +++ b/test/spec/modules/admediaBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/admediaBidAdapter'; +import { spec } from 'modules/admediaBidAdapter.js'; describe('admediaAdapterTests', function () { describe('bidRequestValidity', function () { diff --git a/test/spec/modules/admixerBidAdapter_spec.js b/test/spec/modules/admixerBidAdapter_spec.js index dce3d9a42c7..6d2e3059dc8 100644 --- a/test/spec/modules/admixerBidAdapter_spec.js +++ b/test/spec/modules/admixerBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/admixerBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {spec} from 'modules/admixerBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; const BIDDER_CODE = 'admixer'; const ENDPOINT_URL = 'https://inv-nets.admixer.net/prebid.1.0.aspx'; diff --git a/test/spec/modules/adoceanBidAdapter_spec.js b/test/spec/modules/adoceanBidAdapter_spec.js index 71569ad88bf..1c3383be5aa 100644 --- a/test/spec/modules/adoceanBidAdapter_spec.js +++ b/test/spec/modules/adoceanBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/adoceanBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/adoceanBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('AdoceanAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/adomikAnalyticsAdapter_spec.js b/test/spec/modules/adomikAnalyticsAdapter_spec.js index 16480d746b7..a067ce2770e 100644 --- a/test/spec/modules/adomikAnalyticsAdapter_spec.js +++ b/test/spec/modules/adomikAnalyticsAdapter_spec.js @@ -1,4 +1,4 @@ -import adomikAnalytics from 'modules/adomikAnalyticsAdapter'; +import adomikAnalytics from 'modules/adomikAnalyticsAdapter.js'; import {expect} from 'chai'; let events = require('src/events'); let adapterManager = require('src/adapterManager').default; diff --git a/test/spec/modules/adpod_spec.js b/test/spec/modules/adpod_spec.js index 6137d641cdf..96e8a66a62a 100644 --- a/test/spec/modules/adpod_spec.js +++ b/test/spec/modules/adpod_spec.js @@ -1,10 +1,10 @@ -import * as utils from 'src/utils'; -import { config } from 'src/config'; -import * as videoCache from 'src/videoCache'; -import * as auction from 'src/auction'; -import { ADPOD } from 'src/mediaTypes'; +import * as utils from 'src/utils.js'; +import { config } from 'src/config.js'; +import * as videoCache from 'src/videoCache.js'; +import * as auction from 'src/auction.js'; +import { ADPOD } from 'src/mediaTypes.js'; -import { callPrebidCacheHook, checkAdUnitSetupHook, checkVideoBidSetupHook, adpodSetConfig, sortByPricePerSecond } from 'modules/adpod'; +import { callPrebidCacheHook, checkAdUnitSetupHook, checkVideoBidSetupHook, adpodSetConfig, sortByPricePerSecond } from 'modules/adpod.js'; let expect = require('chai').expect; diff --git a/test/spec/modules/adponeBidAdapter_spec.js b/test/spec/modules/adponeBidAdapter_spec.js index 04cc169f4c8..737f1c284e1 100644 --- a/test/spec/modules/adponeBidAdapter_spec.js +++ b/test/spec/modules/adponeBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec } from 'modules/adponeBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; -import * as utils from 'src/utils'; +import { spec } from 'modules/adponeBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; +import * as utils from 'src/utils.js'; const EMPTY_ARRAY = []; describe('adponeBidAdapter', function () { diff --git a/test/spec/modules/adtelligentBidAdapter_spec.js b/test/spec/modules/adtelligentBidAdapter_spec.js index 1787816fac2..ad81795d0e9 100644 --- a/test/spec/modules/adtelligentBidAdapter_spec.js +++ b/test/spec/modules/adtelligentBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/adtelligentBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {spec} from 'modules/adtelligentBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; const ENDPOINT = 'https://ghb.adtelligent.com/auction/'; diff --git a/test/spec/modules/aduptechBidAdapter_spec.js b/test/spec/modules/aduptechBidAdapter_spec.js index 153f6a2c5e9..1e39e0cfc8b 100644 --- a/test/spec/modules/aduptechBidAdapter_spec.js +++ b/test/spec/modules/aduptechBidAdapter_spec.js @@ -10,8 +10,8 @@ import { extractSizesFromBidRequest, extractTopWindowReferrerFromBidRequest, extractTopWindowUrlFromBidRequest -} from '../../../modules/aduptechBidAdapter'; -import { newBidder } from '../../../src/adapters/bidderFactory'; +} from '../../../modules/aduptechBidAdapter.js'; +import { newBidder } from '../../../src/adapters/bidderFactory.js'; describe('AduptechBidAdapter', () => { describe('extractGdprFromBidderRequest', () => { diff --git a/test/spec/modules/advangelistsBidAdapter_spec.js b/test/spec/modules/advangelistsBidAdapter_spec.js index fbdfc9f30ee..2b9615fb572 100755 --- a/test/spec/modules/advangelistsBidAdapter_spec.js +++ b/test/spec/modules/advangelistsBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/advangelistsBidAdapter'; -import { BANNER, VIDEO } from 'src/mediaTypes'; +import { spec } from 'modules/advangelistsBidAdapter.js'; +import { BANNER, VIDEO } from 'src/mediaTypes.js'; describe('advangelistsBidAdapter', function () { let bidRequests; diff --git a/test/spec/modules/advenueBidAdapter_spec.js b/test/spec/modules/advenueBidAdapter_spec.js index f00b9a9f680..2d7739361b4 100644 --- a/test/spec/modules/advenueBidAdapter_spec.js +++ b/test/spec/modules/advenueBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from '../../../modules/advenueBidAdapter'; +import {spec} from '../../../modules/advenueBidAdapter.js'; describe('AdvenueAdapter', function () { let bid = { diff --git a/test/spec/modules/advertlyBidAdapter_spec.js b/test/spec/modules/advertlyBidAdapter_spec.js index 8705a254377..7825f11948a 100755 --- a/test/spec/modules/advertlyBidAdapter_spec.js +++ b/test/spec/modules/advertlyBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/advertlyBidAdapter'; +import { spec } from 'modules/advertlyBidAdapter.js'; const ENDPOINT = 'https://api.advertly.com/www/admin/plugins/Prebid/getAd.php'; diff --git a/test/spec/modules/adxcgAnalyticsAdapter_spec.js b/test/spec/modules/adxcgAnalyticsAdapter_spec.js index 2c495370a57..a796e7e966d 100644 --- a/test/spec/modules/adxcgAnalyticsAdapter_spec.js +++ b/test/spec/modules/adxcgAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ -import adxcgAnalyticsAdapter from 'modules/adxcgAnalyticsAdapter'; +import adxcgAnalyticsAdapter from 'modules/adxcgAnalyticsAdapter.js'; import { expect } from 'chai'; import adapterManager from 'src/adapterManager.js'; -import { server } from 'test/mocks/xhr'; +import { server } from 'test/mocks/xhr.js'; let events = require('src/events'); let constants = require('src/constants.json'); diff --git a/test/spec/modules/adxcgBidAdapter_spec.js b/test/spec/modules/adxcgBidAdapter_spec.js index 3e73479259c..3ec6a19d20b 100644 --- a/test/spec/modules/adxcgBidAdapter_spec.js +++ b/test/spec/modules/adxcgBidAdapter_spec.js @@ -1,7 +1,7 @@ import {expect} from 'chai'; -import * as url from 'src/url'; -import {spec} from 'modules/adxcgBidAdapter'; -import {deepClone} from '../../../src/utils'; +import * as url from 'src/url.js'; +import {spec} from 'modules/adxcgBidAdapter.js'; +import {deepClone} from '../../../src/utils.js'; describe('AdxcgAdapter', function () { let bidBanner = { diff --git a/test/spec/modules/adyoulikeBidAdapter_spec.js b/test/spec/modules/adyoulikeBidAdapter_spec.js index c6e448fdf6a..0dd6b5ad065 100644 --- a/test/spec/modules/adyoulikeBidAdapter_spec.js +++ b/test/spec/modules/adyoulikeBidAdapter_spec.js @@ -1,8 +1,8 @@ import { expect } from 'chai'; -import { parse } from '../../../src/url'; +import { parse } from '../../../src/url.js'; -import { spec } from 'modules/adyoulikeBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/adyoulikeBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('Adyoulike Adapter', function () { const canonicalUrl = 'https://canonical.url/?t=%26'; diff --git a/test/spec/modules/ajaBidAdapter_spec.js b/test/spec/modules/ajaBidAdapter_spec.js index 4b78711f46f..80ecab764e8 100644 --- a/test/spec/modules/ajaBidAdapter_spec.js +++ b/test/spec/modules/ajaBidAdapter_spec.js @@ -1,5 +1,5 @@ -import { spec } from 'modules/ajaBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/ajaBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const ENDPOINT = 'https://ad.as.amanad.adtdp.com/v2/prebid'; diff --git a/test/spec/modules/aniviewBidAdapter_spec.js b/test/spec/modules/aniviewBidAdapter_spec.js index ce8a34509c4..56a4dadbde3 100644 --- a/test/spec/modules/aniviewBidAdapter_spec.js +++ b/test/spec/modules/aniviewBidAdapter_spec.js @@ -1,5 +1,5 @@ -import { spec } from 'modules/aniviewBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/aniviewBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const { expect } = require('chai'); describe('ANIVIEW Bid Adapter Test', function () { diff --git a/test/spec/modules/aolBidAdapter_spec.js b/test/spec/modules/aolBidAdapter_spec.js index dd624222d69..dd10a57bbfe 100644 --- a/test/spec/modules/aolBidAdapter_spec.js +++ b/test/spec/modules/aolBidAdapter_spec.js @@ -1,7 +1,7 @@ import {expect} from 'chai'; -import * as utils from 'src/utils'; -import {spec} from 'modules/aolBidAdapter'; -import {config} from 'src/config'; +import * as utils from 'src/utils.js'; +import {spec} from 'modules/aolBidAdapter.js'; +import {config} from 'src/config.js'; const DEFAULT_AD_CONTENT = ''; diff --git a/test/spec/modules/appierAnalyticsAdapter_spec.js b/test/spec/modules/appierAnalyticsAdapter_spec.js index cf47f31afe4..cd026f64d49 100644 --- a/test/spec/modules/appierAnalyticsAdapter_spec.js +++ b/test/spec/modules/appierAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ import { appierAnalyticsAdapter, getCpmInUsd, parseBidderCode, parseAdUnitCode, ANALYTICS_VERSION, BIDDER_STATUS -} from 'modules/appierAnalyticsAdapter'; +} from 'modules/appierAnalyticsAdapter.js'; import {expect} from 'chai'; const events = require('src/events'); const constants = require('src/constants.json'); diff --git a/test/spec/modules/appierBidAdapter_spec.js b/test/spec/modules/appierBidAdapter_spec.js index c7fc5744d1c..5b6ccf14162 100644 --- a/test/spec/modules/appierBidAdapter_spec.js +++ b/test/spec/modules/appierBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec, API_SERVERS_MAP, ADAPTER_VERSION } from 'modules/appierBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import { config } from 'src/config'; +import { spec, API_SERVERS_MAP, ADAPTER_VERSION } from 'modules/appierBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { config } from 'src/config.js'; describe('AppierAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js index 5365b0ac529..ec2314ea460 100644 --- a/test/spec/modules/appnexusBidAdapter_spec.js +++ b/test/spec/modules/appnexusBidAdapter_spec.js @@ -1,10 +1,10 @@ import { expect } from 'chai'; -import { spec } from 'modules/appnexusBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import * as bidderFactory from 'src/adapters/bidderFactory'; -import { auctionManager } from 'src/auctionManager'; -import { deepClone } from 'src/utils'; -import { config } from 'src/config'; +import { spec } from 'modules/appnexusBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import * as bidderFactory from 'src/adapters/bidderFactory.js'; +import { auctionManager } from 'src/auctionManager.js'; +import { deepClone } from 'src/utils.js'; +import { config } from 'src/config.js'; const ENDPOINT = 'https://ib.adnxs.com/ut/v3/prebid'; diff --git a/test/spec/modules/astraoneBidAdapter_spec.js b/test/spec/modules/astraoneBidAdapter_spec.js index cd80e742b7d..e422f64b570 100644 --- a/test/spec/modules/astraoneBidAdapter_spec.js +++ b/test/spec/modules/astraoneBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai' -import { spec } from 'modules/astraoneBidAdapter' +import { spec } from 'modules/astraoneBidAdapter.js' function getSlotConfigs(mediaTypes, params) { return { diff --git a/test/spec/modules/atomxBidAdapter_spec.js b/test/spec/modules/atomxBidAdapter_spec.js index 782619d04db..d798bd6308c 100644 --- a/test/spec/modules/atomxBidAdapter_spec.js +++ b/test/spec/modules/atomxBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/atomxBidAdapter'; +import { spec } from 'modules/atomxBidAdapter.js'; describe('atomxAdapterTest', function () { describe('bidRequestValidity', function () { diff --git a/test/spec/modules/audienceNetworkBidAdapter_spec.js b/test/spec/modules/audienceNetworkBidAdapter_spec.js index d92db9f4b73..04694731981 100644 --- a/test/spec/modules/audienceNetworkBidAdapter_spec.js +++ b/test/spec/modules/audienceNetworkBidAdapter_spec.js @@ -3,8 +3,8 @@ */ import { expect } from 'chai'; -import { spec } from 'modules/audienceNetworkBidAdapter'; -import * as utils from 'src/utils'; +import { spec } from 'modules/audienceNetworkBidAdapter.js'; +import * as utils from 'src/utils.js'; const { code, diff --git a/test/spec/modules/audiencerunBidAdapter_spec.js b/test/spec/modules/audiencerunBidAdapter_spec.js index 212a081f0ce..826944abaf5 100644 --- a/test/spec/modules/audiencerunBidAdapter_spec.js +++ b/test/spec/modules/audiencerunBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/audiencerunBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/audiencerunBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const ENDPOINT = 'https://d.audiencerun.com/prebid'; diff --git a/test/spec/modules/beachfrontBidAdapter_spec.js b/test/spec/modules/beachfrontBidAdapter_spec.js index 0b13bdec001..7879ed37dc0 100644 --- a/test/spec/modules/beachfrontBidAdapter_spec.js +++ b/test/spec/modules/beachfrontBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import sinon from 'sinon'; -import { spec, VIDEO_ENDPOINT, BANNER_ENDPOINT, OUTSTREAM_SRC, DEFAULT_MIMES } from 'modules/beachfrontBidAdapter'; -import { parse as parseUrl } from 'src/url'; +import { spec, VIDEO_ENDPOINT, BANNER_ENDPOINT, OUTSTREAM_SRC, DEFAULT_MIMES } from 'modules/beachfrontBidAdapter.js'; +import { parse as parseUrl } from 'src/url.js'; describe('BeachfrontAdapter', function () { let bidRequests; diff --git a/test/spec/modules/betweenBidAdapter_spec.js b/test/spec/modules/betweenBidAdapter_spec.js index 9323386566d..3a6be953d7b 100644 --- a/test/spec/modules/betweenBidAdapter_spec.js +++ b/test/spec/modules/betweenBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/betweenBidAdapter'; +import { spec } from 'modules/betweenBidAdapter.js'; describe('betweenBidAdapterTests', function () { it('validate_pub_params', function () { diff --git a/test/spec/modules/bidfluenceBidAdapter_spec.js b/test/spec/modules/bidfluenceBidAdapter_spec.js index 9ce6e808c6b..ff33715a176 100644 --- a/test/spec/modules/bidfluenceBidAdapter_spec.js +++ b/test/spec/modules/bidfluenceBidAdapter_spec.js @@ -1,114 +1,114 @@ -import { expect } from 'chai'; -import { spec } from 'modules/bidfluenceBidAdapter'; - -const BIDDER_CODE = 'bidfluence'; -const PLACEMENT_ID = '1000'; -const PUB_ID = '1000'; -const CONSENT_STRING = 'DUXDSDFSFWRRR8345F=='; - -const validBidRequests = [{ - 'bidder': BIDDER_CODE, - 'params': { - 'placementId': PLACEMENT_ID, - 'publisherId': PUB_ID, - 'reservePrice': 0 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], - 'bidId': '2b1f23307fb8ef', - 'bidderRequestId': '10edf38ec1a719', - 'auctionId': '1025ba77-5463-4877-b0eb-14b205cb9304' -}]; - -const bidderRequest = { - 'bidderCode': 'bidfluence', - 'auctionId': '1025ba77-5463-4877-b0eb-14b205cb9304', - 'bidderRequestId': '10edf38ec1a719', - 'refererInfo': { - 'numIframes': 0, - 'reachedTop': true, - 'referer': 'test', - 'stack': ['test'] - }, - 'timeout': 1000, - 'gdprConsent': { - 'gdprApplies': true, - 'consentString': CONSENT_STRING, - 'vendorData': '' - } -}; - -bidderRequest.bids = validBidRequests; - -describe('Bidfluence Adapter test', () => { - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(validBidRequests[0])).to.equal(true); - }); - it('should return the right bidder code', function () { - expect(spec.code).to.eql(BIDDER_CODE); - }); - }); - - describe('buildRequests', function () { - const request = spec.buildRequests(validBidRequests, bidderRequest); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - const payload = JSON.parse(request.data); - - expect(payload.bids[0].bid).to.equal(validBidRequests[0].bidId); - expect(payload.azr).to.equal(true); - expect(payload.ck).to.not.be.undefined; - expect(payload.bids[0].tid).to.equal(PLACEMENT_ID); - expect(payload.bids[0].pid).to.equal(PUB_ID); - expect(payload.bids[0].rp).to.be.a('number'); - expect(payload.re).to.not.be.undefined; - expect(payload.st).to.not.be.undefined; - expect(payload.tz).to.not.be.undefined; - expect(payload.sr).to.not.be.undefined; - expect(payload.vp).to.not.be.undefined; - expect(payload.sdt).to.not.be.undefined; - expect(payload.bids[0].w).to.equal('300'); - expect(payload.bids[0].h).to.equal('250'); - - it('sends gdpr info if exists', function () { - expect(payload.gdpr).to.equal(true); - expect(payload.gdprc).to.equal(CONSENT_STRING); - }); - }); - - describe('interpretResponse', function () { - const response = { - body: { - Bids: - [{ - 'CreativeId': '1000', - 'Cpm': 0.50, - 'Ad': '
', - 'Height': 250, - 'Width': 300 - }] - } - }; - - it('should get correct bid response', function () { - const expectedResponse = [{ - requestId: response.body.Bids[0].BidId, - cpm: response.body.Bids[0].Cpm, - width: response.body.Bids[0].Width, - height: response.body.Bids[0].Height, - creativeId: response.body.Bids[0].CreativeId, - ad: response.body.Bids[0].Ad, - currency: 'USD', - netRevenue: true, - ttl: 360 - }]; - - let result = spec.interpretResponse(response, { 'bidderRequest': validBidRequests[0] }); - expect(result).to.deep.equal(expectedResponse); - }); - }); -}); +import { expect } from 'chai'; +import { spec } from 'modules/bidfluenceBidAdapter.js'; + +const BIDDER_CODE = 'bidfluence'; +const PLACEMENT_ID = '1000'; +const PUB_ID = '1000'; +const CONSENT_STRING = 'DUXDSDFSFWRRR8345F=='; + +const validBidRequests = [{ + 'bidder': BIDDER_CODE, + 'params': { + 'placementId': PLACEMENT_ID, + 'publisherId': PUB_ID, + 'reservePrice': 0 + }, + 'adUnitCode': 'adunit-code', + 'sizes': [[300, 250]], + 'bidId': '2b1f23307fb8ef', + 'bidderRequestId': '10edf38ec1a719', + 'auctionId': '1025ba77-5463-4877-b0eb-14b205cb9304' +}]; + +const bidderRequest = { + 'bidderCode': 'bidfluence', + 'auctionId': '1025ba77-5463-4877-b0eb-14b205cb9304', + 'bidderRequestId': '10edf38ec1a719', + 'refererInfo': { + 'numIframes': 0, + 'reachedTop': true, + 'referer': 'test', + 'stack': ['test'] + }, + 'timeout': 1000, + 'gdprConsent': { + 'gdprApplies': true, + 'consentString': CONSENT_STRING, + 'vendorData': '' + } +}; + +bidderRequest.bids = validBidRequests; + +describe('Bidfluence Adapter test', () => { + describe('isBidRequestValid', function () { + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(validBidRequests[0])).to.equal(true); + }); + it('should return the right bidder code', function () { + expect(spec.code).to.eql(BIDDER_CODE); + }); + }); + + describe('buildRequests', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + + it('sends bid request to our endpoint via POST', function () { + expect(request.method).to.equal('POST'); + }); + + const payload = JSON.parse(request.data); + + expect(payload.bids[0].bid).to.equal(validBidRequests[0].bidId); + expect(payload.azr).to.equal(true); + expect(payload.ck).to.not.be.undefined; + expect(payload.bids[0].tid).to.equal(PLACEMENT_ID); + expect(payload.bids[0].pid).to.equal(PUB_ID); + expect(payload.bids[0].rp).to.be.a('number'); + expect(payload.re).to.not.be.undefined; + expect(payload.st).to.not.be.undefined; + expect(payload.tz).to.not.be.undefined; + expect(payload.sr).to.not.be.undefined; + expect(payload.vp).to.not.be.undefined; + expect(payload.sdt).to.not.be.undefined; + expect(payload.bids[0].w).to.equal('300'); + expect(payload.bids[0].h).to.equal('250'); + + it('sends gdpr info if exists', function () { + expect(payload.gdpr).to.equal(true); + expect(payload.gdprc).to.equal(CONSENT_STRING); + }); + }); + + describe('interpretResponse', function () { + const response = { + body: { + Bids: + [{ + 'CreativeId': '1000', + 'Cpm': 0.50, + 'Ad': '
', + 'Height': 250, + 'Width': 300 + }] + } + }; + + it('should get correct bid response', function () { + const expectedResponse = [{ + requestId: response.body.Bids[0].BidId, + cpm: response.body.Bids[0].Cpm, + width: response.body.Bids[0].Width, + height: response.body.Bids[0].Height, + creativeId: response.body.Bids[0].CreativeId, + ad: response.body.Bids[0].Ad, + currency: 'USD', + netRevenue: true, + ttl: 360 + }]; + + let result = spec.interpretResponse(response, { 'bidderRequest': validBidRequests[0] }); + expect(result).to.deep.equal(expectedResponse); + }); + }); +}); diff --git a/test/spec/modules/bidglassAdapter_spec.js b/test/spec/modules/bidglassAdapter_spec.js index 00a47fc997a..d153430103d 100644 --- a/test/spec/modules/bidglassAdapter_spec.js +++ b/test/spec/modules/bidglassAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/bidglassBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/bidglassBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('Bid Glass Adapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/bidphysicsBidAdapter_spec.js b/test/spec/modules/bidphysicsBidAdapter_spec.js index 8c46b8cefa6..fc15c39cf81 100644 --- a/test/spec/modules/bidphysicsBidAdapter_spec.js +++ b/test/spec/modules/bidphysicsBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from 'modules/bidphysicsBidAdapter'; +import {spec} from 'modules/bidphysicsBidAdapter.js'; const REQUEST = { 'bidderCode': 'bidphysics', diff --git a/test/spec/modules/bridgewellBidAdapter_spec.js b/test/spec/modules/bridgewellBidAdapter_spec.js index 512777cf796..9a0abd067c9 100644 --- a/test/spec/modules/bridgewellBidAdapter_spec.js +++ b/test/spec/modules/bridgewellBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/bridgewellBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/bridgewellBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('bridgewellBidAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/brightcomBidAdapter_spec.js b/test/spec/modules/brightcomBidAdapter_spec.js index 14ed4d3024d..6477e94d9d6 100644 --- a/test/spec/modules/brightcomBidAdapter_spec.js +++ b/test/spec/modules/brightcomBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import * as utils from 'src/utils'; -import { spec } from 'modules/brightcomBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import * as utils from 'src/utils.js'; +import { spec } from 'modules/brightcomBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const URL = 'https://brightcombid.marphezis.com/hb'; diff --git a/test/spec/modules/britepoolIdSystem_spec.js b/test/spec/modules/britepoolIdSystem_spec.js index d7250eeb941..2c6dd234a90 100644 --- a/test/spec/modules/britepoolIdSystem_spec.js +++ b/test/spec/modules/britepoolIdSystem_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import {britepoolIdSubmodule} from 'modules/britepoolIdSystem'; +import {britepoolIdSubmodule} from 'modules/britepoolIdSystem.js'; describe('BritePool Submodule', () => { const api_key = '1111'; diff --git a/test/spec/modules/bucksenseBidAdapter_spec.js b/test/spec/modules/bucksenseBidAdapter_spec.js index b9da6c077b2..35aa97cf717 100644 --- a/test/spec/modules/bucksenseBidAdapter_spec.js +++ b/test/spec/modules/bucksenseBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from 'modules/bucksenseBidAdapter'; +import {spec} from 'modules/bucksenseBidAdapter.js'; describe('Bucksense Adapter', function() { const BIDDER_CODE = 'bucksense'; diff --git a/test/spec/modules/buzzoolaBidAdapter_spec.js b/test/spec/modules/buzzoolaBidAdapter_spec.js index e6f22d1da20..8a04999219d 100644 --- a/test/spec/modules/buzzoolaBidAdapter_spec.js +++ b/test/spec/modules/buzzoolaBidAdapter_spec.js @@ -1,8 +1,8 @@ import {expect} from 'chai'; -import {spec} from 'modules/buzzoolaBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; -import {executeRenderer, Renderer} from '../../../src/Renderer'; -import {deepClone} from '../../../src/utils'; +import {spec} from 'modules/buzzoolaBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; +import {executeRenderer, Renderer} from '../../../src/Renderer.js'; +import {deepClone} from '../../../src/utils.js'; const ENDPOINT = 'https://exchange.buzzoola.com/ssp/prebidjs'; const RENDERER_SRC = 'https://tube.buzzoola.com/new/build/buzzlibrary.js'; diff --git a/test/spec/modules/byplayBidAdapter_spec.js b/test/spec/modules/byplayBidAdapter_spec.js index 21249c0c9f2..57aad403c4e 100644 --- a/test/spec/modules/byplayBidAdapter_spec.js +++ b/test/spec/modules/byplayBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec } from 'modules/byplayBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import * as bidderFactory from 'src/adapters/bidderFactory'; +import { spec } from 'modules/byplayBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import * as bidderFactory from 'src/adapters/bidderFactory.js'; describe('byplayBidAdapter', () => { describe('isBidRequestValid', () => { diff --git a/test/spec/modules/c1xBidAdapter_spec.js b/test/spec/modules/c1xBidAdapter_spec.js index a728e52dbc4..00741abda7a 100644 --- a/test/spec/modules/c1xBidAdapter_spec.js +++ b/test/spec/modules/c1xBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { c1xAdapter } from 'modules/c1xBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { c1xAdapter } from 'modules/c1xBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const ENDPOINT = 'https://ht.c1exchange.com/ht'; const BIDDER_CODE = 'c1x'; diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js index 17cc07269b0..f8684c0d7c0 100644 --- a/test/spec/modules/categoryTranslation_spec.js +++ b/test/spec/modules/categoryTranslation_spec.js @@ -1,6 +1,6 @@ -import { getAdserverCategoryHook, initTranslation } from 'modules/categoryTranslation'; -import { config } from 'src/config'; -import * as utils from 'src/utils'; +import { getAdserverCategoryHook, initTranslation } from 'modules/categoryTranslation.js'; +import { config } from 'src/config.js'; +import * as utils from 'src/utils.js'; import { expect } from 'chai'; describe('category translation', function () { diff --git a/test/spec/modules/ccxBidAdapter_spec.js b/test/spec/modules/ccxBidAdapter_spec.js index 01e52c3559a..f14612629b1 100644 --- a/test/spec/modules/ccxBidAdapter_spec.js +++ b/test/spec/modules/ccxBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/ccxBidAdapter'; -import * as utils from 'src/utils'; +import { spec } from 'modules/ccxBidAdapter.js'; +import * as utils from 'src/utils.js'; describe('ccxAdapter', function () { let bids = [ diff --git a/test/spec/modules/cedatoBidAdapter_spec.js b/test/spec/modules/cedatoBidAdapter_spec.js index 0cf6d14147a..bb71f0ff3ea 100644 --- a/test/spec/modules/cedatoBidAdapter_spec.js +++ b/test/spec/modules/cedatoBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from 'modules/cedatoBidAdapter'; +import {spec} from 'modules/cedatoBidAdapter.js'; describe('the cedato adapter', function () { function getValidBidObject() { diff --git a/test/spec/modules/cleanmedianetBidAdapter_spec.js b/test/spec/modules/cleanmedianetBidAdapter_spec.js index af3eeb853fd..5438f6c8701 100644 --- a/test/spec/modules/cleanmedianetBidAdapter_spec.js +++ b/test/spec/modules/cleanmedianetBidAdapter_spec.js @@ -1,7 +1,7 @@ import {expect} from 'chai'; -import {spec, helper} from 'modules/cleanmedianetBidAdapter'; -import * as utils from 'src/utils'; -import {newBidder} from '../../../src/adapters/bidderFactory'; +import {spec, helper} from 'modules/cleanmedianetBidAdapter.js'; +import * as utils from 'src/utils.js'; +import {newBidder} from '../../../src/adapters/bidderFactory.js'; const supplyPartnerId = '123'; const adapter = newBidder(spec); diff --git a/test/spec/modules/clickforceBidAdapter_spec.js b/test/spec/modules/clickforceBidAdapter_spec.js index 3d4fc70c057..d0fb9439534 100644 --- a/test/spec/modules/clickforceBidAdapter_spec.js +++ b/test/spec/modules/clickforceBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/clickforceBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/clickforceBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('ClickforceAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/coinzillaBidAdapter_spec.js b/test/spec/modules/coinzillaBidAdapter_spec.js index e9157e2a735..a3438b80126 100644 --- a/test/spec/modules/coinzillaBidAdapter_spec.js +++ b/test/spec/modules/coinzillaBidAdapter_spec.js @@ -1,6 +1,6 @@ import {assert, expect} from 'chai'; -import {spec} from 'modules/coinzillaBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {spec} from 'modules/coinzillaBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; const ENDPOINT_URL = 'https://request.czilladx.com/serve/request.php'; diff --git a/test/spec/modules/collectcentBidAdapter_spec.js b/test/spec/modules/collectcentBidAdapter_spec.js index 7398c5c7dd9..0ab83a8024b 100644 --- a/test/spec/modules/collectcentBidAdapter_spec.js +++ b/test/spec/modules/collectcentBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from '../../../modules/collectcentBidAdapter'; +import {spec} from '../../../modules/collectcentBidAdapter.js'; describe('Collectcent', function () { let bid = { diff --git a/test/spec/modules/colossussspBidAdapter_spec.js b/test/spec/modules/colossussspBidAdapter_spec.js index 9ed2dbe6e6b..d2343516b6a 100644 --- a/test/spec/modules/colossussspBidAdapter_spec.js +++ b/test/spec/modules/colossussspBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from '../../../modules/colossussspBidAdapter'; +import {spec} from '../../../modules/colossussspBidAdapter.js'; describe('ColossussspAdapter', function () { let bid = { diff --git a/test/spec/modules/consentManagementUsp_spec.js b/test/spec/modules/consentManagementUsp_spec.js index 05f98d1c6a3..2e8d7db92b5 100644 --- a/test/spec/modules/consentManagementUsp_spec.js +++ b/test/spec/modules/consentManagementUsp_spec.js @@ -5,10 +5,10 @@ import { consentAPI, consentTimeout, staticConsentData -} from 'modules/consentManagementUsp'; -import * as utils from 'src/utils'; -import { config } from 'src/config'; -import { uspDataHandler } from 'src/adapterManager'; +} from 'modules/consentManagementUsp.js'; +import * as utils from 'src/utils.js'; +import { config } from 'src/config.js'; +import { uspDataHandler } from 'src/adapterManager.js'; let assert = require('chai').assert; let expect = require('chai').expect; diff --git a/test/spec/modules/consentManagement_spec.js b/test/spec/modules/consentManagement_spec.js index 9731164c655..4fb49f4f8b8 100644 --- a/test/spec/modules/consentManagement_spec.js +++ b/test/spec/modules/consentManagement_spec.js @@ -1,7 +1,7 @@ -import {setConsentConfig, requestBidsHook, resetConsentData, userCMP, consentTimeout, allowAuction, staticConsentData} from 'modules/consentManagement'; -import {gdprDataHandler} from 'src/adapterManager'; -import * as utils from 'src/utils'; -import { config } from 'src/config'; +import {setConsentConfig, requestBidsHook, resetConsentData, userCMP, consentTimeout, allowAuction, staticConsentData} from 'modules/consentManagement.js'; +import {gdprDataHandler} from 'src/adapterManager.js'; +import * as utils from 'src/utils.js'; +import { config } from 'src/config.js'; let assert = require('chai').assert; let expect = require('chai').expect; diff --git a/test/spec/modules/consumableBidAdapter_spec.js b/test/spec/modules/consumableBidAdapter_spec.js index 7785454f8e1..44076194885 100644 --- a/test/spec/modules/consumableBidAdapter_spec.js +++ b/test/spec/modules/consumableBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/consumableBidAdapter'; -import {createBid} from 'src/bidfactory'; +import {spec} from 'modules/consumableBidAdapter.js'; +import {createBid} from 'src/bidfactory.js'; const ENDPOINT = 'https://e.serverbid.com/api/v2'; const SMARTSYNC_CALLBACK = 'serverbidCallBids'; diff --git a/test/spec/modules/conversantBidAdapter_spec.js b/test/spec/modules/conversantBidAdapter_spec.js index 67dd721a059..4c9896166bf 100644 --- a/test/spec/modules/conversantBidAdapter_spec.js +++ b/test/spec/modules/conversantBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/conversantBidAdapter'; -import * as utils from 'src/utils'; +import {spec} from 'modules/conversantBidAdapter.js'; +import * as utils from 'src/utils.js'; describe('Conversant adapter tests', function() { const siteId = '108060'; diff --git a/test/spec/modules/cosmosBidAdapter_spec.js b/test/spec/modules/cosmosBidAdapter_spec.js index 7eb51c596e4..b33f53221e2 100644 --- a/test/spec/modules/cosmosBidAdapter_spec.js +++ b/test/spec/modules/cosmosBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/cosmosBidAdapter'; -import * as utils from 'src/utils'; +import { spec } from 'modules/cosmosBidAdapter.js'; +import * as utils from 'src/utils.js'; const constants = require('src/constants.json'); describe('Cosmos adapter', function () { diff --git a/test/spec/modules/cpmstarBidAdapter_spec.js b/test/spec/modules/cpmstarBidAdapter_spec.js index d080a2570ab..9e794d3e098 100755 --- a/test/spec/modules/cpmstarBidAdapter_spec.js +++ b/test/spec/modules/cpmstarBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/cpmstarBidAdapter'; -import { deepClone } from 'src/utils'; +import { spec } from 'modules/cpmstarBidAdapter.js'; +import { deepClone } from 'src/utils.js'; describe('Cpmstar Bid Adapter', function () { describe('isBidRequestValid', function () { diff --git a/test/spec/modules/criteoBidAdapter_spec.js b/test/spec/modules/criteoBidAdapter_spec.js index 3114fbc7355..9c96cfa3a05 100755 --- a/test/spec/modules/criteoBidAdapter_spec.js +++ b/test/spec/modules/criteoBidAdapter_spec.js @@ -1,10 +1,10 @@ import { expect } from 'chai'; -import { tryGetCriteoFastBid, spec, PROFILE_ID_PUBLISHERTAG, ADAPTER_VERSION, PUBLISHER_TAG_URL } from 'modules/criteoBidAdapter'; -import { createBid } from 'src/bidfactory'; +import { tryGetCriteoFastBid, spec, PROFILE_ID_PUBLISHERTAG, ADAPTER_VERSION, PUBLISHER_TAG_URL } from 'modules/criteoBidAdapter.js'; +import { createBid } from 'src/bidfactory.js'; import CONSTANTS from 'src/constants.json'; -import * as utils from 'src/utils'; -import { config } from '../../../src/config'; -import { NATIVE, VIDEO } from '../../../src/mediaTypes'; +import * as utils from 'src/utils.js'; +import { config } from '../../../src/config.js'; +import { NATIVE, VIDEO } from '../../../src/mediaTypes.js'; describe('The Criteo bidding adapter', function () { let utilsMock; diff --git a/test/spec/modules/criteoIdSystem_spec.js b/test/spec/modules/criteoIdSystem_spec.js index 44decfd56b6..c36852251f8 100644 --- a/test/spec/modules/criteoIdSystem_spec.js +++ b/test/spec/modules/criteoIdSystem_spec.js @@ -1,7 +1,7 @@ -import { criteoIdSubmodule } from 'modules/criteoIdSystem'; -import * as utils from 'src/utils'; -import * as ajaxLib from 'src/ajax'; -import * as urlLib from 'src/url'; +import { criteoIdSubmodule } from 'modules/criteoIdSystem.js'; +import * as utils from 'src/utils.js'; +import * as ajaxLib from 'src/ajax.js'; +import * as urlLib from 'src/url.js'; const pastDateString = new Date(0).toString() diff --git a/test/spec/modules/currency_spec.js b/test/spec/modules/currency_spec.js index 98f51b72251..577d36e9215 100644 --- a/test/spec/modules/currency_spec.js +++ b/test/spec/modules/currency_spec.js @@ -1,14 +1,14 @@ import { getCurrencyRates -} from 'test/fixtures/fixtures'; +} from 'test/fixtures/fixtures.js'; import { setConfig, addBidResponseHook, currencySupportEnabled, currencyRates -} from 'modules/currency'; +} from 'modules/currency.js'; var assert = require('chai').assert; var expect = require('chai').expect; diff --git a/test/spec/modules/dailyhuntBidAdapter_spec.js b/test/spec/modules/dailyhuntBidAdapter_spec.js index 617c1be04bb..de384d0a1f7 100644 --- a/test/spec/modules/dailyhuntBidAdapter_spec.js +++ b/test/spec/modules/dailyhuntBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/dailyhuntBidAdapter'; +import { spec } from 'modules/dailyhuntBidAdapter.js'; const PROD_PREBID_ENDPOINT_URL = 'https://money.dailyhunt.in/openrtb2/auction'; diff --git a/test/spec/modules/datablocksBidAdapter_spec.js b/test/spec/modules/datablocksBidAdapter_spec.js index af0fd8a3bc9..18b8aac7371 100644 --- a/test/spec/modules/datablocksBidAdapter_spec.js +++ b/test/spec/modules/datablocksBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from '../../../modules/datablocksBidAdapter'; +import { spec } from '../../../modules/datablocksBidAdapter.js'; let bid = { bidId: '2dd581a2b6281d', diff --git a/test/spec/modules/deepintentBidAdapter_spec.js b/test/spec/modules/deepintentBidAdapter_spec.js index 33dfd14d074..a934c7c33b4 100644 --- a/test/spec/modules/deepintentBidAdapter_spec.js +++ b/test/spec/modules/deepintentBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/deepintentBidAdapter'; -import * as utils from '../../../src/utils'; +import {spec} from 'modules/deepintentBidAdapter.js'; +import * as utils from '../../../src/utils.js'; describe('Deepintent adapter', function () { let request; diff --git a/test/spec/modules/dfpAdServerVideo_spec.js b/test/spec/modules/dfpAdServerVideo_spec.js index ff527c379e2..562c7eb297b 100644 --- a/test/spec/modules/dfpAdServerVideo_spec.js +++ b/test/spec/modules/dfpAdServerVideo_spec.js @@ -1,15 +1,15 @@ import { expect } from 'chai'; import parse from 'url-parse'; -import { buildDfpVideoUrl, buildAdpodVideoUrl } from 'modules/dfpAdServerVideo'; -import { parseQS } from 'src/url'; -import adUnit from 'test/fixtures/video/adUnit'; -import * as utils from 'src/utils'; -import { config } from 'src/config'; -import { targeting } from 'src/targeting'; -import { auctionManager } from 'src/auctionManager'; -import * as adpod from 'modules/adpod'; -import { server } from 'test/mocks/xhr'; +import { buildDfpVideoUrl, buildAdpodVideoUrl } from 'modules/dfpAdServerVideo.js'; +import { parseQS } from 'src/url.js'; +import adUnit from 'test/fixtures/video/adUnit.json'; +import * as utils from 'src/utils.js'; +import { config } from 'src/config.js'; +import { targeting } from 'src/targeting.js'; +import { auctionManager } from 'src/auctionManager.js'; +import * as adpod from 'modules/adpod.js'; +import { server } from 'test/mocks/xhr.js'; const bid = { videoCacheKey: 'abc', diff --git a/test/spec/modules/digitrustIdSystem_spec.js b/test/spec/modules/digitrustIdSystem_spec.js index 4b138e0d49d..dcffbe20355 100644 --- a/test/spec/modules/digitrustIdSystem_spec.js +++ b/test/spec/modules/digitrustIdSystem_spec.js @@ -1,7 +1,7 @@ import { digiTrustIdSubmodule, surfaceTestHook -} from 'modules/digiTrustIdSystem'; +} from 'modules/digiTrustIdSystem.js'; let assert = require('chai').assert; let expect = require('chai').expect; diff --git a/test/spec/modules/districtmDmxBidAdapter_spec.js b/test/spec/modules/districtmDmxBidAdapter_spec.js index a98bcaca9e0..90349fe042f 100644 --- a/test/spec/modules/districtmDmxBidAdapter_spec.js +++ b/test/spec/modules/districtmDmxBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; import * as _ from 'lodash'; -import {spec, matchRequest, checkDeepArray, defaultSize, upto5, cleanSizes, shuffle} from '../../../modules/districtmDMXBidAdapter'; +import {spec, matchRequest, checkDeepArray, defaultSize, upto5, cleanSizes, shuffle} from '../../../modules/districtmDMXBidAdapter.js'; const supportedSize = [ { diff --git a/test/spec/modules/djaxBidAdapter_spec.js b/test/spec/modules/djaxBidAdapter_spec.js index 82955ba43bc..bef2b1fddc5 100644 --- a/test/spec/modules/djaxBidAdapter_spec.js +++ b/test/spec/modules/djaxBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/djaxBidAdapter'; +import { spec } from 'modules/djaxBidAdapter.js'; const ENDPOINT = 'https://demo.reviveadservermod.com/headerbidding_adminshare/www/admin/plugins/Prebid/getAd.php'; diff --git a/test/spec/modules/dspxBidAdapter_spec.js b/test/spec/modules/dspxBidAdapter_spec.js index b1f392188a2..1156eb8d169 100644 --- a/test/spec/modules/dspxBidAdapter_spec.js +++ b/test/spec/modules/dspxBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/dspxBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/dspxBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const ENDPOINT_URL = 'https://buyer.dspx.tv/request/'; const ENDPOINT_URL_DEV = 'https://dcbuyer.dspx.tv/request/'; diff --git a/test/spec/modules/ebdrBidAdapter_spec.js b/test/spec/modules/ebdrBidAdapter_spec.js index 3cac03024c0..ba1cad475da 100644 --- a/test/spec/modules/ebdrBidAdapter_spec.js +++ b/test/spec/modules/ebdrBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec } from 'modules/ebdrBidAdapter'; -import { VIDEO, BANNER } from 'src/mediaTypes'; -import * as utils from 'src/utils'; +import { spec } from 'modules/ebdrBidAdapter.js'; +import { VIDEO, BANNER } from 'src/mediaTypes.js'; +import * as utils from 'src/utils.js'; describe('ebdrBidAdapter', function () { let bidRequests; diff --git a/test/spec/modules/emoteevBidAdapter_spec.js b/test/spec/modules/emoteevBidAdapter_spec.js index 5e22c039269..b967eee33b6 100644 --- a/test/spec/modules/emoteevBidAdapter_spec.js +++ b/test/spec/modules/emoteevBidAdapter_spec.js @@ -47,10 +47,10 @@ import { validateExternalId, VENDOR_ID, WALLPAPER, -} from 'modules/emoteevBidAdapter'; -import * as url from '../../../src/url'; -import * as utils from '../../../src/utils'; -import {config} from '../../../src/config'; +} from 'modules/emoteevBidAdapter.js'; +import * as url from '../../../src/url.js'; +import * as utils from '../../../src/utils.js'; +import {config} from '../../../src/config.js'; const cannedValidBidRequests = [{ adUnitCode: '/19968336/header-bid-tag-1', diff --git a/test/spec/modules/emx_digitalBidAdapter_spec.js b/test/spec/modules/emx_digitalBidAdapter_spec.js index 7f01d3566a0..e064c4833e6 100644 --- a/test/spec/modules/emx_digitalBidAdapter_spec.js +++ b/test/spec/modules/emx_digitalBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec } from 'modules/emx_digitalBidAdapter'; -import * as utils from 'src/utils'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/emx_digitalBidAdapter.js'; +import * as utils from 'src/utils.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('emx_digital Adapter', function () { describe('callBids', function () { diff --git a/test/spec/modules/envivoBidAdapter_spec.js b/test/spec/modules/envivoBidAdapter_spec.js index e3315ced921..7bd1dd1ccf1 100644 --- a/test/spec/modules/envivoBidAdapter_spec.js +++ b/test/spec/modules/envivoBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/envivoBidAdapter'; +import { spec } from 'modules/envivoBidAdapter.js'; const ENDPOINT = 'https://ad.nvivo.tv/ads/www/admin/plugins/Prebid/getAd.php'; diff --git a/test/spec/modules/eplanningAnalyticsAdapter_spec.js b/test/spec/modules/eplanningAnalyticsAdapter_spec.js index 3e72cfc1dcc..e900f7ca31c 100644 --- a/test/spec/modules/eplanningAnalyticsAdapter_spec.js +++ b/test/spec/modules/eplanningAnalyticsAdapter_spec.js @@ -1,8 +1,8 @@ -import eplAnalyticsAdapter from 'modules/eplanningAnalyticsAdapter'; -import includes from 'core-js/library/fn/array/includes'; +import eplAnalyticsAdapter from 'modules/eplanningAnalyticsAdapter.js'; +import includes from 'core-js/library/fn/array/includes.js'; import { expect } from 'chai'; -import {parse as parseURL} from 'src/url'; -import { server } from 'test/mocks/xhr'; +import {parse as parseURL} from 'src/url.js'; +import { server } from 'test/mocks/xhr.js'; let adapterManager = require('src/adapterManager').default; let events = require('src/events'); let constants = require('src/constants.json'); diff --git a/test/spec/modules/eplanningBidAdapter_spec.js b/test/spec/modules/eplanningBidAdapter_spec.js index d0913ca53e8..52c9d75ecf8 100644 --- a/test/spec/modules/eplanningBidAdapter_spec.js +++ b/test/spec/modules/eplanningBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec } from 'modules/eplanningBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import * as utils from 'src/utils'; +import { spec } from 'modules/eplanningBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import * as utils from 'src/utils.js'; describe('E-Planning Adapter', function () { const adapter = newBidder('spec'); diff --git a/test/spec/modules/etargetBidAdapter_spec.js b/test/spec/modules/etargetBidAdapter_spec.js index ed512e55ea9..0d8ad7bcf11 100644 --- a/test/spec/modules/etargetBidAdapter_spec.js +++ b/test/spec/modules/etargetBidAdapter_spec.js @@ -1,7 +1,7 @@ import {assert, expect} from 'chai'; -import * as url from 'src/url'; -import {spec} from 'modules/etargetBidAdapter'; -import { BANNER, VIDEO } from 'src/mediaTypes'; +import * as url from 'src/url.js'; +import {spec} from 'modules/etargetBidAdapter.js'; +import { BANNER, VIDEO } from 'src/mediaTypes.js'; describe('etarget adapter', function () { let serverResponse, bidRequest, bidResponses; diff --git a/test/spec/modules/feedadBidAdapter_spec.js b/test/spec/modules/feedadBidAdapter_spec.js index d7d0f32e252..066ab6b21f6 100644 --- a/test/spec/modules/feedadBidAdapter_spec.js +++ b/test/spec/modules/feedadBidAdapter_spec.js @@ -1,7 +1,7 @@ import {expect} from 'chai'; -import {spec} from 'modules/feedadBidAdapter'; -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes'; -import {server} from 'test/mocks/xhr'; +import {spec} from 'modules/feedadBidAdapter.js'; +import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; +import {server} from 'test/mocks/xhr.js'; const CODE = 'feedad'; diff --git a/test/spec/modules/fidelityBidAdapter_spec.js b/test/spec/modules/fidelityBidAdapter_spec.js index 85cd0bb0c3b..15bb5a1b59e 100644 --- a/test/spec/modules/fidelityBidAdapter_spec.js +++ b/test/spec/modules/fidelityBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/fidelityBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/fidelityBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('FidelityAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/fintezaAnalyticsAdapter_spec.js b/test/spec/modules/fintezaAnalyticsAdapter_spec.js index da575035d09..4b58761d8a6 100644 --- a/test/spec/modules/fintezaAnalyticsAdapter_spec.js +++ b/test/spec/modules/fintezaAnalyticsAdapter_spec.js @@ -1,8 +1,8 @@ -import fntzAnalyticsAdapter from 'modules/fintezaAnalyticsAdapter'; -import includes from 'core-js/library/fn/array/includes'; +import fntzAnalyticsAdapter from 'modules/fintezaAnalyticsAdapter.js'; +import includes from 'core-js/library/fn/array/includes.js'; import { expect } from 'chai'; -import { parse as parseURL } from 'src/url'; -import { server } from 'test/mocks/xhr'; +import { parse as parseURL } from 'src/url.js'; +import { server } from 'test/mocks/xhr.js'; let adapterManager = require('src/adapterManager').default; let events = require('src/events'); diff --git a/test/spec/modules/fluctBidAdapter_spec.js b/test/spec/modules/fluctBidAdapter_spec.js index 54829d5323c..6530a3c36cf 100644 --- a/test/spec/modules/fluctBidAdapter_spec.js +++ b/test/spec/modules/fluctBidAdapter_spec.js @@ -1,7 +1,7 @@ import {expect} from 'chai'; -import {spec} from 'modules/fluctBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; -import {config} from 'src/config'; +import {spec} from 'modules/fluctBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; +import {config} from 'src/config.js'; describe('fluctAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/freeWheelAdserverVideo_spec.js b/test/spec/modules/freeWheelAdserverVideo_spec.js index 1026cfb9e67..172909f99ca 100644 --- a/test/spec/modules/freeWheelAdserverVideo_spec.js +++ b/test/spec/modules/freeWheelAdserverVideo_spec.js @@ -1,8 +1,8 @@ import { expect } from 'chai'; -import { adpodUtils } from 'modules/freeWheelAdserverVideo'; -import { auctionManager } from 'src/auctionManager'; -import { config } from 'src/config'; -import { server } from 'test/mocks/xhr'; +import { adpodUtils } from 'modules/freeWheelAdserverVideo.js'; +import { auctionManager } from 'src/auctionManager.js'; +import { config } from 'src/config.js'; +import { server } from 'test/mocks/xhr.js'; describe('freeWheel adserver module', function() { let amStub; diff --git a/test/spec/modules/freewheel-sspBidAdapter_spec.js b/test/spec/modules/freewheel-sspBidAdapter_spec.js index 3c2b10b1b45..69e42c1b2e6 100644 --- a/test/spec/modules/freewheel-sspBidAdapter_spec.js +++ b/test/spec/modules/freewheel-sspBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/freewheel-sspBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/freewheel-sspBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const ENDPOINT = '//ads.stickyadstv.com/www/delivery/swfIndex.php'; diff --git a/test/spec/modules/gammaBidAdapter_spec.js b/test/spec/modules/gammaBidAdapter_spec.js index 78e69444bfd..cdaa1b5448a 100644 --- a/test/spec/modules/gammaBidAdapter_spec.js +++ b/test/spec/modules/gammaBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/gammaBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/gammaBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('gammaBidAdapter', function() { const adapter = newBidder(spec); diff --git a/test/spec/modules/gamoshiBidAdapter_spec.js b/test/spec/modules/gamoshiBidAdapter_spec.js index 003d6887ff8..79f58470cb3 100644 --- a/test/spec/modules/gamoshiBidAdapter_spec.js +++ b/test/spec/modules/gamoshiBidAdapter_spec.js @@ -1,7 +1,7 @@ import {expect} from 'chai'; -import {spec, helper} from 'modules/gamoshiBidAdapter'; -import * as utils from 'src/utils'; -import {newBidder} from '../../../src/adapters/bidderFactory'; +import {spec, helper} from 'modules/gamoshiBidAdapter.js'; +import * as utils from 'src/utils.js'; +import {newBidder} from '../../../src/adapters/bidderFactory.js'; const supplyPartnerId = '123'; const adapter = newBidder(spec); diff --git a/test/spec/modules/getintentBidAdapter_spec.js b/test/spec/modules/getintentBidAdapter_spec.js index e743d85972c..1959bda5c39 100644 --- a/test/spec/modules/getintentBidAdapter_spec.js +++ b/test/spec/modules/getintentBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai' -import { spec } from 'modules/getintentBidAdapter' +import { spec } from 'modules/getintentBidAdapter.js' describe('GetIntent Adapter Tests:', function () { const bidRequests = [{ diff --git a/test/spec/modules/googleAnalyticsAdapter_spec.js b/test/spec/modules/googleAnalyticsAdapter_spec.js index 6bc0d4e192d..b801b5fe696 100644 --- a/test/spec/modules/googleAnalyticsAdapter_spec.js +++ b/test/spec/modules/googleAnalyticsAdapter_spec.js @@ -1,4 +1,4 @@ -import ga from 'modules/googleAnalyticsAdapter'; +import ga from 'modules/googleAnalyticsAdapter.js'; var assert = require('assert'); diff --git a/test/spec/modules/gridBidAdapter_spec.js b/test/spec/modules/gridBidAdapter_spec.js index a71f2c05657..26ab27f5273 100644 --- a/test/spec/modules/gridBidAdapter_spec.js +++ b/test/spec/modules/gridBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec, resetUserSync, getSyncUrl } from 'modules/gridBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec, resetUserSync, getSyncUrl } from 'modules/gridBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('TheMediaGrid Adapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index fb4c1bf7b30..9073ad3bfda 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { newBidder } from 'src/adapters/bidderFactory'; -import { spec } from 'modules/gumgumBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { spec } from 'modules/gumgumBidAdapter.js'; const ENDPOINT = 'https://g2.gumgum.com/hbid/imp'; diff --git a/test/spec/modules/hpmdnetworkBidAdapter_spec.js b/test/spec/modules/hpmdnetworkBidAdapter_spec.js index 8e400f20def..9023fb248e9 100644 --- a/test/spec/modules/hpmdnetworkBidAdapter_spec.js +++ b/test/spec/modules/hpmdnetworkBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/hpmdnetworkBidAdapter'; +import { spec } from 'modules/hpmdnetworkBidAdapter.js'; describe('HPMDNetwork Adapter', function() { describe('isBidRequestValid', function () { diff --git a/test/spec/modules/iasBidAdapter_spec.js b/test/spec/modules/iasBidAdapter_spec.js index 7ac9d1906f5..1743ac947e6 100644 --- a/test/spec/modules/iasBidAdapter_spec.js +++ b/test/spec/modules/iasBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/iasBidAdapter'; +import { spec } from 'modules/iasBidAdapter.js'; describe('iasBidAdapter is an adapter that', function () { it('has the correct bidder code', function () { diff --git a/test/spec/modules/imonomyBidAdapter_spec.js b/test/spec/modules/imonomyBidAdapter_spec.js index 91b907186c2..45b3bed6e77 100644 --- a/test/spec/modules/imonomyBidAdapter_spec.js +++ b/test/spec/modules/imonomyBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/imonomyBidAdapter'; +import { spec } from 'modules/imonomyBidAdapter.js'; describe('Imonomy Adapter Tests', function () { const bidsRequest = [ diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 8983b47fcb0..676f6ab0fd0 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { ImproveDigitalAdServerJSClient, spec } from 'modules/improvedigitalBidAdapter'; -import { config } from 'src/config'; -import { userSync } from 'src/userSync'; +import { ImproveDigitalAdServerJSClient, spec } from 'modules/improvedigitalBidAdapter.js'; +import { config } from 'src/config.js'; +import { userSync } from 'src/userSync.js'; describe('Improve Digital Adapter Tests', function () { let idClient = new ImproveDigitalAdServerJSClient('hb'); diff --git a/test/spec/modules/innityBidAdapter_spec.js b/test/spec/modules/innityBidAdapter_spec.js index 653fd762709..80c00252632 100644 --- a/test/spec/modules/innityBidAdapter_spec.js +++ b/test/spec/modules/innityBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/innityBidAdapter'; +import { spec } from 'modules/innityBidAdapter.js'; describe('innityAdapterTest', () => { describe('bidRequestValidity', () => { diff --git a/test/spec/modules/inskinBidAdapter_spec.js b/test/spec/modules/inskinBidAdapter_spec.js index 408661085e8..1be79a5a963 100644 --- a/test/spec/modules/inskinBidAdapter_spec.js +++ b/test/spec/modules/inskinBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/inskinBidAdapter'; -import { createBid } from 'src/bidfactory'; +import { spec } from 'modules/inskinBidAdapter.js'; +import { createBid } from 'src/bidfactory.js'; const ENDPOINT = 'https://mfad.inskinad.com/api/v2'; diff --git a/test/spec/modules/invibesBidAdapter_spec.js b/test/spec/modules/invibesBidAdapter_spec.js index 3ca31c0abb4..d21405a8b9d 100644 --- a/test/spec/modules/invibesBidAdapter_spec.js +++ b/test/spec/modules/invibesBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec, resetInvibes, stubDomainOptions } from 'modules/invibesBidAdapter'; +import { spec, resetInvibes, stubDomainOptions } from 'modules/invibesBidAdapter.js'; describe('invibesBidAdapter:', function () { const BIDDER_CODE = 'invibes'; diff --git a/test/spec/modules/invisiblyAnalyticsAdapter_spec.js b/test/spec/modules/invisiblyAnalyticsAdapter_spec.js index 8338476f770..419d5a29700 100644 --- a/test/spec/modules/invisiblyAnalyticsAdapter_spec.js +++ b/test/spec/modules/invisiblyAnalyticsAdapter_spec.js @@ -1,6 +1,6 @@ -import invisiblyAdapter from 'modules/invisiblyAnalyticsAdapter'; +import invisiblyAdapter from 'modules/invisiblyAnalyticsAdapter.js'; import { expect } from 'chai'; -import { server } from 'test/mocks/xhr'; +import { server } from 'test/mocks/xhr.js'; let events = require('src/events'); let constants = require('src/constants.json'); diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js index 2c942a672dc..4f4c4734205 100644 --- a/test/spec/modules/ixBidAdapter_spec.js +++ b/test/spec/modules/ixBidAdapter_spec.js @@ -1,8 +1,8 @@ -import * as utils from 'src/utils'; -import { config } from 'src/config'; +import * as utils from 'src/utils.js'; +import { config } from 'src/config.js'; import { expect } from 'chai'; -import { newBidder } from 'src/adapters/bidderFactory'; -import { spec } from 'modules/ixBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { spec } from 'modules/ixBidAdapter.js'; describe('IndexexchangeAdapter', function () { const IX_SECURE_ENDPOINT = 'https://as-sec.casalemedia.com/cygnus'; diff --git a/test/spec/modules/jcmBidAdapter_spec.js b/test/spec/modules/jcmBidAdapter_spec.js index fa6791674bc..9d84bca5513 100644 --- a/test/spec/modules/jcmBidAdapter_spec.js +++ b/test/spec/modules/jcmBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/jcmBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/jcmBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const ENDPOINT = 'https://media.adfrontiers.com/'; diff --git a/test/spec/modules/justpremiumBidAdapter_spec.js b/test/spec/modules/justpremiumBidAdapter_spec.js index 3b34799f36d..c162b785aed 100644 --- a/test/spec/modules/justpremiumBidAdapter_spec.js +++ b/test/spec/modules/justpremiumBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai' -import { spec } from 'modules/justpremiumBidAdapter' +import { spec } from 'modules/justpremiumBidAdapter.js' describe('justpremium adapter', function () { let sandbox; diff --git a/test/spec/modules/kargoBidAdapter_spec.js b/test/spec/modules/kargoBidAdapter_spec.js index 3136e612595..f64800be290 100644 --- a/test/spec/modules/kargoBidAdapter_spec.js +++ b/test/spec/modules/kargoBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect, assert} from 'chai'; -import {spec} from 'modules/kargoBidAdapter'; -import {config} from 'src/config'; +import {spec} from 'modules/kargoBidAdapter.js'; +import {config} from 'src/config.js'; describe('kargo adapter tests', function () { var sandbox, clock, frozenNow = new Date(); diff --git a/test/spec/modules/komoonaBidAdapter_spec.js b/test/spec/modules/komoonaBidAdapter_spec.js index ed84155b28d..3d62f91cae6 100644 --- a/test/spec/modules/komoonaBidAdapter_spec.js +++ b/test/spec/modules/komoonaBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/komoonaBidAdapter'; +import { spec } from 'modules/komoonaBidAdapter.js'; describe('Komoona.com Adapter Tests', function () { const bidsRequest = [ diff --git a/test/spec/modules/konduitWrapper_spec.js b/test/spec/modules/konduitWrapper_spec.js index bcc65ddd683..bfae5711d32 100644 --- a/test/spec/modules/konduitWrapper_spec.js +++ b/test/spec/modules/konduitWrapper_spec.js @@ -1,9 +1,9 @@ import { expect } from 'chai'; import parse from 'url-parse'; -import { buildVastUrl } from 'modules/konduitWrapper'; -import { parseQS } from 'src/url'; -import { config } from 'src/config'; +import { buildVastUrl } from 'modules/konduitWrapper.js'; +import { parseQS } from 'src/url.js'; +import { config } from 'src/config.js'; describe('The Konduit vast wrapper module', function () { it('should make a wrapped request url when `bid` passed', function () { diff --git a/test/spec/modules/lemmaBidAdapter_spec.js b/test/spec/modules/lemmaBidAdapter_spec.js index 3f359cc5e9e..a236ac17d71 100644 --- a/test/spec/modules/lemmaBidAdapter_spec.js +++ b/test/spec/modules/lemmaBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/lemmaBidAdapter'; -import * as utils from 'src/utils'; +import { spec } from 'modules/lemmaBidAdapter.js'; +import * as utils from 'src/utils.js'; const constants = require('src/constants.json'); describe('lemmaBidAdapter', function() { diff --git a/test/spec/modules/liveIntentIdSystem_spec.js b/test/spec/modules/liveIntentIdSystem_spec.js index 4c0e2bb25e6..450c4b71bd7 100644 --- a/test/spec/modules/liveIntentIdSystem_spec.js +++ b/test/spec/modules/liveIntentIdSystem_spec.js @@ -1,6 +1,6 @@ -import { liveIntentIdSubmodule } from 'modules/liveIntentIdSystem'; -import * as utils from 'src/utils'; -import { server } from 'test/mocks/xhr'; +import { liveIntentIdSubmodule } from 'modules/liveIntentIdSystem.js'; +import * as utils from 'src/utils.js'; +import { server } from 'test/mocks/xhr.js'; describe('LiveIntentId', function() { let getCookieStub; diff --git a/test/spec/modules/livewrappedAnalyticsAdapter_spec.js b/test/spec/modules/livewrappedAnalyticsAdapter_spec.js index 2676de0de10..4e05d1a31ff 100644 --- a/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +++ b/test/spec/modules/livewrappedAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ -import livewrappedAnalyticsAdapter, { BID_WON_TIMEOUT } from 'modules/livewrappedAnalyticsAdapter'; +import livewrappedAnalyticsAdapter, { BID_WON_TIMEOUT } from 'modules/livewrappedAnalyticsAdapter.js'; import CONSTANTS from 'src/constants.json'; -import { config } from 'src/config'; -import { server } from 'test/mocks/xhr'; +import { config } from 'src/config.js'; +import { server } from 'test/mocks/xhr.js'; let events = require('src/events'); let utils = require('src/utils'); diff --git a/test/spec/modules/livewrappedBidAdapter_spec.js b/test/spec/modules/livewrappedBidAdapter_spec.js index 68ae22efa0d..a48c00b6890 100644 --- a/test/spec/modules/livewrappedBidAdapter_spec.js +++ b/test/spec/modules/livewrappedBidAdapter_spec.js @@ -1,8 +1,8 @@ import {expect} from 'chai'; -import {spec} from 'modules/livewrappedBidAdapter'; -import {config} from 'src/config'; -import * as utils from 'src/utils'; -import { BANNER, NATIVE } from 'src/mediaTypes'; +import {spec} from 'modules/livewrappedBidAdapter.js'; +import {config} from 'src/config.js'; +import * as utils from 'src/utils.js'; +import { BANNER, NATIVE } from 'src/mediaTypes.js'; describe('Livewrapped adapter tests', function () { let sandbox, diff --git a/test/spec/modules/liveyieldAnalyticsAdapter_spec.js b/test/spec/modules/liveyieldAnalyticsAdapter_spec.js index 36ade5ce67b..9ec4eaf9acd 100644 --- a/test/spec/modules/liveyieldAnalyticsAdapter_spec.js +++ b/test/spec/modules/liveyieldAnalyticsAdapter_spec.js @@ -1,5 +1,5 @@ import CONSTANTS from 'src/constants.json'; -import liveyield from 'modules/liveyieldAnalyticsAdapter'; +import liveyield from 'modules/liveyieldAnalyticsAdapter.js'; import { expect } from 'chai'; const events = require('src/events'); diff --git a/test/spec/modules/lkqdBidAdapter_spec.js b/test/spec/modules/lkqdBidAdapter_spec.js index e43ff9b2667..f10d936a28b 100644 --- a/test/spec/modules/lkqdBidAdapter_spec.js +++ b/test/spec/modules/lkqdBidAdapter_spec.js @@ -1,5 +1,5 @@ -import { spec } from 'modules/lkqdBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/lkqdBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const { expect } = require('chai'); describe('LKQD Bid Adapter Test', () => { diff --git a/test/spec/modules/lockerdomeBidAdapter_spec.js b/test/spec/modules/lockerdomeBidAdapter_spec.js index 895164c633c..42e3f52e533 100644 --- a/test/spec/modules/lockerdomeBidAdapter_spec.js +++ b/test/spec/modules/lockerdomeBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from '../../../modules/lockerdomeBidAdapter'; -import * as utils from 'src/utils'; +import { spec } from '../../../modules/lockerdomeBidAdapter.js'; +import * as utils from 'src/utils.js'; describe('LockerDomeAdapter', function () { const bidRequests = [{ diff --git a/test/spec/modules/logicadBidAdapter_spec.js b/test/spec/modules/logicadBidAdapter_spec.js index 1cae535aee0..eddcaecac7b 100644 --- a/test/spec/modules/logicadBidAdapter_spec.js +++ b/test/spec/modules/logicadBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from '../../../modules/logicadBidAdapter'; -import * as utils from 'src/utils'; +import {spec} from '../../../modules/logicadBidAdapter.js'; +import * as utils from 'src/utils.js'; describe('LogicadAdapter', function () { const bidRequests = [{ diff --git a/test/spec/modules/loopmeBidAdapter_spec.js b/test/spec/modules/loopmeBidAdapter_spec.js index 0d7e71c22db..a47bdfe47df 100644 --- a/test/spec/modules/loopmeBidAdapter_spec.js +++ b/test/spec/modules/loopmeBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from '../../../modules/loopmeBidAdapter'; -import * as utils from 'src/utils'; +import { spec } from '../../../modules/loopmeBidAdapter.js'; +import * as utils from 'src/utils.js'; describe('LoopMeAdapter', function () { const bidRequests = [{ diff --git a/test/spec/modules/madvertiseBidAdapter_spec.js b/test/spec/modules/madvertiseBidAdapter_spec.js index e10a192355a..041b49ef69e 100644 --- a/test/spec/modules/madvertiseBidAdapter_spec.js +++ b/test/spec/modules/madvertiseBidAdapter_spec.js @@ -1,7 +1,7 @@ import {expect} from 'chai'; -import {config} from 'src/config'; -import * as utils from 'src/utils'; -import {spec} from 'modules/madvertiseBidAdapter'; +import {config} from 'src/config.js'; +import * as utils from 'src/utils.js'; +import {spec} from 'modules/madvertiseBidAdapter.js'; describe('madvertise adapater', function () { describe('Test validate req', function () { diff --git a/test/spec/modules/mantisBidAdapter_spec.js b/test/spec/modules/mantisBidAdapter_spec.js index 7caa9b29f6f..1dad60f5d98 100644 --- a/test/spec/modules/mantisBidAdapter_spec.js +++ b/test/spec/modules/mantisBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/mantisBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {spec} from 'modules/mantisBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; describe('MantisAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/marsmediaBidAdapter_spec.js b/test/spec/modules/marsmediaBidAdapter_spec.js index 72329330713..553a3b19c55 100644 --- a/test/spec/modules/marsmediaBidAdapter_spec.js +++ b/test/spec/modules/marsmediaBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {spec} from '../../../modules/marsmediaBidAdapter'; -import * as utils from '../../../src/utils'; +import {spec} from '../../../modules/marsmediaBidAdapter.js'; +import * as utils from '../../../src/utils.js'; import * as sinon from 'sinon'; var r1adapter = spec; diff --git a/test/spec/modules/meazyBidAdapter_spec.js b/test/spec/modules/meazyBidAdapter_spec.js index 123d53f2fa1..2c24791f515 100644 --- a/test/spec/modules/meazyBidAdapter_spec.js +++ b/test/spec/modules/meazyBidAdapter_spec.js @@ -1,7 +1,7 @@ -import * as utils from 'src/utils'; +import * as utils from 'src/utils.js'; import { expect } from 'chai'; -import { spec } from 'modules/meazyBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/meazyBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const MEAZY_PID = '6910b7344ae566a1' const VALID_ENDPOINT = `https://rtb-filter.meazy.co/pbjs?host=${utils.getOrigin()}&api_key=${MEAZY_PID}`; diff --git a/test/spec/modules/medianetBidAdapter_spec.js b/test/spec/modules/medianetBidAdapter_spec.js index afe91ce3166..2b331f0e72e 100644 --- a/test/spec/modules/medianetBidAdapter_spec.js +++ b/test/spec/modules/medianetBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/medianetBidAdapter'; -import { config } from 'src/config'; +import {spec} from 'modules/medianetBidAdapter.js'; +import { config } from 'src/config.js'; let VALID_BID_REQUEST = [{ 'bidder': 'medianet', diff --git a/test/spec/modules/mgidBidAdapter_spec.js b/test/spec/modules/mgidBidAdapter_spec.js index fbf58254d39..b96d718ab36 100644 --- a/test/spec/modules/mgidBidAdapter_spec.js +++ b/test/spec/modules/mgidBidAdapter_spec.js @@ -1,7 +1,7 @@ import {assert, expect} from 'chai'; -import {spec} from 'modules/mgidBidAdapter'; -import * as utils from '../../../src/utils'; -import * as urlUtils from '../../../src/url'; +import {spec} from 'modules/mgidBidAdapter.js'; +import * as utils from '../../../src/utils.js'; +import * as urlUtils from '../../../src/url.js'; describe('Mgid bid adapter', function () { let sandbox; diff --git a/test/spec/modules/microadBidAdapter_spec.js b/test/spec/modules/microadBidAdapter_spec.js index b80a6938425..8298e2bd559 100644 --- a/test/spec/modules/microadBidAdapter_spec.js +++ b/test/spec/modules/microadBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/microadBidAdapter'; -import * as utils from 'src/utils'; +import { spec } from 'modules/microadBidAdapter.js'; +import * as utils from 'src/utils.js'; describe('microadBidAdapter', () => { const bidRequestTemplate = { diff --git a/test/spec/modules/mobsmartBidAdapter_spec.js b/test/spec/modules/mobsmartBidAdapter_spec.js index 7c1128276ab..b48878adff6 100644 --- a/test/spec/modules/mobsmartBidAdapter_spec.js +++ b/test/spec/modules/mobsmartBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/mobsmartBidAdapter'; +import { spec } from 'modules/mobsmartBidAdapter.js'; describe('mobsmartBidAdapter', function () { describe('isBidRequestValid', function () { diff --git a/test/spec/modules/my6senseBidAdapter_spec.js b/test/spec/modules/my6senseBidAdapter_spec.js index d2c875dad07..5e51280d70b 100644 --- a/test/spec/modules/my6senseBidAdapter_spec.js +++ b/test/spec/modules/my6senseBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/my6senseBidAdapter'; +import { spec } from 'modules/my6senseBidAdapter.js'; describe('My6sense Bid adapter test', function () { let bidRequests, serverResponses; diff --git a/test/spec/modules/mytargetBidAdapter_spec.js b/test/spec/modules/mytargetBidAdapter_spec.js index 01a94e76d60..ea998303fe3 100644 --- a/test/spec/modules/mytargetBidAdapter_spec.js +++ b/test/spec/modules/mytargetBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { config } from 'src/config'; -import { spec } from 'modules/mytargetBidAdapter'; +import { config } from 'src/config.js'; +import { spec } from 'modules/mytargetBidAdapter.js'; describe('MyTarget Adapter', function() { describe('isBidRequestValid', function () { diff --git a/test/spec/modules/nafdigitalBidAdapter_spec.js b/test/spec/modules/nafdigitalBidAdapter_spec.js index ca486c632c7..c8ffb9fbbaf 100644 --- a/test/spec/modules/nafdigitalBidAdapter_spec.js +++ b/test/spec/modules/nafdigitalBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import * as utils from 'src/utils'; -import { spec } from 'modules/nafdigitalBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import * as utils from 'src/utils.js'; +import { spec } from 'modules/nafdigitalBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const URL = 'https://nafdigitalbidder.com/hb'; diff --git a/test/spec/modules/nanointeractiveBidAdapter_spec.js b/test/spec/modules/nanointeractiveBidAdapter_spec.js index f999c2a4656..715a26a4597 100644 --- a/test/spec/modules/nanointeractiveBidAdapter_spec.js +++ b/test/spec/modules/nanointeractiveBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import * as utils from 'src/utils'; +import * as utils from 'src/utils.js'; import * as sinon from 'sinon'; import { @@ -13,7 +13,7 @@ import { REF, spec, SUB_ID -} from '../../../modules/nanointeractiveBidAdapter'; +} from '../../../modules/nanointeractiveBidAdapter.js'; describe('nanointeractive adapter tests', function () { const SIZES_PARAM = 'sizes'; diff --git a/test/spec/modules/nasmediaAdmixerBidAdapter_spec.js b/test/spec/modules/nasmediaAdmixerBidAdapter_spec.js index 969c819ebef..4731b1a77d3 100644 --- a/test/spec/modules/nasmediaAdmixerBidAdapter_spec.js +++ b/test/spec/modules/nasmediaAdmixerBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/nasmediaAdmixerBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {spec} from 'modules/nasmediaAdmixerBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; describe('nasmediaAdmixerBidAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/newborntownWebBidAdapter_spec.js b/test/spec/modules/newborntownWebBidAdapter_spec.js index d7cf4a7dd95..84937d00012 100644 --- a/test/spec/modules/newborntownWebBidAdapter_spec.js +++ b/test/spec/modules/newborntownWebBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import {spec} from 'modules/newborntownWebBidAdapter'; +import {spec} from 'modules/newborntownWebBidAdapter.js'; describe('NewborntownWebAdapter', function() { describe('isBidRequestValid', function () { let bid = { diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index 087f06d7e8e..f4d929b439c 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/nextMillenniumBidAdapter'; +import { spec } from 'modules/nextMillenniumBidAdapter.js'; describe('nextMillenniumBidAdapterTests', function() { let bidRequestData = { diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js index f86ec0ce22e..0005f35523e 100644 --- a/test/spec/modules/nobidBidAdapter_spec.js +++ b/test/spec/modules/nobidBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import * as utils from 'src/utils'; -import { spec } from 'modules/nobidBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import * as utils from 'src/utils.js'; +import { spec } from 'modules/nobidBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('Nobid Adapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js index 623fbeaf90d..fc7c29c7b51 100644 --- a/test/spec/modules/oneVideoBidAdapter_spec.js +++ b/test/spec/modules/oneVideoBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec } from 'modules/oneVideoBidAdapter'; -import * as utils from 'src/utils'; -import {config} from 'src/config'; +import { spec } from 'modules/oneVideoBidAdapter.js'; +import * as utils from 'src/utils.js'; +import {config} from 'src/config.js'; describe('OneVideoBidAdapter', function () { let bidRequest; diff --git a/test/spec/modules/onetagBidAdapter_spec.js b/test/spec/modules/onetagBidAdapter_spec.js index 9a6a8697651..aeea84836bf 100644 --- a/test/spec/modules/onetagBidAdapter_spec.js +++ b/test/spec/modules/onetagBidAdapter_spec.js @@ -1,4 +1,4 @@ -import { spec } from 'modules/onetagBidAdapter'; +import { spec } from 'modules/onetagBidAdapter.js'; import { expect } from 'chai'; describe('onetag', function () { diff --git a/test/spec/modules/open8BidAdapter_spec.js b/test/spec/modules/open8BidAdapter_spec.js index 7ef1c38abb2..506742bef9e 100644 --- a/test/spec/modules/open8BidAdapter_spec.js +++ b/test/spec/modules/open8BidAdapter_spec.js @@ -1,5 +1,5 @@ -import { spec } from 'modules/open8BidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/open8BidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const ENDPOINT = 'https://as.vt.open8.com/v1/control/prebid'; diff --git a/test/spec/modules/openxAnalyticsAdapter_spec.js b/test/spec/modules/openxAnalyticsAdapter_spec.js index 1020b89d3b7..805435abf80 100644 --- a/test/spec/modules/openxAnalyticsAdapter_spec.js +++ b/test/spec/modules/openxAnalyticsAdapter_spec.js @@ -1,10 +1,10 @@ import { expect } from 'chai'; -import openxAdapter from 'modules/openxAnalyticsAdapter'; -import { config } from 'src/config'; -import events from 'src/events'; +import openxAdapter from 'modules/openxAnalyticsAdapter.js'; +import { config } from 'src/config.js'; +import events from 'src/events.js'; import CONSTANTS from 'src/constants.json'; -import * as utils from 'src/utils'; -import { server } from 'test/mocks/xhr'; +import * as utils from 'src/utils.js'; +import { server } from 'test/mocks/xhr.js'; const { EVENTS: { AUCTION_INIT, BID_REQUESTED, BID_RESPONSE, BID_TIMEOUT, BID_WON } diff --git a/test/spec/modules/openxBidAdapter_spec.js b/test/spec/modules/openxBidAdapter_spec.js index 38046409211..9d6359e712a 100644 --- a/test/spec/modules/openxBidAdapter_spec.js +++ b/test/spec/modules/openxBidAdapter_spec.js @@ -1,9 +1,9 @@ import {expect} from 'chai'; -import {spec, resetBoPixel} from 'modules/openxBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; -import {userSync} from 'src/userSync'; -import {config} from 'src/config'; -import * as utils from 'src/utils'; +import {spec, resetBoPixel} from 'modules/openxBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; +import {userSync} from 'src/userSync.js'; +import {config} from 'src/config.js'; +import * as utils from 'src/utils.js'; const URLBASE = '/w/1.0/arj'; const URLBASEVIDEO = '/v/1.0/avjp'; diff --git a/test/spec/modules/optimeraBidAdapter_spec.js b/test/spec/modules/optimeraBidAdapter_spec.js index a0111ca9944..ada07fe25c2 100644 --- a/test/spec/modules/optimeraBidAdapter_spec.js +++ b/test/spec/modules/optimeraBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/optimeraBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/optimeraBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('OptimeraAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/orbidderBidAdapter_spec.js b/test/spec/modules/orbidderBidAdapter_spec.js index 9e7d10d7b04..7e07c47ba95 100644 --- a/test/spec/modules/orbidderBidAdapter_spec.js +++ b/test/spec/modules/orbidderBidAdapter_spec.js @@ -1,8 +1,8 @@ import {expect} from 'chai'; -import {spec} from 'modules/orbidderBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; -import openxAdapter from '../../../modules/openxAnalyticsAdapter'; -import {detectReferer} from 'src/refererDetection'; +import {spec} from 'modules/orbidderBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; +import openxAdapter from '../../../modules/openxAnalyticsAdapter.js'; +import {detectReferer} from 'src/refererDetection.js'; describe('orbidderBidAdapter', () => { const adapter = newBidder(spec); diff --git a/test/spec/modules/otmBidAdapter_spec.js b/test/spec/modules/otmBidAdapter_spec.js index f3a98d43e57..8ac01c1657e 100644 --- a/test/spec/modules/otmBidAdapter_spec.js +++ b/test/spec/modules/otmBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from 'modules/otmBidAdapter'; +import {spec} from 'modules/otmBidAdapter.js'; describe('otmBidAdapterTests', function () { it('validate_pub_params', function () { diff --git a/test/spec/modules/outconBidAdapter_spec.js b/test/spec/modules/outconBidAdapter_spec.js index d9e763b9df9..81c3fdded62 100644 --- a/test/spec/modules/outconBidAdapter_spec.js +++ b/test/spec/modules/outconBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from '../../../modules/outconBidAdapter'; +import { spec } from '../../../modules/outconBidAdapter.js'; describe('outconBidAdapter', function () { describe('bidRequestValidity', function () { diff --git a/test/spec/modules/ozoneBidAdapter_spec.js b/test/spec/modules/ozoneBidAdapter_spec.js index 7d7d658351f..05ed217fb31 100644 --- a/test/spec/modules/ozoneBidAdapter_spec.js +++ b/test/spec/modules/ozoneBidAdapter_spec.js @@ -1,9 +1,9 @@ import { expect } from 'chai'; -import { spec, getWidthAndHeightFromVideoObject, playerSizeIsNestedArray, defaultSize } from 'modules/ozoneBidAdapter'; -import { config } from 'src/config'; -import {Renderer} from '../../../src/Renderer'; -import {getGranularityKeyName, getGranularityObject} from '../../../modules/ozoneBidAdapter'; -import * as utils from '../../../src/utils'; +import { spec, getWidthAndHeightFromVideoObject, playerSizeIsNestedArray, defaultSize } from 'modules/ozoneBidAdapter.js'; +import { config } from 'src/config.js'; +import {Renderer} from '../../../src/Renderer.js'; +import {getGranularityKeyName, getGranularityObject} from '../../../modules/ozoneBidAdapter.js'; +import * as utils from '../../../src/utils.js'; const OZONEURI = 'https://elb.the-ozone-project.com/openrtb2/auction'; const BIDDER_CODE = 'ozone'; /* diff --git a/test/spec/modules/padsquadBidAdapter_spec.js b/test/spec/modules/padsquadBidAdapter_spec.js index 88c9680c888..d30b1f34a9e 100644 --- a/test/spec/modules/padsquadBidAdapter_spec.js +++ b/test/spec/modules/padsquadBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from 'modules/padsquadBidAdapter'; +import {spec} from 'modules/padsquadBidAdapter.js'; const REQUEST = { 'bidderCode': 'padsquad', diff --git a/test/spec/modules/papyrusBidAdapter_spec.js b/test/spec/modules/papyrusBidAdapter_spec.js index f3c6f42f5b2..20fcced2950 100644 --- a/test/spec/modules/papyrusBidAdapter_spec.js +++ b/test/spec/modules/papyrusBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/papyrusBidAdapter'; +import { spec } from 'modules/papyrusBidAdapter.js'; const ENDPOINT = 'https://prebid.papyrus.global'; const BIDDER_CODE = 'papyrus'; diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js index 540e63aa630..936b4c3a824 100644 --- a/test/spec/modules/parrableIdSystem_spec.js +++ b/test/spec/modules/parrableIdSystem_spec.js @@ -1,8 +1,8 @@ import { expect } from 'chai'; -import {config} from 'src/config'; -import * as utils from 'src/utils'; +import {config} from 'src/config.js'; +import * as utils from 'src/utils.js'; import { init, requestBidsHook, setSubmoduleRegistry } from 'modules/userId/index.js'; -import { parrableIdSubmodule } from 'modules/parrableIdSystem'; +import { parrableIdSubmodule } from 'modules/parrableIdSystem.js'; const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; const P_COOKIE_NAME = '_parrable_eid'; diff --git a/test/spec/modules/piximediaBidAdapter_spec.js b/test/spec/modules/piximediaBidAdapter_spec.js index 95e03734345..88a6433b71d 100644 --- a/test/spec/modules/piximediaBidAdapter_spec.js +++ b/test/spec/modules/piximediaBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/piximediaBidAdapter'; +import { spec } from 'modules/piximediaBidAdapter.js'; describe('piximediaAdapterTest', function() { describe('bidRequestValidity', function() { diff --git a/test/spec/modules/playgroundxyzBidAdapter_spec.js b/test/spec/modules/playgroundxyzBidAdapter_spec.js index 7b89a4a160c..fd90d7e9992 100644 --- a/test/spec/modules/playgroundxyzBidAdapter_spec.js +++ b/test/spec/modules/playgroundxyzBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec } from 'modules/playgroundxyzBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import { deepClone } from 'src/utils'; +import { spec } from 'modules/playgroundxyzBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { deepClone } from 'src/utils.js'; const URL = 'https://ads.playground.xyz/host-config/prebid?v=2'; const GDPR_CONSENT = 'XYZ-CONSENT'; diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index bc655c6e432..43592d501a9 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -1,12 +1,12 @@ import { expect } from 'chai'; import { PrebidServer as Adapter, resetSyncedStatus } from 'modules/prebidServerBidAdapter/index.js'; -import adapterManager from 'src/adapterManager'; -import * as utils from 'src/utils'; -import { ajax } from 'src/ajax'; -import { config } from 'src/config'; -import events from 'src/events'; -import CONSTANTS from 'src/constants'; -import { server } from 'test/mocks/xhr'; +import adapterManager from 'src/adapterManager.js'; +import * as utils from 'src/utils.js'; +import { ajax } from 'src/ajax.js'; +import { config } from 'src/config.js'; +import events from 'src/events.js'; +import CONSTANTS from 'src/constants.json'; +import { server } from 'test/mocks/xhr.js'; let CONFIG = { accountId: '1', diff --git a/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js b/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js index fcff6837ece..7c9173c14ab 100644 --- a/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js +++ b/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js @@ -1,6 +1,6 @@ -import prebidmanagerAnalytics from 'modules/prebidmanagerAnalyticsAdapter'; +import prebidmanagerAnalytics from 'modules/prebidmanagerAnalyticsAdapter.js'; import {expect} from 'chai'; -import {server} from 'test/mocks/xhr'; +import {server} from 'test/mocks/xhr.js'; let events = require('src/events'); let constants = require('src/constants.json'); diff --git a/test/spec/modules/projectLimeLightBidAdapter_spec.js b/test/spec/modules/projectLimeLightBidAdapter_spec.js index f51e1188b73..3ffc017f177 100644 --- a/test/spec/modules/projectLimeLightBidAdapter_spec.js +++ b/test/spec/modules/projectLimeLightBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from '../../../modules/projectLimeLightBidAdapter'; +import {spec} from '../../../modules/projectLimeLightBidAdapter.js'; describe('ProjectLimeLightAdapter', function () { let bid = { diff --git a/test/spec/modules/pubCommonId_spec.js b/test/spec/modules/pubCommonId_spec.js index fd2bff5bac6..ab0ef2adc51 100644 --- a/test/spec/modules/pubCommonId_spec.js +++ b/test/spec/modules/pubCommonId_spec.js @@ -9,11 +9,11 @@ import { setStorageItem, getStorageItem, removeStorageItem, - getPubcidConfig } from 'modules/pubCommonId'; -import { getAdUnits } from 'test/fixtures/fixtures'; -import * as auctionModule from 'src/auction'; -import { registerBidder } from 'src/adapters/bidderFactory'; -import * as utils from 'src/utils'; + getPubcidConfig } from 'modules/pubCommonId.js'; +import { getAdUnits } from 'test/fixtures/fixtures.js'; +import * as auctionModule from 'src/auction.js'; +import { registerBidder } from 'src/adapters/bidderFactory.js'; +import * as utils from 'src/utils.js'; let events = require('src/events'); let constants = require('src/constants.json'); diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 902f8b1fd73..b54bcc15bc3 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -1,7 +1,7 @@ import {expect} from 'chai'; -import {spec} from 'modules/pubmaticBidAdapter'; -import * as utils from 'src/utils'; -import {config} from 'src/config'; +import {spec} from 'modules/pubmaticBidAdapter.js'; +import * as utils from 'src/utils.js'; +import {config} from 'src/config.js'; const constants = require('src/constants.json'); describe('PubMatic adapter', function () { diff --git a/test/spec/modules/pubwiseAnalyticsAdapter_spec.js b/test/spec/modules/pubwiseAnalyticsAdapter_spec.js index b2235212cbf..5e4b2be894e 100644 --- a/test/spec/modules/pubwiseAnalyticsAdapter_spec.js +++ b/test/spec/modules/pubwiseAnalyticsAdapter_spec.js @@ -1,4 +1,4 @@ -import pubwiseAnalytics from 'modules/pubwiseAnalyticsAdapter'; +import pubwiseAnalytics from 'modules/pubwiseAnalyticsAdapter.js'; let events = require('src/events'); let adapterManager = require('src/adapterManager').default; let constants = require('src/constants.json'); diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js index 80cf00d2ff8..ea81aa5d962 100644 --- a/test/spec/modules/pulsepointBidAdapter_spec.js +++ b/test/spec/modules/pulsepointBidAdapter_spec.js @@ -1,7 +1,7 @@ /* eslint dot-notation:0, quote-props:0 */ import {expect} from 'chai'; -import {spec} from 'modules/pulsepointBidAdapter'; -import {deepClone} from 'src/utils'; +import {spec} from 'modules/pulsepointBidAdapter.js'; +import {deepClone} from 'src/utils.js'; describe('PulsePoint Adapter Tests', function () { const slotConfigs = [{ diff --git a/test/spec/modules/quantcastBidAdapter_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js index 7e7d47d3644..19d53674793 100644 --- a/test/spec/modules/quantcastBidAdapter_spec.js +++ b/test/spec/modules/quantcastBidAdapter_spec.js @@ -8,9 +8,9 @@ import { QUANTCAST_PROTOCOL, QUANTCAST_PORT, spec as qcSpec -} from '../../../modules/quantcastBidAdapter'; -import { newBidder } from '../../../src/adapters/bidderFactory'; -import { parse } from 'src/url'; +} from '../../../modules/quantcastBidAdapter.js'; +import { newBidder } from '../../../src/adapters/bidderFactory.js'; +import { parse } from 'src/url.js'; describe('Quantcast adapter', function () { const quantcastAdapter = newBidder(qcSpec); diff --git a/test/spec/modules/quantumBidAdapter_spec.js b/test/spec/modules/quantumBidAdapter_spec.js index ba020fbc536..c03d74ea52e 100644 --- a/test/spec/modules/quantumBidAdapter_spec.js +++ b/test/spec/modules/quantumBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai' -import { spec } from 'modules/quantumBidAdapter' -import { newBidder } from 'src/adapters/bidderFactory' +import { spec } from 'modules/quantumBidAdapter.js' +import { newBidder } from 'src/adapters/bidderFactory.js' const ENDPOINT = 'https://s.sspqns.com/hb' const REQUEST = { diff --git a/test/spec/modules/radsBidAdapter_spec.js b/test/spec/modules/radsBidAdapter_spec.js index 6981955f261..c629daf3da5 100644 --- a/test/spec/modules/radsBidAdapter_spec.js +++ b/test/spec/modules/radsBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/radsBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/radsBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const RADS_ENDPOINT_URL = 'https://rads.recognified.net/md.request.php'; diff --git a/test/spec/modules/readpeakBidAdapter_spec.js b/test/spec/modules/readpeakBidAdapter_spec.js index 06971169e2a..a0cff8a3464 100644 --- a/test/spec/modules/readpeakBidAdapter_spec.js +++ b/test/spec/modules/readpeakBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec, ENDPOINT } from 'modules/readpeakBidAdapter'; -import { config } from 'src/config'; -import { parse as parseUrl } from 'src/url'; +import { spec, ENDPOINT } from 'modules/readpeakBidAdapter.js'; +import { config } from 'src/config.js'; +import { parse as parseUrl } from 'src/url.js'; describe('ReadPeakAdapter', function() { let bidRequest; diff --git a/test/spec/modules/realTimeModule_spec.js b/test/spec/modules/realTimeModule_spec.js index ae83e83e10f..bf25b3f0a04 100644 --- a/test/spec/modules/realTimeModule_spec.js +++ b/test/spec/modules/realTimeModule_spec.js @@ -3,15 +3,15 @@ import { requestBidsHook, setTargetsAfterRequestBids, deepMerge -} from 'modules/rtdModule/index'; +} from 'modules/rtdModule/index.js'; import { init as browsiInit, addBrowsiTag, isIdMatchingAdUnit, setData -} from 'modules/browsiRtdProvider'; -import {config} from 'src/config'; -import {makeSlot} from '../integration/faker/googletag'; +} from 'modules/browsiRtdProvider.js'; +import {config} from 'src/config.js'; +import {makeSlot} from '../integration/faker/googletag.js'; let expect = require('chai').expect; diff --git a/test/spec/modules/realvuAnalyticsAdapter_spec.js b/test/spec/modules/realvuAnalyticsAdapter_spec.js index 359fb329359..d499743e8b4 100644 --- a/test/spec/modules/realvuAnalyticsAdapter_spec.js +++ b/test/spec/modules/realvuAnalyticsAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import realvuAnalyticsAdapter, { lib } from 'modules/realvuAnalyticsAdapter'; +import realvuAnalyticsAdapter, { lib } from 'modules/realvuAnalyticsAdapter.js'; import CONSTANTS from 'src/constants.json'; function addDiv(id) { diff --git a/test/spec/modules/reklamstoreBidAdapter_spec.js b/test/spec/modules/reklamstoreBidAdapter_spec.js index 92f309fd54f..1dcd6c17ca4 100644 --- a/test/spec/modules/reklamstoreBidAdapter_spec.js +++ b/test/spec/modules/reklamstoreBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/reklamstoreBidAdapter'; +import { spec } from 'modules/reklamstoreBidAdapter.js'; describe('reklamstoreBidAdapterTests', function() { let bidRequestData = { diff --git a/test/spec/modules/reloadBidAdapter_spec.js b/test/spec/modules/reloadBidAdapter_spec.js index 674c810d48a..b22dd9e7b92 100644 --- a/test/spec/modules/reloadBidAdapter_spec.js +++ b/test/spec/modules/reloadBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/reloadBidAdapter'; +import { spec } from 'modules/reloadBidAdapter.js'; let getParams = () => { return JSON.parse(JSON.stringify({ diff --git a/test/spec/modules/resultsmediaBidAdapter_spec.js b/test/spec/modules/resultsmediaBidAdapter_spec.js index e06da25ebf2..0e2d4c0013a 100644 --- a/test/spec/modules/resultsmediaBidAdapter_spec.js +++ b/test/spec/modules/resultsmediaBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {spec} from '../../../modules/resultsmediaBidAdapter'; -import * as utils from '../../../src/utils'; +import {spec} from '../../../modules/resultsmediaBidAdapter.js'; +import * as utils from '../../../src/utils.js'; import * as sinon from 'sinon'; var r1adapter = spec; diff --git a/test/spec/modules/revcontentBidAdapter_spec.js b/test/spec/modules/revcontentBidAdapter_spec.js index 7ae508ce97e..548f3019a4f 100644 --- a/test/spec/modules/revcontentBidAdapter_spec.js +++ b/test/spec/modules/revcontentBidAdapter_spec.js @@ -1,9 +1,9 @@ // jshint esversion: 6, es3: false, node: true import {assert, expect} from 'chai'; -import * as url from 'src/url'; -import {spec} from 'modules/revcontentBidAdapter'; -import { NATIVE } from 'src/mediaTypes'; -import { config } from 'src/config'; +import * as url from 'src/url.js'; +import {spec} from 'modules/revcontentBidAdapter.js'; +import { NATIVE } from 'src/mediaTypes.js'; +import { config } from 'src/config.js'; describe('revcontent adapter', function () { let serverResponse, bidRequest, bidResponses; diff --git a/test/spec/modules/rhythmoneBidAdapter_spec.js b/test/spec/modules/rhythmoneBidAdapter_spec.js index 80cbdb4a0af..d9342332e61 100644 --- a/test/spec/modules/rhythmoneBidAdapter_spec.js +++ b/test/spec/modules/rhythmoneBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {spec} from '../../../modules/rhythmoneBidAdapter'; -import * as utils from '../../../src/utils'; +import {spec} from '../../../modules/rhythmoneBidAdapter.js'; +import * as utils from '../../../src/utils.js'; import * as sinon from 'sinon'; var r1adapter = spec; diff --git a/test/spec/modules/richaudienceBidAdapter_spec.js b/test/spec/modules/richaudienceBidAdapter_spec.js index 0508e4c1cce..ad1f5e9cc5f 100644 --- a/test/spec/modules/richaudienceBidAdapter_spec.js +++ b/test/spec/modules/richaudienceBidAdapter_spec.js @@ -2,9 +2,9 @@ import {expect} from 'chai'; // may prefer 'assert' in place of 'expect' import { spec -} from 'modules/richaudienceBidAdapter'; -import {config} from 'src/config'; -import * as utils from 'src/utils'; +} from 'modules/richaudienceBidAdapter.js'; +import {config} from 'src/config.js'; +import * as utils from 'src/utils.js'; describe('Richaudience adapter tests', function () { var DEFAULT_PARAMS = [{ diff --git a/test/spec/modules/rivrAnalyticsAdapter_spec.js b/test/spec/modules/rivrAnalyticsAdapter_spec.js index 2676c3a59b6..9add7ed5f7d 100644 --- a/test/spec/modules/rivrAnalyticsAdapter_spec.js +++ b/test/spec/modules/rivrAnalyticsAdapter_spec.js @@ -1,5 +1,5 @@ -import * as utils from 'src/utils'; -import analyticsAdapter from 'modules/rivrAnalyticsAdapter'; +import * as utils from 'src/utils.js'; +import analyticsAdapter from 'modules/rivrAnalyticsAdapter.js'; import { sendImpressions, handleClickEventWithClosureScope, @@ -15,10 +15,10 @@ import { storeAndReturnRivrUsrIdCookie, arrayDifference, activelyWaitForBannersToRender, -} from 'modules/rivrAnalyticsAdapter'; +} from 'modules/rivrAnalyticsAdapter.js'; import {expect} from 'chai'; -import adapterManager from 'src/adapterManager'; -import * as ajax from 'src/ajax'; +import adapterManager from 'src/adapterManager.js'; +import * as ajax from 'src/ajax.js'; import CONSTANTS from 'src/constants.json'; const events = require('../../../src/events'); diff --git a/test/spec/modules/roxotAnalyticsAdapter_spec.js b/test/spec/modules/roxotAnalyticsAdapter_spec.js index 1ad6ba2e86a..79c58e36735 100644 --- a/test/spec/modules/roxotAnalyticsAdapter_spec.js +++ b/test/spec/modules/roxotAnalyticsAdapter_spec.js @@ -1,6 +1,6 @@ -import roxotAnalytic from 'modules/roxotAnalyticsAdapter'; +import roxotAnalytic from 'modules/roxotAnalyticsAdapter.js'; import {expect} from 'chai'; -import {server} from 'test/mocks/xhr'; +import {server} from 'test/mocks/xhr.js'; let events = require('src/events'); let constants = require('src/constants.json'); diff --git a/test/spec/modules/rtbdemandBidAdapter_spec.js b/test/spec/modules/rtbdemandBidAdapter_spec.js index 6b5ef215162..be9872ec01b 100644 --- a/test/spec/modules/rtbdemandBidAdapter_spec.js +++ b/test/spec/modules/rtbdemandBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/rtbdemandBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/rtbdemandBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('rtbdemandAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/rtbhouseBidAdapter_spec.js b/test/spec/modules/rtbhouseBidAdapter_spec.js index 6c6faf4e4d0..93b9692d2e2 100644 --- a/test/spec/modules/rtbhouseBidAdapter_spec.js +++ b/test/spec/modules/rtbhouseBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { OPENRTB, spec } from 'modules/rtbhouseBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { OPENRTB, spec } from 'modules/rtbhouseBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('RTBHouseAdapter', () => { const adapter = newBidder(spec); diff --git a/test/spec/modules/rtbsolutionsBidAdapter_spec.js b/test/spec/modules/rtbsolutionsBidAdapter_spec.js index a9ffcd2ce4b..c47b086fe50 100644 --- a/test/spec/modules/rtbsolutionsBidAdapter_spec.js +++ b/test/spec/modules/rtbsolutionsBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/rtbsolutionsBidAdapter'; +import { spec } from 'modules/rtbsolutionsBidAdapter.js'; describe('rtbsolutionsBidAdapterTests', function () { it('validate_pub_params_1', function () { diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js index 6a652a6ab86..6c99b6a6b00 100644 --- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js +++ b/test/spec/modules/rubiconAnalyticsAdapter_spec.js @@ -1,12 +1,12 @@ -import rubiconAnalyticsAdapter, { SEND_TIMEOUT, parseBidResponse } from 'modules/rubiconAnalyticsAdapter'; +import rubiconAnalyticsAdapter, { SEND_TIMEOUT, parseBidResponse } from 'modules/rubiconAnalyticsAdapter.js'; import CONSTANTS from 'src/constants.json'; -import { config } from 'src/config'; -import { server } from 'test/mocks/xhr'; +import { config } from 'src/config.js'; +import { server } from 'test/mocks/xhr.js'; import { setConfig, addBidResponseHook, -} from 'modules/currency'; +} from 'modules/currency.js'; let Ajv = require('ajv'); let schema = require('./rubiconAnalyticsSchema.json'); @@ -21,7 +21,7 @@ function validate(message) { expect(validator.errors).to.deep.equal(null); } -// using es6 "import * as events from 'src/events'" causes the events.getEvents stub not to work... +// using es6 "import * as events from 'src/events.js'" causes the events.getEvents stub not to work... let events = require('src/events'); let ajax = require('src/ajax'); let utils = require('src/utils'); diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 66f1dd0a989..42348036bfe 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -1,12 +1,12 @@ import {expect} from 'chai'; -import adapterManager from 'src/adapterManager'; -import {spec, getPriceGranularity, masSizeOrdering, resetUserSync, hasVideoMediaType, FASTLANE_ENDPOINT} from 'modules/rubiconBidAdapter'; +import adapterManager from 'src/adapterManager.js'; +import {spec, getPriceGranularity, masSizeOrdering, resetUserSync, hasVideoMediaType, FASTLANE_ENDPOINT} from 'modules/rubiconBidAdapter.js'; import {parse as parseQuery} from 'querystring'; -import {newBidder} from 'src/adapters/bidderFactory'; -import {userSync} from 'src/userSync'; -import {config} from 'src/config'; -import * as utils from 'src/utils'; -import find from 'core-js/library/fn/array/find'; +import {newBidder} from 'src/adapters/bidderFactory.js'; +import {userSync} from 'src/userSync.js'; +import {config} from 'src/config.js'; +import * as utils from 'src/utils.js'; +import find from 'core-js/library/fn/array/find.js'; var CONSTANTS = require('src/constants.json'); diff --git a/test/spec/modules/s2sTesting_spec.js b/test/spec/modules/s2sTesting_spec.js index 52377dcabf2..5c7f3004dee 100644 --- a/test/spec/modules/s2sTesting_spec.js +++ b/test/spec/modules/s2sTesting_spec.js @@ -1,5 +1,5 @@ -import s2sTesting from 'modules/s2sTesting'; -import { config } from 'src/config'; +import s2sTesting from 'modules/s2sTesting.js'; +import { config } from 'src/config.js'; var expect = require('chai').expect; diff --git a/test/spec/modules/scaleableAnalyticsAdapter_spec.js b/test/spec/modules/scaleableAnalyticsAdapter_spec.js index 7ee1a7b1e96..70b94a2b807 100644 --- a/test/spec/modules/scaleableAnalyticsAdapter_spec.js +++ b/test/spec/modules/scaleableAnalyticsAdapter_spec.js @@ -1,8 +1,8 @@ -import scaleableAnalytics from 'modules/scaleableAnalyticsAdapter'; +import scaleableAnalytics from 'modules/scaleableAnalyticsAdapter.js'; import { expect } from 'chai'; -import events from 'src/events'; +import events from 'src/events.js'; import CONSTANTS from 'src/constants.json'; -import { server } from 'test/mocks/xhr'; +import { server } from 'test/mocks/xhr.js'; const BID_TIMEOUT = CONSTANTS.EVENTS.BID_TIMEOUT; const AUCTION_INIT = CONSTANTS.EVENTS.AUCTION_INIT; diff --git a/test/spec/modules/schain_spec.js b/test/spec/modules/schain_spec.js index 6e8d6839efe..34d0cff9a60 100644 --- a/test/spec/modules/schain_spec.js +++ b/test/spec/modules/schain_spec.js @@ -1,6 +1,6 @@ -import { isValidSchainConfig, isSchainObjectValid, makeBidRequestsHook } from '../../../modules/schain'; -import { deepClone } from '../../../src/utils'; -import {config} from '../../../src/config'; +import { isValidSchainConfig, isSchainObjectValid, makeBidRequestsHook } from '../../../modules/schain.js'; +import { deepClone } from '../../../src/utils.js'; +import {config} from '../../../src/config.js'; import { expect } from 'chai'; describe('#isValidSchainConfig: module config validation', function() { diff --git a/test/spec/modules/seedingAllianceAdapter_spec.js b/test/spec/modules/seedingAllianceAdapter_spec.js index f4c833b41a8..c5c2a5d682e 100755 --- a/test/spec/modules/seedingAllianceAdapter_spec.js +++ b/test/spec/modules/seedingAllianceAdapter_spec.js @@ -1,9 +1,9 @@ // jshint esversion: 6, es3: false, node: true import {assert, expect} from 'chai'; -import * as url from 'src/url'; -import {spec} from 'modules/seedingAllianceBidAdapter'; -import { NATIVE } from 'src/mediaTypes'; -import { config } from 'src/config'; +import * as url from 'src/url.js'; +import {spec} from 'modules/seedingAllianceBidAdapter.js'; +import { NATIVE } from 'src/mediaTypes.js'; +import { config } from 'src/config.js'; describe('SeedingAlliance adapter', function () { let serverResponse, bidRequest, bidResponses; diff --git a/test/spec/modules/seedtagBidAdapter_spec.js b/test/spec/modules/seedtagBidAdapter_spec.js index 4bd4b599c55..5c8c58196f7 100644 --- a/test/spec/modules/seedtagBidAdapter_spec.js +++ b/test/spec/modules/seedtagBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai' -import { spec, getTimeoutUrl } from 'modules/seedtagBidAdapter' +import { spec, getTimeoutUrl } from 'modules/seedtagBidAdapter.js' function getSlotConfigs(mediaTypes, params) { return { diff --git a/test/spec/modules/segmentoBidAdapter_spec.js b/test/spec/modules/segmentoBidAdapter_spec.js index 96f356b0ee2..17ad424f73f 100644 --- a/test/spec/modules/segmentoBidAdapter_spec.js +++ b/test/spec/modules/segmentoBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from '../../../modules/segmentoBidAdapter'; +import { spec } from '../../../modules/segmentoBidAdapter.js'; const BIDDER_CODE = 'segmento'; const URL = 'https://prebid-bidder.rutarget.ru/bid'; diff --git a/test/spec/modules/sekindoUMBidAdapter_spec.js b/test/spec/modules/sekindoUMBidAdapter_spec.js index 2718d26b2b4..2c361c21303 100644 --- a/test/spec/modules/sekindoUMBidAdapter_spec.js +++ b/test/spec/modules/sekindoUMBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/sekindoUMBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/sekindoUMBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('sekindoUMAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/shareUserIds_spec.js b/test/spec/modules/shareUserIds_spec.js index 4ae5f93a1a6..18f45e405f5 100644 --- a/test/spec/modules/shareUserIds_spec.js +++ b/test/spec/modules/shareUserIds_spec.js @@ -1,4 +1,4 @@ -import {userIdTargeting} from '../../../modules/userIdTargeting'; +import {userIdTargeting} from '../../../modules/userIdTargeting.js'; import { expect } from 'chai'; describe('#userIdTargeting', function() { diff --git a/test/spec/modules/sharethroughBidAdapter_spec.js b/test/spec/modules/sharethroughBidAdapter_spec.js index 1dbd0abb169..0ddb113e062 100644 --- a/test/spec/modules/sharethroughBidAdapter_spec.js +++ b/test/spec/modules/sharethroughBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { sharethroughAdapterSpec, sharethroughInternal } from 'modules/sharethroughBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { sharethroughAdapterSpec, sharethroughInternal } from 'modules/sharethroughBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const spec = newBidder(sharethroughAdapterSpec).getSpec(); const bidRequests = [ diff --git a/test/spec/modules/showheroes-bsBidAdapter_spec.js b/test/spec/modules/showheroes-bsBidAdapter_spec.js index 37df0790f4e..c82042469ef 100644 --- a/test/spec/modules/showheroes-bsBidAdapter_spec.js +++ b/test/spec/modules/showheroes-bsBidAdapter_spec.js @@ -1,7 +1,7 @@ import {expect} from 'chai' -import {spec} from 'modules/showheroes-bsBidAdapter' -import {newBidder} from 'src/adapters/bidderFactory' -import {VIDEO, BANNER} from 'src/mediaTypes' +import {spec} from 'modules/showheroes-bsBidAdapter.js' +import {newBidder} from 'src/adapters/bidderFactory.js' +import {VIDEO, BANNER} from 'src/mediaTypes.js' const bidderRequest = { refererInfo: { diff --git a/test/spec/modules/sigmoidAnalyticsAdapter_spec.js b/test/spec/modules/sigmoidAnalyticsAdapter_spec.js index c07d35ae68f..75afb0ed86e 100644 --- a/test/spec/modules/sigmoidAnalyticsAdapter_spec.js +++ b/test/spec/modules/sigmoidAnalyticsAdapter_spec.js @@ -1,4 +1,4 @@ -import sigmoidAnalytic from 'modules/sigmoidAnalyticsAdapter'; +import sigmoidAnalytic from 'modules/sigmoidAnalyticsAdapter.js'; import { expect } from 'chai'; let events = require('src/events'); let adapterManager = require('src/adapterManager').default; diff --git a/test/spec/modules/slimcutBidAdapter_spec.js b/test/spec/modules/slimcutBidAdapter_spec.js index ecbb926cdd1..44da1d87824 100644 --- a/test/spec/modules/slimcutBidAdapter_spec.js +++ b/test/spec/modules/slimcutBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/slimcutBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {spec} from 'modules/slimcutBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; const ENDPOINT = 'https://sb.freeskreen.com/pbr'; const AD_SCRIPT = '"'; diff --git a/test/spec/modules/smartadserverBidAdapter_spec.js b/test/spec/modules/smartadserverBidAdapter_spec.js index caa806f9ccc..26855e4bb2e 100644 --- a/test/spec/modules/smartadserverBidAdapter_spec.js +++ b/test/spec/modules/smartadserverBidAdapter_spec.js @@ -3,15 +3,15 @@ import { } from 'chai'; import { spec -} from 'modules/smartadserverBidAdapter'; +} from 'modules/smartadserverBidAdapter.js'; import { newBidder -} from 'src/adapters/bidderFactory'; +} from 'src/adapters/bidderFactory.js'; import { config -} from 'src/config'; -import * as utils from 'src/utils'; -import { requestBidsHook } from 'modules/consentManagement'; +} from 'src/config.js'; +import * as utils from 'src/utils.js'; +import { requestBidsHook } from 'modules/consentManagement.js'; // Default params with optional ones describe('Smart bid adapter tests', function () { diff --git a/test/spec/modules/smartrtbBidAdapter_spec.js b/test/spec/modules/smartrtbBidAdapter_spec.js index 955dd3ba471..cb5ceee0870 100644 --- a/test/spec/modules/smartrtbBidAdapter_spec.js +++ b/test/spec/modules/smartrtbBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai' -import { spec, _getPlatform } from 'modules/smartrtbBidAdapter' -import { newBidder } from 'src/adapters/bidderFactory' +import { spec, _getPlatform } from 'modules/smartrtbBidAdapter.js' +import { newBidder } from 'src/adapters/bidderFactory.js' const br = { body: { diff --git a/test/spec/modules/smartyadsBidAdapter_spec.js b/test/spec/modules/smartyadsBidAdapter_spec.js index 65f28d440a8..2780e88255d 100644 --- a/test/spec/modules/smartyadsBidAdapter_spec.js +++ b/test/spec/modules/smartyadsBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from '../../../modules/smartyadsBidAdapter'; +import {spec} from '../../../modules/smartyadsBidAdapter.js'; describe('SmartyadsAdapter', function () { let bid = { diff --git a/test/spec/modules/smilewantedBidAdapter_spec.js b/test/spec/modules/smilewantedBidAdapter_spec.js index 78a793137b6..0ac242ce0e1 100644 --- a/test/spec/modules/smilewantedBidAdapter_spec.js +++ b/test/spec/modules/smilewantedBidAdapter_spec.js @@ -1,9 +1,9 @@ import { expect } from 'chai'; -import { spec } from 'modules/smilewantedBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import { config } from 'src/config'; -import * as utils from 'src/utils'; -import { requestBidsHook } from 'modules/consentManagement'; +import { spec } from 'modules/smilewantedBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { config } from 'src/config.js'; +import * as utils from 'src/utils.js'; +import { requestBidsHook } from 'modules/consentManagement.js'; const DISPLAY_REQUEST = [{ adUnitCode: 'sw_300x250', diff --git a/test/spec/modules/smmsBidAdapter_spec.js b/test/spec/modules/smmsBidAdapter_spec.js index 3ed952811ea..3cbeb91cf5a 100644 --- a/test/spec/modules/smmsBidAdapter_spec.js +++ b/test/spec/modules/smmsBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec, _getUrlVars} from 'modules/smmsBidAdapter'; -import * as utils from 'src/utils'; +import {spec, _getUrlVars} from 'modules/smmsBidAdapter.js'; +import * as utils from 'src/utils.js'; const BASE_URI = 'https://bidder.mediams.mb.softbank.jp/api/v1/prebid/banner' const NATIVE_BASE_URI = 'https://bidder.mediams.mb.softbank.jp/api/v1/prebid/native' diff --git a/test/spec/modules/somoBidAdapter_spec.js b/test/spec/modules/somoBidAdapter_spec.js index 8ffed99a16a..32e9c6c5323 100644 --- a/test/spec/modules/somoBidAdapter_spec.js +++ b/test/spec/modules/somoBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/somoBidAdapter'; -import * as utils from 'src/utils'; +import {spec} from 'modules/somoBidAdapter.js'; +import * as utils from 'src/utils.js'; describe('Somo Audience Adapter Tests', function () { describe('isBidRequestValid', function () { diff --git a/test/spec/modules/sonobiAnalyticsAdapter_spec.js b/test/spec/modules/sonobiAnalyticsAdapter_spec.js index d857c060f90..76ff88836d4 100644 --- a/test/spec/modules/sonobiAnalyticsAdapter_spec.js +++ b/test/spec/modules/sonobiAnalyticsAdapter_spec.js @@ -1,6 +1,6 @@ -import sonobiAnalytics from 'modules/sonobiAnalyticsAdapter'; +import sonobiAnalytics from 'modules/sonobiAnalyticsAdapter.js'; import {expect} from 'chai'; -import {server} from 'test/mocks/xhr'; +import {server} from 'test/mocks/xhr.js'; let events = require('src/events'); let adapterManager = require('src/adapterManager').default; let constants = require('src/constants.json'); diff --git a/test/spec/modules/sonobiBidAdapter_spec.js b/test/spec/modules/sonobiBidAdapter_spec.js index eacd854f55e..c2aec88f06f 100644 --- a/test/spec/modules/sonobiBidAdapter_spec.js +++ b/test/spec/modules/sonobiBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai' -import { spec, _getPlatform } from 'modules/sonobiBidAdapter' -import { newBidder } from 'src/adapters/bidderFactory' -import {userSync} from '../../../src/userSync'; +import { spec, _getPlatform } from 'modules/sonobiBidAdapter.js' +import { newBidder } from 'src/adapters/bidderFactory.js' +import {userSync} from '../../../src/userSync.js'; describe('SonobiBidAdapter', function () { const adapter = newBidder(spec) diff --git a/test/spec/modules/sortableAnalyticsAdapter_spec.js b/test/spec/modules/sortableAnalyticsAdapter_spec.js index 866f3fcb512..5c2a27fb2d7 100644 --- a/test/spec/modules/sortableAnalyticsAdapter_spec.js +++ b/test/spec/modules/sortableAnalyticsAdapter_spec.js @@ -1,9 +1,9 @@ import {expect} from 'chai'; -import sortableAnalyticsAdapter, {TIMEOUT_FOR_REGISTRY, DEFAULT_PBID_TIMEOUT} from 'modules/sortableAnalyticsAdapter'; -import events from 'src/events'; +import sortableAnalyticsAdapter, {TIMEOUT_FOR_REGISTRY, DEFAULT_PBID_TIMEOUT} from 'modules/sortableAnalyticsAdapter.js'; +import events from 'src/events.js'; import CONSTANTS from 'src/constants.json'; -import * as prebidGlobal from 'src/prebidGlobal'; -import {server} from 'test/mocks/xhr'; +import * as prebidGlobal from 'src/prebidGlobal.js'; +import {server} from 'test/mocks/xhr.js'; describe('Sortable Analytics Adapter', function() { let sandbox; diff --git a/test/spec/modules/sovrnAnalyticsAdapter_spec.js b/test/spec/modules/sovrnAnalyticsAdapter_spec.js index 25c615f0d5c..d6795331417 100644 --- a/test/spec/modules/sovrnAnalyticsAdapter_spec.js +++ b/test/spec/modules/sovrnAnalyticsAdapter_spec.js @@ -1,8 +1,8 @@ -import sovrnAnalyticsAdapter from '../../../modules/sovrnAnalyticsAdapter'; +import sovrnAnalyticsAdapter from '../../../modules/sovrnAnalyticsAdapter.js'; import { expect } from 'chai'; -import {config} from 'src/config'; -import adaptermanager from 'src/adapterManager'; -import { server } from 'test/mocks/xhr'; +import {config} from 'src/config.js'; +import adaptermanager from 'src/adapterManager.js'; +import { server } from 'test/mocks/xhr.js'; var assert = require('assert'); let events = require('src/events'); diff --git a/test/spec/modules/sovrnBidAdapter_spec.js b/test/spec/modules/sovrnBidAdapter_spec.js index 0778b6487c2..c82cc32207a 100644 --- a/test/spec/modules/sovrnBidAdapter_spec.js +++ b/test/spec/modules/sovrnBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {LogError, spec} from 'modules/sovrnBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {LogError, spec} from 'modules/sovrnBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; const ENDPOINT = `https://ap.lijit.com/rtb/bid?src=$$REPO_AND_VERSION$$`; diff --git a/test/spec/modules/spotxBidAdapter_spec.js b/test/spec/modules/spotxBidAdapter_spec.js index d9890a85154..9c6e6071155 100644 --- a/test/spec/modules/spotxBidAdapter_spec.js +++ b/test/spec/modules/spotxBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec, GOOGLE_CONSENT} from 'modules/spotxBidAdapter'; +import {spec, GOOGLE_CONSENT} from 'modules/spotxBidAdapter.js'; describe('the spotx adapter', function () { function getValidBidObject() { diff --git a/test/spec/modules/staqAnalyticsAdapter_spec.js b/test/spec/modules/staqAnalyticsAdapter_spec.js index 1b35f491854..f8e3ba83bbe 100644 --- a/test/spec/modules/staqAnalyticsAdapter_spec.js +++ b/test/spec/modules/staqAnalyticsAdapter_spec.js @@ -1,6 +1,6 @@ -import analyticsAdapter, { ExpiringQueue, getUmtSource, storage } from 'modules/staqAnalyticsAdapter'; +import analyticsAdapter, { ExpiringQueue, getUmtSource, storage } from 'modules/staqAnalyticsAdapter.js'; import { expect } from 'chai'; -import adapterManager from 'src/adapterManager'; +import adapterManager from 'src/adapterManager.js'; import CONSTANTS from 'src/constants.json'; const events = require('../../../src/events'); diff --git a/test/spec/modules/stvBidAdapter_spec.js b/test/spec/modules/stvBidAdapter_spec.js index 72ea428304a..c2278313b2d 100644 --- a/test/spec/modules/stvBidAdapter_spec.js +++ b/test/spec/modules/stvBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/stvBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/stvBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const VADS_ENDPOINT_URL = 'https://ads.smartstream.tv/r/'; diff --git a/test/spec/modules/sublimeBidAdapter_spec.js b/test/spec/modules/sublimeBidAdapter_spec.js index 45173b09953..087d5790f4a 100644 --- a/test/spec/modules/sublimeBidAdapter_spec.js +++ b/test/spec/modules/sublimeBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/sublimeBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/sublimeBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('Sublime Adapter', function() { const adapter = newBidder(spec); diff --git a/test/spec/modules/synacormediaBidAdapter_spec.js b/test/spec/modules/synacormediaBidAdapter_spec.js index 4f59fdd19e0..b67da86ebf2 100644 --- a/test/spec/modules/synacormediaBidAdapter_spec.js +++ b/test/spec/modules/synacormediaBidAdapter_spec.js @@ -1,6 +1,6 @@ import { assert, expect } from 'chai'; -import { BANNER } from 'src/mediaTypes'; -import { spec } from 'modules/synacormediaBidAdapter'; +import { BANNER } from 'src/mediaTypes.js'; +import { spec } from 'modules/synacormediaBidAdapter.js'; describe('synacormediaBidAdapter ', function () { describe('isBidRequestValid', function () { diff --git a/test/spec/modules/taphypeBidAdapter_spec.js b/test/spec/modules/taphypeBidAdapter_spec.js index 2fcdd964520..6b36973814e 100644 --- a/test/spec/modules/taphypeBidAdapter_spec.js +++ b/test/spec/modules/taphypeBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/taphypeBidAdapter'; +import { spec } from 'modules/taphypeBidAdapter.js'; describe('taphypeBidAdapterTests', function () { it('validate_pub_params', function () { diff --git a/test/spec/modules/teadsBidAdapter_spec.js b/test/spec/modules/teadsBidAdapter_spec.js index c557eef7aca..ea3b7fed967 100644 --- a/test/spec/modules/teadsBidAdapter_spec.js +++ b/test/spec/modules/teadsBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/teadsBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {spec} from 'modules/teadsBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; const ENDPOINT = 'https://a.teads.tv/hb/bid-request'; const AD_SCRIPT = '"'; diff --git a/test/spec/modules/telariaBidAdapter_spec.js b/test/spec/modules/telariaBidAdapter_spec.js index e061c51018d..9e4098d7854 100644 --- a/test/spec/modules/telariaBidAdapter_spec.js +++ b/test/spec/modules/telariaBidAdapter_spec.js @@ -1,7 +1,7 @@ import {expect} from 'chai'; -import {newBidder} from 'src/adapters/bidderFactory'; -import {spec, getTimeoutUrl} from 'modules/telariaBidAdapter'; -import * as utils from 'src/utils'; +import {newBidder} from 'src/adapters/bidderFactory.js'; +import {spec, getTimeoutUrl} from 'modules/telariaBidAdapter.js'; +import * as utils from 'src/utils.js'; const ENDPOINT = '.ads.tremorhub.com/ad/tag'; const AD_CODE = 'ssp-!demo!-lufip'; diff --git a/test/spec/modules/theAdxBidAdapter_spec.js b/test/spec/modules/theAdxBidAdapter_spec.js index 4874fbd0841..99e5156190c 100644 --- a/test/spec/modules/theAdxBidAdapter_spec.js +++ b/test/spec/modules/theAdxBidAdapter_spec.js @@ -4,10 +4,10 @@ import { import { spec, internals -} from 'modules/theAdxBidAdapter'; +} from 'modules/theAdxBidAdapter.js'; import { newBidder -} from 'src/adapters/bidderFactory'; +} from 'src/adapters/bidderFactory.js'; describe('TheAdxAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/timBidAdapter_spec.js b/test/spec/modules/timBidAdapter_spec.js index 8e22d4716d7..bf2d2e28510 100644 --- a/test/spec/modules/timBidAdapter_spec.js +++ b/test/spec/modules/timBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/timBidAdapter'; +import { spec } from 'modules/timBidAdapter.js'; describe('timAdapterTests', function () { describe('bidRequestValidity', function () { diff --git a/test/spec/modules/topRTBBidAdapter_spec.js b/test/spec/modules/topRTBBidAdapter_spec.js index 1c88658d6df..9b97917a0b6 100644 --- a/test/spec/modules/topRTBBidAdapter_spec.js +++ b/test/spec/modules/topRTBBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/topRTBBidAdapter'; +import { spec } from 'modules/topRTBBidAdapter.js'; describe('topRTBBidAdapterTests', function () { it('validate_pub_params', function () { diff --git a/test/spec/modules/tpmnBidAdapter_spec.js b/test/spec/modules/tpmnBidAdapter_spec.js index ea027ddd1e5..b4f6882dbe1 100644 --- a/test/spec/modules/tpmnBidAdapter_spec.js +++ b/test/spec/modules/tpmnBidAdapter_spec.js @@ -1,6 +1,6 @@ /* eslint-disable no-tabs */ import { expect } from 'chai'; -import { spec } from 'modules/tpmnBidAdapter'; +import { spec } from 'modules/tpmnBidAdapter.js'; describe('tpmnAdapterTests', function() { describe('isBidRequestValid', function() { diff --git a/test/spec/modules/tribeosBidAdapter_spec.js b/test/spec/modules/tribeosBidAdapter_spec.js index b0e5b5dd487..db92fe94e3e 100644 --- a/test/spec/modules/tribeosBidAdapter_spec.js +++ b/test/spec/modules/tribeosBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/tribeosBidAdapter'; +import { spec } from 'modules/tribeosBidAdapter.js'; describe('tribeosBidAdapter', function() { describe('isBidRequestValid', function() { diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index eaa206df984..596e8a3e2d9 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import * as utils from 'src/utils'; -import {spec, acceptPostMessage, getStorageData, setStorageData} from 'modules/trionBidAdapter'; +import * as utils from 'src/utils.js'; +import {spec, acceptPostMessage, getStorageData, setStorageData} from 'modules/trionBidAdapter.js'; const CONSTANTS = require('src/constants.json'); const adloader = require('src/adloader'); diff --git a/test/spec/modules/tripleliftBidAdapter_spec.js b/test/spec/modules/tripleliftBidAdapter_spec.js index 6642e59d7c3..428d92345d9 100644 --- a/test/spec/modules/tripleliftBidAdapter_spec.js +++ b/test/spec/modules/tripleliftBidAdapter_spec.js @@ -1,8 +1,8 @@ import { expect } from 'chai'; -import { tripleliftAdapterSpec } from 'modules/tripleliftBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import { deepClone } from 'src/utils'; -import { config } from 'src/config'; +import { tripleliftAdapterSpec } from 'modules/tripleliftBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { deepClone } from 'src/utils.js'; +import { config } from 'src/config.js'; import prebid from '../../../package.json'; const ENDPOINT = 'https://tlx.3lift.com/header/auction?'; diff --git a/test/spec/modules/trustxBidAdapter_spec.js b/test/spec/modules/trustxBidAdapter_spec.js index bf9c0d9c895..9e0aad9b36f 100644 --- a/test/spec/modules/trustxBidAdapter_spec.js +++ b/test/spec/modules/trustxBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/trustxBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/trustxBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('TrustXAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/turktelekomBidAdapter_spec.js b/test/spec/modules/turktelekomBidAdapter_spec.js index e591da90563..c4e55178638 100644 --- a/test/spec/modules/turktelekomBidAdapter_spec.js +++ b/test/spec/modules/turktelekomBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/turktelekomBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/turktelekomBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('TurkTelekomAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/ucfunnelAnalyticsAdapter_spec.js b/test/spec/modules/ucfunnelAnalyticsAdapter_spec.js index 8ae0ee074c4..2b7f047c85a 100644 --- a/test/spec/modules/ucfunnelAnalyticsAdapter_spec.js +++ b/test/spec/modules/ucfunnelAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ import { ucfunnelAnalyticsAdapter, parseBidderCode, parseAdUnitCode, ANALYTICS_VERSION, BIDDER_STATUS -} from 'modules/ucfunnelAnalyticsAdapter'; +} from 'modules/ucfunnelAnalyticsAdapter.js'; import {expect} from 'chai'; diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index 38d86e7d808..70b273cfb8c 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/ucfunnelBidAdapter'; -import {BANNER, VIDEO, NATIVE} from 'src/mediaTypes'; +import { spec } from 'modules/ucfunnelBidAdapter.js'; +import {BANNER, VIDEO, NATIVE} from 'src/mediaTypes.js'; const URL = 'https://hb.aralego.com/header'; const BIDDER_CODE = 'ucfunnel'; diff --git a/test/spec/modules/underdogmediaBidAdapter_spec.js b/test/spec/modules/underdogmediaBidAdapter_spec.js index 66668c39b48..aeb9f56c851 100644 --- a/test/spec/modules/underdogmediaBidAdapter_spec.js +++ b/test/spec/modules/underdogmediaBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec, resetUserSync } from 'modules/underdogmediaBidAdapter'; +import { spec, resetUserSync } from 'modules/underdogmediaBidAdapter.js'; describe('UnderdogMedia adapter', function () { let bidRequests; diff --git a/test/spec/modules/undertoneBidAdapter_spec.js b/test/spec/modules/undertoneBidAdapter_spec.js index 24be9e93a90..f379081f88d 100644 --- a/test/spec/modules/undertoneBidAdapter_spec.js +++ b/test/spec/modules/undertoneBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/undertoneBidAdapter'; +import { spec } from 'modules/undertoneBidAdapter.js'; const URL = 'https://hb.undertone.com/hb'; const BIDDER_CODE = 'undertone'; diff --git a/test/spec/modules/unrulyBidAdapter_spec.js b/test/spec/modules/unrulyBidAdapter_spec.js index 3cab4d86591..9ece8927ef7 100644 --- a/test/spec/modules/unrulyBidAdapter_spec.js +++ b/test/spec/modules/unrulyBidAdapter_spec.js @@ -1,10 +1,10 @@ /* globals describe, it, beforeEach, afterEach, sinon */ import { expect } from 'chai' -import * as utils from 'src/utils' -import { STATUS } from 'src/constants' -import { VIDEO } from 'src/mediaTypes' -import { Renderer } from 'src/Renderer' -import { adapter } from 'modules/unrulyBidAdapter' +import * as utils from 'src/utils.js' +import { STATUS } from 'src/constants.json' +import { VIDEO } from 'src/mediaTypes.js' +import { Renderer } from 'src/Renderer.js' +import { adapter } from 'modules/unrulyBidAdapter.js' describe('UnrulyAdapter', function () { function createOutStreamExchangeBid({ diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index 2649fddf5df..22d8c6ac86a 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -6,17 +6,17 @@ import { setSubmoduleRegistry, syncDelay } from 'modules/userId/index.js'; -import {config} from 'src/config'; -import * as utils from 'src/utils'; -import events from 'src/events'; +import {config} from 'src/config.js'; +import * as utils from 'src/utils.js'; +import events from 'src/events.js'; import CONSTANTS from 'src/constants.json'; -import {unifiedIdSubmodule} from 'modules/unifiedIdSystem'; -import {pubCommonIdSubmodule} from 'modules/pubCommonIdSystem'; -import {britepoolIdSubmodule} from 'modules/britepoolIdSystem'; -import {id5IdSubmodule} from 'modules/id5IdSystem'; -import {identityLinkSubmodule} from 'modules/identityLinkIdSystem'; -import {liveIntentIdSubmodule} from 'modules/liveIntentIdSystem'; -import {server} from 'test/mocks/xhr'; +import {unifiedIdSubmodule} from 'modules/unifiedIdSystem.js'; +import {pubCommonIdSubmodule} from 'modules/pubCommonIdSystem.js'; +import {britepoolIdSubmodule} from 'modules/britepoolIdSystem.js'; +import {id5IdSubmodule} from 'modules/id5IdSystem.js'; +import {identityLinkSubmodule} from 'modules/identityLinkIdSystem.js'; +import {liveIntentIdSubmodule} from 'modules/liveIntentIdSystem.js'; +import {server} from 'test/mocks/xhr.js'; let assert = require('chai').assert; let expect = require('chai').expect; diff --git a/test/spec/modules/viBidAdapter_spec.js b/test/spec/modules/viBidAdapter_spec.js index 8f1c07047ec..e1a88c004bb 100644 --- a/test/spec/modules/viBidAdapter_spec.js +++ b/test/spec/modules/viBidAdapter_spec.js @@ -25,7 +25,7 @@ import { getViewabilityDescription, mergeArrays, documentFocus -} from 'modules/viBidAdapter'; +} from 'modules/viBidAdapter.js'; describe('ratioToPercentageCeil', () => { it('1 converts to percentage', () => diff --git a/test/spec/modules/vidazooBidAdapter_spec.js b/test/spec/modules/vidazooBidAdapter_spec.js index c1fd63f599c..755295c7bd6 100644 --- a/test/spec/modules/vidazooBidAdapter_spec.js +++ b/test/spec/modules/vidazooBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec as adapter, URL} from 'modules/vidazooBidAdapter'; -import * as utils from 'src/utils'; +import {spec as adapter, URL} from 'modules/vidazooBidAdapter.js'; +import * as utils from 'src/utils.js'; const BID = { 'bidId': '2d52001cabd527', diff --git a/test/spec/modules/videoNowBidAdapter_spec.js b/test/spec/modules/videoNowBidAdapter_spec.js index 1648a971010..a419c73456b 100644 --- a/test/spec/modules/videoNowBidAdapter_spec.js +++ b/test/spec/modules/videoNowBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai' -import { spec } from 'modules/videoNowBidAdapter' -import { replaceAuctionPrice } from 'src/utils' -import * as utils from 'src/utils'; +import { spec } from 'modules/videoNowBidAdapter.js' +import { replaceAuctionPrice } from 'src/utils.js' +import * as utils from 'src/utils.js'; // childNode.remove polyfill for ie11 // suggested by: https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove diff --git a/test/spec/modules/videoreachBidAdapter_spec.js b/test/spec/modules/videoreachBidAdapter_spec.js index 47000e5fab5..e5c6b9b30ad 100644 --- a/test/spec/modules/videoreachBidAdapter_spec.js +++ b/test/spec/modules/videoreachBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/videoreachBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {spec} from 'modules/videoreachBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; const ENDPOINT_URL = 'https://a.videoreach.com/hb/'; diff --git a/test/spec/modules/viewdeosDXBidAdapter_spec.js b/test/spec/modules/viewdeosDXBidAdapter_spec.js index 89fe1ff94ef..f9bee1b0efe 100644 --- a/test/spec/modules/viewdeosDXBidAdapter_spec.js +++ b/test/spec/modules/viewdeosDXBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/viewdeosDXBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {spec} from 'modules/viewdeosDXBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; const ENDPOINT = 'https://ghb.sync.viewdeos.com/auction/'; diff --git a/test/spec/modules/visxBidAdapter_spec.js b/test/spec/modules/visxBidAdapter_spec.js index b14f5331fd1..85a66efe795 100755 --- a/test/spec/modules/visxBidAdapter_spec.js +++ b/test/spec/modules/visxBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec } from 'modules/visxBidAdapter'; -import { config } from 'src/config'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/visxBidAdapter.js'; +import { config } from 'src/config.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('VisxAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/vmgBidAdapter_spec.js b/test/spec/modules/vmgBidAdapter_spec.js index 688c03577fd..41aa077adc7 100644 --- a/test/spec/modules/vmgBidAdapter_spec.js +++ b/test/spec/modules/vmgBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/vmgBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/vmgBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('VmgAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/vrtcalBidAdapter_spec.js b/test/spec/modules/vrtcalBidAdapter_spec.js index 7b37e393575..729b0a723e4 100644 --- a/test/spec/modules/vrtcalBidAdapter_spec.js +++ b/test/spec/modules/vrtcalBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from '../../../modules/vrtcalBidAdapter'; +import {spec} from '../../../modules/vrtcalBidAdapter.js'; describe('Vrtcal Adapter', function () { let bid = { diff --git a/test/spec/modules/vubleBidAdapter_spec.js b/test/spec/modules/vubleBidAdapter_spec.js index 81e7936809a..2f0d1c1e262 100644 --- a/test/spec/modules/vubleBidAdapter_spec.js +++ b/test/spec/modules/vubleBidAdapter_spec.js @@ -1,8 +1,8 @@ // import or require modules necessary for the test, e.g.: import {expect} from 'chai'; -import {spec as adapter} from 'modules/vubleBidAdapter'; -import * as utils from 'src/utils'; +import {spec as adapter} from 'modules/vubleBidAdapter.js'; +import * as utils from 'src/utils.js'; describe('VubleAdapter', function () { describe('Check methods existance', function () { diff --git a/test/spec/modules/widespaceBidAdapter_spec.js b/test/spec/modules/widespaceBidAdapter_spec.js index 247c859002e..c7d4f3bdaf9 100644 --- a/test/spec/modules/widespaceBidAdapter_spec.js +++ b/test/spec/modules/widespaceBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; -import {spec} from 'modules/widespaceBidAdapter'; -import includes from 'core-js/library/fn/array/includes'; +import {spec} from 'modules/widespaceBidAdapter.js'; +import includes from 'core-js/library/fn/array/includes.js'; describe('+widespaceAdatperTest', function () { // Dummy bid request diff --git a/test/spec/modules/xhbBidAdapter_spec.js b/test/spec/modules/xhbBidAdapter_spec.js index 004bdcc4b54..a12abc74c64 100644 --- a/test/spec/modules/xhbBidAdapter_spec.js +++ b/test/spec/modules/xhbBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec } from 'modules/xhbBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import { deepClone } from 'src/utils'; +import { spec } from 'modules/xhbBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { deepClone } from 'src/utils.js'; const ENDPOINT = 'https://ib.adnxs.com/ut/v3/prebid'; diff --git a/test/spec/modules/yieldlabBidAdapter_spec.js b/test/spec/modules/yieldlabBidAdapter_spec.js index c8709969e00..43a18bce094 100644 --- a/test/spec/modules/yieldlabBidAdapter_spec.js +++ b/test/spec/modules/yieldlabBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai' -import { spec } from 'modules/yieldlabBidAdapter' -import { newBidder } from 'src/adapters/bidderFactory' +import { spec } from 'modules/yieldlabBidAdapter.js' +import { newBidder } from 'src/adapters/bidderFactory.js' const REQUEST = { 'bidder': 'yieldlab', diff --git a/test/spec/modules/yieldmoBidAdapter_spec.js b/test/spec/modules/yieldmoBidAdapter_spec.js index 6a4a142975f..0bbc4b57785 100644 --- a/test/spec/modules/yieldmoBidAdapter_spec.js +++ b/test/spec/modules/yieldmoBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { spec } from 'modules/yieldmoBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import * as utils from 'src/utils'; +import { spec } from 'modules/yieldmoBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import * as utils from 'src/utils.js'; describe('YieldmoAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/yieldoneAnalyticsAdapter_spec.js b/test/spec/modules/yieldoneAnalyticsAdapter_spec.js index eb79fc55806..bc1001cc6c1 100644 --- a/test/spec/modules/yieldoneAnalyticsAdapter_spec.js +++ b/test/spec/modules/yieldoneAnalyticsAdapter_spec.js @@ -1,5 +1,5 @@ -import yieldoneAnalytics from 'modules/yieldoneAnalyticsAdapter'; -import { targeting } from 'src/targeting'; +import yieldoneAnalytics from 'modules/yieldoneAnalyticsAdapter.js'; +import { targeting } from 'src/targeting.js'; import { expect } from 'chai'; let events = require('src/events'); let adapterManager = require('src/adapterManager').default; diff --git a/test/spec/modules/yieldoneBidAdapter_spec.js b/test/spec/modules/yieldoneBidAdapter_spec.js index 78b6122aff5..84065682297 100644 --- a/test/spec/modules/yieldoneBidAdapter_spec.js +++ b/test/spec/modules/yieldoneBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { spec } from 'modules/yieldoneBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; +import { spec } from 'modules/yieldoneBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const ENDPOINT = 'https://y.one.impact-ad.jp/h_bid'; const USER_SYNC_URL = 'https://y.one.impact-ad.jp/push_sync'; diff --git a/test/spec/modules/yuktamediaAnalyticsAdaptor_spec.js b/test/spec/modules/yuktamediaAnalyticsAdaptor_spec.js index 74d37226e61..24a524c85c7 100644 --- a/test/spec/modules/yuktamediaAnalyticsAdaptor_spec.js +++ b/test/spec/modules/yuktamediaAnalyticsAdaptor_spec.js @@ -1,8 +1,8 @@ -import yuktamediaAnalyticsAdapter from 'modules/yuktamediaAnalyticsAdapter'; +import yuktamediaAnalyticsAdapter from 'modules/yuktamediaAnalyticsAdapter.js'; import { expect } from 'chai'; import adapterManager from 'src/adapterManager.js'; -import * as utils from 'src/utils'; -import { server } from 'test/mocks/xhr'; +import * as utils from 'src/utils.js'; +import { server } from 'test/mocks/xhr.js'; let events = require('src/events'); let constants = require('src/constants.json'); diff --git a/test/spec/native_spec.js b/test/spec/native_spec.js index 2fb2fd810fa..bd56ba53e4a 100644 --- a/test/spec/native_spec.js +++ b/test/spec/native_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { fireNativeTrackers, getNativeTargeting, nativeBidIsValid, getAssetMessage } from 'src/native'; +import { fireNativeTrackers, getNativeTargeting, nativeBidIsValid, getAssetMessage } from 'src/native.js'; import CONSTANTS from 'src/constants.json'; const utils = require('src/utils'); diff --git a/test/spec/refererDetection_spec.js b/test/spec/refererDetection_spec.js index b2ef4e2058f..90892d915fe 100644 --- a/test/spec/refererDetection_spec.js +++ b/test/spec/refererDetection_spec.js @@ -1,4 +1,4 @@ -import { detectReferer } from 'src/refererDetection'; +import { detectReferer } from 'src/refererDetection.js'; import { expect } from 'chai'; var mocks = { diff --git a/test/spec/renderer_spec.js b/test/spec/renderer_spec.js index da10c67f223..2688c6437fe 100644 --- a/test/spec/renderer_spec.js +++ b/test/spec/renderer_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; -import { Renderer } from 'src/Renderer'; -import * as utils from 'src/utils'; -import { loadExternalScript } from 'src/adloader'; +import { Renderer } from 'src/Renderer.js'; +import * as utils from 'src/utils.js'; +import { loadExternalScript } from 'src/adloader.js'; describe('Renderer', function () { describe('Renderer: A renderer installed on a bid response', function () { diff --git a/test/spec/sizeMapping_spec.js b/test/spec/sizeMapping_spec.js index 254dcb8003e..b6b8c00ada3 100644 --- a/test/spec/sizeMapping_spec.js +++ b/test/spec/sizeMapping_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { resolveStatus, setSizeConfig, sizeSupported } from 'src/sizeMapping'; -import includes from 'core-js/library/fn/array/includes'; +import { resolveStatus, setSizeConfig, sizeSupported } from 'src/sizeMapping.js'; +import includes from 'core-js/library/fn/array/includes.js'; let utils = require('src/utils'); let deepClone = utils.deepClone; diff --git a/test/spec/unit/adServerManager_spec.js b/test/spec/unit/adServerManager_spec.js index 4ae475ac013..ec58ff7f5b3 100644 --- a/test/spec/unit/adServerManager_spec.js +++ b/test/spec/unit/adServerManager_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { getGlobal } from 'src/prebidGlobal'; -import { registerVideoSupport } from 'src/adServerManager'; +import { getGlobal } from 'src/prebidGlobal.js'; +import { registerVideoSupport } from 'src/adServerManager.js'; const prebid = getGlobal(); diff --git a/test/spec/unit/adUnits_spec.js b/test/spec/unit/adUnits_spec.js index fb666feb9b8..a8443d36522 100644 --- a/test/spec/unit/adUnits_spec.js +++ b/test/spec/unit/adUnits_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { adunitCounter } from 'src/adUnits'; +import { adunitCounter } from 'src/adUnits.js'; describe('Adunit Counter', function () { const ADUNIT_ID_1 = 'test1'; diff --git a/test/spec/unit/core/adapterManager_spec.js b/test/spec/unit/core/adapterManager_spec.js index bd8f880378b..566ebe2e400 100644 --- a/test/spec/unit/core/adapterManager_spec.js +++ b/test/spec/unit/core/adapterManager_spec.js @@ -1,19 +1,19 @@ import { expect } from 'chai'; -import adapterManager, { gdprDataHandler } from 'src/adapterManager'; +import adapterManager, { gdprDataHandler } from 'src/adapterManager.js'; import { getAdUnits, getServerTestingConfig, getServerTestingsAds, getBidRequests -} from 'test/fixtures/fixtures'; +} from 'test/fixtures/fixtures.js'; import CONSTANTS from 'src/constants.json'; -import * as utils from 'src/utils'; -import { config } from 'src/config'; -import { registerBidder } from 'src/adapters/bidderFactory'; -import { setSizeConfig } from 'src/sizeMapping'; -import find from 'core-js/library/fn/array/find'; -import includes from 'core-js/library/fn/array/includes'; -import s2sTesting from 'modules/s2sTesting'; +import * as utils from 'src/utils.js'; +import { config } from 'src/config.js'; +import { registerBidder } from 'src/adapters/bidderFactory.js'; +import { setSizeConfig } from 'src/sizeMapping.js'; +import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js/library/fn/array/includes.js'; +import s2sTesting from 'modules/s2sTesting.js'; var events = require('../../../../src/events'); const CONFIG = { diff --git a/test/spec/unit/core/bidderFactory_spec.js b/test/spec/unit/core/bidderFactory_spec.js index e1b2f205bf7..c06eb29b6b9 100644 --- a/test/spec/unit/core/bidderFactory_spec.js +++ b/test/spec/unit/core/bidderFactory_spec.js @@ -1,11 +1,11 @@ -import { newBidder, registerBidder, preloadBidderMappingFile } from 'src/adapters/bidderFactory'; -import adapterManager from 'src/adapterManager'; -import * as ajax from 'src/ajax'; +import { newBidder, registerBidder, preloadBidderMappingFile } from 'src/adapters/bidderFactory.js'; +import adapterManager from 'src/adapterManager.js'; +import * as ajax from 'src/ajax.js'; import { expect } from 'chai'; -import { userSync } from 'src/userSync' -import * as utils from 'src/utils'; -import { config } from 'src/config'; -import { server } from 'test/mocks/xhr'; +import { userSync } from 'src/userSync.js' +import * as utils from 'src/utils.js'; +import { config } from 'src/config.js'; +import { server } from 'test/mocks/xhr.js'; const CODE = 'sampleBidder'; const MOCK_BIDS_REQUEST = { diff --git a/test/spec/unit/core/targeting_spec.js b/test/spec/unit/core/targeting_spec.js index ad94ebccfb2..4e0599ad27d 100644 --- a/test/spec/unit/core/targeting_spec.js +++ b/test/spec/unit/core/targeting_spec.js @@ -1,10 +1,10 @@ import { expect } from 'chai'; -import { targeting as targetingInstance, filters, sortByDealAndPriceBucket } from 'src/targeting'; -import { config } from 'src/config'; -import { getAdUnits, createBidReceived } from 'test/fixtures/fixtures'; +import { targeting as targetingInstance, filters, sortByDealAndPriceBucket } from 'src/targeting.js'; +import { config } from 'src/config.js'; +import { getAdUnits, createBidReceived } from 'test/fixtures/fixtures.js'; import CONSTANTS from 'src/constants.json'; -import { auctionManager } from 'src/auctionManager'; -import * as utils from 'src/utils'; +import { auctionManager } from 'src/auctionManager.js'; +import * as utils from 'src/utils.js'; const bid1 = { 'bidderCode': 'rubicon', diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index 6d98830ac42..f18310e8287 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -7,14 +7,14 @@ import { getTargetingKeysBidLandscape, getAdUnits, createBidReceived -} from 'test/fixtures/fixtures'; -import { auctionManager, newAuctionManager } from 'src/auctionManager'; -import { targeting, newTargeting, filters } from 'src/targeting'; -import { config as configObj } from 'src/config'; -import * as ajaxLib from 'src/ajax'; -import * as auctionModule from 'src/auction'; -import { newBidder, registerBidder } from 'src/adapters/bidderFactory'; -import find from 'core-js/library/fn/array/find'; +} from 'test/fixtures/fixtures.js'; +import { auctionManager, newAuctionManager } from 'src/auctionManager.js'; +import { targeting, newTargeting, filters } from 'src/targeting.js'; +import { config as configObj } from 'src/config.js'; +import * as ajaxLib from 'src/ajax.js'; +import * as auctionModule from 'src/auction.js'; +import { newBidder, registerBidder } from 'src/adapters/bidderFactory.js'; +import find from 'core-js/library/fn/array/find.js'; var assert = require('chai').assert; var expect = require('chai').expect; diff --git a/test/spec/unit/secureCreatives_spec.js b/test/spec/unit/secureCreatives_spec.js index f0f26bf5653..97dfa119193 100644 --- a/test/spec/unit/secureCreatives_spec.js +++ b/test/spec/unit/secureCreatives_spec.js @@ -1,8 +1,8 @@ import { _sendAdToCreative -} from '../../../src/secureCreatives'; +} from '../../../src/secureCreatives.js'; import { expect } from 'chai'; -import * as utils from 'src/utils'; +import * as utils from 'src/utils.js'; describe('secureCreatives', () => { describe('_sendAdToCreative', () => { diff --git a/test/spec/url_spec.js b/test/spec/url_spec.js index 90047273043..842b954c4bc 100644 --- a/test/spec/url_spec.js +++ b/test/spec/url_spec.js @@ -1,4 +1,4 @@ -import {format, parse} from '../../src/url'; +import {format, parse} from '../../src/url.js'; import { expect } from 'chai'; describe('helpers.url', function () { diff --git a/test/spec/userSync_spec.js b/test/spec/userSync_spec.js index 806e86e998b..bd7c7d66a85 100644 --- a/test/spec/userSync_spec.js +++ b/test/spec/userSync_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { config } from 'src/config'; +import { config } from 'src/config.js'; // Use require since we need to be able to write to these vars const utils = require('../../src/utils'); let { newUserSync } = require('../../src/userSync'); diff --git a/test/spec/utils_spec.js b/test/spec/utils_spec.js index 012dfacd92f..e7be6880444 100755 --- a/test/spec/utils_spec.js +++ b/test/spec/utils_spec.js @@ -1,7 +1,7 @@ -import { getAdServerTargeting } from 'test/fixtures/fixtures'; +import { getAdServerTargeting } from 'test/fixtures/fixtures.js'; import { expect } from 'chai'; import CONSTANTS from 'src/constants.json'; -import * as utils from 'src/utils'; +import * as utils from 'src/utils.js'; var assert = require('assert'); diff --git a/test/spec/videoCache_spec.js b/test/spec/videoCache_spec.js index a3864eb22fa..7d706947416 100644 --- a/test/spec/videoCache_spec.js +++ b/test/spec/videoCache_spec.js @@ -1,8 +1,7 @@ -import 'mocha/mocha'; import chai from 'chai'; -import { getCacheUrl, store } from 'src/videoCache'; -import { config } from 'src/config'; -import { server } from 'test/mocks/xhr'; +import { getCacheUrl, store } from 'src/videoCache.js'; +import { config } from 'src/config.js'; +import { server } from 'test/mocks/xhr.js'; const should = chai.should(); diff --git a/test/spec/video_spec.js b/test/spec/video_spec.js index dc6c11a7491..72a585049c3 100644 --- a/test/spec/video_spec.js +++ b/test/spec/video_spec.js @@ -1,4 +1,4 @@ -import { isValidVideoBid } from 'src/video'; +import { isValidVideoBid } from 'src/video.js'; describe('video.js', function () { it('validates valid instream bids', function () { From e1d10e060fee61b803417448c3051df0e5168a46 Mon Sep 17 00:00:00 2001 From: dpapworth-qc <50959025+dpapworth-qc@users.noreply.github.com> Date: Thu, 20 Feb 2020 04:06:49 +0000 Subject: [PATCH 066/496] Removed error message when no bids are made. (#4872) --- modules/quantcastBidAdapter.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js index 854d68d5b07..bcd6929cd04 100644 --- a/modules/quantcastBidAdapter.js +++ b/modules/quantcastBidAdapter.js @@ -179,15 +179,16 @@ export const spec = { const response = serverResponse['body']; - if ( - response === undefined || - !response.hasOwnProperty('bids') || - utils.isEmpty(response.bids) - ) { + if (response === undefined || !response.hasOwnProperty('bids')) { utils.logError('Sub-optimal JSON received from Quantcast server'); return []; } + if (utils.isEmpty(response.bids)) { + // Shortcut response handling if no bids are present + return []; + } + const bidResponsesList = response.bids.map(bid => { const { ad, cpm, width, height, creativeId, currency, videoUrl, dealId } = bid; From f39427e18ff0924676f4a681b791ac95f67ae828 Mon Sep 17 00:00:00 2001 From: chino117 Date: Thu, 20 Feb 2020 14:46:51 -0300 Subject: [PATCH 067/496] Add new optional parameter for changing placement names (#4878) --- modules/eplanningBidAdapter.js | 12 +++-- test/spec/modules/eplanningBidAdapter_spec.js | 51 +++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/modules/eplanningBidAdapter.js b/modules/eplanningBidAdapter.js index b7747c93086..979f6dbf464 100644 --- a/modules/eplanningBidAdapter.js +++ b/modules/eplanningBidAdapter.js @@ -5,7 +5,7 @@ const BIDDER_CODE = 'eplanning'; const rnd = Math.random(); const DEFAULT_SV = 'ads.us.e-planning.net'; const DEFAULT_ISV = 'i.e-planning.net'; -const PARAMS = ['ci', 'sv', 't']; +const PARAMS = ['ci', 'sv', 't', 'ml']; const DOLLARS = 'USD'; const NET_REVENUE = true; const TTL = 120; @@ -29,7 +29,7 @@ export const spec = { let params; const urlConfig = getUrlConfig(bidRequests); const pcrs = getCharset(); - const spaces = getSpaces(bidRequests); + const spaces = getSpaces(bidRequests, urlConfig.ml); const pageUrl = bidderRequest.refererInfo.referer; const getDomain = (url) => { let anchor = document.createElement('a'); @@ -185,12 +185,16 @@ function getSpacesStruct(bids) { return e; } -function getSpaces(bidRequests) { +function cleanName(name) { + return name.replace(/_|\.|-|\//g, '').replace(/\)\(|\(|\)|:/g, '_').replace(/^_+|_+$/g, ''); +} + +function getSpaces(bidRequests, ml) { let spacesStruct = getSpacesStruct(bidRequests); let es = {str: '', vs: '', map: {}}; es.str = Object.keys(spacesStruct).map(size => spacesStruct[size].map((bid, i) => { es.vs += getVs(bid); - let name = getSize(bid, true) + '_' + i; + let name = ml ? cleanName(bid.adUnitCode) : getSize(bid, true) + '_' + i; es.map[name] = bid.bidId; return name + ':' + getSize(bid); }).join('+')).join('+'); diff --git a/test/spec/modules/eplanningBidAdapter_spec.js b/test/spec/modules/eplanningBidAdapter_spec.js index 52c9d75ecf8..e9d478f911f 100644 --- a/test/spec/modules/eplanningBidAdapter_spec.js +++ b/test/spec/modules/eplanningBidAdapter_spec.js @@ -13,6 +13,7 @@ describe('E-Planning Adapter', function () { const ADUNIT_CODE_VIEW3 = 'adunit-code-view3'; const CLEAN_ADUNIT_CODE2 = '300x250_1'; const CLEAN_ADUNIT_CODE = '300x250_0'; + const CLEAN_ADUNIT_CODE_ML = 'adunitco_de'; const BID_ID = '123456789'; const BID_ID2 = '987654321'; const BID_ID3 = '998877665'; @@ -32,6 +33,17 @@ describe('E-Planning Adapter', function () { 'adUnitCode': ADUNIT_CODE, 'sizes': [[300, 250], [300, 600]], }; + const ML = '1'; + const validBidMappingLinear = { + 'bidder': 'eplanning', + 'bidId': BID_ID, + 'params': { + 'ci': CI, + 'ml': ML, + }, + 'adUnitCode': ADUNIT_CODE, + 'sizes': [[300, 250], [300, 600]], + }; const validBid2 = { 'bidder': 'eplanning', 'bidId': BID_ID2, @@ -261,6 +273,12 @@ describe('E-Planning Adapter', function () { expect(e).to.equal('300x250_0:300x250,300x600'); }); + it('should return e parameter with linear mapping attribute with value according to the adunit sizes', function () { + let bidRequestsML = [validBidMappingLinear]; + const e = spec.buildRequests(bidRequestsML, bidderRequest).data.e; + expect(e).to.equal(CLEAN_ADUNIT_CODE_ML + ':300x250,300x600'); + }); + it('should return correct e parameter with more than one adunit', function () { const NEW_CODE = ADUNIT_CODE + '2'; const CLEAN_NEW_CODE = CLEAN_ADUNIT_CODE + '2'; @@ -278,6 +296,25 @@ describe('E-Planning Adapter', function () { expect(e).to.equal('300x250_0:300x250,300x600+100x100_0:100x100'); }); + it('should return correct e parameter with linear mapping attribute with more than one adunit', function () { + let bidRequestsML = [validBidMappingLinear]; + const NEW_CODE = ADUNIT_CODE + '2'; + const CLEAN_NEW_CODE = CLEAN_ADUNIT_CODE_ML + '2'; + const anotherBid = { + 'bidder': 'eplanning', + 'params': { + 'ci': CI, + 'ml': ML, + }, + 'adUnitCode': NEW_CODE, + 'sizes': [[100, 100]], + }; + bidRequestsML.push(anotherBid); + + const e = spec.buildRequests(bidRequestsML, bidderRequest).data.e; + expect(e).to.equal(CLEAN_ADUNIT_CODE_ML + ':300x250,300x600+' + CLEAN_NEW_CODE + ':100x100'); + }); + it('should return correct e parameter when the adunit has no size', function () { const noSizeBid = { 'bidder': 'eplanning', @@ -291,6 +328,20 @@ describe('E-Planning Adapter', function () { expect(e).to.equal('1x1_0:1x1'); }); + it('should return correct e parameter with linear mapping attribute when the adunit has no size', function () { + const noSizeBid = { + 'bidder': 'eplanning', + 'params': { + 'ci': CI, + 'ml': ML, + }, + 'adUnitCode': ADUNIT_CODE, + }; + + const e = spec.buildRequests([noSizeBid], bidderRequest).data.e; + expect(e).to.equal(CLEAN_ADUNIT_CODE_ML + ':1x1'); + }); + it('should return ur parameter with current window url', function () { const ur = spec.buildRequests(bidRequests, bidderRequest).data.ur; expect(ur).to.equal(encodeURIComponent(bidderRequest.refererInfo.referer)); From aa09d5dec037555cf9661560d10bf547b1624623 Mon Sep 17 00:00:00 2001 From: Bret Gorsline Date: Thu, 20 Feb 2020 14:23:16 -0500 Subject: [PATCH 068/496] Prebid 3.8.0 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7bcce9cb943..49c33c16fd0 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.8.0-pre", + "version": "3.8.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From d5b217196c2a00b8e76ac91f70a0abc947b83072 Mon Sep 17 00:00:00 2001 From: Bret Gorsline Date: Thu, 20 Feb 2020 15:15:52 -0500 Subject: [PATCH 069/496] Increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 49c33c16fd0..ae1cecf4b69 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.8.0", + "version": "3.9.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 469f82cfe676bcca633f3539b2dad75d4561c13f Mon Sep 17 00:00:00 2001 From: "Isaac A. Dettman" Date: Thu, 20 Feb 2020 13:20:39 -0800 Subject: [PATCH 070/496] Rubicon Adapter: Add liveramp support (#4863) * Add microadBidAdapter * Remove unnecessary encodeURIComponent from microadBidAdapter * Submit Advangelists Prebid Adapter * Submit Advangelists Prebid Adapter 1.1 * Correct procudtion endpoint for prebid * analytics update with wrapper name * reverted error merge * update changed default value of netRevenue to true * Re-add rubicon analytics without deprecated getTopWindowUrl util * Cache referrer on auction_init instead of bid_requested * add liveramp support to rp adapter * add liveramp support to prebid server Co-authored-by: msm0504 <51493331+msm0504@users.noreply.github.com> --- modules/prebidServerBidAdapter/index.js | 11 ++++++++++- modules/rubiconBidAdapter.js | 17 ++++++++++++++++- .../modules/prebidServerBidAdapter_spec.js | 5 ++++- test/spec/modules/rubiconBidAdapter_spec.js | 19 ++++++++++++++++++- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js index 2ad31bda2ee..c32542226e2 100644 --- a/modules/prebidServerBidAdapter/index.js +++ b/modules/prebidServerBidAdapter/index.js @@ -589,7 +589,7 @@ const OPEN_RTB_PROTOCOL = { } const bidUserId = utils.deepAccess(bidRequests, '0.bids.0.userId'); - if (bidUserId && typeof bidUserId === 'object' && (bidUserId.tdid || bidUserId.pubcid || bidUserId.parrableid || bidUserId.lipb || bidUserId.id5id || bidUserId.criteoId || bidUserId.britepoolid)) { + if (bidUserId && typeof bidUserId === 'object' && (bidUserId.tdid || bidUserId.pubcid || bidUserId.parrableid || bidUserId.lipb || bidUserId.id5id || bidUserId.criteoId || bidUserId.britepoolid || bidUserId.idl_env)) { utils.deepSetValue(request, 'user.ext.eids', []); if (bidUserId.tdid) { @@ -664,6 +664,15 @@ const OPEN_RTB_PROTOCOL = { }] }); } + + if (bidUserId.idl_env) { + request.user.ext.eids.push({ + source: 'liveramp.com', + uids: [{ + id: bidUserId.idl_env + }] + }) + } } if (bidRequests) { diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index cc516567f6b..1e34080579c 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -216,7 +216,7 @@ export const spec = { } if (bidRequest.userId && typeof bidRequest.userId === 'object' && - (bidRequest.userId.tdid || bidRequest.userId.pubcid || bidRequest.userId.lipb)) { + (bidRequest.userId.tdid || bidRequest.userId.pubcid || bidRequest.userId.lipb || bidRequest.userId.idl_env)) { utils.deepSetValue(data, 'user.ext.eids', []); if (bidRequest.userId.tdid) { @@ -258,6 +258,16 @@ export const spec = { utils.deepSetValue(data, 'rp.target.LIseg', bidRequest.userId.lipb.segments); } } + + // support identityLink (aka LiveRamp) + if (bidRequest.userId.idl_env) { + data.user.ext.eids.push({ + source: 'liveramp.com', + uids: [{ + id: bidRequest.userId.idl_env + }] + }); + } } if (config.getConfig('coppa') === true) { @@ -492,6 +502,11 @@ export const spec = { data['tg_v.LIseg'] = bidRequest.userId.lipb.segments.join(','); } } + + // support identityLink (aka LiveRamp) + if (bidRequest.userId.idl_env) { + data['tpid_liveramp.com'] = bidRequest.userId.idl_env; + } } if (bidderRequest.gdprConsent) { diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index 43592d501a9..0415eace069 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -1082,7 +1082,8 @@ describe('S2S Adapter', function () { lipb: { lipbid: 'li-xyz', segments: ['segA', 'segB'] - } + }, + idl_env: '0000-1111-2222-3333' }; adapter.callBids(REQUEST, userIdBidRequest, addBidResponse, done, ajax); @@ -1102,6 +1103,8 @@ describe('S2S Adapter', function () { expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveintent.com')[0].ext.segments.length).is.equal(2); expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveintent.com')[0].ext.segments[0]).is.equal('segA'); expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveintent.com')[0].ext.segments[1]).is.equal('segB'); + // LiveRamp should exist + expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveramp.com')[0].uids[0].id).is.equal('0000-1111-2222-3333'); }); it('when config \'currency.adServerCurrency\' value is an array: ORTB has property \'cur\' value set to a single item array', function () { diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 42348036bfe..7adedbcfdde 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -224,7 +224,8 @@ describe('the rubicon adapter', function () { lipb: { lipbid: '0000-1111-2222-3333', segments: ['segA', 'segB'] - } + }, + idl_env: '1111-2222-3333-4444' }; bid.storedAuctionResponse = 11111; } @@ -1305,6 +1306,19 @@ describe('the rubicon adapter', function () { expect(unescapedData.indexOf('&tg_v.LIseg=segD,segE&') !== -1).to.equal(true); }); }); + + describe('LiveRamp support', function () { + it('should send tpid_liveramp.com when userId defines idl_env', function () { + const clonedBid = utils.deepClone(bidderRequest.bids[0]); + clonedBid.userId = { + idl_env: '1111-2222-3333-4444' + }; + let [request] = spec.buildRequests([clonedBid], bidderRequest); + let data = parseQuery(request.data); + + expect(data['tpid_liveramp.com']).to.equal('1111-2222-3333-4444'); + }); + }); }) describe('Prebid AdSlot', function () { @@ -1418,6 +1432,9 @@ describe('the rubicon adapter', function () { expect(post.user.ext.tpid).that.is.an('object'); expect(post.user.ext.tpid.source).to.equal('liveintent.com'); expect(post.user.ext.tpid.uid).to.equal('0000-1111-2222-3333'); + // LiveRamp should exist + expect(post.user.ext.eids[1].source).to.equal('liveramp.com'); + expect(post.user.ext.eids[1].uids[0].id).to.equal('1111-2222-3333-4444'); expect(post.rp).that.is.an('object'); expect(post.rp.target).that.is.an('object'); expect(post.rp.target.LIseg).that.is.an('array'); From b66837976331053cb0cccb100f8079b6b1e97194 Mon Sep 17 00:00:00 2001 From: AdGlare Ad Server <37909027+adglare@users.noreply.github.com> Date: Fri, 21 Feb 2020 19:23:25 +0200 Subject: [PATCH 071/496] New Bidder Adapter: AdGlare Ad Server (#4808) * Create adglareBidAdapter.js Initial version AdGlare adapter. * Create adglareBidAdapter.md * Create adglareBidAdapter_spec.js * Complying to CircleCI * Complying with CircleCI * Implemented changes as requested * Added test for buildRequests() function * Complying with CircleCI * Complying with CircleCI * Complying with CircleCI * Complying with CircleCI * Complying with CircleCI * Complying with CircleCI * Complying with CircleCI * Complying with CircleCI * Update adglareBidAdapter_spec.js * Update adglareBidAdapter_spec.js * Update adglareBidAdapter_spec.js * Update adglareBidAdapter.js * Update adglareBidAdapter.js --- modules/adglareBidAdapter.js | 90 +++++++++++++ modules/adglareBidAdapter.md | 36 +++++ test/spec/modules/adglareBidAdapter_spec.js | 138 ++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 modules/adglareBidAdapter.js create mode 100644 modules/adglareBidAdapter.md create mode 100644 test/spec/modules/adglareBidAdapter_spec.js diff --git a/modules/adglareBidAdapter.js b/modules/adglareBidAdapter.js new file mode 100644 index 00000000000..95fb10698f5 --- /dev/null +++ b/modules/adglareBidAdapter.js @@ -0,0 +1,90 @@ +'use strict'; + +import {registerBidder} from '../src/adapters/bidderFactory'; + +const BIDDER_CODE = 'adglare'; + +export const spec = { + code: BIDDER_CODE, + isBidRequestValid: function (bid) { + let p = bid.params; + if (typeof p.domain === 'string' && !!p.domain.length && p.zID && !isNaN(p.zID) && p.type == 'banner') return true; + return false; + }, + buildRequests: function (validBidRequests, bidderRequest) { + let i; + let j; + let bidRequest; + let zID; + let domain; + let keywords; + let url; + let type; + let availscreen = window.innerWidth + 'x' + window.innerHeight; + let pixelRatio = window.devicePixelRatio || 1; + let screen = (pixelRatio * window.screen.width) + 'x' + (pixelRatio * window.screen.height); + let sizes = []; + let serverRequests = []; + let timeout = bidderRequest.timeout || 0; + let referer = bidderRequest.refererInfo.referer || ''; + let reachedtop = bidderRequest.refererInfo.reachedTop || ''; + for (i = 0; i < validBidRequests.length; i++) { + bidRequest = validBidRequests[i]; + zID = bidRequest.params.zID; + domain = bidRequest.params.domain; + keywords = bidRequest.params.keywords || ''; + type = bidRequest.params.type; + + // Build ad unit sizes + if (bidRequest.mediaTypes && bidRequest.mediaTypes[type]) { + for (j in bidRequest.mediaTypes[type].sizes) { + sizes.push(bidRequest.mediaTypes[type].sizes[j].join('x')); + } + } + + // Build URL + url = 'https://' + domain + '/?' + encodeURIComponent(zID) + '&pbjs&pbjs_version=1'; + url += '&pbjs_type=' + encodeURIComponent(type); + url += '&pbjs_timeout=' + encodeURIComponent(timeout); + url += '&pbjs_reachedtop=' + encodeURIComponent(reachedtop); + url += '&sizes=' + encodeURIComponent(sizes.join(',')); + url += '&screen=' + encodeURIComponent(screen); + url += '&availscreen=' + encodeURIComponent(availscreen); + url += '&referer=' + encodeURIComponent(referer); + if (keywords !== '') { + url += '&keywords=' + encodeURIComponent(keywords); + } + + // Push server request + serverRequests.push({ + method: 'GET', + url: url, + data: {}, + bidRequest: bidRequest + }); + } + return serverRequests; + }, + interpretResponse: function (serverResponse, request) { + const bidObj = request.bidRequest; + let bidResponses = []; + let bidResponse = {}; + serverResponse = serverResponse.body; + + if (serverResponse && serverResponse.status == 'OK' && bidObj) { + bidResponse.requestId = bidObj.bidId; + bidResponse.bidderCode = bidObj.bidder; + bidResponse.cpm = serverResponse.cpm; + bidResponse.width = serverResponse.width; + bidResponse.height = serverResponse.height; + bidResponse.ad = serverResponse.adhtml; + bidResponse.ttl = serverResponse.ttl; + bidResponse.creativeId = serverResponse.crID; + bidResponse.netRevenue = true; + bidResponse.currency = serverResponse.currency; + bidResponses.push(bidResponse); + } + return bidResponses; + }, +}; +registerBidder(spec); diff --git a/modules/adglareBidAdapter.md b/modules/adglareBidAdapter.md new file mode 100644 index 00000000000..845564473c7 --- /dev/null +++ b/modules/adglareBidAdapter.md @@ -0,0 +1,36 @@ +# Overview + +``` +Module Name: AdGlare Ad Server Adapter +Module Type: Bidder Adapter +Maintainer: prebid@adglare.com +``` + +# Description + +Adapter that connects to your AdGlare Ad Server. +Including support for your white label ad serving domain. + +# Test Parameters +``` + var adUnits = [ + { + code: 'your-div-id', + mediaTypes: { + banner: { + sizes: [[300,250], [728,90]], + } + }, + bids: [ + { + bidder: 'adglare', + params: { + domain: 'try.engine.adglare.net', + zID: '475579334', + type: 'banner' + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/adglareBidAdapter_spec.js b/test/spec/modules/adglareBidAdapter_spec.js new file mode 100644 index 00000000000..5b8d1a45f72 --- /dev/null +++ b/test/spec/modules/adglareBidAdapter_spec.js @@ -0,0 +1,138 @@ +import {expect} from 'chai'; +import {spec} from 'modules/adglareBidAdapter'; + +describe('AdGlare Adapter Tests', function () { + let bidRequests; + + beforeEach(function () { + bidRequests = [ + { + bidder: 'adglare', + params: { + domain: 'try.engine.adglare.net', + zID: '475579334', + type: 'banner' + }, + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + }, + }, + bidId: '23acc48ad47af5', + auctionId: '0fb4905b-9456-4152-86be-c6f6d259ba99', + bidderRequestId: '1c56ad30b9b8ca8', + transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' + } + ]; + }); + + describe('implementation', function () { + describe('for requests', function () { + it('should accept valid bid', function () { + let validBid = { + bidder: 'adglare', + params: { + domain: 'try.engine.adglare.net', + zID: '475579334', + type: 'banner' + } + }, + isValid = spec.isBidRequestValid(validBid); + + expect(isValid).to.equal(true); + }); + + it('should reject invalid bid', function () { + let invalidBid = { + bidder: 'adglare', + params: { + domain: 'somedomain.com', + zID: 'not an integer', + type: 'unsupported' + } + }, + isValid = spec.isBidRequestValid(invalidBid); + + expect(isValid).to.equal(false); + }); + + it('should build a valid endpoint URL', function () { + let bidRequests = [ + { + bidder: 'adglare', + params: { + domain: 'try.engine.adglare.net', + zID: '475579334', + type: 'banner' + }, + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + }, + }, + bidId: '23acc48ad47af5', + auctionId: '0fb4905b-9456-4152-86be-c6f6d259ba99', + bidderRequestId: '1c56ad30b9b8ca8', + transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' + } + ], + bidderRequest = { + bidderCode: 'adglare', + auctionID: '0fb4905b-9456-4152-86be-c6f6d259ba99', + bidderRequestId: '1c56ad30b9b8ca8', + auctionStart: 1581497568252, + timeout: 5000, + refererInfo: { + referer: 'https://www.somedomain.com', + reachedTop: true, + numFrames: 0 + }, + start: 1581497568254 + }, + requests = spec.buildRequests(bidRequests, bidderRequest), + requestURL = requests[0].url; + + expect(requestURL).to.have.string('https://try.engine.adglare.net/?475579334'); + }); + }); + + describe('bid responses', function () { + it('should return complete bid response', function () { + let serverResponse = { + body: { + status: 'OK', + zID: 475579334, + cID: 501658124, + crID: 442123173, + cpm: 1.5, + ttl: 3600, + currency: 'USD', + width: 300, + height: 250, + adhtml: 'I am an ad.' + } + }, + bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); + + expect(bids).to.be.lengthOf(1); + expect(bids[0].bidderCode).to.equal('adglare'); + expect(bids[0].cpm).to.equal(1.5); + expect(bids[0].width).to.equal(300); + expect(bids[0].height).to.equal(250); + expect(bids[0].currency).to.equal('USD'); + expect(bids[0].netRevenue).to.equal(true); + }); + + it('should return empty bid response', function () { + let serverResponse = { + body: { + status: 'NOADS' + } + }, + bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); + + expect(bids).to.be.lengthOf(0); + }); + }); + }); +}); From f50e0b8cd3ffd8f9de7234bcf6eeea66e27834ca Mon Sep 17 00:00:00 2001 From: Steve Alliance Date: Fri, 21 Feb 2020 17:44:20 -0500 Subject: [PATCH 072/496] Districtm dmx passing dealid to prebid (#4772) * adding DMX test @97%, two files added one updated * Update districtm_spec.js * Update districtmDMX.js * adding all districtm needed file * remove legacy file * remove typo || 0 in the test method * force default to return a valid width and height * update unit test code for failing test * changed class for an object * remove package-lock.json * change file name for dmx adapter * renamed files * restaure package-lock.json * update to last package-lock state * update gdpr user consent * fix sizes issue * Documentation updates Adding the readme.md info * update file name and update unit testing import file location * current machine state * lint correction * remove variable assigment duplicate * adding CCPA support for DMX * adding test for ccpa and gdpr * districtm dmx adding deal id field * idsync support ccpa & gdpr Co-authored-by: Luis Co-authored-by: steve-a-districtm <56413795+steve-a-districtm@users.noreply.github.com> --- modules/districtmDMXBidAdapter.js | 18 +++++++++++-- .../modules/districtmDmxBidAdapter_spec.js | 26 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/modules/districtmDMXBidAdapter.js b/modules/districtmDMXBidAdapter.js index fac275a229b..83f3ac5b3c9 100644 --- a/modules/districtmDMXBidAdapter.js +++ b/modules/districtmDMXBidAdapter.js @@ -27,6 +27,9 @@ export const spec = { nBid.requestId = nBid.impid; nBid.width = nBid.w || width; nBid.height = nBid.h || height; + if (nBid.dealid) { + nBid.dealId = nBid.dealid; + } nBid.ad = nBid.adm; nBid.netRevenue = true; nBid.creativeId = nBid.crid; @@ -130,11 +133,22 @@ export const spec = { test() { return window.location.href.indexOf('dmTest=true') !== -1 ? 1 : 0; }, - getUserSyncs(optionsType) { + getUserSyncs(optionsType, serverResponses, gdprConsent, uspConsent) { + let query = []; + let url = 'https://cdn.districtm.io/ids/index.html' + if (gdprConsent && gdprConsent.gdprApplies && typeof gdprConsent.consentString === 'string') { + query.push(['gdpr', gdprConsent.consentString]) + } + if (uspConsent) { + query.push(['ccpa', uspConsent]) + } + if (query.length > 0) { + url += '?' + query.map(q => q.join('=')).join('&') + } if (optionsType.iframeEnabled) { return [{ type: 'iframe', - url: 'https://cdn.districtm.io/ids/index.html' + url: url }]; } } diff --git a/test/spec/modules/districtmDmxBidAdapter_spec.js b/test/spec/modules/districtmDmxBidAdapter_spec.js index 90349fe042f..e7a8e8c3064 100644 --- a/test/spec/modules/districtmDmxBidAdapter_spec.js +++ b/test/spec/modules/districtmDmxBidAdapter_spec.js @@ -559,6 +559,32 @@ describe('DistrictM Adaptor', function () { }); }); + describe(`check validation for id sync gdpr ccpa`, () => { + let allin = spec.getUserSyncs({iframeEnabled: true}, {}, bidderRequest.gdprConsent, bidderRequest.uspConsent)[0] + let noCCPA = spec.getUserSyncs({iframeEnabled: true}, {}, bidderRequest.gdprConsent, null)[0] + let noGDPR = spec.getUserSyncs({iframeEnabled: true}, {}, null, bidderRequest.uspConsent)[0] + let nothing = spec.getUserSyncs({iframeEnabled: true}, {}, null, null)[0] + + /* + + 'uspConsent': '1NY', + 'gdprConsent': { + 'consentString': 'BOPqNzUOPqNzUAHABBAAA5AAAAAAAA', + */ + it(`gdpr & ccpa should be present`, () => { + expect(allin.url).to.be.equal('https://cdn.districtm.io/ids/index.html?gdpr=BOPqNzUOPqNzUAHABBAAA5AAAAAAAA&ccpa=1NY') + }) + it(`ccpa should be present`, () => { + expect(noGDPR.url).to.be.equal('https://cdn.districtm.io/ids/index.html?ccpa=1NY') + }) + it(`gdpr should be present`, () => { + expect(noCCPA.url).to.be.equal('https://cdn.districtm.io/ids/index.html?gdpr=BOPqNzUOPqNzUAHABBAAA5AAAAAAAA') + }) + it(`gdpr & ccpa shouldn't be present`, () => { + expect(nothing.url).to.be.equal('https://cdn.districtm.io/ids/index.html') + }) + }) + describe(`Helper function testing`, function () { const bid = matchRequest('29a28a1bbc8a8d', {bidderRequest}); const {width, height} = defaultSize(bid); From d357f7e7dde292b3df1b65db73d938f4a1837299 Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Mon, 24 Feb 2020 05:32:43 -0800 Subject: [PATCH 073/496] update imports to include extensions (#4886) --- modules/adglareBidAdapter.js | 2 +- test/spec/modules/adglareBidAdapter_spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/adglareBidAdapter.js b/modules/adglareBidAdapter.js index 95fb10698f5..d66a38482ec 100644 --- a/modules/adglareBidAdapter.js +++ b/modules/adglareBidAdapter.js @@ -1,6 +1,6 @@ 'use strict'; -import {registerBidder} from '../src/adapters/bidderFactory'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'adglare'; diff --git a/test/spec/modules/adglareBidAdapter_spec.js b/test/spec/modules/adglareBidAdapter_spec.js index 5b8d1a45f72..d0dbe891f9d 100644 --- a/test/spec/modules/adglareBidAdapter_spec.js +++ b/test/spec/modules/adglareBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from 'modules/adglareBidAdapter'; +import {spec} from 'modules/adglareBidAdapter.js'; describe('AdGlare Adapter Tests', function () { let bidRequests; From 241292425c758c7a54126cac226d3f3b06401821 Mon Sep 17 00:00:00 2001 From: kamilf92 Date: Mon, 24 Feb 2020 15:38:17 +0100 Subject: [PATCH 074/496] OpenX adapter: support Criteo ID (#4882) * added criteo support to openx adapter * lint fix * fixing unit test variable name Co-authored-by: bretg --- modules/openxBidAdapter.js | 3 ++- test/spec/modules/openxBidAdapter_spec.js | 31 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/modules/openxBidAdapter.js b/modules/openxBidAdapter.js index a895e64b897..b0d1ae3a075 100644 --- a/modules/openxBidAdapter.js +++ b/modules/openxBidAdapter.js @@ -12,7 +12,8 @@ const BIDDER_VERSION = '3.0.1'; const USER_ID_CODE_TO_QUERY_ARG = { idl_env: 'lre', // liveramp pubcid: 'pubcid', // publisher common id - tdid: 'ttduuid' // the trade desk + tdid: 'ttduuid', // the trade desk + criteoId: 'criteoid' // criteo id }; export const spec = { diff --git a/test/spec/modules/openxBidAdapter_spec.js b/test/spec/modules/openxBidAdapter_spec.js index 9d6359e712a..66e59ad6f3b 100644 --- a/test/spec/modules/openxBidAdapter_spec.js +++ b/test/spec/modules/openxBidAdapter_spec.js @@ -1142,6 +1142,37 @@ describe('OpenxAdapter', function () { expect(request[0].data.lre).to.equal('00000000-aaaa-1111-bbbb-222222222222'); }); }); + + describe('with the criteo id for exchanges', function () { + it('should not send a criteoid query param when there is no userId.criteoId defined in the bid requests', function () { + const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest); + expect(request[0].data).to.not.have.any.keys('criteoid'); + }); + + it('should send a criteoid query param when userId.criteoId is defined in the bid requests', function () { + const bidRequestsWithCriteo = [{ + bidder: 'openx', + params: { + unit: '11', + delDomain: 'test-del-domain' + }, + userId: { + criteoId: '00000000-aaaa-1111-bbbb-222222222222' + }, + adUnitCode: 'adunit-code', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]] + } + }, + bidId: 'test-bid-id-1', + bidderRequestId: 'test-bid-request-1', + auctionId: 'test-auction-1' + }]; + const request = spec.buildRequests(bidRequestsWithCriteo, mockBidderRequest); + expect(request[0].data.criteoid).to.equal('00000000-aaaa-1111-bbbb-222222222222'); + }); + }); }); }); From 9f72231b2b9d94814bf402fe592dd37e05d2154a Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Mon, 24 Feb 2020 12:01:00 -0500 Subject: [PATCH 075/496] update criteo userid in appnexus bid adapter (#4862) --- modules/appnexusBidAdapter.js | 6 +++--- test/spec/modules/appnexusBidAdapter_spec.js | 6 +----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 0334479b716..9f107bf54ec 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -182,12 +182,12 @@ export const spec = { }); } - const rtusId = utils.deepAccess(bidRequests[0], `userId.criteortus.${BIDDER_CODE}.userid`); - if (rtusId) { + const criteoId = utils.deepAccess(bidRequests[0], `userId.criteoId`); + if (criteoId) { let tpuids = []; tpuids.push({ 'provider': 'criteo', - 'user_id': rtusId + 'user_id': criteoId }); payload.tpuids = tpuids; } diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js index ec2314ea460..a3d019c83d2 100644 --- a/test/spec/modules/appnexusBidAdapter_spec.js +++ b/test/spec/modules/appnexusBidAdapter_spec.js @@ -681,11 +681,7 @@ describe('AppNexusAdapter', function () { it('should populate tpids array when userId is available', function () { const bidRequest = Object.assign({}, bidRequests[0], { userId: { - criteortus: { - appnexus: { - userid: 'sample-userid' - } - } + criteoId: 'sample-userid' } }); From 2fdecfe8786fb4cb2a814ecee7a9ee6d67fd4d5f Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Mon, 24 Feb 2020 10:38:22 -0800 Subject: [PATCH 076/496] Rubicon analytics passes referrerHostname (#4885) * analytics passes referrerHostname * adding it to expected message --- modules/rubiconAnalyticsAdapter.js | 11 ++++++++++- test/spec/modules/rubiconAnalyticsAdapter_spec.js | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/modules/rubiconAnalyticsAdapter.js b/modules/rubiconAnalyticsAdapter.js index 817779dbb64..939afc42f6d 100644 --- a/modules/rubiconAnalyticsAdapter.js +++ b/modules/rubiconAnalyticsAdapter.js @@ -4,6 +4,7 @@ import CONSTANTS from '../src/constants.json'; import { ajax } from '../src/ajax.js'; import { config } from '../src/config.js'; import * as utils from '../src/utils.js'; +import * as urlLib from '../src/url.js' const { EVENTS: { @@ -36,6 +37,13 @@ const cache = { timeouts: {}, }; +let referrerHostname; + +function getHostNameFromReferer(referer) { + referrerHostname = urlLib.parse(referer).hostname; + return referrerHostname; +}; + function stringProperties(obj) { return Object.keys(obj).reduce((newObj, prop) => { let value = obj[prop]; @@ -115,7 +123,8 @@ function sendMessage(auctionId, bidWonId) { eventTimeMillis: Date.now(), integration: config.getConfig('rubicon.int_type') || DEFAULT_INTEGRATION, version: '$prebid.version$', - referrerUri: referrer + referrerUri: referrer, + referrerHostname: referrerHostname || getHostNameFromReferer(referrer) }; const wrapperName = config.getConfig('rubicon.wrapperName'); if (wrapperName) { diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js index 6c99b6a6b00..2ad828ef3e0 100644 --- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js +++ b/test/spec/modules/rubiconAnalyticsAdapter_spec.js @@ -274,6 +274,7 @@ const ANALYTICS_MESSAGE = { 'integration': 'pbjs', 'version': '$prebid.version$', 'referrerUri': 'http://www.test.com/page.html', + 'referrerHostname': 'www.test.com', 'auctions': [ { 'clientTimeoutMillis': 3000, From 01390ac09c539a4f370228569c57bfeeee5dc1f9 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Mon, 24 Feb 2020 11:38:05 -0800 Subject: [PATCH 077/496] PubMatic adapter to support PM Deals (#4887) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * PubMatic to support deals param * more than 3 chars check added --- modules/pubmaticBidAdapter.js | 24 ++++- modules/pubmaticBidAdapter.md | 3 +- test/spec/modules/pubmaticBidAdapter_spec.js | 106 +++++++++++++++++++ 3 files changed, 131 insertions(+), 2 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index e2bf57bc5a6..1a5de695c3c 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -496,6 +496,26 @@ function _createVideoRequest(bid) { return videoObj; } +// support for PMP deals +function _addPMPDealsInImpression(impObj, bid) { + if (bid.params.deals) { + if (utils.isArray(bid.params.deals)) { + bid.params.deals.forEach(function(dealId) { + if (utils.isStr(dealId) && dealId.length > 3) { + if (!impObj.pmp) { + impObj.pmp = { private_auction: 0, deals: [] }; + } + impObj.pmp.deals.push({ id: dealId }); + } else { + utils.logWarn(LOG_WARN_PREFIX + 'Error: deal-id present in array bid.params.deals should be a strings with more than 3 charaters length, deal-id ignored: ' + dealId); + } + }); + } else { + utils.logWarn(LOG_WARN_PREFIX + 'Error: bid.params.deals should be an array of strings.'); + } + } +} + function _createImpressionObject(bid, conf) { var impObj = {}; var bannerObj; @@ -516,6 +536,8 @@ function _createImpressionObject(bid, conf) { bidfloorcur: bid.params.currency ? _parseSlotParam('currency', bid.params.currency) : DEFAULT_CURRENCY }; + _addPMPDealsInImpression(impObj, bid); + if (bid.hasOwnProperty('mediaTypes')) { for (mediaTypes in bid.mediaTypes) { switch (mediaTypes) { @@ -747,7 +769,7 @@ function _blockedIabCategoriesValidation(payload, blockedIabCategories) { } }) .map(category => category.trim()) // trim all - .filter(function(category, index, arr) { // minimum 3 charaters length + .filter(function(category, index, arr) { // more than 3 charaters length if (category.length > 3) { return arr.indexOf(category) === index; // unique value only } else { diff --git a/modules/pubmaticBidAdapter.md b/modules/pubmaticBidAdapter.md index fc7766430a2..4a5d881a637 100644 --- a/modules/pubmaticBidAdapter.md +++ b/modules/pubmaticBidAdapter.md @@ -35,7 +35,8 @@ var adUnits = [ kadfloor: '0.50', // optional currency: 'AUD', // optional (Value configured only in the 1st adunit will be passed on. < br/> Values if present in subsequent adunits, will be ignored.) dctr: 'key1=123|key2=345', // optional (Value configured only in the 1st adunit will be passed on. < br/> Values if present in subsequent adunits, will be ignored.) - bcat: ['IAB1-5', 'IAB1-7'] // Optional: Blocked IAB Categories. (Values from all slots will be combined and only unique values will be passed. An array of strings only. Each category should be a string of a length of more than 3 characters.) + bcat: ['IAB1-5', 'IAB1-7'], // Optional: Blocked IAB Categories. (Values from all slots will be combined and only unique values will be passed. An array of strings only. Each category should be a string of a length of more than 3 characters.) + deals: ['deal-id-1', 'deal-id-200'] // optional: PMP Deals, should be array of strings } }] }]; diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index b54bcc15bc3..5c2f1f76b2e 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -2299,6 +2299,112 @@ describe('PubMatic adapter', function () { expect(data.site.ext).to.not.exist; }); + it('Request params deals check', function () { + let multipleBidRequests = [ + { + bidder: 'pubmatic', + params: { + publisherId: '301', + adSlot: '/15671365/DMDemo@300x250:0', + kadfloor: '1.2', + pmzoneid: 'aabc, ddef', + kadpageurl: 'www.publisher.com', + yob: '1986', + gender: 'M', + lat: '12.3', + lon: '23.7', + wiid: '1234567890', + profId: '100', + verId: '200', + currency: 'AUD', + deals: ['deal-id-1', 'deal-id-2', 'dea'] // "dea" will not be passed as more than 3 characters needed + }, + placementCode: '/19968336/header-bid-tag-1', + sizes: [[300, 250], [300, 600]], + bidId: '23acc48ad47af5', + requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', + bidderRequestId: '1c56ad30b9b8ca8', + transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' + }, + { + bidder: 'pubmatic', + params: { + publisherId: '301', + adSlot: '/15671365/DMDemo@300x250:0', + kadfloor: '1.2', + pmzoneid: 'aabc, ddef', + kadpageurl: 'www.publisher.com', + yob: '1986', + gender: 'M', + lat: '12.3', + lon: '23.7', + wiid: '1234567890', + profId: '100', + verId: '200', + currency: 'GBP', + deals: ['deal-id-100', 'deal-id-200'] + }, + placementCode: '/19968336/header-bid-tag-1', + sizes: [[300, 250], [300, 600]], + bidId: '23acc48ad47af5', + requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', + bidderRequestId: '1c56ad30b9b8ca8', + transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' + } + ]; + + let request = spec.buildRequests(multipleBidRequests); + let data = JSON.parse(request.data); + // case 1 - deals are passed as expected, ['', ''] , in both adUnits + expect(data.imp[0].pmp).to.deep.equal({ + 'private_auction': 0, + 'deals': [ + { + 'id': 'deal-id-1' + }, + { + 'id': 'deal-id-2' + } + ] + }); + expect(data.imp[1].pmp).to.deep.equal({ + 'private_auction': 0, + 'deals': [ + { + 'id': 'deal-id-100' + }, + { + 'id': 'deal-id-200' + } + ] + }); + + // case 2 - deals not present in adunit[0] + delete multipleBidRequests[0].params.deals; + request = spec.buildRequests(multipleBidRequests); + data = JSON.parse(request.data); + expect(data.imp[0].pmp).to.not.exist; + + // case 3 - deals is present in adunit[0], but is not an array + multipleBidRequests[0].params.deals = 123; + request = spec.buildRequests(multipleBidRequests); + data = JSON.parse(request.data); + expect(data.imp[0].pmp).to.not.exist; + + // case 4 - deals is present in adunit[0] as an array but one of the value is not a string + multipleBidRequests[0].params.deals = [123, 'deal-id-1']; + request = spec.buildRequests(multipleBidRequests); + data = JSON.parse(request.data); + expect(data.imp[0].pmp).to.deep.equal({ + 'private_auction': 0, + 'deals': [ + { + 'id': 'deal-id-1' + } + ] + }); + }); + describe('Request param bcat checking', function() { let multipleBidRequests = [ { From ac0ce271b3821e4b157a0b415770e429254f604e Mon Sep 17 00:00:00 2001 From: daisato-tsumiki Date: Tue, 25 Feb 2020 14:30:28 +0900 Subject: [PATCH 078/496] update ByPlay Adapter (#4854) --- modules/byplayBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/byplayBidAdapter.js b/modules/byplayBidAdapter.js index b5156e4bd99..6133cdfa647 100644 --- a/modules/byplayBidAdapter.js +++ b/modules/byplayBidAdapter.js @@ -57,7 +57,7 @@ function createRenderer() { renderer.setRender(bid => { bid.renderer.push(() => { - window.adtagRender(bid.vastXml); + window.adtagRender(bid); }); }); From 90228067cb3c21e0ce700b376682d12cdce85338 Mon Sep 17 00:00:00 2001 From: Eddy Pechuzal <46331062+epechuzal@users.noreply.github.com> Date: Tue, 25 Feb 2020 07:13:37 -0800 Subject: [PATCH 079/496] Always use HTTPS when serving within an iframe (#4859) * ALways use HTTPS to request sfp.js * Increment adapter version * Fix spec --- modules/sharethroughBidAdapter.js | 4 ++-- test/spec/modules/sharethroughBidAdapter_spec.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/sharethroughBidAdapter.js b/modules/sharethroughBidAdapter.js index 4c73cb2c28f..f687311f461 100644 --- a/modules/sharethroughBidAdapter.js +++ b/modules/sharethroughBidAdapter.js @@ -1,6 +1,6 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; -const VERSION = '3.2.0'; +const VERSION = '3.2.1'; const BIDDER_CODE = 'sharethrough'; const STR_ENDPOINT = 'https://btlr.sharethrough.com/WYu2BXv1/v1'; const DEFAULT_SIZE = [1, 1]; @@ -153,7 +153,7 @@ function generateAd(body, req) { if (req.strData.skipIframeBusting) { // Don't break out of iframe - adMarkup = adMarkup + ``; + adMarkup = adMarkup + ``; } else { // Add logic to the markup that detects whether or not in top level document is accessible // this logic will deploy sfp.js and/or iframe buster script(s) as appropriate diff --git a/test/spec/modules/sharethroughBidAdapter_spec.js b/test/spec/modules/sharethroughBidAdapter_spec.js index 0ddb113e062..92f9fd11eeb 100644 --- a/test/spec/modules/sharethroughBidAdapter_spec.js +++ b/test/spec/modules/sharethroughBidAdapter_spec.js @@ -457,7 +457,7 @@ describe('sharethrough adapter spec', function () { /data-str-native-key="pKey" data-stx-response-name="str_response_bidId"/); expect(!!adMarkup.indexOf(resp)).to.eql(true); expect(adMarkup).to.match( - /` } - if (isVideo(bidRequest)) { + if (isVideo(bidRequest, adType)) { const playersize = getPlayerSize(bidRequest) if (playersize) { bidResponse.width = playersize[0] @@ -124,10 +126,11 @@ export const spec = { /** * Is this a video format? * @param {Object} format + * @param {String} adtype * @returns {Boolean} */ -function isVideo (format) { - return utils.deepAccess(format, 'mediaTypes.video') +function isVideo (format, adtype) { + return utils.deepAccess(format, 'mediaTypes.video') && adtype.toLowerCase() === 'video' } /** diff --git a/test/spec/modules/yieldlabBidAdapter_spec.js b/test/spec/modules/yieldlabBidAdapter_spec.js index 43a18bce094..584a9040bcf 100644 --- a/test/spec/modules/yieldlabBidAdapter_spec.js +++ b/test/spec/modules/yieldlabBidAdapter_spec.js @@ -27,9 +27,14 @@ const RESPONSE = { format: 0, id: 1111, price: 1, - pid: 2222 + pid: 2222, + adtype: 'BANNER' } +const VIDEO_RESPONSE = Object.assign({}, RESPONSE, { + 'adtype': 'VIDEO' +}) + describe('yieldlabBidAdapter', function () { const adapter = newBidder(spec) @@ -140,7 +145,7 @@ describe('yieldlabBidAdapter', function () { } } }) - const result = spec.interpretResponse({body: [RESPONSE]}, {validBidRequests: [VIDEO_REQUEST]}) + const result = spec.interpretResponse({body: [VIDEO_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST]}) expect(result[0].requestId).to.equal('2d925f27f5079f') expect(result[0].cpm).to.equal(0.01) @@ -158,7 +163,7 @@ describe('yieldlabBidAdapter', function () { } } }) - const result = spec.interpretResponse({body: [RESPONSE]}, {validBidRequests: [OUTSTREAM_REQUEST]}) + const result = spec.interpretResponse({body: [VIDEO_RESPONSE]}, {validBidRequests: [OUTSTREAM_REQUEST]}) expect(result[0].renderer.id).to.equal('2d925f27f5079f') expect(result[0].renderer.url).to.equal('https://ad2.movad.net/dynamic.ad?a=o193092&ma_loadEvent=ma-start-event') From cd0fdb87c6aec7e5a8b7b462bdc0bb1a0ba01fd2 Mon Sep 17 00:00:00 2001 From: Stephen Johnston Date: Thu, 5 Mar 2020 15:19:07 -0500 Subject: [PATCH 101/496] added vdo.ai bidder adapter (#4814) --- modules/vdoaiBidAdapter.js | 119 ++++++++++++++++++++++ modules/vdoaiBidAdapter.md | 34 +++++++ test/spec/modules/vdoaiBidAdapter_spec.js | 105 +++++++++++++++++++ 3 files changed, 258 insertions(+) create mode 100644 modules/vdoaiBidAdapter.js create mode 100644 modules/vdoaiBidAdapter.md create mode 100644 test/spec/modules/vdoaiBidAdapter_spec.js diff --git a/modules/vdoaiBidAdapter.js b/modules/vdoaiBidAdapter.js new file mode 100644 index 00000000000..48e6081b2d9 --- /dev/null +++ b/modules/vdoaiBidAdapter.js @@ -0,0 +1,119 @@ +import * as utils from '../src/utils'; +import {config} from '../src/config'; +import {registerBidder} from '../src/adapters/bidderFactory'; +import {BANNER} from '../src/mediaTypes'; + +const BIDDER_CODE = 'vdo.ai'; +const ENDPOINT_URL = 'https://prebid.vdo.ai/auction'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER], + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bid) { + return !!(bid.params.placementId); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @return Array Info describing the request to the server. + * @param validBidRequests + * @param bidderRequest + */ + buildRequests: function (validBidRequests, bidderRequest) { + if (validBidRequests.length === 0) { + return []; + } + return validBidRequests.map(bidRequest => { + const sizes = utils.parseSizesInput(bidRequest.params.size || bidRequest.sizes)[0]; + const width = sizes.split('x')[0]; + const height = sizes.split('x')[1]; + const payload = { + placementId: bidRequest.params.placementId, + width: width, + height: height, + bidId: bidRequest.bidId, + referer: bidderRequest.refererInfo.referer, + id: bidRequest.auctionId + }; + bidRequest.params.bidFloor && (payload['bidFloor'] = bidRequest.params.bidFloor); + return { + method: 'POST', + url: ENDPOINT_URL, + data: payload + }; + }); + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {ServerResponse} serverResponse A successful response from the server. + * @param bidRequest + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function (serverResponse, bidRequest) { + const bidResponses = []; + const response = serverResponse.body; + const creativeId = response.adid || 0; + // const width = response.w || 0; + const width = bidRequest.data.width; + // const height = response.h || 0; + const height = bidRequest.data.height; + const cpm = response.price || 0; + + response.rWidth = width; + response.rHeight = height; + + const adCreative = response.vdoCreative; + + if (width !== 0 && height !== 0 && cpm !== 0 && creativeId !== 0) { + // const dealId = response.dealid || ''; + const currency = response.cur || 'USD'; + const netRevenue = true; + // const referrer = bidRequest.data.referer; + const bidResponse = { + requestId: response.bidId, + cpm: cpm, + width: width, + height: height, + creativeId: creativeId, + // dealId: dealId, + currency: currency, + netRevenue: netRevenue, + ttl: config.getConfig('_bidderTimeout'), + // referrer: referrer, + // ad: response.adm + ad: adCreative + }; + bidResponses.push(bidResponse); + } + return bidResponses; + }, + + getUserSyncs: function(syncOptions, serverResponse) { + let syncUrls = serverResponse[0] && serverResponse[0].body && serverResponse[0].body.cookiesync && serverResponse[0].body.cookiesync.bidder_status; + + if (syncOptions.iframeEnabled && syncUrls && syncUrls.length > 0) { + let prebidSyncUrls = syncUrls.map(syncObj => { + return { + url: syncObj.usersync.url, + type: 'iframe' + } + }) + return prebidSyncUrls; + } + return []; + }, + + onTImeout: function(data) {}, + onBidWon: function(bid) {}, + onSetTargeting: function(bid) {} +}; +registerBidder(spec); diff --git a/modules/vdoaiBidAdapter.md b/modules/vdoaiBidAdapter.md new file mode 100644 index 00000000000..81bd8e69c1d --- /dev/null +++ b/modules/vdoaiBidAdapter.md @@ -0,0 +1,34 @@ +# Overview + +``` +Module Name: VDO.AI Bidder Adapter +Module Type: Bidder Adapter +Maintainer: arjit@z1media.com +``` + +# Description + +Module that connects to VDO.AI's demand sources + +# Test Parameters +``` + var adUnits = [ + { + code: 'test-div', + mediaTypes: { + banner: { + sizes: [[300, 250]] // a display size + } + }, + bids: [ + { + bidder: "vdo.ai", + params: { + placement: 'newsdv77', + bidFloor: 0.01 // Optional + } + } + ] + } + ]; +``` \ No newline at end of file diff --git a/test/spec/modules/vdoaiBidAdapter_spec.js b/test/spec/modules/vdoaiBidAdapter_spec.js new file mode 100644 index 00000000000..507f3ffa3ac --- /dev/null +++ b/test/spec/modules/vdoaiBidAdapter_spec.js @@ -0,0 +1,105 @@ +import {assert, expect} from 'chai'; +import {spec} from 'modules/vdoaiBidAdapter'; +import {newBidder} from 'src/adapters/bidderFactory'; + +const ENDPOINT_URL = 'https://prebid.vdo.ai/auction'; + +describe('vdoaiBidAdapter', function () { + const adapter = newBidder(spec); + describe('isBidRequestValid', function () { + let bid = { + 'bidder': 'vdo.ai', + 'params': { + placementId: 'testPlacementId' + }, + 'adUnitCode': 'adunit-code', + 'sizes': [ + [300, 250] + ], + 'bidId': '1234asdf1234', + 'bidderRequestId': '1234asdf1234asdf', + 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf120' + }; + it('should return true where required params found', function () { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + }); + describe('buildRequests', function () { + let bidRequests = [ + { + 'bidder': 'vdo.ai', + 'params': { + placementId: 'testPlacementId' + }, + 'sizes': [ + [300, 250] + ], + 'bidId': '23beaa6af6cdde', + 'bidderRequestId': '19c0c1efdf37e7', + 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', + } + ]; + + let bidderRequests = { + 'refererInfo': { + 'numIframes': 0, + 'reachedTop': true, + 'referer': 'https://example.com', + 'stack': ['https://example.com'] + } + }; + + const request = spec.buildRequests(bidRequests, bidderRequests); + it('sends bid request to our endpoint via POST', function () { + expect(request[0].method).to.equal('POST'); + }); + it('attaches source and version to endpoint URL as query params', function () { + expect(request[0].url).to.equal(ENDPOINT_URL); + }); + }); + + describe('interpretResponse', function () { + let bidRequest = [ + { + 'method': 'POST', + 'url': ENDPOINT_URL, + 'data': { + 'placementId': 'testPlacementId', + 'width': '300', + 'height': '200', + 'bidId': 'bidId123', + 'referer': 'www.example.com' + } + + } + ]; + let serverResponse = { + body: { + 'vdoCreative': '

I am an ad

', + 'price': 4.2, + 'adid': '12345asdfg', + 'currency': 'EUR', + 'statusMessage': 'Bid available', + 'requestId': 'bidId123', + 'width': 300, + 'height': 250, + 'netRevenue': true + } + }; + it('should get the correct bid response', function () { + let expectedResponse = [{ + 'requestId': 'bidId123', + 'cpm': 4.2, + 'width': 300, + 'height': 250, + 'creativeId': '12345asdfg', + 'currency': 'EUR', + 'netRevenue': true, + 'ttl': 3000, + 'ad': '

I am an ad

' + }]; + let result = spec.interpretResponse(serverResponse, bidRequest[0]); + expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); + }); + }); +}); From b71bed18ae615a8d1def8ec52a491dcd4f7c79bb Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Thu, 5 Mar 2020 15:30:16 -0500 Subject: [PATCH 102/496] Audigent Segmentation Real-time Data Provider (#4834) * audigentRtdProvider * fix line error * fix tests * deep equal test fix * conditionally set data in html5 local storage, add markdown readme * add integration test instructions to audigent readme --- .../gpt/audigentSegments_example.html | 262 ++++++++++++++++++ modules/audigentRtdProvider.js | 138 +++++++++ modules/audigentRtdProvider.md | 52 ++++ test/spec/modules/realTimeModule_spec.js | 53 +++- 4 files changed, 504 insertions(+), 1 deletion(-) create mode 100644 integrationExamples/gpt/audigentSegments_example.html create mode 100644 modules/audigentRtdProvider.js create mode 100644 modules/audigentRtdProvider.md diff --git a/integrationExamples/gpt/audigentSegments_example.html b/integrationExamples/gpt/audigentSegments_example.html new file mode 100644 index 00000000000..9b72da76d23 --- /dev/null +++ b/integrationExamples/gpt/audigentSegments_example.html @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + +

Audigent Segments Prebid

+ +
+ +
+TDID: +
+
+ +Audigent Segments: +
+
+ + diff --git a/modules/audigentRtdProvider.js b/modules/audigentRtdProvider.js new file mode 100644 index 00000000000..8b45287bddc --- /dev/null +++ b/modules/audigentRtdProvider.js @@ -0,0 +1,138 @@ +/** + * This module adds audigent provider to the real time data module + * The {@link module:modules/realTimeData} module is required + * The module will fetch segments from audigent server + * @module modules/audigentRtdProvider + * @requires module:modules/realTimeData + */ + +/** + * @typedef {Object} ModuleParams + * @property {string} siteKey + * @property {string} pubKey + * @property {string} url + * @property {?string} keyName + * @property {number} auctionDelay + */ + +import {config} from '../src/config.js'; +import {getGlobal} from '../src/prebidGlobal.js'; +import * as utils from '../src/utils.js'; +import {submodule} from '../src/hook.js'; +import {ajax} from '../src/ajax.js'; + +/** @type {string} */ +const MODULE_NAME = 'realTimeData'; + +/** @type {ModuleParams} */ +let _moduleParams = {}; + +/** + * XMLHttpRequest to get data form audigent server + * @param {string} url server url with query params + */ + +export function setData(data) { + utils.setDataInLocalStorage('__adgntseg', JSON.stringify(data)); +} + +function getSegments(adUnits, onDone) { + try { + let jsonData = utils.getDataFromLocalStorage('__adgntseg'); + if (jsonData) { + let data = JSON.parse(jsonData); + if (data.audigent_segments) { + let dataToReturn = adUnits.reduce((rp, cau) => { + const adUnitCode = cau && cau.code; + if (!adUnitCode) { return rp } + rp[adUnitCode] = data; + return rp; + }, {}); + + onDone(dataToReturn); + return; + } + } + getSegmentsAsync(adUnits, onDone); + } catch (e) { + getSegmentsAsync(adUnits, onDone); + } +} + +function getSegmentsAsync(adUnits, onDone) { + const userIds = (getGlobal()).getUserIds(); + let tdid = null; + + if (userIds && userIds['tdid']) { + tdid = userIds['tdid']; + } else { + onDone({}); + } + + const url = `https://seg.ad.gt/api/v1/rtb_segments?tdid=${tdid}`; + + ajax(url, { + success: function (response, req) { + if (req.status === 200) { + try { + const data = JSON.parse(response); + if (data && data.audigent_segments) { + setData(data); + let dataToReturn = adUnits.reduce((rp, cau) => { + const adUnitCode = cau && cau.code; + if (!adUnitCode) { return rp } + rp[adUnitCode] = data; + return rp; + }, {}); + + onDone(dataToReturn); + } else { + onDone({}); + } + } catch (err) { + utils.logError('unable to parse audigent segment data'); + onDone({}) + } + } else if (req.status === 204) { + // unrecognized site key + onDone({}); + } + }, + error: function () { + onDone({}); + utils.logError('unable to get audigent segment data'); + } + } + ); +} + +/** @type {RtdSubmodule} */ +export const audigentSubmodule = { + /** + * used to link submodule with realTimeData + * @type {string} + */ + name: 'audigent', + /** + * get data and send back to realTimeData module + * @function + * @param {adUnit[]} adUnits + * @param {function} onDone + */ + getData: getSegments +}; + +export function init(config) { + const confListener = config.getConfig(MODULE_NAME, ({realTimeData}) => { + try { + _moduleParams = realTimeData.dataProviders && realTimeData.dataProviders.filter(pr => pr.name && pr.name.toLowerCase() === 'audigent')[0].params; + _moduleParams.auctionDelay = realTimeData.auctionDelay; + } catch (e) { + _moduleParams = {}; + } + confListener(); + }); +} + +submodule('realTimeData', audigentSubmodule); +init(config); diff --git a/modules/audigentRtdProvider.md b/modules/audigentRtdProvider.md new file mode 100644 index 00000000000..47bcbbbf951 --- /dev/null +++ b/modules/audigentRtdProvider.md @@ -0,0 +1,52 @@ +Audigent is a next-generation data management platform and a first-of-a-kind +"data agency" containing some of the most exclusive content-consuming audiences +across desktop, mobile and social platforms. + +This real-time data module provides first-party Audigent segments that can be +attached to bid request objects destined for different SSPs in order to optimize +targeting. Audigent maintains a large database of first-party Tradedesk Unified +ID to third party segment mappings that can now be queried at bid-time. + +Usage: + +Compile the audigent RTD module into your Prebid build: + +`gulp build --modules=userId,unifiedIdSystem,rtdModule,audigentRtdProvider,rubiconBidAdapter` + +Audigent segments will then be attached to each bid request objects in +`bid.realTimeData.audigent_segments` + +The format of the segments is a per-SSP mapping: + +``` +{ + 'appnexus': ['anseg1', 'anseg2'], + 'google': ['gseg1', 'gseg2'] +} +``` + +If a given SSP's API backend supports segment fields, they can then be +attached prior to the bid request being sent: + +``` +pbjs.requestBids({bidsBackHandler: addAudigentSegments}); + +function addAudigentSegments() { + for (i = 0; i < adUnits.length; i++) { + let adUnit = adUnits[i]; + for (j = 0; j < adUnit.bids.length; j++) { + adUnit.bids[j].userId.lipb.segments = adUnit.bids[j].realTimeData.audigent_segments['rubicon']; + } + } +} +``` + +To view an example of the segments returned by Audigent's backends: + +`gulp serve --modules=userId,unifiedIdSystem,rtdModule,audigentRtdProvider,rubiconBidAdapter` + +and then point your browser at: + +`http://localhost:9999/integrationExamples/gpt/audigentSegments_example.html` + + diff --git a/test/spec/modules/realTimeModule_spec.js b/test/spec/modules/realTimeModule_spec.js index bf25b3f0a04..89b44333636 100644 --- a/test/spec/modules/realTimeModule_spec.js +++ b/test/spec/modules/realTimeModule_spec.js @@ -10,6 +10,10 @@ import { isIdMatchingAdUnit, setData } from 'modules/browsiRtdProvider.js'; +import { + init as audigentInit, + setData as setAudigentData +} from 'modules/audigentRtdProvider.js'; import {config} from 'src/config.js'; import {makeSlot} from '../integration/faker/googletag.js'; @@ -27,8 +31,9 @@ describe('Real time module', function() { 'pubKey': 'testPub', 'keyName': 'bv' } + }, { + 'name': 'audigent' }] - } }; @@ -58,6 +63,10 @@ describe('Real time module', function() { } }; + const audigentSegments = { + audigent_segments: {'a': 1, 'b': 2} + } + function getAdUnitMock(code = 'adUnit-code') { return { code, @@ -189,4 +198,46 @@ describe('Real time module', function() { expect(test4).to.equal(true); }) }); + + describe('Real time module with Audigent provider', function() { + afterEach(function () { + $$PREBID_GLOBAL$$.requestBids.removeAll(); + }); + + let targeting = []; + init(config); + audigentInit(config); + config.setConfig(conf); + setAudigentData(audigentSegments); + + it('check module using requestBidsHook', function () { + let adUnits1 = [getAdUnitMock('audigentAd_1')]; + let targeting = []; + let dataReceived = null; + + // set slot + const slotsB = createSlots(); + window.googletag.pubads().setSlots(slotsB); + + function afterBidHook(data) { + dataReceived = data; + slotsB.map(s => { + targeting = []; + s.getTargeting().map(value => { + targeting.push(Object.keys(value).toString()); + }); + }); + } + + requestBidsHook(afterBidHook, {adUnits: adUnits1}); + setTimeout(() => { + dataReceived.adUnits.forEach(unit => { + unit.bids.forEach(bid => { + expect(bid.realTimeData).to.have.property('audigent_segments'); + expect(bid.realTimeData.audigent_segments).to.deep.equal(audigentSegments.audigent_segments); + }); + }); + }, 200); + }); + }); }); From 3b709209dc7bd0064a6e4c7e79ca35cdc783f42d Mon Sep 17 00:00:00 2001 From: msm0504 <51493331+msm0504@users.noreply.github.com> Date: Thu, 5 Mar 2020 16:32:56 -0500 Subject: [PATCH 103/496] ozone 2.3.0 adapter updates (#4891) * ozone 2.3.0 adapter updates * ozone 2.3.0 adapter - added .js suffix to fix circleCI warnings from upstream * ozone 2.3.0 adapter - more fixes for circleCI errors from upstream * ozone 2.3.0 adapter - more fixes for circleCI errors from upstream - no-multiple-empty-lines * misc fixes --- modules/ozoneBidAdapter.js | 286 +++++++++++++++++---- test/spec/modules/ozoneBidAdapter_spec.js | 288 ++++++++++++++++++++-- 2 files changed, 507 insertions(+), 67 deletions(-) diff --git a/modules/ozoneBidAdapter.js b/modules/ozoneBidAdapter.js index f30b33fe2dd..32ae1ced2f3 100644 --- a/modules/ozoneBidAdapter.js +++ b/modules/ozoneBidAdapter.js @@ -6,88 +6,107 @@ import {getPriceBucketString} from '../src/cpmBucketManager.js'; import { Renderer } from '../src/Renderer.js'; const BIDDER_CODE = 'ozone'; - +const ALLOWED_LOTAME_PARAMS = ['oz_lotameid', 'oz_lotamepid', 'oz_lotametpid']; const OZONEURI = 'https://elb.the-ozone-project.com/openrtb2/auction'; const OZONECOOKIESYNC = 'https://elb.the-ozone-project.com/static/load-cookie.html'; const OZONE_RENDERER_URL = 'https://prebid.the-ozone-project.com/ozone-renderer.js'; -const OZONEVERSION = '2.2.0'; +const OZONEVERSION = '2.3.0'; export const spec = { code: BIDDER_CODE, supportedMediaTypes: [VIDEO, BANNER], cookieSyncBag: {'publisherId': null, 'siteId': null, 'userIdObject': {}}, // variables we want to make available to cookie sync - placementIdWasOverridenByGetParam: {'val': 0}, // send GET param ozstoredrequest=12345 to do this /** * Basic check to see whether required parameters are in the request. * @param bid * @returns {boolean} */ isBidRequestValid(bid) { - utils.logInfo('OZONE: isBidRequestValid : ', config.getConfig()); + utils.logInfo('OZONE: isBidRequestValid : ', config.getConfig(), bid); + let adUnitCode = bid.adUnitCode; // adunit[n].code if (!(bid.params.hasOwnProperty('placementId'))) { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : missing placementId : siteId, placementId and publisherId are REQUIRED'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : missing placementId : siteId, placementId and publisherId are REQUIRED', adUnitCode); return false; } if (!this.isValidPlacementId(bid.params.placementId)) { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : placementId must be exactly 10 numeric characters'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : placementId must be exactly 10 numeric characters', adUnitCode); return false; } if (!(bid.params.hasOwnProperty('publisherId'))) { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : missing publisherId : siteId, placementId and publisherId are REQUIRED'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : missing publisherId : siteId, placementId and publisherId are REQUIRED', adUnitCode); return false; } if (!(bid.params.publisherId).toString().match(/^[a-zA-Z0-9\-]{12}$/)) { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : publisherId must be exactly 12 alphanumieric characters including hyphens'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : publisherId must be exactly 12 alphanumieric characters including hyphens', adUnitCode); return false; } if (!(bid.params.hasOwnProperty('siteId'))) { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : missing siteId : siteId, placementId and publisherId are REQUIRED'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : missing siteId : siteId, placementId and publisherId are REQUIRED', adUnitCode); return false; } if (!(bid.params.siteId).toString().match(/^[0-9]{10}$/)) { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : siteId must be exactly 10 numeric characters'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : siteId must be exactly 10 numeric characters', adUnitCode); return false; } if (bid.params.hasOwnProperty('customParams')) { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : customParams should be renamed to customData'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : customParams should be renamed to customData', adUnitCode); return false; } if (bid.params.hasOwnProperty('customData')) { if (!Array.isArray(bid.params.customData)) { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : customData is not an Array'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : customData is not an Array', adUnitCode); return false; } if (bid.params.customData.length < 1) { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : customData is an array but does not contain any elements'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : customData is an array but does not contain any elements', adUnitCode); return false; } if (!(bid.params.customData[0]).hasOwnProperty('targeting')) { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : customData[0] does not contain "targeting"'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : customData[0] does not contain "targeting"', adUnitCode); return false; } if (typeof bid.params.customData[0]['targeting'] != 'object') { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : customData[0] targeting is not an object'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : customData[0] targeting is not an object', adUnitCode); return false; } } if (bid.params.hasOwnProperty('lotameData')) { if (typeof bid.params.lotameData !== 'object') { - utils.logInfo('OZONE: OZONE BID ADAPTER VALIDATION FAILED : lotameData is not an object'); + utils.logError('OZONE: OZONE BID ADAPTER VALIDATION FAILED : lotameData is not an object', adUnitCode); return false; } } if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) { - if (!bid.mediaTypes.video.hasOwnProperty('context')) { - utils.logInfo('OZONE: [WARNING] No context key/value in bid. Rejecting bid: ', bid); + if (!bid.mediaTypes[VIDEO].hasOwnProperty('context')) { + utils.logError('OZONE: No context key/value in bid. Rejecting bid: ', bid); return false; } - if (bid.mediaTypes.video.context !== 'outstream') { - utils.logInfo('OZONE: [WARNING] Only outstream video is supported. Rejecting bid: ', bid); + if (bid.mediaTypes[VIDEO].context === 'instream') { + utils.logWarn('OZONE: video.context instream is not supported. Only outstream video is supported. Video will not be used for Bid: ', bid); + } else if (bid.mediaTypes.video.context !== 'outstream') { + utils.logError('OZONE: video.context is invalid. Only outstream video is supported. Rejecting bid: ', bid); return false; } } + // guard against hacks in GET parameters that we might allow + const arrLotameOverride = this.getLotameOverrideParams(); + // lotame override, test params. All 3 must be present, or none. + let lotameKeys = Object.keys(arrLotameOverride); + if (lotameKeys.length === ALLOWED_LOTAME_PARAMS.length) { + utils.logInfo('OZONE: VALIDATION : arrLotameOverride', arrLotameOverride); + for (let i in lotameKeys) { + if (!arrLotameOverride[ALLOWED_LOTAME_PARAMS[i]].toString().match(/^[0-9a-zA-Z]+$/)) { + utils.logError('OZONE: Only letters & numbers allowed in lotame override: ' + i.toString() + ': ' + arrLotameOverride[ALLOWED_LOTAME_PARAMS[i]].toString() + '. Rejecting bid: ', bid); + return false; + } + } + } else if (lotameKeys.length > 0) { + utils.logInfo('OZONE: VALIDATION : arrLotameOverride', arrLotameOverride); + utils.logError('OZONE: lotame override params are incomplete. You must set all ' + ALLOWED_LOTAME_PARAMS.length + ': ' + JSON.stringify(ALLOWED_LOTAME_PARAMS) + ', . Rejecting bid: ', bid); + return false; + } return true; }, @@ -101,6 +120,10 @@ export const spec = { buildRequests(validBidRequests, bidderRequest) { utils.logInfo('OZONE: ozone v' + OZONEVERSION + ' validBidRequests', validBidRequests, 'bidderRequest', bidderRequest); + // First check - is there any config to block this request? + if (this.blockTheRequest(bidderRequest)) { + return []; + } let htmlParams = {'publisherId': '', 'siteId': ''}; if (validBidRequests.length > 0) { this.cookieSyncBag.userIdObject = Object.assign(this.cookieSyncBag.userIdObject, this.findAllUserIds(validBidRequests[0])); @@ -132,9 +155,12 @@ export const spec = { const getParams = this.getGetParametersAsObject(); const ozTestMode = getParams.hasOwnProperty('oztestmode') ? getParams.oztestmode : null; // this can be any string, it's used for testing ads ozoneRequest.device = {'w': window.innerWidth, 'h': window.innerHeight}; + let placementIdOverrideFromGetParam = this.getPlacementIdOverrideFromGetParam(); // null or string + let arrLotameOverride = this.getLotameOverrideParams(); + let lotameIdsOverride = 0; let tosendtags = validBidRequests.map(ozoneBidRequest => { var obj = {}; - let placementId = this.getPlacementId(ozoneBidRequest); + let placementId = placementIdOverrideFromGetParam || this.getPlacementId(ozoneBidRequest); // prefer to use a valid override param, else the bidRequest placement Id 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." obj.tagid = placementId; obj.secure = window.location.protocol === 'https:' ? 1 : 0; @@ -152,7 +178,7 @@ export const spec = { arrBannerSizes = ozoneBidRequest.mediaTypes[BANNER].sizes; /* Note - if there is a sizes element in the config root it will be pushed into here */ utils.logInfo('OZONE: setting banner size from the mediaTypes.banner element for bidId ' + obj.id + ': ', arrBannerSizes); } - if (ozoneBidRequest.mediaTypes.hasOwnProperty(VIDEO)) { + if (ozoneBidRequest.mediaTypes.hasOwnProperty(VIDEO) && ozoneBidRequest.mediaTypes[VIDEO].context === 'outstream') { obj.video = ozoneBidRequest.mediaTypes[VIDEO]; // we need to duplicate some of the video values let wh = getWidthAndHeightFromVideoObject(obj.video); @@ -210,17 +236,30 @@ export const spec = { } else { utils.logInfo('no ozTestMode '); } - utils.logInfo('lotameData', ozoneBidRequest, ozoneBidRequest.params.lotameData); - if (ozoneBidRequest.params.hasOwnProperty('lotameData')) { - obj.ext.ozone.lotameData = ozoneBidRequest.params.lotameData; - } else { - obj.ext.ozone.lotameData = 'Failed to find lotameData'; + // now deal with lotame, including the optional override parameters + if (Object.keys(arrLotameOverride).length === ALLOWED_LOTAME_PARAMS.length) { + // all override params are present, override lotame object: + if (ozoneBidRequest.params.hasOwnProperty('lotameData')) { + obj.ext.ozone.lotameData = this.makeLotameObjectFromOverride(arrLotameOverride, ozoneBidRequest.params.lotameData); + } else { + obj.ext.ozone.lotameData = this.makeLotameObjectFromOverride(arrLotameOverride, {}); + } + lotameIdsOverride = 1; + } else if (ozoneBidRequest.params.hasOwnProperty('lotameData')) { + // no lotame override, use it as-is + if (this.isLotameDataValid(ozoneBidRequest.params.lotameData)) { + obj.ext.ozone.lotameData = ozoneBidRequest.params.lotameData; + } else { + utils.logError('INVALID LOTAME DATA FOUND - WILL NOT USE THIS AT ALL ELSE IT MIGHT BREAK THE AUCTION CALL!', ozoneBidRequest.params.lotameData); + obj.ext.ozone.lotameData = {}; + } } + // otherwise don't set obj.ext.ozone.lotameData return obj; }); // in v 2.0.0 we moved these outside of the individual ad slots - let extObj = {'ozone': {'oz_pb_v': OZONEVERSION, 'oz_rw': this.placementIdWasOverridenByGetParam.val}}; + let extObj = {'ozone': {'oz_pb_v': OZONEVERSION, 'oz_rw': placementIdOverrideFromGetParam ? 1 : 0, 'oz_lot_rw': lotameIdsOverride}}; if (validBidRequests.length > 0) { let userIds = this.findAllUserIds(validBidRequests[0]); if (userIds.hasOwnProperty('pubcid')) { @@ -230,8 +269,19 @@ export const spec = { var userExtEids = this.generateEids(validBidRequests); // generate the UserIDs in the correct format for UserId module - ozoneRequest.site = {'publisher': {'id': htmlParams.publisherId}, 'page': document.location.href, 'id': htmlParams.siteId}; + ozoneRequest.site = { + 'publisher': {'id': htmlParams.publisherId}, + 'page': document.location.href, + 'id': htmlParams.siteId + }; ozoneRequest.test = (getParams.hasOwnProperty('pbjs_debug') && getParams['pbjs_debug'] == 'true') ? 1 : 0; + + // this is for 2.2.1 + // coppa compliance + if (config.getConfig('coppa') === true) { + utils.deepSetValue(ozoneRequest, 'regs.coppa', 1); + } + // return the single request object OR the array: if (singleRequest) { utils.logInfo('OZONE: buildRequests starting to generate response for a single request'); @@ -286,8 +336,13 @@ export const spec = { interpretResponse(serverResponse, request) { utils.logInfo('OZONE: interpretResponse: serverResponse, request', serverResponse, request); serverResponse = serverResponse.body || {}; - if (!serverResponse.hasOwnProperty('seatbid')) { return []; } - if (typeof serverResponse.seatbid !== 'object') { return []; } + // note that serverResponse.id value is the auction_id we might want to use for reporting reasons. + if (!serverResponse.hasOwnProperty('seatbid')) { + return []; + } + if (typeof serverResponse.seatbid !== 'object') { + return []; + } let arrAllBids = []; let enhancedAdserverTargeting = config.getConfig('ozone.enhancedAdserverTargeting'); utils.logInfo('OZONE: enhancedAdserverTargeting', enhancedAdserverTargeting); @@ -317,7 +372,7 @@ export const spec = { let allBidsForThisBidid = ozoneGetAllBidsForBidId(ozoneInternalKey, serverResponse.seatbid); // add all the winning & non-winning bids for this bidId: utils.logInfo('OZONE: Going to iterate allBidsForThisBidId', allBidsForThisBidid); - Object.keys(allBidsForThisBidid).forEach(function(bidderName, index, ar2) { + Object.keys(allBidsForThisBidid).forEach(function (bidderName, index, ar2) { adserverTargeting['oz_' + bidderName] = bidderName; adserverTargeting['oz_' + bidderName + '_pb'] = String(allBidsForThisBidid[bidderName].price); adserverTargeting['oz_' + bidderName + '_crid'] = String(allBidsForThisBidid[bidderName].crid); @@ -414,28 +469,91 @@ export const spec = { utils.logInfo('OZONE: debug going to return: ', ret); return ret; }, - /** - * Convenient method to get the value we need for the placementId - either from the bidRequest, or from the GET - * parameter introduced in 2.2.0 : ozstoredrequest - * IF the GET parameter exists then it must validate for placementId correctly + * get all the lotame override keys/values from the querystring. + * @return object containing zero or more keys/values + */ + getLotameOverrideParams() { + const arrGet = this.getGetParametersAsObject(); + utils.logInfo('getLotameOverrideParams - arrGet', arrGet); + let arrRet = {}; + for (let i in ALLOWED_LOTAME_PARAMS) { + if (arrGet.hasOwnProperty(ALLOWED_LOTAME_PARAMS[i])) { + arrRet[ALLOWED_LOTAME_PARAMS[i]] = arrGet[ALLOWED_LOTAME_PARAMS[i]]; + } + } + return arrRet; + }, + /** + * Boolean function to check that this lotame data is valid (check Audience.id) + */ + isLotameDataValid(lotameObj) { + if (!lotameObj.hasOwnProperty('Profile')) return false; + let prof = lotameObj.Profile; + if (!prof.hasOwnProperty('tpid')) return false; + if (!prof.hasOwnProperty('pid')) return false; + let audiences = utils.deepAccess(prof, 'Audiences.Audience'); + if (typeof audiences != 'object') { + return false; + } + for (var i = 0; i < audiences.length; i++) { + let aud = audiences[i]; + if (!aud.hasOwnProperty('id')) { + return false; + } + } + return true; // All Audiences objects have an 'id' key + }, + /** + * Use the arrOverride keys/vals to update the arrExisting lotame object. + * @param objOverride object will contain all the ALLOWED_LOTAME_PARAMS parameters + * @param lotameData object might be {} or contain the lotame data + */ + makeLotameObjectFromOverride(objOverride, lotameData) { + if ((lotameData.hasOwnProperty('Profile') && Object.keys(lotameData.Profile).length < 3) || + (!lotameData.hasOwnProperty('Profile'))) { // bad or empty lotame object (should contain pid, tpid & Audiences object) - build a total replacement + utils.logInfo('makeLotameObjectFromOverride', 'will return a full default lotame object'); + return { + 'Profile': { + 'tpid': objOverride['oz_lotametpid'], + 'pid': objOverride['oz_lotamepid'], + 'Audiences': {'Audience': [{'id': objOverride['oz_lotameid'], 'abbr': objOverride['oz_lotameid']}]} + } + }; + } + if (utils.deepAccess(lotameData, 'Profile.Audiences.Audience')) { + utils.logInfo('makeLotameObjectFromOverride', 'will return the existing lotame object with updated Audience by oz_lotameid'); + lotameData.Profile.Audiences.Audience = [{'id': objOverride['oz_lotameid'], 'abbr': objOverride['oz_lotameid']}]; + return lotameData; + } + utils.logInfo('makeLotameObjectFromOverride', 'Weird error - failed to find Profile.Audiences.Audience in lotame object. Will return the object as-is'); + return lotameData; + }, + /** + * Convenient method to get the value we need for the placementId - ONLY from the bidRequest - NOT taking into account any GET override ID * @param bidRequest * @return string */ getPlacementId(bidRequest) { + return (bidRequest.params.placementId).toString(); + }, + /** + * GET parameter introduced in 2.2.0 : ozstoredrequest + * IF the GET parameter exists then it must validate for placementId correctly + * IF there's a $_GET['ozstoredrequest'] & it's valid then return this. Else return null. + * @returns null|string + */ + getPlacementIdOverrideFromGetParam() { let arr = this.getGetParametersAsObject(); - this.placementIdWasOverridenByGetParam.val = 0; if (arr.hasOwnProperty('ozstoredrequest')) { if (this.isValidPlacementId(arr.ozstoredrequest)) { - let override = arr.ozstoredrequest; - utils.logInfo('OZONE: using GET ozstoredrequest ' + override + ' to replace placementId'); - this.placementIdWasOverridenByGetParam.val = 1; - return override; + utils.logInfo('OZONE: using GET ozstoredrequest ' + arr.ozstoredrequest + ' to replace placementId'); + return arr.ozstoredrequest; } else { utils.logError('OZONE: GET ozstoredrequest FAILED VALIDATION - will not use it'); } } - return (bidRequest.params.placementId).toString(); + return null; }, /** * Produces external userid object @@ -502,8 +620,87 @@ export const spec = { ret[tmp[0]] = tmp[1]; } return ret; + }, + /** + * This will be called IF we want to enforce gdpr on the client + * Do we have to block this request? Could be due to config values & gdpr permissions etc + * @return {boolean|*[]} true = block the request, else false + */ + blockTheRequest(bidderRequest) { + // if there is an ozone.oz_request = false then quit now. + let ozRequest = config.getConfig('ozone.oz_request'); + if (typeof ozRequest == 'boolean' && !ozRequest) { + utils.logError('OZONE: Will not allow auction : ozone.oz_request is set to false'); + return true; + } + // is there ozone.oz_enforceGdpr == true (ANYTHING else means don't enforce GDPR)) + let ozEnforce = config.getConfig('ozone.oz_enforceGdpr'); + if (typeof ozEnforce != 'boolean' || !ozEnforce) { // ozEnforce is false by default + utils.logError('OZONE: Will not validate GDPR on the client : oz_enforceGdpr is not set to true'); + return false; + } + // maybe the module was built without consentManagement module so we won't find any gdpr information + if (!bidderRequest.hasOwnProperty('gdprConsent')) { + return false; + } + // + // FROM HERE ON : WE ARE DOING GDPR CHECKS + // + // If there is indeterminate GDPR (gdprConsent.consentString == undefined or not a string), we will DITCH this: + if (typeof bidderRequest.gdprConsent.consentString !== 'string') { + utils.logError('OZONE: Will block the request - bidderRequest.gdprConsent.consentString is not a string'); + return true; + } + // IF the consentManagement module sends through the CMP information and user has refused all permissions: + if (this.failsGdprCheck(bidderRequest)) { + return true; + } + return false; + }, + /** + * Examine the gdpr information inside the bidderRequest and return the boolean answer to the question + * @param bidderRequest + * @return {boolean} + */ + failsGdprCheck(bidderRequest) { + let consentRequired = (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true; + if (consentRequired) { + let vendorConsentsObject = utils.deepAccess(bidderRequest.gdprConsent, 'vendorData'); + if (!vendorConsentsObject || typeof vendorConsentsObject !== 'object') { + utils.logError('OZONE: gdpr test failed - bidderRequest.gdprConsent.vendorData is not an array'); + return true; + } + if (!vendorConsentsObject.hasOwnProperty('purposeConsents')) { + return true; + } + if (typeof vendorConsentsObject.purposeConsents != 'object') { + return true; + } + if (!this.purposeConsentsAreOk((vendorConsentsObject.purposeConsents))) { + utils.logError('OZONE: gdpr test failed - missing Purposes consent'); + return true; + } + if (!vendorConsentsObject.vendorConsents[524]) { + utils.logError('OZONE: gdpr test failed - missing Vendor ID consent'); + return true; + } + } + return false; + }, + /** + * Test that vendor purpose consents 1,2,3,4 and 5 are true + * This is because we can't use Object.values(vendorConsentsObject.purposeConsents).slice(0, 5) + * @param obj + * @return {boolean} + */ + purposeConsentsAreOk(obj) { + for (let i = 1; i <= 5; i++) { + if (!obj.hasOwnProperty(i) || !obj[i]) return false; + } + return true; } } + /** * add a page-level-unique adId element to all server response bids. * NOTE that this is distructive - it mutates the serverResponse object sent in as a parameter @@ -511,6 +708,7 @@ export const spec = { * @returns seatbid object */ export function injectAdIdsIntoAllBidResponses(seatbid) { + utils.logInfo('injectAdIdsIntoAllBidResponses', seatbid); for (let i = 0; i < seatbid.length; i++) { let sb = seatbid[i]; for (let j = 0; j < sb.bid.length; j++) { @@ -520,6 +718,7 @@ export function injectAdIdsIntoAllBidResponses(seatbid) { } return seatbid; } + export function checkDeepArray(Arr) { if (Array.isArray(Arr)) { if (Array.isArray(Arr[0])) { @@ -531,6 +730,7 @@ export function checkDeepArray(Arr) { return Arr; } } + export function defaultSize(thebidObj) { if (!thebidObj) { utils.logInfo('OZONE: defaultSize received empty bid obj! going to return fixed default size'); @@ -760,4 +960,4 @@ function getPlayerSizeFromObject(objVideo) { } registerBidder(spec); -utils.logInfo('OZONE: ozoneBidAdapter ended'); +utils.logInfo('OZONE: ozoneBidAdapter was loaded'); diff --git a/test/spec/modules/ozoneBidAdapter_spec.js b/test/spec/modules/ozoneBidAdapter_spec.js index 05ed217fb31..16ebb5c321b 100644 --- a/test/spec/modules/ozoneBidAdapter_spec.js +++ b/test/spec/modules/ozoneBidAdapter_spec.js @@ -781,25 +781,6 @@ describe('ozone Adapter', function () { expect(spec.isBidRequestValid(xBadLotame)).to.equal(false); }); - var xBadVideoContext = { - bidder: BIDDER_CODE, - params: { - 'placementId': '1234567890', - 'publisherId': '9876abcd12-3', - 'lotameData': {}, - siteId: '1234567890' - }, - mediaTypes: { - video: { - mimes: ['video/mp4'], - 'context': 'instream'}, - } - }; - - it('should not validate video instream being sent', function () { - expect(spec.isBidRequestValid(xBadVideoContext)).to.equal(false); - }); - var xBadVideoContext2 = { bidder: BIDDER_CODE, params: { @@ -835,6 +816,40 @@ describe('ozone Adapter', function () { it('should validate video outstream being sent', function () { expect(spec.isBidRequestValid(validVideoBidReq)).to.equal(true); }); + it('should validate video instream being sent even though its not properly supported yet', function () { + let instreamVid = JSON.parse(JSON.stringify(validVideoBidReq)); + instreamVid.mediaTypes.video.context = 'instream'; + expect(spec.isBidRequestValid(instreamVid)).to.equal(true); + }); + // validate lotame override parameters + it('should validate lotame override params', function () { + // mock the getGetParametersAsObject function to simulate GET parameters for lotame overrides: + spec.getGetParametersAsObject = function() { + return {'oz_lotameid': '123abc', 'oz_lotamepid': 'pid123', 'oz_lotametpid': 'tpid123'}; + }; + expect(spec.isBidRequestValid(validBidReq)).to.equal(true); + }); + it('should validate missing lotame override params', function () { + // mock the getGetParametersAsObject function to simulate GET parameters for lotame overrides: + spec.getGetParametersAsObject = function() { + return {'oz_lotameid': '123abc', 'oz_lotamepid': 'pid123'}; + }; + expect(spec.isBidRequestValid(validBidReq)).to.equal(false); + }); + it('should validate invalid lotame override params', function () { + // mock the getGetParametersAsObject function to simulate GET parameters for lotame overrides: + spec.getGetParametersAsObject = function() { + return {'oz_lotameid': '123abc', 'oz_lotamepid': 'pid123', 'oz_lotametpid': '123 "this ain\\t right!" eee'}; + }; + expect(spec.isBidRequestValid(validBidReq)).to.equal(false); + }); + it('should validate no lotame override params', function () { + // mock the getGetParametersAsObject function to simulate GET parameters for lotame overrides: + spec.getGetParametersAsObject = function() { + return {}; + }; + expect(spec.isBidRequestValid(validBidReq)).to.equal(true); + }); }); describe('buildRequests', function () { @@ -931,7 +946,8 @@ describe('ozone Adapter', function () { expect(payload.user.ext.consent).to.equal(consentString); }); - it('should add gdpr consent information to the request when ozone is true and vendorData is missing vendorConsents (Mirror)', function () { + // mirror + it('should add gdpr consent information to the request when ozone.oz_enforceGdpr is false and vendorData is missing vendorConsents (Mirror)', function () { let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; let bidderRequest = validBidderRequest; bidderRequest.gdprConsent = { @@ -948,6 +964,39 @@ describe('ozone Adapter', function () { expect(payload.regs.ext.gdpr).to.equal(1); expect(payload.user.ext.consent).to.equal(consentString); }); + it('should add gdpr consent information to the request when ozone.oz_enforceGdpr is NOT PRESENT and vendorData is missing vendorConsents (Mirror)', function () { + let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; + let bidderRequest = validBidderRequest; + bidderRequest.gdprConsent = { + consentString: consentString, + gdprApplies: true, + vendorData: { + metadata: consentString, + gdprApplies: true + } + } + const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.regs.ext.gdpr).to.equal(1); + expect(payload.user.ext.consent).to.equal(consentString); + config.resetConfig(); + }); + it('should kill the auction request when ozone.oz_enforceGdpr is true & vendorData is missing vendorConsents (Mirror)', function () { + let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; + let bidderRequest = validBidderRequest; + bidderRequest.gdprConsent = { + consentString: consentString, + gdprApplies: true, + vendorData: { + metadata: consentString, + gdprApplies: true + } + } + config.setConfig({'ozone': {'oz_enforceGdpr': true}}); + const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest); + expect(request.length).to.equal(0); + config.resetConfig(); + }); it('should set regs.ext.gdpr flag to 0 when gdprApplies is false', function () { let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; @@ -1002,7 +1051,6 @@ describe('ozone Adapter', function () { }); it('should pick up the value of pubcid when built using the pubCommonId module (not userId)', function () { - console.log(validBidRequests[0].crumbs); let bidRequests = validBidRequests; // values from http://prebid.org/dev-docs/modules/userId.html#pubcommon-id bidRequests[0]['userId'] = { @@ -1084,6 +1132,68 @@ describe('ozone Adapter', function () { expect(data.ext.ozone.oz_rw).to.equal(0); expect(data.imp[0].ext.prebid.storedrequest.id).to.equal('1310000099'); }); + + it('should pick up the value of valid lotame override parameters when there is a lotame object', function () { + spec.getGetParametersAsObject = function() { + return {'oz_lotameid': '123abc', 'oz_lotamepid': 'pid123', 'oz_lotametpid': '123eee'}; + }; + const request = spec.buildRequests(validBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + expect(payload.imp[0].ext.ozone.lotameData.Profile.Audiences.Audience[0].id).to.equal('123abc'); + expect(payload.ext.ozone.oz_lot_rw).to.equal(1); + }); + it('should pick up the value of valid lotame override parameters when there is an empty lotame object', function () { + let nolotameBidReq = JSON.parse(JSON.stringify(validBidRequests)); + nolotameBidReq[0].params.lotameData = {}; + spec.getGetParametersAsObject = function() { + return {'oz_lotameid': '123abc', 'oz_lotamepid': 'pid123', 'oz_lotametpid': '123eeetpid'}; + }; + const request = spec.buildRequests(nolotameBidReq, validBidderRequest); + const payload = JSON.parse(request.data); + expect(payload.imp[0].ext.ozone.lotameData.Profile.Audiences.Audience[0].id).to.equal('123abc'); + expect(payload.imp[0].ext.ozone.lotameData.Profile.tpid).to.equal('123eeetpid'); + expect(payload.imp[0].ext.ozone.lotameData.Profile.pid).to.equal('pid123'); + expect(payload.ext.ozone.oz_lot_rw).to.equal(1); + }); + it('should pick up the value of valid lotame override parameters when there is NO "lotame" key at all', function () { + let nolotameBidReq = JSON.parse(JSON.stringify(validBidRequests)); + delete (nolotameBidReq[0].params['lotameData']); + spec.getGetParametersAsObject = function() { + return {'oz_lotameid': '123abc', 'oz_lotamepid': 'pid123', 'oz_lotametpid': '123eeetpid'}; + }; + const request = spec.buildRequests(nolotameBidReq, validBidderRequest); + const payload = JSON.parse(request.data); + expect(payload.imp[0].ext.ozone.lotameData.Profile.Audiences.Audience[0].id).to.equal('123abc'); + expect(payload.imp[0].ext.ozone.lotameData.Profile.tpid).to.equal('123eeetpid'); + expect(payload.imp[0].ext.ozone.lotameData.Profile.pid).to.equal('pid123'); + expect(payload.ext.ozone.oz_lot_rw).to.equal(1); + }); + // NOTE - only one negative test case; + // you can't send invalid lotame params to buildRequests because 'validate' will have rejected them + it('should not use lotame override parameters if they dont exist', function () { + spec.getGetParametersAsObject = function() { + return {}; // no lotame override params + }; + const request = spec.buildRequests(validBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + expect(payload.ext.ozone.oz_lot_rw).to.equal(0); + }); + + it('should pick up the config value of coppa & set it in the request', function () { + config.setConfig({'coppa': true}); + const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); + const payload = JSON.parse(request.data); + expect(payload.regs).to.include.keys('coppa'); + expect(payload.regs.coppa).to.equal(1); + config.resetConfig(); + }); + it('should pick up the config value of coppa & only set it in the request if its true', function () { + config.setConfig({'coppa': false}); + const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); + const payload = JSON.parse(request.data); + expect(utils.deepAccess(payload, 'regs.coppa')).to.be.undefined; + config.resetConfig(); + }); }); describe('interpretResponse', function () { @@ -1103,9 +1213,10 @@ describe('ozone Adapter', function () { }); it('should build bid array with gdpr', function () { - var validBidderRequestWithGdpr = bidderRequestWithFullGdpr; - validBidderRequestWithGdpr.gdprConsent = {'gdprApplies': 1, 'consentString': 'This is the gdpr consent string'}; - const request = spec.buildRequests(validBidRequests, validBidderRequestWithGdpr); + let validBR = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); + validBR.gdprConsent = {'gdprApplies': 1, 'consentString': 'This is the gdpr consent string'}; + const request = spec.buildRequests(validBidRequests, validBR); // works the old way, with GDPR not enforced by default + // const request = spec.buildRequests(validBidRequests, bidderRequestWithFullGdpr); // works with oz_enforceGdpr true by default const result = spec.interpretResponse(validResponse, request); expect(result.length).to.equal(1); }); @@ -1258,4 +1369,133 @@ describe('ozone Adapter', function () { expect(result.name).to.equal('rupert'); }); }); + + describe('blockTheRequest', function() { + it('should return true if oz_request is false', function() { + config.setConfig({'ozone': {'oz_request': false}}); + let result = spec.blockTheRequest(bidderRequestWithFullGdpr); + expect(result).to.be.true; + config.resetConfig(); + }); + it('should return false if oz_request is true', function() { + config.setConfig({'ozone': {'oz_request': true}}); + let result = spec.blockTheRequest(bidderRequestWithFullGdpr); + expect(result).to.be.false; + config.resetConfig(); + }); + it('should return true if oz_enforceGdpr is true and consentString is undefined', function() { + config.setConfig({'ozone': {'oz_enforceGdpr': true}}); + let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); + delete req.gdprConsent.consentString; + let result = spec.blockTheRequest(req); + expect(result).to.be.true; + config.resetConfig(); + }); + it('should return false if oz_enforceGdpr is false and consentString is undefined', function() { + config.setConfig({'ozone': {'oz_enforceGdpr': false}}); + let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); + delete req.gdprConsent.consentString; + let result = spec.blockTheRequest(req); + expect(result).to.be.false; + config.resetConfig(); + }); + it('should return false if oz_enforceGdpr is NOT SET (default) and consentString is undefined', function() { + let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); + delete req.gdprConsent.consentString; + let result = spec.blockTheRequest(req); + expect(result).to.be.false; + }); + it('should return false if gdprApplies is false', function() { + config.setConfig({'ozone': {'oz_request': true}}); + let req = {'gdprConsent': {'gdprApplies': false}}; + let result = spec.blockTheRequest(req); + expect(result).to.be.false; + config.resetConfig(); + }); + it('should return false if gdprConsent key does not exist', function() { + let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); + config.setConfig({'ozone': {'oz_enforceGdpr': true}}); + delete req.gdprConsent; + let result = spec.blockTheRequest(req); + expect(result).to.be.false; + config.resetConfig(); + }); + it('should return false if gdpr is set, and all is ok', function() { + let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); + config.setConfig({'ozone': {'oz_enforceGdpr': true}}); + let result = spec.blockTheRequest(req); + expect(result).to.be.false; + config.resetConfig(); + }); + }); + + describe('failsGdprCheck', function() { + it('should return false for a a fully accepted user', function () { + let result = spec.failsGdprCheck(bidderRequestWithFullGdpr); + expect(result).to.be.false; + }); + it('should return false if gdprConsent is not present on the bidder object', function () { + let result = spec.failsGdprCheck(validBidderRequest); + expect(result).to.be.false; + }); + it('should return true if gdpr applies and vendorData is not an array', function () { + let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); + req.gdprConsent.vendorData = null; + let result = spec.failsGdprCheck(req); + expect(result).to.be.true; + }); + it('should return true if gdpr applies and purposeConsents do not contain all the required true values', function () { + let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); + req.gdprConsent.vendorData.purposeConsents[1] = false; + let result = spec.failsGdprCheck(req); + expect(result).to.be.true; + }); + it('should return true if gdpr applies and vendorConsents[524] is not true', function () { + config.setConfig({'ozone': {'oz_enforceGdpr': true}}); + let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); + req.gdprConsent.vendorData.vendorConsents[524] = false; + let result = spec.failsGdprCheck(req); + expect(result).to.be.true; + config.resetConfig(); + }); + }); + + describe('makeLotameObjectFromOverride', function() { + it('should update an object with valid lotame data', function () { + let objLotameOverride = {'oz_lotametpid': '1234', 'oz_lotameid': '12345', 'oz_lotamepid': '123456'}; + let result = spec.makeLotameObjectFromOverride( + objLotameOverride, + {'Profile': {'pid': 'originalpid', 'tpid': 'originaltpid', 'Audiences': {'Audience': [{'id': 'aud1'}]}}} + ); + expect(result.Profile.Audiences.Audience).to.be.an('array'); + expect(result.Profile.Audiences.Audience[0]).to.be.an('object'); + expect(result.Profile.Audiences.Audience[0]).to.deep.include({'id': '12345', 'abbr': '12345'}); + }); + it('should return the original object if it seems weird', function () { + let objLotameOverride = {'oz_lotametpid': '1234', 'oz_lotameid': '12345', 'oz_lotamepid': '123456'}; + let objLotameOriginal = {'Profile': {'pid': 'originalpid', 'tpid': 'originaltpid', 'somethingstrange': [{'id': 'aud1'}]}}; + let result = spec.makeLotameObjectFromOverride( + objLotameOverride, + objLotameOriginal + ); + expect(result).to.equal(objLotameOriginal); + }); + }); + describe('lotameDataIsValid', function() { + it('should allow a valid minimum lotame object', function() { + let obj = {'Profile': {'pid': '', 'tpid': '', 'Audiences': {'Audience': []}}}; + let result = spec.isLotameDataValid(obj); + expect(result).to.be.true; + }); + it('should allow a valid lotame object', function() { + let obj = {'Profile': {'pid': '12345', 'tpid': '45678', 'Audiences': {'Audience': [{'id': '1234', 'abbr': '567'}, {'id': '9999', 'abbr': '1111'}]}}}; + let result = spec.isLotameDataValid(obj); + expect(result).to.be.true; + }); + it('should disallow a lotame object without an Audience.id', function() { + let obj = {'Profile': {'tpid': '', 'pid': '', 'Audiences': {'Audience': [{'abbr': 'marktest'}]}}}; + let result = spec.isLotameDataValid(obj); + expect(result).to.be.false; + }); + }); }); From 42d4a7931ce1a153e93e623030c0b87fe28157ab Mon Sep 17 00:00:00 2001 From: harpere Date: Thu, 5 Mar 2020 16:46:57 -0500 Subject: [PATCH 104/496] No bid version 1.2.3 (#4930) * Enable supplyChain support * Added support for COPPA --- modules/nobidBidAdapter.js | 24 ++++++++- test/spec/modules/nobidBidAdapter_spec.js | 60 ++++++++++++++++++++++- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index cce79efead0..7fca2d10534 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -1,8 +1,9 @@ import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'nobid'; -window.nobidVersion = '1.2.1'; +window.nobidVersion = '1.2.3'; window.nobid = window.nobid || {}; window.nobid.bidResponses = window.nobid.bidResponses || {}; window.nobid.timeoutTotal = 0; @@ -57,6 +58,21 @@ function nobidBuildRequests(bids, bidderRequest) { } return uspConsent; } + var schain = function(bids) { + if (bids && bids.length > 0) { + return bids[0].schain + } + return null; + } + var coppa = function() { + if (config.getConfig('coppa') === true) { + return {'coppa': true}; + } + if (bids && bids.length > 0) { + return bids[0].coppa + } + return null; + } var topLocation = function(bidderRequest) { var ret = ''; if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { @@ -99,6 +115,10 @@ function nobidBuildRequests(bids, bidderRequest) { state['ref'] = document.referrer; state['gdpr'] = gdprConsent(bidderRequest); state['usp'] = uspConsent(bidderRequest); + const sch = schain(bids); + if (sch) state['schain'] = sch; + const cop = coppa(); + if (cop) state['coppa'] = cop; return state; } function newAdunit(adunitObject, adunits) { @@ -269,7 +289,7 @@ export const spec = { var buildEndpoint = function() { return resolveEndpoint() + 'adreq?cb=' + Math.floor(Math.random() * 11000); } - log('buildRequests', validBidRequests); + log('validBidRequests', validBidRequests); if (!validBidRequests || validBidRequests.length <= 0) { log('Empty validBidRequests'); return; diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js index 0005f35523e..8d119461d6a 100644 --- a/test/spec/modules/nobidBidAdapter_spec.js +++ b/test/spec/modules/nobidBidAdapter_spec.js @@ -2,6 +2,7 @@ import { expect } from 'chai'; import * as utils from 'src/utils.js'; import { spec } from 'modules/nobidBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; +import * as bidderFactory from 'src/adapters/bidderFactory.js'; describe('Nobid Adapter', function () { const adapter = newBidder(spec); @@ -70,7 +71,7 @@ describe('Nobid Adapter', function () { refererInfo: {referer: REFERER} } - it('should add source and verison to the tag', function () { + it('should add source and version to the tag', function () { const request = spec.buildRequests(bidRequests, bidderRequest); const payload = JSON.parse(request.data); expect(payload.sid).to.equal(SITE_ID); @@ -281,6 +282,56 @@ describe('Nobid Adapter', function () { }); }); + describe('buildRequestsWithSupplyChain', function () { + const SITE_ID = 2; + let bidRequests = [ + { + bidder: 'nobid', + params: { + siteId: SITE_ID + }, + adUnitCode: 'adunit-code', + sizes: [[300, 250]], + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + coppa: true, + schain: { + validation: 'strict', + config: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + name: 'name.com', + hp: 1 + } + ] + } + } + } + ]; + + it('schain exist', function () { + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.schain).to.exist; + expect(payload.schain.validation).to.exist.and.to.equal('strict'); + expect(payload.schain.config.ver).to.exist.and.to.equal('1.0'); + expect(payload.schain.config.complete).to.exist.and.to.equal(1); + expect(payload.schain.config.nodes[0].asi).to.exist.and.to.equal('indirectseller.com'); + expect(payload.schain.config.nodes[0].sid).to.exist.and.to.equal('00001'); + expect(payload.schain.config.nodes[0].name).to.exist.and.to.equal('name.com'); + expect(payload.schain.config.nodes[0].hp).to.exist.and.to.equal(1); + expect(payload.coppa).to.exist; + expect(payload.coppa).to.exist.and.to.be.true; + expect(payload.a).to.be.lengthOf(1); + expect(request.method).to.equal('POST'); + }); + }); + describe('interpretResponseWithUserLimit', function () { const CREATIVE_ID_300x250 = 'CREATIVE-100'; const ADUNIT_300x250 = 'ADUNIT-1'; @@ -359,6 +410,13 @@ describe('Nobid Adapter', function () { expect(pixel.length).to.equal(0); }); + it('should get correct user sync when !iframeEnabled and pixelEnabled', function () { + let pixel = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{body: {syncs: ['sync_url']}}]) + expect(pixel.length).to.equal(1); + expect(pixel[0].type).to.equal('image'); + expect(pixel[0].url).to.equal('sync_url'); + }); + it('should get correct user sync when !iframeEnabled', function () { let pixel = spec.getUserSyncs({}) expect(pixel.length).to.equal(0); From f08b14a767f785c73aecb209d64016ef842dc753 Mon Sep 17 00:00:00 2001 From: harpere Date: Thu, 5 Mar 2020 16:49:51 -0500 Subject: [PATCH 105/496] updates to fix lint error (#4937) --- modules/vdoaiBidAdapter.js | 238 ++++++++++++++++++------------------- 1 file changed, 119 insertions(+), 119 deletions(-) diff --git a/modules/vdoaiBidAdapter.js b/modules/vdoaiBidAdapter.js index 48e6081b2d9..395953fb737 100644 --- a/modules/vdoaiBidAdapter.js +++ b/modules/vdoaiBidAdapter.js @@ -1,119 +1,119 @@ -import * as utils from '../src/utils'; -import {config} from '../src/config'; -import {registerBidder} from '../src/adapters/bidderFactory'; -import {BANNER} from '../src/mediaTypes'; - -const BIDDER_CODE = 'vdo.ai'; -const ENDPOINT_URL = 'https://prebid.vdo.ai/auction'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params.placementId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @return Array Info describing the request to the server. - * @param validBidRequests - * @param bidderRequest - */ - buildRequests: function (validBidRequests, bidderRequest) { - if (validBidRequests.length === 0) { - return []; - } - return validBidRequests.map(bidRequest => { - const sizes = utils.parseSizesInput(bidRequest.params.size || bidRequest.sizes)[0]; - const width = sizes.split('x')[0]; - const height = sizes.split('x')[1]; - const payload = { - placementId: bidRequest.params.placementId, - width: width, - height: height, - bidId: bidRequest.bidId, - referer: bidderRequest.refererInfo.referer, - id: bidRequest.auctionId - }; - bidRequest.params.bidFloor && (payload['bidFloor'] = bidRequest.params.bidFloor); - return { - method: 'POST', - url: ENDPOINT_URL, - data: payload - }; - }); - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {ServerResponse} serverResponse A successful response from the server. - * @param bidRequest - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - const creativeId = response.adid || 0; - // const width = response.w || 0; - const width = bidRequest.data.width; - // const height = response.h || 0; - const height = bidRequest.data.height; - const cpm = response.price || 0; - - response.rWidth = width; - response.rHeight = height; - - const adCreative = response.vdoCreative; - - if (width !== 0 && height !== 0 && cpm !== 0 && creativeId !== 0) { - // const dealId = response.dealid || ''; - const currency = response.cur || 'USD'; - const netRevenue = true; - // const referrer = bidRequest.data.referer; - const bidResponse = { - requestId: response.bidId, - cpm: cpm, - width: width, - height: height, - creativeId: creativeId, - // dealId: dealId, - currency: currency, - netRevenue: netRevenue, - ttl: config.getConfig('_bidderTimeout'), - // referrer: referrer, - // ad: response.adm - ad: adCreative - }; - bidResponses.push(bidResponse); - } - return bidResponses; - }, - - getUserSyncs: function(syncOptions, serverResponse) { - let syncUrls = serverResponse[0] && serverResponse[0].body && serverResponse[0].body.cookiesync && serverResponse[0].body.cookiesync.bidder_status; - - if (syncOptions.iframeEnabled && syncUrls && syncUrls.length > 0) { - let prebidSyncUrls = syncUrls.map(syncObj => { - return { - url: syncObj.usersync.url, - type: 'iframe' - } - }) - return prebidSyncUrls; - } - return []; - }, - - onTImeout: function(data) {}, - onBidWon: function(bid) {}, - onSetTargeting: function(bid) {} -}; -registerBidder(spec); +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER} from '../src/mediaTypes.js'; + +const BIDDER_CODE = 'vdo.ai'; +const ENDPOINT_URL = 'https://prebid.vdo.ai/auction'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER], + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bid) { + return !!(bid.params.placementId); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @return Array Info describing the request to the server. + * @param validBidRequests + * @param bidderRequest + */ + buildRequests: function (validBidRequests, bidderRequest) { + if (validBidRequests.length === 0) { + return []; + } + return validBidRequests.map(bidRequest => { + const sizes = utils.parseSizesInput(bidRequest.params.size || bidRequest.sizes)[0]; + const width = sizes.split('x')[0]; + const height = sizes.split('x')[1]; + const payload = { + placementId: bidRequest.params.placementId, + width: width, + height: height, + bidId: bidRequest.bidId, + referer: bidderRequest.refererInfo.referer, + id: bidRequest.auctionId + }; + bidRequest.params.bidFloor && (payload['bidFloor'] = bidRequest.params.bidFloor); + return { + method: 'POST', + url: ENDPOINT_URL, + data: payload + }; + }); + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {ServerResponse} serverResponse A successful response from the server. + * @param bidRequest + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function (serverResponse, bidRequest) { + const bidResponses = []; + const response = serverResponse.body; + const creativeId = response.adid || 0; + // const width = response.w || 0; + const width = bidRequest.data.width; + // const height = response.h || 0; + const height = bidRequest.data.height; + const cpm = response.price || 0; + + response.rWidth = width; + response.rHeight = height; + + const adCreative = response.vdoCreative; + + if (width !== 0 && height !== 0 && cpm !== 0 && creativeId !== 0) { + // const dealId = response.dealid || ''; + const currency = response.cur || 'USD'; + const netRevenue = true; + // const referrer = bidRequest.data.referer; + const bidResponse = { + requestId: response.bidId, + cpm: cpm, + width: width, + height: height, + creativeId: creativeId, + // dealId: dealId, + currency: currency, + netRevenue: netRevenue, + ttl: config.getConfig('_bidderTimeout'), + // referrer: referrer, + // ad: response.adm + ad: adCreative + }; + bidResponses.push(bidResponse); + } + return bidResponses; + }, + + getUserSyncs: function(syncOptions, serverResponse) { + let syncUrls = serverResponse[0] && serverResponse[0].body && serverResponse[0].body.cookiesync && serverResponse[0].body.cookiesync.bidder_status; + + if (syncOptions.iframeEnabled && syncUrls && syncUrls.length > 0) { + let prebidSyncUrls = syncUrls.map(syncObj => { + return { + url: syncObj.usersync.url, + type: 'iframe' + } + }) + return prebidSyncUrls; + } + return []; + }, + + onTImeout: function(data) {}, + onBidWon: function(bid) {}, + onSetTargeting: function(bid) {} +}; +registerBidder(spec); From cd15a80e45b364798a50b54252f4f3441629959f Mon Sep 17 00:00:00 2001 From: Eric Harper Date: Thu, 5 Mar 2020 16:57:08 -0500 Subject: [PATCH 106/496] Prebid 3.10.0 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1183d9123d5..9d72c7ec96d 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.10.0-pre", + "version": "3.10.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 65737488c592a897c29687019122d668ddc3917a Mon Sep 17 00:00:00 2001 From: Eric Harper Date: Thu, 5 Mar 2020 17:06:31 -0500 Subject: [PATCH 107/496] Increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d72c7ec96d..80d6cb75ea5 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.10.0", + "version": "3.11.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From ee697cd20233030ea8e0aebe300642d81cccd969 Mon Sep 17 00:00:00 2001 From: harpere Date: Thu, 5 Mar 2020 18:04:57 -0500 Subject: [PATCH 108/496] Add prebid version to /bid and /win calls (#4855) * orbidder adapter: add withCredentials:true header to BidRequest and onBidWon Requests * add blank in order to trigger build again * remove blank to trigger build ... again * adding extra line to trigger build ... again * add prebid version to request * add unit test for version parameter * add version parameter to win requests * fix comment * trigger rebuild * trigger rebuild Co-authored-by: RainerVolk4014 <53347752+RainerVolk4014@users.noreply.github.com> Co-authored-by: siggi-otto <57615762+siggi-otto@users.noreply.github.com> Co-authored-by: hendrikiseke1979 <53309111+hendrikiseke1979@users.noreply.github.com> --- modules/orbidderBidAdapter.js | 8 +++----- test/spec/modules/orbidderBidAdapter_spec.js | 9 +++++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/modules/orbidderBidAdapter.js b/modules/orbidderBidAdapter.js index d3607c2b882..2335bd37603 100644 --- a/modules/orbidderBidAdapter.js +++ b/modules/orbidderBidAdapter.js @@ -34,6 +34,7 @@ export const spec = { method: 'POST', options: { withCredentials: true }, data: { + v: $$PREBID_GLOBAL$$.version, pageUrl: referer, bidId: bidRequest.bidId, auctionId: bidRequest.auctionId, @@ -74,17 +75,14 @@ export const spec = { }, onBidWon(bid) { - this.onHandler(bid, '/win'); - }, - - onHandler (bid, route) { const getRefererInfo = detectReferer(window); + bid.v = $$PREBID_GLOBAL$$.version; bid.pageUrl = getRefererInfo().referer; if (spec.bidParams[bid.requestId] && (typeof bid.params === 'undefined')) { bid.params = [spec.bidParams[bid.requestId]]; } - spec.ajaxCall(`${spec.orbidderHost}${route}`, JSON.stringify(bid)); + spec.ajaxCall(`${spec.orbidderHost}/win`, JSON.stringify(bid)); }, ajaxCall(endpoint, data) { diff --git a/test/spec/modules/orbidderBidAdapter_spec.js b/test/spec/modules/orbidderBidAdapter_spec.js index 7e07c47ba95..c20f11da5b5 100644 --- a/test/spec/modules/orbidderBidAdapter_spec.js +++ b/test/spec/modules/orbidderBidAdapter_spec.js @@ -96,9 +96,13 @@ describe('orbidderBidAdapter', () => { expect(request.url).to.equal(`${spec.orbidderHost}/bid`); }); + it('contains prebid version parameter', () => { + expect(request.data.v).to.equal($$PREBID_GLOBAL$$.version); + }); + it('sends correct bid parameters', () => { - // we add one, because we add referer information from bidderRequest object - expect(Object.keys(request.data).length).to.equal(Object.keys(defaultBidRequest).length + 1); + // we add two, because we add referer information and version from bidderRequest object + expect(Object.keys(request.data).length).to.equal(Object.keys(defaultBidRequest).length + 2); expect(request.data.pageUrl).to.equal('https://localhost:9876/'); // expect(request.data.referrer).to.equal(''); Object.keys(defaultBidRequest).forEach((key) => { @@ -162,6 +166,7 @@ describe('orbidderBidAdapter', () => { spec.bidParams['123req456'] = {'accountId': '123acc456'}; let bidObjClone = deepClone(bidObj); + bidObjClone.v = $$PREBID_GLOBAL$$.version; bidObjClone.pageUrl = detectReferer(window)().referer; bidObjClone.params = [{'accountId': '123acc456'}]; From 36abdf691ea4bf3b1146c57db1c09e015503ecba Mon Sep 17 00:00:00 2001 From: Samuel Horwitz Date: Fri, 6 Mar 2020 11:04:30 -0500 Subject: [PATCH 109/496] Kargo adding ad domain metadata (#4905) --- modules/kargoBidAdapter.js | 9 ++++++++- test/spec/modules/kargoBidAdapter_spec.js | 19 ++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/modules/kargoBidAdapter.js b/modules/kargoBidAdapter.js index c0e27518bd9..7d50840e88f 100644 --- a/modules/kargoBidAdapter.js +++ b/modules/kargoBidAdapter.js @@ -59,6 +59,12 @@ export const spec = { const bidResponses = []; for (let bidId in bids) { let adUnit = bids[bidId]; + let meta; + if (adUnit.metadata && adUnit.metadata.landingPageDomain) { + meta = { + clickUrl: adUnit.metadata.landingPageDomain + }; + } bidResponses.push({ requestId: bidId, cpm: Number(adUnit.cpm), @@ -69,7 +75,8 @@ export const spec = { creativeId: adUnit.id, dealId: adUnit.targetingCustom, netRevenue: true, - currency: bidRequest.currency + currency: bidRequest.currency, + meta: meta }); } return bidResponses; diff --git a/test/spec/modules/kargoBidAdapter_spec.js b/test/spec/modules/kargoBidAdapter_spec.js index f64800be290..380f55bc67b 100644 --- a/test/spec/modules/kargoBidAdapter_spec.js +++ b/test/spec/modules/kargoBidAdapter_spec.js @@ -440,7 +440,8 @@ describe('kargo adapter tests', function () { cpm: 3, adm: '
', width: 320, - height: 50 + height: 50, + metadata: {} }, 2: { id: 'bar', @@ -448,7 +449,10 @@ describe('kargo adapter tests', function () { adm: '
', width: 300, height: 250, - targetingCustom: 'dmpmptest1234' + targetingCustom: 'dmpmptest1234', + metadata: { + landingPageDomain: 'https://foobar.com' + } }, 3: { id: 'bar', @@ -486,7 +490,8 @@ describe('kargo adapter tests', function () { creativeId: 'foo', dealId: undefined, netRevenue: true, - currency: 'USD' + currency: 'USD', + meta: undefined }, { requestId: '2', cpm: 2.5, @@ -497,7 +502,10 @@ describe('kargo adapter tests', function () { creativeId: 'bar', dealId: 'dmpmptest1234', netRevenue: true, - currency: 'USD' + currency: 'USD', + meta: { + clickUrl: 'https://foobar.com' + } }, { requestId: '3', cpm: 2.5, @@ -508,7 +516,8 @@ describe('kargo adapter tests', function () { creativeId: 'bar', dealId: undefined, netRevenue: true, - currency: 'USD' + currency: 'USD', + meta: undefined }]; expect(resp).to.deep.equal(expectation); }); From 6324c93c0574672abe52b017b731ec0eba7360e2 Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Fri, 6 Mar 2020 12:58:13 -0500 Subject: [PATCH 110/496] fix bug related to default usersync config for image-based pixels (#4928) * fix bug related to default usersync config * fix lint error --- src/userSync.js | 40 ++++++++++++------ test/spec/userSync_spec.js | 83 +++++++++++++++++++++++++++++++++++++- 2 files changed, 110 insertions(+), 13 deletions(-) diff --git a/src/userSync.js b/src/userSync.js index 6f23d915883..4d09d95a412 100644 --- a/src/userSync.js +++ b/src/userSync.js @@ -2,20 +2,22 @@ import * as utils from './utils.js'; import { config } from './config.js'; import includes from 'core-js/library/fn/array/includes.js'; +export const USERSYNC_DEFAULT_CONFIG = { + syncEnabled: true, + filterSettings: { + image: { + bidders: '*', + filter: 'include' + } + }, + syncsPerBidder: 5, + syncDelay: 3000, + auctionDelay: 0 +}; + // Set userSync default values config.setDefaults({ - 'userSync': { - syncEnabled: true, - filterSettings: { - image: { - bidders: '*', - filter: 'include' - } - }, - syncsPerBidder: 5, - syncDelay: 3000, - auctionDelay: 0 - } + 'userSync': utils.deepClone(USERSYNC_DEFAULT_CONFIG) }); /** @@ -45,6 +47,20 @@ export function newUserSync(userSyncDependencies) { let usConfig = userSyncDependencies.config; // Update if it's (re)set config.getConfig('userSync', (conf) => { + // if userSync.filterSettings only contains iframe, merge in default image config to ensure image pixels are fired + if (conf.userSync) { + let fs = conf.userSync.filterSettings; + if (utils.isPlainObject(fs)) { + let fsKeys = Object.keys(fs); + if (fsKeys.length === 1 && fsKeys[0] === 'iframe') { + conf.userSync.filterSettings.image = { + bidders: '*', + filter: 'include' + }; + } + } + } + usConfig = Object.assign(usConfig, conf.userSync); }); diff --git a/test/spec/userSync_spec.js b/test/spec/userSync_spec.js index bd7c7d66a85..2b68349ca31 100644 --- a/test/spec/userSync_spec.js +++ b/test/spec/userSync_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { config } from 'src/config.js'; // Use require since we need to be able to write to these vars const utils = require('../../src/utils'); -let { newUserSync } = require('../../src/userSync'); +let { newUserSync, USERSYNC_DEFAULT_CONFIG } = require('../../src/userSync'); describe('user sync', function () { let triggerPixelStub; @@ -34,6 +34,7 @@ describe('user sync', function () { }); beforeEach(function () { + config.setConfig({ userSync: USERSYNC_DEFAULT_CONFIG }); triggerPixelStub = sinon.stub(utils, 'triggerPixel'); logWarnStub = sinon.stub(utils, 'logWarn'); shuffleStub = sinon.stub(utils, 'shuffle').callsFake((array) => array.reverse()); @@ -47,6 +48,7 @@ describe('user sync', function () { shuffleStub.restore(); getUniqueIdentifierStrStub.restore(); insertUserSyncIframeStub.restore(); + config.resetConfig(); }); it('should register and fire a pixel URL', function () { @@ -374,6 +376,85 @@ describe('user sync', function () { expect(insertUserSyncIframeStub.getCall(0)).to.be.null; }); + it('should still allow default image syncs if setConfig only defined iframe', function () { + const userSync = newUserSync({ + config: config.getConfig('userSync'), + browserSupportsCookies: true + }); + + config.setConfig({ + userSync: { + filterSettings: { + iframe: { + bidders: ['bidderXYZ'], + filter: 'include' + } + } + } + }); + + userSync.registerSync('image', 'testBidder', 'http://example.com'); + userSync.registerSync('iframe', 'bidderXYZ', 'http://example.com/iframe'); + userSync.syncUsers(); + expect(triggerPixelStub.getCall(0)).to.not.be.null; + expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com'); + expect(insertUserSyncIframeStub.getCall(0).args[0]).to.equal('http://example.com/iframe'); + }); + + it('should override default image syncs if setConfig used image filter', function () { + const userSync = newUserSync({ + config: config.getConfig('userSync'), + browserSupportsCookies: true + }); + + config.setConfig({ + userSync: { + filterSettings: { + image: { + bidders: ['bidderXYZ'], + filter: 'exclude' + } + } + } + }); + + userSync.registerSync('image', 'testBidder', 'http://example.com'); + userSync.registerSync('image', 'bidderXYZ', 'http://example.com/image-blocked'); + userSync.syncUsers(); + expect(triggerPixelStub.getCall(0)).to.not.be.null; + expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com'); + expect(triggerPixelStub.getCall(1)).to.be.null; + }); + + it('should override default image syncs if setConfig used all filter', function() { + const userSync = newUserSync({ + config: config.getConfig('userSync'), + browserSupportsCookies: true + }); + + config.setConfig({ + userSync: { + filterSettings: { + all: { + bidders: ['bidderXYZ'], + filter: 'exclude' + } + } + } + }); + + userSync.registerSync('image', 'testBidder', 'http://example.com'); + userSync.registerSync('image', 'bidderXYZ', 'http://example.com/image-blocked'); + userSync.registerSync('iframe', 'testBidder', 'http://example.com/iframe'); + userSync.registerSync('iframe', 'bidderXYZ', 'http://example.com/iframe-blocked'); + userSync.syncUsers(); + expect(triggerPixelStub.getCall(0)).to.not.be.null; + expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com'); + expect(triggerPixelStub.getCall(1)).to.be.null; + expect(insertUserSyncIframeStub.getCall(0).args[0]).to.equal('http://example.com/iframe'); + expect(insertUserSyncIframeStub.getCall(1)).to.be.null; + }); + describe('publicAPI', function () { describe('canBidderRegisterSync', function () { describe('with filterSettings', function () { From 9c1550ff27c3a45b75f7a4efded579e628a0c532 Mon Sep 17 00:00:00 2001 From: Tomas Roos Date: Fri, 6 Mar 2020 19:22:21 +0100 Subject: [PATCH 111/496] Find gpt div based on adId to be resized instead of hardcoded adunitcode / slotelementid (#4710) * Added failing test * Added working implementation to secureCreatives * Implemented correctly set/get*Targeting behaviour in googletag * Walk through all targeting keys in case, send all bids or custom adid key is used * Fix googletag inconsistency with real gpt behaviour --- src/secureCreatives.js | 19 ++++-- test/spec/modules/shareUserIds_spec.js | 10 +-- test/spec/unit/pbjs_api_spec.js | 91 ++++++++++++++++++++------ 3 files changed, 90 insertions(+), 30 deletions(-) diff --git a/src/secureCreatives.js b/src/secureCreatives.js index fb0d7e2bc9c..36e5efe22cd 100644 --- a/src/secureCreatives.js +++ b/src/secureCreatives.js @@ -6,10 +6,11 @@ import events from './events.js'; import { fireNativeTrackers, getAssetMessage } from './native.js'; import { EVENTS } from './constants.json'; -import { isSlotMatchingAdUnitCode, logWarn, replaceAuctionPrice } from './utils.js'; +import { logWarn, replaceAuctionPrice } from './utils.js'; import { auctionManager } from './auctionManager.js'; import find from 'core-js/library/fn/array/find.js'; import { isRendererRequired, executeRenderer } from './Renderer.js'; +import includes from 'core-js/library/fn/array/includes.js'; const BID_WON = EVENTS.BID_WON; @@ -79,7 +80,7 @@ export function _sendAdToCreative(adObject, remoteDomain, source) { } } -function resizeRemoteCreative({ adUnitCode, width, height }) { +function resizeRemoteCreative({ adId, adUnitCode, width, height }) { // resize both container div + iframe ['div', 'iframe'].forEach(elmType => { // not select element that gets removed after dfp render @@ -94,14 +95,14 @@ function resizeRemoteCreative({ adUnitCode, width, height }) { }); function getElementByAdUnit(elmType) { - let id = getElementIdBasedOnAdServer(adUnitCode); + let id = getElementIdBasedOnAdServer(adId, adUnitCode); let parentDivEle = document.getElementById(id); return parentDivEle && parentDivEle.querySelector(elmType); } - function getElementIdBasedOnAdServer(adUnitCode) { + function getElementIdBasedOnAdServer(adId, adUnitCode) { if (window.googletag) { - return getDfpElementId(adUnitCode) + return getDfpElementId(adId) } else if (window.apntag) { return getAstElementId(adUnitCode) } else { @@ -109,8 +110,12 @@ function resizeRemoteCreative({ adUnitCode, width, height }) { } } - function getDfpElementId(adUnitCode) { - return find(window.googletag.pubads().getSlots().filter(isSlotMatchingAdUnitCode(adUnitCode)), slot => slot).getSlotElementId() + function getDfpElementId(adId) { + return find(window.googletag.pubads().getSlots(), slot => { + return find(slot.getTargetingKeys(), key => { + return includes(slot.getTargeting(key), adId); + }); + }).getSlotElementId(); } function getAstElementId(adUnitCode) { diff --git a/test/spec/modules/shareUserIds_spec.js b/test/spec/modules/shareUserIds_spec.js index 18f45e405f5..451892919cb 100644 --- a/test/spec/modules/shareUserIds_spec.js +++ b/test/spec/modules/shareUserIds_spec.js @@ -22,7 +22,7 @@ describe('#userIdTargeting', function() { pubads.clearTargeting(); pubads.setTargeting('test', ['TEST']); userIdTargeting(userIds, JSON.stringify(config)); - expect(pubads.getTargeting()).to.deep.equal({test: ['TEST']}); + expect(pubads.getTargeting('test')).to.deep.equal(['TEST']); }); it('all UserIds are passed as is with GAM: true', function() { @@ -31,7 +31,8 @@ describe('#userIdTargeting', function() { pubads.setTargeting('test', ['TEST']); delete config.GAM_KEYS; userIdTargeting(userIds, config); - expect(pubads.getTargeting()).to.deep.equal({test: ['TEST'], tdid: ['my-tdid']}); + expect(pubads.getTargeting('test')).to.deep.equal(['TEST']); + expect(pubads.getTargeting('tdid')).to.deep.equal(['my-tdid']); }) it('Publisher prefered key-names are used', function() { @@ -39,7 +40,8 @@ describe('#userIdTargeting', function() { pubads.clearTargeting(); pubads.setTargeting('test', ['TEST']); userIdTargeting(userIds, config); - expect(pubads.getTargeting()).to.deep.equal({test: ['TEST'], 'TD_ID': ['my-tdid']}); + expect(pubads.getTargeting('test')).to.deep.equal(['TEST']); + expect(pubads.getTargeting('TD_ID')).to.deep.equal(['my-tdid']); }); it('Publisher does not want to pass an id', function() { @@ -48,6 +50,6 @@ describe('#userIdTargeting', function() { pubads.setTargeting('test', ['TEST']); config.GAM_KEYS.tdid = ''; userIdTargeting(userIds, config); - expect(pubads.getTargeting()).to.deep.equal({test: ['TEST']}); + expect(pubads.getTargeting('test')).to.deep.equal(['TEST']); }); }); diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index f18310e8287..f0bd4eecdeb 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -14,6 +14,7 @@ import { config as configObj } from 'src/config.js'; import * as ajaxLib from 'src/ajax.js'; import * as auctionModule from 'src/auction.js'; import { newBidder, registerBidder } from 'src/adapters/bidderFactory.js'; +import { _sendAdToCreative } from 'src/secureCreatives.js'; import find from 'core-js/library/fn/array/find.js'; var assert = require('chai').assert; @@ -56,7 +57,7 @@ function resetAuction() { var Slot = function Slot(elementId, pathId) { var slot = { - targeting: [], + targeting: {}, getSlotElementId: function getSlotElementId() { return elementId; }, @@ -66,24 +67,24 @@ var Slot = function Slot(elementId, pathId) { }, setTargeting: function setTargeting(key, value) { - var obj = []; - obj[key] = value; - this.targeting.push(obj); + this.targeting[key] = Array.isArray(value) ? value : [value]; }, - getTargeting: function getTargeting() { - return this.targeting; + getTargeting: function getTargeting(key) { + return this.targeting[key] || []; }, getTargetingKeys: function getTargetingKeys() { - return []; + return Object.getOwnPropertyNames(this.targeting); }, clearTargeting: function clearTargeting() { - return googletag.pubads().getSlots(); + this.targeting = {}; + return this; } }; slot.spySetTargeting = sinon.spy(slot, 'setTargeting'); + slot.spyGetSlotElementId = sinon.spy(slot, 'getSlotElementId'); return slot; }; @@ -121,11 +122,15 @@ window.googletag = { }, setTargeting: function(key, arrayOfValues) { - self._targeting[key] = arrayOfValues; + self._targeting[key] = Array.isArray(arrayOfValues) ? arrayOfValues : [arrayOfValues]; }, - getTargeting: function() { - return self._targeting; + getTargeting: function(key) { + return self._targeting[key] || []; + }, + + getTargetingKeys: function() { + return Object.getOwnPropertyNames(self._targeting); }, clearTargeting: function() { @@ -856,17 +861,31 @@ describe('Unit: Prebid Module', function () { it('should set googletag targeting keys after calling setTargetingForGPTAsync function', function () { var slots = createSlotArrayScenario2(); window.googletag.pubads().setSlots(slots); - $$PREBID_GLOBAL$$.setTargetingForGPTAsync(); + $$PREBID_GLOBAL$$.setTargetingForGPTAsync([config.adUnitCodes[0]]); + + // we need to transform the spySetTargeting into something that looks like + // googletag's targeting structure + // googletag setTargeting will override old value if invoked with same key + + const targeting = []; + slots[1].getTargetingKeys().map(function (key) { + const value = slots[1].getTargeting(key); + targeting.push([key, value]); + }); - var targeting = []; - slots[1].getTargeting().map(function (value) { - var temp = []; - temp.push(Object.keys(value).toString()); - temp.push(value[Object.keys(value)]); - targeting.push(temp); + var invokedTargetingMap = {}; + slots[1].spySetTargeting.args.map(function (entry) { + invokedTargetingMap[entry[0]] = entry[1]; }); - assert.deepEqual(slots[1].spySetTargeting.args, targeting, 'google tag targeting options not matching'); + var invokedTargeting = []; + + console.log(invokedTargetingMap); + Object.getOwnPropertyNames(invokedTargetingMap).map(function (key) { + const value = Array.isArray(invokedTargetingMap[key]) ? invokedTargetingMap[key] : [invokedTargetingMap[key]]; // values are always returned as array in googletag + invokedTargeting.push([key, value]); + }); + assert.deepEqual(targeting, invokedTargeting, 'google tag targeting options not matching'); }); it('should set googletag targeting keys to specific slot with customSlotMatching', function () { @@ -925,6 +944,40 @@ describe('Unit: Prebid Module', function () { expect(slots[0].spySetTargeting.args).to.deep.contain.members(expected); }); + it('should find correct gpt slot based on ad id rather than ad unit code when resizing secure creative', function () { + var slots = [ + new Slot('div-not-matching-adunit-code-1', config.adUnitCodes[0]), + new Slot('div-not-matching-adunit-code-2', config.adUnitCodes[0]), + new Slot('div-not-matching-adunit-code-3', config.adUnitCodes[0]) + ]; + + slots[1].setTargeting('hb_adid', ['someAdId']); + slots[1].spyGetSlotElementId.resetHistory(); + window.googletag.pubads().setSlots(slots); + + const mockAdObject = { + adId: 'someAdId', + ad: '', + adUrl: 'http://creative.prebid.org/${AUCTION_PRICE}', + width: 300, + height: 250, + renderer: null, + cpm: '1.00', + adUnitCode: config.adUnitCodes[0], + }; + + const remoteDomain = '*'; + const source = { + postMessage: sinon.stub() + }; + + _sendAdToCreative(mockAdObject, remoteDomain, source); + + expect(slots[0].spyGetSlotElementId.called).to.equal(false); + expect(slots[1].spyGetSlotElementId.called).to.equal(true); + expect(slots[2].spyGetSlotElementId.called).to.equal(false); + }); + it('Calling enableSendAllBids should set targeting to include standard keys with bidder' + ' append to key name', function () { var slots = createSlotArray(); From ac04468e6e00c44f612084d671219d4c81a6865d Mon Sep 17 00:00:00 2001 From: sumit sharma Date: Sat, 7 Mar 2020 00:50:16 +0530 Subject: [PATCH 112/496] E2e tests for instream, Prebid modules and features (#4744) * longform and other e2etests with mock server * tests with mock response * fix indentation * instream e2e tests * consent management e2e tests * gdpr mock response file * currency e2e * refactor structure * add test for targeting keys * e2e prebid features * e2e sizeConfig feature * refactor * fix lint errors * update test title * multiple bidders adUnit test * switch to parent to switch frames * add debugger to test page Co-authored-by: sumit sharma Co-authored-by: sumit sharma --- gulpfile.js | 2 +- .../request-response-pairs/currency/index.js | 175 ++++ .../request-response-pairs/gdpr/index.js | 94 ++ .../request-response-pairs/instream/index.js | 94 ++ .../ad_server_translation_request_1.js | 577 ++++++++++++ .../ad_server_translation_request_2.js | 289 ++++++ .../basic_w_requireExactDuration_request_1.js | 606 +++++++++++++ .../basic_w_requireExactDuration_request_2.js | 288 ++++++ ...sic_wo_brandCategoryExclusion_request_1.js | 852 ++++++++++++++++++ ...sic_wo_brandCategoryExclusion_request_2.js | 312 +++++++ ...basic_wo_requireExactDuration_request_1.js | 620 +++++++++++++ ...basic_wo_requireExactDuration_request_2.js | 312 +++++++ .../longform/bidder_settings_request_1.js | 418 +++++++++ .../longform/bidder_settings_request_2.js | 284 ++++++ .../longform/price_gran_request_1.js | 620 +++++++++++++ .../longform/price_gran_request_2.js | 283 ++++++ .../multiple-bidders/index-1.js | 110 +++ .../multiple-bidders/index-2.js | 175 ++++ .../request-response-pairs/native/index.js | 191 ++++ .../request-response-pairs/outstream/index.js | 162 ++++ .../request-middlewares/prebid-request.js | 2 +- test/pages/bidderSettings.html | 125 +++ test/pages/consent_mgt_gdpr.html | 206 +++++ test/pages/currency.html | 129 +++ test/pages/{video.html => instream.html} | 8 +- test/pages/multiple_bidders.html | 174 ++++ test/pages/priceGranularity.html | 131 +++ test/pages/sizeConfig.html | 142 +++ test/pages/userSync.html | 121 +++ .../instream/basic_instream_video_ad.spec.js | 52 ++ .../e2e/modules/e2e_bidderSettings.spec.js | 59 ++ .../e2e/modules/e2e_consent_mgt_gdpr.spec.js | 59 ++ test/spec/e2e/modules/e2e_currency.spec.js | 59 ++ .../e2e/modules/e2e_priceGranularity.spec.js | 59 ++ test/spec/e2e/modules/e2e_sizeConfig.spec.js | 59 ++ test/spec/e2e/modules/e2e_userSync.spec.js | 59 ++ .../multi-format/e2e_multiple_bidders.spec.js | 68 ++ test/spec/e2e/native/basic_native_ad.spec.js | 2 +- wdio.conf.js | 3 +- 39 files changed, 7975 insertions(+), 6 deletions(-) create mode 100644 test/mock-server/expectations/request-response-pairs/currency/index.js create mode 100644 test/mock-server/expectations/request-response-pairs/gdpr/index.js create mode 100644 test/mock-server/expectations/request-response-pairs/instream/index.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_1.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_2.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_1.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_2.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_1.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_2.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_1.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_2.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_1.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_2.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/price_gran_request_1.js create mode 100644 test/mock-server/expectations/request-response-pairs/longform/price_gran_request_2.js create mode 100644 test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js create mode 100644 test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js create mode 100644 test/mock-server/expectations/request-response-pairs/native/index.js create mode 100644 test/mock-server/expectations/request-response-pairs/outstream/index.js create mode 100644 test/pages/bidderSettings.html create mode 100644 test/pages/consent_mgt_gdpr.html create mode 100644 test/pages/currency.html rename test/pages/{video.html => instream.html} (93%) create mode 100644 test/pages/multiple_bidders.html create mode 100644 test/pages/priceGranularity.html create mode 100644 test/pages/sizeConfig.html create mode 100644 test/pages/userSync.html create mode 100644 test/spec/e2e/instream/basic_instream_video_ad.spec.js create mode 100644 test/spec/e2e/modules/e2e_bidderSettings.spec.js create mode 100644 test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js create mode 100644 test/spec/e2e/modules/e2e_currency.spec.js create mode 100644 test/spec/e2e/modules/e2e_priceGranularity.spec.js create mode 100644 test/spec/e2e/modules/e2e_sizeConfig.spec.js create mode 100644 test/spec/e2e/modules/e2e_userSync.spec.js create mode 100644 test/spec/e2e/multi-format/e2e_multiple_bidders.spec.js diff --git a/gulpfile.js b/gulpfile.js index 7c4ca306886..d8b78106777 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -328,7 +328,7 @@ function setupE2e(done) { gulp.task('updatepath', function(){ return gulp.src(['build/dist/*.js']) - .pipe(replace('ib.adnxs.com/ut/v3/prebid', host + ':' + mockServerPort + '/')) + .pipe(replace('https://ib.adnxs.com/ut/v3/prebid', 'http://' + host + ':' + mockServerPort + '/')) .pipe(gulp.dest('build/dist')); }); diff --git a/test/mock-server/expectations/request-response-pairs/currency/index.js b/test/mock-server/expectations/request-response-pairs/currency/index.js new file mode 100644 index 00000000000..1f809476afa --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/currency/index.js @@ -0,0 +1,175 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 300, + 'height': 250 + }, { + 'width': 300, + 'height': 600 + }], + 'primary_size': { + 'width': 300, + 'height': 250 + }, + 'ad_types': ['banner'], + 'id': 13144370, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true + }, { + 'sizes': [{ + 'width': 1, + 'height': 1 + }], + 'ad_types': ['native'], + 'id': 13232354, + 'allow_smaller_sizes': true, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'native': { + 'layouts': [{ + 'title': { + 'required': true + }, + 'description': { + 'required': true + }, + 'main_image': { + 'required': true + }, + 'sponsored_by': { + 'required': true + }, + 'icon': { + 'required': false + } + }] + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '232f6ceccb3749', + 'tag_id': 13144370, + 'auction_id': '4842409943576641356', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QK7CKA7BAAAAwDWAAUBCNvV-_AFEMz-0f3_xeyZQxjCs_b6q5D9_0oqNgkAAAkCABEJBywAABkAAACA61HgPyEREgApEQkAMREb8GkwsqKiBjjtSEDtSEgAUABYnPFbYABotc95eACAAQGKAQCSAQNVU0SYAawCoAHYBKgBAbABALgBAcABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3OTA4NDUwNyk7AR0scicsIDk4NDkzNTgxNh4A8NCSArUCIVpqeldtZ2l1c0s0S0VJM0oteTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlNSUdhQUJ3RG5qd0U0QUJUSWdCOEJPUUFRQ1lBUUNnQVFHb0FRT3dBUUM1QVNtTGlJTUFBT0Ffd1FFcGk0aURBQURnUDhrQmxiMDhGYV9INERfWkFRQUFBQUFBQVBBXzRBRUE5UUVBQUFBQW1BSUFvQUlBdFFJQUFBQUF2UUlBQUFBQTRBSUE2QUlBLUFJQWdBTUJtQU1CcUFPdQHEiHVnTUpVMGxPTXpvME56TTE0QU80R1lnRUFKQUVBSmdFQWNFCV0FAQhESkIFCAkBGDJBUUE4UVEJDQEBLFBnRUFJZ0ZfeVNwQhEXNFBBX5oCiQEhblE4cUxBNjkBJG5QRmJJQVFvQUQRZBBEZ1B6bzKRABBRTGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJLDTpIdGVzdC5sb2NhbGhvc3Q6OTk5OQUUWC9wYWdlcy9tb2R1bGVzL2N1cnJlbmN5BUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbDwXpgEAKIECzEwLjc1Ljc0LjY5qATikAGyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8ASNyfsuiAUBmAUAoAX_____BQMYAcAFAMkFAAUBFPA_0gUJCQULfAAAANgFAeAFAfAFmfQh-gUECAAQAJAGAJgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=16a5ea7c8d5eb050a368495961803753dd6086c2', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'banner', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 98493581, + 'media_type_id': 1, + 'media_subtype_id': 1, + 'cpm': 0.500000, + 'cpm_publisher_currency': 0.500000, + 'publisher_currency_code': '$', + 'brand_category_id': 53, + 'client_initiated_ad_counting': true, + 'rtb': { + 'banner': { + 'content': "
", + 'width': 300, + 'height': 600 + }, + 'trackers': [{ + 'impression_urls': ['http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLDCKBDBAAAAwDWAAUBCNvV-_AFEMz-0f3_xeyZQxjCs_b6q5D9_0oqNgkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJADERG6gwsqKiBjjtSEDtSEgCUI3J-y5YnPFbYABotc95eJ64BYABAYoBA1VTRJIBAQbwUpgBrAKgAdgEqAEBsAEAuAEBwAEEyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5MDg0NTA3KTt1ZigncicsIDk4NDkzNTgxNh4A8NCSArUCIVpqeldtZ2l1c0s0S0VJM0oteTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlNSUdhQUJ3RG5qd0U0QUJUSWdCOEJPUUFRQ1lBUUNnQVFHb0FRT3dBUUM1QVNtTGlJTUFBT0Ffd1FFcGk0aURBQURnUDhrQmxiMDhGYV9INERfWkFRQUFBQUFBQVBBXzRBRUE5UUVBQUFBQW1BSUFvQUlBdFFJQUFBQUF2UUlBQUFBQTRBSUE2QUlBLUFJQWdBTUJtQU1CcUFPdQHEiHVnTUpVMGxPTXpvME56TTE0QU80R1lnRUFKQUVBSmdFQWNFCV0FAQhESkIFCAkBGDJBUUE4UVEJDQEBLFBnRUFJZ0ZfeVNwQhEXNFBBX5oCiQEhblE4cUxBNjkBJG5QRmJJQVFvQUQRZBBEZ1B6bzKRABBRTGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJLDTpIdGVzdC5sb2NhbGhvc3Q6OTk5OQUUWC9wYWdlcy9tb2R1bGVzL2N1cnJlbmN5BUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbDwXpgEAKIECzEwLjc1Ljc0LjY5qATikAGyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQB8ASNyfsuiAUBmAUAoAX_____BQMYAcAFAMkFAAUBFPA_0gUJCQULfAAAANgFAeAFAfAFmfQh-gUECAAQAJAGAJgGALgGAMEGASEwAADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=9c378bb4ca21a7509f69955fb4e6fe72035190c6'], + 'video_events': {} + }] + } + }] + }, { + 'uuid': '3867e6fdb23eb6', + 'tag_id': 13232354, + 'auction_id': '8100967561168057198', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKECKAEBAAAAwDWAAUBCNvV-_AFEO7mieO34pq2cBjCs_b6q5D9_0oqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5MDg0NTA3KTsBHSxyJywgOTc0OTQyMDQ2HgDwmpICtQIhMVR6c3lRajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWU1JR2FBQndBSGdBZ0FGTWlBSHdFNUFCQUpnQkFLQUJBYWdCQTdBQkFMa0I4NjFxcEFBQUpFREJBZk90YXFRQUFDUkF5UUc5QzZTMEtFampQOWtCQUFBQUFBQUE4RF9nQVFEMUFRAQ8sQ1lBZ0NnQWdDMUFnBRAAOQkI8EBEZ0FnRG9BZ0Q0QWdDQUF3R1lBd0dvQV96NHZBcTZBd2xUU1U0ek9qUTNNelhnQTdnWmlBUUFrQVFBbUFRQndRUQFNCQEITWtFCQkBARhEWUJBRHhCAQsNASwtQVFBaUFYX0pLa0YNEzxBOEQ4LpoCiQEhZUE4dE1BNjkBJG5QRmJJQVFvQUQVWFhrUURvSlUwbE9Nem8wTnpNMVFMZ1pTUQ1PDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gJLaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPDXL3BhZ2VzL21vZHVsZXMvY3VycmVuY3kuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagE4pABsgQOCAAQARgAIAAoADAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8AS8yb4uiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaVZ0ANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=428486554947609aac96ed5569d9bb2dd2be5502', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'native', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 97494204, + 'media_type_id': 12, + 'media_subtype_id': 65, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 53, + 'client_initiated_ad_counting': true, + 'viewability': { + 'config': '' + }, + 'rtb': { + 'native': { + 'title': 'This is a Prebid Native Creative', + 'desc': 'This is a Prebid Native Creative. There are many like it, but this one is mine.', + 'sponsored': 'Prebid.org', + 'icon': { + 'url': 'http://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png', + 'width': 127, + 'height': 83, + 'prevent_crop': false + }, + 'main_img': { + 'url': 'http://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg', + 'width': 989, + 'height': 742, + 'prevent_crop': false + }, + 'link': { + 'url': 'http://prebid.org/dev-docs/show-native-ads.html', + 'click_trackers': ['http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQG5zYnwTa2xwwpldv4L0_0rb6h5eAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAYBc26wAAAAA./bcr=AAAAAAAA8D8=/cnd=%21eA8tMAj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzM1QLgZSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3MzU=/bn=89118/'] + }, + 'impression_trackers': ['http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKMCKAMBAAAAwDWAAUBCNvV-_AFEO7mieO34pq2cBjCs_b6q5D9_0oqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXieuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzkwODQ1MDcpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPCakgK1AiExVHpzeVFqOC1Md0tFTHpKdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZTUlHYUFCd0FIZ0FnQUZNaUFId0U1QUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRRzlDNlMwS0VqalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BX3o0dkFxNkF3bFRTVTR6T2pRM016WGdBN2daaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhfSktrRg0TPEE4RDgumgKJASFlQTh0TUE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBOek0xUUxnWlNRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDKBlQUEu2AIA4AKtmEjqAktodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OQUU8NcvcGFnZXMvbW9kdWxlcy9jdXJyZW5jeS5odG1sP3BianNfZGVidWc9dHJ1ZYADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATikAGyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBAHwBLzJvi6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQBpXnQA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYJJCjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=d6c58ebc137658c5dd258579c2575ad499e7a7b4'], + 'id': 97494204 + } + } + }] + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/gdpr/index.js b/test/mock-server/expectations/request-response-pairs/gdpr/index.js new file mode 100644 index 00000000000..646559f2a7f --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/gdpr/index.js @@ -0,0 +1,94 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 300, + 'height': 250 + }, { + 'width': 300, + 'height': 600 + }], + 'primary_size': { + 'width': 300, + 'height': 250 + }, + 'ad_types': ['banner'], + 'id': 13144370, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '27c4cea6dfcad4', + 'tag_id': 13144370, + 'auction_id': '6784868202366971885', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fgdpr_hello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QL0CWz0BAAAAwDWAAUBCKKt0fAFEO3ftM_qtayUXhj_EQEQASo2CQANAQARDQgoABkAAACA61HgPyEREgApEQkAMREb8GkwsqKiBjjtSEDtSEgAUABYnPFbYABotc95eACAAQGKAQCSAQNVU0SYAawCoAH6AagBAbABALgBAcABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3ODM5MTIwMik7AR0scicsIDk2ODQ2MDM1Nh4A9A4BkgLJAiF0ajlmS2dpdXNLNEtFTk9CbHk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRc3FLaUJsZ0FZUF9fX184UGFBQndBWGdCZ0FFQmlBRUJrQUVCbUFFQm9BRUJxQUVEc0FFQXVRRXBpNGlEQUFEZ1A4RUJLWXVJZ3dBQTREX0pBZWxBS28zZEV1OF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBTUFDQWNnQ0FkQUNBZGdDQWVBQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pPZUFEX0JpSUJBQ1FCQUNZQkFIQkJBQUFBQQmDCHlRUQkJAQEYTmdFQVBFRQELCQEwRDRCQUNJQllNbHFRVQkTREFEd1B3Li6aAokBIWZnOFhHUTZNASRuUEZiSUFRb0FEEUhYRGdQem9KVTBsT016bzBOek01UVB3WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EBlQUEuwgIvaHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3MvZ2V0dGluZy1zdGFydGVkLmh0bWzYAgDgAq2YSOoCWA068IF0ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvZ3B0L2dkcHJfaGVsbG9fd29ybGQuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwGIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDb3wW5gEAKIECzEwLjc1Ljc0LjY5qAS_NrIEEggEEAQYrAIg-gEoASgCMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM52gQCCADgBAHwBNOBly6IBQGYBQCgBf__bcwUAcAFAMkFaakU8D_SBQkJCQyIAADYBQHgBQHwBQH6BQQIABAAkAYAmAYAsgaWAUJPc3kwUXkBBixYaUFBQUJBRU5DMi0hswh0RjdhJQxfX185AQXwcV9fOXV6X092X3ZfZl9fMzNlOF9fOXZfbF83Xy1fX191Xy0zM2Q0dV8xdmY5OXlmbTEtN2V0cjN0cF84N3VlczJfWHVyX183OV9fM3ozXzlweFA3OGs4OXI3MzM3RXdfdi1fdi1iN0pDT05fQbgGAcEGAAW-KPC_0Ab1L9oGFgoQBRAdAVAQABgA4AYB8gYCCACABwGIBwCgBwE.&s=896d8d25ed5c73ed4b49adebaa58ba23ed6afa43', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'banner', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 96846035, + 'media_type_id': 1, + 'media_subtype_id': 1, + 'cpm': 0.500000, + 'cpm_publisher_currency': 0.500000, + 'publisher_currency_code': '$', + 'brand_category_id': 0, + 'client_initiated_ad_counting': true, + 'rtb': { + 'banner': { + 'content': "
", + 'width': 300, + 'height': 250 + }, + 'trackers': [{ + 'impression_urls': ['http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fgdpr_hello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QL8CWz8BAAAAwDWAAUBCKKt0fAFEO3ftM_qtayUXhj_EQEQASo2CQAFAQjgPxEFCDAA4D8ZAAAAgOtR4D8hERIAKREJADERG6gwsqKiBjjtSEDtSEgCUNOBly5YnPFbYABotc95eMu4BYABAYoBA1VTRJIBAQbwUpgBrAKgAfoBqAEBsAEAuAEBwAEEyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc4MzkxMjAyKTt1ZigncicsIDk2ODQ2MDM1Nh4A9A4BkgLJAiF0ajlmS2dpdXNLNEtFTk9CbHk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRc3FLaUJsZ0FZUF9fX184UGFBQndBWGdCZ0FFQmlBRUJrQUVCbUFFQm9BRUJxQUVEc0FFQXVRRXBpNGlEQUFEZ1A4RUJLWXVJZ3dBQTREX0pBZWxBS28zZEV1OF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBTUFDQWNnQ0FkQUNBZGdDQWVBQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pPZUFEX0JpSUJBQ1FCQUNZQkFIQkJBQUFBQQmDCHlRUQkJAQEYTmdFQVBFRQELCQEwRDRCQUNJQllNbHFRVQkTREFEd1B3Li6aAokBIWZnOFhHUTZNASRuUEZiSUFRb0FEEUhYRGdQem9KVTBsT016bzBOek01UVB3WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EBlQUEuwgIvaHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3MvZ2V0dGluZy1zdGFydGVkLmh0bWzYAgDgAq2YSOoCWA068IF0ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvZ3B0L2dkcHJfaGVsbG9fd29ybGQuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwGIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDb3wW5gEAKIECzEwLjc1Ljc0LjY5qAS_NrIEEggEEAQYrAIg-gEoASgCMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM52gQCCAHgBAHwBNOBly6IBQGYBQCgBf__bdQUAcAFAMkFabEU8D_SBQkJCQyIAADYBQHgBQHwBQH6BQQIABAAkAYAmAYAsgaWAUJPc3kwUXkBBixYaUFBQUJBRU5DMi0hswh0RjdhJQxfX185AQXwcV9fOXV6X092X3ZfZl9fMzNlOF9fOXZfbF83Xy1fX191Xy0zM2Q0dV8xdmY5OXlmbTEtN2V0cjN0cF84N3VlczJfWHVyX183OV9fM3ozXzlweFA3OGs4OXI3MzM3RXdfdi1fdi1iN0pDT05fQbgGAcEGAAW-KPA_0Ab1L9oGFgoQBRAdAVAQABgA4AYB8gYCCACABwGIBwCgBwE.&s=1ad011df80b035fdd957f6ae84e46bdeebae9f83'], + 'video_events': {} + }] + } + }] + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/instream/index.js b/test/mock-server/expectations/request-response-pairs/instream/index.js new file mode 100644 index 00000000000..5164e56e093 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/instream/index.js @@ -0,0 +1,94 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 13232361, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': {} + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '206465a8c326a5', + 'tag_id': 13232361, + 'auction_id': '1398509384102899505', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Finstream.html&e=wqT_3QKxCKAxBAAAAwDWAAUBCKXQzPAFELHeg_SAnKC0ExjCs_b6q5D9_0oqNgkAAAkCABEJBywAABkAAADgehQUQCEREgApEQkAMREb8Hkw6dGnBjjtSEDtSEgAUABYnPFbYABozbp1eACAAQGKAQCSAQNVU0SYAQGgAQGoAQGwAQC4AQPAAQDIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzgzMTM3NjUpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPD1kgK1AiF5andtb2dpMi1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNmRHbkJsZ0FZTUlHYUFCd0tIZ0dnQUU4aUFFR2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFVUU1FQjg2MXFwQUFBRkVESkFmZjUwcVFyNGVvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHR2aThDcm9EQ1ZOSlRqTTZORGN6T09BRC1SaUlCQUNRQkFDWUJBSEJCBUUJAQh5UVEJCQEBFE5nRUFQRRGNAZAsNEJBQ0lCWUlscVFVAREBFDx3UHcuLpoCiQEhTGc5WkRRNjkBJG5QRmJJQVFvQUQVSFRVUURvSlUwbE9Nem8wTnpNNFFQa1lTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBSZUFBLsICP2h0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctdmlkZW8td2l0aC1hLWRmcC12aWRlby10YWcuaHRtbNgCAOACrZhI6gIzaHQFSkh0ZXN0LmxvY2FsaG9zdDo5OTk5BRQ4L3BhZ2VzL2luc3RyZWFtBT7IgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvCanwXpgEAKIECzEwLjc1Ljc0LjY5qAS0LLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM42gQCCADgBADwBMuBwC6IBQGYBQCgBf______AQMUAcAFAMkFaX8U8D_SBQkJCQx4AADYBQHgBQHwBcOVC_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=6805157848bdfdf973d0dbafff4bb9b4c4ce7e60', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQklKBNeAAAAABEx74AO4IBoExklKBNeAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQ6dGnBljDlQtiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=07e6e5f2f03cc92e899c3ddbf4e2988e966caaa2&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 97517771, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 5.000000, + 'cpm_publisher_currency': 5.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 36, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Finstream.html&e=wqT_3QKNCaCNBAAAAwDWAAUBCKXQzPAFELHeg_SAnKC0ExjCs_b6q5D9_0oqNgkAAAECCBRAEQEHNAAAFEAZAAAA4HoUFEAhERIAKREJADERG6gw6dGnBjjtSEDtSEgCUMuBwC5YnPFbYABozbp1eJG4BYABAYoBA1VTRJIBAQbwUpgBAaABAagBAbABALgBA8ABBMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3ODMxMzc2NSk7dWYoJ3InLCA5NzUxNzc3MSwgLh4A8PWSArUCIXlqd21vZ2kyLUx3S0VNdUJ3QzRZQUNDYzhWc3dBRGdBUUFSSTdVaFE2ZEduQmxnQVlNSUdhQUJ3S0hnR2dBRThpQUVHa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUh6cldxa0FBQVVRTUVCODYxcXBBQUFGRURKQWZmNTBxUXI0ZW9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEdHZpOENyb0RDVk5KVGpNNk5EY3pPT0FELVJpSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkCw0QkFDSUJZSWxxUVUBEQEUPHdQdy4umgKJASFMZzlaRFE2OQEkblBGYklBUW9BRBVIVFVRRG9KVTBsT016bzBOek00UVBrWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8FJlQUEuwgI_aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy12aWRlby13aXRoLWEtZGZwLXZpZGVvLXRhZy5odG1s2AIA4AKtmEjqAjNodAVKSHRlc3QubG9jYWxob3N0Ojk5OTkFFDgvcGFnZXMvaW5zdHJlYW0FPmjyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-4ElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw398F6YBACiBAsxMC43NS43NC42OagEtCyyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczONoEAggB4AQA8ATLgcAuiAUBmAUAoAX______wEDFAHABQDJBWnbFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=68b9d39d60a72307a201e479000a8c7be5508188' + } + } + }] + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_1.js new file mode 100644 index 00000000000..d92e64c6075 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_1.js @@ -0,0 +1,577 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '7360998998672342781', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEP39-97ssuGTZhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIVNqMmZTQWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQmtTcHl1c2Q4XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzhKRnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=c92cbcde5c8bf8e053f86493dd4c4698da0392de', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABH9_t7LloUnZhne-wVeAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=8e35c1264cd1b4f1d89f929c3a4a334cf6a68eca&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEP39-97ssuGTZhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFTajJmU0FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkJrU3B5dXNkOF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc4SkZ3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBNLsn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=ca640dffaea7bfcf2b0f2e11d8877821189b74bb' + } + } + }] + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '1919339751435064934', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEOasy7zbqrfRGhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIU1EMUZJQWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRclZ0ZGpIUGVBXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASE1QTdmLVE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=c3130de64bc0b8df258e603dfb96f78550ab0c3c', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABFm1pK3Vd2iGhne-wVeAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=2c3cee10303d9b93531bed443c0781d905270598&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418123, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 12, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEOasy7zbqrfRGhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFNRDFGSUFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUXJWdGRqSFBlQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhNUE3Zi1RNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBIvhn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=996a3937245f03e5eefb0cb69917d2d8d7f60424' + } + } + }] + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '3257875652791896280', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '5756905673624319729', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '4205438746002589111', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '204849530930208960', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '3482944224379652843', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '2123689132466331410', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '6150444453316813936', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '2810956382376737966', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '7164199537578897638', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCN73l_AFEObhocvZsJa2Yxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXNENXVfQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYSEZfdmZOei1NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFDd19DQnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZs2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgUhLADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=2b9ed1e2e7f27fea52cbdc64cb700195bbd14d75', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQne-wVeAAAAABHmcGiZhVlsYxne-wVeAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=8ba7f141449cb45f8b6e12361a62d8d68aa9c812&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418671, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 30, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCN73l_AFEObhocvZsJa2Yxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFzRDV1X0FpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWEhGX3ZmTnotTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhQ3dfQ0J3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=527640949733fba32740156d743d421eb1fe2863' + } + } + }] + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '8404712946290777461', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEPW6p5bQvOLRdBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIWp6MkdiZ2lta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQ0RhTlBDYk9NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFOUS0yRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56TXpRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE18LYuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASSxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABldnDYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgUiLADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ed84428f432d6e743bcad6f7862aed957bece82b', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABF13ckC5YmjdBne-wVeAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=7024b063fcacac27e184ed097ad5878c4dd4dc1d&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417951, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 33, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEPW6p5bQvOLRdBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFqejJHYmdpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkNEYU5QQ2JPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhTlEtMkY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNXwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wn0lGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpwxTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=aefe9625d8e866e048a156abdf26d7c626e6a398' + } + } + }] + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '4063389973481762703', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEI_fjorv9IOyOBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIV96eHRIQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFSVExWM2x4c2VJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFEZy1VQ1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAExd2fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=2fb33b5204f9b75c58d89487725a9d55139f9ff4', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABGPr0Pxpg9kOBne-wVeAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=f9ec8d0b81c1cf4eefc58a7990f4a0a78440725f&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417669, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 4, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-CKB-BAAAAwDWAAUBCN73l_AFEI_fjorv9IOyOBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjSuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc0NTA0NjIpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIV96eHRIQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFSVExWM2x4c2VJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFEZy1VQ1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNXwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wn0lGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAExd2fR4gFAZgFAKAF______8BBRQBwAUAyQVpwxTwP9IFCQkJDHgAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=6b79542e3cee0319d8cb83d1daf127c3aeea9b28' + } + } + }] + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '5097385192927446024', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '201bba5bb8827', + 'tag_id': 15394006, + 'auction_id': '2612757136292876686', + 'nobid': true, + 'ad_profile_id': 1182765 + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_2.js new file mode 100644 index 00000000000..ea77d211826 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_2.js @@ -0,0 +1,289 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '285a2f41615348', + 'tag_id': 15394006, + 'auction_id': '2837696487158070058', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCNSDmPAFEKr2uMu5veGwJxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIV9EemhKUWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTbnRDdFVIdU9BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFOdzh1Rnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDtLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAAAU3DQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=3414eb9e83df14945d2dbfb00e17fb3f2bad2e33', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnUAQZeAAAAABEqO26Z64VhJxnUAQZeAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=e5a720a9884e1df845be9c33658ab69f4c56981e&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417951, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 33, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCNSDmPAFEKr2uMu5veGwJxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFfRHpoSlFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU250Q3RVSHVPQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhTnc4dUZ3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBN_fn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=99418325b8f5ec79e22c1a9aedd73f03de616c2d' + } + } + }] + }, { + 'uuid': '285a2f41615348', + 'tag_id': 15394006, + 'auction_id': '8688113570839045503', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCNSDmPAFEP_K8rCtqJjJeBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIUN6d3Rud2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWUzRZeVVvR09JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFKQTlsRUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDXLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGBSEsAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=2e7c9d18300402e2e183667711728f7743b70a2b', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnUAQZeAAAAABF_pRzWQmGSeBnUAQZeAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=febf12010c66ac7247f571f03c33175ca9036b32&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418948, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 1, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCNSDmPAFEP_K8rCtqJjJeBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFDend0bndpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVlM0WXlVb0dPSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhSkE5bEVBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBMTnn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=92aa9e9c89384c435ab9c7fa62b963d8fc087ef7' + } + } + }] + }, { + 'uuid': '285a2f41615348', + 'tag_id': 15394006, + 'auction_id': '4162295099171231907', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCNSDmPAFEKOxzaPwqtzhORiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIWREMGtXZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhSFRjUzNjWS1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFEUTg2Q0E2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDXLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=95047e919846faea401c778106fb33dae0c95b02', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnUAQZeAAAAABGjWHMEV3HDORnUAQZeAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=50350aadc603f4bb6c59888515d60e9182da0eb8&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418671, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 30, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCNSDmPAFEKOxzaPwqtzhORiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFkRDBrV2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYUhUY1MzY1ktVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhRFE4NkNBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=82c42e6aa09e7c842254552ae524791fa3693bbb' + } + } + }] + }, { + 'uuid': '285a2f41615348', + 'tag_id': 15394006, + 'auction_id': '1076114531988487576', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCNSDmPAFEJj7vIbyjsj3Dhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIVRqMWVUZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZOUNHX2M3MHRvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0BBRHdQdy4umgKJASFFQThNQzo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TTFRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE18O0uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASrxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQA8ATF3Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAAAABTcNAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=c49afba7ca4b5193f7da37b17e1fbfbee2328f61', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnUAQZeAAAAABGYPc8gdyDvDhnUAQZeAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=47618eb9096567900e84fd1c6aff09d753b2fe91&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417669, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 4, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-CKB-BAAAAwDWAAUBCNSDmPAFEJj7vIbyjsj3Dhiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc0NTE5ODgpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIVRqMWVUZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZOUNHX2M3MHRvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0BBRHdQdy4umgKJASFFQThNQzo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TTFRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE1fC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCfSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASrxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQA8ATF3Z9HiAUBmAUAoAX______wEFFAHABQDJBWnDFPA_0gUJCQkMeAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=72d1ec3db5baaa29c1b0e5f07c012db606675fe5' + } + } + }] + }, { + 'uuid': '285a2f41615348', + 'tag_id': 15394006, + 'auction_id': '7495588537924508785', + 'nobid': true, + 'ad_profile_id': 1182765 + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_1.js new file mode 100644 index 00000000000..0c58bd6fb3e --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_1.js @@ -0,0 +1,606 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 15, + 'maxduration': 15 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '4424969993715088689', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFELH6mcm82Km0PRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIWhUNEwzZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjek5XT196NC1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFTZy1SR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBNLsn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=3d8c006f4f85ecffd49c500554c3852b9079ff2b', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABExfSbJw6ZoPRlNxwleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=e2c6cedf67a96613ea8851673ebcfdd25a19435c&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFELH6mcm82Km0PRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFoVDRMM2dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY3pOV09fejQtVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhU2ctUkd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHgAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=de23f822f483b6e85615d4297d872262310c240d' + } + } + }] + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '2013100091803497646', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '2659371493620557151', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEN_KtpiJif_zJBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIWR6eUJxQWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWSHZpWGF0Q09zXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASEtQTVuX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBIvhn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=eafba287adec58427d1679f43a84ebb19223c4e7', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABFfpQ2TSPznJBlNxwleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=b335b2c79378c1699d54cf9ffe097958bd989a0b&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418123, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 12, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEN_KtpiJif_zJBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFkenlCcUFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVkh2aVhhdENPc18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhLUE1bl9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHgAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=66b9e769da1e1d68b202605fc178fc172046e9c5' + } + } + }] + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '5424637592449788792', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '3470330348822422583', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '4415549097692431196', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '1628359298176905427', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '1949183409076770477', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '4707958683377993236', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '2499032734231846767', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '1295788165766409083', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEPvWpeWKj-T9ERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCITR6eVM5d2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFlS0tONGIwQS00XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzkxRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBMTnn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=3cb170cdf53cd6a6bfec0676659daeb6170895e3', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABF7a6mseJD7ERlNxwleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=45f5cce314725120ec769afaacbb7aa92d32e674&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418948, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 1, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEPvWpeWKj-T9ERiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE0enlTOXdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZUtLTjRiMEEtNF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc5MUZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7w7UlGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwP9AG9S_aBhYKEACJABUBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=5c9f03b9c5c6cc2bf070d8cdc6c9af4b06595879' + } + } + }] + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '702761892273189154', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEKLi_7T7xq3gCRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4NDg2Nh8A8P2SArkCITdUeVNDd2lva184UEVQYmpuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFHSTh5N21BQUFzUU1FQmlQTXU1Z0FBTEVESkFYQTM4QzJIcnVFXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHFKUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFaQThESlE2PQEkblBGYklBUW9BRBVIVHNRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBPbjn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBf0F-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=f459a78a1b20c9643b90d7491f22593d79cff253', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABEi8Z-2N7bACRlNxwleAAAAACD2459HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1j9BWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgB9uOfR7ABAQ..&s=83289d261bced5258930a1ce2464260a96565241&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418486, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 14.000010, + 'cpm_publisher_currency': 14.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 30, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEKLi_7T7xq3gCRiq5MnUovf28WEqNgmOWItPAQAsQBGOWItPAQAsQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ9uOfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODQ4NiwgMTUZH_D9kgK5AiE3VHlTQ3dpb2tfOFBFUGJqbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRR0k4eTdtQUFBc1FNRUJpUE11NWdBQUxFREpBWEEzOEMySHJ1RV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RxSlBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhWkE4REpRNj0BJG5QRmJJQVFvQUQVSFRzUURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7w7UlGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8AT2459HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF_QX6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwP9AG9S_aBhYKEACJABUBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=16a432c0a05db78fa40fefc7967796ff2a2e8444' + } + } + }] + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '8192047453391406704', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEPCMp9SW-P_XcRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXhUdGdYZ2lHa184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFSR0FWSjZORXVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFKUThlRDo9ASRuUEZiSUFRb0FEFUhUcVFEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=8bf90e0756a9265ab6ac029e883e14803447a7fb', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABFwxolqwf-vcRlNxwleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=cf9ea0df7655a5c6150a527399cb2852c61ec14a&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417951, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 13.000010, + 'cpm_publisher_currency': 13.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 33, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEPCMp9SW-P_XcRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF4VHRnWGdpR2tfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBUkdBVko2TkV1TV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhSlE4ZUQ6PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGNIIgFAZgFAKAF_xEBFAHABQDJBWm-FPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=cefb5f476892ed335cd8b0fc20fabf7650b1d2e3' + } + } + }] + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '9041697983972949142', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEJb5yqiVjaS9fRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIURUMkpEd2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFYeHdUOEhkUmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFJZzhjRGc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBMXdn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBcLyF_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=308ea3c3363b379ef62dbb6c7a91d1d91d9ee47a', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABGWvBJVaZB6fRlNxwleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=70a33aa1a57d812d9da5c321e898197836ed16f8&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417669, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 4, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5CKB5BAAAAwDWAAUBCM2Op_AFEJb5yqiVjaS9fRiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXiVuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTkxNDkpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIURUMkpEd2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFYeHdUOEhkUmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFJZzhjRGc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYAAGHxKPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ee15793b41a9d22ffad9bd46878a47821d6044fa' + } + } + }] + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '356000177781223639', + 'nobid': true, + 'ad_profile_id': 1182765 + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_2.js new file mode 100644 index 00000000000..38331688a9b --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_2.js @@ -0,0 +1,288 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'minduration': 30, + 'maxduration': 30 + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '198494455120718841', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEPnX6_r7tMzgAhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXpUMDRwQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhejg2NVNoMGVJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKQTkzRFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCADgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=645b6e0a37eb3a315bc3208365bd4fc03e1ecd18', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABH561q_pzHBAhlNxwleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=35a21bf0bef1ca2c138e37a2e025ad523b5a1db2&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418671, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 30, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEPnX6_r7tMzgAhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiF6VDA0cEFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYXo4NjVTaDBlSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNEQUR3UHcuLpoCiQEhSkE5M0RRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0N9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHQAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYJJCjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=cf3130989b2b4fe5271240d65055b85d1192b78a' + } + } + }] + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '998265386177420565', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEJW6sbXGoqPtDRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIVdqM1Jid2lHa184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFmcXpCNjduMU9rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0BBRHdQdy4umgKJASFLZzlMRDo9ASRuUEZiSUFRb0FEFUhUcVFEb0pVMGxPTXpvME56UTNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDfaBAIIAOAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=33f01ddfb15bc84d7bf134a168aeb9d9de76fa57', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABEVXaxmFI3aDRlNxwleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=023640de7c18a0d0e80b2456144b89a351455cda&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417951, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 13.000010, + 'cpm_publisher_currency': 13.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 33, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEJW6sbXGoqPtDRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFXajNSYndpR2tfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBZnF6QjY3bjFPa18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNAQUR3UHcuLpoCiQEhS2c5TEQ6PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBGGNIIgFAZgFAKAF_xEBFAHABQDJBWm-FPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=515ab42a7fdcad8fcf34e4fb98b1e076a75006a9' + } + } + }] + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '8884527464400177295', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEI-RmcaB1Yumexiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCITVqcmtHUWlta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYb0paejlaR09NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0BBRHdQdy4umgKJASFPdy1pRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UTNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDfaBAIIAOAEAPAExOefR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHQAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYJJCjwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=dc7d874e52ac39980ec1070a7769632be56a2f00', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABGPSMYYqC5MexlNxwleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=9fd739e9f0a6054296f9bb5168c49a89a425795c&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418948, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 1, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEI-RmcaB1Yumexiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE1anJrR1FpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWG9KWno5WkdPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNAQUR3UHcuLpoCiQEhT3ctaUY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkAFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=1f8ea8f07f781fe149beb0d65dd25ad725a12f3b' + } + } + }] + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '1279521442385130931', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFELPr8f6Pv_HgERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIW9EeDJEQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFkb01fcFZkVGVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKdzlKRHc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCADgBADwBMXdn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBcLyF_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=4b14660ae659b3d301ec6c40f0f096bb88db145b', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABGzddz_-MXBERlNxwleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=5f277bcab624f05c9d3a3a9c111961f3f33ccca2&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417669, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 4, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5CKB5BAAAAwDWAAUBCM2Op_AFELPr8f6Pv_HgERiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjFuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTkxNDkpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIW9EeDJEQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFkb01fcFZkVGVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKdzlKRHc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYAAGHxKPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=7bb7b75e4769a1260eaed2c79752ee542b4d28ce' + } + } + }] + }, { + 'uuid': '25593f19ac7ed2', + 'tag_id': 15394006, + 'auction_id': '7664937561033023835', + 'nobid': true, + 'ad_profile_id': 1182765 + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_1.js new file mode 100644 index 00000000000..ee1a19d21b2 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_1.js @@ -0,0 +1,852 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '6316075342634007031', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPfztqL2oc3TVxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIV96eWNLZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZYkYwSW1fZGU0XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASE5dzR0Xzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=bb81a081c756fd493253bf765c06ff46888f009a', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABH3uU1kDzWnVxk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=a3da30186f69a5ce2edcfc14fa3a31b92ee70060&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418123, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 12, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPfztqL2oc3TVxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFfenljS2dpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWWJGMEltX2RlNF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhOXc0dF86PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=62b9db151b3739399e0970c74fafc4bb61486510' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '8259815099516488747', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEKuY2qihwrDQchiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIW1UeUFCd2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYNml4eGFGdE8wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=8a55db8e788616ef057647b49c0560296fdacb65', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABErjBYVEsKgchk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=75d46be63f76fd4062f354a56c692855da366148&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418948, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 1, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEKuY2qihwrDQchiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFtVHlBQndpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWDZpeHhhRnRPMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=59e0ab1f626c2e4dc5c4f6e6837b77559cf502b4' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '7960926407704980889', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEJnboLK5jLm9bhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIUZEeFl4QWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhSUpVQVhXMC1JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTQThFR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=8d00bc7576c3cc19fe8b3fb4aa42966583741dfa', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGZLUiWY-R6bhk3yQleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=c813392cbb81d43466d5d949b9bebc2305e6fe7d&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417951, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 33, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEJnboLK5jLm9bhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFGRHhZeEFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYUlKVUFYVzAtSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU0E4RUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=284760a6e2d4f226b639d29237e9c1aa25ca49a9' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '7561862402601574638', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEO7By9umucj4aBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCITREcWpId2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTSVA1dzg5RGVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=917e8af2ed1c82091f487b6abd78de47b99e9e46', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABHu4HJryiHxaBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=ff73768bfb14e9ae603064fc91e95b60c8d872e2&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEO7By9umucj4aBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiE0RHFqSHdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU0lQNXc4OURlUV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=84c66b632a2930d28092e00985ee154ba2e97288' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '6577796711489765634', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEIKC0sii6MGkWxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIVBUem53UWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFlaE5hMWl1Y3V3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASE5dzR0X2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ea4a54786a8f3cf5177b3372ce97682da060c358', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABECgRQpQgdJWxk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=778fbf3014328ec0b01d6ebd7b306be32cf79950&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418123, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 12, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEIKC0sii6MGkWxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFQVHpud1FpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZWhOYTFpdWN1d18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhOXc0dF9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=28a3b583912b95528519f63a75c0fe2d06064e7b' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '2418275491761094586', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELr_z7v0l9zHIRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUF6MUJSZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVNUE2dXpUVy1ZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTUTlYR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=c563626304ebb31fd6f1644cc2d4098133dec096', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABG6_3NHv3CPIRk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=88c9fbb2b9dc273865a5f9238543a29224908b26&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELr_z7v0l9zHIRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFBejFCUmdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVTVBNnV6VFctWV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU1E5WEd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e76aeb8daad477f4428631fc89d277d4a4646ded' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '5990197965284733361', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELHjwfj9qd2QUxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIURUeDF3d2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFmWXBYSEoxUGVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e443347514ff5f6a52a2811f591f9a346061a756', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGxcRDfT3UhUxk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=50348eb78116f7d35ca5ac6f6fa4c5548a6ceffc&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELHjwfj9qd2QUxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFEVHgxd3dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZllwWEhKMVBlTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a24f331ff55f96c5afe5134762f8d8e230b6287c' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '4399290132982250349', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEO32psKU4tqGPRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCITN6dDlwd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRWlZqbkpncmV3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0d9b0a06992ff427d281fae8d8b18d4e6838b944', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABFtu0lIEWsNPRk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=52a446d84f5e9a2baa068760c4406f4a567a911a&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEO32psKU4tqGPRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiEzenQ5cHdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUVpWam5KZ3Jld18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e6ae592b5fc3de0053b5acd46294b83549aa00c8' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '8677372908685012092', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPzYku74lY62eBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIVVEeGp5d2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVN29abmh2c09RXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASE5dzR0X2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=522b764f2276ce75053a55a0198b79fb8d1d39d5', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABF8rMSNrzhseBk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=02b75d0ecc71c7897b9590be5e50b094158c8097&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418123, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 12, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPzYku74lY62eBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFVRHhqeXdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVTdvWm5odnNPUV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhOXc0dF9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0ae5558a7b0cc87eaa0c6811522629963b41bac5' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '617065604518434488', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELitu4PevJDICBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUFqMVNSZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaUzdZYTg5Ny13XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTUTlYR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9HYBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAAAAAAAAAAAAAAAAAAAAEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f59bdb7b0f7020f75c6019f23686915b72d61779', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABG41m7g5UGQCBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=912a721db8e85d4d64a8869d7cf9b56cd0c24907&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELitu4PevJDICBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFBajFTUmdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWlM3WWE4OTctd18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU1E5WEd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBGAHABQDJBQAFARTwP9IFCQkFC3wAAADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgEhMAAA8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=9b4372ae0674305d9cd7152959910d1fa7d4daec' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '8957511111704921777', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELGNpebanN6nfBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXVqdHppQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFUM1dNOVpkQU9JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFIZzhRRDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBK_ln0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAaakNAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a8817d9dc3326ba1b59fe308f126ddaca5710a9c', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABGxRsms5XhPfBk3yQleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=a0ac94e902cbc609881fa9f39537bbc67ba046e7&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418671, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 30, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELGNpebanN6nfBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiF1anR6aUFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVDNXTTlaZEFPSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhSGc4UUQ6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=75b3ad3e867323196da165cd655b3ae51c8b44d0' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '2680240375770812721', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELGi6rO9jYiZJRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIWd6eTMtZ2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYcFdVTk9rai1jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f8458c6a48fed591c269169a9744aba11cb90285', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABExkXrWayAyJRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=e2dbd082b353a37db9f632efc2532913a0c48166&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418948, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 1, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELGi6rO9jYiZJRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFnenkzLWdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWHBXVU5Pa2otY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=5475ac640321ae51a06b5c05ac62519e97e90114' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '8439286287321689724', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEPzciY2kxZePdRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIU1UeWZ6d2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWalR1QThjek9FXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=73e760427d2aec3d47824994cf35c35f1eeddcf8', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABF8bqJBKl4edRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=dac1e836a6f2c4dc036c50d0b3128dfefb34915d&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418948, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 1, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEPzciY2kxZePdRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFNVHlmendpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVmpUdUE4Y3pPRV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=6c1fb35564d2ffd08fb4c5b290aadd6e1e3d83ec' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '5519278898732145414', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEIa29Pmn3ZrMTBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCITFEc0hwUWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkQUZ3YVliRWVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTQThFR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=d01f411e7cc9126e912daca85136b2ca6f99a347', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABEGGz1_6mqYTBk3yQleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=81115280cee86ae0bc259627410fa5dbbc178646&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417951, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 33, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEIa29Pmn3ZrMTBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiExRHNIcFFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZEFGd2FZYkVlTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU0E4RUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=90f21feeb2c798cd77b3cadbc961240238825f0d' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '6754624236211478320', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELC-hPXI3s_eXRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIVJqc0hVUWlta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaRjJPd05MVnVvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=34811f7e5c917550619274f5b75a0cd214119812', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABEwH6GO9D69XRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=d811faa48963b18d33c0a1f9d1e64ff97640a415&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418948, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 1, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELC-hPXI3s_eXRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFSanNIVVFpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkYyT3dOTFZ1b18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=c0a0a2d65dd091bd2ed81f95da1a9f7ff16ad70e' + } + } + }] + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_2.js new file mode 100644 index 00000000000..ce8bad3e9d7 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_2.js @@ -0,0 +1,312 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '4631210661889362034', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPKQq-_0sdeiQBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXF6eU1HUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVQk5fYTFxbHU0XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0dae5294ed5bb48b7d3a156e5e587a26da27c7e1', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABFyyOpNj11FQBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=9085e4dbb4849b0e6d3714d84a2754bbab578e16&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPKQq-_0sdeiQBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFxenlNR1FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVUJOX2ExcWx1NF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=aa5533d04e16ee398f8028ab3af03a48d7d8cc17' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '714778825826946473', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEKmbi7Ph8dn1CRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIU56dmJOZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRbjlXUzRmY09jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASEtUTZrXzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCADgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=8917b1722eed5b6d85c6d5a01eea7862089bee32', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGpzWIWjmfrCRk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=9ec7e7de16b948b60d74b47f1917faf5d3b6dbf0&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418123, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 12, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEKmbi7Ph8dn1CRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFOenZiTmdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUW45V1M0ZmNPY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhLVE2a186PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8N5JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgAAYfQo8D_QBvUv2gYWChABDy4BAFAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=8198652a5ee16abf4595ab1bfc6b051f81f0579d' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '231404788116786844', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEJydmpjcrYebAxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUVqMFlVZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhLXFPTExmZ2VrXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=775dfc49086467337dee9a5e8d78b361931c6aaa', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGcjgbDbR02Axk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=914256a92514df787ccb1eae7dea7578d23c8fba&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEJydmpjcrYebAxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFFajBZVWdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYS1xT0xMZmdla18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f624619431372f9a248d0fa0dd8d09c4977bb544' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '7557072342526904599', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEJeS-7GaqIfwaBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIUFqdmVKQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFSY2lLblVqeU9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASFJQS1IRDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0dQFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCADgBADwBK_ln0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAAAAAAAAAAAAAAAAAABAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=552663ed1246fd2a3cc5824164f57d32f18078ee', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABEXyT6mQR3gaBk3yQleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=e1c80e622aa60bf7683413f4371b0055d0d16f47&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418671, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 30, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEJeS-7GaqIfwaBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFBanZlSkFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUmNpS25VanlPVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhSUEtSEQ6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEYAcAFAMkFAAUBFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=ccf266d1b02551a2ad0af0871d4af43e4aee4bba' + } + } + }] + }, { + 'uuid': '2c52d7d1f2f703', + 'tag_id': 15394006, + 'auction_id': '5093465143102876632', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFENjX7JP78efXRhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIUJUeXRwUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYamVBMVdNcXUwXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASEtUTZrX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=6651c1436b699842aabb3ae53d96d07caf5b4938', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABHYK3uyj5-vRhk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=f62098bf5037b22ca4e5583289a1527fdfa87e43&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418123, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 12, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFENjX7JP78efXRhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFCVHl0cFFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWGplQTFXTXF1MF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhLVE2a19nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAGH0KPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=4b43aaab766ee7d2e4c900ec32cb3c8b7ccef1d0' + } + } + }] + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_1.js new file mode 100644 index 00000000000..fc2ad82fe5f --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_1.js @@ -0,0 +1,620 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '8905202273088829598', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEJ7x1-ORyejKexiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIWlEeE84Z2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhV09TRWpDY09NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0BBRHdQdy4umgKJASFQZzlaRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56YzNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAZWQU8D_SBQkJBQt4AAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgEgMAAA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=21195aa3e27f8eb88ba43d5da32e6b78c2aa03f8', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABGe-HUcSaKVexm1ywleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=3c05b8509dd5c7c4459886f4c69fdd9cd07caa66&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418948, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 1, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEJ7x1-ORyejKexiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFpRHhPOGdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYVdPU0VqQ2NPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNAQUR3UHcuLpoCiQEhUGc5WkY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXObNgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYFISwA8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=203ae79160a460b18f20165e5de53bb1f45e4933' + } + } + }] + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '2428831247136753876', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFENSR0sfppLzaIRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXRUeV9FQWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTek5nNXJvQi0wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFVUThpSFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=af2d5096aa4f934e84b59ad16cd18dfe5b9bbc77', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHUiPSYJvG0IRm1ywleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=440a389c7f556dac70c650bb1e593a10cbcdf2af&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417951, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 33, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFENSR0sfppLzaIRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF0VHlfRUFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU3pOZzVyb0ItMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhVVE4aUhRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9b00ed17c420f328d63b72519d2d578c5921d0d7' + } + } + }] + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '1625697369389546128', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEJD1gLbO5OjHFhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIXVqeHMtUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhcDVwSkxuSXVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFBQTlhQUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0e70f535a95c82238d685147f41e0bd2f86631c0', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGQOsDmJKOPFhm1ywleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=144214d77cc4ced0893c9fe64132ad01c429c43c&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418123, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 12, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEJD1gLbO5OjHFhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiF1anhzLVFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYXA1cEpMbkl1VV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhQUE5YUFBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f6bc475b66c167036dcb9f10c7c5f176124829a6' + } + } + }] + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '5434800203981031918', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEO6TivzZv5K2Sxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIW5Ud3I5QWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFXVVcwV1Y1LU9JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFKdzh1RGc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=c3ba85f0eb0293896e02066385f82b4450af2cfb', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABHuiYKf_UlsSxm1ywleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=9eb2d880fa9b524a6a0807eef0c65b7b1393f48a&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418671, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 30, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEO6TivzZv5K2Sxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFuVHdyOUFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBV1VXMFdWNS1PSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhSnc4dURnNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASv5Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=17038c2671b58d2fd6ea98dd3f3e1166ee664dd0' + } + } + }] + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '8071104954749355970', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEMKP7OWZ5pSBcBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXBUeEJEQWlsa184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFRbWtta1pXNGVZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFSZ19sR1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=005579c0ff91586a887354409f637a63a1d69031', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHCB7ucMVMCcBm1ywleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=edbfae73be0f41d672298d5c3ec9dd28a5307233&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6CKB6BAAAAwDWAAUBCLWXp_AFEMKP7OWZ5pSBcBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDS7J9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc3MDAyNzcpO3VmKCdyJywgMTQ5NDE5NjAyLCAxNRkf8P2SArkCIXBUeEJEQWlsa184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFRbWtta1pXNGVZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFSZ19sR1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0ac18b64a6c0d58a114085d8b565b4c98de56448' + } + } + }] + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '6893555531330982923', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEIuopuO2h7XVXxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIVFqd1R0Z2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFZS1J6NEZQV2V3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASEzUTZnOHc2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF8owB-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f9ddb1066825dfc556d108168ffc0d16cf567ae8', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABELlGlsO9SqXxm1ywleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=db3a0d52f97edd94aa7e4213c437d8e4a5bd16ce&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149414188, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 13.000010, + 'cpm_publisher_currency': 13.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 32, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 29000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEIuopuO2h7XVXxiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFRandUdGdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBWUtSejRGUFdld18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhM1E2Zzh3Nj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASswp9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=917c8192c7dc7e382c0bb7296ab0df261e69f572' + } + } + }] + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '5615186251901272031', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '6647218197537074925', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '4707051182303115567', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '4831890668873532085', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '7151522995196673389', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '4077353832159380438', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFENaHwKvS9urKOBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIWJqeHo1UWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZd1VQNVZMNi1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFLZzhBRUE2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAExd2fR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e96d121a0a7d49e05c1d2b4fab2da60d0b544287', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHWA3AltauVOBm1ywleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=8d90e3ce42fe47da19cb85f8fb2d78822c590464&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417669, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 4, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6CKB6BAAAAwDWAAUBCLWXp_AFENaHwKvS9urKOBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc3MDAyNzcpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIWJqeHo1UWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZd1VQNVZMNi1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFLZzhBRUE2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=db30796cc71c3bee3aa8fc2890c75ad7186f9d73' + } + } + }] + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '2099457773367093540', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '7214207858308840891', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '4564285281969145467', + 'nobid': true, + 'ad_profile_id': 1182765 + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_2.js new file mode 100644 index 00000000000..751abfa14e4 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_2.js @@ -0,0 +1,312 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '2704229116537156015', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEK_j3NPcwdbDJRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXpUczJvQWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFURVBwVy1oVE9ZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0BBRHdQdy4umgKJASFVQV9qSDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UTVRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAZWQU8D_SBQkJBQt8AAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYBITAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=64565aadf65d370e9730e9ce82c93c9bd2fcfc14', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGvMXfKDVqHJRm1ywleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=3b1f10f67b3253e38770fff694edbe6052795602&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417951, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 33, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEK_j3NPcwdbDJRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF6VHMyb0FpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVEVQcFctaFRPWV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNAQUR3UHcuLpoCiQEhVUFfakg6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ52gQCCAHgBADwBN_fn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=5316c3262f36e4d89735b1ba252c64651a84f479' + } + } + }] + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '7987581685263122854', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEKaDmaSQ5-Xsbhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIU16MXpZd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYLVkxZU5tY3VRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFVUTgySFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=17f2a3f5e78c188cc6ca23e677ced305198a8a05', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGmQYYEOZfZbhm1ywleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=28e8f96efdfb9bc1e33e4d087ff5ed992e4692b1&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEKaDmaSQ5-Xsbhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFNejF6WXdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWC1ZMWVObWN1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhVVE4MkhRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=89d4586d9597cd2f9a4a918d1e6985aee45ade01' + } + } + }] + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '653115326806257319', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEKfdmd3enZWICRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCITlEd0hNZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjTnlESmJxeS13XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFKZ192RFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=1928a9daadbd431792adace7620880dda961eefb', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABGnbqbr7VQQCRm1ywleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=7617d08e0c16fe1dea8ec80cd6bf73ec0a736b41&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418671, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 30, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEKfdmd3enZWICRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiE5RHdITWdpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY055REpicXktd18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhSmdfdkRRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ASv5Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0d1d3f42fa225995a2f57ab84877dce3d24e9901' + } + } + }] + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '866435845408148233', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEImW35H52YyDDBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIXJEenNfZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjMmZTZ1BpMi1BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFfdzRiQUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=83f65f38b4fd56344b3aceb70df7bac1b9b5f229', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABEJyzeSzzIGDBm1ywleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=9130c13cca7a1d3eb05c2b96585ccfdc2faa6844&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418123, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 12, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEImW35H52YyDDBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFyRHpzX2dpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYzJmU2dQaTItQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhX3c0YkFBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=1f88d8b0a467d528291f90a54fd810b8fdac4488' + } + } + }] + }, { + 'uuid': '2022b6b1fcf477', + 'tag_id': 15394006, + 'auction_id': '1540903203561034860', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEOyokYzL6ZixFRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIXdUekVId2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaeE00NUxjRXVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFQUThhRmc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a4de0e4084ce04a5cb2d347c07fde867aa9ff5c1', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABFsVISxTGNiFRm1ywleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=cf600d825cec85f83c06119e5e383f8548b469a2&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418948, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 1, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEOyokYzL6ZixFRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiF3VHpFSHdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWnhNNDVMY0V1TV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhUFE4YUZnNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=17c466ea45d5d4beff02aa2b0eb87bc6c4d5aff3' + } + } + }] + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_1.js new file mode 100644 index 00000000000..4f11a203724 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_1.js @@ -0,0 +1,418 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }], + 'user': {}, + 'brand_category_uniqueness': true + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '2678252910506723691', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '3548675574061430850', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '8693167356543642173', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '7686428711280367086', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '3784359541475413084', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '7233136875958651734', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '159775901183771330', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '6558726890185052779', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '6624810255570939818', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '528384387675374412', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '2535665225687089273', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '2166694611986638079', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '9137369006412413609', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '3524702228053475248', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2d4806af582cf6', + 'tag_id': 15394006, + 'auction_id': '57990683038266307', + 'nobid': true, + 'ad_profile_id': 1182765 + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_2.js new file mode 100644 index 00000000000..b69612d86b9 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_2.js @@ -0,0 +1,284 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }], + 'user': {}, + 'brand_category_uniqueness': true + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '245a09bd675168', + 'tag_id': 15394006, + 'auction_id': '3810681093956255668', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKVCKAVBAAAAwDWAAUBCKD4kfAFELT_vOy9yJDxNBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUxEMWZkUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZVS10N09mcU9BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFLdy1SRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=66ba37441db5e28c87ee52e729333fd9324333f9', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQkgfAReAAAAABG0P4_dQ0LiNBkgfAReAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=6931bf3569012d0e1f02cb5a2e88dfcafe00dba9&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLxCOhxBAAAAwDWAAUBCKD4kfAFELT_vOy9yJDxNBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFMRDFmZFFpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWVUtdDdPZnFPQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhS3ctUkZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ea46ec90cf31744c7be2af5d5f239ab4eed29098' + } + } + }] + }, { + 'uuid': '245a09bd675168', + 'tag_id': 15394006, + 'auction_id': '7325897349627488405', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKUCKAUBAAAAwDWAAUBCKD4kfAFEJXRloy0mrTVZRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXJUeTNJd2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVSzAtQ2hwcWRrXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFBQTlLQlE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=271fd8a0ccdfc36e320f707164588ed1b33e9861', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQkgfAReAAAAABGVqIVB09CqZRkgfAReAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=115ac2b842cf3efeb5acaeda94ddf05632c345ca&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418671, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 30, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLwCOhwBAAAAwDWAAUBCKD4kfAFEJXRloy0mrTVZRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFyVHkzSXdpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVUswLUNocHFka18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhQUE5S0JRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=f73e060b15a6bbcca65f918a296f155b78c74eca' + } + } + }] + }, { + 'uuid': '245a09bd675168', + 'tag_id': 15394006, + 'auction_id': '968802322305726102', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKVCKAVBAAAAwDWAAUBCKD4kfAFEJbt7LTEkvi4DRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIUtUejN5d2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFTT3dTTWVaYnVJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASF0ZzY4Nmc2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULfAAAANgFAeAFAfAF8owB-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e35825a106304da78477df1575f981395be21d5f', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQkgfAReAAAAABGWNptGlOBxDRkgfAReAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=677bedd5b2d21fdc3f940cbae279261c8f84c2e7&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149414188, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 13.000010, + 'cpm_publisher_currency': 13.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 32, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 29000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLxCOhxBAAAAwDWAAUBCKD4kfAFEJbt7LTEkvi4DRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFLVHozeXdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBU093U01lWmJ1SV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhdGc2ODZnNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0707b1385afa81517cd338f1516aeccc46fe33e1' + } + } + }] + }, { + 'uuid': '245a09bd675168', + 'tag_id': 15394006, + 'auction_id': '1273216786519070425', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '245a09bd675168', + 'tag_id': 15394006, + 'auction_id': '1769115862397582681', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKUCKAUBAAAAwDWAAUBCKD4kfAFENn63YWPsMrGGBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIXp6djFzd2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZbW5MamdJaXVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFGdzkxRFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULeAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=fb3a15e7ff747fccd750671b763e312d97083c72', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQkgfAReAAAAABFZfbfwgCmNGBkgfAReAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=7f4b8dd7c7dd9faecebac2e9ec6d7ef8da08da16&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418948, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 1, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLwCOhwBAAAAwDWAAUBCKD4kfAFENn63YWPsMrGGBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiF6enYxc3dpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWW1uTGpnSWl1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhRnc5MURRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwsEFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBWm2FPA_0gUJCQkMdAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=3a27c12c33ebaaae43dbce1cafb0bae43b753fa0' + } + } + }] + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_1.js new file mode 100644 index 00000000000..ffb03cc0563 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_1.js @@ -0,0 +1,620 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '1249897353793397796', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEKTIuZTW4KGsERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCITFqdjBlZ2lta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFXU1JOVU1OTk9jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFTUTgtR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e9887c670ae9fcb7eb2a0253037c64c3587f4bcb', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEkZI5iBYdYERnJwgleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=68a5c49da3a6ecf3dfc0835cb3da72b3b2c7b080&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417951, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 33, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEKTIuZTW4KGsERiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiExanYwZWdpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBV1NSTlVNTk5PY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhU1E4LUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9514ae5f8aae1ee9dddd24dce3e812ae76e0e783' + } + } + }] + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '4278372095219023172', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMT65MOLmPWvOxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIUxEeUhqUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQWJScDluWS1FXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASEtQTVuX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=987d4bb0c7611d41b5974ec412469da2241084cd', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABFEPXm4wNRfOxnJwgleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=75aaa9ec84807690ceff60e39fbba6625240f9f3&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418123, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 12, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEMT65MOLmPWvOxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFMRHlIalFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkFiUnA5blktRV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhLUE1bl9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9872a378866ce61fc366ca8c34bdd9302fa41a9b' + } + } + }] + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '8860024420878272196', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFEMSN8Z3LqMj6ehiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIU9EMjhLZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkZExBS3hfN09nXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFIdzlLREE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=1289862cbe265fd9af13d2aab9635e3232421ec1', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnKwgleAAAAABHERryzRCH1ehnJwgleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=0b094204d5c18803149e081bd2bc0077d25ebb14&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418671, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 30, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFEMSN8Z3LqMj6ehiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFPRDI4S2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZGRMQUt4XzdPZ18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhSHc5S0RBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=f35771975371bb250fd6701914534b4f595fcf68' + } + } + }] + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '5236733650551797458', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFENLt5YOosKfWSBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIThUMjJsZ2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkczByb2Ytbk9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzkxRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=e997907677e4e2f9b641d51b522a901b85944899', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnKwgleAAAAABHSdnmAgp2sSBnJwgleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=d70eef0df40cece50465a13d05a2dc11b65eadeb&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418948, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 1, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFENLt5YOosKfWSBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE4VDIybGdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZHMwcm9mLW5PVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc5MUZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_DtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAGn1FQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e8b6716ad3d2fcbdb79976f72d60f8e90ce8f5a6' + } + } + }] + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '4987762881548953446', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '201567478388503336', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEKjm-NzbkYfmAhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXV6NlFDd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkejE5MUdLNk8wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFTZy1SRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=4a887316a3197dfae07c1443a4debc62a2f17fef', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEoM567jRzMAhnJwgleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=eef6278d136f8df4879846840f97933e9d67388a&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEKjm-NzbkYfmAhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiF1ejZRQ3dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZHoxOTFHSzZPMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhU2ctUkc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8JplQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkNVU1RPTREdCEFTVAEL8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAEYYIgiAUBmAUAoAX_EQEUAcAFAMkFabMU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e68b089e4fc94aa7566784ccbff299e50c8bc090' + } + } + }] + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '3876520534914199302', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '4833995299234629234', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '8352235304492782614', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEJaok6aeuMb0cxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIUpUMS1FZ2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFmQ1lIN1I1bmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASExUTY4OFE2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=7081f4ad4ae9837aaff4b4f59abc4ce7f8b02cb6', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEW1MTkwRnpcxnJwgleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=71f281c81d1ae269bde275b84aa955c833ab1dea&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149414188, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 13.000010, + 'cpm_publisher_currency': 13.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 32, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 29000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEJaok6aeuMb0cxiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFKVDEtRWdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBZkNZSDdSNW5lc18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhMVE2ODhRNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=05fc37623521011853ff69d194aa6d692b6c0504' + } + } + }] + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '2318891724556922037', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '5654583906891472332', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMy7oJeqw8e8Thiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIXZ6Ml9mZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFhYzY5MFRlZi1rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFJZzhjRDo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATF3Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=f929565158c7caa5b85e88fa456cdd04d0e4b6d8', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABHMHeiiGh55ThnJwgleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=a93773067b8588465b9c007e19970bd9e08c1b6c&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149417669, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 4, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCKBuBAAAAwDWAAUBCMmFp_AFEMy7oJeqw8e8Thiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjDuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTc5OTMpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIXZ6Ml9mZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFhYzY5MFRlZi1rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFJZzhjRDo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwmmVBQS7YAgDgAq2YSOoCTmh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19wcmljZUdyYW4uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTV9NT0RFTF9MRUFGX05BTUUSAPICHgoaQ1VTVE9NER0IQVNUAQvwkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhgiCIBQGYBQCgBf8RARQBwAUAyQVpsxTwP9IFCQkJDHgAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=a3a24cbf148bb959f539e883af3d118f64e81bc9' + } + } + }] + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '2268711976967571175', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '8379392370800588084', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '6225030428438795793', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '1592368529919250324', + 'nobid': true, + 'ad_profile_id': 1182765 + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_2.js new file mode 100644 index 00000000000..5a716c6e8e9 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_2.js @@ -0,0 +1,283 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 15394006, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'require_asset_url': true, + 'video': { + 'maxduration': 30 + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '6123799897847039642', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFEJqN_JX98Yb-VBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIUN6dzV3Z2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYQm5aNWdRbi1NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFJQS1IREE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=a7e4ff14c60153db90971365f90e514f45875324', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnJwgleAAAAABGaBr_Sjxv8VBnJwgleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=842283d9de78fba7e92fac09f95bb63902a0b54a&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418671, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 30, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFEJqN_JX98Yb-VBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFDenc1d2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWEJuWjVnUW4tTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhSUEtSERBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0fb74d544be103e1440c3ee8f7abc14d2c322d15' + } + } + }] + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '889501690217653627', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEPvKoYSxoomsDBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIWt6eTlHUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRSzgzNzR1VnVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=78ac70aeeae1da43c90efd248fb30a4ee630ffd5', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABF7ZYgQEyVYDBnJwgleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=f21e2a522ddcaf0a67bc7d52f70288fdf7e6f3dd&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149419602, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 24, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEPvKoYSxoomsDBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFrenk5R1FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUUs4Mzc0dVZ1VV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=69611db1024ddb77e0754087ddbeae68a00633a1' + } + } + }] + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '2793012314322059080', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMj-1IPuvLHhJhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIXhqb2ZBZ2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFRQWhlSGt0VHVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASExZzc1OFE2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=243f58d85b09468de2fe485662c950a86b5d90fb', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABFIP3Xg5sXCJhnJwgleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=99dd40ab6ae736c6aa7c96b5319e1723ea581e0d&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149414188, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 13.000010, + 'cpm_publisher_currency': 13.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 32, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 29000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEMj-1IPuvLHhJhiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiF4am9mQWdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBUUFoZUhrdFR1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhMWc3NThRNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=d9a3c817696f263b6e6d81f7251827fa54a47c37' + } + } + }] + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '45194178065897765', + 'nobid': true, + 'ad_profile_id': 1182765 + }, { + 'uuid': '2def02900a6cda', + 'tag_id': 15394006, + 'auction_id': '3805126675549039795', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFELPZ2uvQ0aHnNBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIWNUM1hkZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjbUQzMExTME9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASEtUTZrXzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=bbeaa584bea9afedf6dcab51b1616988441dfa22', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABGzrHYNjYbONBnJwgleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=b7e937b5acc3d8b910f6b08c3a40e04aa10818cd&event_type=1', + 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 149418123, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 15.000010, + 'cpm_publisher_currency': 15.000010, + 'publisher_currency_code': '$', + 'brand_category_id': 12, + 'client_initiated_ad_counting': true, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 15000, + 'playback_methods': ['auto_play_sound_on'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFELPZ2uvQ0aHnNBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFjVDNYZGdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY21EMzBMUzBPVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhLVE2a186PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8JplQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkNVU1RPTREdCEFTVAEL8N5JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgAAYeYo8D_QBvUv2gYWChABDy4BAFAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=279827127eba3204bc3a152b8abaf701260eb494' + } + } + }] + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js b/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js new file mode 100644 index 00000000000..9c4128fc004 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js @@ -0,0 +1,110 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 1, + 'height': 1 + }], + 'ad_types': ['native'], + 'id': 13232392, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'native': { + 'layouts': [{ + 'title': { + 'required': true + }, + 'main_image': { + 'required': true + }, + 'sponsored_by': { + 'required': true + } + }] + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '256e5e4b136d05', + 'tag_id': 13232392, + 'auction_id': '6287559286677633407', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKICKAIBAAAAwDWAAUBCM3FpfEFEP_yg9W7u_mgVxi7_-bKzp3kuD8qNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIjSpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5NzcwNTczKTsBHSxyJywgOTc1MjA0MzQ2HgDw0JICtQIhQWp4NUh3aUgtYndLRUxLV3dDNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUWlOS25CbGdBWUtzR2FBQndBbmlLQVlBQkhvZ0JpZ0dRQVFDWUFRQ2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCb2FZc1BwVDM0VF9aQVFBQUFBQUFBUEFfNEFFQTlRRUFBQUFBbUFJQW9BSUF0UUlBQUFBQXZRSUFBQUFBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQU9IAcSIdWdNSlUwbE9Nem8wT0RRMDRBUDRHWWdFQUpBRUFKZ0VBY0UJXQUBCERKQgUICQEYMkFRQThRUQkNAQEsUGdFQUlnRjdDV3BCERc0UEFfmgKJASFDZy1TX2c2OQEkblBGYklBUW9BRBVkDGtRRG8ykQAQUVBnWlMdTQBVEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCS2h0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTw3i9wYWdlcy9tdWx0aXBsZV9iaWRkZXJzLmh0bWw_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQOMTAzLjc5LjEwMC4xODCoBOZCsgQQCAQQARgAIAAoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODQ02gQCCADgBAHwBLKWwC6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAABDnDYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgEhMAAA8L_QBvUv2gYWChAJERkBUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=8b14b952b73092945ef66436be991786b53f7a68', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'native', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 97520434, + 'media_type_id': 12, + 'media_subtype_id': 65, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 53, + 'client_initiated_ad_counting': true, + 'viewability': { + 'config': '' + }, + 'rtb': { + 'native': { + 'title': 'This is a Prebid Native Creative', + 'sponsored': 'Prebid.org', + 'main_img': { + 'url': 'https://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg', + 'width': 989, + 'height': 742, + 'prevent_crop': false + }, + 'link': { + 'url': 'http://prebid.org/dev-docs/show-multi-format-ads.html', + 'click_trackers': ['https://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQH_5oLrb5UFXu79Z6eyQcT_NYileAAAAAAjpyQBtJAAAbSQAAAIAAAAyC9AFnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAnRbC8wAAAAA./bcr=AAAAAAAA8D8=/cnd=%21Cg-S_giH-bwKELKWwC4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0ODQ0QPgZSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ4NDQ=/bn=89112/'] + }, + 'impression_trackers': ['https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKQCKAQBAAAAwDWAAUBCM3FpfEFEP_yg9W7u_mgVxi7_-bKzp3kuD8qNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIjSpwY47UhA7UhIAlCylsAuWJzxW2AAaM26dXiYuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1Nzk3NzA1NzMpO3VmKCdyJywgOTc1MjA0MzQsIC4eAPDQkgK1AiFBang1SHdpSC1id0tFTEtXd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRaU5LbkJsZ0FZS3NHYUFCd0FuaUtBWUFCSG9nQmlnR1FBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JvYVlzUHBUMzRUX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBT0gBxIh1Z01KVTBsT016bzBPRFEwNEFQNEdZZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BASxQZ0VBSWdGN0NXcEIRFzRQQV-aAokBIUNnLVNfZzY5ASRuUEZiSUFRb0FEFWQMa1FEbzKRABBRUGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gJLaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPDeL3BhZ2VzL211bHRpcGxlX2JpZGRlcnMuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA4xMDMuNzkuMTAwLjE4MKgE5kKyBBAIBBABGAAgACgBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4NDTaBAIIAeAEAfAEspbALogFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAEOcNgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGASEwAADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=2061bd85ce022a41bc16ebb20c193aabbbc07809'], + 'id': 97520434 + } + } + }] + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js b/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js new file mode 100644 index 00000000000..d3c8e8ea376 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js @@ -0,0 +1,175 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 300, + 'height': 250 + }, { + 'width': 300, + 'height': 600 + }], + 'primary_size': { + 'width': 300, + 'height': 250 + }, + 'ad_types': ['banner'], + 'id': 13232392, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true + }, { + 'sizes': [{ + 'width': 1, + 'height': 1 + }], + 'ad_types': ['native'], + 'id': 13232354, + 'allow_smaller_sizes': true, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'native': { + 'layouts': [{ + 'title': { + 'required': true + }, + 'description': { + 'required': true + }, + 'main_image': { + 'required': true + }, + 'sponsored_by': { + 'required': true + }, + 'icon': { + 'required': false + } + }] + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '28ae233df319a1', + 'tag_id': 13232392, + 'auction_id': '6917498423334366136', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLBCKBBBAAAAwDWAAUBCNGcpvEFELjXrYmmhfn_Xxi7_-bKzp3kuD8qNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQn0gQEkQDCI0qcGOO1IQO1ISABQAFic8VtgAGjNunV4AIABAYoBAJIBA1VTRJgBrAKgAfoBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5NzgxNzEzKTt1ZigncicsIDk2ODQ2MDM1LCAxNTc5NzgxNzEzKTuSArUCITZEb2NyZ2lILWJ3S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFpTktuQmxnQVlLc0dhQUJ3R25oaWdBR1lBWWdCWXBBQkFKZ0JBS0FCQWFnQkE3QUJBTGtCODYxcXBBQUFKRURCQWZPdGFxUUFBQ1JBeVFHQ1VBT2x6Q0xkUDlrQkFBQUFBQUFBOERfZ0FRRDFBUUFBQUFDWUFnQ2dBZ0MxQWdBQUFBQzlBZ0FBQUFEZ0FnRG9BZ0Q0QWdDQUF3R1lBd0dvQTRmNXZBcTZBd2xUU1U0ek9qUTNNem5nQV9nWmlBUUFrQVFBbUFRQndRUQFNCQEITWtFCQkBARhEWUJBRHhCAQsNASwtQVFBaUFXREpha0YNE0BBOEQ4LpoCiQEhOEE1YjlRaTI5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME56TTVRUGdaU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EZlQUEuwgI1aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1tdWx0aS1mb3JtYXQtYWRzLmh0bWzYAgDgAq2YSOoCSw1ASHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvBUYocGxlX2JpZGRlcnMFRvBAP3BianNfZGVidWc9dHJ1ZYADAIgDAZADAJgDF6ADAaoDAMADrALIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMNtvBhmAQAogQOMTAzLjc5LjEwMC4xODCoBJ9EsgQSCAQQARisAiD6ASgBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MznaBAIIAOAEAfAE04GXLogFAZgFAKAF______8BAxQBwAUAyQVpiBTwP9IFCQkJDHAAANgFAeAFAfAFAfoFBAgAEACQBgCYBgC4BgDBBgkjKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYB8gYCCACABwGIBwCgBwE.&s=8d42ac30ca2d2a8a63215f5aba2a43bd23af0023', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'banner', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 96846035, + 'media_type_id': 1, + 'media_subtype_id': 1, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 0, + 'client_initiated_ad_counting': true, + 'rtb': { + 'banner': { + 'content': "
", + 'width': 300, + 'height': 250 + }, + 'trackers': [{ + 'impression_urls': ['https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLJCKBJBAAAAwDWAAUBCNGcpvEFELjXrYmmhfn_Xxi7_-bKzp3kuD8qNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIjSpwY47UhA7UhIAlDTgZcuWJzxW2AAaM26dXicuAWAAQGKAQNVU0SSAQEG8FKYAawCoAH6AagBAbABALgBAcABBMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3OTc4MTcxMyk7dWYoJ3InLCA5Njg0NjAzNTYeAPCakgK1AiE2RG9jcmdpSC1id0tFTk9CbHk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRaU5LbkJsZ0FZS3NHYUFCd0duaGlnQUdZQVlnQllwQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRR0NVQU9sekNMZFA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BNGY1dkFxNkF3bFRTVTR6T2pRM016bmdBX2daaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVdESmFrRg0TPEE4RDgumgKJASE4QTViOVE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBOek01UVBnWlNRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBGZUFBLsICNWh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctbXVsdGktZm9ybWF0LWFkcy5odG1s2AIA4AKtmEjqAksNQEh0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLwVGKHBsZV9iaWRkZXJzBUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbbwYZgEAKIEDjEwMy43OS4xMDAuMTgwqASfRLIEEggEEAEYrAIg-gEoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM52gQCCAHgBAHwBNOBly6IBQGYBQCgBf______AQMUAcAFAMkFaZAU8D_SBQkJCQxwAADYBQHgBQHwBQH6BQQIABAAkAYAmAYAuAYAwQYJIyjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=6c6fb8a005b60bc5535b528c16ed74cd66c08dd0'], + 'video_events': {} + }] + } + }] + }, { + 'uuid': '375d249fda4d84', + 'tag_id': 13232354, + 'auction_id': '2793298983265666969', + 'nobid': false, + 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKGCKAGBAAAAwDWAAUBCNGcpvEFEJmPioiD1PLhJhi7_-bKzp3kuD8qNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5NzgxNzEzKTsBHSxyJywgOTc0OTQyMDQ2HgDw0JICtQIhZ2oxVmFnajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWUtzR2FBQndCbmlhQklBQm1BR0lBV0tRQVFDWUFRQ2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCQXNyenVXOVg0RF9aQVFBQUFBQUFBUEFfNEFFQTlRRUFBQUFBbUFJQW9BSUF0UUlBQUFBQXZRSUFBQUFBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQVA4AcSIdWdNSlUwbE9Nem8wTnpNNTRBUDRHWWdFQUpBRUFKZ0VBY0UJXQUBCERKQgUICQEYMkFRQThRUQkNAQEsUGdFQUlnRmd5V3BCERc0UEFfmgKJASF2QS1kUHc2OQEkblBGYklBUW9BRBVkDGtRRG8ykQAQUVBnWlMdTQBVEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCS2h0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRT0DgEvcGFnZXMvbXVsdGlwbGVfYmlkZGVycy5odG1sP3BianNfZGVidWc9dHJ1ZYADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDjEwMy43OS4xMDAuMTgwqASfRLIEDggAEAEYACAAKAAwADgCuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MznaBAIIAOAEAfAEvMm-LogFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYM8gYCCACABwGIBwCgB0E.&s=acd26154fe24e1ce797e3016322901140c18ce65', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'native', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 97494204, + 'media_type_id': 12, + 'media_subtype_id': 65, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 53, + 'client_initiated_ad_counting': true, + 'viewability': { + 'config': '' + }, + 'rtb': { + 'native': { + 'title': 'This is a Prebid Native Creative', + 'desc': 'This is a Prebid Native Creative. There are many like it, but this one is mine.', + 'sponsored': 'Prebid.org', + 'icon': { + 'url': 'https://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png', + 'width': 127, + 'height': 83, + 'prevent_crop': false + }, + 'main_img': { + 'url': 'https://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg', + 'width': 989, + 'height': 742, + 'prevent_crop': false + }, + 'link': { + 'url': 'http://prebid.org/dev-docs/show-native-ads.html', + 'click_trackers': ['https://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQJmHAjGgysMmu79Z6eyQcT9RjileAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAxBbHxgAAAAA./bcr=AAAAAAAA8D8=/cnd=%21vA-dPwj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzM5QPgZSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3Mzk=/bn=89116/'] + }, + 'impression_trackers': ['https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKOCKAOBAAAAwDWAAUBCNGcpvEFEJmPioiD1PLhJhi7_-bKzp3kuD8qNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXicuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1Nzk3ODE3MTMpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPDQkgK1AiFnajFWYWdqOC1Md0tFTHpKdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZS3NHYUFCd0JuaWFCSUFCbUFHSUFXS1FBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JBc3J6dVc5WDREX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOek01NEFQNEdZZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BASxQZ0VBSWdGZ3lXcEIRFzRQQV-aAokBIXZBLWRQdzY5ASRuUEZiSUFRb0FEFWQMa1FEbzKRABBRUGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gJLaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPQOAS9wYWdlcy9tdWx0aXBsZV9iaWRkZXJzLmh0bWw_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQOMTAzLjc5LjEwMC4xODCoBJ9EsgQOCAAQARgAIAAoADAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczOdoEAggB4AQB8AS8yb4uiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8D_QBvUv2gYWChAJERkBUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=2d3f9336af4da684d7733e29f53bbb80bf69a18c'], + 'id': 97494204 + } + } + }] + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/native/index.js b/test/mock-server/expectations/request-response-pairs/native/index.js new file mode 100644 index 00000000000..f9a8b9e3585 --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/native/index.js @@ -0,0 +1,191 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 1, + 'height': 1 + }], + 'ad_types': ['native'], + 'id': 13232354, + 'allow_smaller_sizes': true, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'native': { + 'layouts': [{ + 'title': { + 'required': true + }, + 'main_image': { + 'required': true + }, + 'sponsored_by': { + 'required': true + } + }] + } + }, { + 'sizes': [{ + 'width': 1, + 'height': 1 + }], + 'ad_types': ['native'], + 'id': 13232354, + 'allow_smaller_sizes': true, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'native': { + 'layouts': [{ + 'title': { + 'required': true + }, + 'description': { + 'required': true + }, + 'main_image': { + 'required': true + }, + 'sponsored_by': { + 'required': true + }, + 'icon': { + 'required': false + } + }] + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '2b7ae9fa0e76be', + 'tag_id': 13232354, + 'auction_id': '2566965852006062421', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLhB6DhAwAAAwDWAAUBCNDZme8FENWyhPv4uuzPIxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc1MzgyMjI0KTsBHThyJywgOTc0OTQ0MDMsIDEdHvDQkgKpAiFCenhPTlFqOC1Md0tFSVBMdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JRTDdBTHVfbzFqX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVBQZ0VBSWdGaGlVLpoCiQEhYWdfb0o6LQEkblBGYklBUW9BRBVYDGtRRG8yhQAQUU9ZV1MRWAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCMWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTwvC9wYWdlcy9uYXRpdmUuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATruAKyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQy2gQCCADgBAHwBIPLvi6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQkMeAAA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYJJTTwv8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=54514bb848c51d509dfe3e21af09b77edfe9738e', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'native', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 97494403, + 'media_type_id': 12, + 'media_subtype_id': 65, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 53, + 'client_initiated_ad_counting': true, + 'viewability': { + 'config': '' + }, + 'rtb': { + 'native': { + 'title': 'This is a Prebid Native Creative', + 'sponsored': 'Prebid.org', + 'main_img': { + 'url': 'http://vcdn.adnxs.com/p/creative-image/94/22/cd/0f/9422cd0f-f400-45d3-80f5-2b92629d9257.jpg', + 'width': 3000, + 'height': 2250, + 'prevent_crop': false + }, + 'link': { + 'url': 'http://prebid.org/dev-docs/show-native-ads.html', + 'click_trackers': ['http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQFUZYY_XsZ8jKnKSKrrb42HQbOZdAAAAAOLoyQBtJAAAbSQAAAIAAACDpc8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoA8BZszgAAAAA./bcr=AAAAAAAA8D8=/cnd=%21ag_oJQj8-LwKEIPLvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzQyQOYWSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3NDI=/bn=89169/'] + }, + 'impression_trackers': ['http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLpB6DpAwAAAwDWAAUBCNDZme8FENWyhPv4uuzPIxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlCDy74uWJzxW2AAaM26dXjRuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzUzODIyMjQpO3VmKCdyJywgOTc0OTQ0MDMsIC4eAPDQkgKpAiFCenhPTlFqOC1Md0tFSVBMdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JRTDdBTHVfbzFqX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVBQZ0VBSWdGaGlVLpoCiQEhYWdfb0o6LQEkblBGYklBUW9BRBVYDGtRRG8yhQAQUU9ZV1MRWAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCMWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTwlS9wYWdlcy9uYXRpdmUuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATruAKyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQy2gQCCAHgBAHwBEH6IIgFAZgFAKAF_xEBGAHABQDJBQAFARTwP9IFCQkFC3wAAADYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgEhQAAA8D_IBgDQBvUv2gYWChAAOgEAUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=6b203c7aee654cffa9c0b3771f6945f6d1e8d06c'], + 'id': 97494403 + } + } + }] + }, { + 'uuid': '35598a5ad26f59', + 'tag_id': 13232354, + 'auction_id': '6083251961435599864', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLhB6DhAwAAAwDWAAUBCNDZme8FEPjnxITbrYO2VBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc1MzgyMjI0KTsBHSxyJywgOTc0OTQyMDQ2HgDw0JICqQIhYlR3OWZBajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWUlJQ2FBQndBSGdBZ0FHbUFZZ0JfRi1RQVFDWUFRQ2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCeVdmYjBYeWIxVF9aQVFBQUFBQUFBUEFfNEFFQTlRRUFBQUFBbUFJQW9BSUF0UUlBQUFBQXZRSUFBQUFBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQVA4AcSIdWdNSlUwbE9Nem8wTnpReTRBUG1Gb2dFQUpBRUFKZ0VBY0UJXQUBCERKQgUICQEYMkFRQThRUQkNAQFUUGdFQUlnRmhpVS6aAokBIW9ROTNPUTYtASRuUEZiSUFRb0FEFVgMa1FEbzKFABBRT1lXUxFYDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gIxaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPC8L3BhZ2VzL25hdGl2ZS5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBOu4ArIEDggAEAEYACAAKAAwADgCuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDLaBAIIAOAEAfAEvMm-LogFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJCQx4AADYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgklNPC_yAYA0Ab1L9oGFgoQCRQZAVAQABgA4AYM8gYCCACABwGIBwCgB0E.&s=99a73b39ab82dd9384eee306ff03276ab688cfe5', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'native', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 97494204, + 'media_type_id': 12, + 'media_subtype_id': 65, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 53, + 'client_initiated_ad_counting': true, + 'viewability': { + 'config': '' + }, + 'rtb': { + 'native': { + 'title': 'This is a Prebid Native Creative', + 'desc': 'This is a Prebid Native Creative. There are many like it, but this one is mine.', + 'sponsored': 'Prebid.org', + 'icon': { + 'url': 'http://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png', + 'width': 127, + 'height': 83, + 'prevent_crop': false + }, + 'main_img': { + 'url': 'http://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg', + 'width': 989, + 'height': 742, + 'prevent_crop': false + }, + 'link': { + 'url': 'http://prebid.org/dev-docs/show-native-ads.html', + 'click_trackers': ['http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQPgzkbBtDWxUKnKSKrrb42HQbOZdAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAJhcX3AAAAAA./bcr=AAAAAAAA8D8=/cnd=%21oQ93OQj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzQyQOYWSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3NDI=/bn=89169/'] + }, + 'impression_trackers': ['http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLpB6DpAwAAAwDWAAUBCNDZme8FEPjnxITbrYO2VBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXjRuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzUzODIyMjQpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPDQkgKpAiFiVHc5ZkFqOC1Md0tFTHpKdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0J5V2ZiMFh5YjFUX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVRQZ0VBSWdGaGlVLpoCiQEhb1E5M09RNi0BJG5QRmJJQVFvQUQVWAxrUURvMoUAEFFPWVdTEVgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDKBlQUEu2AIA4AKtmEjqAjFodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OQUU8LwvcGFnZXMvbmF0aXZlLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagE67gCsgQOCAAQARgAIAAoADAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDc0MtoEAggB4AQB8AS8yb4uiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkJDHgAANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSU48D_IBgDQBvUv2gYWChAAOgEAUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=5c316c116b6e2bdb19f3950c4c769821e735688e'], + 'id': 97494204 + } + } + }] + }] + } + } + } +} diff --git a/test/mock-server/expectations/request-response-pairs/outstream/index.js b/test/mock-server/expectations/request-response-pairs/outstream/index.js new file mode 100644 index 00000000000..be5f4654b9f --- /dev/null +++ b/test/mock-server/expectations/request-response-pairs/outstream/index.js @@ -0,0 +1,162 @@ +var app = require('../../../index'); + +/** + * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. + * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse + * these files and return the response when expecation is met + * + */ + +/** + * This function will return the request object with all the entities method, path, body, header etc. + * + * @return {object} Request object + */ +exports.getRequest = function() { + return { + 'httpRequest': { + 'method': 'POST', + 'path': '/', + 'body': { + 'tags': [{ + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 13232385, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'video': { + 'skippable': true, + 'playback_method': ['auto_play_sound_off'] + } + }, { + 'sizes': [{ + 'width': 640, + 'height': 480 + }], + 'primary_size': { + 'width': 640, + 'height': 480 + }, + 'ad_types': ['video'], + 'id': 13232385, + 'allow_smaller_sizes': false, + 'use_pmt_rule': false, + 'prebid': true, + 'disable_psa': true, + 'video': { + 'skippable': true, + 'playback_method': ['auto_play_sound_off'] + } + }], + 'user': {} + } + } + } +} + +/** + * This function will return the response object with all the entities method, path, body, header etc. + * + * @return {object} Response object + */ +exports.getResponse = function() { + return { + 'httpResponse': { + 'body': { + 'version': '3.0.0', + 'tags': [{ + 'uuid': '223e8549781f2e', + 'tag_id': 13232385, + 'auction_id': '527250675737245396', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Foutstream.html&e=wqT_3QKwCKAwBAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIHSpwY47UhA7UhIAFAAWJzxW2AAaOWljwF4AIABAYoBAJIBA1VTRJgBAaABAagBAbABALgBA8ABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3NTU1Mzg5NikFHTRyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_yIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzLwmj8F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAOAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWlyFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwv8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9953ce4d94992db04897ab580bf81b3e274b2601', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQloC-ldAAAAABHUNucysitRBxloC-ldAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQgdKnBljDlQtiAi0taAFwAXgAgAECiAEEkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=979aee1106a0bea5609a3c23fdc46153ad6d9eec&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 97517771, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 36, + 'renderer_url': 'http://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', + 'renderer_id': 2, + 'renderer_config': '{"skippable":{"videoThreshold":null,"skipLocation":"top-right"}}', + 'client_initiated_ad_counting': true, + 'viewability': { + 'config': 'tv=vh2-121&d=1x1&s=3479483&st=0&vctx=4&ts=1575553896&vc=iab;vid_ccr=1&vjs=http%3A%2F%2Fcdn.adnxs.com%2Fv%2Fvideo%2F182%2Ftrk.js&cb=http%3A%2F%2Fsin3-ib.adnxs.com%2Fvevent%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QK4CKA4BAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_yIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzLwmj8F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAeAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWl6FPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwP8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA%26s%3D5adef946cd5f0d8db86d67860914e02ef6f91d6b&cet=0&cecb=&rdcb=http%3A%2F%2Fsin3-ib.adnxs.com%2Frd_log%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QKMCaCMBAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_aPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7gSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDffwXpgEAKIECzEwLjc1Ljc0LjY5qASYzwKyBBIIBBAEGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDgzNNoEAggB4AQA8ATLgcAuiAUBmAUAoAX_____BQMUAcAFAMkFac4U8D_SBQkJCQx4AADYBQHgBQHwBcOVC_oFBAgAEACQBgGYBgC4BgDBBgklNPA_yAYA0Ab1L9oGFgoQCRQZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.%26s%3Df2a73057b50fb0c9e98a6093141472a4ed2e401e&bridge=1.11.0&rblog=auc=527250675737245396;bm=9325;sm=9325;cr=97517771;pl=13232385&vid_context=anoutstream;anbannerstream;anoverlayplayer' + }, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_off'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'content': 'adnxs00:00:30.000' + } + } + }] + }, { + 'uuid': '3acfd472dd4bdf', + 'tag_id': 13232385, + 'auction_id': '3449642271543746980', + 'nobid': false, + 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Foutstream.html&e=wqT_3QKwCKAwBAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIHSpwY47UhA7UhIAFAAWJzxW2AAaOWljwF4AIABAYoBAJIBA1VTRJgBAaABAagBAbABALgBA8ABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3NTU1Mzg5NikFHTRyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP8iAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My8Jo_BemAQAogQLMTAuNzUuNzQuNjmoBJjPArIEEggEEAQYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODM02gQCCADgBADwBMuBwC6IBQGYBQCgBf____8FAxQBwAUAyQVpchTwP9IFCQkJDHgAANgFAeAFAfAFw5UL-gUECAAQAJAGAZgGALgGAMEGCSU08L_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=e43b45a2391036da6d93eda546d8808de0169bb1', + 'timeout_ms': 0, + 'ad_profile_id': 1182765, + 'rtb_video_fallback': false, + 'ads': [{ + 'content_source': 'rtb', + 'ad_type': 'video', + 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQloC-ldAAAAABGkYYl1XpffLxloC-ldAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQgdKnBljDlQtiAi0taAFwAXgAgAECiAEEkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=414834fdc6e268f284292aedf8b01ee525c3e999&event_type=1', + 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', + 'buyer_member_id': 9325, + 'advertiser_id': 2529885, + 'creative_id': 97517771, + 'media_type_id': 4, + 'media_subtype_id': 64, + 'cpm': 10.000000, + 'cpm_publisher_currency': 10.000000, + 'publisher_currency_code': '$', + 'brand_category_id': 36, + 'renderer_url': 'http://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', + 'renderer_id': 2, + 'renderer_config': '{"skippable":{"videoThreshold":null,"skipLocation":"top-right"}}', + 'client_initiated_ad_counting': true, + 'viewability': { + 'config': 'tv=vh2-121&d=1x1&s=3479483&st=0&vctx=4&ts=1575553896&vc=iab;vid_ccr=1&vjs=http%3A%2F%2Fcdn.adnxs.com%2Fv%2Fvideo%2F182%2Ftrk.js&cb=http%3A%2F%2Fsin3-ib.adnxs.com%2Fvevent%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QK4CKA4BAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP8iAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My8Jo_BemAQAogQLMTAuNzUuNzQuNjmoBJjPArIEEggEEAQYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODM02gQCCAHgBADwBMuBwC6IBQGYBQCgBf____8FAxQBwAUAyQVpehTwP9IFCQkJDHgAANgFAeAFAfAFw5UL-gUECAAQAJAGAZgGALgGAMEGCSU08D_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..%26s%3Dc2a8dac8959d9366981afc868ec5b54853090944&cet=0&cecb=&rdcb=http%3A%2F%2Fsin3-ib.adnxs.com%2Frd_log%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QKMCaCMBAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP2jyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-4ElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw338F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAeAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWnOFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwP8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA%26s%3D4e9e218d8f075cb19c4a4e8da2a7e716fa15d3c5&bridge=1.11.0&rblog=auc=3449642271543746980;bm=9325;sm=9325;cr=97517771;pl=13232385&vid_context=anoutstream;anbannerstream;anoverlayplayer' + }, + 'rtb': { + 'video': { + 'player_width': 640, + 'player_height': 480, + 'duration_ms': 30000, + 'playback_methods': ['auto_play_sound_off'], + 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], + 'content': 'adnxs00:00:30.000' + } + } + }] + }] + } + } + } +} diff --git a/test/mock-server/request-middlewares/prebid-request.js b/test/mock-server/request-middlewares/prebid-request.js index 6e2d03487cf..b14c3119247 100644 --- a/test/mock-server/request-middlewares/prebid-request.js +++ b/test/mock-server/request-middlewares/prebid-request.js @@ -39,7 +39,7 @@ module.exports = function (req, res, next) { // values within these request props are dynamically generated and aren't // vital to check in these tests, so they are deleted rather than updating // the request-response pairs continuously - ['sdk', 'referrer_detection'].forEach(prop => { + ['sdk', 'referrer_detection', 'brand_category_uniqueness', 'gdpr_consent'].forEach(prop => { if (reqBody && reqBody[prop]) { delete reqBody[prop]; } diff --git a/test/pages/bidderSettings.html b/test/pages/bidderSettings.html new file mode 100644 index 00000000000..a4a718d6497 --- /dev/null +++ b/test/pages/bidderSettings.html @@ -0,0 +1,125 @@ + + + + + + + + + + + + +

Prebid.js Test

+
Div-1
+
+ +
+ + diff --git a/test/pages/consent_mgt_gdpr.html b/test/pages/consent_mgt_gdpr.html new file mode 100644 index 00000000000..a7da17ca2f7 --- /dev/null +++ b/test/pages/consent_mgt_gdpr.html @@ -0,0 +1,206 @@ + + + + + + + + + + + + + +

Prebid.js Test

+
Div-1
+
+ +
+ + diff --git a/test/pages/currency.html b/test/pages/currency.html new file mode 100644 index 00000000000..5214982f67c --- /dev/null +++ b/test/pages/currency.html @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + +

Prebid.js Test

+
Div-1
+
+ +
+ + diff --git a/test/pages/video.html b/test/pages/instream.html similarity index 93% rename from test/pages/video.html rename to test/pages/instream.html index 3fabeb14b94..be7aceb40db 100644 --- a/test/pages/video.html +++ b/test/pages/instream.html @@ -38,7 +38,7 @@ { bidder: 'appnexus', params: { - placementId: '9333431', + placementId: '13232361', video: { skipppable: false, playback_methods: ['auto_play_sound_off'] @@ -50,6 +50,12 @@ pbjs.que.push(function(){ pbjs.addAdUnits(videoAdUnit); + pbjs.setConfig({ + debug: true, + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + } + }); pbjs.requestBids({ timeout : 700, bidsBackHandler : function(bids) { diff --git a/test/pages/multiple_bidders.html b/test/pages/multiple_bidders.html new file mode 100644 index 00000000000..1cf139fd0b8 --- /dev/null +++ b/test/pages/multiple_bidders.html @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + +

Multi-Format Ad Units

+

div-banner

+
+ +
+ +

div-native

+
+

No response

+ +
+ + + + \ No newline at end of file diff --git a/test/pages/priceGranularity.html b/test/pages/priceGranularity.html new file mode 100644 index 00000000000..588b11044fb --- /dev/null +++ b/test/pages/priceGranularity.html @@ -0,0 +1,131 @@ + + + + + + + + + + + + +

Prebid.js Test

+
Div-1
+
+ +
+ + diff --git a/test/pages/sizeConfig.html b/test/pages/sizeConfig.html new file mode 100644 index 00000000000..b62b4a741ab --- /dev/null +++ b/test/pages/sizeConfig.html @@ -0,0 +1,142 @@ + + + + + + + + + + + + +

Prebid.js Test

+
Div-1
+
+ +
+ + diff --git a/test/pages/userSync.html b/test/pages/userSync.html new file mode 100644 index 00000000000..43aeafd46e9 --- /dev/null +++ b/test/pages/userSync.html @@ -0,0 +1,121 @@ + + + + + + + + + + + + +

Prebid.js Test

+
Div-1
+
+ +
+ + diff --git a/test/spec/e2e/instream/basic_instream_video_ad.spec.js b/test/spec/e2e/instream/basic_instream_video_ad.spec.js new file mode 100644 index 00000000000..034363685d2 --- /dev/null +++ b/test/spec/e2e/instream/basic_instream_video_ad.spec.js @@ -0,0 +1,52 @@ +const expect = require('chai').expect; +const { host, protocol } = require('../../../helpers/testing-utils'); + +const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/instream.html?pbjs_debug=true`; +const CREATIVE_IFRAME_CSS_SELECTOR = 'div[class="VPAID-container"] > div > iframe'; + +const EXPECTED_TARGETING_KEYS = { + hb_cache_id: '', + hb_uuid: '', + hb_format: 'video', + hb_source: 'client', + hb_size: '640x480', + hb_pb: '10.00', + hb_bidder: 'appnexus', + hb_format_appnexus: 'video', + hb_source_appnexus: 'client', + hb_size_appnexus: '640x480', + hb_pb_appnexus: '10.00', + hb_bidder_appnexus: 'appnexus' +}; + +describe('Prebid.js Instream Video Ad Test', function () { + before(function loadTestPage() { + browser + .url(TEST_PAGE_URL) + try { + browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 5000); + // const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; + // browser.frame(creativeIframe); + } catch (e) { + // If creative Iframe didn't load, repeat the steps again! + // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js + loadTestPage(); + } + }); + + // it('should load the targeting keys with correct values', function () { + // const result = browser.execute(function () { + // console.log('pbjs::', window.top.pbjs); + // return window.top.pbjs.getAdserverTargeting('video1'); + // }); + // console.log('result:::', result); + // const targetingKeys = result.value['vid1']; + // expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); + // expect(targetingKeys.hb_adid).to.be.a('string'); + // expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); + // }); + + it('should render the instream ad on the page', function() { + expect(browser.isVisible(CREATIVE_IFRAME_CSS_SELECTOR)); + }); +}); diff --git a/test/spec/e2e/modules/e2e_bidderSettings.spec.js b/test/spec/e2e/modules/e2e_bidderSettings.spec.js new file mode 100644 index 00000000000..d9f1d18725d --- /dev/null +++ b/test/spec/e2e/modules/e2e_bidderSettings.spec.js @@ -0,0 +1,59 @@ +const expect = require('chai').expect; +const { host, protocol } = require('../../../helpers/testing-utils'); + +const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/bidderSettings.html?pbjs_debug=true`; +const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; + +const EXPECTED_TARGETING_KEYS = { + hb_source: 'client', + hb_source_appnexus: 'client', + hb_pb_appnexus: '10.00', + hb_native_title_appn: 'This is a Prebid Native Creative', + hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_format: 'native', + hb_native_brand: 'Prebid.org', + hb_size: '0x0', + hb_bidder_appnexus: 'appnexus', + hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_native_title: 'This is a Prebid Native Creative', + hb_pb: '10.00', + hb_native_brand_appn: 'Prebid.org', + hb_bidder: 'appnexus', + hb_format_appnexus: 'native', + hb_size_appnexus: '0x0' +} + +describe('Prebid.js Bidder Settings Ad Unit Test', function () { + before(function loadTestPage() { + browser.url(TEST_PAGE_URL).pause(3000); + try { + browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); + const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; + browser.frame(creativeIframe); + } catch (e) { + // If creative Iframe didn't load, repeat the steps again! + // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js + loadTestPage(); + } + }); + + it('should load the targeting keys with correct values', function () { + const result = browser.execute(function () { + return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + }); + + const targetingKeys = result.value['/19968336/prebid_native_example_2']; + expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); + expect(targetingKeys.hb_adid).to.be.a('string'); + expect(targetingKeys.hb_native_body).to.be.a('string'); + expect(targetingKeys.hb_native_body_appne).to.be.a('string'); + expect(targetingKeys.hb_native_icon).to.be.a('string'); + expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); + expect(targetingKeys.hb_native_image).to.be.a('string'); + expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); + }); + + it('should render the Banner Ad on the page', function () { + expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + }); +}); diff --git a/test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js b/test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js new file mode 100644 index 00000000000..1c11a5432ff --- /dev/null +++ b/test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js @@ -0,0 +1,59 @@ +const expect = require('chai').expect; +const { host, protocol } = require('../../../helpers/testing-utils'); + +const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/consent_mgt_gdpr.html?pbjs_debug=true`; +const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; + +const EXPECTED_TARGETING_KEYS = { + hb_source: 'client', + hb_source_appnexus: 'client', + hb_pb_appnexus: '10.00', + hb_native_title_appn: 'This is a Prebid Native Creative', + hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_format: 'native', + hb_native_brand: 'Prebid.org', + hb_size: '0x0', + hb_bidder_appnexus: 'appnexus', + hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_native_title: 'This is a Prebid Native Creative', + hb_pb: '10.00', + hb_native_brand_appn: 'Prebid.org', + hb_bidder: 'appnexus', + hb_format_appnexus: 'native', + hb_size_appnexus: '0x0' +}; + +describe('Prebid.js GDPR Ad Unit Test', function () { + before(function loadTestPage() { + browser.url(TEST_PAGE_URL).pause(3000); + try { + browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); + const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; + browser.frame(creativeIframe); + } catch (e) { + // If creative Iframe didn't load, repeat the steps again! + // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js + loadTestPage(); + } + }); + + it('should load the targeting keys with correct values', function () { + const result = browser.execute(function () { + return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + }); + + const targetingKeys = result.value['/19968336/prebid_native_example_2']; + expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); + expect(targetingKeys.hb_adid).to.be.a('string'); + expect(targetingKeys.hb_native_body).to.be.a('string'); + expect(targetingKeys.hb_native_body_appne).to.be.a('string'); + expect(targetingKeys.hb_native_icon).to.be.a('string'); + expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); + expect(targetingKeys.hb_native_image).to.be.a('string'); + expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); + }); + + it('should render the Banner Ad on the page', function () { + expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + }); +}); diff --git a/test/spec/e2e/modules/e2e_currency.spec.js b/test/spec/e2e/modules/e2e_currency.spec.js new file mode 100644 index 00000000000..8692b4991bd --- /dev/null +++ b/test/spec/e2e/modules/e2e_currency.spec.js @@ -0,0 +1,59 @@ +const expect = require('chai').expect; +const { host, protocol } = require('../../../helpers/testing-utils'); + +const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/currency.html?pbjs_debug=true`; +const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; + +const EXPECTED_TARGETING_KEYS = { + hb_source: 'client', + hb_source_appnexus: 'client', + hb_pb_appnexus: '7.50', + hb_native_title_appn: 'This is a Prebid Native Creative', + hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_format: 'native', + hb_native_brand: 'Prebid.org', + hb_size: '0x0', + hb_bidder_appnexus: 'appnexus', + hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_native_title: 'This is a Prebid Native Creative', + hb_pb: '7.50', + hb_native_brand_appn: 'Prebid.org', + hb_bidder: 'appnexus', + hb_format_appnexus: 'native', + hb_size_appnexus: '0x0' +} + +describe('Prebid.js Currency Ad Unit Test', function () { + before(function loadTestPage() { + browser.url(TEST_PAGE_URL).pause(3000); + try { + browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); + const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; + browser.frame(creativeIframe); + } catch (e) { + // If creative Iframe didn't load, repeat the steps again! + // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js + loadTestPage(); + } + }); + + it('should load the targeting keys with correct values', function () { + const result = browser.execute(function () { + return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + }); + + const targetingKeys = result.value['/19968336/prebid_native_example_2']; + expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); + expect(targetingKeys.hb_adid).to.be.a('string'); + expect(targetingKeys.hb_native_body).to.be.a('string'); + expect(targetingKeys.hb_native_body_appne).to.be.a('string'); + expect(targetingKeys.hb_native_icon).to.be.a('string'); + expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); + expect(targetingKeys.hb_native_image).to.be.a('string'); + expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); + }); + + it('should render the Banner Ad on the page', function () { + expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + }); +}); diff --git a/test/spec/e2e/modules/e2e_priceGranularity.spec.js b/test/spec/e2e/modules/e2e_priceGranularity.spec.js new file mode 100644 index 00000000000..1042ab491fb --- /dev/null +++ b/test/spec/e2e/modules/e2e_priceGranularity.spec.js @@ -0,0 +1,59 @@ +const expect = require('chai').expect; +const { host, protocol } = require('../../../helpers/testing-utils'); + +const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/priceGranularity.html?pbjs_debug=true`; +const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; + +const EXPECTED_TARGETING_KEYS = { + hb_source: 'client', + hb_source_appnexus: 'client', + hb_pb_appnexus: '10.00', + hb_native_title_appn: 'This is a Prebid Native Creative', + hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_format: 'native', + hb_native_brand: 'Prebid.org', + hb_size: '0x0', + hb_bidder_appnexus: 'appnexus', + hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_native_title: 'This is a Prebid Native Creative', + hb_pb: '10.00', + hb_native_brand_appn: 'Prebid.org', + hb_bidder: 'appnexus', + hb_format_appnexus: 'native', + hb_size_appnexus: '0x0' +} + +describe('Prebid.js Price Granularity Ad Unit Test', function () { + before(function loadTestPage() { + browser.url(TEST_PAGE_URL).pause(3000); + try { + browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); + const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; + browser.frame(creativeIframe); + } catch (e) { + // If creative Iframe didn't load, repeat the steps again! + // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js + loadTestPage(); + } + }); + + it('should load the targeting keys with correct values', function () { + const result = browser.execute(function () { + return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + }); + + const targetingKeys = result.value['/19968336/prebid_native_example_2']; + expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); + expect(targetingKeys.hb_adid).to.be.a('string'); + expect(targetingKeys.hb_native_body).to.be.a('string'); + expect(targetingKeys.hb_native_body_appne).to.be.a('string'); + expect(targetingKeys.hb_native_icon).to.be.a('string'); + expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); + expect(targetingKeys.hb_native_image).to.be.a('string'); + expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); + }); + + it('should render the Banner Ad on the page', function () { + expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + }); +}); diff --git a/test/spec/e2e/modules/e2e_sizeConfig.spec.js b/test/spec/e2e/modules/e2e_sizeConfig.spec.js new file mode 100644 index 00000000000..1eb3fad8dea --- /dev/null +++ b/test/spec/e2e/modules/e2e_sizeConfig.spec.js @@ -0,0 +1,59 @@ +const expect = require('chai').expect; +const { host, protocol } = require('../../../helpers/testing-utils'); + +const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/sizeConfig.html?pbjs_debug=true`; +const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; + +const EXPECTED_TARGETING_KEYS = { + hb_source: 'client', + hb_source_appnexus: 'client', + hb_pb_appnexus: '10.00', + hb_native_title_appn: 'This is a Prebid Native Creative', + hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_format: 'native', + hb_native_brand: 'Prebid.org', + hb_size: '0x0', + hb_bidder_appnexus: 'appnexus', + hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_native_title: 'This is a Prebid Native Creative', + hb_pb: '10.00', + hb_native_brand_appn: 'Prebid.org', + hb_bidder: 'appnexus', + hb_format_appnexus: 'native', + hb_size_appnexus: '0x0' +} + +describe('Prebid.js Size Config Ad Unit Test', function () { + before(function loadTestPage() { + browser.url(TEST_PAGE_URL).pause(3000); + try { + browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); + const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; + browser.frame(creativeIframe); + } catch (e) { + // If creative Iframe didn't load, repeat the steps again! + // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js + loadTestPage(); + } + }); + + it('should load the targeting keys with correct values', function () { + const result = browser.execute(function () { + return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + }); + + const targetingKeys = result.value['/19968336/prebid_native_example_2']; + expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); + expect(targetingKeys.hb_adid).to.be.a('string'); + expect(targetingKeys.hb_native_body).to.be.a('string'); + expect(targetingKeys.hb_native_body_appne).to.be.a('string'); + expect(targetingKeys.hb_native_icon).to.be.a('string'); + expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); + expect(targetingKeys.hb_native_image).to.be.a('string'); + expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); + }); + + it('should render the Banner Ad on the page', function () { + expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + }); +}); diff --git a/test/spec/e2e/modules/e2e_userSync.spec.js b/test/spec/e2e/modules/e2e_userSync.spec.js new file mode 100644 index 00000000000..3957f3cdfef --- /dev/null +++ b/test/spec/e2e/modules/e2e_userSync.spec.js @@ -0,0 +1,59 @@ +const expect = require('chai').expect; +const { host, protocol } = require('../../../helpers/testing-utils'); + +const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/userSync.html?pbjs_debug=true`; +const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; + +const EXPECTED_TARGETING_KEYS = { + hb_source: 'client', + hb_source_appnexus: 'client', + hb_pb_appnexus: '10.00', + hb_native_title_appn: 'This is a Prebid Native Creative', + hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_format: 'native', + hb_native_brand: 'Prebid.org', + hb_size: '0x0', + hb_bidder_appnexus: 'appnexus', + hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_native_title: 'This is a Prebid Native Creative', + hb_pb: '10.00', + hb_native_brand_appn: 'Prebid.org', + hb_bidder: 'appnexus', + hb_format_appnexus: 'native', + hb_size_appnexus: '0x0' +} + +describe('Prebid.js User Sync Ad Unit Test', function () { + before(function loadTestPage() { + browser.url(TEST_PAGE_URL).pause(3000); + try { + browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); + const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; + browser.frame(creativeIframe); + } catch (e) { + // If creative Iframe didn't load, repeat the steps again! + // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js + loadTestPage(); + } + }); + + it('should load the targeting keys with correct values', function () { + const result = browser.execute(function () { + return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + }); + + const targetingKeys = result.value['/19968336/prebid_native_example_2']; + expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); + expect(targetingKeys.hb_adid).to.be.a('string'); + expect(targetingKeys.hb_native_body).to.be.a('string'); + expect(targetingKeys.hb_native_body_appne).to.be.a('string'); + expect(targetingKeys.hb_native_icon).to.be.a('string'); + expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); + expect(targetingKeys.hb_native_image).to.be.a('string'); + expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); + }); + + it('should render the Banner Ad on the page', function () { + expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + }); +}); diff --git a/test/spec/e2e/multi-format/e2e_multiple_bidders.spec.js b/test/spec/e2e/multi-format/e2e_multiple_bidders.spec.js new file mode 100644 index 00000000000..4ce750bdd96 --- /dev/null +++ b/test/spec/e2e/multi-format/e2e_multiple_bidders.spec.js @@ -0,0 +1,68 @@ +const expect = require('chai').expect; +const { host, protocol } = require('../../../helpers/testing-utils'); + +const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/multiple_bidders.html?pbjs_debug=true`; +const CREATIVE_BANNER_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/prebid_multiformat_test_0"]'; +const CREATIVE_NATIVE_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/prebid_multiformat_test_1"]'; + +const EXPECTED_TARGETING_KEYS = { + hb_source: 'client', + hb_source_appnexus: 'client', + hb_pb_appnexus: '10.00', + hb_native_title_appn: 'This is a Prebid Native Creative', + hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_format: 'native', + hb_native_brand: 'Prebid.org', + hb_size: '0x0', + hb_bidder_appnexus: 'appnexus', + hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', + hb_native_title: 'This is a Prebid Native Creative', + hb_pb: '10.00', + hb_native_brand_appn: 'Prebid.org', + hb_bidder: 'appnexus', + hb_format_appnexus: 'native', + hb_size_appnexus: '0x0' +}; + +describe('Prebid.js Multiple Bidder Ad Unit Test', function () { + before(function loadTestPage() { + browser.url(TEST_PAGE_URL).pause(3000); + try { + browser.waitForExist(CREATIVE_BANNER_CSS_SELECTOR, 3000); + const creativeIframe = $(CREATIVE_BANNER_CSS_SELECTOR).value; + browser.frame(creativeIframe); + } catch (e) { + // If creative Iframe didn't load, repeat the steps again! + // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js + loadTestPage(); + } + }); + + it('should load the targeting keys with correct values', function () { + const result = browser.execute(function () { + return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + }); + + const targetingKeys = result.value['/19968336/prebid_native_example_2']; + expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); + expect(targetingKeys.hb_adid).to.be.a('string'); + expect(targetingKeys.hb_native_body).to.be.a('string'); + expect(targetingKeys.hb_native_body_appne).to.be.a('string'); + expect(targetingKeys.hb_native_icon).to.be.a('string'); + expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); + expect(targetingKeys.hb_native_image).to.be.a('string'); + expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); + }); + + it('should render the Banner Ad on the page', function () { + expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + }); + + it('should render the native ad on the page', function () { + browser.frameParent(); + browser.waitForExist(CREATIVE_NATIVE_CSS_SELECTOR, 3000); + const creativeIframe = $(CREATIVE_NATIVE_CSS_SELECTOR).value; + browser.frame(creativeIframe); + expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > div[class="card"]')).to.be.true; + }); +}); diff --git a/test/spec/e2e/native/basic_native_ad.spec.js b/test/spec/e2e/native/basic_native_ad.spec.js index ed09228b532..8eb9a5940a0 100644 --- a/test/spec/e2e/native/basic_native_ad.spec.js +++ b/test/spec/e2e/native/basic_native_ad.spec.js @@ -37,7 +37,7 @@ describe('Prebid.js Native Ad Unit Test', function () { it('should load the targeting keys with correct values', function () { const result = browser.execute(function () { - return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); }); const targetingKeys = result.value['/19968336/prebid_native_example_2']; diff --git a/wdio.conf.js b/wdio.conf.js index 22765e34346..dd94e82cf90 100644 --- a/wdio.conf.js +++ b/wdio.conf.js @@ -35,9 +35,8 @@ function getCapabilities() { } exports.config = { - // TODO: below change is only for testing and is to be removed. specs: [ - './test/spec/e2e/banner/*.spec.js' + './test/spec/e2e/**/*.spec.js' ], services: ['browserstack'], user: process.env.BROWSERSTACK_USERNAME, From 4f78849e47e28243eeab22b9ca9f526b699a0afe Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Fri, 6 Mar 2020 12:20:41 -0700 Subject: [PATCH 113/496] add validation to callbackWithBidder to ensure called with function (#4734) * add validation to callbackWithBidder to ensure called with function * better error message in callbackWithBidder --- src/config.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/config.js b/src/config.js index 41056ced591..678b680d712 100644 --- a/src/config.js +++ b/src/config.js @@ -429,7 +429,11 @@ export function newConfig() { function callbackWithBidder(bidder) { return function(cb) { return function(...args) { - return runWithBidder(bidder, utils.bind.call(cb, this, ...args)) + if (typeof cb === 'function') { + return runWithBidder(bidder, utils.bind.call(cb, this, ...args)) + } else { + utils.logWarn('config.callbackWithBidder callback is not a function'); + } } } } From 4dbf39618d98aba2806531c76dcae84331c4fbc4 Mon Sep 17 00:00:00 2001 From: kusapan Date: Sat, 7 Mar 2020 06:49:37 +0900 Subject: [PATCH 114/496] YIELDONE adapter - add transactionId param (#4939) * added UserSync * added UserSync Unit Test * support for multi sizes * register the adapter as supporting video * supporting video * change requestId acquisition method * fix the parameter name of dealID * update test parameters * support instream video * add test for bidRequest * add test for interpretResponse * add test params * add note to documentaion * add payload params * add test * delete tmax param * add tid param --- modules/yieldoneBidAdapter.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/yieldoneBidAdapter.js b/modules/yieldoneBidAdapter.js index 1b6c0e7083e..59240878426 100644 --- a/modules/yieldoneBidAdapter.js +++ b/modules/yieldoneBidAdapter.js @@ -24,6 +24,7 @@ export const spec = { const cb = Math.floor(Math.random() * 99999999999); const referrer = bidderRequest.refererInfo.referer; const bidId = bidRequest.bidId; + const transactionId = bidRequest.transactionId; const unitCode = bidRequest.adUnitCode; const timeout = config.getConfig('bidderTimeout'); const payload = { @@ -32,6 +33,7 @@ export const spec = { cb: cb, r: referrer, uid: bidId, + tid: transactionId, uc: unitCode, tmax: timeout, t: 'i' From 89b0d0af310fdf71630fe31f7afbb217b10d4ae7 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Fri, 6 Mar 2020 14:10:27 -0800 Subject: [PATCH 115/496] Vdoai spec import js (#4943) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * added .js to imports in vdoai spec --- test/spec/modules/vdoaiBidAdapter_spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/spec/modules/vdoaiBidAdapter_spec.js b/test/spec/modules/vdoaiBidAdapter_spec.js index 507f3ffa3ac..c9d826d8dc8 100644 --- a/test/spec/modules/vdoaiBidAdapter_spec.js +++ b/test/spec/modules/vdoaiBidAdapter_spec.js @@ -1,6 +1,6 @@ import {assert, expect} from 'chai'; -import {spec} from 'modules/vdoaiBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import {spec} from 'modules/vdoaiBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; const ENDPOINT_URL = 'https://prebid.vdo.ai/auction'; From 88e9b871f504598c3cfbf4ccda3ee53ab15aa60b Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Fri, 6 Mar 2020 18:10:52 -0500 Subject: [PATCH 116/496] small update to usersync to follow-up #4928 (#4942) --- src/userSync.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/userSync.js b/src/userSync.js index 4d09d95a412..e19f64d8082 100644 --- a/src/userSync.js +++ b/src/userSync.js @@ -47,12 +47,12 @@ export function newUserSync(userSyncDependencies) { let usConfig = userSyncDependencies.config; // Update if it's (re)set config.getConfig('userSync', (conf) => { - // if userSync.filterSettings only contains iframe, merge in default image config to ensure image pixels are fired + // Added this logic for https://github.com/prebid/Prebid.js/issues/4864 + // if userSync.filterSettings does not contain image/all configs, merge in default image config to ensure image pixels are fired if (conf.userSync) { let fs = conf.userSync.filterSettings; if (utils.isPlainObject(fs)) { - let fsKeys = Object.keys(fs); - if (fsKeys.length === 1 && fsKeys[0] === 'iframe') { + if (!fs.image && !fs.all) { conf.userSync.filterSettings.image = { bidders: '*', filter: 'include' From ef66d9344aee980d03d1c0dedb4ce5702943ba6c Mon Sep 17 00:00:00 2001 From: "Cheng-Yao , Xu" Date: Sat, 7 Mar 2020 07:13:35 +0800 Subject: [PATCH 117/496] Update bridgewell bid adapter (#4920) * Add consumed to bid response * Modify test * Use include instead of containAllKeys * Use adUnitCode to match response and request * Add test * Restore packageLock --- modules/bridgewellBidAdapter.js | 10 +- .../spec/modules/bridgewellBidAdapter_spec.js | 205 ++++++++++++++++++ 2 files changed, 213 insertions(+), 2 deletions(-) diff --git a/modules/bridgewellBidAdapter.js b/modules/bridgewellBidAdapter.js index 1c09cfc3624..a95a19f0402 100644 --- a/modules/bridgewellBidAdapter.js +++ b/modules/bridgewellBidAdapter.js @@ -38,6 +38,7 @@ export const spec = { utils._each(validBidRequests, function (bid) { adUnits.push({ ChannelID: bid.params.ChannelID, + adUnitCode: bid.adUnitCode, mediaTypes: bid.mediaTypes || { banner: { sizes: bid.sizes @@ -89,9 +90,12 @@ export const spec = { let matchedResponse = find(serverResponse.body, function (res) { let valid = false; - if (res) { + if (res && !res.consumed) { let mediaTypes = req.mediaTypes; - if (res.width && res.height && mediaTypes) { + let adUnitCode = req.adUnitCode; + if (res.adUnitCode) { + return res.adUnitCode === adUnitCode; + } else if (res.width && res.height && mediaTypes) { if (mediaTypes.native) { // dont care native sizes valid = true; } else if (mediaTypes.banner) { @@ -116,6 +120,8 @@ export const spec = { }); if (matchedResponse) { + matchedResponse.consumed = true; + // check required parameters if (typeof matchedResponse.cpm !== 'number') { return; diff --git a/test/spec/modules/bridgewellBidAdapter_spec.js b/test/spec/modules/bridgewellBidAdapter_spec.js index 9a0abd067c9..644f468abe8 100644 --- a/test/spec/modules/bridgewellBidAdapter_spec.js +++ b/test/spec/modules/bridgewellBidAdapter_spec.js @@ -113,6 +113,7 @@ describe('bridgewellBidAdapter', function () { expect(payload.url).to.exist.and.to.equal('https://www.bridgewell.com/'); for (let i = 0, max_i = payload.adUnits.length; i < max_i; i++) { expect(payload.adUnits[i]).to.have.property('ChannelID').that.is.a('string'); + expect(payload.adUnits[i]).to.have.property('adUnitCode').and.to.equal('adunit-code-2'); } }); @@ -1010,5 +1011,209 @@ describe('bridgewellBidAdapter', function () { const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); expect(result).to.deep.equal([]); }); + + it('should contain every request bid id in responses', function () { + const request = { + validBidRequests: [ + { + 'mediaTypes': { + 'banner': { + 'sizes': [300, 250] + } + }, + 'bidId': '3150ccb55da321', + }, + { + 'mediaTypes': { + 'banner': { + 'sizes': [300, 250] + } + }, + 'bidId': '3150ccb55da322', + } + ], + }; + const response = [{ + 'id': '0cd250f4-f40e-4a78-90f5-5168eb0a97e9', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, { + 'id': '8a740063-6820-45e4-b01f-34ce9b38e858', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }]; + const result = spec.interpretResponse({ 'body': response }, request); + let actualBidId = result.map(obj => obj.requestId); + let expectedBidId = ['3150ccb55da321', '3150ccb55da322']; + + expect(actualBidId).to.include(expectedBidId[0]).and.to.include(expectedBidId[1]); + }); + + it('should have 2 consumed responses when two requests with same sizes are given', function () { + const request = { + validBidRequests: [ + { + 'mediaTypes': { + 'banner': { + 'sizes': [300, 250] + } + }, + 'bidId': '3150ccb55da321', + }, + { + 'mediaTypes': { + 'banner': { + 'sizes': [300, 250] + } + }, + 'bidId': '3150ccb55da322', + } + ], + }; + const response = [{ + 'id': '0cd250f4-f40e-4a78-90f5-5168eb0a97e9', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, { + 'id': '8a740063-6820-45e4-b01f-34ce9b38e858', + 'bidder_code': 'bridgewell', + 'cpm': 7.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }]; + const reducer = function(accumulator, currentValue) { + if (currentValue.consumed) accumulator++; + return accumulator; + }; + + spec.interpretResponse({ 'body': response }, request); + expect(response.reduce(reducer, 0)).to.equal(2); + }); + + it('should use adUnitCode to build bidResponses', function () { + const request = { + validBidRequests: [ + { + 'adUnitCode': 'div-gpt-ad-1564632520056-0', + 'bidId': '3150ccb55da321', + }, + { + 'adUnitCode': 'div-gpt-ad-1564632520056-1', + 'bidId': '3150ccb55da322', + } + ], + }; + const response = [{ + 'id': '0cd250f4-f40e-4a78-90f5-5168eb0a97e9', + 'bidder_code': 'bridgewell', + 'adUnitCode': 'div-gpt-ad-1564632520056-0', + 'cpm': 7.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, { + 'id': '8a740063-6820-45e4-b01f-34ce9b38e858', + 'bidder_code': 'bridgewell', + 'adUnitCode': 'div-gpt-ad-1564632520056-1', + 'cpm': 7.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }]; + const result = spec.interpretResponse({ 'body': response }, request); + let actualBidId = result.map(obj => obj.requestId); + let expectedBidId = ['3150ccb55da321', '3150ccb55da322']; + + expect(actualBidId).to.include(expectedBidId[0]).and.to.include(expectedBidId[1]); + }); + + it('should use size to match when adUnitCode is empty string in server response', function () { + const request = { + validBidRequests: [ + { + 'mediaTypes': { + 'banner': { + 'sizes': [300, 250] + } + }, + 'adUnitCode': 'div-gpt-ad-1564632520056-0', + 'bidId': '3150ccb55da321', + }, + { + 'mediaTypes': { + 'banner': { + 'sizes': [300, 250] + } + }, + 'adUnitCode': 'div-gpt-ad-1564632520056-1', + 'bidId': '3150ccb55da322', + } + ], + }; + const response = [{ + 'id': '0cd250f4-f40e-4a78-90f5-5168eb0a97e9', + 'bidder_code': 'bridgewell', + 'adUnitCode': '', + 'cpm': 7.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }, { + 'id': '8a740063-6820-45e4-b01f-34ce9b38e858', + 'bidder_code': 'bridgewell', + 'adUnitCode': '', + 'cpm': 7.0, + 'width': 300, + 'height': 250, + 'mediaType': 'banner', + 'ad': '
test 300x250
', + 'ttl': 400, + 'netRevenue': true, + 'currency': 'NTD' + }]; + const result = spec.interpretResponse({ 'body': response }, request); + let actualBidId = result.map(obj => obj.requestId); + let expectedBidId = ['3150ccb55da321', '3150ccb55da322']; + + expect(actualBidId).to.include(expectedBidId[0]).and.to.include(expectedBidId[1]); + }); }); }); From 19b7319e9b3df60be82f0f0b930f6050f3640d88 Mon Sep 17 00:00:00 2001 From: vincentproxistore <56686565+vincentproxistore@users.noreply.github.com> Date: Sun, 8 Mar 2020 11:28:41 +0100 Subject: [PATCH 118/496] use bidId or bidIds in the payload (#4903) --- modules/proxistoreBidAdapter.js | 4 +++- test/spec/modules/proxistoreBidAdapter_spec.js | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/proxistoreBidAdapter.js b/modules/proxistoreBidAdapter.js index a399a906402..6facf5d1480 100644 --- a/modules/proxistoreBidAdapter.js +++ b/modules/proxistoreBidAdapter.js @@ -9,7 +9,6 @@ function _mapSizes(sizes) { function _createServerRequest(bidRequests, bidderRequest) { const payload = { - bidId: bidRequests.map(req => req.bidId), auctionId: bidRequests[0].auctionId, transactionId: bidRequests[0].transactionId, sizes: _mapSizes(bidRequests.map(x => x.sizes)), @@ -20,6 +19,9 @@ function _createServerRequest(bidRequests, bidderRequest) { } }; + const bidIds = bidRequests.map(req => req.bidId); + bidIds.length === 1 ? payload.bidId = bidIds[0] : payload.bidIds = bidIds; + const options = { contentType: 'application/json', withCredentials: true diff --git a/test/spec/modules/proxistoreBidAdapter_spec.js b/test/spec/modules/proxistoreBidAdapter_spec.js index 4fd7d97ae99..579ef5fdb3b 100644 --- a/test/spec/modules/proxistoreBidAdapter_spec.js +++ b/test/spec/modules/proxistoreBidAdapter_spec.js @@ -50,10 +50,15 @@ describe('ProxistoreBidAdapter', function () { }); it('should have the value consentGiven to true bc we have 418 in the vendor list', function () { const data = JSON.parse(request.data); + expect(data.gdpr.consentString).equal(bidderRequest.gdprConsent.consentString); expect(data.gdpr.applies).to.be.true; expect(data.gdpr.consentGiven).to.be.true; }); + it('should have a property bidId if there is only one bid', function () { + const data = JSON.parse(request.data); + expect(data.hasOwnProperty('bidId')).to.be.true; + }) }); describe('interpretResponse', function () { From a088d66b7489a2ce05866dea98553e99eeacc99f Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Mon, 9 Mar 2020 11:02:39 -0400 Subject: [PATCH 119/496] update audigent tests to fix larger test suite issue (#4952) --- test/spec/modules/realTimeModule_spec.js | 62 ++++++++++++------------ 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/test/spec/modules/realTimeModule_spec.js b/test/spec/modules/realTimeModule_spec.js index 89b44333636..27440a3ec23 100644 --- a/test/spec/modules/realTimeModule_spec.js +++ b/test/spec/modules/realTimeModule_spec.js @@ -14,12 +14,12 @@ import { init as audigentInit, setData as setAudigentData } from 'modules/audigentRtdProvider.js'; -import {config} from 'src/config.js'; -import {makeSlot} from '../integration/faker/googletag.js'; +import { config } from 'src/config.js'; +import { makeSlot } from '../integration/faker/googletag.js'; let expect = require('chai').expect; -describe('Real time module', function() { +describe('Real time module', function () { const conf = { 'realTimeData': { 'auctionDelay': 250, @@ -37,8 +37,8 @@ describe('Real time module', function() { } }; - const predictions = - {p: { + const predictions = { + p: { 'browsiAd_2': { 'w': [ '/57778053/Browsi_Demo_Low', @@ -61,31 +61,35 @@ describe('Real time module', function() { 'p': 0.85 } } - }; + }; const audigentSegments = { - audigent_segments: {'a': 1, 'b': 2} + audigent_segments: { 'a': 1, 'b': 2 } } function getAdUnitMock(code = 'adUnit-code') { return { code, - mediaTypes: {banner: {}, native: {}}, + mediaTypes: { banner: {}, native: {} }, sizes: [[300, 200], [300, 600]], - bids: [{bidder: 'sampleBidder', params: {placementId: 'banner-only-bidder'}}] + bids: [{ bidder: 'sampleBidder', params: { placementId: 'banner-only-bidder' } }] }; } function createSlots() { - const slot1 = makeSlot({code: '/57778053/Browsi_Demo_300x250', divId: 'browsiAd_1'}); + const slot1 = makeSlot({ code: '/57778053/Browsi_Demo_300x250', divId: 'browsiAd_1' }); return [slot1]; } - describe('Real time module with browsi provider', function() { + describe('Real time module with browsi provider', function () { afterEach(function () { $$PREBID_GLOBAL$$.requestBids.removeAll(); }); + after(function () { + config.resetConfig(); + }); + it('check module using bidsBackCallback', function () { let adUnits1 = [getAdUnitMock('browsiAd_1')]; let targeting = []; @@ -105,12 +109,10 @@ describe('Real time module', function() { targeting.push(Object.keys(value).toString()); }); }); - } - setTargetsAfterRequestBids(afterBidHook, adUnits1, true); - setTimeout(() => { expect(targeting.indexOf('bv')).to.be.greaterThan(-1); - }, 200); + } + setTargetsAfterRequestBids(afterBidHook, adUnits1, true); }); it('check module using requestBidsHook', function () { @@ -130,16 +132,15 @@ describe('Real time module', function() { targeting.push(Object.keys(value).toString()); }); }); - } - requestBidsHook(afterBidHook, {adUnits: adUnits1}); - setTimeout(() => { + expect(targeting.indexOf('bv')).to.be.greaterThan(-1); dataReceived.adUnits.forEach(unit => { unit.bids.forEach(bid => { expect(bid.realTimeData).to.have.property('bv'); }); }); - }, 200); + } + requestBidsHook(afterBidHook, { adUnits: adUnits1 }); }); it('check object deep merge', function () { @@ -199,17 +200,19 @@ describe('Real time module', function() { }) }); - describe('Real time module with Audigent provider', function() { + describe('Real time module with Audigent provider', function () { + before(function () { + init(config); + audigentInit(config); + config.setConfig(conf); + setAudigentData(audigentSegments); + }); + afterEach(function () { $$PREBID_GLOBAL$$.requestBids.removeAll(); + config.resetConfig(); }); - let targeting = []; - init(config); - audigentInit(config); - config.setConfig(conf); - setAudigentData(audigentSegments); - it('check module using requestBidsHook', function () { let adUnits1 = [getAdUnitMock('audigentAd_1')]; let targeting = []; @@ -227,17 +230,16 @@ describe('Real time module', function() { targeting.push(Object.keys(value).toString()); }); }); - } - requestBidsHook(afterBidHook, {adUnits: adUnits1}); - setTimeout(() => { dataReceived.adUnits.forEach(unit => { unit.bids.forEach(bid => { expect(bid.realTimeData).to.have.property('audigent_segments'); expect(bid.realTimeData.audigent_segments).to.deep.equal(audigentSegments.audigent_segments); }); }); - }, 200); + } + + requestBidsHook(afterBidHook, { adUnits: adUnits1 }); }); }); }); From 60f66c96e51a06374f46e651d30fd691a1d3dff6 Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Tue, 10 Mar 2020 08:12:53 -0400 Subject: [PATCH 120/496] enable no-console eslint rule for project (#4802) * add no-console eslint rule for tests directory * remove console logs from onetag tests * update scope of rule to include src files --- .eslintrc.js | 1 + modules/adxpremiumAnalyticsAdapter.js | 8 ++++---- modules/nobidBidAdapter.js | 2 +- modules/sharethroughBidAdapter.js | 5 +++-- modules/sovrnBidAdapter.js | 6 ++---- src/adapters/analytics/example2.js | 1 + src/adapters/analytics/libraries/example.js | 1 + src/adapters/analytics/libraries/example2.js | 1 + src/utils.js | 1 + test/.eslintrc.js | 2 +- test/mock-server/index.js | 1 + test/spec/modules/onetagBidAdapter_spec.js | 8 ++------ test/spec/modules/tribeosBidAdapter_spec.js | 2 -- test/spec/unit/pbjs_api_spec.js | 2 +- 14 files changed, 20 insertions(+), 21 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 74948bb8bad..c64ab379c52 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -39,6 +39,7 @@ module.exports = { "no-throw-literal": "off", "no-undef": 2, "no-useless-escape": "off", + "no-console": "error" }, "overrides": Object.keys(allowedModules).map((key) => ({ "files": key + "/**/*.js", diff --git a/modules/adxpremiumAnalyticsAdapter.js b/modules/adxpremiumAnalyticsAdapter.js index 201aab1db03..47b401e2bb4 100644 --- a/modules/adxpremiumAnalyticsAdapter.js +++ b/modules/adxpremiumAnalyticsAdapter.js @@ -62,7 +62,7 @@ let googletag = window.googletag || {}; googletag.cmd = googletag.cmd || []; googletag.cmd.push(function() { googletag.pubads().addEventListener('slotRenderEnded', args => { - console.log(Date.now() + ' GOOGLE SLOT: ' + JSON.stringify(args)); + utils.logInfo(Date.now() + ' GOOGLE SLOT: ' + JSON.stringify(args)); }); }); @@ -72,7 +72,7 @@ let bidResponsesMapper = {}; function auctionInit(args) { completeObject.auction_id = args.auctionId; completeObject.publisher_id = adxpremiumAnalyticsAdapter.initOptions.pubId; - try { completeObject.referer = args.bidderRequests[0].refererInfo.referer.split('?')[0]; } catch (e) { console.log(e.message); } + try { completeObject.referer = args.bidderRequests[0].refererInfo.referer.split('?')[0]; } catch (e) { utils.logWarn('Could not parse referer, error details:', e.message); } completeObject.device_type = deviceType(); } function bidRequested(args) { @@ -130,11 +130,11 @@ function sendEvent(completeObject) { let responseEvents = btoa(JSON.stringify(completeObject)); let mutation = `mutation {createEvent(input: {event: {eventData: "${responseEvents}"}}) {event {createTime } } }`; let dataToSend = JSON.stringify({ query: mutation }); - ajax(url, function () { console.log(Date.now() + ' Sending event to adxpremium server.') }, dataToSend, { + ajax(url, function () { utils.logInfo(Date.now() + ' Sending event to adxpremium server.') }, dataToSend, { contentType: 'application/json', method: 'POST' }); - } catch (err) { console.log(err) } + } catch (err) { utils.logError('Could not send event, error details:', err) } } // save the base class function diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index 7fca2d10534..b9408bcf3c0 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -99,7 +99,7 @@ function nobidBuildRequests(bids, bidderRequest) { var height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); return `${width}x${height}`; } catch (e) { - console.error(e); + utils.logWarn('Could not parse screen dimensions, error details:', e); } } var state = {}; diff --git a/modules/sharethroughBidAdapter.js b/modules/sharethroughBidAdapter.js index f687311f461..0d183be05df 100644 --- a/modules/sharethroughBidAdapter.js +++ b/modules/sharethroughBidAdapter.js @@ -1,4 +1,5 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; const VERSION = '3.2.1'; const BIDDER_CODE = 'sharethrough'; @@ -181,7 +182,7 @@ function handleIframe () { window.document.getElementsByTagName('body')[0].appendChild(sfpIframeBusterJs); iframeBusterLoaded = true; } catch (e) { - console.error(e); + utils.logError('Trouble writing frame buster script, error details:', e); } } @@ -199,7 +200,7 @@ function handleIframe () { window.document.getElementsByTagName('body')[0].appendChild(sfpJs); } } catch (e) { - console.error(e); + utils.logError('Trouble writing sfp script, error details:', e); } } } diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js index ee3eba90f04..2566f314018 100644 --- a/modules/sovrnBidAdapter.js +++ b/modules/sovrnBidAdapter.js @@ -107,8 +107,7 @@ export const spec = { options: {contentType: 'text/plain'} } } catch (e) { - console.log('error in build:') - console.log(e) + utils.logError('Could not build bidrequest, error deatils:', e); } }, @@ -143,8 +142,7 @@ export const spec = { } return sovrnBidResponses } catch (e) { - console.log('error in interpret:') - console.log(e) + utils.logError('Could not intrepret bidresponse, error deatils:', e); } }, diff --git a/src/adapters/analytics/example2.js b/src/adapters/analytics/example2.js index 55d34697b8c..eadf994ce36 100644 --- a/src/adapters/analytics/example2.js +++ b/src/adapters/analytics/example2.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import { ajax } from '../../../src/ajax.js'; /** diff --git a/src/adapters/analytics/libraries/example.js b/src/adapters/analytics/libraries/example.js index 55ef2b8ca45..0d758fd5513 100644 --- a/src/adapters/analytics/libraries/example.js +++ b/src/adapters/analytics/libraries/example.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ /** @module example */ window.ExampleAnalyticsGlobalObject = function(hander, type, data) { diff --git a/src/adapters/analytics/libraries/example2.js b/src/adapters/analytics/libraries/example2.js index 913f21177d0..68e814b1417 100644 --- a/src/adapters/analytics/libraries/example2.js +++ b/src/adapters/analytics/libraries/example2.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ /** @module example */ window.ExampleAnalyticsGlobalObject2 = function(hander, type, data) { diff --git a/src/utils.js b/src/utils.js index f2b4a986ca7..3211048b5a8 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import { config } from './config.js'; import clone from 'just-clone'; import find from 'core-js/library/fn/array/find.js'; diff --git a/test/.eslintrc.js b/test/.eslintrc.js index 4cd5a854ac4..842bccd99b1 100644 --- a/test/.eslintrc.js +++ b/test/.eslintrc.js @@ -35,6 +35,6 @@ module.exports = { "no-unused-vars": "off", "no-use-before-define": "off", "no-useless-escape": "off", - "one-var": "off", + "one-var": "off" } }; diff --git a/test/mock-server/index.js b/test/mock-server/index.js index 30ead952fcc..9a97ca5e0a0 100644 --- a/test/mock-server/index.js +++ b/test/mock-server/index.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ const express = require('express'); const argv = require('yargs').argv; const app = module.exports = express(); diff --git a/test/spec/modules/onetagBidAdapter_spec.js b/test/spec/modules/onetagBidAdapter_spec.js index aeea84836bf..791077d15b9 100644 --- a/test/spec/modules/onetagBidAdapter_spec.js +++ b/test/spec/modules/onetagBidAdapter_spec.js @@ -80,18 +80,14 @@ describe('onetag', function () { expect(bid.pubId).to.be.a('string'); } }); - } catch (e) { - console.log('Error while parsing'); - } + } catch (e) {} it('Returns empty data if no valid requests are passed', function () { serverRequest = spec.buildRequests([]); let dataString = serverRequest.data; try { let dataObj = JSON.parse(dataString); expect(dataObj.bids).to.be.an('array').that.is.empty; - } catch (e) { - console.log('Error while parsing'); - } + } catch (e) {} }); it('should send GDPR consent data', function () { let consentString = 'consentString'; diff --git a/test/spec/modules/tribeosBidAdapter_spec.js b/test/spec/modules/tribeosBidAdapter_spec.js index db92fe94e3e..fd7f7087eb7 100644 --- a/test/spec/modules/tribeosBidAdapter_spec.js +++ b/test/spec/modules/tribeosBidAdapter_spec.js @@ -75,8 +75,6 @@ describe('tribeosBidAdapter', function() { expect(bids).to.have.lengthOf(1); let bid = bids[0]; - console.error(JSON.stringify(bid)); - expect(bid.cpm).to.equal(1.1); expect(bid.currency).to.equal('USD'); expect(bid.width).to.equal(300); diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index f0bd4eecdeb..de2fa7a2fe8 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -1457,7 +1457,7 @@ describe('Unit: Prebid Module', function () { try { $$PREBID_GLOBAL$$.requestBids({}); } catch (e) { - console.log(e); + console.log(e); // eslint-disable-line } assert.ok(logMessageSpy.calledWith('No adUnits configured. No bids requested.'), 'expected message was logged'); }); From 5d4c823992c84ef4cf94437e320985b22a0b67f3 Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Tue, 10 Mar 2020 18:01:29 +0530 Subject: [PATCH 121/496] Fix failing code-coverage command (#4892) * replace karma-coverage-istanbul-reporter with karma-coverage * remove unused variable * create coverage folder when required * merge with master to fix issue of all unit tests not running * update processKillTimeout to 10secs * change reporter type html to lcov --- gulpfile.js | 2 +- karma.conf.maker.js | 26 ++- package-lock.json | 465 +++++++++++++++++++++++++------------------- package.json | 13 +- 4 files changed, 284 insertions(+), 222 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index d8b78106777..a3f94cb9b88 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -84,7 +84,7 @@ function viewCoverage(done) { connect.server({ port: coveragePort, - root: 'build/coverage/karma_html', + root: 'build/coverage/lcov-report', livereload: false }); opens('http://' + mylocalhost + ':' + coveragePort); diff --git a/karma.conf.maker.js b/karma.conf.maker.js index 9aa416375b5..2a120151f14 100644 --- a/karma.conf.maker.js +++ b/karma.conf.maker.js @@ -4,7 +4,6 @@ var _ = require('lodash'); var webpackConf = require('./webpack.conf'); -var path = require('path') var karmaConstants = require('karma').constants; function newWebpackConfig(codeCoverage) { @@ -33,7 +32,7 @@ function newWebpackConfig(codeCoverage) { function newPluginsArray(browserstack) { var plugins = [ 'karma-chrome-launcher', - 'karma-coverage-istanbul-reporter', + 'karma-coverage', 'karma-es5-shim', 'karma-mocha', 'karma-chai', @@ -66,18 +65,15 @@ function setReporters(karmaConf, codeCoverage, browserstack) { suppressPassed: true }; } + if (codeCoverage) { - karmaConf.reporters.push('coverage-istanbul'); - karmaConf.coverageIstanbulReporter = { - reports: ['html', 'lcovonly', 'text-summary'], - dir: path.join(__dirname, 'build', 'coverage'), - 'report-config': { - html: { - subdir: 'karma_html', - urlFriendlyName: true, // simply replaces spaces with _ for files/dirs - } - } - } + karmaConf.reporters.push('coverage'); + karmaConf.coverageReporter = { + dir: 'build/coverage', + reporters: [ + { type: 'lcov', subdir: '.' } + ] + }; } } @@ -157,6 +153,7 @@ module.exports = function(codeCoverage, browserstack, watchMode, file) { autoWatch: true, reporters: ['mocha'], + mochaReporter: { showDiff: true, output: 'minimal' @@ -168,7 +165,8 @@ module.exports = function(codeCoverage, browserstack, watchMode, file) { browserDisconnectTimeout: 10000, // default 2000 browserDisconnectTolerance: 1, // default 0 browserNoActivityTimeout: 4 * 60 * 1000, // default 10000 - captureTimeout: 4 * 60 * 1000, // default 60000 + captureTimeout: 4 * 60 * 1000, // default 60000, + processKillTimeout: 10000, // default 2000 plugins: plugins } diff --git a/package-lock.json b/package-lock.json index cd48008ba20..06d14496209 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.8.0-pre", + "version": "3.11.0-pre", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -14,9 +14,9 @@ } }, "@babel/compat-data": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.5.tgz", - "integrity": "sha512-jWYUqQX/ObOhG1UiEkbH5SANsE/8oKXiQWjj7p7xgj9Zmnt//aUvyz4dBkK0HNsS8/cbyC5NmmH87VekW+mXFg==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.6.tgz", + "integrity": "sha512-CurCIKPTkS25Mb8mz267vU95vy+TyUpnctEX2lV33xWNmHAfjruztgiPBbXZRh3xZZy1CYvGx6XfxyTVS+sk7Q==", "dev": true, "requires": { "browserslist": "^4.8.5", @@ -25,18 +25,18 @@ } }, "@babel/core": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz", - "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.7.tgz", + "integrity": "sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", + "@babel/generator": "^7.8.7", "@babel/helpers": "^7.8.4", - "@babel/parser": "^7.8.4", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3", + "@babel/parser": "^7.8.7", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -65,12 +65,12 @@ } }, "@babel/generator": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", - "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.7.tgz", + "integrity": "sha512-DQwjiKJqH4C3qGiyQCAExJHoZssn49JTMJgZ8SANGgVFdkupcUhLOdkAeoC6kmHZCPfoDG5M0b6cFlSN5wW7Ew==", "dev": true, "requires": { - "@babel/types": "^7.8.3", + "@babel/types": "^7.8.7", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -96,35 +96,36 @@ } }, "@babel/helper-call-delegate": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.3.tgz", - "integrity": "sha512-6Q05px0Eb+N4/GTyKPPvnkig7Lylw+QzihMpws9iiZQv7ZImf84ZsZpQH7QoWN4n4tm81SnSzPgHw2qtO0Zf3A==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.7.tgz", + "integrity": "sha512-doAA5LAKhsFCR0LAFIf+r2RSMmC+m8f/oQ+URnUET/rWeEzC0yTRmAGyWkD4sSu3xwbS7MYQ2u+xlt1V5R56KQ==", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.8.3", "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/types": "^7.8.7" } }, "@babel/helper-compilation-targets": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.4.tgz", - "integrity": "sha512-3k3BsKMvPp5bjxgMdrFyq0UaEO48HciVrOVF0+lon8pp95cyJ2ujAh0TrBHNMnJGT2rr0iKOJPFFbSqjDyf/Pg==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz", + "integrity": "sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw==", "dev": true, "requires": { - "@babel/compat-data": "^7.8.4", - "browserslist": "^4.8.5", + "@babel/compat-data": "^7.8.6", + "browserslist": "^4.9.1", "invariant": "^2.2.4", "levenary": "^1.1.1", "semver": "^5.5.0" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.3.tgz", - "integrity": "sha512-Gcsm1OHCUr9o9TcJln57xhWHtdXbA2pgQ58S0Lxlks0WMGNXuki4+GLfX0p+L2ZkINUGZvfkz8rzoqJQSthI+Q==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.6.tgz", + "integrity": "sha512-bPyujWfsHhV/ztUkwGHz/RPV1T1TDEsSZDsN42JPehndA+p1KKTh3npvTadux0ZhCrytx9tvjpWNowKby3tM6A==", "dev": true, "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/helper-regex": "^7.8.3", "regexpu-core": "^4.6.0" } @@ -198,16 +199,17 @@ } }, "@babel/helper-module-transforms": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.3.tgz", - "integrity": "sha512-C7NG6B7vfBa/pwCOshpMbOYUmrYQDfCpVL/JCRu0ek8B5p8kue1+BCXpg2vOYs7w5ACB9GTOBYQ5U6NwrMg+3Q==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.6.tgz", + "integrity": "sha512-RDnGJSR5EFBJjG3deY0NiL0K9TO8SXxS9n/MPsbPK/s9LbQymuLNtlzvDiNS7IpecuL45cMeLVkA+HfmlrnkRg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", "@babel/helper-simple-access": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.8.6", "lodash": "^4.17.13" } }, @@ -249,15 +251,15 @@ } }, "@babel/helper-replace-supers": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz", - "integrity": "sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz", + "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==", "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.8.3", "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.6" } }, "@babel/helper-simple-access": { @@ -314,9 +316,9 @@ } }, "@babel/parser": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", - "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.7.tgz", + "integrity": "sha512-9JWls8WilDXFGxs0phaXAZgpxTZhSk/yOYH2hTHC0X1yC7Z78IJfvR1vJ+rmJKq3I35td2XzXzN6ZLYlna+r/A==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -512,9 +514,9 @@ } }, "@babel/plugin-transform-classes": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.3.tgz", - "integrity": "sha512-SjT0cwFJ+7Rbr1vQsvphAHwUHvSUPmMjMU/0P59G8U2HLFqSa082JO7zkbDNWs9kH/IUqpHI6xWNesGf8haF1w==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.6.tgz", + "integrity": "sha512-k9r8qRay/R6v5aWZkrEclEhKO6mc1CCQr2dLsVHBmOQiMpN6I2bpjX3vgnldUWeEI1GHVNByULVxZ4BdP4Hmdg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", @@ -522,7 +524,7 @@ "@babel/helper-function-name": "^7.8.3", "@babel/helper-optimise-call-expression": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", "@babel/helper-split-export-declaration": "^7.8.3", "globals": "^11.1.0" } @@ -575,9 +577,9 @@ } }, "@babel/plugin-transform-for-of": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.4.tgz", - "integrity": "sha512-iAXNlOWvcYUYoV8YIxwS7TxGRJcxyl8eQCfT+A5j8sKUzRFvJdcyjp97jL2IghWSRDaL2PU2O2tX8Cu9dTBq5A==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.6.tgz", + "integrity": "sha512-M0pw4/1/KI5WAxPsdcUL/w2LJ7o89YHN3yLkzNjg7Yl15GlVGgzHyCU+FMeAxevHGsLVmUqbirlUIKTafPmzdw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" @@ -685,12 +687,12 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.4.tgz", - "integrity": "sha512-IsS3oTxeTsZlE5KqzTbcC2sV0P9pXdec53SU+Yxv7o/6dvGM5AkTotQKhoSffhNgZ/dftsSiOoxy7evCYJXzVA==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.7.tgz", + "integrity": "sha512-brYWaEPTRimOctz2NDA3jnBbDi7SVN2T4wYuu0aqSzxC3nozFZngGaw29CJ9ZPweB7k+iFmZuoG3IVPIcXmD2g==", "dev": true, "requires": { - "@babel/helper-call-delegate": "^7.8.3", + "@babel/helper-call-delegate": "^7.8.7", "@babel/helper-get-function-arity": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3" } @@ -705,12 +707,12 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.3.tgz", - "integrity": "sha512-qt/kcur/FxrQrzFR432FGZznkVAjiyFtCOANjkAKwCbt465L6ZCiUQh2oMYGU3Wo8LRFJxNDFwWn106S5wVUNA==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", + "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", "dev": true, "requires": { - "regenerator-transform": "^0.14.0" + "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { @@ -780,13 +782,13 @@ } }, "@babel/preset-env": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.4.tgz", - "integrity": "sha512-HihCgpr45AnSOHRbS5cWNTINs0TwaR8BS8xIIH+QwiW8cKL0llV91njQMpeMReEPVs+1Ao0x3RLEBLtt1hOq4w==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.7.tgz", + "integrity": "sha512-BYftCVOdAYJk5ASsznKAUl53EMhfBbr8CJ1X+AJLfGPscQkwJFiaV/Wn9DPH/7fzm2v6iRYJKYHSqyynTGw0nw==", "dev": true, "requires": { - "@babel/compat-data": "^7.8.4", - "@babel/helper-compilation-targets": "^7.8.4", + "@babel/compat-data": "^7.8.6", + "@babel/helper-compilation-targets": "^7.8.7", "@babel/helper-module-imports": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-proposal-async-generator-functions": "^7.8.3", @@ -809,13 +811,13 @@ "@babel/plugin-transform-async-to-generator": "^7.8.3", "@babel/plugin-transform-block-scoped-functions": "^7.8.3", "@babel/plugin-transform-block-scoping": "^7.8.3", - "@babel/plugin-transform-classes": "^7.8.3", + "@babel/plugin-transform-classes": "^7.8.6", "@babel/plugin-transform-computed-properties": "^7.8.3", "@babel/plugin-transform-destructuring": "^7.8.3", "@babel/plugin-transform-dotall-regex": "^7.8.3", "@babel/plugin-transform-duplicate-keys": "^7.8.3", "@babel/plugin-transform-exponentiation-operator": "^7.8.3", - "@babel/plugin-transform-for-of": "^7.8.4", + "@babel/plugin-transform-for-of": "^7.8.6", "@babel/plugin-transform-function-name": "^7.8.3", "@babel/plugin-transform-literals": "^7.8.3", "@babel/plugin-transform-member-expression-literals": "^7.8.3", @@ -826,9 +828,9 @@ "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", "@babel/plugin-transform-new-target": "^7.8.3", "@babel/plugin-transform-object-super": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.8.4", + "@babel/plugin-transform-parameters": "^7.8.7", "@babel/plugin-transform-property-literals": "^7.8.3", - "@babel/plugin-transform-regenerator": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.7", "@babel/plugin-transform-reserved-words": "^7.8.3", "@babel/plugin-transform-shorthand-properties": "^7.8.3", "@babel/plugin-transform-spread": "^7.8.3", @@ -836,7 +838,7 @@ "@babel/plugin-transform-template-literals": "^7.8.3", "@babel/plugin-transform-typeof-symbol": "^7.8.4", "@babel/plugin-transform-unicode-regex": "^7.8.3", - "@babel/types": "^7.8.3", + "@babel/types": "^7.8.7", "browserslist": "^4.8.5", "core-js-compat": "^3.6.2", "invariant": "^2.2.2", @@ -844,29 +846,46 @@ "semver": "^5.5.0" } }, + "@babel/runtime": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz", + "integrity": "sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz", + "integrity": "sha512-plpwicqEzfEyTQohIKktWigcLzmNStMGwbOUbykx51/29Z3JOGYldaaNGK7ngNXV+UcoqvIMmloZ48Sr74sd+g==", + "dev": true + } + } + }, "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" } }, "@babel/traverse": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", - "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", + "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", + "@babel/generator": "^7.8.6", "@babel/helper-function-name": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.4", - "@babel/types": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" @@ -890,9 +909,9 @@ } }, "@babel/types": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", - "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", + "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -1203,9 +1222,9 @@ "dev": true }, "@sinonjs/commons": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.0.tgz", - "integrity": "sha512-qbk9AP+cZUsKdW1GJsBpxPKFmCJ0T8swwzVje3qFd+AkQb74Q/tiuzrdfFg8AD2g5HH/XbE/I8Uc1KYHVYWfhg==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", + "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -1238,9 +1257,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", - "integrity": "sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.6.tgz", + "integrity": "sha512-tTnhWszAqvXnhW7m5jQU9PomXSiKXk2sFxpahXvI20SZKu9ylPi8WtIxueZ6ehDWikPT0jeFujMj3X4ZHuf3Tg==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -1270,9 +1289,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.8.tgz", - "integrity": "sha512-yGeB2dHEdvxjP0y4UbRtQaSkXJ9649fYCmIdRoul5kfAoGCwxuCbMhag0k3RPfnuh9kPGm8x89btcfDEXdVWGw==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.9.tgz", + "integrity": "sha512-jEFQ8L1tuvPjOI8lnpaf73oCJe+aoxL6ygqSy6c8LcW98zaC+4mzWuQIRCEvKeCOu+lbqdXcg4Uqmm1S8AP1tw==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -1389,9 +1408,9 @@ }, "dependencies": { "acorn": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", - "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true } } @@ -3398,9 +3417,9 @@ "dev": true }, "browser-process-hrtime": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "dev": true }, "browser-resolve": { @@ -3498,14 +3517,14 @@ } }, "browserslist": { - "version": "4.8.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.7.tgz", - "integrity": "sha512-gFOnZNYBHrEyUML0xr5NJ6edFaaKbTFX9S9kQHlYfCP0Rit/boRIz4G+Avq6/4haEKJXdGGUnoolx+5MWW2BoA==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz", + "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001027", - "electron-to-chromium": "^1.3.349", - "node-releases": "^1.1.49" + "caniuse-lite": "^1.0.30001030", + "electron-to-chromium": "^1.3.363", + "node-releases": "^1.1.50" } }, "browserstack": { @@ -3572,9 +3591,9 @@ } }, "buffer": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz", - "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.5.0.tgz", + "integrity": "sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww==", "dev": true, "requires": { "base64-js": "^1.0.2", @@ -3775,9 +3794,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001027", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001027.tgz", - "integrity": "sha512-7xvKeErvXZFtUItTHgNtLgS9RJpVnwBlWX8jSo/BO8VsF6deszemZSkJJJA1KOKrXuzZH4WALpAJdq5EyfgMLg==", + "version": "1.0.30001033", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001033.tgz", + "integrity": "sha512-8Ibzxee6ibc5q88cM1usPsMpJOG5CTq0s/dKOmlekPbDGKt+UrnOOTPSjQz3kVo6yL7N4SB5xd+FGLHQmbzh6A==", "dev": true }, "capture-exit": { @@ -5312,9 +5331,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.349", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.349.tgz", - "integrity": "sha512-uEb2zs6EJ6OZIqaMsCSliYVgzE/f7/s1fLWqtvRtHg/v5KBF2xds974fUnyatfxIDgkqzQVwFtam5KExqywx0Q==", + "version": "1.3.372", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.372.tgz", + "integrity": "sha512-77a4jYC52OdisHM+Tne7dgWEvQT1FoNu/jYl279pP88ZtG4ZRIPyhQwAKxj6C2rzsyC1OwsOds9JlZtNncSz6g==", "dev": true }, "elliptic": { @@ -5339,9 +5358,9 @@ "dev": true }, "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "dev": true }, "encodeurl": { @@ -6897,7 +6916,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -6918,12 +6938,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6938,17 +6960,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -7065,7 +7090,8 @@ "inherits": { "version": "2.0.4", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -7077,6 +7103,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7091,6 +7118,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7098,12 +7126,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.9.0", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -7122,6 +7152,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -7211,7 +7242,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -7223,6 +7255,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -7308,7 +7341,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -7344,6 +7378,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7363,6 +7398,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7406,12 +7442,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -8693,9 +8731,9 @@ }, "dependencies": { "ajv": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", - "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -8846,9 +8884,9 @@ } }, "hast-util-is-element": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.0.3.tgz", - "integrity": "sha512-C62CVn7jbjp89yOhhy7vrkSaB7Vk906Gtcw/Ihd+Iufnq+2pwOZjdPmpzpKLWJXPJBMDX3wXg4FqmdOayPcewA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.0.4.tgz", + "integrity": "sha512-NFR6ljJRvDcyPP5SbV7MyPBgF47X3BsskLnmw1U34yL+X6YC0MoBx9EyMg8Jtx4FzGH95jw8+c1VPLHaRA0wDQ==", "dev": true }, "hast-util-sanitize": { @@ -8888,9 +8926,9 @@ } }, "hast-util-whitespace": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.3.tgz", - "integrity": "sha512-AlkYiLTTwPOyxZ8axq2/bCwRUPjIPBfrHkXuCR92B38b3lSdU22R5F/Z4DL6a2kxWpekWq1w6Nj48tWat6GeRA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz", + "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==", "dev": true }, "he": { @@ -8942,9 +8980,9 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", "dev": true }, "html-encoding-sniffer": { @@ -9206,9 +9244,9 @@ "dev": true }, "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, "is-absolute": { "version": "1.0.0", @@ -10664,9 +10702,9 @@ "dev": true }, "just-extend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", - "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", + "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", "dev": true }, "karma": { @@ -10755,6 +10793,24 @@ "which": "^1.2.1" } }, + "karma-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.0.1.tgz", + "integrity": "sha512-SnFkHsnLsaXfxkey51rRN9JDLAEKYW2Lb0qOEvcruukk0NkSNDkjobNDZPt9Ni3kIhLZkLtpGOz661hN7OaZvQ==", + "dev": true, + "requires": { + "dateformat": "^1.0.6", + "istanbul": "^0.4.0", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "lodash": "^4.17.11", + "minimatch": "^3.0.0", + "source-map": "^0.5.1" + } + }, "karma-coverage-istanbul-reporter": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-1.4.3.tgz", @@ -11060,13 +11116,13 @@ "dev": true }, "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", "dev": true, "requires": { "big.js": "^5.2.2", - "emojis-list": "^2.0.0", + "emojis-list": "^3.0.0", "json5": "^1.0.1" }, "dependencies": { @@ -11454,9 +11510,9 @@ } }, "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, "make-error-cause": { @@ -11624,9 +11680,9 @@ } }, "mdast-util-to-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.7.tgz", - "integrity": "sha512-P+gdtssCoHOX+eJUrrC30Sixqao86ZPlVjR5NEAoy0U79Pfxb1Y0Gntei0+GrnQD4T04X9xA8tcugp90cSmNow==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", "dev": true }, "mdast-util-toc": { @@ -11648,9 +11704,9 @@ "dev": true }, "github-slugger": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.1.tgz", - "integrity": "sha512-SsZUjg/P03KPzQBt7OxJPasGw6NRO5uOgiZ5RGXVud5iSIZ0eNZeNp5rTwCxtavrRUa/A77j8mePVc5lEvk0KQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.3.0.tgz", + "integrity": "sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q==", "dev": true, "requires": { "emoji-regex": ">=6.0.0 <=6.1.1" @@ -12341,9 +12397,9 @@ } }, "node-releases": { - "version": "1.1.49", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.49.tgz", - "integrity": "sha512-xH8t0LS0disN0mtRCh+eByxFPie+msJUBL/lJDBuap53QGiYPa9joh83K4pCZgWJ+2L4b9h88vCVdXQ60NO2bg==", + "version": "1.1.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.51.tgz", + "integrity": "sha512-1eQEs6HFYY1kMXQPOLzCf7HdjReErmvn85tZESMczdCNVWP3Y7URYLBAyYynuI7yef1zj4HN5q+oB2x67QU0lw==", "dev": true, "requires": { "semver": "^6.3.0" @@ -13286,13 +13342,13 @@ "dev": true }, "prompts": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.0.tgz", - "integrity": "sha512-NfbbPPg/74fT7wk2XYQ7hAIp9zJyZp5Fu19iRbORqqy1BhtrkZ0fPafBU+7bmn8ie69DpT0R6QpJIN2oisYjJg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.1.tgz", + "integrity": "sha512-qIP2lQyCwYbdzcqHIUi2HAxiWixhoM9OdLCWf8txXsapC/X9YdsCoeyRIXE/GP+Q0J37Q7+XN/MFqbUa7IzXNA==", "dev": true, "requires": { "kleur": "^3.0.3", - "sisteransi": "^1.0.3" + "sisteransi": "^1.0.4" } }, "property-information": { @@ -13308,12 +13364,12 @@ "dev": true }, "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", "requires": { "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" + "ipaddr.js": "1.9.1" } }, "prr": { @@ -13496,9 +13552,9 @@ } }, "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "version": "16.13.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.0.tgz", + "integrity": "sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA==", "dev": true }, "read-pkg": { @@ -13642,12 +13698,13 @@ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "regenerator-transform": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", - "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.2.tgz", + "integrity": "sha512-V4+lGplCM/ikqi5/mkkpJ06e9Bujq1NFmNLvsCs56zg3ZbzrnUzAtizZ24TXxtRX/W2jcdScwQCnbL0CICTFkQ==", "dev": true, "requires": { - "private": "^0.1.6" + "@babel/runtime": "^7.8.4", + "private": "^0.1.8" } }, "regex-cache": { @@ -13705,9 +13762,9 @@ "dev": true }, "regjsparser": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.2.tgz", - "integrity": "sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.3.tgz", + "integrity": "sha512-8uZvYbnfAtEm9Ab8NTb3hdLwL4g/LQzEYP7Xs27T96abJCCE2d6r3cPZPQEsLKy0vRSGVNG+/zVGtLr86HQduA==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -14137,9 +14194,9 @@ "dev": true }, "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", + "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", "dev": true, "requires": { "is-promise": "^2.1.0" @@ -15637,9 +15694,9 @@ } }, "uglify-js": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.7.tgz", - "integrity": "sha512-FeSU+hi7ULYy6mn8PKio/tXsdSXN35lm4KgV2asx00kzrLU9Pi3oAslcJT70Jdj7PHX29gGUPOT6+lXGBbemhA==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.8.0.tgz", + "integrity": "sha512-ugNSTT8ierCsDHso2jkBHXYrU8Y5/fY2ZUprfrJUiD7YpuFvV4jODLFmb3h4btQjqr5Nh4TX4XtgDfCU1WdioQ==", "dev": true, "requires": { "commander": "~2.20.3", @@ -15850,9 +15907,9 @@ "dev": true }, "unist-util-position": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.0.4.tgz", - "integrity": "sha512-tWvIbV8goayTjobxDIr4zVTyG+Q7ragMSMeKC3xnPl9xzIc0+she8mxXLM3JVNDDsfARPbCd3XdzkyLdo7fF3g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", + "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", "dev": true }, "unist-util-remove-position": { @@ -16184,15 +16241,15 @@ } }, "vfile-sort": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-2.2.1.tgz", - "integrity": "sha512-5dt7xEhC44h0uRQKhbM2JAe0z/naHphIZlMOygtMBM9Nn0pZdaX5fshhwWit9wvsuP8t/wp43nTDRRErO1WK8g==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-2.2.2.tgz", + "integrity": "sha512-tAyUqD2R1l/7Rn7ixdGkhXLD3zsg+XLAeUDUhXearjfIcpL1Hcsj5hHpCoy/gvfK/Ws61+e972fm0F7up7hfYA==", "dev": true }, "vfile-statistics": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.3.tgz", - "integrity": "sha512-CstaK/ebTz1W3Qp41Bt9Lj/2DmumFsCwC2sKahDNSPh0mPh7/UyMLCoU8ZBX34CRU0d61B4W41yIFsV0NKMZeA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.4.tgz", + "integrity": "sha512-lXhElVO0Rq3frgPvFBwahmed3X03vjPF8OcjKMy8+F1xU/3Q3QU3tKEDp743SFtb74PdF0UWpxPvtOP0GCLheA==", "dev": true }, "vinyl": { @@ -16282,12 +16339,12 @@ "dev": true }, "w3c-hr-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", - "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", "dev": true, "requires": { - "browser-process-hrtime": "^0.1.2" + "browser-process-hrtime": "^1.0.0" } }, "walk": { @@ -16459,9 +16516,9 @@ }, "dependencies": { "ajv": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", - "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -16785,9 +16842,9 @@ }, "dependencies": { "acorn": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", - "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true }, "ejs": { @@ -17037,6 +17094,12 @@ "sha.js": "2.2.6" } }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, "enhanced-resolve": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", diff --git a/package.json b/package.json index 80d6cb75ea5..bbc7cbec772 100755 --- a/package.json +++ b/package.json @@ -24,8 +24,8 @@ "node": ">=8.9.0" }, "devDependencies": { - "@babel/core": "^7.2.2", - "@babel/preset-env": "^7.2.3", + "@babel/core": "^7.8.4", + "@babel/preset-env": "^7.8.4", "ajv": "5.5.2", "babel-loader": "^8.0.5", "chai": "^4.2.0", @@ -33,7 +33,7 @@ "documentation": "^5.2.2", "es5-shim": "^4.5.2", "eslint-config-standard": "^10.2.1", - "eslint-plugin-import": "^2.2.0", + "eslint-plugin-import": "^2.20.1", "eslint-plugin-node": "^5.1.0", "eslint-plugin-prebid": "file:./plugins/eslint", "eslint-plugin-promise": "^3.5.0", @@ -63,9 +63,10 @@ "karma-browserstack-launcher": "^1.3.0", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^2.2.0", + "karma-coverage": "^2.0.1", "karma-coverage-istanbul-reporter": "^1.3.0", "karma-es5-shim": "^0.0.4", - "karma-firefox-launcher": "^1.0.1", + "karma-firefox-launcher": "^1.3.0", "karma-ie-launcher": "^1.0.0", "karma-mocha": "^1.3.0", "karma-mocha-reporter": "^2.2.5", @@ -97,12 +98,12 @@ "babel-plugin-transform-object-assign": "^6.22.0", "core-js": "^2.4.1", "criteo-direct-rsa-validate": "^1.1.0", - "crypto-js": "^3.1.9-1", + "crypto-js": "^3.3.0", "deep-equal": "^1.0.1", "dlv": "1.1.3", "dset": "2.0.1", "express": "^4.15.4", - "fun-hooks": "^0.9.5", + "fun-hooks": "^0.9.8", "jsencrypt": "^3.0.0-rc.1", "just-clone": "^1.0.2" } From 9325d22a2a408c061e4d0a8ac4a55f5e5f0829d9 Mon Sep 17 00:00:00 2001 From: 7XBID00 <52267720+7XBID00@users.noreply.github.com> Date: Wed, 11 Mar 2020 01:26:23 +0700 Subject: [PATCH 122/496] Add 7xbid adapter to compatible with prebid 3.0 (#4908) * 7xbid adapter * fix error when cli build * update to implement prebid 3.0 * remove unneeded code Co-authored-by: Nguyen Le Thinh --- modules/7xbidBidAdapter.js | 159 +++++++++++++++++++++ modules/7xbidBidAdapter.md | 1 - test/spec/modules/7xbidBidAdapter_spec.js | 161 ++++++++++++++++++++++ 3 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 modules/7xbidBidAdapter.js create mode 100644 test/spec/modules/7xbidBidAdapter_spec.js diff --git a/modules/7xbidBidAdapter.js b/modules/7xbidBidAdapter.js new file mode 100644 index 00000000000..b925912a399 --- /dev/null +++ b/modules/7xbidBidAdapter.js @@ -0,0 +1,159 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; + +const BIDDER_CODE = '7xbid'; +const BIDDER_ALIAS = '7xb'; +const ENDPOINT_BANNER = '//bidder.7xbid.com/api/v1/prebid/banner'; +const ENDPOINT_NATIVE = '//bidder.7xbid.com/api/v1/prebid/native'; +const COOKIE_SYNC_URL = '//bidder.7xbid.com/api/v1/cookie/gen'; +const SUPPORTED_MEDIA_TYPES = ['banner', 'native']; +const SUPPORTED_CURRENCIES = ['USD', 'JPY']; +const DEFAULT_CURRENCY = 'JPY'; +const NET_REVENUE = true; + +/** + * updated to support prebid 3.0 - remove utils.getTopWindowUrl() + */ + +const _encodeURIComponent = function(a) { + let b = window.encodeURIComponent(a); + b = b.replace(/'/g, '%27'); + return b; +} + +export const _getUrlVars = function(url) { + var hash; + var myJson = {}; + var hashes = url.slice(url.indexOf('?') + 1).split('&'); + for (var i = 0; i < hashes.length; i++) { + hash = hashes[i].split('='); + myJson[hash[0]] = hash[1]; + } + return myJson; +} + +export const spec = { + code: BIDDER_CODE, + aliases: [BIDDER_ALIAS], // short code + supportedMediaTypes: SUPPORTED_MEDIA_TYPES, + isBidRequestValid: function(bid) { + if (!(bid.params.placementId)) { + return false; + } + + if (bid.params.hasOwnProperty('currency') && + SUPPORTED_CURRENCIES.indexOf(bid.params.currency) === -1) { + utils.logInfo('Invalid currency type, we support only JPY and USD!') + return false; + } + + return true; + }, + /** + * Make a server request from the list of BidRequests. + * + * @param {validBidRequests[]} - an array of bids + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function(validBidRequests, bidderRequest) { + let serverRequests = []; + var refererInfo; + if (bidderRequest && bidderRequest.refererInfo) { + refererInfo = bidderRequest.refererInfo; + } + validBidRequests.forEach((bid, i) => { + let endpoint = ENDPOINT_BANNER + let data = { + 'placementid': bid.params.placementId, + 'cur': bid.params.hasOwnProperty('currency') ? bid.params.currency : DEFAULT_CURRENCY, + 'ua': navigator.userAgent, + 'loc': utils.deepAccess(bidderRequest, 'refererInfo.referer'), + 'topframe': (window.parent === window.self) ? 1 : 0, + 'sw': screen && screen.width, + 'sh': screen && screen.height, + 'cb': Math.floor(Math.random() * 99999999999), + 'tpaf': 1, + 'cks': 1, + 'requestid': bid.bidId + }; + + if (bid.hasOwnProperty('nativeParams')) { + endpoint = ENDPOINT_NATIVE + data.tkf = 1 // return url tracker + data.ad_track = '1' + data.apiv = '1.1.0' + } + + if (refererInfo && refererInfo.referer) { + data.referer = refererInfo.referer; + } else { + data.referer = ''; + } + + serverRequests.push({ + method: 'GET', + url: endpoint, + data: utils.parseQueryStringParameters(data) + }) + }) + + return serverRequests; + }, + interpretResponse: function(serverResponse, request) { + const data = _getUrlVars(request.data) + const successBid = serverResponse.body || {}; + let bidResponses = []; + if (successBid.hasOwnProperty(data.placementid)) { + let bid = successBid[data.placementid] + let bidResponse = { + requestId: bid.requestid, + cpm: bid.price, + creativeId: bid.creativeId, + currency: bid.cur, + netRevenue: NET_REVENUE, + ttl: 700 + }; + + if (bid.hasOwnProperty('title')) { // it is native ad response + bidResponse.mediaType = 'native' + bidResponse.native = { + title: bid.title, + body: bid.description, + cta: bid.cta, + sponsoredBy: bid.advertiser, + clickUrl: _encodeURIComponent(bid.landingURL), + impressionTrackers: bid.trackings, + } + if (bid.screenshots) { + bidResponse.native.image = { + url: bid.screenshots.url, + height: bid.screenshots.height, + width: bid.screenshots.width, + } + } + if (bid.icon) { + bidResponse.native.icon = { + url: bid.icon.url, + height: bid.icon.height, + width: bid.icon.width, + } + } + } else { + bidResponse.ad = bid.adm + bidResponse.width = bid.width + bidResponse.height = bid.height + } + + bidResponses.push(bidResponse); + } + + return bidResponses; + }, + getUserSyncs: function(syncOptions, serverResponses) { + return [{ + type: 'image', + url: COOKIE_SYNC_URL + }]; + } +} +registerBidder(spec); diff --git a/modules/7xbidBidAdapter.md b/modules/7xbidBidAdapter.md index 13a448da992..692428332f0 100644 --- a/modules/7xbidBidAdapter.md +++ b/modules/7xbidBidAdapter.md @@ -24,7 +24,6 @@ Module that connects to 7xbid's demand sources params: { placementId: 1425292, currency: 'USD' - } } ] diff --git a/test/spec/modules/7xbidBidAdapter_spec.js b/test/spec/modules/7xbidBidAdapter_spec.js new file mode 100644 index 00000000000..4f32e96ce93 --- /dev/null +++ b/test/spec/modules/7xbidBidAdapter_spec.js @@ -0,0 +1,161 @@ +import {expect} from 'chai'; +import {spec, _getUrlVars} from 'modules/7xbidBidAdapter'; +import * as utils from 'src/utils'; +import {config} from 'src/config'; + +const BASE_URI = '//bidder.7xbid.com/api/v1/prebid/banner' +const NATIVE_BASE_URI = '//bidder.7xbid.com/api/v1/prebid/native' + +describe('7xbid adapter', function() { + let bidRequests; + let nativeBidRequests; + + beforeEach(function() { + bidRequests = [ + { + bidder: '7xbid', + params: { + placementId: 1425292, + currency: 'USD' + } + } + ] + + nativeBidRequests = [ + { + bidder: '7xbid', + params: { + placementId: 1429695, + currency: 'USD' + }, + nativeParams: { + title: { + required: true, + len: 80 + }, + image: { + required: true, + sizes: [150, 50] + }, + sponsoredBy: { + required: true + } + } + } + ] + }) + describe('isBidRequestValid', function () { + it('valid bid case', function () { + let validBid = { + bidder: '7xbid', + params: { + placementId: 1425292, + currency: 'USD' + } + } + let isValid = spec.isBidRequestValid(validBid); + expect(isValid).to.equal(true); + }); + + it('invalid bid case: placementId is not passed', function() { + let validBid = { + bidder: '7xbid', + params: { + } + } + let isValid = spec.isBidRequestValid(validBid); + expect(isValid).to.equal(false); + }) + + it('invalid bid case: currency is not support', function() { + let validBid = { + bidder: '7xbid', + params: { + placementId: 1108295, + currency: 'AUD' + } + } + let isValid = spec.isBidRequestValid(validBid); + expect(isValid).to.equal(false); + }) + }) + + describe('buildRequests', function () { + it('sends bid request to ENDPOINT via GET', function () { + const request = spec.buildRequests(bidRequests)[0]; + expect(request.url).to.equal(BASE_URI); + expect(request.method).to.equal('GET'); + }); + + it('sends native bid request to ENDPOINT via GET', function () { + const request = spec.buildRequests(nativeBidRequests)[0]; + expect(request.url).to.equal(NATIVE_BASE_URI); + expect(request.method).to.equal('GET'); + }); + + it('buildRequests function should not modify original bidRequests object', function () { + let originalBidRequests = utils.deepClone(bidRequests); + let request = spec.buildRequests(bidRequests); + expect(bidRequests).to.deep.equal(originalBidRequests); + }); + + it('buildRequests function should not modify original nativeBidRequests object', function () { + let originalBidRequests = utils.deepClone(nativeBidRequests); + let request = spec.buildRequests(nativeBidRequests); + expect(nativeBidRequests).to.deep.equal(originalBidRequests); + }); + + it('Request params check', function() { + let request = spec.buildRequests(bidRequests)[0]; + const data = _getUrlVars(request.data) + expect(parseInt(data.placementid)).to.exist.and.to.equal(bidRequests[0].params.placementId); + expect(data.cur).to.exist.and.to.equal(bidRequests[0].params.currency); + }) + + it('Native request params check', function() { + let request = spec.buildRequests(nativeBidRequests)[0]; + const data = _getUrlVars(request.data) + expect(parseInt(data.placementid)).to.exist.and.to.equal(nativeBidRequests[0].params.placementId); + expect(data.cur).to.exist.and.to.equal(nativeBidRequests[0].params.currency); + }) + }) + + describe('interpretResponse', function () { + let response = { + 1425292: + { + 'creativeId': '', + 'cur': 'USD', + 'price': 0.0920, + 'width': 300, + 'height': 250, + 'requestid': '2e42361a6172bf', + 'adm': '' + } + } + + it('should get correct bid response', function () { + let expectedResponse = [ + { + 'requestId': '2e42361a6172bf', + 'cpm': 0.0920, + 'width': 300, + 'height': 250, + 'netRevenue': true, + 'currency': 'USD', + 'creativeId': '', + 'ttl': 700, + 'ad': '' + } + ]; + let request = spec.buildRequests(bidRequests)[0]; + let result = spec.interpretResponse({body: response}, request); + expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); + expect(result[0].cpm).to.not.equal(null); + expect(result[0].creativeId).to.not.equal(null); + expect(result[0].ad).to.not.equal(null); + expect(result[0].currency).to.equal('USD'); + expect(result[0].netRevenue).to.equal(true); + }); + }) +}) From fc8ebec467037ca3a4422dc593e59d9dd329ffad Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Tue, 10 Mar 2020 11:33:16 -0700 Subject: [PATCH 123/496] add import extensions (#4959) Co-authored-by: rmartinez --- test/spec/modules/7xbidBidAdapter_spec.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/spec/modules/7xbidBidAdapter_spec.js b/test/spec/modules/7xbidBidAdapter_spec.js index 4f32e96ce93..bed2c604349 100644 --- a/test/spec/modules/7xbidBidAdapter_spec.js +++ b/test/spec/modules/7xbidBidAdapter_spec.js @@ -1,7 +1,6 @@ import {expect} from 'chai'; -import {spec, _getUrlVars} from 'modules/7xbidBidAdapter'; -import * as utils from 'src/utils'; -import {config} from 'src/config'; +import {spec, _getUrlVars} from 'modules/7xbidBidAdapter.js'; +import * as utils from 'src/utils.js'; const BASE_URI = '//bidder.7xbid.com/api/v1/prebid/banner' const NATIVE_BASE_URI = '//bidder.7xbid.com/api/v1/prebid/native' From f5b0e4ef5067e8db13e787e7c7e37b5a83d4303c Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Tue, 10 Mar 2020 11:48:56 -0700 Subject: [PATCH 124/496] removing the log (#4960) Co-authored-by: rmartinez --- test/spec/unit/pbjs_api_spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index de2fa7a2fe8..cfdd39239d3 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -880,7 +880,6 @@ describe('Unit: Prebid Module', function () { var invokedTargeting = []; - console.log(invokedTargetingMap); Object.getOwnPropertyNames(invokedTargetingMap).map(function (key) { const value = Array.isArray(invokedTargetingMap[key]) ? invokedTargetingMap[key] : [invokedTargetingMap[key]]; // values are always returned as array in googletag invokedTargeting.push([key, value]); From bb015bdecb0caf8238fec5490778e54fb5bcfce1 Mon Sep 17 00:00:00 2001 From: Vedant Seta Date: Wed, 11 Mar 2020 00:21:56 +0530 Subject: [PATCH 125/496] adding user-id support in medianet adapter (#4925) Co-authored-by: Ambuj Gupta --- modules/medianetBidAdapter.js | 35 ++--- test/spec/modules/medianetBidAdapter_spec.js | 141 +++++++++++++++++++ 2 files changed, 155 insertions(+), 21 deletions(-) diff --git a/modules/medianetBidAdapter.js b/modules/medianetBidAdapter.js index 5a7133001bf..f68f263a0d5 100644 --- a/modules/medianetBidAdapter.js +++ b/modules/medianetBidAdapter.js @@ -132,27 +132,20 @@ function getCoordinates(id) { return null; } -function extParams(params, gdpr, uspConsent) { - let ext = { - customer_id: params.cid, - prebid_version: $$PREBID_GLOBAL$$.version - }; - ext.gdpr_applies = !!(gdpr && gdpr.gdprApplies); - if (ext.gdpr_applies) { - ext.gdpr_consent_string = gdpr.consentString || ''; - } - - ext.usp_applies = !!(uspConsent); - if (ext.usp_applies) { - ext.usp_consent_string = uspConsent || ''; - } - +function extParams(params, gdpr, uspConsent, userId) { let windowSize = spec.getWindowSize(); - if (windowSize.w !== -1 && windowSize.h !== -1) { - ext.screen = windowSize; - } - - return ext; + let gdprApplies = !!(gdpr && gdpr.gdprApplies); + let uspApplies = !!(uspConsent); + return Object.assign({}, + { customer_id: params.cid }, + { prebid_version: $$PREBID_GLOBAL$$.version }, + { gdpr_applies: gdprApplies }, + (gdprApplies) && { gdpr_consent_string: gdpr.consentString || '' }, + { usp_applies: uspApplies }, + uspApplies && { usp_consent_string: uspConsent || '' }, + windowSize.w !== -1 && windowSize.h !== -1 && { screen: windowSize }, + userId && { user_id: userId } + ); } function slotParams(bidRequest) { @@ -247,7 +240,7 @@ function normalizeCoordinates(coordinates) { function generatePayload(bidRequests, bidderRequests) { return { site: siteDetails(bidRequests[0].params.site), - ext: extParams(bidRequests[0].params, bidderRequests.gdprConsent, bidderRequests.uspConsent), + ext: extParams(bidRequests[0].params, bidderRequests.gdprConsent, bidderRequests.uspConsent, bidRequests[0].userId), id: bidRequests[0].auctionId, imp: bidRequests.map(request => slotParams(request)), tmax: bidderRequests.timeout || config.getConfig('bidderTimeout') diff --git a/test/spec/modules/medianetBidAdapter_spec.js b/test/spec/modules/medianetBidAdapter_spec.js index 2b331f0e72e..22e2b1117d5 100644 --- a/test/spec/modules/medianetBidAdapter_spec.js +++ b/test/spec/modules/medianetBidAdapter_spec.js @@ -87,6 +87,52 @@ let VALID_BID_REQUEST = [{ 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', 'bidRequestsCount': 1 }], + VALID_BID_REQUEST_WITH_USERID = [{ + 'bidder': 'medianet', + 'params': { + 'crid': 'crid', + 'cid': 'customer_id', + 'site': { + 'page': 'http://media.net/prebidtest', + 'domain': 'media.net', + 'ref': 'http://media.net/prebidtest', + 'isTop': true + } + }, + userId: { + britepoolid: '82efd5e1-816b-4f87-97f8-044f407e2911' + }, + 'adUnitCode': 'div-gpt-ad-1460505748561-0', + 'transactionId': '277b631f-92f5-4844-8b19-ea13c095d3f1', + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250]], + } + }, + 'bidId': '28f8f8130a583e', + 'bidderRequestId': '1e9b1f07797c1c', + 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', + 'bidRequestsCount': 1 + }, { + 'bidder': 'medianet', + 'params': { + 'crid': 'crid', + 'cid': 'customer_id', + 'site': { + 'page': 'http://media.net/prebidtest', + 'domain': 'media.net', + 'ref': 'http://media.net/prebidtest', + 'isTop': true + } + }, + 'adUnitCode': 'div-gpt-ad-1460505748561-123', + 'transactionId': 'c52a5c62-3c2b-4b90-9ff8-ec1487754822', + 'sizes': [[300, 251]], + 'bidId': '3f97ca71b1e5c2', + 'bidderRequestId': '1e9b1f07797c1c', + 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', + 'bidRequestsCount': 1 + }], VALID_BID_REQUEST_INVALID_BIDFLOOR = [{ 'bidder': 'medianet', @@ -503,6 +549,96 @@ let VALID_BID_REQUEST = [{ }], 'tmax': config.getConfig('bidderTimeout') }, + VALID_PAYLOAD_WITH_USERID = { + 'site': { + 'page': 'http://media.net/prebidtest', + 'domain': 'media.net', + 'ref': 'http://media.net/prebidtest', + 'isTop': true + }, + 'ext': { + 'customer_id': 'customer_id', + 'prebid_version': $$PREBID_GLOBAL$$.version, + 'gdpr_applies': false, + 'user_id': { + britepoolid: '82efd5e1-816b-4f87-97f8-044f407e2911' + }, + 'usp_applies': false, + 'screen': { + 'w': 1000, + 'h': 1000 + } + }, + 'id': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', + 'imp': [{ + 'id': '28f8f8130a583e', + 'tagid': 'crid', + 'ext': { + 'dfp_id': 'div-gpt-ad-1460505748561-0', + 'visibility': 1, + 'viewability': 1, + 'coordinates': { + 'top_left': { + x: 50, + y: 50 + }, + 'bottom_right': { + x: 100, + y: 100 + } + }, + 'display_count': 1 + }, + 'banner': [{ + 'w': 300, + 'h': 250 + }], + 'all': { + 'cid': 'customer_id', + 'crid': 'crid', + 'site': { + 'page': 'http://media.net/prebidtest', + 'domain': 'media.net', + 'ref': 'http://media.net/prebidtest', + 'isTop': true + } + } + }, { + 'id': '3f97ca71b1e5c2', + 'tagid': 'crid', + 'ext': { + 'dfp_id': 'div-gpt-ad-1460505748561-123', + 'visibility': 1, + 'viewability': 1, + 'coordinates': { + 'top_left': { + x: 50, + y: 50 + }, + 'bottom_right': { + x: 100, + y: 100 + } + }, + 'display_count': 1 + }, + 'banner': [{ + 'w': 300, + 'h': 251 + }], + 'all': { + 'cid': 'customer_id', + 'crid': 'crid', + 'site': { + 'page': 'http://media.net/prebidtest', + 'domain': 'media.net', + 'ref': 'http://media.net/prebidtest', + 'isTop': true + } + } + }], + 'tmax': config.getConfig('bidderTimeout') + }, VALID_PAYLOAD_WITH_CRID = { 'site': { 'page': 'http://media.net/prebidtest', @@ -1017,6 +1153,11 @@ describe('Media.net bid adapter', function () { expect(JSON.parse(bidreq.data)).to.deep.equal(VALID_PAYLOAD_WITH_CRID); }); + it('should have userid in bid request', function () { + let bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_USERID, VALID_AUCTIONDATA); + expect(JSON.parse(bidReq.data)).to.deep.equal(VALID_PAYLOAD_WITH_USERID); + }); + describe('build requests: when page meta-data is available', () => { beforeEach(() => { spec.clearMnData(); From 79a5f4632235d2eceb20d27cc33d290334e7e894 Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Tue, 10 Mar 2020 12:07:43 -0700 Subject: [PATCH 126/496] added option to url parser to ignore decoding entire url (#4938) * added option to url parser to ignore decoding entire url * add try catch just in case * updated to test Co-authored-by: rmartinez --- modules/rubiconAnalyticsAdapter.js | 16 ++++++---- .../modules/rubiconAnalyticsAdapter_spec.js | 29 +++++++++++++++---- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/modules/rubiconAnalyticsAdapter.js b/modules/rubiconAnalyticsAdapter.js index 939afc42f6d..9bb8a924b98 100644 --- a/modules/rubiconAnalyticsAdapter.js +++ b/modules/rubiconAnalyticsAdapter.js @@ -37,11 +37,14 @@ const cache = { timeouts: {}, }; -let referrerHostname; - -function getHostNameFromReferer(referer) { - referrerHostname = urlLib.parse(referer).hostname; - return referrerHostname; +export function getHostNameFromReferer(referer) { + try { + rubiconAdapter.referrerHostname = urlLib.parse(referer, {noDecodeWholeURL: true}).hostname; + } catch (e) { + utils.logError('Rubicon Analytics: Unable to parse hostname from supplied url: ', referer, e); + rubiconAdapter.referrerHostname = ''; + } + return rubiconAdapter.referrerHostname }; function stringProperties(obj) { @@ -124,7 +127,7 @@ function sendMessage(auctionId, bidWonId) { integration: config.getConfig('rubicon.int_type') || DEFAULT_INTEGRATION, version: '$prebid.version$', referrerUri: referrer, - referrerHostname: referrerHostname || getHostNameFromReferer(referrer) + referrerHostname: rubiconAdapter.referrerHostname || getHostNameFromReferer(referrer) }; const wrapperName = config.getConfig('rubicon.wrapperName'); if (wrapperName) { @@ -269,6 +272,7 @@ function setRubiconAliases(aliasRegistry) { let baseAdapter = adapter({analyticsType: 'endpoint'}); let rubiconAdapter = Object.assign({}, baseAdapter, { + referrerHostname: '', enableAnalytics(config = {}) { let error = false; samplingFactor = 1; diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js index 2ad828ef3e0..1e71a43999d 100644 --- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js +++ b/test/spec/modules/rubiconAnalyticsAdapter_spec.js @@ -1,4 +1,8 @@ -import rubiconAnalyticsAdapter, { SEND_TIMEOUT, parseBidResponse } from 'modules/rubiconAnalyticsAdapter.js'; +import rubiconAnalyticsAdapter, { + SEND_TIMEOUT, + parseBidResponse, + getHostNameFromReferer, +} from 'modules/rubiconAnalyticsAdapter.js'; import CONSTANTS from 'src/constants.json'; import { config } from 'src/config.js'; import { server } from 'test/mocks/xhr.js'; @@ -22,9 +26,8 @@ function validate(message) { } // using es6 "import * as events from 'src/events.js'" causes the events.getEvents stub not to work... -let events = require('src/events'); -let ajax = require('src/ajax'); -let utils = require('src/utils'); +let events = require('src/events.js'); +let utils = require('src/utils.js'); const { EVENTS: { @@ -477,7 +480,6 @@ function performStandardAuction() { describe('rubicon analytics adapter', function () { let sandbox; - let oldScreen; let clock; beforeEach(function () { @@ -487,6 +489,8 @@ describe('rubicon analytics adapter', function () { clock = sandbox.useFakeTimers(1519767013781); + rubiconAnalyticsAdapter.referrerHostname = ''; + config.setConfig({ s2sConfig: { timeout: 1000, @@ -841,4 +845,19 @@ describe('rubicon analytics adapter', function () { rubiconAnalyticsAdapter.disableAnalytics(); }); }); + + it('getHostNameFromReferer correctly grabs hostname from an input URL', function () { + let inputUrl = 'https://www.prebid.org/some/path?pbjs_debug=true'; + expect(getHostNameFromReferer(inputUrl)).to.equal('www.prebid.org'); + inputUrl = 'https://www.prebid.com/some/path?pbjs_debug=true'; + expect(getHostNameFromReferer(inputUrl)).to.equal('www.prebid.com'); + inputUrl = 'https://prebid.org/some/path?pbjs_debug=true'; + expect(getHostNameFromReferer(inputUrl)).to.equal('prebid.org'); + inputUrl = 'http://xn--p8j9a0d9c9a.xn--q9jyb4c/'; + expect(getHostNameFromReferer(inputUrl)).to.equal('xn--p8j9a0d9c9a.xn--q9jyb4c'); + + // not non-UTF char's in query / path which break if noDecodeWholeURL not set + inputUrl = 'https://prebid.org/search_results/%95x%8Em%92%CA/?category=000'; + expect(getHostNameFromReferer(inputUrl)).to.equal('prebid.org'); + }); }); From 8c84e0107a82c13ecf80c835a281579f39486fac Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Tue, 10 Mar 2020 14:22:17 -0700 Subject: [PATCH 127/496] assert string returned not that we break things (#4962) Co-authored-by: rmartinez --- test/spec/modules/rubiconAnalyticsAdapter_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js index 1e71a43999d..1842c29861d 100644 --- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js +++ b/test/spec/modules/rubiconAnalyticsAdapter_spec.js @@ -854,7 +854,7 @@ describe('rubicon analytics adapter', function () { inputUrl = 'https://prebid.org/some/path?pbjs_debug=true'; expect(getHostNameFromReferer(inputUrl)).to.equal('prebid.org'); inputUrl = 'http://xn--p8j9a0d9c9a.xn--q9jyb4c/'; - expect(getHostNameFromReferer(inputUrl)).to.equal('xn--p8j9a0d9c9a.xn--q9jyb4c'); + expect(typeof getHostNameFromReferer(inputUrl)).to.equal('string'); // not non-UTF char's in query / path which break if noDecodeWholeURL not set inputUrl = 'https://prebid.org/search_results/%95x%8Em%92%CA/?category=000'; From 1b62b0b53e816c1ccf04e7320228ded20f9ebf4b Mon Sep 17 00:00:00 2001 From: Index Exchange 3 Prebid Team Date: Tue, 10 Mar 2020 22:26:24 -0400 Subject: [PATCH 128/496] IX Adapter - Increase banner TTL to 300s (#4957) --- modules/ixBidAdapter.js | 2 +- modules/ixBidAdapter.md | 2 +- test/spec/modules/ixBidAdapter_spec.js | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 18e9dc5bddb..fd22a21b94f 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -11,7 +11,7 @@ const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BANNER_ENDPOINT_VERSION = 7.2; const VIDEO_ENDPOINT_VERSION = 8.1; const CENT_TO_DOLLAR_FACTOR = 100; -const BANNER_TIME_TO_LIVE = 35; +const BANNER_TIME_TO_LIVE = 300; const VIDEO_TIME_TO_LIVE = 3600; // 1hr const NET_REVENUE = true; const PRICE_TO_DOLLAR_FACTOR = { diff --git a/modules/ixBidAdapter.md b/modules/ixBidAdapter.md index 5e1e8c1dc29..4335e496efd 100644 --- a/modules/ixBidAdapter.md +++ b/modules/ixBidAdapter.md @@ -365,7 +365,7 @@ to `'ix'` across all ad units that bids are being requested for does not exceed ### Time-To-Live (TTL) -All bids received from IX have a TTL of 35 seconds, after which time they become +Banner bids from IX have a TTL of 300 seconds while video bids have a TTL of 1 hour, after which time they become invalid. If an invalid bid wins, and its associated ad is rendered, it will not count diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js index 4f4c4734205..fe18947b37a 100644 --- a/test/spec/modules/ixBidAdapter_spec.js +++ b/test/spec/modules/ixBidAdapter_spec.js @@ -807,7 +807,7 @@ describe('IndexexchangeAdapter', function () { mediaType: 'banner', ad: '', currency: 'USD', - ttl: 35, + ttl: 300, netRevenue: true, dealId: undefined, meta: { @@ -834,7 +834,7 @@ describe('IndexexchangeAdapter', function () { mediaType: 'banner', ad: '', currency: 'USD', - ttl: 35, + ttl: 300, netRevenue: true, dealId: undefined, meta: { @@ -860,7 +860,7 @@ describe('IndexexchangeAdapter', function () { mediaType: 'banner', ad: '', currency: 'JPY', - ttl: 35, + ttl: 300, netRevenue: true, dealId: undefined, meta: { @@ -887,7 +887,7 @@ describe('IndexexchangeAdapter', function () { mediaType: 'banner', ad: '', currency: 'USD', - ttl: 35, + ttl: 300, netRevenue: true, dealId: 'deal', meta: { From 6113cd97d293033733702c4e91821aee4a7d8411 Mon Sep 17 00:00:00 2001 From: probably-kira Date: Wed, 11 Mar 2020 13:54:25 +0200 Subject: [PATCH 129/496] Lifestreet adapter 3.0 (#4927) * Added adapter without tests * Added readme * Added tests and CCPA support * Cleaned code, fixed tests * reverted examples * Added more tests + CR fixes * Fixed example in lifestreet readme, reverted integration example page * restored permission for page example --- modules/lifestreetBidAdapter.js | 139 +++++++++++ modules/lifestreetBidAdapter.md | 43 +++- .../spec/modules/lifestreetBidAdapter_spec.js | 232 ++++++++++++++++++ 3 files changed, 407 insertions(+), 7 deletions(-) create mode 100644 modules/lifestreetBidAdapter.js create mode 100644 test/spec/modules/lifestreetBidAdapter_spec.js diff --git a/modules/lifestreetBidAdapter.js b/modules/lifestreetBidAdapter.js new file mode 100644 index 00000000000..4317eb8b82e --- /dev/null +++ b/modules/lifestreetBidAdapter.js @@ -0,0 +1,139 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; + +const BIDDER_CODE = 'lifestreet'; +const ADAPTER_VERSION = '$prebid.version$'; + +const urlTemplate = template`https://ads.lfstmedia.com/gate/${'adapter'}/${'slot'}?adkey=${'adkey'}&ad_size=${'ad_size'}&__location=${'location'}&__referrer=${'referrer'}&__wn=${'wn'}&__sf=${'sf'}&__fif=${'fif'}&__if=${'if'}&__stamp=${'stamp'}&__pp=1&__hb=1&_prebid_json=1&__gz=1&deferred_format=vast_2_0,vast_3_0&__hbver=${'hbver'}`; + +/** + * A helper function for template to generate string from boolean + */ +function boolToString(value) { + return value ? '1' : '0'; +} + +/** + * A helper function to form URL from the template + */ +function template(strings, ...keys) { + return function(...values) { + let dict = values[values.length - 1] || {}; + let result = [strings[0]]; + keys.forEach(function(key, i) { + let value = utils.isInteger(key) ? values[key] : dict[key]; + result.push(value, strings[i + 1]); + }); + return result.join(''); + }; +} + +/** + * Creates a bid requests for a given bid. + * + * @param {BidRequest} bid The bid params to use for formatting a request + */ +function formatBidRequest(bid, bidderRequest = {}) { + const {params} = bid; + const {referer} = (bidderRequest.refererInfo || {}); + let url = urlTemplate({ + adapter: 'prebid', + slot: params.slot, + adkey: params.adkey, + ad_size: params.ad_size, + location: referer, + referrer: referer, + wn: boolToString(/fb_http/i.test(window.name)), + sf: boolToString(window['sfAPI'] || window['$sf']), + fif: boolToString(window['inDapIF'] === true), + if: boolToString(window !== window.top), + stamp: new Date().getTime(), + hbver: ADAPTER_VERSION + }); + + if (bidderRequest.gdprConsent) { + if (bidderRequest.gdprConsent.gdprApplies !== undefined) { + const gdpr = '&__gdpr=' + (bidderRequest.gdprConsent.gdprApplies ? '1' : '0'); + url += gdpr; + } + if (bidderRequest.gdprConsent.consentString !== undefined) { + url += `&__consent=${bidderRequest.gdprConsent.consentString}`; + } + } + + // ccpa support + if (bidderRequest.uspConsent) { + url += `&__us_privacy=${bidderRequest.uspConsent}` + } + + return { + method: 'GET', + url: url, + bidId: bid.bidId + }; +} + +function isResponseValid(response) { + return !/^\s*\{\s*"advertisementAvailable"\s*:\s*false/i.test(response.content) && + response.content.indexOf('') === -1 && (typeof response.cpm !== 'undefined') && + response.status === 1; +} + +export const spec = { + code: BIDDER_CODE, + aliases: ['lsm'], + supportedMediaTypes: [BANNER, VIDEO], + + isBidRequestValid: (bid = {}) => { + const {params = {}} = bid; + return !!(params.slot && params.adkey && params.ad_size); + }, + + buildRequests: (validBidRequests, bidderRequest) => { + return validBidRequests.map(bid => { + return formatBidRequest(bid, bidderRequest) + }); + }, + + interpretResponse: (serverResponse, bidRequest) => { + const bidResponses = []; + let response = serverResponse.body; + + if (!isResponseValid(response)) { + return bidResponses; + } + + const bidResponse = { + requestId: bidRequest.bidId, + cpm: response.cpm, + width: response.width, + height: response.height, + creativeId: response.creativeId, + currency: response.currency ? response.currency : 'USD', + netRevenue: response.netRevenue ? response.netRevenue : true, + ttl: response.ttl ? response.ttl : 86400 + }; + + if (response.hasOwnProperty('dealId')) { + bidResponse.dealId = response.dealId; + } + if (response.content_type.indexOf('vast') > -1) { + if (typeof response.vastUrl !== 'undefined') { + bidResponse.vastUrl = response.vastUrl; + } else { + bidResponse.vastXml = response.content; + } + + bidResponse.mediaType = VIDEO; + } else { + bidResponse.ad = response.content; + bidResponse.mediaType = BANNER; + } + + bidResponses.push(bidResponse); + return bidResponses; + } +}; + +registerBidder(spec); diff --git a/modules/lifestreetBidAdapter.md b/modules/lifestreetBidAdapter.md index 58cf4a533a9..a874792d84c 100644 --- a/modules/lifestreetBidAdapter.md +++ b/modules/lifestreetBidAdapter.md @@ -1,22 +1,41 @@ # Overview +``` Module Name: Lifestreet Bid Adapter - Module Type: Lifestreet Adapter - Maintainer: hb.tech@lifestreet.com +``` # Description Module that connects to Lifestreet's demand sources +Values, listed in `ALL_BANNER_SIZES` and `ALL_VIDEO_SIZES` are all the values which our server supports. +For `ad_size`, please use one of that values in following format: `ad_size: WIDTHxHEIGHT` + # Test Parameters ```javascript - var adUnits = [ - // Banner adUnit + const ALL_BANNER_SIZES = [ + [120, 600], [160, 600], [300, 250], [300, 600], [320, 480], + [320, 50], [468, 60], [510, 510], [600, 300], + [720, 300], [728, 90], [760, 740], [768, 1024] + ]; + + const ALL_VIDEO_SIZES = [ + [640, 480], [650, 520], [970, 580] + ] +``` + +# Test Parameters (Banner) +``` + const adUnits = [ { code: 'test-ad', - sizes: [[160, 600]], + mediaTypes: { + banner: { + sizes: [[160, 600]], + } + }, bids: [ { bidder: 'lifestreet', @@ -28,10 +47,20 @@ Module that connects to Lifestreet's demand sources } ] }, - // Video instream adUnit + ]; +``` + +# Test Parameters (Video) +``` + const adUnits = [ { code: 'test-video-ad', - sizes: [[640, 480]], + mediaTypes: { + video: { + playerSize: [[640, 480]], + context: 'instream' + } + }, bids: [ { bidder: 'lifestreet', diff --git a/test/spec/modules/lifestreetBidAdapter_spec.js b/test/spec/modules/lifestreetBidAdapter_spec.js new file mode 100644 index 00000000000..d66727da644 --- /dev/null +++ b/test/spec/modules/lifestreetBidAdapter_spec.js @@ -0,0 +1,232 @@ +import { expect } from 'chai'; +import { BANNER, VIDEO } from 'src/mediaTypes.js'; +import { spec } from 'modules/lifestreetBidAdapter.js'; + +describe('lifestreetBidAdapter', function() { + let bidRequests; + let videoBidRequests; + let bidResponses; + let videoBidResponses; + beforeEach(function() { + bidRequests = [ + { + bidder: 'lifestreet', + params: { + slot: 'slot166704', + adkey: '78c', + ad_size: '160x600' + }, + mediaTypes: { + banner: { + sizes: [ + [160, 600], + [300, 600] + ] + } + }, + sizes: [ + [160, 600], + [300, 600] + ] + } + ]; + + bidResponses = { + body: { + cpm: 0.1, + netRevenue: true, + content_type: 'display_flash', + width: 160, + currency: 'USD', + ttl: 86400, + content: '', - 'price': 0.8, - 'creativeId': '12610997325162499419', - 'exp': 30, - 'cookies': [{ - 'src': 'https://sync.com', - 'type': 'iframe' - }, { - 'src': 'https://sync.com', - 'type': 'img' + results: [{ + 'ad': '', + 'price': 0.8, + 'creativeId': '12610997325162499419', + 'exp': 30, + 'width': 300, + 'height': 250, + 'cookies': [{ + 'src': 'https://sync.com', + 'type': 'iframe' + }, { + 'src': 'https://sync.com', + 'type': 'img' + }] }] } }; @@ -119,30 +124,14 @@ describe('VidazooBidAdapter', function () { it('should build request for each size', function () { const requests = adapter.buildRequests([BID], BIDDER_REQUEST); - expect(requests).to.have.length(2); + expect(requests).to.have.length(1); expect(requests[0]).to.deep.equal({ - method: 'GET', - url: `${URL}/prebid/59db6b3b4ffaa70004f45cdc`, + method: 'POST', + url: `${URL}/prebid/multi/59db6b3b4ffaa70004f45cdc`, data: { - consent: 'consent_string', - width: '300', - height: '250', - url: 'https%3A%2F%2Fwww.greatsite.com', - cb: 1000, - bidFloor: 0.1, - bidId: '2d52001cabd527', - publisherId: '59ac17c192832d0011283fe3', - 'ext.param1': 'loremipsum', - 'ext.param2': 'dolorsitamet', - } - }); - expect(requests[1]).to.deep.equal({ - method: 'GET', - url: `${URL}/prebid/59db6b3b4ffaa70004f45cdc`, - data: { - consent: 'consent_string', - width: '300', - height: '600', + gdprConsent: 'consent_string', + gdpr: 1, + sizes: ['300x250', '300x600'], url: 'https%3A%2F%2Fwww.greatsite.com', cb: 1000, bidFloor: 0.1, @@ -158,6 +147,25 @@ describe('VidazooBidAdapter', function () { sandbox.restore(); }); }); + describe('getUserSyncs', function () { + it('should have valid user sync with iframeEnabled', function () { + const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + + expect(result).to.deep.equal([{ + type: 'iframe', + url: 'https://static.cootlogix.com/basev/sync/user_sync.html' + }]); + }); + + it('should have valid user sync with pixelEnabled', function () { + const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]); + + expect(result).to.deep.equal([{ + 'url': 'https://sync.com', + 'type': 'image' + }]); + }) + }); describe('interpret response', function () { it('should return empty array when there is no response', function () { @@ -193,7 +201,7 @@ describe('VidazooBidAdapter', function () { it('should take default TTL', function () { const serverResponse = utils.deepClone(SERVER_RESPONSE); - delete serverResponse.body.exp; + delete serverResponse.body.results[0].exp; const responses = adapter.interpretResponse(serverResponse, REQUEST); expect(responses).to.have.length(1); expect(responses[0].ttl).to.equal(300); From 95c0d4a31488facf247bbd29db039ff8258d7e8f Mon Sep 17 00:00:00 2001 From: Convergo <61470027+Converge-Digital@users.noreply.github.com> Date: Thu, 2 Apr 2020 18:35:53 +0300 Subject: [PATCH 197/496] Added new Converge Bid Adapter (#5053) * Added new Converge Bid Adapter * Fix JSDoc in Converge Bid Adapter --- modules/convergeBidAdapter.js | 313 +++++++ modules/convergeBidAdapter.md | 57 ++ test/spec/modules/convergeBidAdapter_spec.js | 899 +++++++++++++++++++ 3 files changed, 1269 insertions(+) create mode 100644 modules/convergeBidAdapter.js create mode 100644 modules/convergeBidAdapter.md create mode 100644 test/spec/modules/convergeBidAdapter_spec.js diff --git a/modules/convergeBidAdapter.js b/modules/convergeBidAdapter.js new file mode 100644 index 00000000000..bea3b6cb1ab --- /dev/null +++ b/modules/convergeBidAdapter.js @@ -0,0 +1,313 @@ +import * as utils from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; + +const BIDDER_CODE = 'converge'; +const ENDPOINT_URL = 'https://tech.convergd.com/hb'; +const TIME_TO_LIVE = 360; +const SYNC_URL = 'https://tech.convergd.com/push_sync'; +const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; + +let hasSynced = false; + +const LOG_ERROR_MESS = { + noAuid: 'Bid from response has no auid parameter - ', + noAdm: 'Bid from response has no adm parameter - ', + noBid: 'Array of bid objects is empty', + noPlacementCode: "Can't find in requested bids the bid with auid - ", + emptyUids: 'Uids should be not empty', + emptySeatbid: 'Seatbid array from response has empty item', + emptyResponse: 'Response is empty', + hasEmptySeatbidArray: 'Response has empty seatbid array', + hasNoArrayOfBids: 'Seatbid from response has no array of bid objects - ' +}; +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [ BANNER, VIDEO ], + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function(bid) { + return !!bid.params.uid; + }, + /** + * Make a server request from the list of BidRequests. + * + * @param {BidRequest[]} validBidRequests - an array of bids + * @param {bidderRequest} bidderRequest - bidder request object + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function(validBidRequests, bidderRequest) { + const auids = []; + const bidsMap = {}; + const slotsMapByUid = {}; + const sizeMap = {}; + const bids = validBidRequests || []; + let priceType = 'net'; + let pageKeywords; + let reqId; + + bids.forEach(bid => { + if (bid.params.priceType === 'gross') { + priceType = 'gross'; + } + reqId = bid.bidderRequestId; + const {params: {uid}, adUnitCode} = bid; + auids.push(uid); + const sizesId = utils.parseSizesInput(bid.sizes); + + if (!pageKeywords && !utils.isEmpty(bid.params.keywords)) { + const keywords = utils.transformBidderParamKeywords(bid.params.keywords); + + if (keywords.length > 0) { + keywords.forEach(deleteValues); + } + pageKeywords = keywords; + } + + if (!slotsMapByUid[uid]) { + slotsMapByUid[uid] = {}; + } + const slotsMap = slotsMapByUid[uid]; + if (!slotsMap[adUnitCode]) { + slotsMap[adUnitCode] = {adUnitCode, bids: [bid], parents: []}; + } else { + slotsMap[adUnitCode].bids.push(bid); + } + const slot = slotsMap[adUnitCode]; + + sizesId.forEach((sizeId) => { + sizeMap[sizeId] = true; + if (!bidsMap[uid]) { + bidsMap[uid] = {}; + } + + if (!bidsMap[uid][sizeId]) { + bidsMap[uid][sizeId] = [slot]; + } else { + bidsMap[uid][sizeId].push(slot); + } + slot.parents.push({parent: bidsMap[uid], key: sizeId, uid}); + }); + }); + + const payload = { + pt: priceType, + auids: auids.join(','), + sizes: utils.getKeys(sizeMap).join(','), + r: reqId, + wrapperType: 'Prebid_js', + wrapperVersion: '$prebid.version$' + }; + + if (pageKeywords) { + payload.keywords = JSON.stringify(pageKeywords); + } + + if (bidderRequest) { + if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { + payload.u = bidderRequest.refererInfo.referer; + } + if (bidderRequest.timeout) { + payload.wtimeout = bidderRequest.timeout; + } + if (bidderRequest.gdprConsent) { + if (bidderRequest.gdprConsent.consentString) { + payload.gdpr_consent = bidderRequest.gdprConsent.consentString; + } + payload.gdpr_applies = + (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') + ? Number(bidderRequest.gdprConsent.gdprApplies) : 1; + } + if (bidderRequest.uspConsent) { + payload.us_privacy = bidderRequest.uspConsent; + } + } + + return { + method: 'GET', + url: ENDPOINT_URL, + data: utils.parseQueryStringParameters(payload).replace(/\&$/, ''), + bidsMap: bidsMap, + }; + }, + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @param {*} bidRequest + * @param {Renderer} RendererConst + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function(serverResponse, bidRequest, RendererConst = Renderer) { + serverResponse = serverResponse && serverResponse.body; + const bidResponses = []; + const bidsMap = bidRequest.bidsMap; + const priceType = bidRequest.data.pt; + + let errorMessage; + + if (!serverResponse) errorMessage = LOG_ERROR_MESS.emptyResponse; + else if (serverResponse.seatbid && !serverResponse.seatbid.length) { + errorMessage = LOG_ERROR_MESS.hasEmptySeatbidArray; + } + + if (!errorMessage && serverResponse.seatbid) { + serverResponse.seatbid.forEach(respItem => { + _addBidResponse(_getBidFromResponse(respItem), bidsMap, priceType, bidResponses, RendererConst); + }); + } + if (errorMessage) utils.logError(errorMessage); + return bidResponses; + }, + getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) { + if (!hasSynced && syncOptions.pixelEnabled) { + let params = ''; + + if (gdprConsent && typeof gdprConsent.consentString === 'string') { + if (typeof gdprConsent.gdprApplies === 'boolean') { + params += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; + } else { + params += `&gdpr_consent=${gdprConsent.consentString}`; + } + } + if (uspConsent) { + params += `&us_privacy=${uspConsent}`; + } + + hasSynced = true; + return { + type: 'image', + url: SYNC_URL + params + }; + } + } +}; + +function isPopulatedArray(arr) { + return !!(utils.isArray(arr) && arr.length > 0); +} + +function deleteValues(keyPairObj) { + if (isPopulatedArray(keyPairObj.value) && keyPairObj.value[0] === '') { + delete keyPairObj.value; + } +} + +function _getBidFromResponse(respItem) { + if (!respItem) { + utils.logError(LOG_ERROR_MESS.emptySeatbid); + } else if (!respItem.bid) { + utils.logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem)); + } else if (!respItem.bid[0]) { + utils.logError(LOG_ERROR_MESS.noBid); + } + return respItem && respItem.bid && respItem.bid[0]; +} + +function _addBidResponse(serverBid, bidsMap, priceType, bidResponses, RendererConst) { + if (!serverBid) return; + let errorMessage; + if (!serverBid.auid) errorMessage = LOG_ERROR_MESS.noAuid + JSON.stringify(serverBid); + if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid); + else { + const awaitingBids = bidsMap[serverBid.auid]; + if (awaitingBids) { + const sizeId = `${serverBid.w}x${serverBid.h}`; + if (awaitingBids[sizeId]) { + const slot = awaitingBids[sizeId][0]; + + const bid = slot.bids.shift(); + const bidResponse = { + requestId: bid.bidId, // bid.bidderRequestId, + bidderCode: spec.code, + cpm: serverBid.price, + width: serverBid.w, + height: serverBid.h, + creativeId: serverBid.auid, // bid.bidId, + currency: 'EUR', + netRevenue: priceType !== 'gross', + ttl: TIME_TO_LIVE, + dealId: serverBid.dealid + }; + if (serverBid.content_type === 'video' || (!serverBid.content_type && bid.mediaTypes && bid.mediaTypes.video)) { + bidResponse.vastXml = serverBid.adm; + bidResponse.mediaType = VIDEO; + bidResponse.adResponse = { + content: bidResponse.vastXml + }; + if (!bid.renderer && (!bid.mediaTypes || !bid.mediaTypes.video || bid.mediaTypes.video.context === 'outstream')) { + bidResponse.renderer = createRenderer(bidResponse, { + id: bid.bidId, + url: RENDERER_URL + }, RendererConst); + } + } else { + bidResponse.ad = serverBid.adm; + bidResponse.mediaType = BANNER; + } + + bidResponses.push(bidResponse); + + if (!slot.bids.length) { + slot.parents.forEach(({parent, key, uid}) => { + const index = parent[key].indexOf(slot); + if (index > -1) { + parent[key].splice(index, 1); + } + if (!parent[key].length) { + delete parent[key]; + if (!utils.getKeys(parent).length) { + delete bidsMap[uid]; + } + } + }); + } + } + } else { + errorMessage = LOG_ERROR_MESS.noPlacementCode + serverBid.auid; + } + } + if (errorMessage) { + utils.logError(errorMessage); + } +} + +function outstreamRender (bid) { + bid.renderer.push(() => { + window.ANOutstreamVideo.renderAd({ + targetId: bid.adUnitCode, + adResponse: bid.adResponse + }); + }); +} + +function createRenderer (bid, rendererParams, RendererConst) { + const rendererInst = RendererConst.install({ + id: rendererParams.id, + url: rendererParams.url, + loaded: false + }); + + try { + rendererInst.setRender(outstreamRender); + } catch (err) { + utils.logWarn('Prebid Error calling setRender on renderer', err); + } + + return rendererInst; +} + +export function resetUserSync() { + hasSynced = false; +} + +export function getSyncUrl() { + return SYNC_URL; +} + +registerBidder(spec); diff --git a/modules/convergeBidAdapter.md b/modules/convergeBidAdapter.md new file mode 100644 index 00000000000..ab916a8b3b6 --- /dev/null +++ b/modules/convergeBidAdapter.md @@ -0,0 +1,57 @@ +# Overview + +Module Name: Converge Bidder Adapter +Module Type: Bidder Adapter +Maintainer: support@converge-digital.com + +# Description + +Module that connects to Converge demand source to fetch bids. +Converge Bid Adapter supports Banner and Video (instream and outstream). + +# Test Parameters +``` + var adUnits = [ + { + code: 'test-div', + sizes: [[300, 250]], + bids: [ + { + bidder: "converge", + params: { + uid: '59', + priceType: 'gross' // by default is 'net' + } + } + ] + },{ + code: 'test-div', + sizes: [[728, 90]], + bids: [ + { + bidder: "converge", + params: { + uid: 1, + priceType: 'gross', + keywords: { + brandsafety: ['disaster'], + topic: ['stress', 'fear'] + } + } + } + ] + },{ + code: 'test-div', + sizes: [[640, 360]], + mediaTypes: { video: {} }, + bids: [ + { + bidder: "converge", + params: { + uid: 60 + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/convergeBidAdapter_spec.js b/test/spec/modules/convergeBidAdapter_spec.js new file mode 100644 index 00000000000..e92ed475497 --- /dev/null +++ b/test/spec/modules/convergeBidAdapter_spec.js @@ -0,0 +1,899 @@ +import { expect } from 'chai'; +import { spec, resetUserSync, getSyncUrl } from 'modules/convergeBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; + +describe('ConvergeAdapter', function () { + const adapter = newBidder(spec); + + describe('inherited functions', function () { + it('exists and is a function', function () { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', function () { + let bid = { + 'bidder': 'converge', + 'params': { + 'uid': '1' + }, + 'adUnitCode': 'adunit-code', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when required params are not passed', function () { + let bid = Object.assign({}, bid); + delete bid.params; + bid.params = { + 'uid': 0 + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + function parseRequest(url) { + const res = {}; + url.split('&').forEach((it) => { + const couple = it.split('='); + res[couple[0]] = decodeURIComponent(couple[1]); + }); + return res; + } + + const bidderRequest = { + refererInfo: { + referer: 'https://example.com' + } + }; + const referrer = bidderRequest.refererInfo.referer; + + let bidRequests = [ + { + 'bidder': 'converge', + 'params': { + 'uid': '59' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '59' + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [[728, 90], [300, 250]], + 'bidId': '3150ccb55da321', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '60' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '42dbe3a7168a6a', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + } + ]; + + it('should attach valid params to the tag', function () { + const request = spec.buildRequests([bidRequests[0]], bidderRequest); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload).to.have.property('u', referrer); + expect(payload).to.have.property('pt', 'net'); + expect(payload).to.have.property('auids', '59'); + expect(payload).to.have.property('sizes', '300x250,300x600'); + expect(payload).to.have.property('r', '22edbae2733bf6'); + expect(payload).to.have.property('wrapperType', 'Prebid_js'); + expect(payload).to.have.property('wrapperVersion', '$prebid.version$'); + }); + + it('sizes must not be duplicated', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload).to.have.property('u', referrer); + expect(payload).to.have.property('pt', 'net'); + expect(payload).to.have.property('auids', '59,59,60'); + expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); + expect(payload).to.have.property('r', '22edbae2733bf6'); + }); + + it('pt parameter must be "gross" if params.priceType === "gross"', function () { + bidRequests[1].params.priceType = 'gross'; + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload).to.have.property('u', referrer); + expect(payload).to.have.property('pt', 'gross'); + expect(payload).to.have.property('auids', '59,59,60'); + expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); + expect(payload).to.have.property('r', '22edbae2733bf6'); + delete bidRequests[1].params.priceType; + }); + + it('pt parameter must be "net" or "gross"', function () { + bidRequests[1].params.priceType = 'some'; + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload).to.have.property('u', referrer); + expect(payload).to.have.property('pt', 'net'); + expect(payload).to.have.property('auids', '59,59,60'); + expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); + expect(payload).to.have.property('r', '22edbae2733bf6'); + delete bidRequests[1].params.priceType; + }); + + it('if gdprConsent is present payload must have gdpr params', function () { + const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: true}}, bidderRequest); + const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload).to.have.property('gdpr_consent', 'AAA'); + expect(payload).to.have.property('gdpr_applies', '1'); + }); + + it('if gdprApplies is false gdpr_applies must be 0', function () { + const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: false}}, bidderRequest); + const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload).to.have.property('gdpr_consent', 'AAA'); + expect(payload).to.have.property('gdpr_applies', '0'); + }); + + it('if gdprApplies is undefined gdpr_applies must be 1', function () { + const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA'}}, bidderRequest); + const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload).to.have.property('gdpr_consent', 'AAA'); + expect(payload).to.have.property('gdpr_applies', '1'); + }); + + it('if usPrivacy is present payload must have us_privacy param', function () { + const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); + const request = spec.buildRequests(bidRequests, bidderRequestWithUSP); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload).to.have.property('us_privacy', '1YNN'); + }); + + it('should convert keyword params to proper form and attaches to request', function () { + const bidRequestWithKeywords = [].concat(bidRequests); + bidRequestWithKeywords[1] = Object.assign({}, + bidRequests[1], + { + params: { + uid: '59', + keywords: { + single: 'val', + singleArr: ['val'], + singleArrNum: [5], + multiValMixed: ['value1', 2, 'value3'], + singleValNum: 123, + emptyStr: '', + emptyArr: [''], + badValue: {'foo': 'bar'} // should be dropped + } + } + } + ); + + const request = spec.buildRequests(bidRequestWithKeywords, bidderRequest); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload.keywords).to.be.an('string'); + payload.keywords = JSON.parse(payload.keywords); + + expect(payload.keywords).to.deep.equal([{ + 'key': 'single', + 'value': ['val'] + }, { + 'key': 'singleArr', + 'value': ['val'] + }, { + 'key': 'singleArrNum', + 'value': ['5'] + }, { + 'key': 'multiValMixed', + 'value': ['value1', '2', 'value3'] + }, { + 'key': 'singleValNum', + 'value': ['123'] + }, { + 'key': 'emptyStr' + }, { + 'key': 'emptyArr' + }]); + }); + }); + + describe('interpretResponse', function () { + const responses = [ + {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 59, 'h': 250, 'w': 300}], 'seat': '1'}, + {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 60, 'h': 600, 'w': 300}], 'seat': '1'}, + {'bid': [{'price': 0.15, 'adm': '
test content 3
', 'auid': 59, 'h': 90, 'w': 728}], 'seat': '1'}, + {'bid': [{'price': 0, 'auid': 61, 'h': 250, 'w': 300}], 'seat': '1'}, + {'bid': [{'price': 0, 'adm': '
test content 5
', 'h': 250, 'w': 300}], 'seat': '1'}, + undefined, + {'bid': [], 'seat': '1'}, + {'seat': '1'}, + ]; + + it('should get correct bid response', function () { + const bidRequests = [ + { + 'bidder': 'converge', + 'params': { + 'uid': '59' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '659423fff799cb', + 'bidderRequestId': '5f2009617a7c0a', + 'auctionId': '1cbd2feafe5e8b', + } + ]; + const request = spec.buildRequests(bidRequests); + const expectedResponse = [ + { + 'requestId': '659423fff799cb', + 'cpm': 1.15, + 'creativeId': 59, + 'dealId': undefined, + 'width': 300, + 'height': 250, + 'ad': '
test content 1
', + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'banner', + 'netRevenue': true, + 'ttl': 360, + } + ]; + + const result = spec.interpretResponse({'body': {'seatbid': [responses[0]]}}, request); + expect(result).to.deep.equal(expectedResponse); + }); + + it('should get correct multi bid response', function () { + const bidRequests = [ + { + 'bidder': 'converge', + 'params': { + 'uid': '59' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '300bfeb0d71a5b', + 'bidderRequestId': '2c2bb1972df9a', + 'auctionId': '1fa09aee5c8c99', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '60' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '4dff80cc4ee346', + 'bidderRequestId': '2c2bb1972df9a', + 'auctionId': '1fa09aee5c8c99', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '59' + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [[728, 90]], + 'bidId': '5703af74d0472a', + 'bidderRequestId': '2c2bb1972df9a', + 'auctionId': '1fa09aee5c8c99', + } + ]; + const request = spec.buildRequests(bidRequests); + const expectedResponse = [ + { + 'requestId': '300bfeb0d71a5b', + 'cpm': 1.15, + 'creativeId': 59, + 'dealId': undefined, + 'width': 300, + 'height': 250, + 'ad': '
test content 1
', + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'banner', + 'netRevenue': true, + 'ttl': 360, + }, + { + 'requestId': '4dff80cc4ee346', + 'cpm': 0.5, + 'creativeId': 60, + 'dealId': undefined, + 'width': 300, + 'height': 600, + 'ad': '
test content 2
', + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'banner', + 'netRevenue': true, + 'ttl': 360, + }, + { + 'requestId': '5703af74d0472a', + 'cpm': 0.15, + 'creativeId': 59, + 'dealId': undefined, + 'width': 728, + 'height': 90, + 'ad': '
test content 3
', + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'banner', + 'netRevenue': true, + 'ttl': 360, + } + ]; + + const result = spec.interpretResponse({'body': {'seatbid': responses.slice(0, 3)}}, request); + expect(result).to.deep.equal(expectedResponse); + }); + + it('handles wrong and nobid responses', function () { + const bidRequests = [ + { + 'bidder': 'converge', + 'params': { + 'uid': '61' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '300bfeb0d7190gf', + 'bidderRequestId': '2c2bb1972d23af', + 'auctionId': '1fa09aee5c84d34', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '65' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '300bfeb0d71321', + 'bidderRequestId': '2c2bb1972d23af', + 'auctionId': '1fa09aee5c84d34', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '70' + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [[728, 90]], + 'bidId': '300bfeb0d7183bb', + 'bidderRequestId': '2c2bb1972d23af', + 'auctionId': '1fa09aee5c84d34', + } + ]; + const request = spec.buildRequests(bidRequests); + const result = spec.interpretResponse({'body': {'seatbid': responses.slice(3)}}, request); + expect(result.length).to.equal(0); + }); + + it('complicated case', function () { + const fullResponse = [ + {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 59, 'h': 250, 'w': 300}], 'seat': '1'}, + {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 60, 'h': 600, 'w': 300}], 'seat': '1'}, + {'bid': [{'price': 0.15, 'adm': '
test content 3
', 'auid': 59, 'h': 90, 'w': 728}], 'seat': '1'}, + {'bid': [{'price': 0.15, 'adm': '
test content 4
', 'auid': 59, 'h': 600, 'w': 300}], 'seat': '1'}, + {'bid': [{'price': 0.5, 'adm': '
test content 5
', 'auid': 60, 'h': 600, 'w': 350}], 'seat': '1'}, + ]; + const bidRequests = [ + { + 'bidder': 'converge', + 'params': { + 'uid': '59' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '2164be6358b9', + 'bidderRequestId': '106efe3247', + 'auctionId': '32a1f276cb87cb8', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '59' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '326bde7fbf69', + 'bidderRequestId': '106efe3247', + 'auctionId': '32a1f276cb87cb8', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '60' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '4e111f1b66e4', + 'bidderRequestId': '106efe3247', + 'auctionId': '32a1f276cb87cb8', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '59' + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [[728, 90]], + 'bidId': '26d6f897b516', + 'bidderRequestId': '106efe3247', + 'auctionId': '32a1f276cb87cb8', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '60' + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [[728, 90]], + 'bidId': '1751cd90161', + 'bidderRequestId': '106efe3247', + 'auctionId': '32a1f276cb87cb8', + } + ]; + const request = spec.buildRequests(bidRequests); + const expectedResponse = [ + { + 'requestId': '2164be6358b9', + 'cpm': 1.15, + 'creativeId': 59, + 'dealId': undefined, + 'width': 300, + 'height': 250, + 'ad': '
test content 1
', + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'banner', + 'netRevenue': true, + 'ttl': 360, + }, + { + 'requestId': '4e111f1b66e4', + 'cpm': 0.5, + 'creativeId': 60, + 'dealId': undefined, + 'width': 300, + 'height': 600, + 'ad': '
test content 2
', + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'banner', + 'netRevenue': true, + 'ttl': 360, + }, + { + 'requestId': '26d6f897b516', + 'cpm': 0.15, + 'creativeId': 59, + 'dealId': undefined, + 'width': 728, + 'height': 90, + 'ad': '
test content 3
', + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'banner', + 'netRevenue': true, + 'ttl': 360, + }, + { + 'requestId': '326bde7fbf69', + 'cpm': 0.15, + 'creativeId': 59, + 'dealId': undefined, + 'width': 300, + 'height': 600, + 'ad': '
test content 4
', + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'banner', + 'netRevenue': true, + 'ttl': 360, + } + ]; + + const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); + expect(result).to.deep.equal(expectedResponse); + }); + + it('dublicate uids and sizes in one slot', function () { + const fullResponse = [ + {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 59, 'h': 250, 'w': 300}], 'seat': '1'}, + {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 59, 'h': 250, 'w': 300}], 'seat': '1'}, + ]; + const bidRequests = [ + { + 'bidder': 'converge', + 'params': { + 'uid': '59' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '5126e301f4be', + 'bidderRequestId': '171c5405a390', + 'auctionId': '35bcbc0f7e79c', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '59' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '57b2ebe70e16', + 'bidderRequestId': '171c5405a390', + 'auctionId': '35bcbc0f7e79c', + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '59' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '225fcd44b18c', + 'bidderRequestId': '171c5405a390', + 'auctionId': '35bcbc0f7e79c', + } + ]; + const request = spec.buildRequests(bidRequests); + const expectedResponse = [ + { + 'requestId': '5126e301f4be', + 'cpm': 1.15, + 'creativeId': 59, + 'dealId': undefined, + 'width': 300, + 'height': 250, + 'ad': '
test content 1
', + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'banner', + 'netRevenue': true, + 'ttl': 360, + }, + { + 'requestId': '57b2ebe70e16', + 'cpm': 0.5, + 'creativeId': 59, + 'dealId': undefined, + 'width': 300, + 'height': 250, + 'ad': '
test content 2
', + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'banner', + 'netRevenue': true, + 'ttl': 360, + } + ]; + + const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); + expect(result).to.deep.equal(expectedResponse); + }); + }); + + it('should get correct video bid response', function () { + const bidRequests = [ + { + 'bidder': 'converge', + 'params': { + 'uid': '58' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '57dfefb80eca', + 'bidderRequestId': '20394420a762a2', + 'auctionId': '140132d07b031', + 'mediaTypes': { + 'video': { + 'context': 'instream' + } + } + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '60' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': 'e893c787c22dd', + 'bidderRequestId': '20394420a762a2', + 'auctionId': '140132d07b031', + 'mediaTypes': { + 'video': { + 'context': 'instream' + } + } + } + ]; + const response = [ + {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 58, content_type: 'video', w: 300, h: 600}], 'seat': '2'}, + {'bid': [{'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 60, content_type: 'video'}], 'seat': '2'} + ]; + const request = spec.buildRequests(bidRequests); + const expectedResponse = [ + { + 'requestId': '57dfefb80eca', + 'cpm': 1.15, + 'creativeId': 58, + 'dealId': undefined, + 'width': 300, + 'height': 600, + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'video', + 'netRevenue': true, + 'ttl': 360, + 'vastXml': '\n<\/Ad>\n<\/VAST>', + 'adResponse': { + 'content': '\n<\/Ad>\n<\/VAST>' + } + } + ]; + + const result = spec.interpretResponse({'body': {'seatbid': response}}, request); + expect(result).to.deep.equal(expectedResponse); + }); + + it('should have right renderer in the bid response', function () { + const spySetRenderer = sinon.spy(); + const stubRenderer = { + setRender: spySetRenderer + }; + const spyRendererInstall = sinon.spy(function() { return stubRenderer; }); + const stubRendererConst = { + install: spyRendererInstall + }; + const bidRequests = [ + { + 'bidder': 'converge', + 'params': { + 'uid': '58' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': 'e6e65553fc8', + 'bidderRequestId': '1380f393215dc7', + 'auctionId': '10b8d2f3c697e3', + 'mediaTypes': { + 'video': { + 'context': 'outstream' + } + } + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '60' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': 'c8fdcb3f269f', + 'bidderRequestId': '1380f393215dc7', + 'auctionId': '10b8d2f3c697e3' + }, + { + 'bidder': 'converge', + 'params': { + 'uid': '61' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '1de036c37685', + 'bidderRequestId': '1380f393215dc7', + 'auctionId': '10b8d2f3c697e3', + 'renderer': {} + } + ]; + const response = [ + {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 58, content_type: 'video', w: 300, h: 600}], 'seat': '2'}, + {'bid': [{'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 60, content_type: 'video', w: 300, h: 250}], 'seat': '2'}, + {'bid': [{'price': 1.20, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 61, content_type: 'video', w: 300, h: 250}], 'seat': '2'} + ]; + const request = spec.buildRequests(bidRequests); + const expectedResponse = [ + { + 'requestId': 'e6e65553fc8', + 'cpm': 1.15, + 'creativeId': 58, + 'dealId': undefined, + 'width': 300, + 'height': 600, + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'video', + 'netRevenue': true, + 'ttl': 360, + 'vastXml': '\n<\/Ad>\n<\/VAST>', + 'adResponse': { + 'content': '\n<\/Ad>\n<\/VAST>' + }, + 'renderer': stubRenderer + }, + { + 'requestId': 'c8fdcb3f269f', + 'cpm': 1.00, + 'creativeId': 60, + 'dealId': undefined, + 'width': 300, + 'height': 250, + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'video', + 'netRevenue': true, + 'ttl': 360, + 'vastXml': '\n<\/Ad>\n<\/VAST>', + 'adResponse': { + 'content': '\n<\/Ad>\n<\/VAST>' + }, + 'renderer': stubRenderer + }, + { + 'requestId': '1de036c37685', + 'cpm': 1.20, + 'creativeId': 61, + 'dealId': undefined, + 'width': 300, + 'height': 250, + 'bidderCode': 'converge', + 'currency': 'EUR', + 'mediaType': 'video', + 'netRevenue': true, + 'ttl': 360, + 'vastXml': '\n<\/Ad>\n<\/VAST>', + 'adResponse': { + 'content': '\n<\/Ad>\n<\/VAST>' + } + } + ]; + + const result = spec.interpretResponse({'body': {'seatbid': response}}, request, stubRendererConst); + + expect(spySetRenderer.calledTwice).to.equal(true); + expect(spySetRenderer.getCall(0).args[0]).to.be.a('function'); + expect(spySetRenderer.getCall(1).args[0]).to.be.a('function'); + + expect(spyRendererInstall.calledTwice).to.equal(true); + expect(spyRendererInstall.getCall(0).args[0]).to.deep.equal({ + id: 'e6e65553fc8', + url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', + loaded: false + }); + expect(spyRendererInstall.getCall(1).args[0]).to.deep.equal({ + id: 'c8fdcb3f269f', + url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', + loaded: false + }); + + expect(result).to.deep.equal(expectedResponse); + }); + + describe('user sync', function () { + const syncUrl = getSyncUrl(); + + beforeEach(function () { + resetUserSync(); + }); + + it('should register sync image', function () { + let syncs = spec.getUserSyncs({ + pixelEnabled: true + }); + + expect(syncs).to.deep.equal({type: 'image', url: syncUrl}); + }); + + it('should not register sync image more than once', function () { + let syncs = spec.getUserSyncs({ + pixelEnabled: true + }); + expect(syncs).to.deep.equal({type: 'image', url: syncUrl}); + + // when called again, should still have only been called once + syncs = spec.getUserSyncs(); + expect(syncs).to.equal(undefined); + }); + + it('should pass gdpr params if consent is true', function () { + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { + gdprApplies: true, consentString: 'foo' + })).to.deep.equal({ + type: 'image', url: `${syncUrl}&gdpr=1&gdpr_consent=foo` + }); + }); + + it('should pass gdpr params if consent is false', function () { + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { + gdprApplies: false, consentString: 'foo' + })).to.deep.equal({ + type: 'image', url: `${syncUrl}&gdpr=0&gdpr_consent=foo` + }); + }); + + it('should pass gdpr param gdpr_consent only when gdprApplies is undefined', function () { + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { + consentString: 'foo' + })).to.deep.equal({ + type: 'image', url: `${syncUrl}&gdpr_consent=foo` + }); + }); + + it('should pass no params if gdpr consentString is not defined', function () { + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {})).to.deep.equal({ + type: 'image', url: syncUrl + }); + }); + + it('should pass no params if gdpr consentString is a number', function () { + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { + consentString: 0 + })).to.deep.equal({ + type: 'image', url: syncUrl + }); + }); + + it('should pass no params if gdpr consentString is null', function () { + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { + consentString: null + })).to.deep.equal({ + type: 'image', url: syncUrl + }); + }); + + it('should pass no params if gdpr consentString is a object', function () { + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { + consentString: {} + })).to.deep.equal({ + type: 'image', url: syncUrl + }); + }); + + it('should pass no params if gdpr is not defined', function () { + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, undefined)).to.deep.equal({ + type: 'image', url: syncUrl + }); + }); + + it('should pass usPrivacy param if it is available', function() { + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {}, '1YNN')).to.deep.equal({ + type: 'image', url: `${syncUrl}&us_privacy=1YNN` + }); + }); + }); +}); From 10ea4869ce6bb1b1a00d7ffa85f84fe3ee7c43e1 Mon Sep 17 00:00:00 2001 From: e-volution-tech <61746103+e-volution-tech@users.noreply.github.com> Date: Thu, 2 Apr 2020 19:55:40 +0300 Subject: [PATCH 198/496] e-volution-tech: change file names (#5060) * initial * fix * fix * fix * fix * fix * fix * fix * fix * fix * fixes * navigator check * navigator.language check * fix namings * fix namings --- modules/e_volutionBidAdapter.js | 111 +++++++++ modules/e_volutionBidAdapter.md | 53 ++++ .../spec/modules/e_volutionBidAdapter_spec.js | 235 ++++++++++++++++++ 3 files changed, 399 insertions(+) create mode 100644 modules/e_volutionBidAdapter.js create mode 100644 modules/e_volutionBidAdapter.md create mode 100644 test/spec/modules/e_volutionBidAdapter_spec.js diff --git a/modules/e_volutionBidAdapter.js b/modules/e_volutionBidAdapter.js new file mode 100644 index 00000000000..9fc7035db32 --- /dev/null +++ b/modules/e_volutionBidAdapter.js @@ -0,0 +1,111 @@ +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; + +const BIDDER_CODE = 'e_volution'; +const AD_URL = 'https://service.e-volution.ai/?c=o&m=multi'; +const URL_SYNC = 'https://service.e-volution.ai/?c=o&m=sync'; +const NO_SYNC = true; + +function isBidResponseValid(bid) { + if (!bid.requestId || !bid.cpm || !bid.creativeId || + !bid.ttl || !bid.currency) { + return false; + } + switch (bid.mediaType) { + case BANNER: + return Boolean(bid.width && bid.height && bid.ad); + case VIDEO: + return Boolean(bid.vastUrl); + case NATIVE: + return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); + default: + return false; + } +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + noSync: NO_SYNC, + + isBidRequestValid: (bid) => { + return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId))); + }, + + buildRequests: (validBidRequests = [], bidderRequest) => { + let winTop = window; + let location; + try { + location = new URL(bidderRequest.refererInfo.referer) + winTop = window.top; + } catch (e) { + location = winTop.location; + utils.logMessage(e); + }; + let placements = []; + let request = { + 'deviceWidth': winTop.screen.width, + 'deviceHeight': winTop.screen.height, + 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', + 'secure': 1, + 'host': location.host, + 'page': location.pathname, + 'placements': placements + }; + if (bidderRequest) { + if (bidderRequest.uspConsent) { + request.ccpa = bidderRequest.uspConsent; + } + if (bidderRequest.gdprConsent) { + request.gdpr = bidderRequest.gdprConsent + } + } + const len = validBidRequests.length; + + for (let i = 0; i < len; i++) { + let bid = validBidRequests[i]; + let traff = bid.params.traffic || BANNER + + placements.push({ + placementId: bid.params.placementId, + bidId: bid.bidId, + sizes: bid.mediaTypes && bid.mediaTypes[traff] && bid.mediaTypes[traff].sizes ? bid.mediaTypes[traff].sizes : [], + traffic: traff + }); + if (bid.schain) { + placements.schain = bid.schain; + } + } + return { + method: 'POST', + url: AD_URL, + data: request + }; + }, + + interpretResponse: (serverResponse) => { + let response = []; + for (let i = 0; i < serverResponse.body.length; i++) { + let resItem = serverResponse.body[i]; + if (isBidResponseValid(resItem)) { + response.push(resItem); + } + } + return response; + }, + + getUserSyncs: (syncOptions, serverResponses) => { + if (NO_SYNC) { + return false + } else { + return [{ + type: 'image', + url: URL_SYNC + }]; + } + } + +}; + +registerBidder(spec); diff --git a/modules/e_volutionBidAdapter.md b/modules/e_volutionBidAdapter.md new file mode 100644 index 00000000000..ff5b2860e05 --- /dev/null +++ b/modules/e_volutionBidAdapter.md @@ -0,0 +1,53 @@ +# Overview + +``` +Module Name: e_volution Bidder Adapter +Module Type: Bidder Adapter +``` + +# Description + +Module that connects to e-volution-tech demand sources + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'placementId_0', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [ + { + bidder: 'e_volution', + params: { + placementId: 0, + traffic: 'banner' + } + } + ] + }, + // Will return test vast xml. All video params are stored under placement in publishers UI + { + code: 'placementId_0', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream' + } + }, + bids: [ + { + bidder: 'e_volution', + params: { + placementId: 0, + traffic: 'video' + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/e_volutionBidAdapter_spec.js b/test/spec/modules/e_volutionBidAdapter_spec.js new file mode 100644 index 00000000000..447420616d1 --- /dev/null +++ b/test/spec/modules/e_volutionBidAdapter_spec.js @@ -0,0 +1,235 @@ +import {expect} from 'chai'; +import {spec} from '../../../modules/e_volutionBidAdapter.js'; + +describe('EvolutionTechBidAdapter', function () { + let bid = { + bidId: '23fhj33i987f', + bidder: 'e_volution', + params: { + placementId: 0, + traffic: 'banner' + } + }; + + describe('isBidRequestValid', function () { + it('Should return true if there are bidId, params and placementId parameters present', function () { + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + it('Should return false if at least one of parameters is not present', function () { + delete bid.params.placementId; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests([bid]); + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + it('Returns valid URL', function () { + expect(serverRequest.url).to.equal('https://service.e-volution.ai/?c=o&m=multi'); + }); + it('Returns valid data if array of bids is valid', function () { + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.language).to.be.a('string'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + let placement = data['placements'][0]; + expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes'); + expect(placement.placementId).to.equal(0); + expect(placement.bidId).to.equal('23fhj33i987f'); + expect(placement.traffic).to.equal('banner'); + }); + it('Returns empty data if no valid requests are passed', function () { + serverRequest = spec.buildRequests([]); + let data = serverRequest.data; + expect(data.placements).to.be.an('array').that.is.empty; + }); + }); + describe('interpretResponse', function () { + it('Should interpret banner response', function () { + const banner = { + body: [{ + mediaType: 'banner', + width: 300, + height: 250, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let bannerResponses = spec.interpretResponse(banner); + expect(bannerResponses).to.be.an('array').that.is.not.empty; + let dataItem = bannerResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.width).to.equal(300); + expect(dataItem.height).to.equal(250); + expect(dataItem.ad).to.equal('Test'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret video response', function () { + const video = { + body: [{ + vastUrl: 'test.com', + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let videoResponses = spec.interpretResponse(video); + expect(videoResponses).to.be.an('array').that.is.not.empty; + + let dataItem = videoResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.5); + expect(dataItem.vastUrl).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret native response', function () { + const native = { + body: [{ + mediaType: 'native', + native: { + clickUrl: 'test.com', + title: 'Test', + image: 'test.com', + impressionTrackers: ['test.com'], + }, + ttl: 120, + cpm: 0.4, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let nativeResponses = spec.interpretResponse(native); + expect(nativeResponses).to.be.an('array').that.is.not.empty; + + let dataItem = nativeResponses[0]; + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); + expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.native.clickUrl).to.equal('test.com'); + expect(dataItem.native.title).to.equal('Test'); + expect(dataItem.native.image).to.equal('test.com'); + expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; + expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should return an empty array if invalid banner response is passed', function () { + const invBanner = { + body: [{ + width: 300, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + + let serverResponses = spec.interpretResponse(invBanner); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid video response is passed', function () { + const invVideo = { + body: [{ + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invVideo); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid native response is passed', function () { + const invNative = { + body: [{ + mediaType: 'native', + clickUrl: 'test.com', + title: 'Test', + impressionTrackers: ['test.com'], + ttl: 120, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let serverResponses = spec.interpretResponse(invNative); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid response is passed', function () { + const invalid = { + body: [{ + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invalid); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); + describe('getUserSyncs', function () { + let userSync = spec.getUserSyncs(); + it('Returns valid URL and type', function () { + if (spec.noSync) { + expect(userSync).to.be.equal(false); + } else { + expect(userSync).to.be.an('array').with.lengthOf(1); + expect(userSync[0].type).to.exist; + expect(userSync[0].url).to.exist; + expect(userSync[0].type).to.be.equal('image'); + expect(userSync[0].url).to.be.equal('https://service.e-volution.ai/?c=o&m=sync'); + } + }); + }); +}); From 2b0c8a5d3ef9f77c2a0b7acbb8bc8ec095527704 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 2 Apr 2020 16:38:03 -0400 Subject: [PATCH 199/496] evolution_tech: completing file rename from 5060 (#5068) * evolution_tech: completing file rename from 5060 * removing test cases --- modules/evolution_techBidAdapter.js | 111 --------- modules/evolution_techBidAdapter.md | 53 ---- .../modules/evolution_techBidAdapter_spec.js | 235 ------------------ 3 files changed, 399 deletions(-) delete mode 100644 modules/evolution_techBidAdapter.js delete mode 100644 modules/evolution_techBidAdapter.md delete mode 100644 test/spec/modules/evolution_techBidAdapter_spec.js diff --git a/modules/evolution_techBidAdapter.js b/modules/evolution_techBidAdapter.js deleted file mode 100644 index 9fc7035db32..00000000000 --- a/modules/evolution_techBidAdapter.js +++ /dev/null @@ -1,111 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'e_volution'; -const AD_URL = 'https://service.e-volution.ai/?c=o&m=multi'; -const URL_SYNC = 'https://service.e-volution.ai/?c=o&m=sync'; -const NO_SYNC = true; - -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); - default: - return false; - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - noSync: NO_SYNC, - - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId))); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - let winTop = window; - let location; - try { - location = new URL(bidderRequest.refererInfo.referer) - winTop = window.top; - } catch (e) { - location = winTop.location; - utils.logMessage(e); - }; - let placements = []; - let request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent - } - } - const len = validBidRequests.length; - - for (let i = 0; i < len; i++) { - let bid = validBidRequests[i]; - let traff = bid.params.traffic || BANNER - - placements.push({ - placementId: bid.params.placementId, - bidId: bid.bidId, - sizes: bid.mediaTypes && bid.mediaTypes[traff] && bid.mediaTypes[traff].sizes ? bid.mediaTypes[traff].sizes : [], - traffic: traff - }); - if (bid.schain) { - placements.schain = bid.schain; - } - } - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses) => { - if (NO_SYNC) { - return false - } else { - return [{ - type: 'image', - url: URL_SYNC - }]; - } - } - -}; - -registerBidder(spec); diff --git a/modules/evolution_techBidAdapter.md b/modules/evolution_techBidAdapter.md deleted file mode 100644 index ff5b2860e05..00000000000 --- a/modules/evolution_techBidAdapter.md +++ /dev/null @@ -1,53 +0,0 @@ -# Overview - -``` -Module Name: e_volution Bidder Adapter -Module Type: Bidder Adapter -``` - -# Description - -Module that connects to e-volution-tech demand sources - -# Test Parameters -``` - var adUnits = [ - // Will return static test banner - { - code: 'placementId_0', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: 'e_volution', - params: { - placementId: 0, - traffic: 'banner' - } - } - ] - }, - // Will return test vast xml. All video params are stored under placement in publishers UI - { - code: 'placementId_0', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - bids: [ - { - bidder: 'e_volution', - params: { - placementId: 0, - traffic: 'video' - } - } - ] - } - ]; -``` diff --git a/test/spec/modules/evolution_techBidAdapter_spec.js b/test/spec/modules/evolution_techBidAdapter_spec.js deleted file mode 100644 index 54e92db4847..00000000000 --- a/test/spec/modules/evolution_techBidAdapter_spec.js +++ /dev/null @@ -1,235 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/evolution_techBidAdapter.js'; - -describe('EvolutionTechBidAdapter', function () { - let bid = { - bidId: '23fhj33i987f', - bidder: 'e_volution', - params: { - placementId: 0, - traffic: 'banner' - } - }; - - describe('isBidRequestValid', function () { - it('Should return true if there are bidId, params and placementId parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false if at least one of parameters is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid]); - it('Creates a ServerRequest object with method, URL and data', function () { - expect(serverRequest).to.exist; - expect(serverRequest.method).to.exist; - expect(serverRequest.url).to.exist; - expect(serverRequest.data).to.exist; - }); - it('Returns POST method', function () { - expect(serverRequest.method).to.equal('POST'); - }); - it('Returns valid URL', function () { - expect(serverRequest.url).to.equal('https://service.e-volution.ai/?c=o&m=multi'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - expect(data.deviceWidth).to.be.a('number'); - expect(data.deviceHeight).to.be.a('number'); - expect(data.language).to.be.a('string'); - expect(data.secure).to.be.within(0, 1); - expect(data.host).to.be.a('string'); - expect(data.page).to.be.a('string'); - let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes'); - expect(placement.placementId).to.equal(0); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal('banner'); - }); - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - describe('interpretResponse', function () { - it('Should interpret banner response', function () { - const banner = { - body: [{ - mediaType: 'banner', - width: 300, - height: 250, - cpm: 0.4, - ad: 'Test', - requestId: '23fhj33i987f', - ttl: 120, - creativeId: '2', - netRevenue: true, - currency: 'USD', - dealId: '1' - }] - }; - let bannerResponses = spec.interpretResponse(banner); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - it('Should interpret video response', function () { - const video = { - body: [{ - vastUrl: 'test.com', - mediaType: 'video', - cpm: 0.5, - requestId: '23fhj33i987f', - ttl: 120, - creativeId: '2', - netRevenue: true, - currency: 'USD', - dealId: '1' - }] - }; - let videoResponses = spec.interpretResponse(video); - expect(videoResponses).to.be.an('array').that.is.not.empty; - - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.5); - expect(dataItem.vastUrl).to.equal('test.com'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - it('Should interpret native response', function () { - const native = { - body: [{ - mediaType: 'native', - native: { - clickUrl: 'test.com', - title: 'Test', - image: 'test.com', - impressionTrackers: ['test.com'], - }, - ttl: 120, - cpm: 0.4, - requestId: '23fhj33i987f', - creativeId: '2', - netRevenue: true, - currency: 'USD', - }] - }; - let nativeResponses = spec.interpretResponse(native); - expect(nativeResponses).to.be.an('array').that.is.not.empty; - - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); - expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.native.clickUrl).to.equal('test.com'); - expect(dataItem.native.title).to.equal('Test'); - expect(dataItem.native.image).to.equal('test.com'); - expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; - expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - it('Should return an empty array if invalid banner response is passed', function () { - const invBanner = { - body: [{ - width: 300, - cpm: 0.4, - ad: 'Test', - requestId: '23fhj33i987f', - ttl: 120, - creativeId: '2', - netRevenue: true, - currency: 'USD', - dealId: '1' - }] - }; - - let serverResponses = spec.interpretResponse(invBanner); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - it('Should return an empty array if invalid video response is passed', function () { - const invVideo = { - body: [{ - mediaType: 'video', - cpm: 0.5, - requestId: '23fhj33i987f', - ttl: 120, - creativeId: '2', - netRevenue: true, - currency: 'USD', - dealId: '1' - }] - }; - let serverResponses = spec.interpretResponse(invVideo); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - it('Should return an empty array if invalid native response is passed', function () { - const invNative = { - body: [{ - mediaType: 'native', - clickUrl: 'test.com', - title: 'Test', - impressionTrackers: ['test.com'], - ttl: 120, - requestId: '23fhj33i987f', - creativeId: '2', - netRevenue: true, - currency: 'USD', - }] - }; - let serverResponses = spec.interpretResponse(invNative); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - it('Should return an empty array if invalid response is passed', function () { - const invalid = { - body: [{ - ttl: 120, - creativeId: '2', - netRevenue: true, - currency: 'USD', - dealId: '1' - }] - }; - let serverResponses = spec.interpretResponse(invalid); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - }); - describe('getUserSyncs', function () { - let userSync = spec.getUserSyncs(); - it('Returns valid URL and type', function () { - if (spec.noSync) { - expect(userSync).to.be.equal(false); - } else { - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.exist; - expect(userSync[0].url).to.exist; - expect(userSync[0].type).to.be.equal('image'); - expect(userSync[0].url).to.be.equal('https://service.e-volution.ai/?c=o&m=sync'); - } - }); - }); -}); From 785aa9fc0d651e491dd29863384297fc22d0d83a Mon Sep 17 00:00:00 2001 From: hybrid-ai <58724131+hybrid-ai@users.noreply.github.com> Date: Fri, 3 Apr 2020 03:34:40 +0300 Subject: [PATCH 200/496] Added Hybrid.ai adapter (#4566) * Added Hybrid.ai adapter * Is used 'find' from 'core-js/library/fn/array/find' instead Array.find * Fixed missing file extensions for imports * Typo fixed * Fixed missing file extensions for imports Co-authored-by: s.shevtsov --- modules/hybridBidAdapter.js | 198 +++++++++++++++ modules/hybridBidAdapter.md | 54 ++++ test/spec/modules/hybridBidAdapter_spec.js | 275 +++++++++++++++++++++ 3 files changed, 527 insertions(+) create mode 100644 modules/hybridBidAdapter.js create mode 100644 modules/hybridBidAdapter.md create mode 100644 test/spec/modules/hybridBidAdapter_spec.js diff --git a/modules/hybridBidAdapter.js b/modules/hybridBidAdapter.js new file mode 100644 index 00000000000..34a4cd9e5d6 --- /dev/null +++ b/modules/hybridBidAdapter.js @@ -0,0 +1,198 @@ +import * as utils from '../src/utils.js' +import { registerBidder } from '../src/adapters/bidderFactory.js' +import { auctionManager } from '../src/auctionManager.js' +import { BANNER, VIDEO } from '../src/mediaTypes.js' +import {Renderer} from '../src/Renderer.js'; +import find from 'core-js/library/fn/array/find'; + +const BIDDER_CODE = 'hybrid'; +const DSP_ENDPOINT = 'https://hbe198.hybrid.ai/prebidhb'; +const TRAFFIC_TYPE_WEB = 1; +const PLACEMENT_TYPE_BANNER = 1; +const PLACEMENT_TYPE_VIDEO = 2; +const TTL = 60; +const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; + +const placementTypes = { + 'banner': PLACEMENT_TYPE_BANNER, + 'video': PLACEMENT_TYPE_VIDEO +}; + +function buildBidRequests(validBidRequests) { + return utils._map(validBidRequests, function(validBidRequest) { + const params = validBidRequest.params; + const bidRequest = { + bidId: validBidRequest.bidId, + transactionId: validBidRequest.transactionId, + sizes: validBidRequest.sizes, + placement: placementTypes[params.placement], + placeId: params.placeId + }; + + return bidRequest; + }) +} + +const outstreamRender = bid => { + bid.renderer.push(() => { + window.ANOutstreamVideo.renderAd({ + sizes: [bid.width, bid.height], + targetId: bid.adUnitCode, + rendererOptions: { + showBigPlayButton: false, + showProgressBar: 'bar', + showVolume: false, + allowFullscreen: true, + skippable: false, + content: bid.vastXml + } + }); + }); +} + +const createRenderer = (bid) => { + const renderer = Renderer.install({ + targetId: bid.adUnitCode, + url: RENDERER_URL, + loaded: false + }); + + try { + renderer.setRender(outstreamRender); + } catch (err) { + utils.logWarn('Prebid Error calling setRender on renderer', err); + } + + return renderer; +} + +function buildBid(bidData) { + const bid = { + requestId: bidData.bidId, + cpm: bidData.price, + width: bidData.width, + height: bidData.height, + creativeId: bidData.bidId, + currency: bidData.currency, + netRevenue: true, + ttl: TTL + }; + + if (bidData.placement === PLACEMENT_TYPE_VIDEO) { + bid.vastXml = bidData.content; + bid.mediaType = VIDEO; + + let adUnit = find(auctionManager.getAdUnits(), function (unit) { + return unit.transactionId === bidData.transactionId; + }); + + if (adUnit) { + bid.width = adUnit.mediaTypes.video.playerSize[0][0]; + bid.height = adUnit.mediaTypes.video.playerSize[0][1]; + + if (adUnit.mediaTypes.video.context === 'outstream') { + bid.renderer = createRenderer(bid); + } + } + } else { + bid.ad = bidData.content; + bid.mediaType = BANNER; + } + + return bid; +} + +function getMediaTypeFromBid(bid) { + return bid.mediaTypes && Object.keys(bid.mediaTypes)[0] +} + +function hasVideoMandatoryParams(mediaTypes) { + const isHasVideoContext = !!mediaTypes.video && (mediaTypes.video.context === 'instream' || mediaTypes.video.context === 'outstream'); + + const isPlayerSize = + !!utils.deepAccess(mediaTypes, 'video.playerSize') && + utils.isArray(utils.deepAccess(mediaTypes, 'video.playerSize')); + + return isHasVideoContext && isPlayerSize; +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], + placementTypes: placementTypes, + + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid(bid) { + return ( + !!bid.params.placeId && + !!bid.params.placement && + ( + (getMediaTypeFromBid(bid) === BANNER && bid.params.placement === 'banner') || + (getMediaTypeFromBid(bid) === VIDEO && bid.params.placement === 'video' && hasVideoMandatoryParams(bid.mediaTypes)) + ) + ); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @param {validBidRequests[]} - an array of bids + * @return ServerRequest Info describing the request to the server. + */ + buildRequests(validBidRequests, bidderRequest) { + const payload = { + url: bidderRequest.refererInfo.referer, + cmp: !!bidderRequest.gdprConsent, + trafficType: TRAFFIC_TYPE_WEB, + bidRequests: buildBidRequests(validBidRequests) + }; + + if (payload.cmp) { + const gdprApplies = bidderRequest.gdprConsent.gdprApplies; + if (gdprApplies !== undefined) payload['ga'] = gdprApplies; + payload['cs'] = bidderRequest.gdprConsent.consentString; + } + + const payloadString = JSON.stringify(payload); + return { + method: 'POST', + url: DSP_ENDPOINT, + data: payloadString, + options: { + contentType: 'application/json' + } + } + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {ServerResponse} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function(serverResponse, bidRequest) { + let bidRequests = JSON.parse(bidRequest.data).bidRequests; + const serverBody = serverResponse.body; + + if (serverBody && serverBody.bids && utils.isArray(serverBody.bids)) { + return utils._map(serverBody.bids, function(bid) { + let rawBid = find(bidRequests, function (item) { + return item.bidId === bid.bidId; + }); + bid.placement = rawBid.placement; + bid.transactionId = rawBid.transactionId; + bid.placeId = rawBid.placeId; + return buildBid(bid); + }); + } else { + return []; + } + } + +} +registerBidder(spec); diff --git a/modules/hybridBidAdapter.md b/modules/hybridBidAdapter.md new file mode 100644 index 00000000000..245f010970a --- /dev/null +++ b/modules/hybridBidAdapter.md @@ -0,0 +1,54 @@ +# Overview + + +**Module Name**: Hybrid.ai Bidder Adapter +**Module Type**: Bidder Adapter +**Maintainer**: prebid@hybrid.ai + +# Description + +You can use this adapter to get a bid from Hybrid.ai + +About us: https://hybrid.ai + +## Sample Banner Ad Unit + +```js +var adUnits = [{ + code: 'banner_ad_unit', + mediaTypes: { + banner: { + sizes: [[728, 90]] + } + }, + bids: [{ + bidder: "hybrid", + params: { + placement: "banner", // required + placeId: "5af45ad34d506ee7acad0c26" // required + } + }] +}]; +``` + +## Sample Video Ad Unit + +```js +var adUnits = [{ + code: 'video_ad_unit', + mediaTypes: { + video: { + context: 'outstream', // required + playerSize: [640, 480] // required + } + }, + bids: [{ + bidder: 'hybrid', + params: { + placement: "video", // required + placeId: "5af45ad34d506ee7acad0c26" // required + } + }] +}]; +``` + diff --git a/test/spec/modules/hybridBidAdapter_spec.js b/test/spec/modules/hybridBidAdapter_spec.js new file mode 100644 index 00000000000..e5ad878c9b1 --- /dev/null +++ b/test/spec/modules/hybridBidAdapter_spec.js @@ -0,0 +1,275 @@ +import { expect } from 'chai' +import { spec } from 'modules/hybridBidAdapter.js' + +function getSlotConfigs(mediaTypes, params) { + return { + params: params, + sizes: [], + bidId: '2df8c0733f284e', + bidder: 'hybrid', + mediaTypes: mediaTypes, + transactionId: '31a58515-3634-4e90-9c96-f86196db1459' + } +} + +describe('Hybrid.ai Adapter', function() { + const PLACE_ID = '5af45ad34d506ee7acad0c26'; + const bidderRequest = { + refererInfo: { referer: 'referer' } + } + const bannerMandatoryParams = { + placeId: PLACE_ID, + placement: 'banner' + } + const videoMandatoryParams = { + placeId: PLACE_ID, + placement: 'video' + } + const validBidRequests = [ + getSlotConfigs({ banner: {} }, bannerMandatoryParams), + getSlotConfigs({ video: {playerSize: [[640, 480]]} }, videoMandatoryParams) + ] + describe('isBidRequestValid method', function() { + describe('returns true', function() { + describe('when banner slot config has all mandatory params', () => { + describe('and placement has the correct value', function() { + const slotConfig = getSlotConfigs( + { banner: {} }, + { + placeId: PLACE_ID, + placement: 'banner' + } + ) + const isBidRequestValid = spec.isBidRequestValid(slotConfig) + expect(isBidRequestValid).to.equal(true) + }) + describe('when video slot has all mandatory params.', function() { + it('should return true, when video mediatype object are correct.', function() { + const slotConfig = getSlotConfigs( + { + video: { + context: 'instream', + playerSize: [[640, 480]] + } + }, + { + placeId: PLACE_ID, + placement: 'video' + } + ) + const isBidRequestValid = spec.isBidRequestValid(slotConfig) + expect(isBidRequestValid).to.equal(true) + }) + }) + }) + }) + describe('returns false', function() { + describe('when params are not correct', function() { + function createSlotconfig(params) { + return getSlotConfigs({ banner: {} }, params) + } + it('does not have the placeId.', function() { + const isBidRequestValid = spec.isBidRequestValid( + createSlotconfig({ + placement: 'banner' + }) + ) + expect(isBidRequestValid).to.equal(false) + }) + it('does not have the placement.', function() { + const isBidRequestValid = spec.isBidRequestValid( + createSlotconfig({ + placeId: PLACE_ID + }) + ) + expect(isBidRequestValid).to.equal(false) + }) + it('does not have a the correct placement.', function() { + const isBidRequestValid = spec.isBidRequestValid( + createSlotconfig({ + placeId: PLACE_ID, + placement: 'something' + }) + ) + expect(isBidRequestValid).to.equal(false) + }) + }) + describe('when video mediaType object is not correct.', function() { + function createVideoSlotconfig(mediaType) { + return getSlotConfigs(mediaType, { + placeId: PLACE_ID, + placement: 'video' + }) + } + it('is a void object', function() { + const isBidRequestValid = spec.isBidRequestValid( + createVideoSlotconfig({ video: {} }) + ) + expect(isBidRequestValid).to.equal(false) + }) + it('does not have playerSize.', function() { + const isBidRequestValid = spec.isBidRequestValid( + createVideoSlotconfig({ video: { context: 'instream' } }) + ) + expect(isBidRequestValid).to.equal(false) + }) + it('does not have context', function() { + const isBidRequestValid = spec.isBidRequestValid( + createVideoSlotconfig({ + video: { + playerSize: [[640, 480]] + } + }) + ) + expect(isBidRequestValid).to.equal(false) + }) + }) + }) + }) + it('Url params should be correct ', function() { + const request = spec.buildRequests(validBidRequests, bidderRequest) + expect(request.method).to.equal('POST') + expect(request.url).to.equal('https://hbe198.hybrid.ai/prebidhb') + }) + + describe('buildRequests method', function() { + it('Common data request should be correct', function() { + const request = spec.buildRequests(validBidRequests, bidderRequest) + const data = JSON.parse(request.data) + expect(Array.isArray(data.bidRequests)).to.equal(true) + expect(data.url).to.equal('referer') + data.bidRequests.forEach(bid => { + expect(bid.bidId).to.equal('2df8c0733f284e') + expect(bid.placeId).to.equal(PLACE_ID) + expect(bid.transactionId).to.equal('31a58515-3634-4e90-9c96-f86196db1459') + }) + }) + + describe('GDPR params', function() { + describe('when there are not consent management platform', function() { + it('cmp should be false', function() { + const request = spec.buildRequests(validBidRequests, bidderRequest) + const data = JSON.parse(request.data) + expect(data.cmp).to.equal(false) + }) + }) + describe('when there are consent management platform', function() { + it('cmps should be true and ga should not sended, when gdprApplies is undefined', function() { + bidderRequest['gdprConsent'] = { + gdprApplies: undefined, + consentString: 'consentString' + } + const request = spec.buildRequests(validBidRequests, bidderRequest) + const data = JSON.parse(request.data) + expect(data.cmp).to.equal(true) + expect(Object.keys(data).indexOf('data')).to.equal(-1) + expect(data.cs).to.equal('consentString') + }) + it('cmps should be true and all gdpr parameters should be sended, when there are gdprApplies', function() { + bidderRequest['gdprConsent'] = { + gdprApplies: true, + consentString: 'consentString' + } + const request = spec.buildRequests(validBidRequests, bidderRequest) + const data = JSON.parse(request.data) + expect(data.cmp).to.equal(true) + expect(data.ga).to.equal(true) + expect(data.cs).to.equal('consentString') + }) + }) + }) + + describe('BidRequests params', function() { + const request = spec.buildRequests(validBidRequests, bidderRequest) + const data = JSON.parse(request.data) + const bidRequests = data.bidRequests + it('should request a Banner', function() { + const bannerBid = bidRequests[0] + expect(bannerBid.placement).to.equal(spec.placementTypes[bannerMandatoryParams.placement]) + }) + it('should request a Video', function() { + const bannerBid = bidRequests[1] + expect(bannerBid.placement).to.equal(spec.placementTypes[videoMandatoryParams.placement]) + }) + }) + }) + + describe('interpret response method', function() { + it('should return a void array, when the server response are not correct.', function() { + const request = { data: JSON.stringify({}) } + const serverResponse = { + body: {} + } + const bids = spec.interpretResponse(serverResponse, request) + expect(typeof bids).to.equal('object') + expect(bids.length).to.equal(0) + }) + it('should return a void array, when the server response have not got bids.', function() { + const request = { data: JSON.stringify({}) } + const serverResponse = { body: { bids: [] } } + const bids = spec.interpretResponse(serverResponse, request) + expect(typeof bids).to.equal('object') + expect(bids.length).to.equal(0) + }) + describe('when the server response return a bid', function() { + describe('the bid is a banner', function() { + it('should return a banner bid', function() { + const request = spec.buildRequests([validBidRequests[0]], bidderRequest) + const serverResponse = { + body: { + bids: [ + { + bidId: '2df8c0733f284e', + price: 0.5, + currency: 'USD', + content: 'html', + width: 100, + height: 100 + } + ] + } + } + const bids = spec.interpretResponse(serverResponse, request) + expect(bids.length).to.equal(1) + expect(bids[0].requestId).to.equal('2df8c0733f284e') + expect(bids[0].mediaType).to.equal(spec.supportedMediaTypes[0]) + expect(bids[0].cpm).to.equal(0.5) + expect(bids[0].width).to.equal(100) + expect(bids[0].height).to.equal(100) + expect(bids[0].currency).to.equal('USD') + expect(bids[0].netRevenue).to.equal(true) + expect(typeof bids[0].ad).to.equal('string') + }) + }) + describe('the bid is a video', function() { + it('should return a video bid', function() { + const request = spec.buildRequests([validBidRequests[1]], bidderRequest) + const serverResponse = { + body: { + bids: [ + { + bidId: '2df8c0733f284e', + price: 0.5, + currency: 'USD', + content: 'html', + width: 100, + height: 100 + } + ] + } + } + const bids = spec.interpretResponse(serverResponse, request) + expect(bids.length).to.equal(1) + expect(bids[0].requestId).to.equal('2df8c0733f284e') + expect(bids[0].mediaType).to.equal(spec.supportedMediaTypes[1]) + expect(bids[0].cpm).to.equal(0.5) + expect(bids[0].width).to.equal(100) + expect(bids[0].height).to.equal(100) + expect(bids[0].currency).to.equal('USD') + expect(bids[0].netRevenue).to.equal(true) + expect(typeof bids[0].vastXml).to.equal('string') + }) + }) + }) + }) +}) From 0d4527af4d7aafdb055e3d10c21b53fc87fb1fbb Mon Sep 17 00:00:00 2001 From: Xavier Leune Date: Fri, 3 Apr 2020 09:45:56 +0200 Subject: [PATCH 201/496] Freewheel: Better size detection and allow multiple bid requests (#5065) * Freewheel: Better size detection and allow multiple bid requests * Use declared mediaTypes Co-authored-by: Xavier Leune --- modules/freewheel-sspBidAdapter.js | 124 +++++++++--------- .../modules/freewheel-sspBidAdapter_spec.js | 36 ++--- 2 files changed, 83 insertions(+), 77 deletions(-) diff --git a/modules/freewheel-sspBidAdapter.js b/modules/freewheel-sspBidAdapter.js index 0073e3ae491..34724658631 100644 --- a/modules/freewheel-sspBidAdapter.js +++ b/modules/freewheel-sspBidAdapter.js @@ -1,4 +1,5 @@ import * as utils from '../src/utils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'freewheel-ssp'; @@ -213,7 +214,7 @@ var getOutstreamScript = function(bid) { export const spec = { code: BIDDER_CODE, - supportedMediaTypes: ['banner', 'video'], + supportedMediaTypes: [BANNER, VIDEO], aliases: ['stickyadstv'], // former name for freewheel-ssp /** * Determines whether or not the given bid request is valid. @@ -234,77 +235,82 @@ export const spec = { buildRequests: function(bidRequests, bidderRequest) { // var currency = config.getConfig(currency); - var currentBidRequest = bidRequests[0]; - if (bidRequests.length > 1) { - utils.logMessage('Prebid.JS - freewheel bid adapter: only one ad unit is required.'); - } - - var zone = currentBidRequest.params.zoneId; - var timeInMillis = new Date().getTime(); - var keyCode = hashcode(zone + '' + timeInMillis); - var requestParams = { - reqType: 'AdsSetup', - protocolVersion: '2.0', - zoneId: zone, - componentId: getComponentId(currentBidRequest.params.format), - timestamp: timeInMillis, - pKey: keyCode - }; + let buildRequest = (currentBidRequest, bidderRequest) => { + var zone = currentBidRequest.params.zoneId; + var timeInMillis = new Date().getTime(); + var keyCode = hashcode(zone + '' + timeInMillis); + var requestParams = { + reqType: 'AdsSetup', + protocolVersion: '2.0', + zoneId: zone, + componentId: getComponentId(currentBidRequest.params.format), + timestamp: timeInMillis, + pKey: keyCode + }; - // Add GDPR flag and consent string - if (bidderRequest && bidderRequest.gdprConsent) { - requestParams._fw_gdpr_consent = bidderRequest.gdprConsent.consentString; + // Add GDPR flag and consent string + if (bidderRequest && bidderRequest.gdprConsent) { + requestParams._fw_gdpr_consent = bidderRequest.gdprConsent.consentString; - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { - requestParams._fw_gdpr = bidderRequest.gdprConsent.gdprApplies; + if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { + requestParams._fw_gdpr = bidderRequest.gdprConsent.gdprApplies; + } } - } - if (currentBidRequest.params.gdpr_consented_providers) { - requestParams._fw_gdpr_consented_providers = currentBidRequest.params.gdpr_consented_providers; - } + if (currentBidRequest.params.gdpr_consented_providers) { + requestParams._fw_gdpr_consented_providers = currentBidRequest.params.gdpr_consented_providers; + } - // Add CCPA consent string - if (bidderRequest && bidderRequest.uspConsent) { - requestParams._fw_us_privacy = bidderRequest.uspConsent; - } + // Add CCPA consent string + if (bidderRequest && bidderRequest.uspConsent) { + requestParams._fw_us_privacy = bidderRequest.uspConsent; + } - var vastParams = currentBidRequest.params.vastUrlParams; - if (typeof vastParams === 'object') { - for (var key in vastParams) { - if (vastParams.hasOwnProperty(key)) { - requestParams[key] = vastParams[key]; + var vastParams = currentBidRequest.params.vastUrlParams; + if (typeof vastParams === 'object') { + for (var key in vastParams) { + if (vastParams.hasOwnProperty(key)) { + requestParams[key] = vastParams[key]; + } } } - } - var location = (bidderRequest && bidderRequest.refererInfo) ? bidderRequest.refererInfo.referer : getTopMostWindow().location.href; - if (isValidUrl(location)) { - requestParams.loc = location; - } + var location = (bidderRequest && bidderRequest.refererInfo) ? bidderRequest.refererInfo.referer : getTopMostWindow().location.href; + if (isValidUrl(location)) { + requestParams.loc = location; + } - var playerSize = []; - if (currentBidRequest.mediaTypes.video && currentBidRequest.mediaTypes.video.playerSize) { - // If mediaTypes is video, get size from mediaTypes.video.playerSize per http://prebid.org/blog/pbjs-3 - playerSize = currentBidRequest.mediaTypes.video.playerSize; - } else if (currentBidRequest.mediaTypes.banner.sizes) { - // If mediaTypes is banner, get size from mediaTypes.banner.sizes per http://prebid.org/blog/pbjs-3 - playerSize = getBiggerSizeWithLimit(currentBidRequest.mediaTypes.banner.sizes, currentBidRequest.mediaTypes.banner.minSizeLimit, currentBidRequest.mediaTypes.banner.maxSizeLimit); - } else { - // Backward compatible code, in case size still pass by sizes in bid request - playerSize = getBiggerSize(currentBidRequest.sizes); - } + var playerSize = []; + if (currentBidRequest.mediaTypes.video && currentBidRequest.mediaTypes.video.playerSize) { + // If mediaTypes is video, get size from mediaTypes.video.playerSize per http://prebid.org/blog/pbjs-3 + if (utils.isArray(currentBidRequest.mediaTypes.video.playerSize[0])) { + playerSize = currentBidRequest.mediaTypes.video.playerSize[0]; + } else { + playerSize = currentBidRequest.mediaTypes.video.playerSize; + } + } else if (currentBidRequest.mediaTypes.banner.sizes) { + // If mediaTypes is banner, get size from mediaTypes.banner.sizes per http://prebid.org/blog/pbjs-3 + playerSize = getBiggerSizeWithLimit(currentBidRequest.mediaTypes.banner.sizes, currentBidRequest.mediaTypes.banner.minSizeLimit, currentBidRequest.mediaTypes.banner.maxSizeLimit); + } else { + // Backward compatible code, in case size still pass by sizes in bid request + playerSize = getBiggerSize(currentBidRequest.sizes); + } - if (playerSize[0] > 0 || playerSize[1] > 0) { - requestParams.playerSize = playerSize[0] + 'x' + playerSize[1]; - } + if (playerSize[0] > 0 || playerSize[1] > 0) { + requestParams.playerSize = playerSize[0] + 'x' + playerSize[1]; + } - return { - method: 'GET', - url: FREEWHEEL_ADSSETUP, - data: requestParams, - bidRequest: currentBidRequest + return { + method: 'GET', + url: FREEWHEEL_ADSSETUP, + data: requestParams, + bidRequest: currentBidRequest + }; }; + + return bidRequests.map(function(currentBidRequest) { + return buildRequest(currentBidRequest, bidderRequest); + }); }, /** diff --git a/test/spec/modules/freewheel-sspBidAdapter_spec.js b/test/spec/modules/freewheel-sspBidAdapter_spec.js index 5dc67cc1da6..4b80cce8017 100644 --- a/test/spec/modules/freewheel-sspBidAdapter_spec.js +++ b/test/spec/modules/freewheel-sspBidAdapter_spec.js @@ -103,7 +103,7 @@ describe('freewheelSSP BidAdapter Test', () => { it('should add parameters to the tag', () => { const request = spec.buildRequests(bidRequests); - const payload = request.data; + const payload = request[0].data; expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); @@ -113,8 +113,8 @@ describe('freewheelSSP BidAdapter Test', () => { it('sends bid request to ENDPOINT via GET', () => { const request = spec.buildRequests(bidRequests); - expect(request.url).to.contain(ENDPOINT); - expect(request.method).to.equal('GET'); + expect(request[0].url).to.contain(ENDPOINT); + expect(request[0].method).to.equal('GET'); }); it('should add usp consent to the request', () => { @@ -122,7 +122,7 @@ describe('freewheelSSP BidAdapter Test', () => { let bidderRequest = {}; bidderRequest.uspConsent = uspConsentString; const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; + const payload = request[0].data; expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); @@ -141,7 +141,7 @@ describe('freewheelSSP BidAdapter Test', () => { }; const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; + const payload = request[0].data; expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); @@ -174,7 +174,7 @@ describe('freewheelSSP BidAdapter Test', () => { it('should add parameters to the tag', () => { const request = spec.buildRequests(bidRequests); - const payload = request.data; + const payload = request[0].data; expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); @@ -184,8 +184,8 @@ describe('freewheelSSP BidAdapter Test', () => { it('sends bid request to ENDPOINT via GET', () => { const request = spec.buildRequests(bidRequests); - expect(request.url).to.contain(ENDPOINT); - expect(request.method).to.equal('GET'); + expect(request[0].url).to.contain(ENDPOINT); + expect(request[0].method).to.equal('GET'); }); it('should add usp consent to the request', () => { @@ -193,7 +193,7 @@ describe('freewheelSSP BidAdapter Test', () => { let bidderRequest = {}; bidderRequest.uspConsent = uspConsentString; const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; + const payload = request[0].data; expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); @@ -212,7 +212,7 @@ describe('freewheelSSP BidAdapter Test', () => { }; const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; + const payload = request[0].data; expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); @@ -327,7 +327,7 @@ describe('freewheelSSP BidAdapter Test', () => { } ]; - let result = spec.interpretResponse(response, request); + let result = spec.interpretResponse(response, request[0]); expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); }); @@ -348,15 +348,15 @@ describe('freewheelSSP BidAdapter Test', () => { } ]; - let result = spec.interpretResponse(response, request); + let result = spec.interpretResponse(response, request[0]); expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); }); it('handles nobid responses', () => { - var reqest = spec.buildRequests(formattedBidRequests); + var request = spec.buildRequests(formattedBidRequests); let response = ''; - let result = spec.interpretResponse(response, reqest); + let result = spec.interpretResponse(response, request[0]); expect(result.length).to.equal(0); }); }); @@ -460,7 +460,7 @@ describe('freewheelSSP BidAdapter Test', () => { } ]; - let result = spec.interpretResponse(response, request); + let result = spec.interpretResponse(response, request[0]); expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); }); @@ -483,15 +483,15 @@ describe('freewheelSSP BidAdapter Test', () => { } ]; - let result = spec.interpretResponse(response, request); + let result = spec.interpretResponse(response, request[0]); expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); }); it('handles nobid responses', () => { - var reqest = spec.buildRequests(formattedBidRequests); + var request = spec.buildRequests(formattedBidRequests); let response = ''; - let result = spec.interpretResponse(response, reqest); + let result = spec.interpretResponse(response, request[0]); expect(result.length).to.equal(0); }); }); From 609486bed84cfbb388dbbdaa293a17871c29c9a2 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Fri, 3 Apr 2020 05:08:39 -0700 Subject: [PATCH 202/496] IdentityLink check ats after delaySync (#5070) --- modules/identityLinkIdSystem.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/identityLinkIdSystem.js b/modules/identityLinkIdSystem.js index a5b93a7f0ee..47d8ad9ac05 100644 --- a/modules/identityLinkIdSystem.js +++ b/modules/identityLinkIdSystem.js @@ -42,9 +42,10 @@ export const identityLinkSubmodule = { // use protocol relative urls for http or https const url = `https://api.rlcdn.com/api/identity/envelope?pid=${configParams.pid}${hasGdpr ? '&ct=1&cv=' + gdprConsentString : ''}`; let resp; - // if ats library is initialised, use it to retrieve envelope. If not use standard third party endpoint - if (window.ats) { - resp = function(callback) { + resp = function(callback) { + // Check ats during callback so it has a chance to initialise. + // If ats library is available, use it to retrieve envelope. If not use standard third party endpoint + if (window.ats) { window.ats.retrieveEnvelope(function (envelope) { if (envelope) { callback(JSON.parse(envelope).envelope); @@ -52,15 +53,14 @@ export const identityLinkSubmodule = { getEnvelope(url, callback); } }); - } - } else { - resp = function (callback) { + } else { getEnvelope(url, callback); } - } + }; + return {callback: resp}; } -} +}; // return envelope from third party endpoint function getEnvelope(url, callback) { ajax(url, response => { From 136baaa8939d554b7fec6331a57556e2adc438b4 Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Fri, 3 Apr 2020 19:36:46 +0530 Subject: [PATCH 203/496] User ID auctionDelay timeout bugfix (#4982) * auctiontimeout bugfix * move clearTimeout outside forEach * move setTimout above the function call * increase auctionDelay --- modules/userId/index.js | 8 ++++++-- test/spec/modules/userId_spec.js | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/userId/index.js b/modules/userId/index.js index cad513642a5..4a5c570331f 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -144,6 +144,9 @@ let configRegistry = []; /** @type {Submodule[]} */ let submoduleRegistry = []; +/** @type {(number|undefined)} */ +let timeoutID; + /** @type {(number|undefined)} */ export let syncDelay; @@ -256,6 +259,7 @@ function processSubmoduleCallbacks(submodules, cb) { // clear callback, this prop is used to test if all submodule callbacks are complete below submodule.callback = undefined; }); + clearTimeout(timeoutID); } /** @@ -322,9 +326,9 @@ function initializeSubmodulesAndExecuteCallbacks(continueAuction) { } } utils.logInfo(`${MODULE_NAME} - auction delayed by ${auctionDelay} at most to fetch ids`); - processSubmoduleCallbacks(submodulesWithCallbacks, continueCallback); - setTimeout(continueCallback, auctionDelay); + timeoutID = setTimeout(continueCallback, auctionDelay); + processSubmoduleCallbacks(submodulesWithCallbacks, continueCallback); } else { // wait for auction complete before processing submodule callbacks events.on(CONSTANTS.EVENTS.AUCTION_END, function auctionEndHandler() { diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index 6ff2095665d..41c4841926a 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -419,7 +419,7 @@ describe('User ID', function() { beforeEach(function() { sandbox = sinon.createSandbox(); - sandbox.stub(global, 'setTimeout'); + sandbox.stub(global, 'setTimeout').returns(2); sandbox.stub(events, 'on'); // remove cookie @@ -597,8 +597,8 @@ describe('User ID', function() { coreStorage.setCookie('MOCKID', JSON.stringify({'MOCKID': '123456778'}), new Date(Date.now() + 5000).toUTCString()); config.setConfig({ - userSync: { - auctionDelay: 33, + usersync: { + auctionDelay: 200, syncDelay: 77, userIds: [{ name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } From b0a281870bcfbe06514b9867ca89f84b352604c3 Mon Sep 17 00:00:00 2001 From: Oleg Naydenov Date: Fri, 3 Apr 2020 19:40:49 +0200 Subject: [PATCH 204/496] Fidelity: Add SCHAIN Support (#4945) * Add SCHAIN Support * Add SCHAIN support * Add SCHAIN Support - 2 --- modules/fidelityBidAdapter.js | 22 ++++++++++++++++++++ test/spec/modules/fidelityBidAdapter_spec.js | 21 ++++++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/modules/fidelityBidAdapter.js b/modules/fidelityBidAdapter.js index 7bca0745cc5..f16a8ea96be 100644 --- a/modules/fidelityBidAdapter.js +++ b/modules/fidelityBidAdapter.js @@ -27,6 +27,7 @@ export const spec = { tmax: bidderRequest.timeout, defloc: bidderRequest.refererInfo.referer, referrer: getTopWindowReferrer(), + schain: getSupplyChain(bidRequest.schain), }; setConsentParams(bidderRequest.gdprConsent, bidderRequest.uspConsent, payload); @@ -118,4 +119,25 @@ function setConsentParams(gdprConsent, uspConsent, payload) { } } +function getSupplyChain(schain) { + var supplyChain = ''; + if (schain != null && schain.nodes) { + supplyChain = schain.ver + ',' + schain.complete; + for (let i = 0; i < schain.nodes.length; i++) { + supplyChain += '!'; + supplyChain += (schain.nodes[i].asi) ? encodeURIComponent(schain.nodes[i].asi) : ''; + supplyChain += ','; + supplyChain += (schain.nodes[i].sid) ? encodeURIComponent(schain.nodes[i].sid) : ''; + supplyChain += ','; + supplyChain += (schain.nodes[i].hp) ? encodeURIComponent(schain.nodes[i].hp) : ''; + supplyChain += ','; + supplyChain += (schain.nodes[i].rid) ? encodeURIComponent(schain.nodes[i].rid) : ''; + supplyChain += ','; + supplyChain += (schain.nodes[i].name) ? encodeURIComponent(schain.nodes[i].name) : ''; + supplyChain += ','; + supplyChain += (schain.nodes[i].domain) ? encodeURIComponent(schain.nodes[i].domain) : ''; + } + } + return supplyChain; +} registerBidder(spec); diff --git a/test/spec/modules/fidelityBidAdapter_spec.js b/test/spec/modules/fidelityBidAdapter_spec.js index 15bb5a1b59e..1232c20b0d7 100644 --- a/test/spec/modules/fidelityBidAdapter_spec.js +++ b/test/spec/modules/fidelityBidAdapter_spec.js @@ -67,7 +67,19 @@ describe('FidelityAdapter', function () { bidId: '2ffb201a808da7', bidderRequestId: '178e34bad3658f', requestId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' + transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b', + schain: { + ver: '1.0', + complete: 1, + nodes: [{ + asi: 'exchange1.com', + sid: '1234', + hp: 1, + rid: 'bid-request-1', + name: 'publisher', + domain: 'publisher.com' + }] + } } ], start: 1472239426002, @@ -78,7 +90,8 @@ describe('FidelityAdapter', function () { } }; - it('should add source and verison to the tag', function () { + it('should add params to the request', function () { + let schainString = '1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com'; const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); const payload = request.data; expect(payload.from).to.exist; @@ -92,9 +105,11 @@ describe('FidelityAdapter', function () { expect(payload.flashver).to.exist; expect(payload.tmax).to.exist; expect(payload.defloc).to.exist; + expect(payload.schain).to.exist.and.to.be.a('string'); + expect(payload.schain).to.equal(schainString); }); - it('should add gdpr consent information to the request', function () { + it('should add consent information to the request', function () { let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; let uspConsentString = '1YN-'; bidderRequest.gdprConsent = { From 345e6180bc9cdffbe7d791546ae696240972d79b Mon Sep 17 00:00:00 2001 From: Salomon Rada Date: Mon, 6 Apr 2020 17:38:52 +0300 Subject: [PATCH 205/496] Gamoshi: Update adaptor features (#5076) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add logic to prefer prebid modules over external modules in build process (#4124) * add check in getModules helper function * update logic based on feedback * update node version of project * Improve Digital adapter: adding bid floor, referrer, more native fields (#4103) * Bid floor, https, native ad update * Update the ad server protocol module * Adding referrer * YIELDONE adapter - change urls to adapt https (#4139) * update: change urls to adapt https * fix test code * Added SupplyChain Object support and an onTimeout Callback (#4137) * - Implemented the 'onTimeout' callback to fire a pixel when there's a timeout. - Added the ability to serialize an schain object according to the description provided here: https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md * some mods to the schain tag generation * - added tests for schain param checking. * - fixed a malformed url for timeouts * - Removed a trailing ',' while generating a schain param. * Revert "Added SupplyChain Object support and an onTimeout Callback (#4137)" This reverts commit e61b246b45bd2c2390350eaeca693f208b1a3a24. This commit doesn't use the schain module added in #4084 * Nobid Prebid Adapter commit (#4050) * Nobid Prebid Adapter commit * Fixed global replace and unit tests * Fixed find function * Added nobidBidAdapter.md * Removed description and added "Bid Params" section. * Added test siteId 2 for testing. * Refactored the Adapter to remove most references to the nobid object. We still need the nobid object because we have a passback tag in DFP that makes reference to it. * Fix concurrent responses on the page * Cosmetic change to log an error in case of missing ad markup * Keep nobid.bidResponses cross adapters. * Added GDPR support in user sync and added test coverage. gulp test-coverage gulp view-coverage * Padding issues * Fix padding issues * Fix padding * update outstream prod url (#4104) * support pubcid and uids (#4143) * Fix misspelling and minor cleanup of schain docs (#4150) * Prebid 2.31.0 Release * Increment pre version * Rubicon: tuning logged messages (#4157) * Rubicon: tuning logged messages * Update rubiconBidAdapter.js * fixed indentation * Rubicon Video COPPA fix (#4155) * Rubicon Video COPPA fix * Unit test for Rubicon Video COPPA fix * Playground XYZ adapter - iframe usersync bug fix (#4141) * corrected user sync type * removed support for iframe usersync * added unit tests for getUserSyncs * update nvmrc file (#4162) * update gulp-footer package (#4160) * Datablocks bid/analytics adapter (#4128) * add datablocks Analytics and Bidder Adapters * remove preload param * remove preloadid * better coverage of tests * better coverage * IE doesn't support array.find * lint test * update example host * native asset id should be integer * update logic of ad_types field in appnexusBidAdapter (#4065) * Shorten SomoAudience to just Somo (#4163) * Shorten SomoAudience to just Somo * Make package-lock return * Quantcast: Fix for empty video parameters (#4145) * Copy params from bid.params.video. * Added test for missing video parameters. * Include mimes from adunit. * One Video adding Rewarded Video Feature (#4142) * outstream changes * removing global filtet * reverting page * message * adapter change * remove space * testcases * testpage * spaces for test page * renderer exist case * reverting package-lock.json * adding schain object * adding tagid * syntaxx error fix * video.html * space trailing * space * tagid * inventoryId and placement * rewarded video * added unit test case * Module to pass User Ids to DFP (#4140) * first commit * renamed * minor doc change * documentation * small change * EB * removed unused imports * minor changes * reanmaed a const * adding more methods to test shareUserIds module * unit tets cases for shareUserIds * indentation * renamed DFP to GAM * renamed shareUserIds to userIdTargeting * Update userIdTargeting.md * trying to restart CI * digitrust userId case handled * minor comment change * using auctionEnd event instead of requestBids.before * using events.on * Buzzoola bid adapter (#4127) * initial commit for buzzoola adapter * leave only banners for now * fix bid validation * change endpoint url * add video type * restore renderer * fix renderer * add fixed player sizes * switch bids * convert dimentions to strings * write tests * 100% tests * remove new DOM element creation in tests * handle empty response from server * change description * E2e tests for Native and Outstream video Ad formats. (#4116) * reorganize e2e/ tests into separate directories * new test page for e2e-banner testing * add test to check if Banner Ad is getting loaded * change location of the spec files to reflect change in test/e2e directory structure * add test case to check for generation of valid targeting keys * create Native Ad test page * add test case to check validity of the targeting keys and correct rendering of the Ad * update old browser versions to new * update browser version * update title * remove console.log statements * add basic functional test for e2e outstream video ad format * Update LockerDome adUnitId bid param (#4176) This is not a breaking change * fix several issues in appnexus video bids (#4154) * S2s testing disable client side (#4123) * Add microadBidAdapter * Remove unnecessary encodeURIComponent from microadBidAdapter * Submit Advangelists Prebid Adapter * Submit Advangelists Prebid Adapter 1.1 * Correct procudtion endpoint for prebid * analytics update with wrapper name * reverted error merge * New testServerOnly flag * Tests and a bug fix * Removed dead code * Fixes requested in review * Check each adUnit * isTestingServerOnly changes per Eric * Fixed IE 11 bug * More tests * improved test case names * New option to Include deal KVPs when enableSendAllBids === false (#4136) * new option to include KVPs which have deals when enableSendAllBids === false * updating tests to be more realistic * Prebid 2.32.0 Release * increment pre version * Rubicon doc: changing video test zone (#4187) * added schain support to sonobi adapter (#4173) * if schain config is not defined then error should not be thrown (#4165) * if schain config is not defiend then error should not be thrown * relaxed mode nodes param not defined error handled * added test cases for config validation * a curly bracket was missing in the example * Rubicon: updating test params (#4190) * myTargetBidAdapter: support currency config (#4188) * Update README.md (#4193) * Update README.md * Update README.md * cedato bid adapter instream video support (#4153) * Added adxpremium prebid analytics adapter (#4181) * feat(OAFLO-186): added support for schain (#4194) * Sonobi - send entire userid payload (#4196) * added userid param to pass the entire userId payload to sonobis bid request endpoint * removed console log git p * fixed lint * OpenX Adapter fix: updating outdated video examples (#4198) * userId - Add support for refreshing the cached user id (#4082) * [userId] Added support for refreshing the cached user id: refreshInSeconds storage parameter, related tests and implementation in id5 module * [userId] Added support for refreshing the cached user id: refreshInSeconds storage parameter, related tests and implementation in id5 module * UserId - ID5 - Updated doc with new contact point for partners * UserId - Merged getStoredValue and getStoredDate * [UserId] - ID5 - Moved back ID5 in ./modules * UserId - ID5 - Fixed incorrect GDPR condition * [UserId] - Doc update and test cleanup * Prebid 2.33.0 Release * Increment pre version * SupplyChainObject support and fires a pixel onTimeout (#4152) * - Implemented the 'onTimeout' callback to fire a pixel when there's a timeout. - Added the ability to serialize an schain object according to the description provided here: https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md * some mods to the schain tag generation * - added tests for schain param checking. * - fixed a malformed url for timeouts * - Removed a trailing ',' while generating a schain param. * - Using the schain object from validBidRequest if present. Reverting to checking if params has it if not. * - reverting changes to merge with master * - Resolving merge issues * Feature/add profile parameter (#4185) * Add optional profile parameter * EMXDigital Bid Adapter: Add video dimensions in request (#4174) * addressed feedback from #3731 ticket * removed commented code from emx test spec * logging removed from spec * flip h & w values from playerSize for video requests * adding Outstream mediaType to EMX Digital * adding device info. update to grab video param. styling changes. * add video dimensions from playerSize * fix test for video dimensions * Added keywords parameter support in TrustX Bid Adapter (#4183) * Add trustx adapter and tests for it * update integration example * Update trustx adapter * Post-review fixes of Trustx adapter * Code improvement for trustx adapter: changed default price type from gross to net * Update TrustX adapter to support the 1.0 version * Make requested changes for TrustX adapter * Updated markdown file for TrustX adapter * Fix TrustX adapter and spec file * Update TrustX adapter: r parameter was added to ad request as cache buster * Add support of gdpr to Trustx Bid Adapter * Add wtimeout to ad request params for TrustX Bid Adapter * TrustX Bid Adapter: remove last ampersand in the ad request * Update TrustX Bid Adapter to support identical uids in parameters * Update TrustX Bid Adapter to ignore bids that sizes do not match the size of the request * Update TrustX Bid Adapter to support instream and outstream video * Added wrapperType and wrapperVersion parameters in ad request for TrustX Bid Adapter * Update TrustX Bid Adapter to use refererInfo instead depricated function utils.getTopWindowUrl * HOTFIX for referrer encodind in TrustX Bid Adapter * Fix test for TrustX Bid Adapter * TrustX Bid Adapter: added keywords passing support * rubicon: avoid passing unknown position (#4207) * rubicon: not passing pos if not specified * added comment * not sending pos for video when undefined * cleaning up test * fixed unit test * correctly reference bidrequest and determine mediatype of bidresponse (#4204) * GumGum: only send gdprConsent when found (#4205) * adds digitrust module, mods gdpr from bool to int * update unit test * only send gdprconsent if present * LKQD: Use refererInfo.referer as fallback pageurl (#4210) * Refactored URL query parameter passthrough for additional values, changed SSP endpoint to v.lkqd.net, and updated associated unit tests * Use refererInfo.referer as fallback pageurl * Removed logs and testing values * [UserId] - ID5 - Fixed case when consentData is undefined (No CMP) (#4215) * create stubs for localStorage in widespaceBidAdapter test file (#4208) * added adId property to adRenderFailed event (#4097) When no bid (therefore no adUnitCode) is available in the adRenderFailed event it can be difficult to identify the erroring slot.But in almost all cases the given slot still has the adId targeting. * OpenX Adapter: Forcing https requests and adding UserID module support for LiveRamp and TTD (#4182) * OpenX Adapter: Updated requests to force https * OpenX Adapter: Added support for TTD's UnifiedID and LiveRamp's IDL * PubMatic to support userId sub-modules (#4191) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * TripleLift support for UnifiedId and IdentityLink (#4197) * Add IdentityLink support and fix UnifiedId. It appears we've been looking for UnifiedId userIds on the bidderRequest object, when they are found on bidRequests. This commit fixes that error, and adds support for IdentityLink. * change maintainer email to group * Added lemma adapter (#4126) * lemmaBidAdapter.js Added lemma bid adapter file * lemmaBidAdapter.md Added lemma bid adapter md file * lemmaBidAdapter_spec.js Added lemma bid adapter test spec file * Update lemmaBidAdapter.js Fixed automated code review alert comparison between inconvertible types * Update lemmaBidAdapter.js Fixed review changes * Update lemmaBidAdapter.md Correct parameter value. * Adkernel adapter new alias (#4221) * Force https scheme for Criteo Bidder (#4227) * assign adapter version number * Ensure that Criteo's bidder is always called through https * Add Video Support for Datablocks Bid Adapter (#4195) * add datablocks Analytics and Bidder Adapters * remove preload param * remove preloadid * better coverage of tests * better coverage * IE doesn't support array.find * lint test * update example host * native asset id should be integer * add datablocks Video * remove isInteger * skip if empty * update adUnit, bidRequest and bidResponse object (#4180) * update adUnit, bidRequest and bidResponse object * add test for mediaTypes object * 3 display banner and video vast support for rads (#4209) * add stv adapter * remove comments from adapter file * start rads adapter * fix adapter and tests * fixes * fix adapter and doc * fix adapter * fix tests * little fix * add ip param * fix dev url * #3 radsBidAdapter.md * #3 radsBidAdapter.md: cleanup * fix code and doc * UserId - Add SameSite and server-side pubcid support (#3869) * Add SameSite and server-side pubcid support * Fix emoteevBidAdapter unit test * added schain to appnexus bid adapter (#4229) * added schain to appnexus bid adapter * semicolon * update doubleclick url (#4179) * Prebid 2.34.0 release * increment pre version * Rubi Analytics handles > 1 bidResponse per bidRequest (#4224) * videoNow bid adapter (#4088) * -- first commit * -- cors and bidder's name fixed * -- almost ready * -- added docs * -- added nurl tracking * -- bid params * -- tests added * -- test fixed * -- replace placeholder in the onBidWon pixel's url * -- commit for restart tests * -- change response data format for display ad * -- tests updated * -- 100% tests coverage * -- a few clean the test's code * -- custom urls from localStorage * -- tests updated * -- a few clean the test's code * -- new init model * -- spec for new init model * -- fix for new init model * -- code cleaned * -- 100% tests coverage * -- 100% tests coverage * -- fixed test * -- commit for restart tests * djax new bidder adapter (#4192) * djax bidder adapter * djax bidder adapter * Update hello_world.html * Added Turk Telekom Bid Adapter (#4203) * Added Turk Telekom Bid Adapter * Fix md file for Turk Telekom Bid Adapter * MicroAd: Use HTTPS in all requests (#4220) * Always use HTTPS endpoint in MicroAd * Update code * Fixed a broken test in MicroAd * Schain: avoiding Object.values as it is breaking on IE11 (#4238) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * avoiding use of Object.values * 3952 delay auction for ids (#4115) * 3952 delay auction for user ids * 3952 add integration example * 3952 add tests * 3952 fix html example * add todos * 3952 continue auction if ids received * 3952 add tests for auction delay * increase test coverage * set config for test * remove todo * add a few more checks to tests * add comment, force tests to rerun * Feature: adUnitBidLimit (#3906) * added new feature to config to limit bids when sendallbids is enabled * cleaned up code. removed extra spaces etc * removed trailing spaces in config * remove .flat() and replaced with spread operator * removed flat function and instead pushing using spread operator * updated to use sendBidsControl instead * updated targeting_spec to test bidLimit * removed trailing spaces from targeting_spec * Update Rubicon Adapter netRevenue default (#4242) * Add microadBidAdapter * Remove unnecessary encodeURIComponent from microadBidAdapter * Submit Advangelists Prebid Adapter * Submit Advangelists Prebid Adapter 1.1 * Correct procudtion endpoint for prebid * analytics update with wrapper name * reverted error merge * update changed default value of netRevenue to true * Removed AdastaMadia from alias (#4255) * Update appnexusBidAdapter.js (#4251) * IdentityLink - change expiration time to 30 days (#4239) * Add coppa support for AppNexus adapter (#4253) * Add coppa support for AppNexus adapter * test name * add new longform e2e tests (#4206) * Konduit module (#4184) * Adding Konduit module * Removed superfluous arguments passed to obtainVastUrl function * Removed superfluous arguments passed to obtainVastUrl function. * Build trigger (empty commit) * Module documentation updated according to the comments * Logic in obtainVastUrl function updated according to the review comment. * Removed hook, enabled eslint * Circle CI runs e2e tests on every push (#4200) * run functional tests on circle ci on push to any remote branch * remove extraneous key from config file * add test.localhost as alias to 127.0.0.1 * check 0: execute circle-ci * move /etc/config to a separate command * change bid partner to rubicon * test appnexus bid adapter in ci * comment browserstack command * remove console.log statement * test1: circle-ci * change reference dev -> prod while loading prebid * add console.log statement * check-2: circle-ci * comment browserstack testing * change bid adapter * change bid adapter * remove test case for checking targeting keys * remove the ci flag * uncomment test for checking correct generation of targeting keys * swap AN -> Rubicon for testing targeting keys * Outcon bid adapter. (#4161) * Outcon bid adapter. * Fix identation * Fixes * Fixes * Fixes * Spec fixes * Fixes * Fix urls * Fix * Fix parameters * Fix space operators * Fix bidder timeout * Update * Fix whitespace * no message * Outcon unit test * no message * no message * no message * no message * Fixes * Fixes * Change url * no message * no message * no message * Added bidId * no message * no message * no message * no message * Wrapping url with html * no message * no message * no message * Adding workflow to run end to end tests (#4230) * Adding workflow to run end to end tests * trying self branch * Update to run at 12 every day * cleanup config using aliases * update branch and cron time * add command * update prebid path for e2e test pages (#4274) * Prebid 2.35.0 release * Increment pre version * Add usersync to adpone adapter (#4245) * add user sync to adpone adapter * move adpone usersync to global variable * added withcredentials to http request * fix http request options * fix http request options * add withCredentials: true * add withCredentials: true * added test coverage to usersync * update sync function * add test coverage * adpone adapter * package lock * add more testing * add more testing * testing for onBidWon fucntion * test onbidwon function * trigger build * Revert GumGum Adapter 2.28 resizing changes (#4277) * changed resizing unit tests to return the first size dimensions in the sizes array * added some changes * reverted adapter changes * SpotX Bid Adapter: Support schain, ID5 object, Google consent object, and hide_skin (#4281) * Add SpotXBidAdapter * Minor updates * Undo testing changes to shared files * Fix relative imports * Remove superfluous imports and write a few more tests * Formatting, ID5 object, Google consent objects - Added ID5 object support - Added Google Consent object - Reformatted indentaiton on spec file * Revert content_width and content_height changes in docs - not sure how these got moved, lets put them back * Remove click_to_replay flag in example - no reason to use this one in the example * Spotx adapter - Add schain support and update unit tests * Update schain path in ORTB 2.3 request body - schain object is now added to ortb request body at request.ext.source.ext.schain * Add hide_skin to documentation - whoops, this got removed, let's add it back * Update Rubicon Analytics Adapter `bidId` to match PBS (#4156) * Add microadBidAdapter * Remove unnecessary encodeURIComponent from microadBidAdapter * Submit Advangelists Prebid Adapter * Submit Advangelists Prebid Adapter 1.1 * Correct procudtion endpoint for prebid * analytics update with wrapper name * reverted error merge * update for rubicon analytics to send seat[].bid.id for PBS video and banner * fixed conditional for server and video or banner * updated with optimized value test for bidid * update changed default value of netRevenue to true * remove var declaration for rightSlot to correct lgtm error for unused variable * update defineSlot div id to match div id defined in html body * update test ad unit test props * revert lock to match remote master * add seatBidId to bidObj in rpBidAdapter interpretResponse * update setTargeting to execute in the bids back handler * remove dev integration test page * meaningless commit to get lgtm to re-run * SmartRTB adapter update (#4246) * modules: Implement SmartRTB adapter and spec. * Fix for-loop syntax to support IE; refactor getDomain out of exported set. * Remove debugs, update doc * Update test for video support * Handle missing syncs. Add video to media types in sample ad unit * Add null response check, update primary endpoint * Note smrtb video requires renderer * Support Vast Track (#4276) * Add microadBidAdapter * Remove unnecessary encodeURIComponent from microadBidAdapter * Submit Advangelists Prebid Adapter * Submit Advangelists Prebid Adapter 1.1 * Correct procudtion endpoint for prebid * analytics update with wrapper name * reverted error merge * update changed default value of netRevenue to true * Add parameters if config.cache.vasttrack is true * Use requestId instead of adId * Test new vasttrack payload params * Removed commented out code * Relaxed conditional check per review * Removed commented out line * Added 1000x250 size (#4295) * prepare vidazoo adapter for v3.0 (#4291) * Improve Digital adapter: support schain (#4286) * LiveIntent Identity Module. (#4178) * LiveIntentIdSystem. Initial implementation. * LiveIntentIdSystem. Removed whitespace. * Fixed typo * Renamed variables, cookiesm added md. * Changed the default identity url. * Composite id, with having more than just the lipbid passed around. * Composite id. * Merge conflict resolution. * Changed docs and param description. * Added typedoc & mentioned liveIntentIdSystem in submodule.json. * Extracted the LiveIntentIdSystem under modules, removed it from default userId modules. * Fixing the 204 + no body scenario. * Added liveIntent to submodule.json * Fixing docs indentation. * Updated prebidServer & specs. * Minor specs update. * updating liveintent eids source (#4300) * updating liveintent eids source these are supposed to be domains * updating unit test * fix appnexusBidAdapter view-script regex (#4289) * fix an view script regex * minor syntax update * 33Across adding bidder specific extension field (#4298) * - add 33across specific ext field for statedAt * - fix unit test for 33Across adapter * PubMatic to support LiveIntent User Id sub-module (#4306) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * supporting LiveIntent Id in PubMatic adapter * updated source for liveintent * Finteza Analytics Adapter: fix cookies (#4292) * fix reading and sending cookies * fix lint errors * clear comments * add unit tests * fix calling of setCookies for IE * clear cookies after test * use own setCookie method inside tests * Update LockerDome adapter to support Prebid 3.0 (#4301) * Returning the `IdResponse` type with an obj + callback. Fix for 4304 (#4305) * Returning the `IdResponse` type with an obj + callback. * Renamed resp -> result. * Removed whitespace. * ShowHeroes adapter - expanded outstream support (#4222) * add ShowHeroes Adapter * ShowHeroes adapter - expanded outstream support * Revert "ShowHeroes adapter - expanded outstream support" This reverts commit bfcdb913b52012b5afbf95a84956b906518a4b51. * ShowHeroes adapter - expanded outstream support * ShowHeroes adapter - fixes (#4222) * ShowHeroes adapter - banner and outstream fixes (#4222) * ShowHeroes adapter - description and outstream changes (#4222) * ShowHeroes adapter - increase test coverage and small fix * [Orbidder-Adapter] Add bidRequestCount and remove bid.params.keyValues (#4264) * initial orbidder version in personal github repo * use adUnits from orbidder_example.html * replace obsolete functions * forgot to commit the test * check if bidderRequest object is available * try to fix weird safari/ie issue * ebayK: add more params * update orbidderBidAdapter.md * use spec. instead of this. for consistency reasons * add bidfloor parameter to params object * fix gdpr object handling * default to consentRequired: false when not explicitly given * wip - use onSetTargeting callback * add tests for onSetTargeting callback * fix params and respective tests * remove not used bid.params.keyValues * add bidRequestCount to orbidder.otto.de/bid Post request * add bidRequestCount to test object defaultBidRequest * PulsePoint: remove usage of deprecated utils method / prep for 3.0 (#4257) * ET-1691: Pulsepoint Analytics adapter for Prebid. (#1) * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: cleanup * ET-1691: minor * ET-1691: revert package.json change * Adding bidRequest to bidFactory.createBid method as per https://github.com/prebid/Prebid.js/issues/509 * ET-1765: Adding support for additional params in PulsePoint adapter (#2) * ET-1850: Fixing https://github.com/prebid/Prebid.js/issues/866 * Minor fix * Adding mandatory parameters to Bid * Removing usage of deprecated utils method * minor refactor * Use isArray method (#4288) * Add Parrable ID submodule (#4266) * add parrable id submodule * fix integration test config * fix var name * always refresh sotredId for parrable * add submodulesThatAlwaysRefresh concept * remove comment * add parrable url as one string * add parrable prod endpoint * use .indexOf instead of .includes * add params to test config * comment failing test * uncomment failing assertion * add parrable ID to prebid server adapter * add parrableIdSystem to .submodules.json * extract parrableId unit tests from userId spec * remove breakline between imports * remove unused param * remove userId generic feature from parrableId module * remove trailing space * fix failing test due to none merged conflict * Prebid 2.36.0 Release * Increment pre version * Support schain module and send bidfloor param in Sharethrough adapter (#4271) * Add support for supply chain object module Story: [#168742394](https://www.pivotaltracker.com/story/show/168742394) Co-authored-by: Josh Becker * Add bidfloor parameter to bid request sent to STX Story: [#168742573](https://www.pivotaltracker.com/story/show/168742573) * Platform One Analytics Adapter (#4233) * Added Y1 Analytics Adapter * rename y1AnalyticsAdapter in yieldoneAnalyticsAdapter * Yieldone Bid Adapter: fixes from lint check * Yieldone Analytics Adapter: fix endpoint protocol * Added spec file for yieldone Analytics Adapter * Fix parrable id integration example (#4317) * fix parrableId integration example * add parentheses * Improve Digital adapter: support for video (#4318) * Bid floor, https, native ad update * Update the ad server protocol module * Adding referrer * Improve Digital support for video * Improve Digital adapter: video * adapter version -> 6.0.0 * Gamoshi: Update aliases list. Add support for userSync. (#4319) * Add support for multi-format ad units. Add favoredMediaType property to params. * Add tests for gdpr consent. * Add adId to outbids * Modify media type resolving * Refactor multi-format ad units handler. * Modify the way of sending GDPR data. Update aliases. * Add new consent fields. Add unit test. * Add new consent fields. Add unit test. * Add support for id5 and unified id cookie sync. * Add support for id5 and unified id cookie sync. * Add restricted check for gdpr consent. * fix for userSync endpoint getting called with bidder alias names, instead of actual bidder names (#4265) * modify ixBidAdapater to always use the secure endpoint (#4323) * PubMatic to support Parrable User Id sub-module (#4324) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * PubMatic to support parrable id * VISX: currency validation & fix double escape of referer (#4299) * PubMatic to support coppa (#4336) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * added coppa compliance * vuble: outstream has fullscreen option (#4320) * Mod: vuble oustream has fullscreen option * Add: vuble test for outstream scenario * EMXDigital: hotfix to resolve URIError from decodeURIComponent (#4333) * hotfix to resolve URIError from decodeURIComponent * added unit for decoding adm * Specify second parameter for parseInt for pubmaticBidAdapter (#4347) * Remove usage of getTopWindowUrl in Prebid Adapter (#4341) * Conversant Bid Adapter update for 3.0 (#4284) * Add cpmDistribution function for Google Analytics adapter (#4240) * Add cpmDistribution function for Google Analytics adapter * Add test for the cpmDistribution function * Remove half written comment * fixing SRA p_pos (#4337) * In Sonobi Adapter, only read sizes from bid.mediaTypes (#4311) * Fix mediaTypes (#4332) * Outcon bid adapter. * Fix identation * Fixes * Fixes * Fixes * Spec fixes * Fixes * Fix urls * Fix * Fix parameters * Fix space operators * Fix bidder timeout * Update * Fix whitespace * no message * Outcon unit test * no message * no message * no message * no message * Fixes * Fixes * Change url * no message * no message * no message * Added bidId * no message * no message * no message * no message * Wrapping url with html * no message * no message * no message * Fix mediaTypes * no message * Update outconBidAdapter_spec.js * Adding VAS response * no message * no message * no message * Fix * Changed ttl * no message * supportedMediaTypes * no message * no message * Prebid 2.37.0 release * increment pre version * Add vast xml support and other minor changes to Beachfront adapter (#4350) * Add support for vast xml in the bid response * add secure protocol to outstream player url * add device connection type * add player setting for poster color * add new value for creative Id * Update smartrtbBidAdapter (#4362) * modules: Implement SmartRTB adapter and spec. * Fix for-loop syntax to support IE; refactor getDomain out of exported set. * Remove debugs, update doc * Update test for video support * Handle missing syncs. Add video to media types in sample ad unit * Add null response check, update primary endpoint * Note smrtb video requires renderer * Remove old params checks, fix documentation playerSize field name * Revert "Update smartrtbBidAdapter (#4362)" (#4368) This reverts commit be6704bcec65a28d80b6d09a8d1c51ef9a8ba824. * Add userSync in onetagBidAdapter (#4358) * Minor bug fixing in onetagBidAdapter.js Fixed a minor bug. Updated TTL in response to align the correct specifications. * Update onetagBidAdapter Added additional page info and user sync function. * Update onetagBidAdapter_spec.js Added the test for getUserSyncs function. * Fix about userSync * getUserSyncs: test update with gdpr params * Sovrn adapter updates: schain, digitrust, pixel syncing, and 3.0 upgrades (#4335) * schain and digitrust * pixel beacons * unit tests and fixes from testing * Prebid 3.0 updates * review fix * Add bid adapter for ablida (#4256) * Add ablida adapter * rename category parameter, add documentation * AdKernel: added waardex_ak alias (#4290) * added alias Added a new alias * fixing unit test * Revert "Sovrn adapter updates: schain, digitrust, pixel syncing, and 3.0 upgrades (#4335)" (#4376) This reverts commit 6114a3dba93815dcfb535707d7b4d84f1adb2bc7. * Vrtcal Markets Inc. Bid Adapter Addition (#4259) * Added 3 key Vrtcal Adapter files: adapter,markdown,unit tests * Removed unused getUserSyncs;Added mediaTypes.banner.sizes support;Raised test coverage to 85% * lint formatting errors corrected * Update schain path in ORTB path for spotxBidAdapter (#4377) - Move schain object from request.ext.source.ext.schain to request.source.ext.schain * Update Grid Bid Adapter (#4379) * Added Grid Bid Adapter * remove priceType from TheMediaGrid Bid Adapter * Add video support in Grid Bid Adapter * Added test parameter for video slot * update Grid Bid Adapter to set size in response bid * Update Grid Bid Adapter to support identical uids in parameters * Fix typo in test file for Grid Bid Adapter * Update The Grid Media Bidder Adapter to send refererInfo.referer as 'u' parameter in ad request * Hotfix for referrer in Grid Bid Adapter * Grid Bid Adapter: added wrapperType and wrappweVersion to the ad request * TripleLift: Sending schain (#4375) * Add IdentityLink support and fix UnifiedId. It appears we've been looking for UnifiedId userIds on the bidderRequest object, when they are found on bidRequests. This commit fixes that error, and adds support for IdentityLink. * change maintainer email to group * TripleLift: Sending schain (#1) * Sending schain * null -> undefined * DistrictmDMX: adding support for schain and remove content type to default to prebid selection (#4366) * adding DMX test @97%, two files added one updated * Update districtm_spec.js * Update districtmDMX.js * adding all districtm needed file * remove legacy file * remove typo || 0 in the test method * force default to return a valid width and height * update unit test code for failing test * changed class for an object * remove package-lock.json * change file name for dmx adapter * renamed files * restaure package-lock.json * update to last package-lock state * update gdpr user consent * fix sizes issue * Documentation updates Adding the readme.md info * update file name and update unit testing import file location * current machine state * lint correction * remove variable assigment duplicate * Support for ID5 + receive meta data (#4352) * Livewrapped bid and analytics adapter * Fixed some tests for browser compatibility * Fixed some tests for browser compatibility * Changed analytics adapter code name * Fix double quote in debug message * modified how gdpr is being passed * Added support for Publisher Common ID Module * Corrections for ttr in analytics * ANalytics updates * Auction start time stamp changed * Detect recovered ad blocked requests Make it possible to pass dynamic parameters to adapter * Collect info on ad units receiving any valid bid * Support for ID5 Pass metadata from adapter * Typo in test + eids on wrong level * Rubicon Adapter: Always make requests using HTTPS (#4380) * Add microadBidAdapter * Remove unnecessary encodeURIComponent from microadBidAdapter * Submit Advangelists Prebid Adapter * Submit Advangelists Prebid Adapter 1.1 * Correct procudtion endpoint for prebid * analytics update with wrapper name * reverted error merge * update changed default value of netRevenue to true * Always make bids requests using https * rp_secure and imp.secure should always be 1 * 7xbid adapter (#4328) * 7xbid adapter * fix error when cli build * - update 33across adapter cookie sync end point (#4345) - update unit test for 33across adapter * Adform adapter: add renderer for outstream bids (#4363) * Prebid 2.38.0 Release * Increment pre version * Adagio: update with external js (#4217) * Add external loader in AdagioBidAdapter * Change adagioAnalyticsAdapter to "endpoint" type * Change _setPredictions for a generic method * Improve AdagioBidAdapter test coverage * Add features detection in Adagio adapter * Fix adagioBidAdapter tests * Add featuresVersion field to bidRequest * Refacto adagio.queue * Expose versions in ADAGIO namespace * Generate a ADAGIO.pageviewId if missing * Move ad-server events tracking to adagioBidAdapter * Store adUnitCodes in ADAGIO namespace * Update documentation Better description of test parameters. * Add internal array to prevent empty pbjs.adUnits * Be sure to access to window.top - does not work in safe-frame env * Add PrintNumber feature * Be sure to compute features on window.top * Bump versions * Add Post-Bid support - ad-server events are listen in current window (instead of window.top) - a new "outerAdUnitElementId" property is set to ADAGIO.pbjsAdUnits array in case of Post-Bid scenario. This property is the 1st parent element id attribute of the iframe in window.top. * Set pagetype param as optional * Add AdThink ad-server support * Improve internal `pbjsAdUnits.sizes` detection Use the adUnit `mediaTypes.banner.sizes` property if exists to build the `ADAGIO.pbjsAdUnits.sizes`. The use of the `sizes` root property is deprecated. * adagioAnalyticsAdapter: add and improve tests * adagioBidAdapter: add and improve tests # Conflicts: # modules/adagioBidAdapter.js # test/spec/modules/adagioBidAdapter_spec.js * adagioBidAdapter: Bump version 1.5 * Adagio: fix import path * PostBid: insure window.top is accessible for specifics functions * Consistency: use Prebid.js utils and fix deprecated * PostBid: do not build a request if in safeframe * Bump version 2.0.0 * Try to fix tests without UA stubing * Try to fix adagioAnalytics failling tests on CI * Consistency: use Prebid loadExternalScript() * Add "adagio" to Prebid.js adloader vendor whitelist * Remove proprietary ad-server listeners * Add RSA validation to adagio external script * add viewdeosDX whitelabel (#4231) * add viewdeosDX hitelabel * Fixed tests and support for sizes * Fix strings * Fix strings * remove only * Fix tests * fix codereview * Fix test + Code review * code review + tests * One video display ad (#4344) * outstream changes * removing global filtet * reverting page * message * adapter change * remove space * testcases * testpage * spaces for test page * renderer exist case * reverting package-lock.json * adding schain object * adding tagid * syntaxx error fix * video.html * space trailing * space * tagid * inventoryId and placement * rewarded video * added unit test case * testing display ad * adding banner * validating banner object * display=1 changes * checking whether diplsy == 1 * html page change * reverting video.html * adding more test cases * spaces * md file change * updated working oneVideoBidAdapter.md file * Update oneVideoBidAdapter.md * Update oneVideoBidAdapter.md * updated the file with both video params and banner * Update video.html * fix double-urlecoded referrer (#4386) * fix double-urlecoded referer (#4388) * PulsePoint Adapter - update for ttl logic (#4400) * ET-1691: Pulsepoint Analytics adapter for Prebid. (#1) * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: cleanup * ET-1691: minor * ET-1691: revert package.json change * Adding bidRequest to bidFactory.createBid method as per https://github.com/prebid/Prebid.js/issues/509 * ET-1765: Adding support for additional params in PulsePoint adapter (#2) * ET-1850: Fixing https://github.com/prebid/Prebid.js/issues/866 * Minor fix * Adding mandatory parameters to Bid * Using the TTL from the bid.ext * Minor refactor * IdentityLink - add logic for sending consent string (#4346) * Fix adagio analytics adapter circleci (#4409) * Add microadBidAdapter * Remove unnecessary encodeURIComponent from microadBidAdapter * Submit Advangelists Prebid Adapter * Submit Advangelists Prebid Adapter 1.1 * Correct procudtion endpoint for prebid * analytics update with wrapper name * reverted error merge * update changed default value of netRevenue to true * update to skip broken circleci tests * skip all * Feature/7xbid remove unneeded params (#4402) * 7xbid adapter * fix error when cli build * remove unneeded params * Empty commit * Empty commit * Remove none ssl (#4406) * adding DMX test @97%, two files added one updated * Update districtm_spec.js * Update districtmDMX.js * adding all districtm needed file * remove legacy file * remove typo || 0 in the test method * force default to return a valid width and height * update unit test code for failing test * changed class for an object * remove package-lock.json * change file name for dmx adapter * renamed files * restaure package-lock.json * update to last package-lock state * update gdpr user consent * fix sizes issue * Documentation updates Adding the readme.md info * update file name and update unit testing import file location * current machine state * lint correction * remove variable assigment duplicate * remove none ssl element from all request] * fixed reference to global object (#4412) * ucfunnel adapter support supply chain (#4383) * Add a new ucfunnel Adapter and test page * Add a new ucfunnel Adapter and test page * 1. Use prebid lib in the repo to keep updated 2. Replace var with let 3. Put JSON.parse(JSON.stringify()) into try catch block * utils.getTopWindowLocation is a function * Change to modules from adapters * Migrate to module design * [Dev Fix] Remove width and height which can be got from ad unit id * Update ucfunnelBidAdapter to fit into new spec * Correct the endpoint. Fix the error of query string * Add test case for ucfunnelBidAdapter * Fix lint error * Update version number * Combine all checks on bid request * Add GDPR support for ucfunnel adapter * Add in-stream video and native support for ucfunnel adapter * Remove demo page. Add more test cases. * Change request method from POST to GET * Remove unnecessary comment * Support vastXml and vastUrl for video request * update TTL to 30 mins * Avoid using arrow function which is not discuraged in mocha * ucfunnel tdid support * ucfunnel adapter support supply chain * LiveIntent support in RP Adapter and PBS Adapter update to pass segments (#4303) * Add microadBidAdapter * Remove unnecessary encodeURIComponent from microadBidAdapter * Submit Advangelists Prebid Adapter * Submit Advangelists Prebid Adapter 1.1 * Correct procudtion endpoint for prebid * analytics update with wrapper name * reverted error merge * update changed default value of netRevenue to true * added semi-colon * update eid source to use domain * update video oRTB with liveintent segments * update pbs adapter with liveintent segments support * update rp adapter liveintent support for fastlane * reverted package lock, fix for unintentional update * added unit tests for fastlane.json and ortb, fix to join segments with commas * fix obj property path data.tpid * update remove unnecessary function call * re-ordering query string params * Rubicon Adapter: Add multiple sizes to sizeMap (#4407) * Add Utils to remove item in LocalStorage (#4355) * Making originalCpm and originalCurrency fields in bid object always available (#4396) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * moving originalCurrency declaration from currency to bidderFactory * added a comment * trying to re-run the CI job * added unit test case * trying to re-run the CI job * Placement and inventory (#4353) * outstream changes * removing global filtet * reverting page * message * adapter change * remove space * testcases * testpage * spaces for test page * renderer exist case * reverting package-lock.json * adding schain object * adding tagid * syntaxx error fix * video.html * space trailing * space * tagid * inventoryId and placement * rewarded video * added unit test case * inventory_id and placement * removed unnecessary file * lint error * Update oneVideoBidAdapter.js * lint error fix * Fixes for Platform One Analytics Adapter (#4359) * Added Y1 Analytics Adapter * rename y1AnalyticsAdapter in yieldoneAnalyticsAdapter * Yieldone Bid Adapter: fixes from lint check * Yieldone Analytics Adapter: fix endpoint protocol * Added spec file for yieldone Analytics Adapter * Add adUnitName to analytics data for Yieldone Analytics Adapter * Fix yieldone Analytics Adapter to log only id from adUnitPath * Fix bug with timeout event in Yieldone Analytics Adapter * Added protocol to url (#4395) * initial commit * updated contact and tag details * changes ti support the renderers * changes to pass dimId * fixed names of internal mapping * added comment * added gdpr param to request and other fixes * modified api url * fix * fixed the secure api call * rolled back video event callback till we support it * updated doc with video details * added bid won and timeout pixel * added testcase for bid events * modified testcase * fixed the url logged * tag param values passed ot renderer * added a conditioal check * changes to support new param to adserver for purpose of tracking * passed param to renderer * missing variable defined * added protocol to url * fixed test for protocol * changed urls to secure only * Update emoteev endpoints (#4329) * JustPremium: Update to Prebid 3.0 (#4410) * Update underdogmedia adapter for pbjs 3.0 (#4390) * Update underdogmedia adapter for pbjs 3.0 * Ensure request to endpoint is secure * Update prebid version * Lint fix * Update Consumable adapter for Prebid.js 3.0 (#4401) * Consumable: Clean up tests. * Consumable: Update use of deprecated function. * Consumable: Read sizes from mediaTypes.banner.sizes. * Consumable: Fix lint violation. * CriteoId User Module (#4287) * Add CriteoId module * Update the return type of getId in Criteo Id module Changes: - Use of url parsing function from url lib - Update the return type of getId() - Update the jsdoc to reflect the real return types * Fix failing tests for Criteo user module * Add CriteoIdSystem submodule to .submodule.json. * 2019/10/18 Create Mobsmart bidder adapter (#4339) * Adpod deal support (#4389) * Adpod deal support * Replacing filterBids with minTier * fix potential issue * remove querystringify package (#4422) * Browsi real time data module (#4114) * real time data module, browsi sub module for real time data, new hook bidsBackCallback, fix for config unsubscribe * change timeout&primary ad server only to auctionDelay update docs * support multiple providers * change promise to callbacks configure submodule on submodules.json * bug fixes * use Prebid ajax * tests fix * Prebid 2.39.0 Release * increment pre version * OpenX Adapter: Prebid 3.0 Compatibility Update (#4413) * Removed usage of deprecated functions * Removed beacons * Banner sizes now reads from bidRequest.mediaTypes.banner.sizes instead of bidRequest.sizes * Updated tests to reflect changes. * GumGum: use mediaTypes.banner.sizes (#4416) * adds digitrust module, mods gdpr from bool to int * update unit test * only send gdprconsent if present * uses mediaTypes before trying bidRequest sizes * removes use of deprecated method * RTBhouse Bid Adapter update for 3.0 (#4428) * add viewable rendering format (#4201) * Feature/adapter (#4219) * feat(bidrequest): code for making bidrequest * feat(bidresponse): format and return the response * feat(tests): added tests for adapter * feat(docs): added docs for the adapter * refactor(url): changed adserver url * test(user sync): added unit tests for the user syncs * refactor(endpoint): changed endpoint for prebid * refactor(endpoint): changed endpoint for prebid * doc(tagid): mandatory param definition added * fix(imp id): fix for correct impression id * fix(width/height): fix for correct width and height sequence * PulsePoint Bid Adapter: Support for schain (#4433) * ET-1691: Pulsepoint Analytics adapter for Prebid. (#1) * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: cleanup * ET-1691: minor * ET-1691: revert package.json change * Adding bidRequest to bidFactory.createBid method as per https://github.com/prebid/Prebid.js/issues/509 * ET-1765: Adding support for additional params in PulsePoint adapter (#2) * ET-1850: Fixing https://github.com/prebid/Prebid.js/issues/866 * Minor fix * Adding mandatory parameters to Bid * ET-5938 SupplyChain Object Support * Formatting * Code review * Code review * Fix to currency parsing on response * Add supply chain support for Teads adapter (#4420) * Rubicon: support SupplyChain (schain) (#4315) * Add microadBidAdapter * Remove unnecessary encodeURIComponent from microadBidAdapter * Submit Advangelists Prebid Adapter * Submit Advangelists Prebid Adapter 1.1 * Correct procudtion endpoint for prebid * analytics update with wrapper name * reverted error merge * update changed default value of netRevenue to true * Starting schain * More tests for banner schain support * Video tests * Encoding tweaks, required fields and comments * Removed .only() from tests * Change requests per Bret * Add 1ad4good bidder (#4081) * adding bidder code and A bidder for non-profit free ads. more info about this bidder project can be found on project site http://1ad4good.org * removed unused code test coverage is improved to >80% tested for instream video support * removed some legacy code, unused params * hardcoding https to endpoint * Improve Digital adapter fix: don't send sizes for instream video (#4427) * Bid floor, https, native ad update * Update the ad server protocol module * Adding referrer * Improve Digital support for video * Improve Digital adapter: video * adapter version -> 6.0.0 * Improve Digital adapter: don't send sizes for video * Fix a typo in code comment (#4450) * Inventory id and schain support for display (#4426) * supporting schain * Update coinzillaBidAdapter.js (#4438) Update sizes const. * Support schain in ZEDO adapter (#4441) * changes to pass schain * PubMatic supporting updated Criteo User Id module (#4431) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * PubMatic supporting updated Criteo User Id module * added a comment to re-start CI * Remove duplicate param to fix unit tests (#4459) * Brightcom Bid Adapter update for 3.0 (#4343) * add support for min_height field in pbs native requests (#4434) * Supporting Alias via Video Requests (#4460) * New adapter Proxistore (#4365) * add test adapter and documentation * integration test with hello_world * reset package-lock.json * delete useless conditionnal * make integrate test work * revert hello-world * revert hello_world * fix descriptor * change adUnits for integration test * remove proxistore widget * uncomment file * change sizes * remove useless script tag * Implementation of setBidderConfig and bidder-specific data (#4334) * initial implementation of setBidderConfig * fix ie11 test errors * Support new setBidderConfig format. Include props from both config and bidderConfig in _getConfig * Use core-js Set to avoid issues with IE * Fix tests in IE * put registerSyncs back on bidderFactory * run bidder event methods with bidder config enabled * Prebid 2.40.0 Release * Increment pre version * Conversant Bid Adapter checks pubcid directly (#4430) * Cookie Sync functionality (#4457) * changing PID param value for testing * cookie sync integration * merge from upstream * Staq Adapter: update with meta envelope (#4372) * initial dev * fix staq adapter name * fix hello world staq call * get hello world working again * add user agent collection * fix some unite tests * Add STAQ Analytics Adapter doc * clean up hello world * fix tests to play nice with browserstack * fix around issues with browserstack and deep equals of objects * dump variable env testing since we can't mod user agent stuff in browserstack * Update STAQ adapter to stop using deprecated utils for referrer * remove package-lock.json changes via master rebase * improve call frequency for ref util * change ajax content type * adjust ajax request to not expect whitelisting * remove superflous commented-out code * update event package to use meta information in envelope rather than per event basis * fix formatting * more formatting fixes * more formatting! * Rhythmone Adapter - schain support (#4414) Circle CI failing tests are not related to this PR. * Media.net Adapter: Support Prebid 3.0 (#4378) * Media.net Adapter: Support Prebid 3.0 * Media.net Adapter: add tests to increase code coverage * Vi Adapter: Passes additional param in the bid request (#4134) * Add focus check (cherry picked from commit 9d6d6dfb83580d6a5ffed8faa5762db48f8fd44d) * Pass focus as numeric value (cherry picked from commit 9fae56a637f87b0d39cc1d24eeb1f9ff9df88f64) * Add unit test (cherry picked from commit 946710f2e9960b3839613d4bdf730e57ba38a964) * Sovrn adapter updates: schain, digitrust, pixel syncing, and 3.0 upgrades (#4385) * schain and digitrust * pixel beacons * unit tests and fixes from testing * Prebid 3.0 updates * review fix * use backwards compatible flatMap impl * update pixel tests * unit test fix * update one more url to ssl * fixed test * review updates * TheMediaGrid Bid Adapter update (#4447) * Added Grid Bid Adapter * remove priceType from TheMediaGrid Bid Adapter * Add video support in Grid Bid Adapter * Added test parameter for video slot * update Grid Bid Adapter to set size in response bid * Update Grid Bid Adapter to support identical uids in parameters * Fix typo in test file for Grid Bid Adapter * Update The Grid Media Bidder Adapter to send refererInfo.referer as 'u' parameter in ad request * Hotfix for referrer in Grid Bid Adapter * Grid Bid Adapter: added wrapperType and wrappweVersion to the ad request * TheMediaGrid Bid Adapter: added sync url * TheMediaGrid Bid Adapter: added GDPR params to sync url * TheMediaGrid Bid Adapter: added tests for getUserSyncs function * Conversant Bid Adapter adds support for extended ids (#4462) * Adkernel 3.0 compatibility (#4477) * Rubicon Adapter pchain support (#4480) * rubicon pchain support * removed describe.only * Implemented changes required to provide support for video in the IX bidding adapter for Instream and Outstream contexts. (#4424) * Default size filter & KVP support (#4452) * adding DMX test @97%, two files added one updated * Update districtm_spec.js * Update districtmDMX.js * adding all districtm needed file * remove legacy file * remove typo || 0 in the test method * force default to return a valid width and height * update unit test code for failing test * changed class for an object * remove package-lock.json * change file name for dmx adapter * renamed files * restaure package-lock.json * update to last package-lock state * update gdpr user consent * fix sizes issue * Documentation updates Adding the readme.md info * update file name and update unit testing import file location * current machine state * lint correction * remove variable assigment duplicate * adding logic upto5 * adding support for removing and shuffle sizes * adding array split test * re-assign none standard size to the request * resolve duplicate format inside format array * update .md and adaptor file for KVP support * remove array helper includes * inforce two digit after decimal * RUn error check nothing on my side but error form another adapter * add id5id to prebid server bid adapter (#4468) * Added _pbjsGlobals for tracking renames. Resolves #4254 (#4419) * Feature/smart video (#4367) * Adding outstream video support. * Fixing unit test. * Adding video instream support. * Handling video startDelay parameter. * Improving unit tests. * Fixing indent. * Handling the request when videoMediaType context is not supported. * Changing maintainer mail address. * Remove video outstream specific code. * Unit test updated. * do not select element that gets removed after dfp render (#4423) * add smms adapter (#4439) * add smms adapter * re-run ci, why adigo adapter failed?? * review comments fix, remove deprecated functions, fix unit test * Prebid 2.41.0 release * Increment pre version * adds schain param (#4442) * Create newborntownWeb adapter (#4455) * Create newborntownWeb adapter * only https protocol * Provide criteoId to server by user.ext.eids (#4478) * ucfunnel adapter fix error message in debug mode (#4338) * Add a new ucfunnel Adapter and test page * Add a new ucfunnel Adapter and test page * 1. Use prebid lib in the repo to keep updated 2. Replace var with let 3. Put JSON.parse(JSON.stringify()) into try catch block * utils.getTopWindowLocation is a function * Change to modules from adapters * Migrate to module design * [Dev Fix] Remove width and height which can be got from ad unit id * Update ucfunnelBidAdapter to fit into new spec * Correct the endpoint. Fix the error of query string * Add test case for ucfunnelBidAdapter * Fix lint error * Update version number * Combine all checks on bid request * Add GDPR support for ucfunnel adapter * Add in-stream video and native support for ucfunnel adapter * Remove demo page. Add more test cases. * Change request method from POST to GET * Remove unnecessary comment * Support vastXml and vastUrl for video request * update TTL to 30 mins * Avoid using arrow function which is not discuraged in mocha * ucfunnel tdid support * ucfunnel fix error message in debug mode * explicitly check undefined to allow falsey values in getConfig (#4486) * Conversant Bid Adapter handles vast xml (#4492) * [feature] Add a config list of submodules that require refreshing the stored ID after each bid request (#4325) * add a feature to always refresh stored id on each bid request for submodules that require that * update test comments * Prebid 2.42.0 Release * Increment pre version * Make adhese adapter prebid 3.0 compatible (#4507) * Added 'adhese' attribute to bid that contains meta data - Jira AD-2642 * added DALE to adhese determination * extra config option: no format, but use size array as format string * Read sizes from mediaTypes.banner.sizes + Apply Eslint suggestions * Use map and join, add originData to response * properly use originData obj * Remove duplicated ids * Update tests * BugFix: Site id missing (#4467) * outstream changes * removing global filtet * reverting page * message * adapter change * remove space * testcases * testpage * spaces for test page * renderer exist case * reverting package-lock.json * adding schain object * adding tagid * syntaxx error fix * video.html * space trailing * space * tagid * inventoryId and placement * rewarded video * added unit test case * adding site id * adding placement and siteis * site id param test case * removing deprecated functions * correcting test cases * indentation * test cases fix * Remove adtarget from aliases * Undo Co-authored-by: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Co-authored-by: Jozef Bartek <31618107+jbartek25@users.noreply.github.com> Co-authored-by: koji-eguchi <50477903+DAC-KOJI-EGUCHI@users.noreply.github.com> Co-authored-by: Telaria Engineering <36203956+telariaEng@users.noreply.github.com> Co-authored-by: Mike Chowla Co-authored-by: robdubois <53589945+robdubois@users.noreply.github.com> Co-authored-by: sumit116 Co-authored-by: nwlosinski Co-authored-by: Bret Gorsline Co-authored-by: bretg Co-authored-by: Artem Seryak Co-authored-by: Jonathan Mullins Co-authored-by: htang555 Co-authored-by: Bryan DeLong Co-authored-by: dpapworth-qc <50959025+dpapworth-qc@users.noreply.github.com> Co-authored-by: DeepthiNeeladri Co-authored-by: Harshad Mane Co-authored-by: Roman Co-authored-by: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Co-authored-by: Margaret Liu Co-authored-by: TJ Eastmond Co-authored-by: Robert Ray Martinez III Co-authored-by: Jason Snellbaker Co-authored-by: JonGoSonobi Co-authored-by: Vladimir Fedoseev Co-authored-by: DJ Rosenbaum Co-authored-by: Alex Khmelnitsky Co-authored-by: adxpremium <55161519+adxpremium@users.noreply.github.com> Co-authored-by: Jimmy Tu Co-authored-by: Pierre-Antoine Durgeat Co-authored-by: Eric Harper Co-authored-by: ujuettner Co-authored-by: Dan Bogdan <43830380+EMXDigital@users.noreply.github.com> Co-authored-by: PWyrembak Co-authored-by: susyt Co-authored-by: Max Crawford Co-authored-by: Pascal S Co-authored-by: Will Chapin Co-authored-by: Lemma Dev <54662130+lemmadev@users.noreply.github.com> Co-authored-by: Denis Logachov Co-authored-by: Léonard Labat Co-authored-by: onlsol <48312668+onlsol@users.noreply.github.com> Co-authored-by: Paul Yang Co-authored-by: Matt Kendall <1870166+mkendall07@users.noreply.github.com> Co-authored-by: Mike Sperone Co-authored-by: sdbaron Co-authored-by: djaxbidder <55269794+djaxbidder@users.noreply.github.com> Co-authored-by: turktelssp <54801433+turktelssp@users.noreply.github.com> Co-authored-by: nkmt <45026101+strong-zero@users.noreply.github.com> Co-authored-by: Mutasem Aldmour Co-authored-by: r-schweitzer <50628828+r-schweitzer@users.noreply.github.com> Co-authored-by: Isaac A. Dettman Co-authored-by: Adasta Media <55529969+Adasta2019@users.noreply.github.com> Co-authored-by: mamatic <52153441+mamatic@users.noreply.github.com> Co-authored-by: Konduit <55142865+konduit-dev@users.noreply.github.com> Co-authored-by: TinchoF <50110327+TinchoF@users.noreply.github.com> Co-authored-by: Jaimin Panchal <7393273+jaiminpanchal27@users.noreply.github.com> Co-authored-by: Jaimin Panchal Co-authored-by: Sergio Co-authored-by: Wayne Yang Co-authored-by: Cody Bonney Co-authored-by: evanmsmrtb Co-authored-by: hdeodhar <35999856+hdeodhar@users.noreply.github.com> Co-authored-by: Oz Weiss Co-authored-by: Janko Ulaga Co-authored-by: thomas-33across <44033452+thomas-33across@users.noreply.github.com> Co-authored-by: Finteza Analytics <45741245+finteza@users.noreply.github.com> Co-authored-by: Vadim Mazzherin Co-authored-by: Hendrik Iseke <39734979+hiseke@users.noreply.github.com> Co-authored-by: Anand Venkatraman Co-authored-by: Eyas Ranjous Co-authored-by: Michael Co-authored-by: hbanalytics <55453525+hbanalytics@users.noreply.github.com> Co-authored-by: Index Exchange 3 Prebid Team Co-authored-by: Michael Kuryshev Co-authored-by: Roffray Co-authored-by: rumesh Co-authored-by: oasis <2394426+bmwcmw@users.noreply.github.com> Co-authored-by: Nepomuk Seiler Co-authored-by: John Salis Co-authored-by: OneTagDevOps <38786435+OneTagDevOps@users.noreply.github.com> Co-authored-by: Ankit Prakash Co-authored-by: Dan Co-authored-by: romanantropov <45817046+romanantropov@users.noreply.github.com> Co-authored-by: msm0504 <51493331+msm0504@users.noreply.github.com> Co-authored-by: vrtcal-dev <50931150+vrtcal-dev@users.noreply.github.com> Co-authored-by: TheMediaGrid <44166371+TheMediaGrid@users.noreply.github.com> Co-authored-by: colbertk <50499465+colbertk@users.noreply.github.com> Co-authored-by: Steve Alliance Co-authored-by: bjorn-lw <32431346+bjorn-lw@users.noreply.github.com> Co-authored-by: 7XBID00 <52267720+7XBID00@users.noreply.github.com> Co-authored-by: Tomas Kovtun Co-authored-by: Olivier Co-authored-by: Gena Co-authored-by: Jonathan Mullins Co-authored-by: ucfunnel <39581136+ucfunnel@users.noreply.github.com> Co-authored-by: ACannuniRP <57228257+ACannuniRP@users.noreply.github.com> Co-authored-by: Hugo Duthil Co-authored-by: skazedo Co-authored-by: 胡雨軒 Петр Co-authored-by: Konrad Dulemba Co-authored-by: Mariya Mego <31904600+mash-a@users.noreply.github.com> Co-authored-by: Daniel Cassidy Co-authored-by: kpis-msa <50609476+kpis-msa@users.noreply.github.com> Co-authored-by: omerBrowsi <54346241+omerBrowsi@users.noreply.github.com> Co-authored-by: Marcian123 Co-authored-by: koji-eguchi <50477903+koji-eguchi@users.noreply.github.com> Co-authored-by: sourabhg Co-authored-by: Alexis Andrieu Co-authored-by: Vlad Gurgov Co-authored-by: Richard Lee <14349+dlackty@users.noreply.github.com> Co-authored-by: Alex Co-authored-by: Vladislav Yatsun Co-authored-by: vincentproxistore <56686565+vincentproxistore@users.noreply.github.com> Co-authored-by: Rich Snapp Co-authored-by: Rade Popovic <32302052+nanointeractive@users.noreply.github.com> Co-authored-by: Matt Quirion Co-authored-by: rhythmonebhaines <49991465+rhythmonebhaines@users.noreply.github.com> Co-authored-by: binoy-chitale Co-authored-by: Alex Pashkov Co-authored-by: harpere Co-authored-by: Scott Co-authored-by: tadam75 Co-authored-by: Veronica Kim <43146383+vkimcm@users.noreply.github.com> Co-authored-by: songtungmtp <57524426+songtungmtp@users.noreply.github.com> Co-authored-by: z-sunshine <33084773+z-sunshine@users.noreply.github.com> Co-authored-by: Sander Co-authored-by: Moshe Moses --- modules/gamoshiBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/gamoshiBidAdapter.js b/modules/gamoshiBidAdapter.js index e052e31cf40..1316d74e430 100644 --- a/modules/gamoshiBidAdapter.js +++ b/modules/gamoshiBidAdapter.js @@ -42,7 +42,7 @@ export const helper = { export const spec = { code: 'gamoshi', - aliases: ['gambid', 'cleanmedia', '9MediaOnline', 'adtarget'], + aliases: ['gambid', 'cleanmedia', '9MediaOnline'], supportedMediaTypes: ['banner', 'video'], isBidRequestValid: function (bid) { From 309c16580b0a39c2954483e632856fa06f7bca20 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Mon, 6 Apr 2020 08:16:46 -0700 Subject: [PATCH 206/496] Pubmatic: setting seat-id and dspid in bid object (#5074) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * PubMatic: setting pm_seat and pm_dspid in bid response * default value for pm_dspid is set to null --- modules/pubmaticBidAdapter.js | 4 +++- test/spec/modules/pubmaticBidAdapter_spec.js | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 605ee69603f..49f193cf93e 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -990,7 +990,9 @@ export const spec = { netRevenue: NET_REVENUE, ttl: 300, referrer: parsedReferrer, - ad: bid.adm + ad: bid.adm, + pm_seat: seatbidder.seat || null, + pm_dspid: bid.ext && bid.ext.dspid ? bid.ext.dspid : null }; if (parsedRequest.imp && parsedRequest.imp.length > 0) { parsedRequest.imp.forEach(req => { diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 62dd76f04b6..36b984296fc 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -533,6 +533,7 @@ describe('PubMatic adapter', function () { 'body': { 'id': '93D3BAD6-E2E2-49FB-9D89-920B1761C865', 'seatbid': [{ + 'seat': 'seat-id', 'bid': [{ 'id': '74858439-49D7-4169-BA5D-44A046315B2F', 'impid': '22bddb28db77d', @@ -2561,6 +2562,8 @@ describe('PubMatic adapter', function () { expect(response[0].meta.clickUrl).to.equal('blackrock.com'); expect(response[0].referrer).to.include(data.site.ref); expect(response[0].ad).to.equal(bidResponses.body.seatbid[0].bid[0].adm); + expect(response[0].pm_seat).to.equal(bidResponses.body.seatbid[0].seat); + expect(response[0].pm_dspid).to.equal(bidResponses.body.seatbid[0].bid[0].ext.dspid); expect(response[1].requestId).to.equal(bidResponses.body.seatbid[1].bid[0].impid); expect(response[1].cpm).to.equal((bidResponses.body.seatbid[1].bid[0].price).toFixed(2)); @@ -2580,6 +2583,8 @@ describe('PubMatic adapter', function () { expect(response[1].meta.clickUrl).to.equal('hivehome.com'); expect(response[1].referrer).to.include(data.site.ref); expect(response[1].ad).to.equal(bidResponses.body.seatbid[1].bid[0].adm); + expect(response[1].pm_seat).to.equal(bidResponses.body.seatbid[1].seat || null); + expect(response[1].pm_dspid).to.equal(bidResponses.body.seatbid[1].bid[0].ext.dspid); }); it('should check for dealChannel value selection', function () { From 59ccbbf7452c110e4558a73b97ecda601e57d2f5 Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Mon, 6 Apr 2020 08:54:08 -0700 Subject: [PATCH 207/496] Fix bug in rubicon bid adapter for fpd keywords (#5078) Co-authored-by: rmartinez --- modules/rubiconBidAdapter.js | 2 +- test/spec/modules/rubiconBidAdapter_spec.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index 616a17f470f..9131a8cb581 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -575,7 +575,7 @@ export const spec = { const keywords = (params.keywords || []).concat( utils.deepAccess(config.getConfig('fpd.user'), 'keywords') || [], utils.deepAccess(config.getConfig('fpd.context'), 'keywords') || []); - data.kw = keywords.length ? keywords.join(',') : ''; + data.kw = Array.isArray(keywords) && keywords.length ? keywords.join(',') : ''; /** * Prebid AdSlot diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 4e999f4bdab..29cc6cb2c0a 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -1924,6 +1924,12 @@ describe('the rubicon adapter', function () { } }); }); + + it('should not fail if keywords param is not an array', function () { + bidderRequest.bids[0].params.keywords = 'a,b,c'; + const slotParams = spec.createSlotParams(bidderRequest.bids[0], bidderRequest); + expect(slotParams.kw).to.equal(''); + }); }); describe('hasVideoMediaType', function () { From 753fcc848be3331cb32a6abe7256696af46cf228 Mon Sep 17 00:00:00 2001 From: Denis Logachov Date: Mon, 6 Apr 2020 19:52:16 +0300 Subject: [PATCH 208/496] Native support for AdKernel adapter (#5045) * Native support for adkernel adapter * Updated doc --- modules/adkernelBidAdapter.js | 136 ++++++++++++++++- modules/adkernelBidAdapter.md | 98 +++++++----- test/spec/modules/adkernelBidAdapter_spec.js | 150 ++++++++++++++++--- 3 files changed, 326 insertions(+), 58 deletions(-) diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index 18c60c3e438..dbb0f4a3344 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -1,5 +1,5 @@ import * as utils from '../src/utils.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import find from 'core-js/library/fn/array/find.js'; import includes from 'core-js/library/fn/array/includes.js'; @@ -15,7 +15,30 @@ import {parse as parseUrl} from '../src/url.js'; const VIDEO_TARGETING = ['mimes', 'minduration', 'maxduration', 'protocols', 'startdelay', 'linearity', 'boxingallowed', 'playbackmethod', 'delivery', 'pos', 'api', 'ext']; -const VERSION = '1.3'; +const VERSION = '1.4'; + +const NATIVE_MODEL = [ + {name: 'title', assetType: 'title'}, + {name: 'icon', assetType: 'img', type: 1}, + {name: 'image', assetType: 'img', type: 3}, + {name: 'body', assetType: 'data', type: 2}, + {name: 'body2', assetType: 'data', type: 10}, + {name: 'sponsoredBy', assetType: 'data', type: 1}, + {name: 'phone', assetType: 'data', type: 8}, + {name: 'address', assetType: 'data', type: 9}, + {name: 'price', assetType: 'data', type: 6}, + {name: 'salePrice', assetType: 'data', type: 7}, + {name: 'cta', assetType: 'data', type: 12}, + {name: 'rating', assetType: 'data', type: 3}, + {name: 'downloads', assetType: 'data', type: 5}, + {name: 'likes', assetType: 'data', type: 4}, + {name: 'displayUrl', assetType: 'data', type: 11} +]; + +const NATIVE_INDEX = NATIVE_MODEL.reduce((acc, val, idx) => { + acc[val.name] = {id: idx, ...val}; + return acc; +}, {}); /** * Adapter for requesting bids from AdKernel white-label display platform @@ -24,7 +47,7 @@ export const spec = { code: 'adkernel', aliases: ['headbidding', 'adsolut', 'oftmediahb', 'audiencemedia', 'waardex_ak', 'roqoon'], - supportedMediaTypes: [BANNER, VIDEO], + supportedMediaTypes: [BANNER, VIDEO, NATIVE], isBidRequestValid: function(bidRequest) { return 'params' in bidRequest && typeof bidRequest.params.host !== 'undefined' && @@ -32,7 +55,7 @@ export const spec = { !isNaN(Number(bidRequest.params.zoneId)) && bidRequest.params.zoneId > 0 && bidRequest.mediaTypes && - (bidRequest.mediaTypes.banner || bidRequest.mediaTypes.video); + (bidRequest.mediaTypes.banner || bidRequest.mediaTypes.video || (bidRequest.mediaTypes.native && validateNativeAdUnit(bidRequest.mediaTypes.native))); }, buildRequests: function(bidRequests, bidderRequest) { let impDispatch = dispatchImps(bidRequests, bidderRequest.refererInfo); @@ -76,12 +99,14 @@ export const spec = { prBid.width = rtbBid.w; prBid.height = rtbBid.h; prBid.ad = formatAdMarkup(rtbBid); - } - if ('video' in imp) { + } else if ('video' in imp) { prBid.mediaType = VIDEO; prBid.vastUrl = rtbBid.nurl; prBid.width = imp.video.w; prBid.height = imp.video.h; + } else if ('native' in imp) { + prBid.mediaType = NATIVE; + prBid.native = buildNativeAd(JSON.parse(rtbBid.adm)); } return prBid; }); @@ -138,6 +163,12 @@ function buildImp(bidRequest, secure) { .filter(key => includes(VIDEO_TARGETING, key)) .forEach(key => imp.video[key] = bidRequest.params.video[key]); } + } else if (utils.deepAccess(bidRequest, 'mediaTypes.native')) { + let nativeRequest = buildNativeRequest(bidRequest.mediaTypes.native); + imp.native = { + ver: '1.1', + request: JSON.stringify(nativeRequest) + } } if (secure) { imp.secure = 1; @@ -145,6 +176,51 @@ function buildImp(bidRequest, secure) { return imp; } +/** + * Builds native request from native adunit + */ +function buildNativeRequest(nativeReq) { + let request = {ver: '1.1', assets: []}; + for (let k of Object.keys(nativeReq)) { + let v = nativeReq[k]; + let desc = NATIVE_INDEX[k]; + if (desc === undefined) { + continue; + } + let assetRoot = { + id: desc.id, + required: ~~v.required, + }; + if (desc.assetType === 'img') { + assetRoot[desc.assetType] = buildImageAsset(desc, v); + } else if (desc.assetType === 'data') { + assetRoot.data = utils.cleanObj({type: desc.type, len: v.len}); + } else if (desc.assetType === 'title') { + assetRoot.title = {len: v.len || 90}; + } else { + return; + } + request.assets.push(assetRoot); + } + return request; +} + +/** + * Builds image asset request + */ +function buildImageAsset(desc, val) { + let img = { + type: desc.type + }; + if (val.sizes) { + [img.w, img.h] = val.sizes; + } else if (val.aspect_ratios) { + img.wmin = val.aspect_ratios[0].min_width; + img.hmin = val.aspect_ratios[0].min_height; + } + return utils.cleanObj(img); +} + /** * Builds complete rtb request * @param imps collection of impressions @@ -224,3 +300,51 @@ function formatAdMarkup(bid) { } return adm; } + +/** + * Basic validates to comply with platform requirements + */ +function validateNativeAdUnit(adUnit) { + return validateNativeImageSize(adUnit.image) && validateNativeImageSize(adUnit.icon) && + !utils.deepAccess(adUnit, 'privacyLink.required') && // not supported yet + !utils.deepAccess(adUnit, 'privacyIcon.required'); // not supported yet +} + +/** + * Validates image asset size definition + */ +function validateNativeImageSize(img) { + if (!img) { + return true; + } + if (img.sizes) { + return utils.isArrayOfNums(img.sizes, 2); + } + if (utils.isArray(img.aspect_ratios)) { + return img.aspect_ratios.length > 0 && img.aspect_ratios[0].min_height && img.aspect_ratios[0].min_width; + } + return true; +} + +/** + * Creates native ad for native 1.1 response + */ +function buildNativeAd(nativeResp) { + const {assets, link, imptrackers, jstracker, privacy} = nativeResp.native; + let nativeAd = { + clickUrl: link.url, + impressionTrackers: imptrackers, + javascriptTrackers: jstracker ? [jstracker] : undefined, + privacyLink: privacy, + }; + utils._each(assets, asset => { + let assetName = NATIVE_MODEL[asset.id].name; + let assetType = NATIVE_MODEL[asset.id].assetType; + nativeAd[assetName] = asset[assetType].text || asset[assetType].value || utils.cleanObj({ + url: asset[assetType].url, + width: asset[assetType].w, + height: asset[assetType].h + }); + }); + return utils.cleanObj(nativeAd); +} diff --git a/modules/adkernelBidAdapter.md b/modules/adkernelBidAdapter.md index f89fa5a26df..b3854d721ad 100644 --- a/modules/adkernelBidAdapter.md +++ b/modules/adkernelBidAdapter.md @@ -9,43 +9,71 @@ Maintainer: prebid-dev@adkernel.com # Description Connects to AdKernel whitelabel platform. -Banner and video formats are supported. +Banner, video and native formats are supported. # Test Parameters ``` - var adUnits = [{ - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], // banner size - } - }, - bids: [ - { - bidder: 'adkernel', - params: { - zoneId: '30164', //required parameter - host: 'cpm.metaadserving.com' //required parameter - } - } - ] - }, { - code: 'video-ad-player', - mediaTypes: { - video: { - context: 'instream', // or 'outstream' - playerSize: [640, 480] // video player size - } - }, - bids: [ - { - bidder: 'adkernel', - params: { - zoneId: '30164', //required parameter - host: 'cpm.metaadserving.com' //required parameter - } - } - ] - }]; +var adUnits = [{ + code: 'banner-ad-div', + mediaTypes: { + banner: { + sizes: [[300, 250]], // banner size + } + }, + bids: [{ + bidder: 'adkernel', + params: { + zoneId: '30164', //required parameter + host: 'cpm.metaadserving.com' //required parameter + } + }] +}, { + code: 'video-ad-player', + mediaTypes: { + video: { + context: 'instream', // or 'outstream' + playerSize: [640, 480] // video player size + } + }, + bids: [{ + bidder: 'adkernel', + params: { + zoneId: '30164', //required parameter + host: 'cpm.metaadserving.com' //required parameter + } + }] +}, { + code: 'native-ad', + mediaTypes: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + }, + sponsoredBy: { + required: true + }, + clickUrl: { + required: true + }, + displayUrl: { + required: false + } + } + }, + bids: [{ + bidder: 'adkernel', + params: { + host: 'cpm.metaadserving.com', + zoneId: 30164 + } + }] +}]; ``` diff --git a/test/spec/modules/adkernelBidAdapter_spec.js b/test/spec/modules/adkernelBidAdapter_spec.js index 3ae37592f1e..ef95febf13d 100644 --- a/test/spec/modules/adkernelBidAdapter_spec.js +++ b/test/spec/modules/adkernelBidAdapter_spec.js @@ -1,6 +1,7 @@ import {expect} from 'chai'; import {spec} from 'modules/adkernelBidAdapter.js'; import * as utils from 'src/utils.js'; +import {NATIVE, BANNER, VIDEO} from 'src/mediaTypes'; describe('Adkernel adapter', function () { const bid1_zone1 = { @@ -105,6 +106,57 @@ describe('Adkernel adapter', function () { bidId: 'Bid_01', bidderRequestId: 'req-001', auctionId: 'auc-001' + }, bid_native = { + bidder: 'adkernel', + params: {zoneId: 1, host: 'rtb.adkernel.com'}, + mediaTypes: { + native: { + title: { + required: true, + len: 80 + }, + body: { + required: true + }, + body2: { + required: true + }, + icon: { + required: true, + aspect_ratios: [{min_width: 50, min_height: 50}] + }, + image: { + required: true, + sizes: [300, 200] + }, + clickUrl: { + required: true + }, + rating: { + required: false + }, + price: { + required: false + }, + privacyLink: { + required: false + }, + cta: { + required: false + }, + sponsoredBy: { + required: false + }, + displayUrl: { + required: false + } + } + }, + adUnitCode: 'ad-unit-1', + transactionId: 'f82c64b8-c602-42a4-9791-4a268f6559ed', + bidId: 'Bid_01', + bidderRequestId: 'req-001', + auctionId: 'auc-001' }; const bidResponse1 = { @@ -125,20 +177,6 @@ describe('Adkernel adapter', function () { ext: { adk_usersync: ['https://adk.sync.com/sync'] } - }, bidResponse2 = { - id: 'bid2', - seatbid: [{ - bid: [{ - id: '2', - impid: 'Bid_02', - crid: '100_002', - price: 1.31, - adm: '', - w: 300, - h: 250 - }] - }], - cur: 'USD' }, videoBidResponse = { id: '47ce4badcf7482', seatbid: [{ @@ -158,6 +196,36 @@ describe('Adkernel adapter', function () { ext: { adk_usersync: ['https://adk.sync.com/sync'] } + }, nativeResponse = { + id: '56fbc713-b737-4651-9050-13376aed9818', + seatbid: [{ + bid: [{ + id: 'someid_01', + impid: 'Bid_01', + price: 2.25, + adid: '4', + adm: JSON.stringify({ + native: { + assets: [ + {id: 0, title: {text: 'Title'}}, + {id: 3, data: {value: 'Description'}}, + {id: 4, data: {value: 'Additional description'}}, + {id: 1, img: {url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0&imgt=icon', w: 50, h: 50}}, + {id: 2, img: {url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0', w: 300, h: 200}}, + {id: 5, data: {value: 'Sponsor.com'}}, + {id: 14, data: {value: 'displayurl.com'}} + ], + link: {url: 'http://rtb.com/click?i=pTuOlf5KHUo_0'}, + imptrackers: ['http://rtb.com/win?i=pTuOlf5KHUo_0&f=imp'] + } + }), + adomain: ['displayurl.com'], + cid: '1', + crid: '4' + }] + }], + bidid: 'pTuOlf5KHUo', + cur: 'USD' }; function buildBidderRequest(url = 'https://example.com/index.html', params = {}) { @@ -191,6 +259,10 @@ describe('Adkernel adapter', function () { it('empty request shouldn\'t generate exception', function () { expect(spec.isBidRequestValid(bid_with_wrong_zoneId)).to.be.equal(false); }); + + it('valid native requests should pass', () => { + expect(spec.isBidRequestValid(bid_native)).to.be.equal(true); + }) }); describe('banner request building', function () { @@ -270,7 +342,6 @@ describe('Adkernel adapter', function () { it('should forward default bidder timeout', function() { let [_, bidRequests] = buildRequest([bid1_zone1], DEFAULT_BIDDER_REQUEST); - let bidRequest = bidRequests[0]; expect(bidRequests[0]).to.have.property('tmax', 3000); }); }); @@ -343,7 +414,7 @@ describe('Adkernel adapter', function () { expect(resp).to.have.property('creativeId', '100_001'); expect(resp).to.have.property('currency'); expect(resp).to.have.property('ttl'); - expect(resp).to.have.property('mediaType', 'banner'); + expect(resp).to.have.property('mediaType', BANNER); expect(resp).to.have.property('ad'); expect(resp.ad).to.have.string(''); }); @@ -352,7 +423,7 @@ describe('Adkernel adapter', function () { let [pbRequests, _] = buildRequest([bid_video]); let resp = spec.interpretResponse({body: videoBidResponse}, pbRequests[0])[0]; expect(resp).to.have.property('requestId', 'Bid_Video'); - expect(resp.mediaType).to.equal('video'); + expect(resp.mediaType).to.equal(VIDEO); expect(resp.cpm).to.equal(0.00145); expect(resp.vastUrl).to.equal('https://rtb.com/win?i=sZSYq5zYMxo_0&f=nurl'); expect(resp.width).to.equal(640); @@ -388,4 +459,49 @@ describe('Adkernel adapter', function () { expect(spec.aliases).to.include.members(['headbidding', 'adsolut', 'oftmediahb', 'audiencemedia', 'waardex_ak', 'roqoon']); }); }); + + describe('native support', () => { + let _, bidRequests; + before(function () { + [_, bidRequests] = buildRequest([bid_native]); + }); + + it('native request building', () => { + expect(bidRequests[0].imp).to.have.length(1); + expect(bidRequests[0].imp[0]).to.have.property('native'); + expect(bidRequests[0].imp[0].native).to.have.property('request'); + let request = JSON.parse(bidRequests[0].imp[0].native.request); + expect(request).to.have.property('ver', '1.1'); + expect(request.assets).to.have.length(10); + expect(request.assets[0]).to.be.eql({id: 0, required: 1, title: {len: 80}}); + expect(request.assets[1]).to.be.eql({id: 3, required: 1, data: {type: 2}}); + expect(request.assets[2]).to.be.eql({id: 4, required: 1, data: {type: 10}}); + expect(request.assets[3]).to.be.eql({id: 1, required: 1, img: {wmin: 50, hmin: 50, type: 1}}); + expect(request.assets[4]).to.be.eql({id: 2, required: 1, img: {w: 300, h: 200, type: 3}}); + expect(request.assets[5]).to.be.eql({id: 11, required: 0, data: {type: 3}}); + expect(request.assets[6]).to.be.eql({id: 8, required: 0, data: {type: 6}}); + expect(request.assets[7]).to.be.eql({id: 10, required: 0, data: {type: 12}}); + expect(request.assets[8]).to.be.eql({id: 5, required: 0, data: {type: 1}}); + expect(request.assets[9]).to.be.eql({id: 14, required: 0, data: {type: 11}}); + }); + + it('native response processing', () => { + let [pbRequests, _] = buildRequest([bid_native]); + let resp = spec.interpretResponse({body: nativeResponse}, pbRequests[0])[0]; + expect(resp).to.have.property('requestId', 'Bid_01'); + expect(resp).to.have.property('cpm', 2.25); + expect(resp).to.have.property('currency', 'USD'); + expect(resp).to.have.property('mediaType', NATIVE); + expect(resp).to.have.property('native'); + expect(resp.native).to.have.property('clickUrl', 'http://rtb.com/click?i=pTuOlf5KHUo_0'); + expect(resp.native.impressionTrackers).to.be.eql(['http://rtb.com/win?i=pTuOlf5KHUo_0&f=imp']); + expect(resp.native).to.have.property('title', 'Title'); + expect(resp.native).to.have.property('body', 'Description'); + expect(resp.native).to.have.property('body2', 'Additional description'); + expect(resp.native.icon).to.be.eql({url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0&imgt=icon', width: 50, height: 50}); + expect(resp.native.image).to.be.eql({url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0', width: 300, height: 200}); + expect(resp.native).to.have.property('sponsoredBy', 'Sponsor.com'); + expect(resp.native).to.have.property('displayUrl', 'displayurl.com'); + }); + }); }); From b297edf5afa74c38269010f31410757a8ccd63e2 Mon Sep 17 00:00:00 2001 From: bidlab <61749467+bidlab@users.noreply.github.com> Date: Tue, 7 Apr 2020 01:07:41 +0300 Subject: [PATCH 209/496] New bidlab prebid adapter (#5020) * initial * fix * initial --- modules/bidlabBidAdapter.js | 112 ++++++++++ modules/bidlabBidAdapter.md | 53 +++++ test/spec/modules/bidlabBidAdapter_spec.js | 235 +++++++++++++++++++++ 3 files changed, 400 insertions(+) create mode 100644 modules/bidlabBidAdapter.js create mode 100644 modules/bidlabBidAdapter.md create mode 100644 test/spec/modules/bidlabBidAdapter_spec.js diff --git a/modules/bidlabBidAdapter.js b/modules/bidlabBidAdapter.js new file mode 100644 index 00000000000..8f501505a6d --- /dev/null +++ b/modules/bidlabBidAdapter.js @@ -0,0 +1,112 @@ +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; + +const BIDDER_CODE = 'bidlab'; +const AD_URL = 'https://service.bidlab.ai/?c=o&m=multi'; +const URL_SYNC = 'https://service.bidlab.ai/?c=o&m=sync'; +const NO_SYNC = true; + +function isBidResponseValid(bid) { + if (!bid.requestId || !bid.cpm || !bid.creativeId || + !bid.ttl || !bid.currency) { + return false; + } + switch (bid.mediaType) { + case BANNER: + return Boolean(bid.width && bid.height && bid.ad); + case VIDEO: + return Boolean(bid.vastUrl); + case NATIVE: + return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); + default: + return false; + } +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + noSync: NO_SYNC, + + isBidRequestValid: (bid) => { + return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId))); + }, + + buildRequests: (validBidRequests = [], bidderRequest) => { + let winTop = window; + let location; + try { + location = new URL(bidderRequest.refererInfo.referer) + winTop = window.top; + } catch (e) { + location = winTop.location; + utils.logMessage(e); + }; + let placements = []; + let request = { + 'deviceWidth': winTop.screen.width, + 'deviceHeight': winTop.screen.height, + 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', + 'secure': 1, + 'host': location.host, + 'page': location.pathname, + 'placements': placements + }; + request.language.indexOf('-') != -1 && (request.language = request.language.split('-')[0]) + if (bidderRequest) { + if (bidderRequest.uspConsent) { + request.ccpa = bidderRequest.uspConsent; + } + if (bidderRequest.gdprConsent) { + request.gdpr = bidderRequest.gdprConsent + } + } + const len = validBidRequests.length; + + for (let i = 0; i < len; i++) { + let bid = validBidRequests[i]; + let traff = bid.params.traffic || BANNER + + placements.push({ + placementId: bid.params.placementId, + bidId: bid.bidId, + sizes: bid.mediaTypes && bid.mediaTypes[traff] && bid.mediaTypes[traff].sizes ? bid.mediaTypes[traff].sizes : [], + traffic: traff + }); + if (bid.schain) { + placements.schain = bid.schain; + } + } + return { + method: 'POST', + url: AD_URL, + data: request + }; + }, + + interpretResponse: (serverResponse) => { + let response = []; + for (let i = 0; i < serverResponse.body.length; i++) { + let resItem = serverResponse.body[i]; + if (isBidResponseValid(resItem)) { + response.push(resItem); + } + } + return response; + }, + + getUserSyncs: (syncOptions, serverResponses) => { + if (NO_SYNC) { + return false + } else { + return [{ + type: 'image', + url: URL_SYNC + }]; + } + } + +}; + +registerBidder(spec); diff --git a/modules/bidlabBidAdapter.md b/modules/bidlabBidAdapter.md new file mode 100644 index 00000000000..3e5fe3128ed --- /dev/null +++ b/modules/bidlabBidAdapter.md @@ -0,0 +1,53 @@ +# Overview + +``` +Module Name: bidlab Bidder Adapter +Module Type: bidlab Bidder Adapter +``` + +# Description + +Module that connects to bidlab demand sources + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'placementId_0', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [ + { + bidder: 'bidlab', + params: { + placementId: 0, + traffic: 'banner' + } + } + ] + }, + // Will return test vast xml. All video params are stored under placement in publishers UI + { + code: 'placementId_0', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream' + } + }, + bids: [ + { + bidder: 'bidlab', + params: { + placementId: 0, + traffic: 'video' + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/bidlabBidAdapter_spec.js b/test/spec/modules/bidlabBidAdapter_spec.js new file mode 100644 index 00000000000..cffd43ae6ca --- /dev/null +++ b/test/spec/modules/bidlabBidAdapter_spec.js @@ -0,0 +1,235 @@ +import {expect} from 'chai'; +import {spec} from '../../../modules/bidlabBidAdapter.js'; + +describe('BidlabBidAdapter', function () { + let bid = { + bidId: '23fhj33i987f', + bidder: 'bidlab', + params: { + placementId: 0, + traffic: 'banner' + } + }; + + describe('isBidRequestValid', function () { + it('Should return true if there are bidId, params and placementId parameters present', function () { + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + it('Should return false if at least one of parameters is not present', function () { + delete bid.params.placementId; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests([bid]); + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + it('Returns valid URL', function () { + expect(serverRequest.url).to.equal('https://service.bidlab.ai/?c=o&m=multi'); + }); + it('Returns valid data if array of bids is valid', function () { + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.language).to.be.a('string'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + let placement = data['placements'][0]; + expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes'); + expect(placement.placementId).to.equal(0); + expect(placement.bidId).to.equal('23fhj33i987f'); + expect(placement.traffic).to.equal('banner'); + }); + it('Returns empty data if no valid requests are passed', function () { + serverRequest = spec.buildRequests([]); + let data = serverRequest.data; + expect(data.placements).to.be.an('array').that.is.empty; + }); + }); + describe('interpretResponse', function () { + it('Should interpret banner response', function () { + const banner = { + body: [{ + mediaType: 'banner', + width: 300, + height: 250, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let bannerResponses = spec.interpretResponse(banner); + expect(bannerResponses).to.be.an('array').that.is.not.empty; + let dataItem = bannerResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.width).to.equal(300); + expect(dataItem.height).to.equal(250); + expect(dataItem.ad).to.equal('Test'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret video response', function () { + const video = { + body: [{ + vastUrl: 'test.com', + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let videoResponses = spec.interpretResponse(video); + expect(videoResponses).to.be.an('array').that.is.not.empty; + + let dataItem = videoResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.5); + expect(dataItem.vastUrl).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret native response', function () { + const native = { + body: [{ + mediaType: 'native', + native: { + clickUrl: 'test.com', + title: 'Test', + image: 'test.com', + impressionTrackers: ['test.com'], + }, + ttl: 120, + cpm: 0.4, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let nativeResponses = spec.interpretResponse(native); + expect(nativeResponses).to.be.an('array').that.is.not.empty; + + let dataItem = nativeResponses[0]; + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); + expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.native.clickUrl).to.equal('test.com'); + expect(dataItem.native.title).to.equal('Test'); + expect(dataItem.native.image).to.equal('test.com'); + expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; + expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should return an empty array if invalid banner response is passed', function () { + const invBanner = { + body: [{ + width: 300, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + + let serverResponses = spec.interpretResponse(invBanner); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid video response is passed', function () { + const invVideo = { + body: [{ + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invVideo); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid native response is passed', function () { + const invNative = { + body: [{ + mediaType: 'native', + clickUrl: 'test.com', + title: 'Test', + impressionTrackers: ['test.com'], + ttl: 120, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let serverResponses = spec.interpretResponse(invNative); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid response is passed', function () { + const invalid = { + body: [{ + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invalid); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); + describe('getUserSyncs', function () { + let userSync = spec.getUserSyncs(); + it('Returns valid URL and type', function () { + if (spec.noSync) { + expect(userSync).to.be.equal(false); + } else { + expect(userSync).to.be.an('array').with.lengthOf(1); + expect(userSync[0].type).to.exist; + expect(userSync[0].url).to.exist; + expect(userSync[0].type).to.be.equal('image'); + expect(userSync[0].url).to.be.equal('https://service.bidlab.ai/?c=o&m=sync'); + } + }); + }); +}); From 4def1cf5bbc3d6be46469a6f9096f72e6b65cc50 Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Mon, 6 Apr 2020 15:09:31 -0700 Subject: [PATCH 210/496] Surrounding adapter calls in try (#4915) * Surrounding adapter calls in try Several test flakyness updates * adding test * const instead of let Co-authored-by: rmartinez --- src/adapterManager.js | 32 +++++++++------ .../modules/adomikAnalyticsAdapter_spec.js | 9 +++- test/spec/unit/core/adapterManager_spec.js | 41 +++++++++++++++++++ test/spec/unit/pbjs_api_spec.js | 8 +++- 4 files changed, 73 insertions(+), 17 deletions(-) diff --git a/src/adapterManager.js b/src/adapterManager.js index 9886934ab47..f658a36aeda 100644 --- a/src/adapterManager.js +++ b/src/adapterManager.js @@ -368,19 +368,25 @@ adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, request request: requestCallbacks.request.bind(null, bidRequest.bidderCode), done: requestCallbacks.done } : undefined); - config.runWithBidder( - bidRequest.bidderCode, - bind.call( - adapter.callBids, - adapter, - bidRequest, - addBidResponse.bind(bidRequest), - doneCb.bind(bidRequest), - ajax, - onTimelyResponse, - config.callbackWithBidder(bidRequest.bidderCode) - ) - ); + const adapterDone = doneCb.bind(bidRequest); + try { + config.runWithBidder( + bidRequest.bidderCode, + bind.call( + adapter.callBids, + adapter, + bidRequest, + addBidResponse.bind(bidRequest), + adapterDone, + ajax, + onTimelyResponse, + config.callbackWithBidder(bidRequest.bidderCode) + ) + ); + } catch (e) { + utils.logError(`${bidRequest.bidderCode} Bid Adapter emitted an uncaught error when parsing their bidRequest`, {e, bidRequest}); + adapterDone(); + } }); }; diff --git a/test/spec/modules/adomikAnalyticsAdapter_spec.js b/test/spec/modules/adomikAnalyticsAdapter_spec.js index a067ce2770e..1414b2402b9 100644 --- a/test/spec/modules/adomikAnalyticsAdapter_spec.js +++ b/test/spec/modules/adomikAnalyticsAdapter_spec.js @@ -7,6 +7,13 @@ let constants = require('src/constants.json'); describe('Adomik Prebid Analytic', function () { let sendEventStub; let sendWonEventStub; + let clock; + before(function () { + clock = sinon.useFakeTimers(); + }); + after(function () { + clock.restore(); + }); describe('enableAnalytics', function () { beforeEach(function () { @@ -120,7 +127,6 @@ describe('Adomik Prebid Analytic', function () { expect(adomikAnalytics.currentContext.timeouted).to.equal(true); // Step 7: Send auction end event - var clock = sinon.useFakeTimers(); events.emit(constants.EVENTS.AUCTION_END, {}); setTimeout(function() { @@ -130,7 +136,6 @@ describe('Adomik Prebid Analytic', function () { }, 3000); clock.tick(5000); - clock.restore(); sinon.assert.callCount(adomikAnalytics.track, 6); }); diff --git a/test/spec/unit/core/adapterManager_spec.js b/test/spec/unit/core/adapterManager_spec.js index 566ebe2e400..29bba0ec0a0 100644 --- a/test/spec/unit/core/adapterManager_spec.js +++ b/test/spec/unit/core/adapterManager_spec.js @@ -43,16 +43,23 @@ var rubiconAdapterMock = { callBids: sinon.stub() }; +var badAdapterMock = { + bidder: 'badBidder', + callBids: sinon.stub().throws(Error('some fake error')) +}; + describe('adapterManager tests', function () { let orgAppnexusAdapter; let orgAdequantAdapter; let orgPrebidServerAdapter; let orgRubiconAdapter; + let orgBadBidderAdapter; before(function () { orgAppnexusAdapter = adapterManager.bidderRegistry['appnexus']; orgAdequantAdapter = adapterManager.bidderRegistry['adequant']; orgPrebidServerAdapter = adapterManager.bidderRegistry['prebidServer']; orgRubiconAdapter = adapterManager.bidderRegistry['rubicon']; + orgBadBidderAdapter = adapterManager.bidderRegistry['badBidder']; }); after(function () { @@ -60,6 +67,7 @@ describe('adapterManager tests', function () { adapterManager.bidderRegistry['adequant'] = orgAdequantAdapter; adapterManager.bidderRegistry['prebidServer'] = orgPrebidServerAdapter; adapterManager.bidderRegistry['rubicon'] = orgRubiconAdapter; + adapterManager.bidderRegistry['badBidder'] = orgBadBidderAdapter; config.setConfig({s2sConfig: { enabled: false }}); }); @@ -72,11 +80,16 @@ describe('adapterManager tests', function () { sinon.stub(utils, 'logError'); appnexusAdapterMock.callBids.reset(); adapterManager.bidderRegistry['appnexus'] = appnexusAdapterMock; + adapterManager.bidderRegistry['rubicon'] = rubiconAdapterMock; + adapterManager.bidderRegistry['badBidder'] = badAdapterMock; }); afterEach(function () { utils.logError.restore(); delete adapterManager.bidderRegistry['appnexus']; + delete adapterManager.bidderRegistry['rubicon']; + delete adapterManager.bidderRegistry['badBidder']; + config.resetConfig(); }); it('should log an error if a bidder is used that does not exist', function () { @@ -95,6 +108,34 @@ describe('adapterManager tests', function () { sinon.assert.called(utils.logError); }); + it('should catch a bidder adapter thrown error and continue with other bidders', function () { + const adUnits = [{ + code: 'adUnit-code', + sizes: [[728, 90]], + bids: [ + {bidder: 'appnexus', params: {placementId: 'id'}}, + {bidder: 'badBidder', params: {placementId: 'id'}}, + {bidder: 'rubicon', params: {account: 1111, site: 2222, zone: 3333}} + ] + }]; + let bidRequests = adapterManager.makeBidRequests(adUnits, 1111, 2222, 1000); + + let doneBidders = []; + function mockDoneCB() { + doneBidders.push(this.bidderCode) + } + adapterManager.callBids(adUnits, bidRequests, () => {}, mockDoneCB); + sinon.assert.calledOnce(appnexusAdapterMock.callBids); + sinon.assert.calledOnce(badAdapterMock.callBids); + sinon.assert.calledOnce(rubiconAdapterMock.callBids); + + expect(utils.logError.calledOnce).to.be.true; + expect(utils.logError.calledWith( + 'badBidder Bid Adapter emitted an uncaught error when parsing their bidRequest' + )).to.be.true; + // done should be called for our bidder! + expect(doneBidders.indexOf('badBidder') === -1).to.be.false; + }); it('should emit BID_REQUESTED event', function () { // function to count BID_REQUESTED events let cnt = 0; diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index cfdd39239d3..252c074cd61 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -1223,6 +1223,12 @@ describe('Unit: Prebid Module', function () { let makeRequestsStub; let adUnits; let clock; + before(function () { + clock = sinon.useFakeTimers(); + }); + after(function () { + clock.restore(); + }); let bidsBackHandlerStub = sinon.stub(); const BIDDER_CODE = 'sampleBidder'; @@ -1309,7 +1315,6 @@ describe('Unit: Prebid Module', function () { spec.isBidRequestValid.returns(true); spec.interpretResponse.returns(bids); - clock = sinon.useFakeTimers(); let requestObj = { bidsBackHandler: null, // does not need to be defined because of newAuction mock in beforeEach timeout: 2000, @@ -1363,7 +1368,6 @@ describe('Unit: Prebid Module', function () { auction.getBidsReceived = function() { return [adResponse]; } auction.getAuctionId = () => auctionId; - clock = sinon.useFakeTimers(); let requestObj = { bidsBackHandler: null, // does not need to be defined because of newAuction mock in beforeEach timeout: 2000, From 3dfc7384402d3d70dc0d1014e2ec0a32c1e472c9 Mon Sep 17 00:00:00 2001 From: Olivier Date: Tue, 7 Apr 2020 10:16:05 +0200 Subject: [PATCH 211/496] AdagiobidAdapter 2.2.0: schain, tcf 2.0 (#5059) * adagioBidAdapter: add schain support * adagioBidAdapter: bump version 2.2.0 * AdagioBidAdapter: send GDPR api version in request --- modules/adagioBidAdapter.js | 13 ++- test/spec/modules/adagioBidAdapter_spec.js | 97 +++++++++++++++++++++- 2 files changed, 107 insertions(+), 3 deletions(-) diff --git a/modules/adagioBidAdapter.js b/modules/adagioBidAdapter.js index 8b593c34270..484371261e3 100644 --- a/modules/adagioBidAdapter.js +++ b/modules/adagioBidAdapter.js @@ -7,7 +7,7 @@ import sha256 from 'crypto-js/sha256.js'; import { getStorageManager } from '../src/storageManager.js'; const BIDDER_CODE = 'adagio'; -const VERSION = '2.1.0'; +const VERSION = '2.2.0'; const FEATURES_VERSION = '1'; const ENDPOINT = 'https://mp.4dex.io/prebid'; const SUPPORTED_MEDIA_TYPES = ['banner']; @@ -338,10 +338,19 @@ function _getGdprConsent(bidderRequest) { if (bidderRequest.gdprConsent.allowAuctionWithoutConsent !== undefined) { consent.allowAuctionWithoutConsent = bidderRequest.gdprConsent.allowAuctionWithoutConsent ? 1 : 0; } + if (bidderRequest.gdprConsent.apiVersion !== undefined) { + consent.apiVersion = bidderRequest.gdprConsent.apiVersion; + } } return consent; } +function _getSchain(bidRequest) { + if (utils.deepAccess(bidRequest, 'schain')) { + return bidRequest.schain; + } +} + export const spec = { code: BIDDER_CODE, gvlid: GVLID, @@ -394,6 +403,7 @@ export const spec = { const site = _getSite(); const pageviewId = _getPageviewId(); const gdprConsent = _getGdprConsent(bidderRequest); + const schain = _getSchain(validBidRequests[0]); const adUnits = utils._map(validBidRequests, (bidRequest) => { bidRequest.features = _getFeatures(bidRequest); return bidRequest; @@ -422,6 +432,7 @@ export const spec = { pageviewId: pageviewId, adUnits: groupedAdUnits[organizationId], gdpr: gdprConsent, + schain: schain, prebidVersion: '$prebid.version$', adapterVersion: VERSION, featuresVersion: FEATURES_VERSION diff --git a/test/spec/modules/adagioBidAdapter_spec.js b/test/spec/modules/adagioBidAdapter_spec.js index b49a591d20d..f387b7a021c 100644 --- a/test/spec/modules/adagioBidAdapter_spec.js +++ b/test/spec/modules/adagioBidAdapter_spec.js @@ -7,7 +7,7 @@ describe('adagioAdapter', () => { let utilsMock; const adapter = newBidder(spec); const ENDPOINT = 'https://mp.4dex.io/prebid'; - const VERSION = '2.1.0'; + const VERSION = '2.2.0'; beforeEach(function() { localStorage.removeItem('adagioScript'); @@ -301,7 +301,29 @@ describe('adagioAdapter', () => { 'gdprConsent': { consentString: consentString, gdprApplies: true, - allowAuctionWithoutConsent: true + allowAuctionWithoutConsent: true, + apiVersion: 1, + }, + 'refererInfo': { + 'numIframes': 0, + 'reachedTop': true, + 'referer': 'http://test.io/index.html?pbjs_debug=true' + } + }; + + let bidderRequestTCF2 = { + 'bidderCode': 'adagio', + 'auctionId': '12jejebn', + 'bidderRequestId': 'hehehehbeheh', + 'timeout': 3000, + 'gdprConsent': { + consentString: consentString, + vendorData: { + tcString: consentString, + gdprApplies: true + }, + gdprApplies: true, + apiVersion: 2 }, 'refererInfo': { 'numIframes': 0, @@ -433,6 +455,17 @@ describe('adagioAdapter', () => { expect(request.data.gdpr).to.exist; expect(request.data.gdpr.consentString).to.exist.and.to.equal(consentString); expect(request.data.gdpr.consentRequired).to.exist.and.to.equal(1); + expect(request.data.gdpr.apiVersion).to.exist.and.to.equal(1); + }); + + it('GDPR consent is applied w/ TCF2', () => { + const requests = spec.buildRequests(bidRequests, bidderRequestTCF2); + expect(requests).to.have.lengthOf(2); + const request = requests[0]; + expect(request.data.gdpr).to.exist; + expect(request.data.gdpr.consentString).to.exist.and.to.equal(consentString); + expect(request.data.gdpr.consentRequired).to.exist.and.to.equal(1); + expect(request.data.gdpr.apiVersion).to.exist.and.to.equal(2); }); it('GDPR consent is not applied', () => { @@ -443,6 +476,18 @@ describe('adagioAdapter', () => { expect(request.data.gdpr).to.exist; expect(request.data.gdpr.consentString).to.exist.and.to.equal(consentString); expect(request.data.gdpr.consentRequired).to.exist.and.to.equal(0); + expect(request.data.gdpr.apiVersion).to.exist.and.to.equal(1); + }); + + it('GDPR consent is not applied w/ TCF2', () => { + bidderRequestTCF2.gdprConsent.gdprApplies = false; + const requests = spec.buildRequests(bidRequests, bidderRequestTCF2); + expect(requests).to.have.lengthOf(2); + const request = requests[0]; + expect(request.data.gdpr).to.exist; + expect(request.data.gdpr.consentString).to.exist.and.to.equal(consentString); + expect(request.data.gdpr.consentRequired).to.exist.and.to.equal(0); + expect(request.data.gdpr.apiVersion).to.exist.and.to.equal(2); }); it('GDPR consent is undefined', () => { @@ -456,6 +501,20 @@ describe('adagioAdapter', () => { expect(request.data.gdpr).to.not.have.property('consentString'); expect(request.data.gdpr).to.not.have.property('gdprApplies'); expect(request.data.gdpr).to.not.have.property('allowAuctionWithoutConsent'); + expect(request.data.gdpr.apiVersion).to.exist.and.to.equal(1); + }); + + it('GDPR consent is undefined w/ TCF2', () => { + delete bidderRequestTCF2.gdprConsent.consentString; + delete bidderRequestTCF2.gdprConsent.gdprApplies; + delete bidderRequestTCF2.gdprConsent.vendorData; + const requests = spec.buildRequests(bidRequests, bidderRequestTCF2); + expect(requests).to.have.lengthOf(2); + const request = requests[0]; + expect(request.data.gdpr).to.exist; + expect(request.data.gdpr).to.not.have.property('consentString'); + expect(request.data.gdpr).to.not.have.property('gdprApplies'); + expect(request.data.gdpr.apiVersion).to.exist.and.to.equal(2); }); it('GDPR consent bidderRequest does not have gdprConsent', () => { @@ -480,6 +539,40 @@ describe('adagioAdapter', () => { }); expect(requests).to.be.empty; }); + + it('Should add the schain if available at bidder level', () => { + const bidRequest = Object.assign({}, bidRequests[0], { + schain: { + ver: '1.0', + complete: 1, + nodes: [{ + asi: 'ssp.test', + sid: '00001', + hp: 1 + }] + } + }); + + const requests = spec.buildRequests([bidRequest], bidderRequest); + const request = requests[0]; + + expect(request.data.schain).to.exist; + expect(request.data.schain).to.deep.equal({ + ver: '1.0', + complete: 1, + nodes: [{ + asi: 'ssp.test', + sid: '00001', + hp: 1 + }] + }); + }); + + it('Schain should not be added to the request', () => { + const requests = spec.buildRequests([bidRequests[0]], bidderRequest); + const request = requests[0]; + expect(request.data.schain).to.not.exist; + }); }); describe('interpretResponse', () => { From 681866445894a688e6c3714c55759b3209c9246b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Alberto=20Polo=20Garc=C3=ADa?= Date: Tue, 7 Apr 2020 15:02:07 +0200 Subject: [PATCH 212/496] Use TCFv2 consent data in Criteo Id module (#5073) Co-authored-by: Jesus Alberto Polo Garcia --- modules/criteoIdSystem.js | 17 ++++++++++++----- test/spec/modules/criteoIdSystem_spec.js | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/modules/criteoIdSystem.js b/modules/criteoIdSystem.js index 0103db8ef80..d03e5de26c7 100644 --- a/modules/criteoIdSystem.js +++ b/modules/criteoIdSystem.js @@ -59,18 +59,19 @@ function getCriteoDataFromAllStorages() { } } -function buildCriteoUsersyncUrl(topUrl, domain, bundle, areCookiesWriteable, isPublishertagPresent) { +function buildCriteoUsersyncUrl(topUrl, domain, bundle, areCookiesWriteable, isPublishertagPresent, gdprString) { const url = 'https://gum.criteo.com/sid/json?origin=prebid' + `${topUrl ? '&topUrl=' + encodeURIComponent(topUrl) : ''}` + `${domain ? '&domain=' + encodeURIComponent(domain) : ''}` + `${bundle ? '&bundle=' + encodeURIComponent(bundle) : ''}` + + `${gdprString ? '&gdprString=' + encodeURIComponent(gdprString) : ''}` + `${areCookiesWriteable ? '&cw=1' : ''}` + `${isPublishertagPresent ? '&pbt=1' : ''}` return url; } -function callCriteoUserSync(parsedCriteoData) { +function callCriteoUserSync(parsedCriteoData, gdprString) { const cw = areCookiesWriteable(); const topUrl = extractProtocolHost(getRefererInfo().referer); const domain = extractProtocolHost(document.location.href, true); @@ -81,7 +82,8 @@ function callCriteoUserSync(parsedCriteoData) { domain, parsedCriteoData.bundle, cw, - isPublishertagPresent + isPublishertagPresent, + gdprString ); ajax.ajaxBuilder()( @@ -122,11 +124,16 @@ export const criteoIdSubmodule = { /** * get the Criteo Id from local storages and initiate a new user sync * @function + * @param {SubmoduleParams} [configParams] + * @param {ConsentData} [consentData] * @returns {{id: {criteoId: string} | undefined}}} */ - getId() { + getId(configParams, consentData) { + const hasGdprData = consentData && typeof consentData.gdprApplies === 'boolean' && consentData.gdprApplies; + const gdprConsentString = hasGdprData ? consentData.consentString : undefined; + let localData = getCriteoDataFromAllStorages(); - callCriteoUserSync(localData); + callCriteoUserSync(localData, gdprConsentString); return { id: localData.bidId ? { criteoId: localData.bidId } : undefined } } diff --git a/test/spec/modules/criteoIdSystem_spec.js b/test/spec/modules/criteoIdSystem_spec.js index dee9a0563e2..74caef69ccc 100644 --- a/test/spec/modules/criteoIdSystem_spec.js +++ b/test/spec/modules/criteoIdSystem_spec.js @@ -132,4 +132,26 @@ describe('CriteoId module', function () { } }); })); + + const gdprConsentTestCases = [ + { consentData: { gdprApplies: true, consentString: 'expectedConsentString' }, expected: 'expectedConsentString' }, + { consentData: { gdprApplies: false, consentString: 'expectedConsentString' }, expected: undefined }, + { consentData: { gdprApplies: true, consentString: undefined }, expected: undefined }, + { consentData: { gdprApplies: 'oui', consentString: 'expectedConsentString' }, expected: undefined }, + { consentData: undefined, expected: undefined } + ]; + + gdprConsentTestCases.forEach(testCase => it('should call user sync url with the gdprConsent', function () { + const emptyObj = '{}'; + let ajaxStub = sinon.stub().callsFake((url, callback) => callback(emptyObj)); + ajaxBuilderStub.callsFake(mockResponse(undefined, ajaxStub)) + + criteoIdSubmodule.getId(undefined, testCase.consentData); + + if (testCase.expected) { + expect(ajaxStub.calledWithMatch(`gdprString=${testCase.expected}`)).to.be.true; + } else { + expect(ajaxStub.calledWithMatch('gdprString')).not.to.be.true; + } + })); }); From a7d44103451a5d8f7e708bd4135fbbe4eb68407e Mon Sep 17 00:00:00 2001 From: Jaimin Panchal <7393273+jaiminpanchal27@users.noreply.github.com> Date: Tue, 7 Apr 2020 13:07:49 -0400 Subject: [PATCH 213/496] Update param in request payload (#5091) Co-authored-by: Jaimin Panchal --- modules/appnexusBidAdapter.js | 5 ++++- test/spec/modules/appnexusBidAdapter_spec.js | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 9c98ccc0651..db621217025 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -74,7 +74,10 @@ export const spec = { if (userObjBid) { Object.keys(userObjBid.params.user) .filter(param => includes(USER_PARAMS, param)) - .forEach(param => userObj[param] = userObjBid.params.user[param]); + .forEach((param) => { + let uparam = utils.convertCamelToUnderscore(param); + userObj[uparam] = userObjBid.params.user[param] + }); } const appDeviceObjBid = find(bidRequests, hasAppDeviceInfo); diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js index 2a6a25752d9..8934d1cdaef 100644 --- a/test/spec/modules/appnexusBidAdapter_spec.js +++ b/test/spec/modules/appnexusBidAdapter_spec.js @@ -258,7 +258,7 @@ describe('AppNexusAdapter', function () { expect(payload.user).to.exist; expect(payload.user).to.deep.equal({ - externalUid: '123', + external_uid: '123', }); }); From dc02ff460bf063766097a312d7c1ae17f40df5e5 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Tue, 7 Apr 2020 10:34:05 -0700 Subject: [PATCH 214/496] PubMatic bid adapter to support app object set using setConfig (#5090) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * merge the device object from setConfig * set app from config and site, remove site if app is set * added test cases for reading device from config * unit test case for reading app from conf * delete the site object * set undefined not null --- modules/pubmaticBidAdapter.js | 15 +++++ test/spec/modules/pubmaticBidAdapter_spec.js | 64 ++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 49f193cf93e..2c1024b6fe3 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -920,6 +920,11 @@ export const spec = { payload.site.page = conf.kadpageurl.trim() || payload.site.page.trim(); payload.site.domain = _getDomainFromURL(payload.site.page); + // merge the device from config.getConfig('device') + if (typeof config.getConfig('device') === 'object') { + payload.device = Object.assign(payload.device, config.getConfig('device')); + } + // passing transactionId in source.tid utils.deepSetValue(payload, 'source.tid', conf.transactionId); @@ -953,6 +958,16 @@ export const spec = { _handleEids(payload, validBidRequests); _blockedIabCategoriesValidation(payload, blockedIabCategories); + // Note: Do not move this block up + // if site object is set in Prebid config then we need to copy required fields from site into app and unset the site object + if (typeof config.getConfig('app') === 'object') { + payload.app = config.getConfig('app'); + // not copying domain from site as it is a derived value from page + payload.app.publisher = payload.site.publisher; + payload.app.ext = payload.site.ext || UNDEFINED; + delete payload.site; + } + return { method: 'POST', url: ENDPOINT, diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 36b984296fc..533edb33858 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -769,6 +769,70 @@ describe('PubMatic adapter', function () { expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain); }); + it('Merge the device info from config', function() { + let sandbox = sinon.sandbox.create(); + sandbox.stub(config, 'getConfig').callsFake((key) => { + var config = { + device: { + 'newkey': 'new-device-data' + } + }; + return config[key]; + }); + let request = spec.buildRequests(bidRequests); + let data = JSON.parse(request.data); + expect(data.device.js).to.equal(1); + expect(data.device.dnt).to.equal((navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0); + expect(data.device.h).to.equal(screen.height); + expect(data.device.w).to.equal(screen.width); + expect(data.device.language).to.equal(navigator.language); + expect(data.device.newkey).to.equal('new-device-data');// additional data from config + sandbox.restore(); + }); + + it('Merge the device info from config; data from config overrides the info we have gathered', function() { + let sandbox = sinon.sandbox.create(); + sandbox.stub(config, 'getConfig').callsFake((key) => { + var config = { + device: { + newkey: 'new-device-data', + language: 'MARATHI' + } + }; + return config[key]; + }); + let request = spec.buildRequests(bidRequests); + let data = JSON.parse(request.data); + expect(data.device.js).to.equal(1); + expect(data.device.dnt).to.equal((navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0); + expect(data.device.h).to.equal(screen.height); + expect(data.device.w).to.equal(screen.width); + expect(data.device.language).to.equal('MARATHI');// // data overriding from config + expect(data.device.newkey).to.equal('new-device-data');// additional data from config + sandbox.restore(); + }); + + it('Set app from config, copy publisher and ext from site, unset site', function() { + let sandbox = sinon.sandbox.create(); + sandbox.stub(config, 'getConfig').callsFake((key) => { + var config = { + app: { + bundle: 'org.prebid.mobile.demoapp', + domain: 'prebid.org' + } + }; + return config[key]; + }); + let request = spec.buildRequests(bidRequests); + let data = JSON.parse(request.data); + expect(data.app.bundle).to.equal('org.prebid.mobile.demoapp'); + expect(data.app.domain).to.equal('prebid.org'); + expect(data.app.publisher.id).to.equal(bidRequests[0].params.publisherId); + expect(data.app.ext.key_val).to.exist.and.to.equal(bidRequests[0].params.dctr); + expect(data.site).to.not.exist; + sandbox.restore(); + }); + it('Request params check: without adSlot', function () { delete bidRequests[0].params.adSlot; let request = spec.buildRequests(bidRequests); From 977f546deed1e69cddcc805d16c3a89f363a113a Mon Sep 17 00:00:00 2001 From: Vedant Seta Date: Tue, 7 Apr 2020 23:07:36 +0530 Subject: [PATCH 215/496] Media.net : fetches gdpr consent string (#5058) Co-authored-by: vedant.s --- modules/medianetAnalyticsAdapter.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/modules/medianetAnalyticsAdapter.js b/modules/medianetAnalyticsAdapter.js index 63f2e2329a2..35a050831f3 100644 --- a/modules/medianetAnalyticsAdapter.js +++ b/modules/medianetAnalyticsAdapter.js @@ -346,11 +346,15 @@ function auctionInitHandler({auctionId, timestamp}) { } } -function bidRequestedHandler({ auctionId, auctionStart, bids, start, timeout, uspConsent, gdprConsent }) { +function bidRequestedHandler({ auctionId, auctionStart, bids, start, timeout, uspConsent, gdpr }) { if (!(auctions[auctionId] instanceof Auction)) { return; } - config.gdprConsent = config.gdprConsent || gdprConsent; + + if (gdpr && gdpr.gdprApplies) { + config.gdprConsent = gdpr.consentString || ''; + } + config.uspConsent = config.uspConsent || uspConsent; bids.forEach(bid => { @@ -542,7 +546,15 @@ function fireAuctionLog(acid, adtag, isBidWonEvent) { } function formatQS(data) { - return utils._map(data, (value, key) => value === undefined ? key + '=' : key + '=' + encodeURIComponent(value)).join('&'); + return utils._map(data, (value, key) => { + if (value === undefined) { + return key + '='; + } + if (utils.isPlainObject(value)) { + value = JSON.stringify(value); + } + return key + '=' + encodeURIComponent(value); + }).join('&'); } function firePixel(qs) { From 9de6609380a263c6794fe973da05fa77be7ca273 Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Tue, 7 Apr 2020 23:22:20 +0530 Subject: [PATCH 216/496] Size Mapping V2 supports 'Identical Ad Units' (#5062) * add support for identical ad units and improve log messages * slight change in log message presentation * fix typo * document return value type --- allowedModules.js | 15 +-- modules/sizeMappingV2.js | 41 ++++---- src/utils.js | 14 ++- test/spec/modules/sizeMappingV2_spec.js | 127 ++++++++++++++++++++---- 4 files changed, 152 insertions(+), 45 deletions(-) diff --git a/allowedModules.js b/allowedModules.js index 0fee2cfdedd..4f8b8039d97 100644 --- a/allowedModules.js +++ b/allowedModules.js @@ -1,11 +1,11 @@ const sharedWhiteList = [ - "core-js/library/fn/array/find", // no ie11 - "core-js/library/fn/array/includes", // no ie11 - "core-js/library/fn/set", // ie11 supports Set but not Set#values - "core-js/library/fn/string/includes", // no ie11 - "core-js/library/fn/number/is-integer", // no ie11, - "core-js/library/fn/array/from" // no ie11 + 'core-js/library/fn/array/find', // no ie11 + 'core-js/library/fn/array/includes', // no ie11 + 'core-js/library/fn/set', // ie11 supports Set but not Set#values + 'core-js/library/fn/string/includes', // no ie11 + 'core-js/library/fn/number/is-integer', // no ie11, + 'core-js/library/fn/array/from' // no ie11 ]; module.exports = { @@ -21,6 +21,7 @@ module.exports = { 'fun-hooks/no-eval', 'just-clone', 'dlv', - 'dset' + 'dset', + 'deep-equal' ] }; diff --git a/modules/sizeMappingV2.js b/modules/sizeMappingV2.js index ec3604faa97..98effb301fb 100644 --- a/modules/sizeMappingV2.js +++ b/modules/sizeMappingV2.js @@ -273,21 +273,21 @@ export function isLabelActivated(bidOrAdUnit, activeLabels, adUnitCode) { let labelOperator; const labelsFound = Object.keys(bidOrAdUnit).filter(prop => prop === 'labelAny' || prop === 'labelAll'); if (labelsFound && labelsFound.length > 1) { - utils.logWarn(`SizeMappingV2:: ${(bidOrAdUnit.code) - ? (`Ad Unit: ${bidOrAdUnit.code} has multiple label operators. Using the first declared operator: ${labelsFound[0]}`) - : (`Bidder: ${bidOrAdUnit.bidder} in Ad Unit: ${adUnitCode} has multiple label operators. Using the first declared operator: ${labelsFound[0]}`)}`); + utils.logWarn(`Size Mapping V2:: ${(bidOrAdUnit.code) + ? (`Ad Unit: ${bidOrAdUnit.code} => Ad unit has multiple label operators. Using the first declared operator: ${labelsFound[0]}`) + : (`Ad Unit: ${adUnitCode}, Bidder: ${bidOrAdUnit.bidder} => Bidder has multiple label operators. Using the first declared operator: ${labelsFound[0]}`)}`); } labelOperator = labelsFound[0]; if (labelOperator === 'labelAll' && Array.isArray(bidOrAdUnit[labelOperator])) { if (bidOrAdUnit.labelAll.length === 0) { - utils.logWarn(`SizeMappingV2:: Ad Unit: ${bidOrAdUnit.code} has declared property labelAll with an empty array. Ad Unit is still enabled!`); + utils.logWarn(`Size Mapping V2:: Ad Unit: ${bidOrAdUnit.code} => Ad unit has declared property 'labelAll' with an empty array. Ad Unit is still enabled!`); return true; } return bidOrAdUnit.labelAll.every(label => includes(activeLabels, label)); } else if (labelOperator === 'labelAny' && Array.isArray(bidOrAdUnit[labelOperator])) { if (bidOrAdUnit.labelAny.length === 0) { - utils.logWarn(`SizeMappingV2:: Ad Unit: ${bidOrAdUnit.code} has declared property labelAny with an empty array. Ad Unit is still enabled!`); + utils.logWarn(`Size Mapping V2:: Ad Unit: ${bidOrAdUnit.code} => Ad unit has declared property 'labelAny' with an empty array. Ad Unit is still enabled!`); return true; } return bidOrAdUnit.labelAny.some(label => includes(activeLabels, label)); @@ -430,7 +430,11 @@ export function getRelevantMediaTypesForBidder(sizeConfig, activeViewport) { // sets sizeMappingInternalStore for a given auctionId with relevant adUnit information returned from the call to 'getFilteredMediaTypes' function // returns adUnit details object. export function getAdUnitDetail(auctionId, adUnit) { - const adUnitDetail = sizeMappingInternalStore.getAuctionDetail(auctionId).adUnits.filter(adUnitDetail => adUnitDetail.adUnitCode === adUnit.code); + // fetch all adUnits for an auction from the sizeMappingInternalStore + const adUnitsForAuction = sizeMappingInternalStore.getAuctionDetail(auctionId).adUnits; + + // check if the adUnit exists already in the sizeMappingInterStore (check for equivalence of 'code' && 'mediaTypes' properties) + const adUnitDetail = adUnitsForAuction.filter(adUnitDetail => adUnitDetail.adUnitCode === adUnit.code && utils.deepEqual(adUnitDetail.mediaTypes, adUnit.mediaTypes)); if (adUnitDetail.length > 0) { return adUnitDetail[0]; @@ -445,16 +449,17 @@ export function getAdUnitDetail(auctionId, adUnit) { transformedMediaTypes }; + // set adUnitDetail in sizeMappingInternalStore against the correct 'auctionId'. + sizeMappingInternalStore.setAuctionDetail(auctionId, adUnitDetail); + // 'filteredMediaTypes' are the mediaTypes that got removed/filtered-out from adUnit.mediaTypes after sizeConfig filtration. - const filteredMediaTypes = Object.keys(mediaTypes).filter(mt => Object.keys(transformedMediaTypes).indexOf(mt) === -1) + const filteredMediaTypes = Object.keys(mediaTypes).filter(mt => Object.keys(transformedMediaTypes).indexOf(mt) === -1); - utils.logInfo(`SizeMappingV2:: AdUnit: ${adUnit.code} - Active size buckets after filtration: `, sizeBucketToSizeMap); + utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Active size buckets after filtration: `, sizeBucketToSizeMap); if (filteredMediaTypes.length > 0) { - utils.logInfo(`SizeMappingV2:: AdUnit: ${adUnit.code} - mediaTypes that got filtered out: ${filteredMediaTypes}`); + utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Media types that got filtered out: ${filteredMediaTypes}`); } - // set adUnitDetail in sizeMappingInternalStore against the correct 'auctionId'. - sizeMappingInternalStore.setAuctionDetail(auctionId, adUnitDetail); return adUnitDetail; } } @@ -468,7 +473,7 @@ export function getBids({ bidderCode, auctionId, bidderRequestId, adUnits, label // check if adUnit has any active media types remaining, if not drop the adUnit from auction, // else proceed to evaluate the bids object. if (Object.keys(transformedMediaTypes).length === 0) { - utils.logInfo(`SizeMappingV2:: Ad Unit: ${adUnit.code} is disabled since there are no active media types after sizeConfig filtration.`); + utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Ad unit disabled since there are no active media types after sizeConfig filtration.`); return result; } result @@ -488,7 +493,7 @@ export function getBids({ bidderCode, auctionId, bidderRequestId, adUnits, label if (bid.sizeConfig) { const relevantMediaTypes = internal.getRelevantMediaTypesForBidder(bid.sizeConfig, activeViewport); if (relevantMediaTypes.length === 0) { - utils.logError(`SizeMappingV2:: AdUnit: ${adUnit.code}, Bidder: ${bidderCode} - sizeConfig is not configured properly. This bidder won't be eligible for sizeConfig checks and will remail active.`); + utils.logError(`Size Mapping V2:: Ad Unit: ${adUnit.code}, Bidder: ${bidderCode} => 'sizeConfig' is not configured properly. This bidder won't be eligible for sizeConfig checks and will remail active.`); bid = Object.assign({}, bid); } else if (relevantMediaTypes[0] !== 'none') { const bidderMediaTypes = Object @@ -502,11 +507,11 @@ export function getBids({ bidderCode, auctionId, bidderRequestId, adUnits, label if (Object.keys(bidderMediaTypes).length > 0) { bid = Object.assign({}, bid, { mediaTypes: bidderMediaTypes }); } else { - utils.logInfo(`SizeMappingV2:: AdUnit: ${adUnit.code}, Bidder: ${bid.bidder} - 'relevantMediaTypes' for this bidder does not match with any of the active mediaTypes at the Ad Unit level. This bidder is disabled.`); + utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}, Bidder: ${bid.bidder} => 'relevantMediaTypes' does not match with any of the active mediaTypes at the Ad Unit level. This bidder is disabled.`); return bids; } } else { - utils.logInfo(`SizeMappingV2:: AdUnit: ${adUnit.code}, Bidder: ${bid.bidder} - 'relevantMediaTypes' is set to 'none' in sizeConfig for current viewport size. This bidder is disabled.`); + utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}, Bidder: ${bid.bidder} => 'relevantMediaTypes' is set to 'none' in sizeConfig for current viewport size. This bidder is disabled.`); return bids; } } @@ -525,15 +530,15 @@ export function getBids({ bidderCode, auctionId, bidderRequestId, adUnits, label })); return bids; } else { - utils.logInfo(`SizeMappingV2:: AdUnit: ${adUnit.code}, Bidder: ${bid.bidder} - Label check for this bidder has failed. This bidder is disabled.`); + utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}, Bidder: ${bid.bidder} => Label check for this bidder has failed. This bidder is disabled.`); return bids; } }, [])); } else { - utils.logWarn(`SizeMappingV2:: Ad Unit: ${adUnit.code} has declared invalid mediaTypes or has not declared a mediaTypes property`); + utils.logWarn(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Ad unit has declared invalid 'mediaTypes' or has not declared a 'mediaTypes' property`); } } else { - utils.logInfo(`SizeMappingV2:: Ad Unit: ${adUnit.code} is disabled due to failing label check.`); + utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Ad unit is disabled due to failing label check.`); return result; } return result; diff --git a/src/utils.js b/src/utils.js index d9c4e5ea0f8..f43097e74b9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,6 +1,7 @@ /* eslint-disable no-console */ import { config } from './config.js'; import clone from 'just-clone'; +import deepequal from 'deep-equal'; import find from 'core-js/library/fn/array/find.js'; import includes from 'core-js/library/fn/array/includes.js'; @@ -36,7 +37,8 @@ export const internal = { logError, logWarn, logMessage, - logInfo + logInfo, + deepEqual }; var uniqueRef = {}; @@ -1242,3 +1244,13 @@ export function compareOn(property) { return 0; } } + +/** + * This function compares two objects for checking their equivalence. + * @param {Object} obj1 + * @param {Object} obj2 + * @returns {boolean} + */ +export function deepEqual(obj1, obj2) { + return deepequal(obj1, obj2); +} diff --git a/test/spec/modules/sizeMappingV2_spec.js b/test/spec/modules/sizeMappingV2_spec.js index 4b76ce2fa1c..cbfc02752a8 100644 --- a/test/spec/modules/sizeMappingV2_spec.js +++ b/test/spec/modules/sizeMappingV2_spec.js @@ -760,7 +760,7 @@ describe('sizeMappingV2', function () { isLabelActivated(adUnits, activeLabels, adUnitCode); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `SizeMappingV2:: Ad Unit: div-gpt-ad-1460505748561-0 has multiple label operators. Using the first declared operator: labelAny`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0 => Ad unit has multiple label operators. Using the first declared operator: labelAny`); }); it('should throw a warning message if both the label operator, "labelAny"/"labelAll" are configured for an Bidder', function () { @@ -772,7 +772,7 @@ describe('sizeMappingV2', function () { isLabelActivated(adUnits.bids[0], activeLabels, adUnitCode); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `SizeMappingV2:: Bidder: appnexus in Ad Unit: div-gpt-ad-1460505748561-0 has multiple label operators. Using the first declared operator: labelAny`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0, Bidder: appnexus => Bidder has multiple label operators. Using the first declared operator: labelAny`); }); it('should give priority to the label operator declared first incase two label operators are found on the same Ad Unit or Bidder', function () { @@ -805,13 +805,13 @@ describe('sizeMappingV2', function () { isLabelActivated(adUnit, activeLabels, adUnitCode); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `SizeMappingV2:: Ad Unit: div-gpt-ad-1460505748561-0 has declared property labelAll with an empty array. Ad Unit is still enabled!`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0 => Ad unit has declared property 'labelAll' with an empty array. Ad Unit is still enabled!`); // bidder level check isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `SizeMappingV2:: Ad Unit: div-gpt-ad-1460505748561-0 has declared property labelAll with an empty array. Ad Unit is still enabled!`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0 => Ad unit has declared property 'labelAll' with an empty array. Ad Unit is still enabled!`); }); it('should throw a warning log message if "labelAny" operator is declared as an empty array', function () { @@ -822,12 +822,12 @@ describe('sizeMappingV2', function () { isLabelActivated(adUnit, activeLabels, adUnitCode); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `SizeMappingV2:: Ad Unit: div-gpt-ad-1460505748561-0 has declared property labelAny with an empty array. Ad Unit is still enabled!`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0 => Ad unit has declared property 'labelAny' with an empty array. Ad Unit is still enabled!`); // bidder level check isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `SizeMappingV2:: Ad Unit: div-gpt-ad-1460505748561-0 has declared property labelAny with an empty array. Ad Unit is still enabled!`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0 => Ad unit has declared property 'labelAny' with an empty array. Ad Unit is still enabled!`); }); it('should return "true" if label operators are not present on the Ad Unit or Bidder', function () { @@ -1001,7 +1001,55 @@ describe('sizeMappingV2', function () { describe('getAdUnitDetail(auctionId, adUnit)', function () { const adUnitDetailFixture_1 = { adUnitCode: 'div-gpt-ad-1460505748561-0', - mediaTypes: {}, + mediaTypes: { + banner: { + sizeConfig: [ + { minViewPort: [0, 0], sizes: [] }, // remove if < 750px + { minViewPort: [750, 0], sizes: [[300, 250], [300, 600]] }, // between 750px and 1199px + { minViewPort: [1200, 0], sizes: [[970, 90], [728, 90], [300, 250]] }, // between 1200px and 1599px + { minViewPort: [1600, 0], sizes: [[1000, 300], [970, 90], [728, 90], [300, 250]] } // greater than 1600px + ] + }, + video: { + context: 'instream', + sizeConfig: [ + { minViewPort: [0, 0], playerSize: [] }, + { minViewPort: [800, 0], playerSize: [[640, 400]] }, + { minViewPort: [1200, 0], playerSize: [] } + ] + }, + native: { + image: { + required: true, + sizes: [150, 50] + }, + title: { + required: true, + len: 80 + }, + sponsoredBy: { + required: true + }, + clickUrl: { + required: true + }, + privacyLink: { + required: false + }, + body: { + required: true + }, + icon: { + required: true, + sizes: [50, 50] + }, + sizeConfig: [ + { minViewPort: [0, 0], active: false }, + { minViewPort: [600, 0], active: true }, + { minViewPort: [1000, 0], active: false } + ] + } + }, sizeBucketToSizeMap: {}, activeViewport: {}, transformedMediaTypes: {} @@ -1021,6 +1069,21 @@ describe('sizeMappingV2', function () { activeViewport: {}, transformedMediaTypes: { banner: {}, video: {} } } + // adunit with same code at adUnitDetailFixture_1 but differnet mediaTypes object + const adUnitDetailFixture_3 = { + adUnitCode: 'div-gpt-ad-1460505748561-0', + mediaTypes: { + banner: { + sizeConfig: [ + { minViewPort: [0, 0], sizes: [] }, + { minViewPort: [1000, 0], sizes: [[1000, 300], [1000, 90], [970, 250], [970, 90], [728, 90]] } + ] + } + }, + sizeBucketToSizeMap: {}, + activeViewport: {}, + transformedMediaTypes: {} + } beforeEach(function () { sinon .stub(sizeMappingInternalStore, 'getAuctionDetail') @@ -1034,12 +1097,18 @@ describe('sizeMappingV2', function () { .stub(sizeMappingInternalStore, 'setAuctionDetail') .withArgs('a1b2c3', adUnitDetailFixture_2); - sinon - .stub(internal, 'getFilteredMediaTypes') - .withArgs(adUnitDetailFixture_2.mediaTypes) + const getFilteredMediaTypesStub = sinon.stub(internal, 'getFilteredMediaTypes'); + + getFilteredMediaTypesStub + .withArgs(AD_UNITS[1].mediaTypes) .returns(adUnitDetailFixture_2); + getFilteredMediaTypesStub + .withArgs(adUnitDetailFixture_3.mediaTypes) + .returns(adUnitDetailFixture_3); + sinon.spy(utils, 'logInfo'); + sinon.spy(utils, 'deepEqual'); }); afterEach(function () { @@ -1047,15 +1116,35 @@ describe('sizeMappingV2', function () { sizeMappingInternalStore.setAuctionDetail.restore(); internal.getFilteredMediaTypes.restore(); utils.logInfo.restore(); + utils.deepEqual.restore(); }); - it('should return adUnit detail object from "sizeMappingInternalStore" if adUnit is alreay present in the store', function () { + it('should return adUnit detail object from "sizeMappingInternalStore" if adUnit is already present in the store', function () { const [adUnit] = utils.deepClone(AD_UNITS); const adUnitDetail = getAdUnitDetail('a1b2c3', adUnit); sinon.assert.callCount(sizeMappingInternalStore.getAuctionDetail, 1); + sinon.assert.callCount(utils.deepEqual, 1); + sinon.assert.callCount(internal.getFilteredMediaTypes, 0); expect(adUnitDetail).to.deep.equal(adUnitDetailFixture_1); }); + it('should NOT return adunit detail object from "sizeMappingInternalStore" if adUnit with the SAME CODE BUT DIFFERENT MEDIATYPES OBJECT is present in the store', function() { + const [adUnit] = utils.deepClone(AD_UNITS); + adUnit.mediaTypes = { + banner: { + sizeConfig: [ + { minViewPort: [0, 0], sizes: [] }, + { minViewPort: [1000, 0], sizes: [[1000, 300], [1000, 90], [970, 250], [970, 90], [728, 90]] } + ] + } + }; + const adUnitDetail = getAdUnitDetail('a1b2c3', adUnit); + sinon.assert.callCount(sizeMappingInternalStore.getAuctionDetail, 1); + sinon.assert.callCount(utils.deepEqual, 1); + expect(adUnitDetail).to.not.deep.equal(adUnitDetailFixture_1); + sinon.assert.callCount(internal.getFilteredMediaTypes, 1); + }); + it('should store value in "sizeMappingInterStore" object if adUnit is NOT preset in this object', function () { const [, adUnit] = utils.deepClone(AD_UNITS); const adUnitDetail = getAdUnitDetail('a1b2c3', adUnit); @@ -1068,7 +1157,7 @@ describe('sizeMappingV2', function () { const [, adUnit] = utils.deepClone(AD_UNITS); getAdUnitDetail('a1b2c3', adUnit); sinon.assert.callCount(utils.logInfo, 1); - sinon.assert.calledWith(utils.logInfo, `SizeMappingV2:: AdUnit: div-gpt-ad-1460505748561-1 - Active size buckets after filtration: `, adUnitDetailFixture_2.sizeBucketToSizeMap); + sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-1 => Active size buckets after filtration: `, adUnitDetailFixture_2.sizeBucketToSizeMap); }); it('should log info message if any of the mediaTypes defined in adUnit.mediaTypes got filtered out', function () { @@ -1100,7 +1189,7 @@ describe('sizeMappingV2', function () { getAdUnitDetail('a1b2c3', adUnit); sinon.assert.callCount(utils.logInfo, 2); - sinon.assert.calledWith(utils.logInfo.getCall(1), `SizeMappingV2:: AdUnit: div-gpt-ad-1460505748561-1 - mediaTypes that got filtered out: video`); + sinon.assert.calledWith(utils.logInfo.getCall(1), `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-1 => Media types that got filtered out: video`); }); }); @@ -1385,7 +1474,7 @@ describe('sizeMappingV2', function () { }); expect(bidRequests[0]).to.be.undefined; sinon.assert.callCount(utils.logInfo, 1); - sinon.assert.calledWith(utils.logInfo, `SizeMappingV2:: Ad Unit: adUnit1 is disabled since there are no active media types after sizeConfig filtration.`); + sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1 => Ad unit disabled since there are no active media types after sizeConfig filtration.`); }); it('should throw an error if bidder level sizeConfig is not configured properly', function () { @@ -1413,7 +1502,7 @@ describe('sizeMappingV2', function () { expect(bidRequests[0]).to.not.be.undefined; sinon.assert.callCount(utils.logError, 1); - sinon.assert.calledWith(utils.logError, `SizeMappingV2:: AdUnit: adUnit1, Bidder: rubicon - sizeConfig is not configured properly. This bidder won't be eligible for sizeConfig checks and will remail active.`); + sinon.assert.calledWith(utils.logError, `Size Mapping V2:: Ad Unit: adUnit1, Bidder: rubicon => 'sizeConfig' is not configured properly. This bidder won't be eligible for sizeConfig checks and will remail active.`); }); it('should ensure bidder relevantMediaTypes is a subset of active media types at the ad unit level', function () { @@ -1514,7 +1603,7 @@ describe('sizeMappingV2', function () { }); expect(bidRequests[0]).to.be.undefined; sinon.assert.callCount(utils.logInfo, 1); - sinon.assert.calledWith(utils.logInfo, `SizeMappingV2:: AdUnit: adUnit1, Bidder: rubicon - 'relevantMediaTypes' for this bidder does not match with any of the active mediaTypes at the Ad Unit level. This bidder is disabled.`); + sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1, Bidder: rubicon => 'relevantMediaTypes' does not match with any of the active mediaTypes at the Ad Unit level. This bidder is disabled.`); }); it('should throw a warning if mediaTypes object is not correctly formatted', function () { @@ -1531,7 +1620,7 @@ describe('sizeMappingV2', function () { src: 'client' }); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `SizeMappingV2:: Ad Unit: adUnit1 has declared invalid mediaTypes or has not declared a mediaTypes property`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: adUnit1 => Ad unit has declared invalid 'mediaTypes' or has not declared a 'mediaTypes' property`); utils.isValidMediaTypes.restore(); }); @@ -1552,7 +1641,7 @@ describe('sizeMappingV2', function () { }); sinon.assert.callCount(utils.logInfo, 1); - sinon.assert.calledWith(utils.logInfo, `SizeMappingV2:: Ad Unit: adUnit1 is disabled due to failing label check.`); + sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1 => Ad unit is disabled due to failing label check.`); internal.isLabelActivated.restore(); }); @@ -1572,7 +1661,7 @@ describe('sizeMappingV2', function () { }); sinon.assert.callCount(utils.logInfo, 1); - sinon.assert.calledWith(utils.logInfo, `SizeMappingV2:: AdUnit: adUnit1, Bidder: appnexus - Label check for this bidder has failed. This bidder is disabled.`); + sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1, Bidder: appnexus => Label check for this bidder has failed. This bidder is disabled.`); internal.isLabelActivated.restore(); }) From 73d5861ae9f631168bd0dcb2688e1abbcb782c1b Mon Sep 17 00:00:00 2001 From: Maxime Lequain Date: Tue, 7 Apr 2020 20:19:27 +0200 Subject: [PATCH 217/496] add adot bidder adapter (#4949) * add adot bidder adapter * remove promises and other methods to ensure IE11 compatibility and remove duplicate code Co-authored-by: Maxime Lequain --- modules/adotBidAdapter.js | 607 +++++ modules/adotBidAdapter.md | 218 ++ test/spec/modules/adotBidAdapter_spec.js | 3118 ++++++++++++++++++++++ 3 files changed, 3943 insertions(+) create mode 100644 modules/adotBidAdapter.js create mode 100644 modules/adotBidAdapter.md create mode 100644 test/spec/modules/adotBidAdapter_spec.js diff --git a/modules/adotBidAdapter.js b/modules/adotBidAdapter.js new file mode 100644 index 00000000000..94672b20c0c --- /dev/null +++ b/modules/adotBidAdapter.js @@ -0,0 +1,607 @@ +import {Renderer} from '../src/Renderer.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; +import {isStr, isArray, isNumber, isPlainObject, isBoolean, logError} from '../src/utils.js'; +import find from 'core-js/library/fn/array/find.js'; + +const ADAPTER_VERSION = 'v1.0.0'; +const BID_METHOD = 'POST'; +const BIDDER_URL = 'https://dsp.adotmob.com/headerbidding/bidrequest'; +const SUPPORTED_VIDEO_CONTEXTS = ['instream', 'outstream']; +const SUPPORTED_INSTREAM_CONTEXTS = ['pre-roll', 'mid-roll', 'post-roll']; +const NATIVE_PLACEMENTS = { + title: {id: 1, name: 'title'}, + icon: {id: 2, type: 1, name: 'img'}, + image: {id: 3, type: 3, name: 'img'}, + sponsoredBy: {id: 4, name: 'data', type: 1}, + body: {id: 5, name: 'data', type: 2}, + cta: {id: 6, type: 12, name: 'data'} +}; +const NATIVE_ID_MAPPING = {1: 'title', 2: 'icon', 3: 'image', 4: 'sponsoredBy', 5: 'body', 6: 'cta'}; +const SUPPORTED_VIDEO_MIMES = ['video/mp4']; +const DOMAIN_REGEX = new RegExp('//([^/]*)'); +const FIRST_PRICE = 1; +const BID_SUPPORTED_MEDIA_TYPES = ['banner', 'video', 'native']; +const TTL = 10; +const NET_REVENUE = true; +// eslint-disable-next-line no-template-curly-in-string +const AUCTION_PRICE = '${AUCTION_PRICE}'; +const OUTSTREAM_VIDEO_PLAYER_URL = 'https://adserver.adotmob.com/video/player.min.js'; + +function isNone(value) { + return (value === null) || (value === undefined); +} + +function groupBy(values, key) { + const groups = values.reduce((acc, value) => { + const groupId = value[key]; + + if (!acc[groupId]) acc[groupId] = []; + acc[groupId].push(value); + + return acc; + }, {}); + + return Object + .keys(groups) + .map(id => ({id, key, values: groups[id]})); +} + +function validateMediaTypes(mediaTypes, allowedMediaTypes) { + if (!isPlainObject(mediaTypes)) return false; + if (!allowedMediaTypes.some(mediaType => mediaType in mediaTypes)) return false; + + if (isBanner(mediaTypes)) { + if (!validateBanner(mediaTypes.banner)) return false; + } + + if (isVideo(mediaTypes)) { + if (!validateVideo(mediaTypes.video)) return false; + } + + return true; +} + +function isBanner(mediaTypes) { + return isPlainObject(mediaTypes) && isPlainObject(mediaTypes.banner); +} + +function isVideo(mediaTypes) { + return isPlainObject(mediaTypes) && isPlainObject(mediaTypes.video); +} + +function validateBanner(banner) { + return isPlainObject(banner) && + isArray(banner.sizes) && + (banner.sizes.length > 0) && + banner.sizes.every(validateMediaSizes); +} + +function validateVideo(video) { + if (!isPlainObject(video)) return false; + if (!isStr(video.context)) return false; + if (SUPPORTED_VIDEO_CONTEXTS.indexOf(video.context) === -1) return false; + + if (!video.playerSize) return true; + if (!isArray(video.playerSize)) return false; + + return video.playerSize.every(validateMediaSizes); +} + +function validateMediaSizes(mediaSize) { + return isArray(mediaSize) && + (mediaSize.length === 2) && + mediaSize.every(size => (isNumber(size) && size >= 0)); +} + +function validateParameters(parameters, adUnit) { + if (isVideo(adUnit.mediaTypes)) { + if (!isPlainObject(parameters)) return false; + if (!validateVideoParameters(parameters.video, adUnit)) return false; + } + + return true; +} + +function validateVideoParameters(video, adUnit) { + if (!video) return false; + + if (!isArray(video.mimes)) return false; + if (video.mimes.length === 0) return false; + if (!video.mimes.every(isStr)) return false; + + if (video.minDuration && !isNumber(video.minDuration)) return false; + if (video.maxDuration && !isNumber(video.maxDuration)) return false; + + if (!isArray(video.protocols)) return false; + if (video.protocols.length === 0) return false; + if (!video.protocols.every(isNumber)) return false; + + if (isInstream(adUnit.mediaTypes.video)) { + if (!video.instreamContext) return false; + if (SUPPORTED_INSTREAM_CONTEXTS.indexOf(video.instreamContext) === -1) return false; + } + + return true; +} + +function validateServerRequest(serverRequest) { + return isPlainObject(serverRequest) && + isPlainObject(serverRequest.data) && + isArray(serverRequest.data.imp) && + isPlainObject(serverRequest._adot_internal) && + isArray(serverRequest._adot_internal.impressions) +} + +function createServerRequestFromAdUnits(adUnits, bidRequestId, adUnitContext) { + return { + method: BID_METHOD, + url: BIDDER_URL, + data: generateBidRequestsFromAdUnits(adUnits, bidRequestId, adUnitContext), + _adot_internal: generateAdotInternal(adUnits) + } +} + +function generateAdotInternal(adUnits) { + const impressions = adUnits.reduce((acc, adUnit) => { + const {bidId, mediaTypes, adUnitCode, params} = adUnit; + const base = {bidId, adUnitCode, container: params.video && params.video.container}; + + const imps = Object + .keys(mediaTypes) + .reduce((acc, mediaType, index) => { + const data = mediaTypes[mediaType]; + const impressionId = `${bidId}_${index}`; + + if (mediaType !== 'banner') return acc.concat({...base, impressionId}); + + const bannerImps = data.sizes.map((item, i) => ({...base, impressionId: `${impressionId}_${i}`})); + + return acc.concat(bannerImps); + }, []); + + return acc.concat(imps); + }, []); + + return {impressions}; +} + +function generateBidRequestsFromAdUnits(adUnits, bidRequestId, adUnitContext) { + return { + id: bidRequestId, + imp: adUnits.reduce(generateImpressionsFromAdUnit, []), + site: generateSiteFromAdUnitContext(adUnitContext), + device: getDeviceInfo(), + user: getUserInfoFromAdUnitContext(adUnitContext), + regs: getRegulationFromAdUnitContext(adUnitContext), + at: FIRST_PRICE, + ext: generateBidRequestExtension() + }; +} + +function generateImpressionsFromAdUnit(acc, adUnit) { + const {bidId, mediaTypes, params} = adUnit; + const {placementId} = params; + const pmp = {}; + + if (placementId) pmp.deals = [{id: placementId}] + + const imps = Object + .keys(mediaTypes) + .reduce((acc, mediaType, index) => { + const data = mediaTypes[mediaType]; + const impId = `${bidId}_${index}`; + + if (mediaType === 'banner') return acc.concat(generateBannerFromAdUnit(impId, data, params)); + if (mediaType === 'video') return acc.concat({id: impId, video: generateVideoFromAdUnit(data, params), pmp}); + if (mediaType === 'native') return acc.concat({id: impId, native: generateNativeFromAdUnit(data, params), pmp}); + }, []); + + return acc.concat(imps); +} + +function isImpressionAVideo(impression) { + return isPlainObject(impression) && isPlainObject(impression.video); +} + +function generateBannerFromAdUnit(impId, data, params) { + const {position, placementId} = params; + const pos = position || 0; + const pmp = {}; + + if (placementId) pmp.deals = [{id: placementId}] + + return data.sizes.map(([w, h], index) => ({id: `${impId}_${index}`, banner: {format: [{w, h}], w, h, pos}, pmp})); +} + +function generateVideoFromAdUnit(data, params) { + const {playerSize} = data; + const hasPlayerSize = isArray(playerSize) && playerSize.length > 0; + const {position, video = {}} = params; + const {minDuration, maxDuration, protocols} = video; + + const size = {width: hasPlayerSize ? playerSize[0][0] : null, height: hasPlayerSize ? playerSize[0][1] : null}; + const duration = {min: isNumber(minDuration) ? minDuration : null, max: isNumber(maxDuration) ? maxDuration : null}; + + return { + mimes: SUPPORTED_VIDEO_MIMES, + w: size.width, + h: size.height, + startdelay: computeStartDelay(data, params), + minduration: duration.min, + maxduration: duration.max, + protocols, + pos: position || 0 + }; +} + +function isInstream(video) { + return isPlainObject(video) && (video.context === 'instream'); +} + +function isOutstream(video) { + return isPlainObject(video) && (video.startdelay === null) +} + +function computeStartDelay(data, params) { + if (isInstream(data)) { + if (params.video.instreamContext === 'pre-roll') return 0; + if (params.video.instreamContext === 'mid-roll') return -1; + if (params.video.instreamContext === 'post-roll') return -2; + } + + return null; +} + +function generateNativeFromAdUnit(data, params) { + const placements = NATIVE_PLACEMENTS; + const assets = Object + .keys(data) + .reduce((acc, placement) => { + const placementData = data[placement]; + const assetInfo = placements[placement]; + + if (!assetInfo) return acc; + + const {id, name, type} = assetInfo; + const {required, len, sizes} = placementData; + const wmin = sizes && sizes[0]; + const hmin = sizes && sizes[1]; + const content = {}; + + if (type) content.type = type; + if (len) content.len = len; + if (wmin) content.wmin = wmin; + if (hmin) content.hmin = hmin; + + acc.push({id, required, [name]: content}); + + return acc; + }, []); + + return { + request: JSON.stringify({assets}) + }; +} + +function generateSiteFromAdUnitContext(adUnitContext) { + if (!adUnitContext || !adUnitContext.refererInfo) return null; + + const domain = extractSiteDomainFromURL(adUnitContext.refererInfo.referer); + + if (!domain) return null; + + return { + page: adUnitContext.refererInfo.referer, + domain: domain, + name: domain + }; +} + +function extractSiteDomainFromURL(url) { + if (!url || !isStr(url)) return null; + + const domain = url.match(DOMAIN_REGEX); + + if (isArray(domain) && domain.length === 2) return domain[1]; + + return null; +} + +function getDeviceInfo() { + return {ua: navigator.userAgent, language: navigator.language}; +} + +function getUserInfoFromAdUnitContext(adUnitContext) { + if (!adUnitContext || !adUnitContext.gdprConsent) return null; + if (!isStr(adUnitContext.gdprConsent.consentString)) return null; + + return { + ext: { + consent: adUnitContext.gdprConsent.consentString + } + }; +} + +function getRegulationFromAdUnitContext(adUnitContext) { + if (!adUnitContext || !adUnitContext.gdprConsent) return null; + if (!isBoolean(adUnitContext.gdprConsent.gdprApplies)) return null; + + return { + ext: { + gdpr: adUnitContext.gdprConsent.gdprApplies + } + }; +} + +function generateBidRequestExtension() { + return { + adot: {adapter_version: ADAPTER_VERSION}, + should_use_gzip: true + }; +} + +function validateServerResponse(serverResponse) { + return isPlainObject(serverResponse) && + isPlainObject(serverResponse.body) && + isStr(serverResponse.body.cur) && + isArray(serverResponse.body.seatbid); +} + +function seatBidsToAds(seatBid, bidResponse, serverRequest) { + return seatBid.bid + .filter(bid => validateBids(bid, serverRequest)) + .map(bid => generateAdFromBid(bid, bidResponse, serverRequest)); +} + +function validateBids(bid, serverRequest) { + if (!isPlainObject(bid)) return false; + if (!isStr(bid.impid)) return false; + if (!isStr(bid.crid)) return false; + if (!isNumber(bid.price)) return false; + + if (!isPlainObject(bid.ext)) return false; + if (!isPlainObject(bid.ext.adot)) return false; + if (!isStr(bid.ext.adot.media_type)) return false; + if (BID_SUPPORTED_MEDIA_TYPES.indexOf(bid.ext.adot.media_type) === -1) return false; + + if (!bid.adm && !bid.nurl) return false; + if (bid.adm) { + if (!isStr(bid.adm)) return false; + if (bid.adm.indexOf(AUCTION_PRICE) === -1) return false; + } + if (bid.nurl) { + if (!isStr(bid.nurl)) return false; + if (bid.nurl.indexOf(AUCTION_PRICE) === -1) return false; + } + + if (isBidABanner(bid)) { + if (!isNumber(bid.h)) return false; + if (!isNumber(bid.w)) return false; + } + if (isBidAVideo(bid)) { + if (!(isNone(bid.h) || isNumber(bid.h))) return false; + if (!(isNone(bid.w) || isNumber(bid.w))) return false; + } + + const impression = getImpressionData(serverRequest, bid.impid); + + if (!isPlainObject(impression.openRTB)) return false; + if (!isPlainObject(impression.internal)) return false; + if (!isStr(impression.internal.adUnitCode)) return false; + + if (isBidABanner(bid)) { + if (!isPlainObject(impression.openRTB.banner)) return false; + } + if (isBidAVideo(bid)) { + if (!isPlainObject(impression.openRTB.video)) return false; + } + if (isBidANative(bid)) { + if (!isPlainObject(impression.openRTB.native) || !tryParse(bid.adm)) return false; + } + + return true; +} + +function isBidABanner(bid) { + return isPlainObject(bid) && + isPlainObject(bid.ext) && + isPlainObject(bid.ext.adot) && + bid.ext.adot.media_type === 'banner'; +} + +function isBidAVideo(bid) { + return isPlainObject(bid) && + isPlainObject(bid.ext) && + isPlainObject(bid.ext.adot) && + bid.ext.adot.media_type === 'video'; +} + +function isBidANative(bid) { + return isPlainObject(bid) && + isPlainObject(bid.ext) && + isPlainObject(bid.ext.adot) && + bid.ext.adot.media_type === 'native'; +} + +function getImpressionData(serverRequest, impressionId) { + const openRTBImpression = find(serverRequest.data.imp, imp => imp.id === impressionId); + const internalImpression = find(serverRequest._adot_internal.impressions, imp => imp.impressionId === impressionId); + + return { + id: impressionId, + openRTB: openRTBImpression || null, + internal: internalImpression || null + }; +} + +function generateAdFromBid(bid, bidResponse, serverRequest) { + const impressionData = getImpressionData(serverRequest, bid.impid); + const isVideo = isBidAVideo(bid); + const base = { + requestId: impressionData.internal.bidId, + cpm: bid.price, + currency: bidResponse.cur, + ttl: TTL, + creativeId: bid.crid, + netRevenue: NET_REVENUE, + mediaType: bid.ext.adot.media_type, + }; + + if (isBidANative(bid)) return {...base, native: formatNativeData(bid.adm)}; + + const size = getSizeFromBid(bid, impressionData); + const creative = getCreativeFromBid(bid, impressionData); + + return { + ...base, + height: size.height, + width: size.width, + ad: creative.markup, + adUrl: creative.markupUrl, + vastXml: isVideo && !isStr(creative.markupUrl) ? creative.markup : null, + vastUrl: isVideo && isStr(creative.markupUrl) ? creative.markupUrl : null, + renderer: creative.renderer + }; +} + +function formatNativeData(adm) { + const parsedAdm = tryParse(adm); + const {assets, link: {url, clicktrackers}, imptrackers, jstracker} = parsedAdm.native; + const placements = NATIVE_PLACEMENTS; + const placementIds = NATIVE_ID_MAPPING; + + return assets.reduce((acc, asset) => { + const placementName = placementIds[asset.id]; + const content = placementName && asset[placements[placementName].name]; + if (!content) return acc; + acc[placementName] = content.text || content.value || {url: content.url, width: content.w, height: content.h}; + return acc; + }, { + clickUrl: url, + clickTrackers: clicktrackers, + impressionTrackers: imptrackers, + javascriptTrackers: jstracker && [jstracker] + }); +} + +function getSizeFromBid(bid, impressionData) { + if (isNumber(bid.w) && isNumber(bid.h)) { + return { width: bid.w, height: bid.h }; + } + + if (isImpressionAVideo(impressionData.openRTB)) { + const { video } = impressionData.openRTB; + + if (isNumber(video.w) && isNumber(video.h)) { + return { width: video.w, height: video.h }; + } + } + + return { width: null, height: null }; +} + +function getCreativeFromBid(bid, impressionData) { + const shouldUseAdMarkup = !!bid.adm; + + return { + markup: shouldUseAdMarkup ? bid.adm : null, + markupUrl: !shouldUseAdMarkup ? bid.nurl : null, + renderer: getRendererFromBid(bid, impressionData) + }; +} + +function getRendererFromBid(bid, impressionData) { + const isOutstreamImpression = isBidAVideo(bid) && + isImpressionAVideo(impressionData.openRTB) && + isOutstream(impressionData.openRTB.video); + + return isOutstreamImpression + ? buildOutstreamRenderer(impressionData) + : null; +} + +function buildOutstreamRenderer(impressionData) { + const renderer = Renderer.install({ + url: OUTSTREAM_VIDEO_PLAYER_URL, + loaded: false, + adUnitCode: impressionData.internal.adUnitCode + }); + + renderer.setRender((ad) => { + ad.renderer.push(() => { + const container = impressionData.internal.container + ? document.querySelector(impressionData.internal.container) + : document.getElementById(impressionData.internal.adUnitCode); + + const player = new window.VASTPlayer(container); + + player.on('ready', () => { + player.adVolume = 0; + player.startAd(); + }); + + try { + isStr(ad.adUrl) + ? player.load(ad.adUrl) + : player.loadXml(ad.ad) + } catch (err) { + logError(err); + } + }); + }); + + return renderer; +} + +function tryParse(data) { + try { + return JSON.parse(data); + } catch (err) { + logError(err); + return null; + } +} + +const adotBidderSpec = { + code: 'adot', + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + isBidRequestValid(adUnit) { + const allowedBidderCodes = [this.code]; + + return isPlainObject(adUnit) && + allowedBidderCodes.indexOf(adUnit.bidder) !== -1 && + isStr(adUnit.adUnitCode) && + isStr(adUnit.bidderRequestId) && + isStr(adUnit.bidId) && + validateMediaTypes(adUnit.mediaTypes, this.supportedMediaTypes) && + validateParameters(adUnit.params, adUnit); + }, + buildRequests(adUnits, adUnitContext) { + if (!adUnits) return null; + + return groupBy(adUnits, 'bidderRequestId').map(group => { + const bidRequestId = group.id; + const adUnits = groupBy(group.values, 'bidId').map((group) => { + const length = group.values.length; + return length > 0 && group.values[length - 1] + }); + + return createServerRequestFromAdUnits(adUnits, bidRequestId, adUnitContext) + }); + }, + interpretResponse(serverResponse, serverRequest) { + if (!validateServerRequest(serverRequest)) return []; + if (!validateServerResponse(serverResponse)) return []; + + const bidResponse = serverResponse.body; + + return bidResponse.seatbid + .filter(seatBid => isPlainObject(seatBid) && isArray(seatBid.bid)) + .reduce((acc, seatBid) => acc.concat(seatBidsToAds(seatBid, bidResponse, serverRequest)), []); + } +}; + +registerBidder(adotBidderSpec); + +export {adotBidderSpec as spec}; diff --git a/modules/adotBidAdapter.md b/modules/adotBidAdapter.md new file mode 100644 index 00000000000..88c8fb0b936 --- /dev/null +++ b/modules/adotBidAdapter.md @@ -0,0 +1,218 @@ +# Adot Bidder Adapter + +Adot Bidder Adapter is a module that enables the communication between the Prebid.js library and Adot's DSP. + +## Overview + +- Module name: Adot Bidder Adapter +- Module type: Bidder Adapter +- Maintainer: `maxime.lequain@we-are-adot.com` +- Supported media types: `banner`, `video`, `native` + +## Example ad units + +### Banner ad unit + +Adot Bidder Adapter accepts banner ad units using the following ad unit format: + +```javascript +const adUnit = { + code: 'test-div', + mediaTypes: { + banner: { + // Dimensions supported by the banner ad unit. + // Each ad unit size is formatted as follows: [width, height]. + sizes: [[300, 250]] + } + }, + bids: [{ + bidder: 'adot', + params: {} + }] +} +``` + +### Video ad unit + +#### Outstream video ad unit + +Adot Bidder Adapter accepts outstream video ad units using the following ad unit format: + +```javascript +const adUnit = { + code: 'test-div', + mediaTypes: { + video: { + // Video context. Must be 'outstream'. + context: 'outstream', + // Video dimensions supported by the video ad unit. + // Each ad unit size is formatted as follows: [width, height]. + playerSize: [[300, 250]] + } + }, + bids: [{ + bidder: 'adot', + params: { + video: { + // Content MIME types supported by the ad unit. + mimes: ['video/mp4'], + // Minimum accepted video ad duration (in seconds). + minDuration: 5, + // Maximum accepted video ad duration (in seconds). + maxDuration: 35, + // Video protocols supported by the ad unit (see the OpenRTB 2.5 specifications, + // section 5.8). + protocols: [2, 3] + } + } + }] +} +``` + +#### Instream video ad unit + +Adot Bidder Adapter accepts instream video ad units using the following ad unit format: + +```javascript +const adUnit = { + code: 'test-div', + mediaTypes: { + video: { + // Video context. Must be 'instream'. + context: 'instream', + // Video dimensions supported by the video ad unit. + // Each ad unit size is formatted as follows: [width, height]. + playerSize: [[300, 250]] + } + }, + bids: [{ + bidder: 'adot', + params: { + video: { + // Content MIME types supported by the ad unit. + mimes: ['video/mp4'], + // Minimum accepted video ad duration (in seconds). + minDuration: 5, + // Maximum accepted video ad duration (in seconds). + maxDuration: 35, + // Video protocols supported by the ad unit (see the OpenRTB 2.5 specifications, + // section 5.8). + protocols: [2, 3], + // Instream video context. Must be either 'pre-roll', 'mid-roll' or 'post-roll'. + instreamContext: 'pre-roll' + } + } + }] +} +``` +### Native ad unit + +Adot Bidder Adapter accepts native ad units using the following ad unit format: + +```javascript +const adUnit = { + code: 'test-div', + mediaTypes: { + native: { + native: { + image: { + // Field required status + required: false, + // Image dimensions supported by the native ad unit. + // Each ad unit size is formatted as follows: [width, height]. + sizes: [100, 50] + }, + title: { + // Field required status + required: false, + // Maximum length of the title + len: 140 + }, + sponsoredBy: { + // Field required status + required: false + }, + clickUrl: { + // Field required status + required: false + }, + body: { + // Field required status + required: false + }, + icon: { + // Field required status + required: false, + // Icon dimensions supported by the native ad unit. + // Each ad unit size is formatted as follows: [width, height]. + sizes: [50, 50] + } + } + } + }, + bids: [{ + bidder: 'adot', + params: {} + }] +} +``` + +## Bidder parameters + +### Position + +You can use the `position` to specify the position of the ad as a relative measure of visibility or prominence. + +#### Accepted values + +|Value|Description | +|-----|----------------| +|0 | Unknown | +|1 | Above the fold | +|3 | Below the fold | + +Note that the position will default to `0` if the field is missing. + +#### Example + +```javascript +const adUnit = { + code: 'test-div', + mediaTypes: { + banner: { + // Dimensions supported by the banner ad unit. + // Each ad unit size is formatted as follows: [width, height]. + sizes: [[300, 250]] + } + }, + bids: [{ + bidder: 'adot', + params: { + position: 0 + } + }] +} +``` + +### PlacementId + +#### Example + +```javascript +const adUnit = { + code: 'test-div', + mediaTypes: { + banner: { + // Dimensions supported by the banner ad unit. + // Each ad unit size is formatted as follows: [width, height]. + sizes: [[300, 250]] + } + }, + bids: [{ + bidder: 'adot', + params: { + placementId: 'eae245d' + } + }] +} +``` diff --git a/test/spec/modules/adotBidAdapter_spec.js b/test/spec/modules/adotBidAdapter_spec.js new file mode 100644 index 00000000000..594fc4ac7b7 --- /dev/null +++ b/test/spec/modules/adotBidAdapter_spec.js @@ -0,0 +1,3118 @@ +import { expect } from 'chai'; +import { executeRenderer } from 'src/Renderer.js'; +import * as utils from 'src/utils.js'; +import { spec } from 'modules/adotBidAdapter.js'; + +const BIDDER_URL = 'https://dsp.adotmob.com/headerbidding/bidrequest'; + +describe('Adot Adapter', function () { + const examples = { + adUnit_banner: { + adUnitCode: 'ad_unit_banner', + bidder: 'adot', + bidderRequestId: 'bid_request_id', + bidId: 'bid_id', + params: {}, + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + } + }, + + adUnit_video_outstream: { + adUnitCode: 'ad_unit_video_outstream', + bidder: 'adot', + bidderRequestId: 'bid_request_id', + bidId: 'bid_id', + params: { + video: { + mimes: ['video/mp4'], + minDuration: 5, + maxDuration: 30, + protocols: [2, 3] + } + }, + mediaTypes: { + video: { + context: 'outstream', + playerSize: [[300, 250]] + } + } + }, + + adUnit_video_instream: { + adUnitCode: 'ad_unit_video_instream', + bidder: 'adot', + bidderRequestId: 'bid_request_id', + bidId: 'bid_id', + params: { + video: { + instreamContext: 'pre-roll', + mimes: ['video/mp4'], + minDuration: 5, + maxDuration: 30, + protocols: [2, 3] + } + }, + mediaTypes: { + video: { + context: 'instream', + playerSize: [[300, 250]] + } + } + }, + + adUnitContext: { + refererInfo: { + referer: 'https://we-are-adot.com/test', + }, + gdprConsent: { + consentString: 'consent_string', + gdprApplies: true + } + }, + + adUnit_position: { + adUnitCode: 'ad_unit_position', + bidder: 'adot', + bidderRequestId: 'bid_request_id', + bidId: 'bid_id', + params: { + position: 1 + }, + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + } + }, + + adUnit_native: { + adUnitCode: 'ad_unit_native', + bidder: 'adot', + bidderRequestId: 'bid_request_id', + bidId: 'bid_id', + params: {}, + mediaTypes: { + native: { + title: {required: true, len: 140}, + icon: {required: true, sizes: [50, 50]}, + image: {required: false, sizes: [320, 200]}, + sponsoredBy: {required: false}, + body: {required: false}, + cta: {required: true} + } + } + }, + + serverRequest_banner: { + method: 'POST', + url: 'https://we-are-adot.com/bidrequest', + data: { + id: 'bid_request_id', + imp: [ + { + id: 'imp_id_banner_0_0', + banner: { + format: [{ + w: 300, + h: 200 + }] + }, + video: null + } + ], + site: { + page: 'https://we-are-adot.com/test', + domain: 'we-are-adot.com', + name: 'we-are-adot.com' + }, + device: { + ua: '', + language: 'en' + }, + user: null, + regs: null, + at: 1, + ext: { + adot: { + 'adapter_version': 'v1.0.0' + } + } + }, + _adot_internal: { + impressions: [ + { + impressionId: 'imp_id_banner_0_0', + adUnitCode: 'ad_unit_banner', + bidId: 'imp_id_banner' + } + ] + } + }, + + serverRequest_banner_twoImps: { + method: 'POST', + url: 'https://we-are-adot.com/bidrequest', + data: { + id: 'bid_request_id', + imp: [ + { + id: 'imp_id_banner_0_0', + banner: { + format: [{ + w: 300, + h: 200 + }] + }, + video: null + }, + { + id: 'imp_id_banner_2_0_0', + banner: { + format: [{ + w: 300, + h: 200 + }] + }, + video: null + } + ], + site: { + page: 'https://we-are-adot.com/test', + domain: 'we-are-adot.com', + name: 'we-are-adot.com' + }, + device: { + ua: '', + language: 'en' + }, + user: null, + regs: null, + at: 1, + ext: { + adot: { + 'adapter_version': 'v1.0.0' + } + } + }, + _adot_internal: { + impressions: [ + { + impressionId: 'imp_id_banner_0_0', + adUnitCode: 'ad_unit_banner', + bidId: 'imp_id_banner' + }, + { + impressionId: 'imp_id_banner_2_0_0', + adUnitCode: 'ad_unit_banner_2', + bidId: 'imp_id_banner_2' + } + ] + } + }, + + serverRequest_video_instream: { + method: 'POST', + url: 'https://we-are-adot.com/bidrequest', + data: { + id: 'bid_request_id', + imp: [ + { + id: 'imp_id_video_instream_0', + banner: null, + video: { + mimes: ['video/mp4'], + w: 300, + h: 200, + startdelay: 0, + minduration: 5, + maxduration: 35, + protocols: [2, 3] + } + } + ], + site: { + page: 'https://we-are-adot.com/test', + domain: 'we-are-adot.com', + name: 'we-are-adot.com' + }, + device: { + ua: '', + language: 'en' + }, + user: null, + regs: null, + at: 1, + ext: { + adot: { + 'adapter_version': 'v1.0.0' + } + } + }, + _adot_internal: { + impressions: [ + { + impressionId: 'imp_id_video_instream_0', + adUnitCode: 'ad_unit_video_instream', + bidId: 'imp_id_video_instream' + } + ] + } + }, + + serverRequest_video_outstream: { + method: 'POST', + url: 'https://we-are-adot.com/bidrequest', + data: { + id: 'bid_request_id', + imp: [ + { + id: 'imp_id_video_outstream_0', + banner: null, + video: { + mimes: ['video/mp4'], + w: 300, + h: 200, + startdelay: null, + minduration: 5, + maxduration: 35, + protocols: [2, 3] + } + } + ], + site: { + page: 'https://we-are-adot.com/test', + domain: 'we-are-adot.com', + name: 'we-are-adot.com' + }, + device: { + ua: '', + language: 'en' + }, + user: null, + regs: null, + at: 1, + ext: { + adot: { + 'adapter_version': 'v1.0.0' + } + } + }, + _adot_internal: { + impressions: [ + { + impressionId: 'imp_id_video_outstream_0', + adUnitCode: 'ad_unit_video_outstream', + bidId: 'imp_id_video_outstream' + } + ] + } + }, + + serverRequest_video_instream_outstream: { + method: 'POST', + url: 'https://we-are-adot.com/bidrequest', + data: { + id: 'bid_request_id', + imp: [ + { + id: 'imp_id_video_instream_0', + banner: null, + video: { + mimes: ['video/mp4'], + w: 300, + h: 200, + startdelay: 0, + minduration: 5, + maxduration: 35, + protocols: [2, 3] + } + }, + { + id: 'imp_id_video_outstream_0', + banner: null, + video: { + mimes: ['video/mp4'], + w: 300, + h: 200, + startdelay: null, + minduration: 5, + maxduration: 35, + protocols: [2, 3] + } + } + ], + site: { + page: 'https://we-are-adot.com/test', + domain: 'we-are-adot.com', + name: 'we-are-adot.com' + }, + device: { + ua: '', + language: 'en' + }, + user: null, + regs: null, + at: 1, + ext: { + adot: { + 'adapter_version': 'v1.0.0' + } + } + }, + _adot_internal: { + impressions: [ + { + impressionId: 'imp_id_video_instream_0', + adUnitCode: 'ad_unit_video_instream', + bidId: 'imp_id_video_instream' + }, + { + impressionId: 'imp_id_video_outstream_0', + adUnitCode: 'ad_unit_video_outstream', + bidId: 'imp_id_video_outstream' + } + ] + } + }, + + serverRequest_position: { + method: 'POST', + url: 'https://we-are-adot.com/bidrequest', + data: { + id: 'bid_request_id', + imp: [ + { + id: 'imp_id_banner', + banner: { + format: [{ + w: 300, + h: 200 + }], + position: 1 + }, + video: null + } + ], + site: { + page: 'https://we-are-adot.com/test', + domain: 'we-are-adot.com', + name: 'we-are-adot.com' + }, + device: { + ua: '', + language: 'en' + }, + user: null, + regs: null, + at: 1, + ext: { + adot: { + 'adapter_version': 'v1.0.0' + } + } + }, + _adot_internal: { + impressions: [ + { + impressionId: 'imp_id_banner', + adUnitCode: 'ad_unit_position' + } + ] + } + }, + + serverRequest_native: { + method: 'POST', + url: 'https://we-are-adot.com/bidrequest', + data: { + id: 'bid_request_id', + imp: [ + { + id: 'imp_id_native_0', + native: { + request: { + assets: [ + { + id: 1, + required: true, + title: { + len: 140 + } + }, + { + id: 2, + required: true, + img: { + type: 1, + wmin: 50, + hmin: 50 + } + }, + { + id: 3, + required: false, + img: { + type: 3, + wmin: 320, + hmin: 200 + } + }, + { + id: 4, + required: false, + data: { + type: 1 + } + }, + { + id: 5, + required: false, + data: { + type: 2 + } + }, + { + id: 6, + required: true, + data: { + type: 12 + } + } + ] + } + }, + video: null, + banner: null + } + ], + site: { + page: 'https://we-are-adot.com/test', + domain: 'we-are-adot.com', + name: 'we-are-adot.com' + }, + device: { + ua: '', + language: 'en' + }, + user: null, + regs: null, + at: 1, + ext: { + adot: { + 'adapter_version': 'v1.0.0' + } + } + }, + _adot_internal: { + impressions: [ + { + impressionId: 'imp_id_native_0', + adUnitCode: 'ad_unit_native', + bidId: 'imp_id_native' + } + ] + } + }, + + serverResponse_banner: { + body: { + cur: 'EUR', + seatbid: [ + { + bid: [ + { + impid: 'imp_id_banner_0_0', + crid: 'creative_id', + adm: 'creative_data_${AUCTION_PRICE}', + nurl: 'win_notice_url_${AUCTION_PRICE}', + price: 1.5, + h: 350, + w: 300, + ext: { + adot: { + media_type: 'banner' + } + } + } + ] + } + ] + } + }, + + serverResponse_banner_twoBids: { + body: { + cur: 'EUR', + seatbid: [ + { + bid: [ + { + impid: 'imp_id_banner_0_0', + crid: 'creative_id', + adm: 'creative_data_${AUCTION_PRICE}', + nurl: 'win_notice_url_${AUCTION_PRICE}', + price: 1.5, + h: 350, + w: 300, + ext: { + adot: { + media_type: 'banner' + } + } + }, + { + impid: 'imp_id_banner_2_0_0', + crid: 'creative_id_2', + adm: 'creative_data_2_${AUCTION_PRICE}', + nurl: 'win_notice_url_2_${AUCTION_PRICE}', + price: 2.5, + h: 400, + w: 350, + ext: { + adot: { + media_type: 'banner' + } + } + } + ] + } + ] + } + }, + + serverResponse_video_instream: { + body: { + cur: 'EUR', + seatbid: [ + { + bid: [ + { + impid: 'imp_id_video_instream_0', + crid: 'creative_id', + adm: 'creative_data_${AUCTION_PRICE}', + nurl: 'win_notice_url_${AUCTION_PRICE}', + price: 1.5, + ext: { + adot: { + media_type: 'video' + } + } + } + ] + } + ] + } + }, + + serverResponse_video_outstream: { + body: { + cur: 'EUR', + seatbid: [ + { + bid: [ + { + impid: 'imp_id_video_outstream_0', + crid: 'creative_id', + adm: 'creative_data_${AUCTION_PRICE}', + nurl: 'win_notice_url_${AUCTION_PRICE}', + price: 1.5, + ext: { + adot: { + media_type: 'video' + } + } + } + ] + } + ] + } + }, + + serverResponse_video_instream_outstream: { + body: { + cur: 'EUR', + seatbid: [ + { + bid: [ + { + impid: 'imp_id_video_instream_0', + crid: 'creative_id', + adm: 'creative_data_${AUCTION_PRICE}', + nurl: 'win_notice_url_${AUCTION_PRICE}', + price: 1.5, + ext: { + adot: { + media_type: 'video' + } + } + }, + { + impid: 'imp_id_video_outstream_0', + crid: 'creative_id', + adm: 'creative_data_${AUCTION_PRICE}', + nurl: 'win_notice_url_${AUCTION_PRICE}', + price: 1.5, + ext: { + adot: { + media_type: 'video' + } + } + } + ] + } + ] + } + }, + + serverResponse_native: { + body: { + cur: 'EUR', + seatbid: [ + { + bid: [ + { + impid: 'imp_id_native_0', + crid: 'creative_id', + adm: '{"native":{"assets":[{"id":1,"title":{"len":140,"text":"Hi everyone"}},{"id":2,"img":{"url":"https://adotmob.com","type":1,"w":50,"h":50}},{"id":3,"img":{"url":"https://adotmob.com","type":3,"w":320,"h":200}},{"id":4,"data":{"type":1,"value":"adotmob"}},{"id":5,"data":{"type":2,"value":"This is a test ad"}},{"id":6,"data":{"type":12,"value":"Click to buy"}}],"link":{"url":"https://adotmob.com?auction=${AUCTION_PRICE}"}}}', + nurl: 'win_notice_url_${AUCTION_PRICE}', + price: 1.5, + ext: { + adot: { + media_type: 'native' + } + } + } + ] + } + ] + } + } + }; + + describe('isBidRequestValid', function () { + describe('General', function () { + it('should return false when not given an ad unit', function () { + const adUnit = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an invalid ad unit', function () { + const adUnit = 'bad_bid'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit without bidder code', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.bidder = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with a bad bidder code', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.bidder = 'unknownBidder'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit without ad unit code', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.adUnitCode = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid ad unit code', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.adUnitCode = {}; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit without bid request identifier', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.bidderRequestId = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid bid request identifier', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.bidderRequestId = {}; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit without impression identifier', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.bidId = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid impression identifier', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.bidId = {}; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit without media types', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with empty media types', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes = {}; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with invalid media types', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes = 'bad_media_types'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + }); + + describe('Banner', function () { + it('should return true when given a valid ad unit', function () { + const adUnit = examples.adUnit_banner; + + expect(spec.isBidRequestValid(adUnit)).to.equal(true); + }); + + it('should return true when given a valid ad unit without bidder parameters', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.params = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(true); + }); + + it('should return false when given an ad unit without size', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes.banner.sizes = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid size', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes.banner.sizes = 'bad_banner_size'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an empty size', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes.banner.sizes = []; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid size value', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes.banner.sizes = ['bad_banner_size_value']; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with a size value with less than 2 dimensions', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes.banner.sizes = [[300]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with a size value with more than 2 dimensions', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes.banner.sizes = [[300, 250, 30]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with a negative width value', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes.banner.sizes = [[-300, 250]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with a negative height value', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes.banner.sizes = [[300, -250]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid width value', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes.banner.sizes = [[false, 250]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid height value', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes.banner.sizes = [[300, {}]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + }); + + describe('Video', function () { + it('should return true when given a valid outstream ad unit', function () { + const adUnit = examples.adUnit_video_outstream; + + expect(spec.isBidRequestValid(adUnit)).to.equal(true); + }); + + it('should return true when given a valid pre-roll instream ad unit', function () { + const adUnit = utils.deepClone(examples.adUnit_video_instream); + adUnit.params.video.instreamContext = 'pre-roll'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(true); + }); + + it('should return true when given a valid mid-roll instream ad unit', function () { + const adUnit = utils.deepClone(examples.adUnit_video_instream); + adUnit.params.video.instreamContext = 'mid-roll'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(true); + }); + + it('should return true when given a valid post-roll instream ad unit', function () { + const adUnit = utils.deepClone(examples.adUnit_video_instream); + adUnit.params.video.instreamContext = 'post-roll'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(true); + }); + + it('should return true when given an ad unit without size', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(true); + }); + + it('should return true when given an ad unit with an empty size', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = []; + + expect(spec.isBidRequestValid(adUnit)).to.equal(true); + }); + + it('should return true when given an ad unit without minimum duration parameter', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.minDuration = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(true); + }); + + it('should return true when given an ad unit without maximum duration parameter', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.maxDuration = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(true); + }); + + it('should return false when given an ad unit without bidder parameters', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with invalid bidder parameters', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params = 'bad_bidder_parameters'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit without video parameters', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with invalid video parameters', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video = 'bad_bidder_parameters'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit without mime types parameter', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.mimes = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid mime types parameter', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.mimes = 'bad_mime_types'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an empty mime types parameter', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.mimes = []; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid mime types parameter value', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.mimes = [200]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid minimum duration parameter', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.minDuration = 'bad_min_duration'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid maximum duration parameter', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.maxDuration = 'bad_max_duration'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit without protocols parameter', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.protocols = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid protocols parameter', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.protocols = 'bad_protocols'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an empty protocols parameter', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.protocols = []; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid protocols parameter value', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.protocols = ['bad_protocols_value']; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an instream ad unit without instream context', function () { + const adUnit = utils.deepClone(examples.adUnit_video_instream); + adUnit.params.video.instreamContext = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an instream ad unit with an invalid instream context', function () { + const adUnit = utils.deepClone(examples.adUnit_video_instream); + adUnit.params.video.instreamContext = 'bad_instream_context'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit without context', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.context = undefined; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid context', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.context = []; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an adpod ad unit', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.context = 'adpod'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an unknown context', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.context = 'invalid_context'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid size', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = 'bad_video_size'; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid size value', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = ['bad_video_size_value']; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with a size value with less than 2 dimensions', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = [[300]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with a size value with more than 2 dimensions', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = [[300, 250, 30]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with a negative width value', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = [[-300, 250]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with a negative height value', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = [[300, -250]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid width value', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = [[false, 250]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + + it('should return false when given an ad unit with an invalid height value', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = [[300, {}]]; + + expect(spec.isBidRequestValid(adUnit)).to.equal(false); + }); + }); + }); + + describe('buildRequests', function () { + describe('ServerRequest', function () { + it('should return a server request when given a valid ad unit and a valid ad unit context', function () { + const adUnits = [examples.adUnit_banner]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.length(1); + expect(serverRequests[0].method).to.exist.and.to.be.a('string').and.to.equal('POST'); + expect(serverRequests[0].url).to.exist.and.to.be.a('string').and.to.equal(BIDDER_URL); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0]._adot_internal).to.exist.and.to.be.an('object'); + expect(serverRequests[0]._adot_internal.impressions).to.exist.and.to.be.an('array').and.to.have.length(1); + expect(serverRequests[0]._adot_internal.impressions[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0]._adot_internal.impressions[0].impressionId).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); + expect(serverRequests[0]._adot_internal.impressions[0].adUnitCode).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].adUnitCode); + }); + + it('should return a server request containing a position when given a valid ad unit and a valid ad unit context and a position in the bidder params', function () { + const adUnits = [examples.adUnit_position]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.length(1); + expect(serverRequests[0].method).to.exist.and.to.be.a('string').and.to.equal('POST'); + expect(serverRequests[0].url).to.exist.and.to.be.a('string').and.to.equal(BIDDER_URL); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0]._adot_internal).to.exist.and.to.be.an('object'); + expect(serverRequests[0]._adot_internal.impressions).to.exist.and.to.be.an('array').and.to.have.length(1); + expect(serverRequests[0]._adot_internal.impressions[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0]._adot_internal.impressions[0].impressionId).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); + expect(serverRequests[0]._adot_internal.impressions[0].adUnitCode).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].adUnitCode); + expect(serverRequests[0].data.imp[0].banner.pos).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.position); + }); + + it('should return a server request when given two valid ad units and a valid ad unit context', function () { + const adUnits_1 = utils.deepClone(examples.adUnit_banner); + adUnits_1.bidId = 'bid_id_1'; + adUnits_1.adUnitCode = 'ad_unit_banner_1'; + + const adUnits_2 = utils.deepClone(examples.adUnit_banner); + adUnits_2.bidId = 'bid_id_2'; + adUnits_2.adUnitCode = 'ad_unit_banner_2'; + + const adUnits = [adUnits_1, adUnits_2]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.length(1); + expect(serverRequests[0].method).to.exist.and.to.be.a('string').and.to.equal('POST'); + expect(serverRequests[0].url).to.exist.and.to.be.a('string').and.to.equal(BIDDER_URL); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0]._adot_internal).to.exist.and.to.be.an('object'); + expect(serverRequests[0]._adot_internal.impressions).to.exist.and.to.be.an('array').and.to.have.length(2); + expect(serverRequests[0]._adot_internal.impressions[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0]._adot_internal.impressions[0].impressionId).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); + expect(serverRequests[0]._adot_internal.impressions[0].adUnitCode).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].adUnitCode); + expect(serverRequests[0]._adot_internal.impressions[1]).to.exist.and.to.be.an('object'); + expect(serverRequests[0]._adot_internal.impressions[1].impressionId).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0_0`); + expect(serverRequests[0]._adot_internal.impressions[1].adUnitCode).to.exist.and.to.be.a('string').and.to.equal(adUnits[1].adUnitCode); + }); + + it('should return an empty server request list when given an empty ad unit list and a valid ad unit context', function () { + const adUnits = []; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.length(0); + }); + + it('should not return a server request when given no ad unit and a valid ad unit context', function () { + const serverRequests = spec.buildRequests(null, examples.adUnitContext); + + expect(serverRequests).to.equal(null); + }); + + it('should not return a server request when given a valid ad unit and no ad unit context', function () { + const adUnits = [examples.adUnit_banner]; + + const serverRequests = spec.buildRequests(adUnits, null); + + expect(serverRequests).to.be.an('array').and.to.have.length(1); + }); + + it('should not return a server request when given a valid ad unit and an invalid ad unit context', function () { + const adUnits = [examples.adUnit_banner]; + + const serverRequests = spec.buildRequests(adUnits, {}); + + expect(serverRequests).to.be.an('array').and.to.have.length(1); + }); + }); + + describe('BidRequest', function () { + it('should return a valid server request when given a valid ad unit', function () { + const adUnits = [examples.adUnit_banner]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.at).to.exist.and.to.be.a('number').and.to.equal(1); + expect(serverRequests[0].data.ext).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.ext.adot).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.ext.adot.adapter_version).to.exist.and.to.be.a('string').and.to.equal('v1.0.0'); + }); + + it('should return one server request when given one valid ad unit', function () { + const adUnits = [examples.adUnit_banner]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].bidderRequestId); + }); + + it('should return one server request when given two valid ad units with different impression identifiers', function () { + const adUnit_1 = utils.deepClone(examples.adUnit_banner); + adUnit_1.bidId = 'bid_id_1'; + + const adUnit_2 = utils.deepClone(examples.adUnit_banner); + adUnit_2.bidId = 'bid_id_2'; + + const adUnits = [adUnit_1, adUnit_2]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[1].bidderRequestId); + }); + + it('should return two server requests when given two valid ad units with different bid request identifiers', function () { + const adUnit_1 = utils.deepClone(examples.adUnit_banner); + adUnit_1.bidderRequestId = 'bidder_request_id_1'; + + const adUnit_2 = utils.deepClone(examples.adUnit_banner); + adUnit_2.bidderRequestId = 'bidder_request_id_2'; + + const adUnits = [adUnit_1, adUnit_2]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(2); + expect(serverRequests[0].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[1].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[1].bidderRequestId); + }); + }); + + describe('Impression', function () { + describe('Banner', function () { + it('should return a server request with one impression when given a valid ad unit', function () { + const adUnits = [examples.adUnit_banner]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); + expect(serverRequests[0].data.imp[0].banner).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][0]); + expect(serverRequests[0].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][1]); + expect(serverRequests[0].data.imp[0].banner.format).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ + w: adUnits[0].mediaTypes.banner.sizes[0][0], + h: adUnits[0].mediaTypes.banner.sizes[0][1] + }); + }); + + it('should return a server request with two impressions containing one banner formats when given a valid ad unit with two banner sizes', function () { + const adUnit = utils.deepClone(examples.adUnit_banner); + adUnit.mediaTypes.banner.sizes = [ + [300, 250], + [350, 300] + ]; + + const adUnits = [adUnit]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(2); + + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); + expect(serverRequests[0].data.imp[0].banner).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][0]); + expect(serverRequests[0].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][1]); + expect(serverRequests[0].data.imp[0].banner.format).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ + w: adUnits[0].mediaTypes.banner.sizes[0][0], + h: adUnits[0].mediaTypes.banner.sizes[0][1] + }); + + expect(serverRequests[0].data.imp[1]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[1].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_1`); + expect(serverRequests[0].data.imp[1].banner).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[1].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[1][0]); + expect(serverRequests[0].data.imp[1].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[1][1]); + expect(serverRequests[0].data.imp[1].banner.format).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[1].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ + w: adUnits[0].mediaTypes.banner.sizes[1][0], + h: adUnits[0].mediaTypes.banner.sizes[1][1] + }); + }); + + it('should return a server request with two impressions when given two valid ad units with different impression identifiers', function () { + const adUnit_1 = utils.deepClone(examples.adUnit_banner); + adUnit_1.bidId = 'bid_id_1'; + + const adUnit_2 = utils.deepClone(examples.adUnit_banner); + adUnit_2.bidId = 'bid_id_2'; + + const adUnits = [adUnit_1, adUnit_2]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(2); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); + expect(serverRequests[0].data.imp[0].banner).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][0]); + expect(serverRequests[0].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][1]); + expect(serverRequests[0].data.imp[0].banner.format).to.exist.and.to.be.an('array'); + expect(serverRequests[0].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ + w: adUnits[0].mediaTypes.banner.sizes[0][0], + h: adUnits[0].mediaTypes.banner.sizes[0][1] + }); + expect(serverRequests[0].data.imp[1]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[1].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0_0`); + expect(serverRequests[0].data.imp[1].banner).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[1].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][0]); + expect(serverRequests[0].data.imp[1].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][1]); + expect(serverRequests[0].data.imp[1].banner.format).to.exist.and.to.be.an('array'); + expect(serverRequests[0].data.imp[1].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ + w: adUnits[1].mediaTypes.banner.sizes[0][0], + h: adUnits[1].mediaTypes.banner.sizes[0][1] + }); + }); + + it('should return a server request with one overriden impression when given two valid ad units with identical identifiers', function () { + const adUnit_1 = utils.deepClone(examples.adUnit_banner); + adUnit_1.mediaTypes.banner.sizes = [[300, 250]]; + + const adUnit_2 = utils.deepClone(examples.adUnit_banner); + adUnit_2.mediaTypes.banner.sizes = [[350, 300]]; + + const adUnits = [adUnit_1, adUnit_2]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0_0`); + expect(serverRequests[0].data.imp[0].banner).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][0]); + expect(serverRequests[0].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][1]); + expect(serverRequests[0].data.imp[0].banner.format).to.exist.and.to.be.an('array'); + expect(serverRequests[0].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ + w: adUnits[1].mediaTypes.banner.sizes[0][0], + h: adUnits[1].mediaTypes.banner.sizes[0][1] + }); + }); + + it('should return two server requests with one impression when given two valid ad units with different bid request identifiers', function () { + const adUnit_1 = utils.deepClone(examples.adUnit_banner); + adUnit_1.bidderRequestId = 'bidder_request_id_1'; + + const adUnit_2 = utils.deepClone(examples.adUnit_banner); + adUnit_2.bidderRequestId = 'bidder_request_id_2'; + + const adUnits = [adUnit_1, adUnit_2]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(2); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); + expect(serverRequests[0].data.imp[0].banner).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][0]); + expect(serverRequests[0].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][1]); + expect(serverRequests[0].data.imp[0].banner.format).to.exist.and.to.be.an('array'); + expect(serverRequests[0].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ + w: adUnits[0].mediaTypes.banner.sizes[0][0], + h: adUnits[0].mediaTypes.banner.sizes[0][1] + }); + expect(serverRequests[1].data).to.exist.and.to.be.an('object'); + expect(serverRequests[1].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[1].bidderRequestId); + expect(serverRequests[1].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[1].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[1].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0_0`); + expect(serverRequests[1].data.imp[0].banner).to.exist.and.to.be.an('object'); + expect(serverRequests[1].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][0]); + expect(serverRequests[1].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][1]); + expect(serverRequests[1].data.imp[0].banner.format).to.exist.and.to.be.an('array'); + expect(serverRequests[1].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ + w: adUnits[1].mediaTypes.banner.sizes[0][0], + h: adUnits[1].mediaTypes.banner.sizes[0][1] + }); + }); + }); + + describe('Video', function () { + it('should return a server request with one impression when given a valid outstream ad unit', function () { + const adUnit = examples.adUnit_video_outstream; + + const adUnits = [adUnit]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); + expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); + expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); + }); + + it('should return a server request with one impression when given a valid pre-roll instream ad unit', function () { + const adUnit = utils.deepClone(examples.adUnit_video_instream); + adUnit.params.video.instreamContext = 'pre-roll'; + + const adUnits = [adUnit]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.exist.and.to.be.a('number').and.to.equal(0); + expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); + expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); + }); + + it('should return a server request with one impression when given a valid mid-roll instream ad unit', function () { + const adUnit = utils.deepClone(examples.adUnit_video_instream); + adUnit.params.video.instreamContext = 'mid-roll'; + + const adUnits = [adUnit]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.exist.and.to.be.a('number').and.to.equal(-1); + expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); + expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); + }); + + it('should return a server request with one impression when given a valid post-roll instream ad unit', function () { + const adUnit = utils.deepClone(examples.adUnit_video_instream); + adUnit.params.video.instreamContext = 'post-roll'; + + const adUnits = [adUnit]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.exist.and.to.be.a('number').and.to.equal(-2); + expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); + expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); + }); + + it('should return a server request with one impression when given a valid ad unit without player size', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = undefined; + + const adUnits = [adUnit]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); + expect(serverRequests[0].data.imp[0].video.w).to.equal(null); + expect(serverRequests[0].data.imp[0].video.h).to.equal(null); + expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); + expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); + }); + + it('should return a server request with one impression when given a valid ad unit with an empty player size', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = []; + + const adUnits = [adUnit]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); + expect(serverRequests[0].data.imp[0].video.w).to.equal(null); + expect(serverRequests[0].data.imp[0].video.h).to.equal(null); + expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); + expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); + }); + + it('should return a server request with one impression when given a valid ad unit with multiple player sizes', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.mediaTypes.video.playerSize = [[350, 300], [400, 350]]; + + const adUnits = [adUnit]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); + expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); + expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); + }); + + it('should return a server request with one impression when given a valid ad unit without minimum duration', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.minDuration = undefined; + + const adUnits = [adUnit]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); + expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[0].data.imp[0].video.minduration).to.equal(null); + expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); + }); + + it('should return a server request with one impression when given a valid ad unit without maximum duration', function () { + const adUnit = utils.deepClone(examples.adUnit_video_outstream); + adUnit.params.video.maxDuration = undefined; + + const adUnits = [adUnit]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); + expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); + expect(serverRequests[0].data.imp[0].video.maxduration).to.equal(null); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); + }); + + it('should return a server request with two impressions when given two valid ad units with different impression identifiers', function () { + const adUnit_1 = utils.deepClone(examples.adUnit_video_outstream); + adUnit_1.bidId = 'bid_id_1'; + + const adUnit_2 = utils.deepClone(examples.adUnit_video_outstream); + adUnit_2.bidId = 'bid_id_2'; + + const adUnits = [adUnit_1, adUnit_2]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(2); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); + expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); + expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); + expect(serverRequests[0].data.imp[1]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[1].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0`); + expect(serverRequests[0].data.imp[1].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[1].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[1].video.startdelay).to.equal(null); + expect(serverRequests[0].data.imp[1].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[0].data.imp[1].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[0].data.imp[1].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.minDuration); + expect(serverRequests[0].data.imp[1].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.maxDuration); + expect(serverRequests[0].data.imp[1].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[1].params.video.protocols); + }); + + it('should return a server request with one overridden impression when given two valid ad units with identical identifiers', function () { + const adUnit_1 = utils.deepClone(examples.adUnit_video_outstream); + adUnit_1.params.video.minDuration = 10; + + const adUnit_2 = utils.deepClone(examples.adUnit_video_outstream); + adUnit_2.params.video.minDuration = 15; + + const adUnits = [adUnit_1, adUnit_2]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); + expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.minDuration); + expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.maxDuration); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[1].params.video.protocols); + }); + + it('should return two server requests with one impression when given two valid ad units with different bid request identifiers', function () { + const adUnit_1 = utils.deepClone(examples.adUnit_video_outstream); + adUnit_1.bidderRequestId = 'bidder_request_id_1'; + + const adUnit_2 = utils.deepClone(examples.adUnit_video_outstream); + adUnit_2.bidderRequestId = 'bidder_request_id_2'; + + const adUnits = [adUnit_1, adUnit_2]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(2); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); + expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); + expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); + expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); + expect(serverRequests[1].data).to.exist.and.to.be.an('object'); + expect(serverRequests[1].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[1].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[1].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0`); + expect(serverRequests[1].data.imp[0].video).to.exist.and.to.be.an('object'); + expect(serverRequests[1].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); + expect(serverRequests[1].data.imp[0].video.startdelay).to.equal(null); + expect(serverRequests[1].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][0]); + expect(serverRequests[1].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][1]); + expect(serverRequests[1].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.minDuration); + expect(serverRequests[1].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.maxDuration); + expect(serverRequests[1].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[1].params.video.protocols); + }); + }); + + describe('Native', function () { + it('should return a server request with one impression when given a valid ad unit', function () { + const adUnits = [examples.adUnit_native]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnit_native); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); + expect(serverRequests[0].data.imp[0].native).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.imp[0].native.request).to.exist.and.to.be.a('string').and.to.equal(JSON.stringify(examples.serverRequest_native.data.imp[0].native.request)) + }); + }); + }); + + describe('Site', function () { + it('should return a server request with site information when given a valid ad unit and a valid ad unit context', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = examples.adUnitContext; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.site).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.site.page).to.exist.and.to.be.an('string').and.to.equal(adUnitContext.refererInfo.referer); + expect(serverRequests[0].data.site.id).to.equal(undefined); + expect(serverRequests[0].data.site.domain).to.exist.and.to.be.an('string').and.to.equal('we-are-adot.com'); + expect(serverRequests[0].data.site.name).to.exist.and.to.be.an('string').and.to.equal('we-are-adot.com'); + }); + + it('should return a server request without site information when not given an ad unit context', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = undefined; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.site).to.equal(null); + }); + + it('should return a server request without site information when given an ad unit context without referer information', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.refererInfo = undefined; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.site).to.equal(null); + }); + + it('should return a server request without site information when given an ad unit context with invalid referer information', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.refererInfo = 'bad_referer_information'; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.site).to.equal(null); + }); + + it('should return a server request without site information when given an ad unit context without referer', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.refererInfo.referer = undefined; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.site).to.equal(null); + }); + + it('should return a server request without site information when given an ad unit context with an invalid referer', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.refererInfo.referer = {}; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.site).to.equal(null); + }); + + it('should return a server request without site information when given an ad unit context with a misformatted referer', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.refererInfo.referer = 'we-are-adot'; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.site).to.equal(null); + }); + }); + + describe('Device', function () { + it('should return a server request with device information when given a valid ad unit and a valid ad unit context', function () { + const adUnits = [examples.adUnit_banner]; + + const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.device).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.device.ua).to.exist.and.to.be.a('string'); + expect(serverRequests[0].data.device.language).to.exist.and.to.be.a('string'); + }); + }); + + describe('Regs', function () { + it('should return a server request with regulations information when given a valid ad unit and a valid ad unit context with GDPR applying', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = examples.adUnitContext; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.regs).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.regs.ext).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.regs.ext.gdpr).to.exist.and.to.be.a('boolean').and.to.equal(adUnitContext.gdprConsent.gdprApplies); + }); + + it('should return a server request with regulations information when given a valid ad unit and a valid ad unit context with GDPR not applying', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.gdprConsent.gdprApplies = false; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.regs).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.regs.ext).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.regs.ext.gdpr).to.exist.and.to.be.a('boolean').and.to.equal(adUnitContext.gdprConsent.gdprApplies); + }); + + it('should return a server request without regulations information when not given an ad unit context', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = undefined; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.regs).to.equal(null); + }); + + it('should return a server request without regulations information when given an ad unit context without GDPR information', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.gdprConsent = undefined; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.regs).to.equal(null); + }); + + it('should return a server request without regulations information when given an ad unit context with invalid GDPR information', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.gdprConsent = 'bad_gdpr_consent'; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.regs).to.equal(null); + }); + + it('should return a server request without regulations information when given an ad unit context with invalid GDPR application information', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.gdprConsent.gdprApplies = 'bad_gdpr_applies'; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.regs).to.equal(null); + }); + }); + + describe('User', function () { + it('should return a server request with user information when given a valid ad unit and a valid ad unit context', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = examples.adUnitContext; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.user).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.user.ext).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.user.ext.consent).to.exist.and.to.be.a('string').and.to.equal(adUnitContext.gdprConsent.consentString); + }); + + it('should return a server request without user information when not given an ad unit context', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = undefined; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.user).to.equal(null); + }); + + it('should return a server request without user information when given an ad unit context without GDPR information', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.gdprConsent = undefined; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.user).to.equal(null); + }); + + it('should return a server request without user information when given an ad unit context with invalid GDPR information', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.gdprConsent = 'bad_gdpr_consent'; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.user).to.equal(null); + }); + + it('should return a server request without user information when given an ad unit context with an invalid consent string', function () { + const adUnits = [examples.adUnit_banner]; + + const adUnitContext = utils.deepClone(examples.adUnitContext); + adUnitContext.gdprConsent.consentString = true; + + const serverRequests = spec.buildRequests(adUnits, adUnitContext); + + expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); + expect(serverRequests[0].data).to.exist.and.to.be.an('object'); + expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); + expect(serverRequests[0].data.user).to.equal(null); + }); + }); + }); + + describe('interpretResponse', function () { + describe('General', function () { + it('should return an ad when given a valid server response with one bid with USD currency', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.cur = 'USD'; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(null); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].h); + expect(ads[0].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return two ads when given a valid server response with two bids', function () { + const serverRequest = examples.serverRequest_banner_twoImps; + + const serverResponse = examples.serverResponse_banner_twoBids; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(2); + + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(null); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].h); + expect(ads[0].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); + expect(ads[0].renderer).to.equal(null); + expect(ads[1].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[1].bidId); + expect(ads[1].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[1].adm); + expect(ads[1].adUrl).to.equal(null); + expect(ads[1].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[1].crid); + expect(ads[1].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[1].price); + expect(ads[1].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[1].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[1].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[1].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[1].h); + expect(ads[1].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[1].w); + expect(ads[1].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); + expect(ads[1].renderer).to.equal(null); + }); + + it('should return no ad when not given a server response', function () { + const ads = spec.interpretResponse(null); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when not given a server response body', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given an invalid server response body', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body = 'invalid_body'; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response without seat bids', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with invalid seat bids', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid = 'invalid_seat_bids'; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with an empty seat bids array', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid = []; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with an invalid seat bid', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid = 'invalid_bids'; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with an empty bids array', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid = []; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with an invalid bid', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid = ['invalid_bid']; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid without currency', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.cur = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid currency', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.cur = {}; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid without impression identifier', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].impid = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid impression identifier', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].impid = {}; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid without creative identifier', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].crid = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid creative identifier', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].crid = {}; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid without ad markup and ad serving URL', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].adm = undefined; + serverResponse.body.seatbid[0].bid[0].nurl = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid ad markup', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].adm = {}; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an ad markup without auction price macro', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].adm = 'creative_data'; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid ad serving URL', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].nurl = {}; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an ad serving URL without auction price macro', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].nurl = 'win_notice_url'; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid without bid price', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].price = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid bid price', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].price = {}; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid without extension', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].ext = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid extension', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].ext = 'bad_ext'; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid without adot extension', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].ext.adot = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid adot extension', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].ext.adot = 'bad_adot_ext'; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid without media type', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].ext.adot.media_type = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid media type', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].ext.adot.media_type = {}; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an unknown media type', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].ext.adot.media_type = 'unknown_media_type'; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and no server request', function () { + const serverRequest = undefined; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and an invalid server request', function () { + const serverRequest = 'bad_server_request'; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request without bid request', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest.data = undefined; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request with an invalid bid request', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest.data = 'bad_bid_request'; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request without impression', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest.data.imp = undefined; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request with an invalid impression field', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest.data.imp = 'invalid_impressions'; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request without matching impression', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest.data.imp[0].id = 'unknown_imp_id'; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request without internal data', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest._adot_internal = undefined; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request with invalid internal data', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest._adot_internal = 'bad_internal_data'; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request without internal impression data', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest._adot_internal.impressions = undefined; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request with invalid internal impression data', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest._adot_internal.impressions = 'bad_internal_impression_data'; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request without matching internal impression', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest._adot_internal.impressions[0].impressionId = 'unknown_imp_id'; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request without internal impression ad unit code', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest._adot_internal.impressions[0].adUnitCode = undefined; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request with an invalid internal impression ad unit code', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest._adot_internal.impressions[0].adUnitCode = {}; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + }); + + describe('Banner', function () { + it('should return an ad when given a valid server response with one bid', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = examples.serverResponse_banner; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(null); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].h); + expect(ads[0].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return an ad when given a valid server response with one bid without a win notice URL', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].nurl = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(null); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].h); + expect(ads[0].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return an ad when given a valid server response with one bid using an ad serving URL', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].adm = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.equal(null); + expect(ads[0].adUrl).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].nurl); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].h); + expect(ads[0].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return no ad when given a server response with a bid without height', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].h = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid height', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].h = {}; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid without width', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].w = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid width', function () { + const serverRequest = examples.serverRequest_banner; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + serverResponse.body.seatbid[0].bid[0].w = {}; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request without banner impression', function () { + const serverRequest = utils.deepClone(examples.serverRequest_banner); + serverRequest.data.imp[0].banner = undefined; + + const serverResponse = utils.deepClone(examples.serverResponse_banner); + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + }); + + describe('Video', function () { + it('should return an ad when given a valid server response with one bid on an instream impression', function () { + const serverRequest = examples.serverRequest_video_instream; + + const serverResponse = examples.serverResponse_video_instream; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); + expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return an ad when given a valid server response with one bid on an outstream impression', function () { + const serverRequest = examples.serverRequest_video_outstream; + + const serverResponse = examples.serverResponse_video_outstream; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); + expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); + expect(ads[0].renderer).to.be.an('object'); + }); + + it('should return two ads when given a valid server response with two bids on both instream and outstream impressions', function () { + const serverRequest = examples.serverRequest_video_instream_outstream; + + const serverResponse = examples.serverResponse_video_instream_outstream; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(2); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); + expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); + expect(ads[0].renderer).to.equal(null); + expect(ads[1].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[1].bidId); + expect(ads[1].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[1].adm); + expect(ads[1].adUrl).to.equal(null); + expect(ads[1].vastXml).to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[1].vastUrl).to.equal(null); + expect(ads[1].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[1].crid); + expect(ads[1].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[1].price); + expect(ads[1].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[1].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[1].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.equal(serverRequest.data.imp[1].video.h); + expect(ads[0].width).to.equal(serverRequest.data.imp[1].video.w); + expect(ads[1].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); + expect(ads[1].renderer).to.be.an('object'); + }); + + it('should return an ad when given a valid server response with one bid without a win notice URL', function () { + const serverRequest = examples.serverRequest_video_instream; + + const serverResponse = utils.deepClone(examples.serverResponse_video_instream); + serverResponse.body.seatbid[0].bid[0].nurl = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); + expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return an ad when given a valid server response with one bid using an ad serving URL', function () { + const serverRequest = examples.serverRequest_video_instream; + + const serverResponse = utils.deepClone(examples.serverResponse_video_instream); + serverResponse.body.seatbid[0].bid[0].adm = undefined; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.equal(null); + expect(ads[0].adUrl).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].nurl); + expect(ads[0].vastXml).to.equal(null); + expect(ads[0].vastUrl).to.equal(serverResponse.body.seatbid[0].bid[0].nurl); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); + expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return an ad when given a valid server response with a bid with a video height', function () { + const serverRequest = examples.serverRequest_video_instream; + + const serverResponse = utils.deepClone(examples.serverResponse_video_instream); + serverResponse.body.seatbid[0].bid[0].h = 500; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); + expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return an ad when given a valid server response with a bid with a video width', function () { + const serverRequest = examples.serverRequest_video_instream; + + const serverResponse = utils.deepClone(examples.serverResponse_video_instream); + serverResponse.body.seatbid[0].bid[0].w = 500; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); + expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return an ad when given a valid server response with a bid with a video width and height', function () { + const serverRequest = examples.serverRequest_video_instream; + + const serverResponse = utils.deepClone(examples.serverResponse_video_instream); + serverResponse.body.seatbid[0].bid[0].w = 500; + serverResponse.body.seatbid[0].bid[0].h = 400; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.equal(serverResponse.body.seatbid[0].bid[0].h); + expect(ads[0].width).to.equal(serverResponse.body.seatbid[0].bid[0].w); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return an ad when given a valid server response and server request with a video impression without width', function () { + const serverRequest = utils.deepClone(examples.serverRequest_video_instream); + serverRequest.data.imp[0].video.w = null; + + const serverResponse = utils.deepClone(examples.serverResponse_video_instream); + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.equal(null); + expect(ads[0].width).to.equal(null); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return an ad when given a valid server response and server request with a video impression without height', function () { + const serverRequest = utils.deepClone(examples.serverRequest_video_instream); + serverRequest.data.imp[0].video.h = null; + + const serverResponse = utils.deepClone(examples.serverResponse_video_instream); + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].adUrl).to.equal(null); + expect(ads[0].vastXml).to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(ads[0].vastUrl).to.equal(null); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].height).to.equal(null); + expect(ads[0].width).to.equal(null); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); + expect(ads[0].renderer).to.equal(null); + }); + + it('should return no ad when given a server response with a bid with an invalid height', function () { + const serverRequest = examples.serverRequest_video_instream; + + const serverResponse = utils.deepClone(examples.serverResponse_video_instream); + serverResponse.body.seatbid[0].bid[0].h = {}; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a server response with a bid with an invalid width', function () { + const serverRequest = examples.serverRequest_video_instream; + + const serverResponse = utils.deepClone(examples.serverResponse_video_instream); + serverResponse.body.seatbid[0].bid[0].w = {}; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + it('should return no ad when given a valid server response and a server request without video impression', function () { + const serverRequest = utils.deepClone(examples.serverRequest_video_instream); + serverRequest.data.imp[0].video = undefined; + + const serverResponse = utils.deepClone(examples.serverResponse_video_instream); + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(0); + }); + + describe('Outstream renderer', function () { + function spyAdRenderingQueue(ad) { + const spy = sinon.spy(ad.renderer, 'push'); + + this.sinonSpies.push(spy); + } + + function executeAdRenderer(ad, onRendererExecution, done) { + executeRenderer(ad.renderer, ad); + + setTimeout(() => { + try { + onRendererExecution(); + } catch (err) { + done(err); + } + + done() + }, 100); + } + + before('Bind helper functions to the Mocha context', function () { + this.spyAdRenderingQueue = spyAdRenderingQueue.bind(this); + + window.VASTPlayer = function VASTPlayer() {}; + window.VASTPlayer.prototype.loadXml = function loadXml() { + return new Promise((resolve, reject) => resolve()) + }; + window.VASTPlayer.prototype.load = function load() { + return new Promise((resolve, reject) => resolve()) + }; + window.VASTPlayer.prototype.on = function on(event, callback) {}; + window.VASTPlayer.prototype.startAd = function startAd() {}; + }); + + beforeEach('Initialize the Sinon spies list', function () { + this.sinonSpies = []; + }); + + afterEach('Clear the registered Sinon spies', function () { + this.sinonSpies.forEach(spy => spy.restore()); + }); + + after('clear data', () => { + window.VASTPlayer = null; + }); + + it('should return an ad with valid renderer', function () { + const serverRequest = examples.serverRequest_video_outstream; + const serverResponse = examples.serverResponse_video_outstream; + + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].renderer).to.be.an('object'); + }); + + it('should append a command to the ad rendering queue when executing the renderer', function (done) { + const serverRequest = examples.serverRequest_video_outstream; + const serverResponse = examples.serverResponse_video_outstream; + + const [ad] = spec.interpretResponse(serverResponse, serverRequest); + + this.spyAdRenderingQueue(ad); + + executeAdRenderer(ad, () => { + expect(ad.renderer.push.calledOnce).to.equal(true); + expect(ad.renderer.push.firstCall.args[0]).to.exist.and.to.be.a('function'); + }, done); + }); + }); + }); + + describe('Native', function () { + it('should return an ad when given a valid server response with one bid', function () { + const serverRequest = examples.serverRequest_native; + const serverResponse = examples.serverResponse_native; + const native = JSON.parse(serverResponse.body.seatbid[0].bid[0].adm).native; + const {link, assets} = native; + const ads = spec.interpretResponse(serverResponse, serverRequest); + + expect(ads).to.be.an('array').and.to.have.length(1); + expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); + expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); + expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); + expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); + expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('native'); + expect(ads[0].native).to.exist.and.to.be.an('object'); + expect(Object.keys(ads[0].native)).to.have.length(10); + expect(ads[0].native.title).to.equal(assets[0].title.text); + expect(ads[0].native.icon.url).to.equal(assets[1].img.url); + expect(ads[0].native.icon.width).to.equal(assets[1].img.w); + expect(ads[0].native.icon.height).to.equal(assets[1].img.h); + expect(ads[0].native.image.url).to.equal(assets[2].img.url); + expect(ads[0].native.image.width).to.equal(assets[2].img.w); + expect(ads[0].native.image.height).to.equal(assets[2].img.h); + expect(ads[0].native.sponsoredBy).to.equal(assets[3].data.value); + expect(ads[0].native.body).to.equal(assets[4].data.value); + expect(ads[0].native.cta).to.equal(assets[5].data.value); + expect(ads[0].native.clickUrl).to.equal(link.url); + }); + }); + }); +}); From 21d1f53f9d522d805ffdf923aa49e60a0c84cfb2 Mon Sep 17 00:00:00 2001 From: Kanchika - Automatad Date: Wed, 8 Apr 2020 00:04:46 +0530 Subject: [PATCH 218/496] Add Automatad Bid Adapter (#5017) * added automatad bid adapter * added automatad bid adapter readme * added automatad bidder adapter unit test * updated maintainer email id for automatad adapter * refactored automatadBidAdapter js * refactored automatadBidAdapter unit test * refactored automatadBidAdapter unit test * added usersync code to automatad bid adapter * Added unit test for onBidWon in automatadBidAdapter_spec * removed trailing spaces * removed trailing space * changes for getUserSync function * lint error fixes * updated usersync url * additional test for onBidWon function added * added ajax stub in test --- modules/automatadBidAdapter.js | 123 +++++++++++++++ modules/automatadBidAdapter.md | 34 +++++ test/spec/modules/automatadBidAdapter_spec.js | 144 ++++++++++++++++++ 3 files changed, 301 insertions(+) create mode 100644 modules/automatadBidAdapter.js create mode 100644 modules/automatadBidAdapter.md create mode 100644 test/spec/modules/automatadBidAdapter_spec.js diff --git a/modules/automatadBidAdapter.js b/modules/automatadBidAdapter.js new file mode 100644 index 00000000000..4a9e6b6a1e4 --- /dev/null +++ b/modules/automatadBidAdapter.js @@ -0,0 +1,123 @@ +import {registerBidder} from '../src/adapters/bidderFactory.js' +import * as utils from '../src/utils.js' +import {BANNER} from '../src/mediaTypes.js' +import {ajax} from '../src/ajax.js' + +const BIDDER = 'automatad' + +const ENDPOINT_URL = 'https://rtb2.automatad.com/ortb2' + +const DEFAULT_BID_TTL = 30 +const DEFAULT_CURRENCY = 'USD' +const DEFAULT_NET_REVENUE = true + +export const spec = { + code: BIDDER, + aliases: ['atd'], + supportedMediaTypes: [BANNER], + + isBidRequestValid: function (bid) { + // will receive request bid. check if have necessary params for bidding + return (bid && bid.hasOwnProperty('params') && bid.params.hasOwnProperty('siteId') && bid.params.hasOwnProperty('placementId') && bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty('banner')) + }, + + buildRequests: function (validBidRequests, bidderRequest) { + if (!validBidRequests || !bidderRequest) { + return + } + + const siteId = validBidRequests[0].params.siteId + const placementId = validBidRequests[0].params.placementId + + const impressions = validBidRequests.map(bidRequest => ({ + id: bidRequest.bidId, + banner: { + format: bidRequest.sizes.map(sizeArr => ({ + w: sizeArr[0], + h: sizeArr[1], + })) + }, + })) + + // params from bid request + const openrtbRequest = { + id: validBidRequests[0].auctionId, + imp: impressions, + site: { + id: siteId, + placement: placementId, + domain: window.location.hostname, + page: window.location.href, + ref: bidderRequest.refererInfo ? bidderRequest.refererInfo.referer || null : null, + }, + } + + const payloadString = JSON.stringify(openrtbRequest) + return { + method: 'POST', + url: ENDPOINT_URL + '/resp', + data: payloadString, + options: { + contentType: 'application/json', + withCredentials: false, + crossOrigin: true, + }, + } + }, + + interpretResponse: function (serverResponse, request) { + const bidResponses = [] + const response = (serverResponse || {}).body + + if (response && response.seatbid && response.seatbid.length === 1 && response.seatbid[0].bid && response.seatbid[0].bid.length) { + response.seatbid[0].bid.forEach(bid => { + bidResponses.push({ + requestId: bid.impid, + cpm: bid.price, + ad: bid.adm, + adDomain: bid.adomain[0], + currency: DEFAULT_CURRENCY, + ttl: DEFAULT_BID_TTL, + creativeId: bid.crid, + width: bid.w, + height: bid.h, + netRevenue: DEFAULT_NET_REVENUE, + nurl: bid.nurl, + }) + }) + } else { + utils.logInfo('automatad :: no valid responses to interpret') + } + + return bidResponses + }, + getUserSyncs: function(syncOptions, serverResponse) { + return [{ + type: 'iframe', + url: 'https://rtb2.automatad.com/ortb2/async_usersync' + }] + }, + onBidWon: function(bid) { + if (!bid.nurl) { return } + const winUrl = bid.nurl.replace( + /\$\{AUCTION_PRICE\}/, + bid.cpm + ).replace( + /\$\{AUCTION_IMP_ID\}/, + bid.requestId + ).replace( + /\$\{AUCTION_CURRENCY\}/, + bid.currency + ).replace( + /\$\{AUCTION_ID\}/, + bid.auctionId + ) + spec.ajaxCall(winUrl, null) + return true + }, + ajaxCall: function(endpoint, data) { + ajax(endpoint, data) + }, + +} +registerBidder(spec) diff --git a/modules/automatadBidAdapter.md b/modules/automatadBidAdapter.md new file mode 100644 index 00000000000..56a4b53c067 --- /dev/null +++ b/modules/automatadBidAdapter.md @@ -0,0 +1,34 @@ +# Overview + +``` +Module Name: Automatad Bid Adapter +Module Type: Bidder Adapter +Maintainer: tech@automatad.com +``` + +# Description + +Connects to automatad exchange for bids. + +automatad bid adapter supports Banner ads. + +# Test Parameters +``` +var adUnits = [ + { + code: 'banner-ad-div', + mediaTypes: { + banner: { + sizes: [[300, 250], [300,600]] + } + }, + bids: [{ + bidder: 'automatad', + params: { + siteId: 'someValue', + placementId: 'someValue' + } + }] + } +]; +``` diff --git a/test/spec/modules/automatadBidAdapter_spec.js b/test/spec/modules/automatadBidAdapter_spec.js new file mode 100644 index 00000000000..788fd3aefc4 --- /dev/null +++ b/test/spec/modules/automatadBidAdapter_spec.js @@ -0,0 +1,144 @@ +import { expect } from 'chai' +import { spec } from 'modules/automatadBidAdapter.js' +import { newBidder } from 'src/adapters/bidderFactory.js' + +describe('automatadBidAdapter', function () { + const adapter = newBidder(spec) + + let bidRequest = { + bidder: 'automatad', + params: {siteId: '123ad', placementId: '123abc345'}, + mediaTypes: { + banner: { + sizes: [[300, 600]], + } + }, + adUnitCode: 'some-ad-unit-code', + transactionId: '1465569e-52cc-4c36-88a1-7174cfef4b44', + sizes: [[300, 600]], + bidId: '123abc', + bidderRequestId: '3213887463c059', + auctionId: 'abc-123', + src: 'client', + bidRequestsCount: 1 + } + + let expectedResponse = [{ + 'body': { + 'id': 'abc-123', + 'seatbid': [ + { + 'bid': [ + { + 'adm': '', + 'adomain': [ + 'someAdDomain' + ], + 'crid': 123, + 'h': 600, + 'id': 'bid1', + 'impid': '1', + 'nurl': 'https://example/win', + 'price': 0.5, + 'w': 300 + } + ] + } + ] + } + }] + + describe('codes', function () { + it('should return a bidder code of automatad', function () { + expect(spec.code).to.equal('automatad') + }) + it('should alias atd', function () { + expect(spec.aliases.length > 0 && spec.aliases[0] === 'atd').to.be.true + }) + }) + + describe('isBidRequestValid', function () { + let inValidBid = Object.assign({}, bidRequest) + delete inValidBid.params + it('should return true if all params present', function () { + expect(spec.isBidRequestValid(bidRequest)).to.equal(true) + }) + + it('should return false if any parameter missing', function () { + expect(spec.isBidRequestValid(inValidBid)).to.be.false + }) + }) + + describe('buildRequests', function () { + let req = spec.buildRequests([ bidRequest ], { refererInfo: { } }) + let rdata + + it('should return request object', function () { + expect(req).to.not.be.null + }) + + it('should build request data', function () { + expect(req.data).to.not.be.null + }) + + it('should include one request', function () { + rdata = JSON.parse(req.data) + expect(rdata.imp.length).to.equal(1) + }) + + it('should include media types', function () { + let r = rdata.imp[0] + expect(r.media_types !== null).to.be.true + }) + + it('should include all publisher params', function () { + let r = rdata.imp[0] + expect(r.siteID !== null && r.placementID !== null).to.be.true + }) + }) + + describe('interpretResponse', function () { + it('should get the correct bid response', function () { + let result = spec.interpretResponse(expectedResponse[0]) + expect(result).to.be.an('array').that.is.not.empty + }) + + it('handles empty bid response', function () { + let response = { + body: '' + } + let result = spec.interpretResponse(response) + expect(result.length).to.equal(0) + }) + }) + + describe('getUserSyncs', function () { + it('should return iframe sync', function () { + let sync = spec.getUserSyncs() + expect(sync.length).to.equal(1) + expect(sync[0].type === 'iframe') + expect(typeof sync[0].url === 'string') + }) + }) + + describe('onBidWon', function () { + let serverResponses = spec.interpretResponse(expectedResponse[0]) + let wonbid = serverResponses[0] + let ajaxStub + + beforeEach(() => { + ajaxStub = sinon.stub(spec, 'ajaxCall') + }) + + afterEach(() => { + ajaxStub.restore() + }) + + it('Returns true is nurl is good/not blank', function () { + expect(wonbid.nurl).to.not.equal('') + expect(spec.onBidWon(wonbid)).to.be.true + expect(ajaxStub.calledOnce).to.equal(true) + expect(ajaxStub.firstCall.args[0].indexOf('https://')).to.equal(0) + }) + }) +}) From 6ad085f01303da153a17c1f20a018b4fef0bff4e Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Tue, 7 Apr 2020 15:07:05 -0400 Subject: [PATCH 219/496] update regex in readme (#5088) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index be07a27ddc1..0e07521ac3b 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ module.exports = { // override the regular exclusion from above (for being inside node_modules). { test: /.js$/, - include: new RegExp(`\\${path.sep}prebid\.js`), + include: new RegExp(`\\${path.sep}prebid\\.js`), use: { loader: 'babel-loader', // presets and plugins for Prebid.js must be manually specified separate from your other babel rule. From 036d71d329a660a8926ee92cc5c3b6c8f07f4ea3 Mon Sep 17 00:00:00 2001 From: Chris DeGroat Date: Tue, 7 Apr 2020 14:28:19 -0500 Subject: [PATCH 220/496] Prebid adapter for windtalker (#5040) * prebid adatper for windtalker * file extension for imports * fix whitespace in adapter * removed inital value assignment per LGTM request * Minorchange to md file for windtalker * Updated windtalker adapter with tests Co-authored-by: Chris DeGroat --- modules/windtalkerBidAdapter.js | 307 +++++++++++++++ modules/windtalkerBidAdapter.md | 86 +++++ .../spec/modules/windtalkerBidAdapter_spec.js | 348 ++++++++++++++++++ 3 files changed, 741 insertions(+) create mode 100644 modules/windtalkerBidAdapter.js create mode 100644 modules/windtalkerBidAdapter.md create mode 100644 test/spec/modules/windtalkerBidAdapter_spec.js diff --git a/modules/windtalkerBidAdapter.js b/modules/windtalkerBidAdapter.js new file mode 100644 index 00000000000..0c0ef571954 --- /dev/null +++ b/modules/windtalkerBidAdapter.js @@ -0,0 +1,307 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import includes from 'core-js/library/fn/array/includes.js'; + +const NATIVE_DEFAULTS = { + TITLE_LEN: 100, + DESCR_LEN: 200, + SPONSORED_BY_LEN: 50, + IMG_MIN: 150, + ICON_MIN: 50, +}; +const DEFAULT_MIMES = ['video/mp4', 'video/webm', 'application/x-shockwave-flash', 'application/javascript']; +const VIDEO_TARGETING = ['mimes', 'skippable', 'playback_method', 'protocols', 'api']; +const DEFAULT_PROTOCOLS = [2, 3, 5, 6]; +const DEFAULT_APIS = [1, 2]; + +export const spec = { + + code: 'windtalker', + supportedMediaTypes: ['banner', 'native', 'video'], + + isBidRequestValid: bid => ( + !!(bid && bid.params && bid.params.pubId && bid.params.placementId) + ), + buildRequests: (bidRequests, bidderRequest) => { + const request = { + id: bidRequests[0].bidderRequestId, + at: 2, + imp: bidRequests.map(slot => impression(slot)), + site: site(bidRequests), + app: app(bidRequests), + device: device(bidRequests), + }; + applyGdpr(bidderRequest, request); + return { + method: 'POST', + url: 'https://windtalkerdisplay.hb.adp3.net/', + data: JSON.stringify(request), + }; + }, + interpretResponse: (response, request) => ( + bidResponseAvailable(request, response.body) + ), +}; + +function bidResponseAvailable(bidRequest, bidResponse) { + const idToImpMap = {}; + const idToBidMap = {}; + const ortbRequest = parse(bidRequest.data); + ortbRequest.imp.forEach(imp => { + idToImpMap[imp.id] = imp; + }); + if (bidResponse) { + bidResponse.seatbid.forEach(seatBid => seatBid.bid.forEach(bid => { + idToBidMap[bid.impid] = bid; + })); + } + const bids = []; + Object.keys(idToImpMap).forEach(id => { + if (idToBidMap[id]) { + const bid = {}; + bid.requestId = id; + bid.adId = id; + bid.creativeId = id; + bid.cpm = idToBidMap[id].price; + bid.currency = bidResponse.cur; + bid.ttl = 360; + bid.netRevenue = true; + if (idToImpMap[id]['native']) { + bid['native'] = nativeResponse(idToImpMap[id], idToBidMap[id]); + let nurl = idToBidMap[id].nurl; + nurl = nurl.replace(/\$(%7B|\{)AUCTION_IMP_ID(%7D|\})/gi, idToBidMap[id].impid); + nurl = nurl.replace(/\$(%7B|\{)AUCTION_PRICE(%7D|\})/gi, idToBidMap[id].price); + nurl = nurl.replace(/\$(%7B|\{)AUCTION_CURRENCY(%7D|\})/gi, bidResponse.cur); + nurl = nurl.replace(/\$(%7B|\{)AUCTION_BID_ID(%7D|\})/gi, bidResponse.bidid); + bid['native']['impressionTrackers'] = [nurl]; + bid.mediaType = 'native'; + } else if (idToImpMap[id]['video']) { + bid.vastUrl = idToBidMap[id].adm; + bid.vastUrl = bid.vastUrl.replace(/\$(%7B|\{)AUCTION_PRICE(%7D|\})/gi, idToBidMap[id].price); + bid.crid = idToBidMap[id].crid; + bid.width = idToImpMap[id].video.w; + bid.height = idToImpMap[id].video.h; + bid.mediaType = 'video'; + } else if (idToImpMap[id]['banner']) { + bid.ad = idToBidMap[id].adm; + bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_IMP_ID(%7D|\})/gi, idToBidMap[id].impid); + bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_AD_ID(%7D|\})/gi, idToBidMap[id].adid); + bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_PRICE(%7D|\})/gi, idToBidMap[id].price); + bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_CURRENCY(%7D|\})/gi, bidResponse.cur); + bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_BID_ID(%7D|\})/gi, bidResponse.bidid); + bid.width = idToBidMap[id].w; + bid.height = idToBidMap[id].h; + bid.mediaType = 'banner'; + } + bids.push(bid); + } + }); + return bids; +} +function impression(slot) { + return { + id: slot.bidId, + secure: window.location.protocol === 'https:' ? 1 : 0, + 'banner': banner(slot), + 'native': nativeImpression(slot), + 'video': videoImpression(slot), + bidfloor: slot.params.bidFloor || '0.000001', + tagid: slot.params.placementId.toString(), + }; +} + +function banner(slot) { + if (slot.mediaType === 'banner' || utils.deepAccess(slot, 'mediaTypes.banner')) { + const sizes = utils.deepAccess(slot, 'mediaTypes.banner.sizes'); + if (sizes.length > 1) { + let format = []; + for (let f = 0; f < sizes.length; f++) { + format.push({'w': sizes[f][0], 'h': sizes[f][1]}); + } + return {'format': format}; + } else { + return { + w: sizes[0][0], + h: sizes[0][1] + } + } + } + return null; +} + +function videoImpression(slot) { + if (slot.mediaType === 'video' || utils.deepAccess(slot, 'mediaTypes.video')) { + const sizes = utils.deepAccess(slot, 'mediaTypes.video.playerSize'); + const video = { + w: sizes[0][0], + h: sizes[0][1], + mimes: DEFAULT_MIMES, + protocols: DEFAULT_PROTOCOLS, + api: DEFAULT_APIS, + }; + if (slot.params.video) { + Object.keys(slot.params.video).filter(param => includes(VIDEO_TARGETING, param)).forEach(param => video[param] = slot.params.video[param]); + } + return video; + } + return null; +} + +function nativeImpression(slot) { + if (slot.mediaType === 'native' || utils.deepAccess(slot, 'mediaTypes.native')) { + const assets = []; + addAsset(assets, titleAsset(1, slot.nativeParams.title, NATIVE_DEFAULTS.TITLE_LEN)); + addAsset(assets, dataAsset(2, slot.nativeParams.body, 2, NATIVE_DEFAULTS.DESCR_LEN)); + addAsset(assets, dataAsset(3, slot.nativeParams.sponsoredBy, 1, NATIVE_DEFAULTS.SPONSORED_BY_LEN)); + addAsset(assets, imageAsset(4, slot.nativeParams.icon, 1, NATIVE_DEFAULTS.ICON_MIN, NATIVE_DEFAULTS.ICON_MIN)); + addAsset(assets, imageAsset(5, slot.nativeParams.image, 3, NATIVE_DEFAULTS.IMG_MIN, NATIVE_DEFAULTS.IMG_MIN)); + return { + request: JSON.stringify({ assets }), + ver: '1.1', + }; + } + return null; +} + +function addAsset(assets, asset) { + if (asset) { + assets.push(asset); + } +} + +function titleAsset(id, params, defaultLen) { + if (params) { + return { + id, + required: params.required ? 1 : 0, + title: { + len: params.len || defaultLen, + }, + }; + } + return null; +} + +function imageAsset(id, params, type, defaultMinWidth, defaultMinHeight) { + return params ? { + id, + required: params.required ? 1 : 0, + img: { + type, + wmin: params.wmin || defaultMinWidth, + hmin: params.hmin || defaultMinHeight, + } + } : null; +} + +function dataAsset(id, params, type, defaultLen) { + return params ? { + id, + required: params.required ? 1 : 0, + data: { + type, + len: params.len || defaultLen, + } + } : null; +} + +function site(bidderRequest) { + const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.pubId : '0'; + const siteId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.siteId : '0'; + const appParams = bidderRequest[0].params.app; + if (!appParams) { + return { + publisher: { + id: pubId.toString(), + domain: window.location.hostname, + }, + id: siteId.toString(), + ref: window.top.document.referrer, + page: window.location.href, + } + } + return null; +} + +function app(bidderRequest) { + const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.pubId : '0'; + const appParams = bidderRequest[0].params.app; + if (appParams) { + return { + publisher: { + id: pubId.toString(), + }, + id: appParams.id, + name: appParams.name, + bundle: appParams.bundle, + storeurl: appParams.storeUrl, + domain: appParams.domain, + } + } + return null; +} + +function device(bidderRequest) { + const lat = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.latitude : ''; + const lon = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.longitude : ''; + const ifa = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.ifa : ''; + return { + dnt: utils.getDNT() ? 1 : 0, + ua: navigator.userAgent, + language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage), + w: (window.screen.width || window.innerWidth), + h: (window.screen.height || window.innerHeigh), + geo: { + lat: lat, + lon: lon, + }, + ifa: ifa, + }; +} + +function parse(rawResponse) { + try { + if (rawResponse) { + return JSON.parse(rawResponse); + } + } catch (ex) { + utils.logError('windtalker.parse', 'ERROR', ex); + } + return null; +} + +function applyGdpr(bidderRequest, ortbRequest) { + if (bidderRequest && bidderRequest.gdprConsent) { + ortbRequest.regs = { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0 } }; + ortbRequest.user = { ext: { consent: bidderRequest.gdprConsent.consentString } }; + } +} + +function nativeResponse(imp, bid) { + if (imp['native']) { + const nativeAd = parse(bid.adm); + const keys = {}; + keys.image = {}; + keys.icon = {}; + if (nativeAd && nativeAd['native'] && nativeAd['native'].assets) { + nativeAd['native'].assets.forEach(asset => { + keys.title = asset.title ? asset.title.text : keys.title; + keys.body = asset.data && asset.id === 2 ? asset.data.value : keys.body; + keys.sponsoredBy = asset.data && asset.id === 3 ? asset.data.value : keys.sponsoredBy; + keys.icon.url = asset.img && asset.id === 4 ? asset.img.url : keys.icon.url; + keys.icon.width = asset.img && asset.id === 4 ? asset.img.w : keys.icon.width; + keys.icon.height = asset.img && asset.id === 4 ? asset.img.h : keys.icon.height; + keys.image.url = asset.img && asset.id === 5 ? asset.img.url : keys.image.url; + keys.image.width = asset.img && asset.id === 5 ? asset.img.w : keys.image.width; + keys.image.height = asset.img && asset.id === 5 ? asset.img.h : keys.image.height; + }); + if (nativeAd['native'].link) { + keys.clickUrl = encodeURIComponent(nativeAd['native'].link.url); + } + return keys; + } + } + return null; +} + +registerBidder(spec); diff --git a/modules/windtalkerBidAdapter.md b/modules/windtalkerBidAdapter.md new file mode 100644 index 00000000000..f7441effc47 --- /dev/null +++ b/modules/windtalkerBidAdapter.md @@ -0,0 +1,86 @@ +# Overview + +**Module Name**: Windtalker Bidder Adapter +**Module Type**: Bidder Adapter +**Maintainer**: corbin@windtalker.io + +# Description + +Connects to Windtalker demand source to fetch bids. +Banner, Native, Video formats are supported. +Please use ```windtalker``` as the bidder code. + +# Test Parameters +``` + var adUnits = [{ + code: 'dfp-native-div', + mediaTypes: { + native: { + title: { + required: true, + len: 75 + }, + image: { + required: true + }, + body: { + len: 200 + }, + icon: { + required: false + } + } + }, + bids: [{ + bidder: 'windtalker', + params: { + pubId: '584971', + siteId: '584971', + placementId: '123', + bidFloor: '0.001', // optional + ifa: 'XXX-XXX', // optional + latitude: '40.712775', // optional + longitude: '-74.005973', // optional + } + }] + }, + { + code: 'dfp-banner-div', + mediaTypes: { + banner: { + sizes: [ + [300, 250],[300,600] + ], + } + }, + bids: [{ + bidder: 'windtalker', + params: { + pubId: '584971', + siteId: '584971', + placementId: '123', + } + }] + }, + { + code: 'dfp-video-div', + mediaTypes: { + video: { + playerSize: [[640, 480]], + context: "instream" + } + }, + bids: [{ + bidder: 'windtalker', + params: { + pubId: '584971', + siteId: '584971', + placementId: '123', + video: { + skipppable: true, + } + } + }] + } + ]; +``` diff --git a/test/spec/modules/windtalkerBidAdapter_spec.js b/test/spec/modules/windtalkerBidAdapter_spec.js new file mode 100644 index 00000000000..222a7611b01 --- /dev/null +++ b/test/spec/modules/windtalkerBidAdapter_spec.js @@ -0,0 +1,348 @@ +import {expect} from 'chai'; +import {spec} from 'modules/windtalkerBidAdapter'; +import {newBidder} from 'src/adapters/bidderFactory'; + +describe('Windtalker Adapter Tests', function () { + const slotConfigs = [{ + placementCode: '/DfpAccount1/slot1', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bidId: 'bid12345', + mediaType: 'banner', + params: { + pubId: '29521', + siteId: '26047', + placementId: '123', + bidFloor: '0.001', + ifa: 'IFA', + latitude: '40.712775', + longitude: '-74.005973' + } + }, { + placementCode: '/DfpAccount2/slot2', + mediaTypes: { + banner: { + sizes: [[728, 90]] + } + }, + bidId: 'bid23456', + mediaType: 'banner', + params: { + pubId: '29521', + siteId: '26047', + placementId: '1234', + bidFloor: '0.000001', + } + }]; + const nativeSlotConfig = [{ + placementCode: '/DfpAccount1/slot3', + bidId: 'bid12345', + mediaType: 'native', + nativeParams: { + title: { required: true, len: 200 }, + body: {}, + image: { wmin: 100 }, + sponsoredBy: { }, + icon: { } + }, + params: { + pubId: '29521', + placementId: '123', + siteId: '26047' + } + }]; + const videoSlotConfig = [{ + placementCode: '/DfpAccount1/slot4', + mediaTypes: { + video: { + playerSize: [[640, 480]] + } + }, + bidId: 'bid12345678', + mediaType: 'video', + video: { + skippable: true + }, + params: { + pubId: '29521', + placementId: '1234567', + siteId: '26047', + } + }]; + const appSlotConfig = [{ + placementCode: '/DfpAccount1/slot5', + bidId: 'bid12345', + params: { + pubId: '29521', + placementId: '1234', + app: { + id: '1111', + name: 'app name', + bundle: 'io.windtalker.apps', + storeUrl: 'https://windtalker.io/apps', + domain: 'windtalker.io' + } + } + }]; + + it('Verify build request', function () { + const request = spec.buildRequests(slotConfigs); + expect(request.url).to.equal('https://windtalkerdisplay.hb.adp3.net/'); + expect(request.method).to.equal('POST'); + const ortbRequest = JSON.parse(request.data); + // site object + expect(ortbRequest.site).to.not.equal(null); + expect(ortbRequest.site.publisher).to.not.equal(null); + expect(ortbRequest.site.publisher.id).to.equal('29521'); + expect(ortbRequest.site.ref).to.equal(window.top.document.referrer); + expect(ortbRequest.site.page).to.equal(window.location.href); + expect(ortbRequest.imp).to.have.lengthOf(2); + // device object + expect(ortbRequest.device).to.not.equal(null); + expect(ortbRequest.device.ua).to.equal(navigator.userAgent); + expect(ortbRequest.device.ifa).to.equal('IFA'); + expect(ortbRequest.device.geo.lat).to.equal('40.712775'); + expect(ortbRequest.device.geo.lon).to.equal('-74.005973'); + // slot 1 + expect(ortbRequest.imp[0].tagid).to.equal('123'); + expect(ortbRequest.imp[0].banner).to.not.equal(null); + expect(ortbRequest.imp[0].banner.w).to.equal(300); + expect(ortbRequest.imp[0].banner.h).to.equal(250); + expect(ortbRequest.imp[0].bidfloor).to.equal('0.001'); + // slot 2 + expect(ortbRequest.imp[1].tagid).to.equal('1234'); + expect(ortbRequest.imp[1].banner).to.not.equal(null); + expect(ortbRequest.imp[1].banner.w).to.equal(728); + expect(ortbRequest.imp[1].banner.h).to.equal(90); + expect(ortbRequest.imp[1].bidfloor).to.equal('0.000001'); + }); + + it('Verify parse response', function () { + const request = spec.buildRequests(slotConfigs); + const ortbRequest = JSON.parse(request.data); + const ortbResponse = { + seatbid: [{ + bid: [{ + impid: ortbRequest.imp[0].id, + price: 1.25, + adm: 'This is an Ad', + w: 300, + h: 250 + }] + }], + cur: 'USD' + }; + const bids = spec.interpretResponse({ body: ortbResponse }, request); + expect(bids).to.have.lengthOf(1); + // verify first bid + const bid = bids[0]; + expect(bid.cpm).to.equal(1.25); + expect(bid.ad).to.equal('This is an Ad'); + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); + expect(bid.adId).to.equal('bid12345'); + expect(bid.creativeId).to.equal('bid12345'); + expect(bid.netRevenue).to.equal(true); + expect(bid.currency).to.equal('USD'); + expect(bid.ttl).to.equal(360); + }); + + it('Verify full passback', function () { + const request = spec.buildRequests(slotConfigs); + const bids = spec.interpretResponse({ body: null }, request) + expect(bids).to.have.lengthOf(0); + }); + + it('Verify Native request', function () { + const request = spec.buildRequests(nativeSlotConfig); + expect(request.url).to.equal('https://windtalkerdisplay.hb.adp3.net/'); + expect(request.method).to.equal('POST'); + const ortbRequest = JSON.parse(request.data); + // native impression + expect(ortbRequest.imp[0].tagid).to.equal('123'); + const nativePart = ortbRequest.imp[0]['native']; + expect(nativePart).to.not.equal(null); + expect(nativePart.ver).to.equal('1.1'); + expect(nativePart.request).to.not.equal(null); + // native request assets + const nativeRequest = JSON.parse(ortbRequest.imp[0]['native'].request); + expect(nativeRequest).to.not.equal(null); + expect(nativeRequest.assets).to.have.lengthOf(5); + expect(nativeRequest.assets[0].id).to.equal(1); + expect(nativeRequest.assets[1].id).to.equal(2); + expect(nativeRequest.assets[2].id).to.equal(3); + expect(nativeRequest.assets[3].id).to.equal(4); + expect(nativeRequest.assets[4].id).to.equal(5); + expect(nativeRequest.assets[0].required).to.equal(1); + expect(nativeRequest.assets[0].title).to.not.equal(null); + expect(nativeRequest.assets[0].title.len).to.equal(200); + expect(nativeRequest.assets[1].title).to.be.undefined; + expect(nativeRequest.assets[1].data).to.not.equal(null); + expect(nativeRequest.assets[1].data.type).to.equal(2); + expect(nativeRequest.assets[1].data.len).to.equal(200); + expect(nativeRequest.assets[2].required).to.equal(0); + expect(nativeRequest.assets[3].img).to.not.equal(null); + expect(nativeRequest.assets[3].img.wmin).to.equal(50); + expect(nativeRequest.assets[3].img.hmin).to.equal(50); + expect(nativeRequest.assets[3].img.type).to.equal(1); + expect(nativeRequest.assets[4].img).to.not.equal(null); + expect(nativeRequest.assets[4].img.wmin).to.equal(100); + expect(nativeRequest.assets[4].img.hmin).to.equal(150); + expect(nativeRequest.assets[4].img.type).to.equal(3); + }); + + it('Verify Native response', function () { + const request = spec.buildRequests(nativeSlotConfig); + expect(request.url).to.equal('https://windtalkerdisplay.hb.adp3.net/'); + expect(request.method).to.equal('POST'); + const ortbRequest = JSON.parse(request.data); + const nativeResponse = { + 'native': { + assets: [ + { id: 1, title: { text: 'Ad Title' } }, + { id: 2, data: { value: 'Test description' } }, + { id: 3, data: { value: 'Brand' } }, + { id: 4, img: { url: 'https://adx1public.s3.amazonaws.com/creatives_icon.png', w: 100, h: 100 } }, + { id: 5, img: { url: 'https://adx1public.s3.amazonaws.com/creatives_image.png', w: 300, h: 300 } } + ], + link: { url: 'https://brand.com/' } + } + }; + const ortbResponse = { + seatbid: [{ + bid: [{ + impid: ortbRequest.imp[0].id, + price: 1.25, + nurl: 'https://rtb.adx1.com/log', + adm: JSON.stringify(nativeResponse) + }] + }], + cur: 'USD', + }; + const bids = spec.interpretResponse({ body: ortbResponse }, request); + // verify bid + const bid = bids[0]; + expect(bid.cpm).to.equal(1.25); + expect(bid.adId).to.equal('bid12345'); + expect(bid.ad).to.be.undefined; + expect(bid.mediaType).to.equal('native'); + const nativeBid = bid['native']; + expect(nativeBid).to.not.equal(null); + expect(nativeBid.title).to.equal('Ad Title'); + expect(nativeBid.sponsoredBy).to.equal('Brand'); + expect(nativeBid.icon.url).to.equal('https://adx1public.s3.amazonaws.com/creatives_icon.png'); + expect(nativeBid.image.url).to.equal('https://adx1public.s3.amazonaws.com/creatives_image.png'); + expect(nativeBid.image.width).to.equal(300); + expect(nativeBid.image.height).to.equal(300); + expect(nativeBid.icon.width).to.equal(100); + expect(nativeBid.icon.height).to.equal(100); + expect(nativeBid.clickUrl).to.equal(encodeURIComponent('https://brand.com/')); + expect(nativeBid.impressionTrackers).to.have.lengthOf(1); + expect(nativeBid.impressionTrackers[0]).to.equal('https://rtb.adx1.com/log'); + }); + + it('Verify Video request', function () { + const request = spec.buildRequests(videoSlotConfig); + expect(request.url).to.equal('https://windtalkerdisplay.hb.adp3.net/'); + expect(request.method).to.equal('POST'); + const videoRequest = JSON.parse(request.data); + // site object + expect(videoRequest.site).to.not.equal(null); + expect(videoRequest.site.publisher.id).to.equal('29521'); + expect(videoRequest.site.ref).to.equal(window.top.document.referrer); + expect(videoRequest.site.page).to.equal(window.location.href); + // device object + expect(videoRequest.device).to.not.equal(null); + expect(videoRequest.device.ua).to.equal(navigator.userAgent); + // slot 1 + expect(videoRequest.imp[0].tagid).to.equal('1234567'); + expect(videoRequest.imp[0].video).to.not.equal(null); + expect(videoRequest.imp[0].video.w).to.equal(640); + expect(videoRequest.imp[0].video.h).to.equal(480); + expect(videoRequest.imp[0].banner).to.equal(null); + expect(videoRequest.imp[0].native).to.equal(null); + }); + + it('Verify parse video response', function () { + const request = spec.buildRequests(videoSlotConfig); + const videoRequest = JSON.parse(request.data); + const videoResponse = { + seatbid: [{ + bid: [{ + impid: videoRequest.imp[0].id, + price: 1.90, + adm: 'https://vid.example.com/9876', + crid: '510511_754567308' + }] + }], + cur: 'USD' + }; + const bids = spec.interpretResponse({ body: videoResponse }, request); + expect(bids).to.have.lengthOf(1); + // verify first bid + const bid = bids[0]; + expect(bid.cpm).to.equal(1.90); + expect(bid.vastUrl).to.equal('https://vid.example.com/9876'); + expect(bid.crid).to.equal('510511_754567308'); + expect(bid.width).to.equal(640); + expect(bid.height).to.equal(480); + expect(bid.adId).to.equal('bid12345678'); + expect(bid.netRevenue).to.equal(true); + expect(bid.currency).to.equal('USD'); + expect(bid.ttl).to.equal(360); + }); + + it('Verifies bidder code', function () { + expect(spec.code).to.equal('windtalker'); + }); + + it('Verifies supported media types', function () { + expect(spec.supportedMediaTypes).to.have.lengthOf(3); + expect(spec.supportedMediaTypes[0]).to.equal('banner'); + expect(spec.supportedMediaTypes[1]).to.equal('native'); + expect(spec.supportedMediaTypes[2]).to.equal('video'); + }); + + it('Verifies if bid request valid', function () { + expect(spec.isBidRequestValid(slotConfigs[0])).to.equal(true); + expect(spec.isBidRequestValid(slotConfigs[1])).to.equal(true); + expect(spec.isBidRequestValid(nativeSlotConfig[0])).to.equal(true); + expect(spec.isBidRequestValid(videoSlotConfig[0])).to.equal(true); + }); + + it('Verify app requests', function () { + const request = spec.buildRequests(appSlotConfig); + const ortbRequest = JSON.parse(request.data); + expect(ortbRequest.site).to.equal(null); + expect(ortbRequest.app).to.not.be.null; + expect(ortbRequest.app.publisher).to.not.equal(null); + expect(ortbRequest.app.publisher.id).to.equal('29521'); + expect(ortbRequest.app.id).to.equal('1111'); + expect(ortbRequest.app.name).to.equal('app name'); + expect(ortbRequest.app.bundle).to.equal('io.windtalker.apps'); + expect(ortbRequest.app.storeurl).to.equal('https://windtalker.io/apps'); + expect(ortbRequest.app.domain).to.equal('windtalker.io'); + }); + + it('Verify GDPR', function () { + const bidderRequest = { + gdprConsent: { + gdprApplies: true, + consentString: 'serialized_gpdr_data' + } + }; + const request = spec.buildRequests(slotConfigs, bidderRequest); + expect(request.url).to.equal('https://windtalkerdisplay.hb.adp3.net/'); + expect(request.method).to.equal('POST'); + const ortbRequest = JSON.parse(request.data); + expect(ortbRequest.user).to.not.equal(null); + expect(ortbRequest.user.ext).to.not.equal(null); + expect(ortbRequest.user.ext.consent).to.equal('serialized_gpdr_data'); + expect(ortbRequest.regs).to.not.equal(null); + expect(ortbRequest.regs.ext).to.not.equal(null); + expect(ortbRequest.regs.ext.gdpr).to.equal(1); + }); +}); From 8275fc1cdb067aea051870426947ad03a9b2afa6 Mon Sep 17 00:00:00 2001 From: Chris Cole Date: Tue, 7 Apr 2020 12:59:38 -0700 Subject: [PATCH 221/496] #5011 Fix to set Secure attribute on cookie when SameSite=none (#5064) * #5011 Fix to set Secure attribute on cookie when SameSite=none * Minor change to use const instead of var per review request. --- src/storageManager.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/storageManager.js b/src/storageManager.js index abda0ccb180..75ad10908dc 100644 --- a/src/storageManager.js +++ b/src/storageManager.js @@ -64,7 +64,9 @@ export function newStorageManager({gvlid, moduleName, moduleType} = {}) { if (result && result.valid) { const domainPortion = (domain && domain !== '') ? ` ;domain=${encodeURIComponent(domain)}` : ''; const expiresPortion = (expires && expires !== '') ? ` ;expires=${expires}` : ''; - document.cookie = `${key}=${encodeURIComponent(value)}${expiresPortion}; path=/${domainPortion}${sameSite ? `; SameSite=${sameSite}` : ''}`; + const isNone = (sameSite != null && sameSite.toLowerCase() == 'none') + const secure = (isNone) ? '; Secure' : ''; + document.cookie = `${key}=${encodeURIComponent(value)}${expiresPortion}; path=/${domainPortion}${sameSite ? `; SameSite=${sameSite}` : ''}${secure}`; } } if (done && typeof done === 'function') { From 8d3dc0820d5f313cbd86e7ee79d732a03e8b64f3 Mon Sep 17 00:00:00 2001 From: Jason Snellbaker Date: Tue, 7 Apr 2020 16:03:05 -0400 Subject: [PATCH 222/496] Prebid 3.15.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7baae6a5f00..5c4f654c20b 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.15.0-pre", + "version": "3.15.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 78602ffd0943b85e8285d3aa116bd131afa6d1a5 Mon Sep 17 00:00:00 2001 From: Jason Snellbaker Date: Tue, 7 Apr 2020 16:13:18 -0400 Subject: [PATCH 223/496] increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5c4f654c20b..66cfd10b357 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.15.0", + "version": "3.16.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 75f13a0c49d48527d6b463346428bcc729dd61e2 Mon Sep 17 00:00:00 2001 From: DeepthiNeeladri Date: Wed, 8 Apr 2020 12:26:51 +0530 Subject: [PATCH 224/496] Support min &max duration for onevideo (#5079) * outstream changes * removing global filtet * reverting page * message * adapter change * remove space * testcases * testpage * spaces for test page * renderer exist case * reverting package-lock.json * adding schain object * adding tagid * syntaxx error fix * video.html * space trailing * space * tagid * inventoryId and placement * rewarded video * added unit test case * comment * changes * min max dduration * .md file * min max * md change * version * tests fix Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana --- modules/oneVideoBidAdapter.js | 11 +++++++++-- modules/oneVideoBidAdapter.md | 4 +++- test/spec/modules/oneVideoBidAdapter_spec.js | 14 +++++++++++--- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/modules/oneVideoBidAdapter.js b/modules/oneVideoBidAdapter.js index 933f2d7a4c8..5747c5e848d 100644 --- a/modules/oneVideoBidAdapter.js +++ b/modules/oneVideoBidAdapter.js @@ -3,8 +3,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'oneVideo'; export const spec = { code: 'oneVideo', - gvlid: 25, - VERSION: '3.0.0', + VERSION: '3.0.1', ENDPOINT: 'https://ads.adaptv.advertising.com/rtb/openrtb?ext_id=', SYNC_ENDPOINT1: 'https://cm.g.doubleclick.net/pixel?google_nid=adaptv_dbm&google_cm&google_sc', SYNC_ENDPOINT2: 'https://pr-bh.ybp.yahoo.com/sync/adaptv_ortb/{combo_uid}', @@ -215,6 +214,14 @@ function getRequestData(bid, consentData, bidRequest) { if (bid.params.video.placement) { bidData.imp[0].banner.placement = bid.params.video.placement } + if (bid.params.video.maxduration) { + bidData.imp[0].banner.ext = bidData.imp[0].banner.ext || {} + bidData.imp[0].banner.ext.maxduration = bid.params.video.maxduration + } + if (bid.params.video.minduration) { + bidData.imp[0].banner.ext = bidData.imp[0].banner.ext || {} + bidData.imp[0].banner.ext.minduration = bid.params.video.minduration + } } if (bid.params.video.inventoryid) { bidData.imp[0].ext.inventoryid = bid.params.video.inventoryid diff --git a/modules/oneVideoBidAdapter.md b/modules/oneVideoBidAdapter.md index 145af1a6fb9..656f81733a0 100644 --- a/modules/oneVideoBidAdapter.md +++ b/modules/oneVideoBidAdapter.md @@ -37,7 +37,9 @@ Connects to One Video demand source to fetch bids. sid: , rewarded: 1, placement: 1, - inventoryid: 123 + inventoryid: 123, + minduration: 10, + maxduration: 30, }, site: { id: 1, diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js index fc7c29c7b51..82546f2e96d 100644 --- a/test/spec/modules/oneVideoBidAdapter_spec.js +++ b/test/spec/modules/oneVideoBidAdapter_spec.js @@ -136,7 +136,7 @@ describe('OneVideoBidAdapter', function () { const placement = bidRequest.params.video.placement; const rewarded = bidRequest.params.video.rewarded; const inventoryid = bidRequest.params.video.inventoryid; - const VERSION = '3.0.0'; + const VERSION = '3.0.1'; expect(data.imp[0].video.w).to.equal(width); expect(data.imp[0].video.h).to.equal(height); expect(data.imp[0].bidfloor).to.equal(bidRequest.params.bidfloor); @@ -292,7 +292,9 @@ describe('OneVideoBidAdapter', function () { placement: 1, inventoryid: 123, sid: 134, - display: 1 + display: 1, + minduration: 10, + maxduration: 30 }, site: { id: 1, @@ -314,6 +316,8 @@ describe('OneVideoBidAdapter', function () { expect(data.imp[0].ext.inventoryid).to.equal(bidRequest.params.video.inventoryid); expect(data.imp[0].banner.mimes).to.equal(bidRequest.params.video.mimes); expect(data.imp[0].banner.placement).to.equal(bidRequest.params.video.placement); + expect(data.imp[0].banner.ext.minduration).to.equal(bidRequest.params.video.minduration); + expect(data.imp[0].banner.ext.maxduration).to.equal(bidRequest.params.video.maxduration); expect(data.site.id).to.equal(bidRequest.params.site.id); }); it('should send video object when display is other than 1', function () { @@ -384,7 +388,9 @@ describe('OneVideoBidAdapter', function () { delivery: [2], playbackmethod: [1, 5], placement: 123, - sid: 134 + sid: 134, + minduration: 10, + maxduration: 30 }, site: { id: 1, @@ -406,6 +412,8 @@ describe('OneVideoBidAdapter', function () { expect(data.imp[0].video.mimes).to.equal(bidRequest.params.video.mimes); expect(data.imp[0].video.protocols).to.equal(bidRequest.params.video.protocols); expect(data.imp[0].video.linearity).to.equal(1); + expect(data.imp[0].video.maxduration).to.equal(bidRequest.params.video.maxduration); + expect(data.imp[0].video.minduration).to.equal(bidRequest.params.video.minduration); }); describe('getUserSyncs', function () { const GDPR_CONSENT_STRING = 'GDPR_CONSENT_STRING'; From c61a2b941a99e91a51dd10c43fb19e874c6fff24 Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 8 Apr 2020 03:27:45 -0400 Subject: [PATCH 225/496] isSafariBrowser update (#5077) * isSafariBrowser-update * can't restore navigator object * update tests to reset navigator.userAgent value to initial value after each test that modifies the value * fix stubs the navigator userAgent property using sinon Co-authored-by: idettman --- src/utils.js | 2 +- test/spec/utils_spec.js | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index f43097e74b9..45822dd7088 100644 --- a/src/utils.js +++ b/src/utils.js @@ -817,7 +817,7 @@ export function inIframe() { } export function isSafariBrowser() { - return /^((?!chrome|android).)*safari/i.test(navigator.userAgent); + return /^((?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent); } export function replaceAuctionPrice(str, cpm) { diff --git a/test/spec/utils_spec.js b/test/spec/utils_spec.js index e7be6880444..9ba70810a08 100755 --- a/test/spec/utils_spec.js +++ b/test/spec/utils_spec.js @@ -922,4 +922,40 @@ describe('Utils', function () { }); }); }); + + describe('isSafariBrowser', function () { + let userAgentStub; + let userAgent; + + before(function () { + userAgentStub = sinon.stub(navigator, 'userAgent').get(function () { + return userAgent; + }); + }); + + after(function () { + userAgentStub.restore(); + }); + + it('properly detects safari', function () { + userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/536.25 (KHTML, like Gecko) Version/6.0 Safari/536.25'; + expect(utils.isSafariBrowser()).to.equal(true); + }); + it('does not flag Chrome on MacOS', function () { + userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'; + expect(utils.isSafariBrowser()).to.equal(false); + }); + it('does not flag Chrome iOS', function () { + userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/80.0.3987.95 Mobile/15E148 Safari/604.1'; + expect(utils.isSafariBrowser()).to.equal(false); + }); + it('does not flag Firefox iOS', function () { + userAgent = 'Mozilla/5.0 (iPhone; CPU OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/23.0 Mobile/15E148 Safari/605.1.15'; + expect(utils.isSafariBrowser()).to.equal(false); + }); + it('does not flag Windows Edge', function () { + userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.74 Safari/537.36 Edg/79.0.309.43'; + expect(utils.isSafariBrowser()).to.equal(false); + }); + }); }); From 925ae0a418890b1a845b9785b4410f52cb22e87e Mon Sep 17 00:00:00 2001 From: mglowackiym <62994965+mglowackiym@users.noreply.github.com> Date: Wed, 8 Apr 2020 03:43:59 -0400 Subject: [PATCH 226/496] CRITEO RTUS Integration with Yieldmo Prebid (#5075) * update maintainer email * add stringified schain * Revert "add stringified schain" This reverts commit 4fd8634f12133945ac44e9b550237321e71fc549. * pass along gdpr consent string and gdpr applies through get * use paramter gdprConsent * add stringified schain * don't change other files * change parameter namves * updates bidder module to be 3.0 compliant, and tests * deletes openxoutstream adapter * fix broken yieldmo test * remove log * remove utils functions that will be depricated in 3.0 and use new referer object in bidderRequest * use prebids gettopwindow util functions. update markdown with 3.0 compliant ad units object * Pass along us_privacy string * remove blank.min * Fix unit tests and remove unused variables and methods * add stringified schain * add stringified schain * Revert "add stringified schain" This reverts commit 4fd8634f12133945ac44e9b550237321e71fc549. * pass along gdpr consent string and gdpr applies through get * use paramter gdprConsent * don't change other files * change parameter namves * updates bidder module to be 3.0 compliant, and tests * deletes openxoutstream adapter * fix broken yieldmo test * remove log * remove utils functions that will be depricated in 3.0 and use new referer object in bidderRequest * use prebids gettopwindow util functions. update markdown with 3.0 compliant ad units object * Pass along us_privacy string * update maintainer email * add stringified schain * Revert "add stringified schain" This reverts commit 4fd8634f12133945ac44e9b550237321e71fc549. * add stringified schain * don't change other files * change parameter namves * updates bidder module to be 3.0 compliant, and tests * fix broken yieldmo test * remove utils functions that will be depricated in 3.0 and use new referer object in bidderRequest * use prebids gettopwindow util functions. update markdown with 3.0 compliant ad units object * Pass along us_privacy string * Clean up console * Do not undo my featureeee * CRITEO RTUS For prebid * Tests for CRITEO RTUS For prebid * Revert "Do not undo my featureeee" This reverts commit 0185407646a6ba15a9d99ab19cc1ea0f3b6bdadd. * linting * add test back in: Co-authored-by: Melody Li Co-authored-by: Elber Carneiro Co-authored-by: Elber Carneiro Co-authored-by: Melody Li Co-authored-by: Melody Li Co-authored-by: Andrew Holz Co-authored-by: Michal --- modules/yieldmoBidAdapter.js | 114 +++++++----- modules/yieldmoBidAdapter.md | 1 + test/spec/modules/yieldmoBidAdapter_spec.js | 188 +++++++++++++------- 3 files changed, 193 insertions(+), 110 deletions(-) diff --git a/modules/yieldmoBidAdapter.js b/modules/yieldmoBidAdapter.js index 7a33dd0db91..5ef146cb2d0 100644 --- a/modules/yieldmoBidAdapter.js +++ b/modules/yieldmoBidAdapter.js @@ -13,10 +13,10 @@ export const spec = { code: BIDDER_CODE, supportedMediaTypes: ['banner'], /** - * Determines whether or not the given bid request is valid. - * @param {object} bid, bid to validate - * @return boolean, true if valid, otherwise false - */ + * Determines whether or not the given bid request is valid. + * @param {object} bid, bid to validate + * @return boolean, true if valid, otherwise false + */ isBidRequestValid: function(bid) { return !!(bid && bid.adUnitCode && bid.bidId); }, @@ -41,13 +41,19 @@ export const spec = { h: localWindow.innerHeight, userConsent: JSON.stringify({ // case of undefined, stringify will remove param - gdprApplies: bidderRequest && bidderRequest.gdprConsent ? bidderRequest.gdprConsent.gdprApplies : undefined, - cmp: bidderRequest && bidderRequest.gdprConsent ? bidderRequest.gdprConsent.consentString : undefined + gdprApplies: + bidderRequest && bidderRequest.gdprConsent + ? bidderRequest.gdprConsent.gdprApplies + : undefined, + cmp: + bidderRequest && bidderRequest.gdprConsent + ? bidderRequest.gdprConsent.consentString + : undefined }), - us_privacy: bidderRequest && bidderRequest.us_privacy, + us_privacy: bidderRequest && bidderRequest.us_privacy }; - bidRequests.forEach((request) => { + bidRequests.forEach(request => { serverRequest.p.push(addPlacement(request)); const pubcid = getId(request, 'pubcid'); if (pubcid) { @@ -61,6 +67,10 @@ export const spec = { if (tdid) { serverRequest.tdid = tdid; } + const criteoId = getId(request, 'criteoId'); + if (criteoId) { + serverRequest.cri_prebid = criteoId; + } if (request.schain) { serverRequest.schain = JSON.stringify(request.schain); } @@ -70,7 +80,7 @@ export const spec = { method: 'GET', url: SERVER_ENDPOINT, data: serverRequest - } + }; }, /** * Makes Yieldmo Ad Server response compatible to Prebid specs @@ -81,7 +91,7 @@ export const spec = { let bids = []; let data = serverResponse.body; if (data.length > 0) { - data.forEach((response) => { + data.forEach(response => { if (response.cpm && response.cpm > 0) { bids.push(createNewBid(response)); } @@ -91,15 +101,17 @@ export const spec = { }, getUserSync: function(syncOptions) { if (trackingEnabled(syncOptions)) { - return [{ - type: 'iframe', - url: SYNC_ENDPOINT + utils.getOrigin() - }]; + return [ + { + type: 'iframe', + url: SYNC_ENDPOINT + utils.getOrigin() + } + ]; } else { return []; } } -} +}; registerBidder(spec); /*************************************** @@ -115,7 +127,7 @@ function addPlacement(request) { placement_id: request.adUnitCode, callback_id: request.bidId, sizes: request.mediaTypes.banner.sizes - } + }; if (request.params) { if (request.params.placementId) { placementInfo.ym_placement_id = request.params.placementId; @@ -128,9 +140,9 @@ function addPlacement(request) { } /** - * creates a new bid with response information - * @param response server response - */ + * creates a new bid with response information + * @param response server response + */ function createNewBid(response) { return { requestId: response['callback_id'], @@ -150,23 +162,25 @@ function createNewBid(response) { * @returns false if dnt or if not iframe/pixel enabled */ function trackingEnabled(options) { - return (isIOS() && !getDNT() && options.iframeEnabled); + return isIOS() && !getDNT() && options.iframeEnabled; } /** - * Detects whether we're in iOS - * @returns true if in iOS - */ + * Detects whether we're in iOS + * @returns true if in iOS + */ function isIOS() { return /iPhone|iPad|iPod/i.test(window.navigator.userAgent); } /** - * Detects whether dnt is true - * @returns true if user enabled dnt - */ + * Detects whether dnt is true + * @returns true if user enabled dnt + */ function getDNT() { - return window.doNotTrack === '1' || window.navigator.doNotTrack === '1' || false; + return ( + window.doNotTrack === '1' || window.navigator.doNotTrack === '1' || false + ); } /** @@ -174,7 +188,9 @@ function getDNT() { */ function getPageDescription() { if (document.querySelector('meta[name="description"]')) { - return document.querySelector('meta[name="description"]').getAttribute('content'); // Value of the description metadata from the publisher's page. + return document + .querySelector('meta[name="description"]') + .getAttribute('content'); // Value of the description metadata from the publisher's page. } else { return ''; } @@ -200,9 +216,9 @@ function getPageDescription() { */ /** - * Detects what environment we're in - * @returns Environment kind - */ + * Detects what environment we're in + * @returns Environment kind + */ function getEnvironment() { if (isSuperSandboxedIframe()) { return 89; @@ -228,28 +244,31 @@ function getEnvironment() { } /** - * @returns true if we are running on the top window at dispatch time - */ + * @returns true if we are running on the top window at dispatch time + */ function isCodeOnPage() { return window === window.parent; } /** - * @returns true if the environment is both DFP and AMP - */ + * @returns true if the environment is both DFP and AMP + */ function isDfpInAmp() { return isDfp() && isAmp(); } /** - * @returns true if the window is in an iframe whose id and parent element id match DFP - */ + * @returns true if the window is in an iframe whose id and parent element id match DFP + */ function isDfp() { try { const frameElement = window.frameElement; const parentElement = window.frameElement.parentNode; if (frameElement && parentElement) { - return frameElement.id.indexOf('google_ads_iframe') > -1 && parentElement.id.indexOf('google_ads_iframe') > -1; + return ( + frameElement.id.indexOf('google_ads_iframe') > -1 && + parentElement.id.indexOf('google_ads_iframe') > -1 + ); } return false; } catch (e) { @@ -258,8 +277,8 @@ function isDfp() { } /** -* @returns true if there is an AMP context object -*/ + * @returns true if there is an AMP context object + */ function isAmp() { try { const ampContext = window.context || window.parent.context; @@ -285,7 +304,11 @@ function isSafeFrame() { function isDFPSafeFrame() { if (window.location && window.location.href) { const href = window.location.href; - return isSafeFrame() && href.indexOf('google') !== -1 && href.indexOf('safeframe') !== -1; + return ( + isSafeFrame() && + href.indexOf('google') !== -1 && + href.indexOf('safeframe') !== -1 + ); } return false; } @@ -318,7 +341,7 @@ function isSuperSandboxedIframe() { * @returns true if the window has the attribute identifying MRAID */ function isMraid() { - return !!(window.mraid); + return !!window.mraid; } /** @@ -329,7 +352,12 @@ function isMraid() { */ function getId(request, idType) { let id; - if (request && request.userId && request.userId[idType] && typeof request.userId === 'object') { + if ( + request && + request.userId && + request.userId[idType] && + typeof request.userId === 'object' + ) { id = request.userId[idType]; } return id; diff --git a/modules/yieldmoBidAdapter.md b/modules/yieldmoBidAdapter.md index ef5f07a4eb9..0f86d2507d1 100644 --- a/modules/yieldmoBidAdapter.md +++ b/modules/yieldmoBidAdapter.md @@ -4,6 +4,7 @@ Module Name: Yieldmo Bid Adapter Module Type: Bidder Adapter Maintainer: opensource@yieldmo.com +Note: Our ads will only render in mobile ``` # Description diff --git a/test/spec/modules/yieldmoBidAdapter_spec.js b/test/spec/modules/yieldmoBidAdapter_spec.js index 0bbc4b57785..5904113bd42 100644 --- a/test/spec/modules/yieldmoBidAdapter_spec.js +++ b/test/spec/modules/yieldmoBidAdapter_spec.js @@ -8,44 +8,48 @@ describe('YieldmoAdapter', function () { const ENDPOINT = 'https://ads.yieldmo.com/exchange/prebid'; let tdid = '8d146286-91d4-4958-aff4-7e489dd1abd6'; + let criteoId = 'aff4'; let bid = { bidder: 'yieldmo', params: { - bidFloor: 0.1 + bidFloor: 0.1, }, adUnitCode: 'adunit-code', mediaTypes: { banner: { - sizes: [[300, 250], [300, 600]] - } + sizes: [ + [300, 250], + [300, 600], + ], + }, }, bidId: '30b31c1838de1e', bidderRequestId: '22edbae2733bf6', auctionId: '1d1a030790a475', crumbs: { - pubcid: 'c604130c-0144-4b63-9bf2-c2bd8c8d86da' + pubcid: 'c604130c-0144-4b63-9bf2-c2bd8c8d86da', }, userId: { tdid, - } + }, }; let bidArray = [bid]; let bidderRequest = { - 'bidderCode': 'yieldmo', - 'auctionId': 'e3a336ad-2761-4a1c-b421-ecc7c5294a34', - 'bidderRequestId': '14c4ede8c693f', - 'bids': bidArray, - 'auctionStart': 1520001292880, - 'timeout': 3000, - 'start': 1520001292884, - 'doneCbCallCount': 0, - 'refererInfo': { - 'numIframes': 1, - 'reachedTop': true, - 'referer': 'yieldmo.com' - } - } + bidderCode: 'yieldmo', + auctionId: 'e3a336ad-2761-4a1c-b421-ecc7c5294a34', + bidderRequestId: '14c4ede8c693f', + bids: bidArray, + auctionStart: 1520001292880, + timeout: 3000, + start: 1520001292884, + doneCbCallCount: 0, + refererInfo: { + numIframes: 1, + reachedTop: true, + referer: 'yieldmo.com', + }, + }; describe('isBidRequestValid', function () { it('should return true when necessary information is found', function () { @@ -77,38 +81,44 @@ describe('YieldmoAdapter', function () { }); it('should not blow up if crumbs is undefined', function () { - let bidArray = [ - { ...bid, crumbs: undefined } - ] - expect(function () { spec.buildRequests(bidArray, bidderRequest) }).not.to.throw() - }) + let bidArray = [{ ...bid, crumbs: undefined }]; + expect(function () { + spec.buildRequests(bidArray, bidderRequest); + }).not.to.throw(); + }); it('should place bid information into the p parameter of data', function () { let placementInfo = spec.buildRequests(bidArray, bidderRequest).data.p; - expect(placementInfo).to.equal('[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1}]'); + expect(placementInfo).to.equal( + '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1}]' + ); bidArray.push({ bidder: 'yieldmo', params: { - bidFloor: 0.2 + bidFloor: 0.2, }, adUnitCode: 'adunit-code-1', mediaTypes: { banner: { - sizes: [[300, 250], [300, 600]] - } + sizes: [ + [300, 250], + [300, 600], + ], + }, }, bidId: '123456789', bidderRequestId: '987654321', auctionId: '0246810', crumbs: { - pubcid: 'c604130c-0144-4b63-9bf2-c2bd8c8d86da' - } - + pubcid: 'c604130c-0144-4b63-9bf2-c2bd8c8d86da', + }, }); // multiple placements placementInfo = spec.buildRequests(bidArray, bidderRequest).data.p; - expect(placementInfo).to.equal('[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1},{"placement_id":"adunit-code-1","callback_id":"123456789","sizes":[[300,250],[300,600]],"bidFloor":0.2}]'); + expect(placementInfo).to.equal( + '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1},{"placement_id":"adunit-code-1","callback_id":"123456789","sizes":[[300,250],[300,600]],"bidFloor":0.2}]' + ); }); it('should add placement id if given', function () { @@ -145,18 +155,23 @@ describe('YieldmoAdapter', function () { adUnitCode: 'adunit-code', mediaTypes: { banner: { - sizes: [[300, 250], [300, 600]] - } + sizes: [ + [300, 250], + [300, 600], + ], + }, }, bidId: '30b31c1838de1e', bidderRequestId: '22edbae2733bf6', auctionId: '1d1a030790a475', userId: { - pubcid: 'c604130c-0144-4b63-9bf2-c2bd8c8d86da2' - } + pubcid: 'c604130c-0144-4b63-9bf2-c2bd8c8d86da2', + }, }; const data = spec.buildRequests([pubcidBid], bidderRequest).data; - expect(data.pubcid).to.deep.equal('c604130c-0144-4b63-9bf2-c2bd8c8d86da2'); + expect(data.pubcid).to.deep.equal( + 'c604130c-0144-4b63-9bf2-c2bd8c8d86da2' + ); }); it('should add unified id as parameter of request', function () { @@ -166,31 +181,60 @@ describe('YieldmoAdapter', function () { adUnitCode: 'adunit-code', mediaTypes: { banner: { - sizes: [[300, 250], [300, 600]] - } + sizes: [ + [300, 250], + [300, 600], + ], + }, }, bidId: '30b31c1838de1e', bidderRequestId: '22edbae2733bf6', auctionId: '1d1a030790a475', userId: { tdid, - } + }, }; const data = spec.buildRequests([unifiedIdBid], bidderRequest).data; expect(data.tdid).to.deep.equal(tdid); }); + it('should add CRITEO RTUS id as parameter of request', function () { + const criteoIdBid = { + bidder: 'yieldmo', + params: {}, + adUnitCode: 'adunit-code', + mediaTypes: { + banner: { + sizes: [ + [300, 250], + [300, 600], + ], + }, + }, + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + userId: { + criteoId, + }, + }; + const data = spec.buildRequests([criteoIdBid], bidderRequest).data; + expect(data.cri_prebid).to.deep.equal(criteoId); + }); + it('should add gdpr information to request if available', () => { bidderRequest.gdprConsent = { - 'consentString': 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - 'vendorData': {'blerp': 1}, - 'gdprApplies': true - } + consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', + vendorData: { blerp: 1 }, + gdprApplies: true, + }; const data = spec.buildRequests(bidArray, bidderRequest).data; - expect(data.userConsent).equal(JSON.stringify({ - 'gdprApplies': true, - 'cmp': 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==' - })); + expect(data.userConsent).equal( + JSON.stringify({ + gdprApplies: true, + cmp: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', + }) + ); }); it('should add ccpa information to request if available', () => { @@ -201,11 +245,15 @@ describe('YieldmoAdapter', function () { }); it('should add schain if it is in the bidRequest', () => { - const schain = {'ver': '1.0', 'complete': 1, 'nodes': [{'asi': 'indirectseller.com', 'sid': '00001', 'hp': 1}]}; + const schain = { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + }; bidArray[0].schain = schain; const request = spec.buildRequests([bidArray[0]], bidderRequest); expect(request.data.schain).equal(JSON.stringify(schain)); - }) + }); }); describe('interpretResponse', function () { @@ -213,17 +261,20 @@ describe('YieldmoAdapter', function () { beforeEach(function () { serverResponse = { - body: [{ - callback_id: '21989fdbef550a', - cpm: 3.45455, - width: 300, - height: 250, - ad: '
', - creative_id: '9874652394875' - }], - header: 'header?' + body: [ + { + callback_id: '21989fdbef550a', + cpm: 3.45455, + width: 300, + height: 250, + ad: + '
', + creative_id: '9874652394875', + }, + ], + header: 'header?', }; - }) + }); it('should correctly reorder the server response', function () { const newResponse = spec.interpretResponse(serverResponse); @@ -237,7 +288,8 @@ describe('YieldmoAdapter', function () { currency: 'USD', netRevenue: true, ttl: 300, - ad: '
' + ad: + '
', }); }); @@ -248,7 +300,7 @@ describe('YieldmoAdapter', function () { serverResponse.body[0].cpm = null; response = spec.interpretResponse(serverResponse); - expect(response).to.deep.equal([]) + expect(response).to.deep.equal([]); }); }); @@ -256,15 +308,17 @@ describe('YieldmoAdapter', function () { const SYNC_ENDPOINT = 'https://static.yieldmo.com/blank.min.html?orig='; let options = { iframeEnabled: true, - pixelEnabled: true + pixelEnabled: true, }; it('should return a tracker with type and url as parameters', function () { if (/iPhone|iPad|iPod/i.test(window.navigator.userAgent)) { - expect(spec.getUserSync(options)).to.deep.equal([{ - type: 'iframe', - url: SYNC_ENDPOINT + utils.getOrigin() - }]); + expect(spec.getUserSync(options)).to.deep.equal([ + { + type: 'iframe', + url: SYNC_ENDPOINT + utils.getOrigin(), + }, + ]); options.iframeEnabled = false; expect(spec.getUserSync(options)).to.deep.equal([]); From c318c02ab49c15acc28811caaffc9cc4c19fd63c Mon Sep 17 00:00:00 2001 From: Prebid Manager <49466873+Prebid-Manager@users.noreply.github.com> Date: Wed, 8 Apr 2020 16:12:24 +0700 Subject: [PATCH 227/496] Prebid manager analytics utm tags (#4998) * prebidmanager add utm tags support * prebidmanager add utm tags support tests * prebidmanager add utm tags support tests * prebidmanager add utm tags support fixes Co-authored-by: apuzanova --- modules/prebidmanagerAnalyticsAdapter.js | 34 ++++++++++++++++++- .../prebidmanagerAnalyticsAdapter_spec.js | 34 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/modules/prebidmanagerAnalyticsAdapter.js b/modules/prebidmanagerAnalyticsAdapter.js index b8112628cb6..b98ca864cd5 100644 --- a/modules/prebidmanagerAnalyticsAdapter.js +++ b/modules/prebidmanagerAnalyticsAdapter.js @@ -20,6 +20,7 @@ var _startAuction = 0; var _bidRequestTimeout = 0; let flushInterval; var pmAnalyticsEnabled = false; +const utmTags = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']; var w = window; var d = document; @@ -68,6 +69,36 @@ prebidmanagerAnalytics.disableAnalytics = function() { prebidmanagerAnalytics.originDisableAnalytics(); }; +function collectUtmTagData() { + let newUtm = false; + let pmUtmTags = {}; + try { + utmTags.forEach(function (utmKey) { + let utmValue = utils.getParameterByName(utmKey); + if (utmValue !== '') { + newUtm = true; + } + pmUtmTags[utmKey] = utmValue; + }); + if (newUtm === false) { + utmTags.forEach(function (utmKey) { + let itemValue = localStorage.getItem(`pm_${utmKey}`); + if (itemValue.length !== 0) { + pmUtmTags[utmKey] = itemValue; + } + }); + } else { + utmTags.forEach(function (utmKey) { + localStorage.setItem(`pm_${utmKey}`, pmUtmTags[utmKey]); + }); + } + } catch (e) { + utils.logError(`${analyticsName}Error`, e); + pmUtmTags['error_utm'] = 1; + } + return pmUtmTags; +} + function flush() { if (!pmAnalyticsEnabled) { return; @@ -78,7 +109,8 @@ function flush() { pageViewId: _pageViewId, ver: _VERSION, bundleId: initOptions.bundleId, - events: _eventQueue + events: _eventQueue, + utmTags: collectUtmTagData(), }; ajax( diff --git a/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js b/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js index 7c9173c14ab..e87be40314c 100644 --- a/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js +++ b/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js @@ -101,4 +101,38 @@ describe('Prebid Manager Analytics Adapter', function () { sinon.assert.callCount(prebidmanagerAnalytics.track, 6); }); }); + + describe('build utm tag data', function () { + beforeEach(function () { + localStorage.setItem('pm_utm_source', 'utm_source'); + localStorage.setItem('pm_utm_medium', 'utm_medium'); + localStorage.setItem('pm_utm_campaign', 'utm_camp'); + localStorage.setItem('pm_utm_term', ''); + localStorage.setItem('pm_utm_content', ''); + }); + afterEach(function () { + localStorage.removeItem('pm_utm_source'); + localStorage.removeItem('pm_utm_medium'); + localStorage.removeItem('pm_utm_campaign'); + localStorage.removeItem('pm_utm_term'); + localStorage.removeItem('pm_utm_content'); + prebidmanagerAnalytics.disableAnalytics() + }); + it('should build utm data from local storage', function () { + prebidmanagerAnalytics.enableAnalytics({ + provider: 'prebidmanager', + options: { + bundleId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + } + }); + + const pmEvents = JSON.parse(server.requests[0].requestBody.substring(2)); + + expect(pmEvents.utmTags.utm_source).to.equal('utm_source'); + expect(pmEvents.utmTags.utm_medium).to.equal('utm_medium'); + expect(pmEvents.utmTags.utm_campaign).to.equal('utm_camp'); + expect(pmEvents.utmTags.utm_term).to.equal(''); + expect(pmEvents.utmTags.utm_content).to.equal(''); + }); + }); }); From 5fab5e1cc9ddbef246f1e780e61dbaf829748059 Mon Sep 17 00:00:00 2001 From: Toshiki Yamamoto <6803209+Tosh39@users.noreply.github.com> Date: Wed, 8 Apr 2020 19:43:41 +0900 Subject: [PATCH 228/496] New bid adapter: Wipes (#5051) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add wipes * done update notes * URL変更 * update test parameter * fix mediaType to make it work * fix spec error * fix comment * fix param names * update fix * erase unused code Co-authored-by: 嘉数貴明 Co-authored-by: yaki(kkz) --- modules/wipesBidAdapter.js | 69 ++++++++++ modules/wipesBidAdapter.md | 33 +++++ test/spec/modules/wipesBidAdapter_spec.js | 148 ++++++++++++++++++++++ 3 files changed, 250 insertions(+) create mode 100644 modules/wipesBidAdapter.js create mode 100644 modules/wipesBidAdapter.md create mode 100644 test/spec/modules/wipesBidAdapter_spec.js diff --git a/modules/wipesBidAdapter.js b/modules/wipesBidAdapter.js new file mode 100644 index 00000000000..c60ffba0815 --- /dev/null +++ b/modules/wipesBidAdapter.js @@ -0,0 +1,69 @@ +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER} from '../src/mediaTypes.js'; + +const BIDDER_CODE = 'wipes'; +const ALIAS_BIDDER_CODE = ['wi']; +const SUPPORTED_MEDIA_TYPES = [BANNER] +const ENDPOINT_URL = 'https://adn-srv.reckoner-api.com/v1/prebid'; + +function isBidRequestValid(bid) { + switch (true) { + case !!(bid.params.asid): + break; + default: + utils.logWarn(`isBidRequestValid Error. ${bid.params}, please check your implementation.`); + return false; + } + return true; +} + +function buildRequests(validBidRequests, bidderRequest) { + return validBidRequests.map(bidRequest => { + const params = bidRequest.params; + const asid = params.asid; + return { + method: 'GET', + url: ENDPOINT_URL, + data: { + asid: asid, + } + } + }); +} + +function interpretResponse(serverResponse, bidRequest) { + const bidResponses = []; + const response = serverResponse.body; + const cpm = response.cpm * 1000 || 0; + if (cpm !== 0) { + const netRevenue = (response.netRevenue === undefined) ? true : response.netRevenue; + const bidResponse = { + requestId: response.uuid, + cpm: cpm, + width: response.width, + height: response.height, + creativeId: response.video_creative_id || 0, + dealId: response.deal_id, + currency: 'JPY', + netRevenue: netRevenue, + ttl: config.getConfig('_bidderTimeout'), + referrer: bidRequest.data.r || '', + mediaType: BANNER, + ad: response.ad_tag, + }; + bidResponses.push(bidResponse); + } + return bidResponses; +} + +export const spec = { + code: BIDDER_CODE, + aliases: ALIAS_BIDDER_CODE, + isBidRequestValid, + buildRequests, + interpretResponse, + supportedMediaTypes: SUPPORTED_MEDIA_TYPES +} +registerBidder(spec); diff --git a/modules/wipesBidAdapter.md b/modules/wipesBidAdapter.md new file mode 100644 index 00000000000..ce7d4289079 --- /dev/null +++ b/modules/wipesBidAdapter.md @@ -0,0 +1,33 @@ +# Overview + +``` +Module Name: WIPES Bidder Adapter +Module Type: Bidder Adapter +Maintainer: contact@3-shake.com +``` + +# Description + +Connect to WIPES for bids. +Publishers needs to be set up and approved by WIPES team to enable this adapter. +Please contact support@wipestream.com for further information. + +# Test Parameters +```javascript +var adUnits = [ + // adUnit + { + code: 'video-div', + mediaTypes: { + banner: { + sizes: [[160, 300]], + } + }, + bids: [{ + bidder: 'wipes', + params: { + asid: 'dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ' + } + }] + }] +``` diff --git a/test/spec/modules/wipesBidAdapter_spec.js b/test/spec/modules/wipesBidAdapter_spec.js new file mode 100644 index 00000000000..b5935563526 --- /dev/null +++ b/test/spec/modules/wipesBidAdapter_spec.js @@ -0,0 +1,148 @@ +import {expect} from 'chai'; +import {spec} from 'modules/wipesBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; + +const ENDPOINT_URL = 'https://adn-srv.reckoner-api.com/v1/prebid'; + +describe('wipesBidAdapter', function () { + const adapter = newBidder(spec); + + describe('isBidRequestValid', function () { + let bid = { + 'bidder': 'wipes', + 'params': { + asid: 'dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ' + }, + 'adUnitCode': 'adunit-code', + 'bidId': '51ef8751f9aead', + 'bidderRequestId': '15246a574e859f', + 'auctionId': 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + }; + + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when asid not passed correctly', function () { + bid.params.asid = ''; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when require params are not passed', function () { + let bid = Object.assign({}, bid); + bid.params = {}; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + let bidRequests = [ + { + 'bidder': 'wipes', + 'params': { + asid: 'dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ' + }, + 'adUnitCode': 'adunit-code', + 'bidId': '51ef8751f9aead', + 'bidderRequestId': '15246a574e859f', + 'auctionId': 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + }, + { + 'bidder': 'wipes', + 'params': { + asid: 'dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ' + }, + 'adUnitCode': 'adunit-code2', + 'bidId': '51ef8751f9aead', + 'bidderRequestId': '15246a574e859f', + 'auctionId': 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + } + ]; + + let bidderRequest = { + refererInfo: { + numIframes: 0, + reachedTop: true, + referer: 'http://example.com', + stack: ['http://example.com'] + } + }; + + const request = spec.buildRequests(bidRequests, bidderRequest); + + it('sends bid request to our endpoint via GET', function () { + expect(request[0].method).to.equal('GET'); + expect(request[1].method).to.equal('GET'); + }); + + it('attaches source and version to endpoint URL as query params', function () { + expect(request[0].url).to.equal(ENDPOINT_URL); + expect(request[1].url).to.equal(ENDPOINT_URL); + }); + + it('adUnitCode should be sent as uc parameters on any requests', function () { + expect(request[0].data.asid).to.equal('dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ'); + expect(request[1].data.asid).to.equal('dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ'); + }); + }); + + describe('interpretResponse', function () { + let bidRequestVideo = [ + { + 'method': 'GET', + 'url': ENDPOINT_URL, + 'data': { + 'asid': 'dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ', + } + } + ]; + + let serverResponseVideo = { + body: { + 'uuid': 'a42947f8-f8fd-4cf7-bb72-31a87ab1f6ff', + 'ad_tag': '', + 'height': 160, + 'width': 300, + 'cpm': 850, + 'status_message': '', + 'currency': 'JPY', + 'video_creative_id': 600004 + } + }; + + it('should get the correct bid response for video', function () { + let expectedResponse = [{ + 'requestId': '23beaa6af6cdde', + 'cpm': 850, + 'width': 300, + 'height': 160, + 'creativeId': '600004', + 'dealId': undefined, + 'currency': 'JPY', + 'netRevenue': true, + 'ttl': 3000, + 'referrer': '', + 'mediaType': 'banner', + 'ad': '' + }]; + let result = spec.interpretResponse(serverResponseVideo, bidRequestVideo[0]); + expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); + expect(result[0].mediaType).to.equal(expectedResponse[0].mediaType); + }); + + it('handles empty bid response', function () { + let response = { + body: { + 'uid': 'a42947f8-f8fd-4cf7-bb72-31a87ab1f6ff', + 'height': 0, + 'crid': '', + 'statusMessage': '', + 'width': 0, + 'cpm': 0 + } + }; + let result = spec.interpretResponse(response, bidRequestVideo[0]); + expect(result.length).to.equal(0); + }); + }); +}); From 1a8406f4325cea3fd2d467e680d019e945773d49 Mon Sep 17 00:00:00 2001 From: "Takaaki.Kojima" Date: Wed, 8 Apr 2020 22:22:00 +0900 Subject: [PATCH 229/496] updateAdGenerationManual (#5032) --- modules/adgenerationBidAdapter.md | 86 ++++++++++++++++--------------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/modules/adgenerationBidAdapter.md b/modules/adgenerationBidAdapter.md index 7dfc301e657..7f66732ff38 100644 --- a/modules/adgenerationBidAdapter.md +++ b/modules/adgenerationBidAdapter.md @@ -15,57 +15,61 @@ AdGeneration bid adapter supports Banner and Native. # Test Parameters ``` var adUnits = [ - // Banner adUnit - { - code: 'banner-div', // banner - sizes: [[300, 250]], - bids: [ - { - bidder: 'adg', - params: { - id: '58278', // banner - } - }, - ] - }, - // Native adUnit - { - code: 'native-div', - sizes: [[1,1]], - mediaTypes: { - native: { - image: { + // Banner adUnit + { + code: 'banner-div', // banner + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [ + { + bidder: 'adg', + params: { + id: '58278', // banner + } + }, + ] + }, + // Native adUnit + { + code: 'native-div', + sizes: [[1,1]], + mediaTypes: { + native: { + image: { required: true - }, - title: { + }, + title: { required: true, len: 80 - }, - sponsoredBy: { + }, + sponsoredBy: { required: true - }, - clickUrl: { + }, + clickUrl: { required: true - }, - body: { + }, + body: { required: true - }, - icon: { + }, + icon: { required: true - }, - privacyLink: { + }, + privacyLink: { required: true - }, }, - }, - bids: [ - { - bidder: 'adg', - params: { + }, + }, + bids: [ + { + bidder: 'adg', + params: { id: '58279', //native - } - }, - ] + } + }, + ] }, ]; ``` From de504a9bb6fd0f5a9954a0949f4d22837e58b7a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9onard=20Labat?= Date: Wed, 8 Apr 2020 16:07:04 +0200 Subject: [PATCH 230/496] Criteo : added first party data mapping to bidder request (#4954) --- modules/criteoBidAdapter.js | 19 +++- test/spec/modules/criteoBidAdapter_spec.js | 114 ++++++++++++++++++++- 2 files changed, 129 insertions(+), 4 deletions(-) diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js index 65675248208..7c2c5d69ad3 100644 --- a/modules/criteoBidAdapter.js +++ b/modules/criteoBidAdapter.js @@ -9,7 +9,7 @@ import { verify } from 'criteo-direct-rsa-validate/build/verify.js'; import { getStorageManager } from '../src/storageManager.js'; const GVLID = 91; -export const ADAPTER_VERSION = 26; +export const ADAPTER_VERSION = 27; const BIDDER_CODE = 'criteo'; const CDB_ENDPOINT = 'https://bidder.criteo.com/cdb'; const CRITEO_VENDOR_ID = 91; @@ -58,7 +58,11 @@ export const spec = { let url; let data; - Object.assign(bidderRequest, { ceh: config.getConfig('criteo.ceh') }); + Object.assign(bidderRequest, { + publisherExt: config.getConfig('fpd.context'), + userExt: config.getConfig('fpd.user'), + ceh: config.getConfig('criteo.ceh') + }); // If publisher tag not already loaded try to get it from fast bid if (!publisherTagAvailable()) { @@ -252,6 +256,7 @@ function buildCdbRequest(context, bidRequests, bidderRequest) { const request = { publisher: { url: context.url, + ext: bidderRequest.publisherExt }, slots: bidRequests.map(bidRequest => { networkId = bidRequest.params.networkId || networkId; @@ -264,6 +269,12 @@ function buildCdbRequest(context, bidRequests, bidderRequest) { if (bidRequest.params.zoneId) { slot.zoneid = bidRequest.params.zoneId; } + if (bidRequest.fpd && bidRequest.fpd.context) { + slot.ext = bidRequest.fpd.context; + } + if (bidRequest.params.ext) { + slot.ext = Object.assign({}, slot.ext, bidRequest.params.ext); + } if (bidRequest.params.publisherSubId) { slot.publishersubid = bidRequest.params.publisherSubId; } @@ -293,7 +304,9 @@ function buildCdbRequest(context, bidRequests, bidderRequest) { if (networkId) { request.publisher.networkid = networkId; } - request.user = {}; + request.user = { + ext: bidderRequest.userExt + }; if (bidderRequest && bidderRequest.ceh) { request.user.ceh = bidderRequest.ceh; } diff --git a/test/spec/modules/criteoBidAdapter_spec.js b/test/spec/modules/criteoBidAdapter_spec.js index 9c96cfa3a05..b1319871b34 100755 --- a/test/spec/modules/criteoBidAdapter_spec.js +++ b/test/spec/modules/criteoBidAdapter_spec.js @@ -7,17 +7,20 @@ import { config } from '../../../src/config.js'; import { NATIVE, VIDEO } from '../../../src/mediaTypes.js'; describe('The Criteo bidding adapter', function () { - let utilsMock; + let utilsMock, sandbox; beforeEach(function () { // Remove FastBid to avoid side effects localStorage.removeItem('criteo_fast_bid'); utilsMock = sinon.mock(utils); + + sandbox = sinon.sandbox.create(); }); afterEach(function() { global.Criteo = undefined; utilsMock.restore(); + sandbox.restore(); }); describe('isBidRequestValid', function () { @@ -705,6 +708,115 @@ describe('The Criteo bidding adapter', function () { expect(request.data.user).to.not.be.null; expect(request.data.user.ceh).to.equal('hashedemail'); }); + + it('should properly build a request without first party data', function () { + const bidRequests = [ + { + bidder: 'criteo', + adUnitCode: 'bid-123', + transactionId: 'transaction-123', + sizes: [[728, 90]], + params: { + zoneId: 123 + } + }, + ]; + + sandbox.stub(config, 'getConfig').callsFake(key => { + const config = { + }; + return utils.deepAccess(config, key); + }); + + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.publisher.ext).to.equal(undefined); + expect(request.data.user.ext).to.equal(undefined); + expect(request.data.slots[0].ext).to.equal(undefined); + }); + + it('should properly build a request with criteo specific ad unit first party data', function () { + const bidRequests = [ + { + bidder: 'criteo', + adUnitCode: 'bid-123', + transactionId: 'transaction-123', + sizes: [[728, 90]], + params: { + zoneId: 123, + ext: { + bidfloor: 0.75 + } + } + }, + ]; + + sandbox.stub(config, 'getConfig').callsFake(key => { + const config = { + }; + return utils.deepAccess(config, key); + }); + + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.slots[0].ext).to.deep.equal({ + bidfloor: 0.75, + }); + }); + + it('should properly build a request with first party data', function () { + const contextData = { + keywords: ['power tools'], + data: { + pageType: 'article' + } + }; + const userData = { + gender: 'M', + data: { + registered: true + } + }; + const bidRequests = [ + { + bidder: 'criteo', + adUnitCode: 'bid-123', + transactionId: 'transaction-123', + sizes: [[728, 90]], + params: { + zoneId: 123, + ext: { + bidfloor: 0.75 + } + }, + fpd: { + context: { + data: { + someContextAttribute: 'abc' + } + } + } + }, + ]; + + sandbox.stub(config, 'getConfig').callsFake(key => { + const config = { + fpd: { + context: contextData, + user: userData + } + }; + return utils.deepAccess(config, key); + }); + + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.publisher.ext).to.deep.equal(contextData); + expect(request.data.user.ext).to.deep.equal(userData); + expect(request.data.slots[0].ext).to.deep.equal({ + bidfloor: 0.75, + data: { + someContextAttribute: 'abc' + } + }); + }); }); describe('interpretResponse', function () { From 9eec929dfc67eeb04604987edfa1e78633f43bea Mon Sep 17 00:00:00 2001 From: bjorn-lw <32431346+bjorn-lw@users.noreply.github.com> Date: Wed, 8 Apr 2020 18:39:52 +0200 Subject: [PATCH 231/496] Read OpenRTB app objects if set in config + bug fix for when ad units are reloaded (#5086) * Livewrapped bid and analytics adapter * Fixed some tests for browser compatibility * Fixed some tests for browser compatibility * Changed analytics adapter code name * Fix double quote in debug message * modified how gdpr is being passed * Added support for Publisher Common ID Module * Corrections for ttr in analytics * ANalytics updates * Auction start time stamp changed * Detect recovered ad blocked requests Make it possible to pass dynamic parameters to adapter * Collect info on ad units receiving any valid bid * Support for ID5 Pass metadata from adapter * Typo in test + eids on wrong level * Fix for Prebid 3.0 * Fix get referer * http -> https in tests * Native support * Read sizes from mediatype.banner * Revert accidental commit * Support native data collection + minor refactorings * Set analytics endpoint * Support for app parameters * Fix issue where adunits with bids were not counted on reload --- modules/livewrappedAnalyticsAdapter.js | 36 +++--- modules/livewrappedBidAdapter.js | 51 +++++++- .../modules/livewrappedBidAdapter_spec.js | 119 +++++++++++++++--- 3 files changed, 170 insertions(+), 36 deletions(-) diff --git a/modules/livewrappedAnalyticsAdapter.js b/modules/livewrappedAnalyticsAdapter.js index 47f7f60d141..b331448161e 100644 --- a/modules/livewrappedAnalyticsAdapter.js +++ b/modules/livewrappedAnalyticsAdapter.js @@ -16,8 +16,7 @@ let initOptions; export const BID_WON_TIMEOUT = 500; const cache = { - auctions: {}, - bidAdUnits: {} + auctions: {} }; let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE}), { @@ -28,7 +27,7 @@ let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE switch (eventType) { case CONSTANTS.EVENTS.AUCTION_INIT: utils.logInfo('LIVEWRAPPED_AUCTION_INIT:', args); - cache.auctions[args.auctionId] = {bids: {}}; + cache.auctions[args.auctionId] = {bids: {}, bidAdUnits: {}}; break; case CONSTANTS.EVENTS.BID_REQUESTED: utils.logInfo('LIVEWRAPPED_BID_REQUESTED:', args); @@ -64,8 +63,12 @@ let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE if (!bidResponse.ttr) { bidResponse.ttr = time - bidResponse.start; } - if (!cache.bidAdUnits[bidResponse.adUnit]) { - cache.bidAdUnits[bidResponse.adUnit] = {sent: 0, timeStamp: cache.auctions[args.auctionId].timeStamp}; + if (!cache.auctions[args.auctionId].bidAdUnits[bidResponse.adUnit]) { + cache.auctions[args.auctionId].bidAdUnits[bidResponse.adUnit] = + { + sent: 0, + timeStamp: cache.auctions[args.auctionId].timeStamp + }; } break; case CONSTANTS.EVENTS.BIDDER_DONE: @@ -240,16 +243,19 @@ function getTimeouts() { function getbidAdUnits() { var bidAdUnits = []; - Object.keys(cache.bidAdUnits).forEach(adUnit => { - let bidAdUnit = cache.bidAdUnits[adUnit]; - if (!bidAdUnit.sent) { - bidAdUnit.sent = 1; - - bidAdUnits.push({ - adUnit: adUnit, - timeStamp: bidAdUnit.timeStamp - }); - } + Object.keys(cache.auctions).forEach(auctionId => { + let auction = cache.auctions[auctionId]; + Object.keys(auction.bidAdUnits).forEach(adUnit => { + let bidAdUnit = auction.bidAdUnits[adUnit]; + if (!bidAdUnit.sent) { + bidAdUnit.sent = 1; + + bidAdUnits.push({ + adUnit: adUnit, + timeStamp: bidAdUnit.timeStamp + }); + } + }); }); return bidAdUnits; diff --git a/modules/livewrappedBidAdapter.js b/modules/livewrappedBidAdapter.js index 5a9ef302d51..57e5a5a7c2f 100644 --- a/modules/livewrappedBidAdapter.js +++ b/modules/livewrappedBidAdapter.js @@ -9,7 +9,7 @@ export const storage = getStorageManager(); const BIDDER_CODE = 'livewrapped'; export const URL = 'https://lwadm.com/ad'; -const VERSION = '1.2'; +const VERSION = '1.3'; export const spec = { code: BIDDER_CODE, @@ -29,6 +29,7 @@ export const spec = { * seats: List of bidders and seats Optional. {"bidder name": ["seat 1", "seat 2"], ...} * deviceId: Device id if available Optional. * ifa: Advertising ID Optional. + * bundle: App bundle Optional. Read from config if exists. * options Dynamic data Optional. Optional data to send into adapter. * * @param {BidRequest} bid The bid params to validate. @@ -55,9 +56,10 @@ export const spec = { const seats = find(bidRequests, hasSeatsParam); const deviceId = find(bidRequests, hasDeviceIdParam); const ifa = find(bidRequests, hasIfaParam); + const bundle = find(bidRequests, hasBundleParam); const tid = find(bidRequests, hasTidParam); bidUrl = bidUrl ? bidUrl.params.bidUrl : URL; - url = url ? url.params.url : getTopWindowLocation(bidderRequest); + url = url ? url.params.url : (getAppDomain() || getTopWindowLocation(bidderRequest)); test = test ? test.params.test : undefined; var adRequests = bidRequests.map(bidToAdRequest); @@ -69,7 +71,10 @@ export const spec = { test: test, seats: seats ? seats.params.seats : undefined, deviceId: deviceId ? deviceId.params.deviceId : undefined, - ifa: ifa ? ifa.params.ifa : undefined, + ifa: ifa ? ifa.params.ifa : getDeviceIfa(), + bundle: bundle ? bundle.params.bundle : getAppBundle(), + width: getDeviceWidth(), + height: getDeviceHeight(), tid: tid ? tid.params.tid : undefined, version: VERSION, gdprApplies: bidderRequest.gdprConsent ? bidderRequest.gdprConsent.gdprApplies : undefined, @@ -178,6 +183,10 @@ function hasIfaParam(bid) { return !!bid.params.ifa; } +function hasBundleParam(bid) { + return !!bid.params.bundle; +} + function hasTidParam(bid) { return !!bid.params.tid; } @@ -264,4 +273,40 @@ function getTopWindowLocation(bidderRequest) { return config.getConfig('pageUrl') || url; } +function getAppBundle() { + if (typeof config.getConfig('app') === 'object') { + return config.getConfig('app').bundle; + } +} + +function getAppDomain() { + if (typeof config.getConfig('app') === 'object') { + return config.getConfig('app').domain; + } +} + +function getDeviceIfa() { + if (typeof config.getConfig('device') === 'object') { + return config.getConfig('device').ifa; + } +} + +function getDeviceWidth() { + let device = config.getConfig('device'); + if (typeof device === 'object' && device.width) { + return device.width; + } + + return window.innerWidth; +} + +function getDeviceHeight() { + let device = config.getConfig('device'); + if (typeof device === 'object' && device.height) { + return device.height; + } + + return window.innerHeight; +} + registerBidder(spec); diff --git a/test/spec/modules/livewrappedBidAdapter_spec.js b/test/spec/modules/livewrappedBidAdapter_spec.js index 7b26f5b533d..b82bf8db160 100644 --- a/test/spec/modules/livewrappedBidAdapter_spec.js +++ b/test/spec/modules/livewrappedBidAdapter_spec.js @@ -100,7 +100,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -135,7 +137,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -171,7 +175,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'caller id 1', @@ -200,7 +206,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'panorama_d_1', @@ -228,7 +236,9 @@ describe('Livewrapped adapter tests', function () { let expectedQuery = { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -258,7 +268,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, deviceId: 'deviceid', ifa: 'ifa', cookieSupport: true, @@ -289,7 +301,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, tid: 'tracking id', test: true, cookieSupport: true, @@ -319,7 +333,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'panorama_d_1', @@ -348,7 +364,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, rcv: true, adRequests: [{ @@ -377,7 +395,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'panorama_d_1', @@ -406,7 +426,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'panorama_d_1', @@ -421,6 +443,53 @@ describe('Livewrapped adapter tests', function () { expect(data).to.deep.equal(expectedQuery); }); + it('should use app objects', function() { + sandbox.stub(utils, 'isSafariBrowser').callsFake(() => false); + sandbox.stub(storage, 'cookiesAreEnabled').callsFake(() => true); + + let testbidRequest = clone(bidderRequest); + delete testbidRequest.bids[0].params.url; + + let origGetConfig = config.getConfig; + sandbox.stub(config, 'getConfig').callsFake(function (key) { + if (key === 'app') { + return {bundle: 'bundle', domain: 'https://appdomain.com'}; + } + if (key === 'device') { + return {ifa: 'ifa', width: 300, height: 200}; + } + return origGetConfig.apply(config, arguments); + }); + + let result = spec.buildRequests(testbidRequest.bids, testbidRequest); + let data = JSON.parse(result.data); + + expect(result.url).to.equal('https://lwadm.com/ad'); + + let expectedQuery = { + auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', + publisherId: '26947112-2289-405D-88C1-A7340C57E63E', + userId: 'user id', + url: 'https://appdomain.com', + seats: {'dsp': ['seat 1']}, + version: '1.3', + width: 300, + height: 200, + ifa: 'ifa', + bundle: 'bundle', + cookieSupport: true, + adRequests: [{ + adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', + callerAdUnitId: 'panorama_d_1', + bidId: '2ffb201a808da7', + transactionId: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D', + formats: [{width: 980, height: 240}, {width: 980, height: 120}] + }] + }; + + expect(data).to.deep.equal(expectedQuery); + }); + it('should use mediaTypes.banner.sizes before legacy sizes', function() { sandbox.stub(utils, 'isSafariBrowser').callsFake(() => false); sandbox.stub(storage, 'cookiesAreEnabled').callsFake(() => true); @@ -436,7 +505,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'panorama_d_1', @@ -468,7 +539,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, gdprApplies: true, gdprConsent: 'test', @@ -502,7 +575,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, gdprApplies: false, adRequests: [{ @@ -531,7 +606,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: false, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -559,7 +636,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: false, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -620,7 +699,9 @@ describe('Livewrapped adapter tests', function () { userId: 'pubcid 123', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -650,7 +731,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', From b8d5e05d788c0041fd77689b4c15ce529b1eadd4 Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Thu, 9 Apr 2020 09:02:42 -0600 Subject: [PATCH 232/496] Utils updates (#5092) * move parseQS to utils * move formatQS to utils * remove url module and combine with utils * remove old unused utils * update config to use query string helper * fix race condition --- modules/adkernelAdnAnalyticsAdapter.js | 7 +- modules/adkernelAdnBidAdapter.js | 3 +- modules/adkernelBidAdapter.js | 3 +- modules/advangelistsBidAdapter.js | 3 +- modules/adxcgAnalyticsAdapter.js | 3 +- modules/adxcgBidAdapter.js | 3 +- modules/adyoulikeBidAdapter.js | 4 +- modules/audienceNetworkBidAdapter.js | 3 +- modules/beachfrontBidAdapter.js | 3 +- modules/brightcomBidAdapter.js | 3 +- modules/criteoBidAdapter.js | 3 +- modules/criteoIdSystem.js | 3 +- modules/datablocksBidAdapter.js | 3 +- modules/dfpAdServerVideo.js | 5 +- modules/emoteevBidAdapter.js | 16 +- modules/emx_digitalBidAdapter.js | 3 +- modules/fintezaAnalyticsAdapter.js | 3 +- modules/konduitWrapper.js | 3 +- modules/medianetAnalyticsAdapter.js | 5 +- modules/medianetBidAdapter.js | 5 +- modules/mgidBidAdapter.js | 3 +- modules/mytargetBidAdapter.js | 3 +- modules/nafdigitalBidAdapter.js | 3 +- modules/nextrollBidAdapter.js | 3 +- modules/openxBidAdapter.js | 3 +- modules/priceFloors.js | 3 +- modules/pubCommonId.js | 5 +- modules/pubCommonIdSystem.js | 5 +- modules/readpeakBidAdapter.js | 3 +- modules/rubiconAnalyticsAdapter.js | 3 +- modules/sortableBidAdapter.js | 3 +- modules/sovrnBidAdapter.js | 3 +- modules/staqAnalyticsAdapter.js | 7 +- modules/theAdxBidAdapter.js | 5 +- modules/tpmnBidAdapter.js | 3 +- modules/undertoneBidAdapter.js | 4 +- modules/yuktamediaAnalyticsAdapter.js | 3 +- src/adserver.js | 2 +- src/ajax.js | 5 +- src/auction.js | 5 +- src/config.js | 3 +- src/events.js | 4 +- src/url.js | 55 ----- src/utils.js | 212 +++++------------- test/spec/modules/adformBidAdapter_spec.js | 1 - .../modules/adformOpenRTBBidAdapter_spec.js | 1 - test/spec/modules/adxcgBidAdapter_spec.js | 21 +- test/spec/modules/adyoulikeBidAdapter_spec.js | 1 - .../spec/modules/beachfrontBidAdapter_spec.js | 2 +- test/spec/modules/criteoIdSystem_spec.js | 3 +- test/spec/modules/dfpAdServerVideo_spec.js | 43 ++-- test/spec/modules/emoteevBidAdapter_spec.js | 41 ++-- .../modules/eplanningAnalyticsAdapter_spec.js | 4 +- test/spec/modules/etargetBidAdapter_spec.js | 1 - .../modules/fintezaAnalyticsAdapter_spec.js | 12 +- test/spec/modules/konduitWrapper_spec.js | 2 +- test/spec/modules/mgidBidAdapter_spec.js | 11 +- test/spec/modules/quantcastBidAdapter_spec.js | 6 +- test/spec/modules/readpeakBidAdapter_spec.js | 2 +- .../spec/modules/revcontentBidAdapter_spec.js | 1 - .../modules/seedingAllianceAdapter_spec.js | 1 - test/spec/unit/core/bidderFactory_spec.js | 4 +- test/spec/url_spec.js | 94 -------- test/spec/utils_spec.js | 126 ++++++++--- 64 files changed, 290 insertions(+), 519 deletions(-) delete mode 100644 src/url.js delete mode 100644 test/spec/url_spec.js mode change 100755 => 100644 test/spec/utils_spec.js diff --git a/modules/adkernelAdnAnalyticsAdapter.js b/modules/adkernelAdnAnalyticsAdapter.js index b0bdadf57d0..b6db6fc22de 100644 --- a/modules/adkernelAdnAnalyticsAdapter.js +++ b/modules/adkernelAdnAnalyticsAdapter.js @@ -1,7 +1,6 @@ import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; import adapterManager from '../src/adapterManager.js'; -import {parse} from '../src/url.js'; import * as utils from '../src/utils.js'; import {ajax} from '../src/ajax.js'; import { getStorageManager } from '../src/storageManager.js'; @@ -211,7 +210,7 @@ export function getUmtSource(pageUrl, referrer) { if (se) { return asUtm(se, ORGANIC, ORGANIC); } - let parsedUrl = parse(pageUrl); + let parsedUrl = utils.parseUrl(pageUrl); let [refHost, refPath] = getReferrer(referrer); if (refHost && refHost !== parsedUrl.hostname) { return asUtm(refHost, REFERRAL, REFERRAL, '', refPath); @@ -238,12 +237,12 @@ export function getUmtSource(pageUrl, referrer) { } function getReferrer(referrer) { - let ref = parse(referrer); + let ref = utils.parseUrl(referrer); return [ref.hostname, ref.pathname]; } function getUTM(pageUrl) { - let urlParameters = parse(pageUrl).search; + let urlParameters = utils.parseUrl(pageUrl).search; if (!urlParameters['utm_campaign'] || !urlParameters['utm_source']) { return; } diff --git a/modules/adkernelAdnBidAdapter.js b/modules/adkernelAdnBidAdapter.js index 25a7f2f4abc..483d6de52b9 100644 --- a/modules/adkernelAdnBidAdapter.js +++ b/modules/adkernelAdnBidAdapter.js @@ -1,7 +1,6 @@ import * as utils from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {parse as parseUrl} from '../src/url.js'; const DEFAULT_ADKERNEL_DSP_DOMAIN = 'tag.adkernel.com'; const DEFAULT_MIMES = ['video/mp4', 'video/webm', 'application/x-shockwave-flash', 'application/javascript']; @@ -71,7 +70,7 @@ function buildRequestParams(tags, auctionId, transactionId, gdprConsent, uspCons } function buildSite(refInfo) { - let loc = parseUrl(refInfo.referer); + let loc = utils.parseUrl(refInfo.referer); let result = { page: `${loc.protocol}://${loc.hostname}${loc.pathname}`, secure: ~~(loc.protocol === 'https') diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index dbb0f4a3344..1a16801ba67 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -3,7 +3,6 @@ import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import find from 'core-js/library/fn/array/find.js'; import includes from 'core-js/library/fn/array/includes.js'; -import {parse as parseUrl} from '../src/url.js'; /* * In case you're AdKernel whitelable platform's client who needs branded adapter to @@ -274,7 +273,7 @@ function getLanguage() { * Creates site description object */ function createSite(refInfo) { - let url = parseUrl(refInfo.referer); + let url = utils.parseUrl(refInfo.referer); let site = { 'domain': url.hostname, 'page': `${url.protocol}://${url.hostname}${url.pathname}` diff --git a/modules/advangelistsBidAdapter.js b/modules/advangelistsBidAdapter.js index b3064568d3a..64e4c58653b 100644 --- a/modules/advangelistsBidAdapter.js +++ b/modules/advangelistsBidAdapter.js @@ -1,5 +1,4 @@ import * as utils from '../src/utils.js'; -import { parse as parseUrl } from '../src/url.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { VIDEO, BANNER } from '../src/mediaTypes.js'; @@ -293,7 +292,7 @@ function createVideoRequestData(bid, bidderRequest) { function getTopWindowLocation(bidderRequest) { let url = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer; - return parseUrl(config.getConfig('pageUrl') || url, { decodeSearchAsString: true }); + return utils.parseUrl(config.getConfig('pageUrl') || url, { decodeSearchAsString: true }); } function createBannerRequestData(bid, bidderRequest) { diff --git a/modules/adxcgAnalyticsAdapter.js b/modules/adxcgAnalyticsAdapter.js index 01baa0ebd46..9f514c545a1 100644 --- a/modules/adxcgAnalyticsAdapter.js +++ b/modules/adxcgAnalyticsAdapter.js @@ -2,7 +2,6 @@ import { ajax } from '../src/ajax.js'; import adapter from '../src/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import CONSTANTS from '../src/constants.json'; -import * as url from '../src/url.js'; import * as utils from '../src/utils.js'; /** @@ -113,7 +112,7 @@ function mapBidWon (bidResponse) { } function send (data) { - let adxcgAnalyticsRequestUrl = url.format({ + let adxcgAnalyticsRequestUrl = utils.buildUrl({ protocol: 'https', hostname: adxcgAnalyticsAdapter.context.host, pathname: '/pbrx/v2', diff --git a/modules/adxcgBidAdapter.js b/modules/adxcgBidAdapter.js index 37690c66d58..cc76731836b 100644 --- a/modules/adxcgBidAdapter.js +++ b/modules/adxcgBidAdapter.js @@ -1,6 +1,5 @@ import { config } from '../src/config.js' import * as utils from '../src/utils.js' -import * as url from '../src/url.js' import { registerBidder } from '../src/adapters/bidderFactory.js' import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js' import includes from 'core-js/library/fn/array/includes.js' @@ -179,7 +178,7 @@ export const spec = { beaconParams.idl_env = validBidRequests[0].userId.idl_env; } - let adxcgRequestUrl = url.format({ + let adxcgRequestUrl = utils.buildUrl({ protocol: 'https', hostname: 'hbps.adxcg.net', pathname: '/get/adi', diff --git a/modules/adyoulikeBidAdapter.js b/modules/adyoulikeBidAdapter.js index 7e591b3901c..9391a3fb94f 100644 --- a/modules/adyoulikeBidAdapter.js +++ b/modules/adyoulikeBidAdapter.js @@ -1,6 +1,4 @@ import * as utils from '../src/utils.js'; -import { format } from '../src/url.js'; -// import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import find from 'core-js/library/fn/array/find.js'; @@ -145,7 +143,7 @@ function getPageRefreshed() { /* Create endpoint url */ function createEndpoint(bidRequests, bidderRequest) { let host = getHostname(bidRequests); - return format({ + return utils.buildUrl({ protocol: 'https', host: `${DEFAULT_DC}${host}.omnitagjs.com`, pathname: '/hb-api/prebid/v1', diff --git a/modules/audienceNetworkBidAdapter.js b/modules/audienceNetworkBidAdapter.js index 54a50af4269..2d7b7eae0dc 100644 --- a/modules/audienceNetworkBidAdapter.js +++ b/modules/audienceNetworkBidAdapter.js @@ -2,8 +2,7 @@ * @file AudienceNetwork adapter. */ import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { formatQS } from '../src/url.js'; -import { generateUUID, deepAccess, convertTypes } from '../src/utils.js'; +import { generateUUID, deepAccess, convertTypes, formatQS } from '../src/utils.js'; import findIndex from 'core-js/library/fn/array/find-index.js'; import includes from 'core-js/library/fn/array/includes.js'; diff --git a/modules/beachfrontBidAdapter.js b/modules/beachfrontBidAdapter.js index bbb4ae35729..9b6c431fdd7 100644 --- a/modules/beachfrontBidAdapter.js +++ b/modules/beachfrontBidAdapter.js @@ -1,5 +1,4 @@ import * as utils from '../src/utils.js'; -import { parse as parseUrl } from '../src/url.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { Renderer } from '../src/Renderer.js'; @@ -247,7 +246,7 @@ function isBannerBidValid(bid) { function getTopWindowLocation(bidderRequest) { let url = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer; - return parseUrl(config.getConfig('pageUrl') || url, { decodeSearchAsString: true }); + return utils.parseUrl(config.getConfig('pageUrl') || url, { decodeSearchAsString: true }); } function getTopWindowReferrer() { diff --git a/modules/brightcomBidAdapter.js b/modules/brightcomBidAdapter.js index 0a418406d4f..a4b013a2fe2 100644 --- a/modules/brightcomBidAdapter.js +++ b/modules/brightcomBidAdapter.js @@ -1,5 +1,4 @@ import * as utils from '../src/utils.js'; -import * as url from '../src/url.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; @@ -57,7 +56,7 @@ function buildRequests(bidReqs, bidderRequest) { id: utils.getUniqueIdentifierStr(), imp: brightcomImps, site: { - domain: url.parse(referrer).host, + domain: utils.parseUrl(referrer).host, page: referrer, publisher: { id: publisherId diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js index 7c2c5d69ad3..6eca0c95dde 100644 --- a/modules/criteoBidAdapter.js +++ b/modules/criteoBidAdapter.js @@ -2,7 +2,6 @@ import { loadExternalScript } from '../src/adloader.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { parse } from '../src/url.js'; import * as utils from '../src/utils.js'; import find from 'core-js/library/fn/array/find.js'; import { verify } from 'criteo-direct-rsa-validate/build/verify.js'; @@ -204,7 +203,7 @@ function buildContext(bidRequests, bidderRequest) { if (bidderRequest && bidderRequest.refererInfo) { referrer = bidderRequest.refererInfo.referer; } - const queryString = parse(referrer).search; + const queryString = utils.parseUrl(referrer).search; const context = { url: referrer, diff --git a/modules/criteoIdSystem.js b/modules/criteoIdSystem.js index d03e5de26c7..c44f0c843ae 100644 --- a/modules/criteoIdSystem.js +++ b/modules/criteoIdSystem.js @@ -7,7 +7,6 @@ import * as utils from '../src/utils.js' import * as ajax from '../src/ajax.js' -import * as urlLib from '../src/url.js' import { getRefererInfo } from '../src/refererDetection.js' import { submodule } from '../src/hook.js'; import { getStorageManager } from '../src/storageManager.js'; @@ -30,7 +29,7 @@ function areCookiesWriteable() { } function extractProtocolHost (url, returnOnlyHost = false) { - const parsedUrl = urlLib.parse(url) + const parsedUrl = utils.parseUrl(url) return returnOnlyHost ? `${parsedUrl.hostname}` : `${parsedUrl.protocol}://${parsedUrl.hostname}${parsedUrl.port ? ':' + parsedUrl.port : ''}/`; diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js index 32b18592417..b00a3eae659 100644 --- a/modules/datablocksBidAdapter.js +++ b/modules/datablocksBidAdapter.js @@ -1,7 +1,6 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { parse as parseUrl } from '../src/url.js'; const NATIVE_MAP = { 'body': 2, 'body2': 10, @@ -61,7 +60,7 @@ export const spec = { let imps = {}; let site = {}; let device = {}; - let refurl = parseUrl(bidderRequest.referrer); + let refurl = utils.parseUrl(bidderRequest.referrer); let requests = []; validBidRequests.forEach(bidRequest => { diff --git a/modules/dfpAdServerVideo.js b/modules/dfpAdServerVideo.js index 426da05efcf..71a8471d554 100644 --- a/modules/dfpAdServerVideo.js +++ b/modules/dfpAdServerVideo.js @@ -4,8 +4,7 @@ import { registerVideoSupport } from '../src/adServerManager.js'; import { targeting } from '../src/targeting.js'; -import { formatQS, format as buildUrl, parse } from '../src/url.js'; -import { deepAccess, isEmpty, logError, parseSizesInput } from '../src/utils.js'; +import { deepAccess, isEmpty, logError, parseSizesInput, formatQS, parseUrl, buildUrl } from '../src/utils.js'; import { config } from '../src/config.js'; import { getHook, submodule } from '../src/hook.js'; import { auctionManager } from '../src/auctionManager.js'; @@ -74,7 +73,7 @@ export function buildDfpVideoUrl(options) { if (options.url) { // when both `url` and `params` are given, parsed url will be overwriten // with any matching param components - urlComponents = parse(options.url, {noDecodeWholeURL: true}); + urlComponents = parseUrl(options.url, {noDecodeWholeURL: true}); if (isEmpty(options.params)) { return buildUrlFromAdserverUrlComponents(urlComponents, bid, options); diff --git a/modules/emoteevBidAdapter.js b/modules/emoteevBidAdapter.js index 0bdf4cda58e..e0f88725d8a 100644 --- a/modules/emoteevBidAdapter.js +++ b/modules/emoteevBidAdapter.js @@ -23,10 +23,10 @@ import { deepAccess, isArray, isInteger, - getParameterByName + getParameterByName, + buildUrl } from '../src/utils.js'; import {config} from '../src/config.js'; -import * as url from '../src/url.js'; import { getStorageManager } from '../src/storageManager.js'; export const storage = getStorageManager(); @@ -234,7 +234,7 @@ export const domain = (env) => { * @param {string} env Emoteev environment parameter * @returns {string} The full URL which events is sent to. */ -export const eventsUrl = env => url.format({ +export const eventsUrl = env => buildUrl({ protocol: (env === DEVELOPMENT) ? 'http' : 'https', hostname: domain(env), pathname: EVENTS_PATH @@ -246,7 +246,7 @@ export const eventsUrl = env => url.format({ * @param {string} env Emoteev environment parameter * @returns {string} The full URL which bidderRequest is sent to. */ -export const bidderUrl = env => url.format({ +export const bidderUrl = env => buildUrl({ protocol: (env === DEVELOPMENT) ? 'http' : 'https', hostname: domain(env), pathname: BIDDER_PATH @@ -258,7 +258,7 @@ export const bidderUrl = env => url.format({ * @param {string} env Emoteev environment parameter * @returns {string} The full URL called for iframe-based user sync */ -export const userSyncIframeUrl = env => url.format({ +export const userSyncIframeUrl = env => buildUrl({ protocol: (env === DEVELOPMENT) ? 'http' : 'https', hostname: domain(env), pathname: USER_SYNC_IFRAME_PATH @@ -270,7 +270,7 @@ export const userSyncIframeUrl = env => url.format({ * @param {string} env Emoteev environment parameter * @returns {string} The full URL called for image-based user sync */ -export const userSyncImageUrl = env => url.format({ +export const userSyncImageUrl = env => buildUrl({ protocol: (env === DEVELOPMENT) ? 'http' : 'https', hostname: domain(env), pathname: USER_SYNC_IMAGE_PATH @@ -508,12 +508,12 @@ export const spec = { bidderRequest), interpretResponse: interpretResponse, onBidWon: (bidObject) => - triggerPixel(url.format(onBidWon( + triggerPixel(buildUrl(onBidWon( resolveEnv(config.getConfig(), getParameterByName('emoteevEnv')), storage.getCookie('_pubcid'), bidObject))), onTimeout: (bidRequest) => - triggerPixel(url.format(onTimeout( + triggerPixel(buildUrl(onTimeout( resolveEnv(config.getConfig(), getParameterByName('emoteevEnv')), bidRequest))), getUserSyncs: (syncOptions) => diff --git a/modules/emx_digitalBidAdapter.js b/modules/emx_digitalBidAdapter.js index 22a7bb6f643..83689aa76f1 100644 --- a/modules/emx_digitalBidAdapter.js +++ b/modules/emx_digitalBidAdapter.js @@ -3,7 +3,6 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { Renderer } from '../src/Renderer.js'; import includes from 'core-js/library/fn/array/includes.js'; -import {parse as parseUrl} from '../src/url.js'; const BIDDER_CODE = 'emx_digital'; const ENDPOINT = 'hb.emxdgt.com'; @@ -130,7 +129,7 @@ export const emxAdapter = { } }, getSite: (refInfo) => { - let url = parseUrl(refInfo.referer); + let url = utils.parseUrl(refInfo.referer); return { domain: url.hostname, page: refInfo.referer, diff --git a/modules/fintezaAnalyticsAdapter.js b/modules/fintezaAnalyticsAdapter.js index f454e6b3acb..8729035491f 100644 --- a/modules/fintezaAnalyticsAdapter.js +++ b/modules/fintezaAnalyticsAdapter.js @@ -2,7 +2,6 @@ import { ajax } from '../src/ajax.js'; import adapter from '../src/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import * as utils from '../src/utils.js'; -import { parse as parseURL } from '../src/url.js'; import { getStorageManager } from '../src/storageManager.js'; const storage = getStorageManager(); @@ -29,7 +28,7 @@ function getPageInfo() { } if (document.referrer) { - pageInfo.referrerDomain = parseURL(document.referrer).hostname; + pageInfo.referrerDomain = utils.parseUrl(document.referrer).hostname; } return pageInfo; diff --git a/modules/konduitWrapper.js b/modules/konduitWrapper.js index c4cb4c8ff81..33bc45f7566 100644 --- a/modules/konduitWrapper.js +++ b/modules/konduitWrapper.js @@ -1,6 +1,5 @@ import { registerVideoSupport } from '../src/adServerManager.js'; import { targeting } from '../src/targeting.js'; -import { format as buildUrl } from '../src/url.js'; import * as utils from '../src/utils.js'; import { config } from '../src/config.js'; @@ -52,7 +51,7 @@ export function buildVastUrl(options) { let resultingUrl = null; if (queryParams.konduit_url) { - resultingUrl = buildUrl({ + resultingUrl = utils.buildUrl({ protocol: 'https', host: 'p.konduit.me', pathname: '/api/vastProxy', diff --git a/modules/medianetAnalyticsAdapter.js b/modules/medianetAnalyticsAdapter.js index 35a050831f3..3da69be92eb 100644 --- a/modules/medianetAnalyticsAdapter.js +++ b/modules/medianetAnalyticsAdapter.js @@ -4,7 +4,6 @@ import CONSTANTS from '../src/constants.json'; import * as utils from '../src/utils.js'; import { ajax } from '../src/ajax.js'; import { getRefererInfo } from '../src/refererDetection.js'; -import * as url from '../src/url.js'; import { getPriceGranularity, AUCTION_IN_PROGRESS, AUCTION_COMPLETED } from '../src/auction.js' const analyticsType = 'endpoint'; @@ -120,7 +119,7 @@ class Configure { init() { // Forces Logging % to 100% - let urlObj = url.parse(pageDetails.page); + let urlObj = utils.parseUrl(pageDetails.page); if (utils.deepAccess(urlObj, 'search.medianet_test') || urlObj.hostname === 'localhost') { this.loggingPercent = 100; this.ajaxState = CONFIG_PASS; @@ -144,7 +143,7 @@ class PageDetail { const twitterUrl = this._getUrlFromSelector('meta[name="twitter:url"]', 'content'); const refererInfo = getRefererInfo(); - this.domain = url.parse(refererInfo.referer).host; + this.domain = utils.parseUrl(refererInfo.referer).host; this.page = refererInfo.referer; this.is_top = refererInfo.reachedTop; this.referrer = this._getTopWindowReferrer(); diff --git a/modules/medianetBidAdapter.js b/modules/medianetBidAdapter.js index d944f354c83..a7434cac6ab 100644 --- a/modules/medianetBidAdapter.js +++ b/modules/medianetBidAdapter.js @@ -1,7 +1,6 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import * as utils from '../src/utils.js'; import { config } from '../src/config.js'; -import * as url from '../src/url.js'; import { BANNER, NATIVE } from '../src/mediaTypes.js'; import { getRefererInfo } from '../src/refererDetection.js'; @@ -22,7 +21,7 @@ let refererInfo = getRefererInfo(); let mnData = {}; mnData.urlData = { - domain: url.parse(refererInfo.referer).host, + domain: utils.parseUrl(refererInfo.referer).host, page: refererInfo.referer, isTop: refererInfo.reachedTop } @@ -287,7 +286,7 @@ function logEvent (event, data) { hostname: EVENT_PIXEL_URL, search: getLoggingData(event, data) }; - utils.triggerPixel(url.format(getParams)); + utils.triggerPixel(utils.buildUrl(getParams)); } function clearMnData() { diff --git a/modules/mgidBidAdapter.js b/modules/mgidBidAdapter.js index 194a8255641..957b9a1d703 100644 --- a/modules/mgidBidAdapter.js +++ b/modules/mgidBidAdapter.js @@ -1,6 +1,5 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import * as utils from '../src/utils.js'; -import * as urlUtils from '../src/url.js'; import {BANNER, NATIVE} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; import { getStorageManager } from '../src/storageManager.js'; @@ -123,7 +122,7 @@ export const spec = { } const info = pageInfo(); const page = info.location || utils.deepAccess(bidderRequest, 'refererInfo.referer') || utils.deepAccess(bidderRequest, 'refererInfo.canonicalUrl'); - const hostname = urlUtils.parse(page).hostname; + const hostname = utils.parseUrl(page).hostname; let domain = extractDomainFromHost(hostname) || hostname; const accountId = setOnAny(validBidRequests, 'params.accountId'); const muid = getLocalStorageSafely('mgMuidn'); diff --git a/modules/mytargetBidAdapter.js b/modules/mytargetBidAdapter.js index 24ad488d382..bcf8e7ad17f 100644 --- a/modules/mytargetBidAdapter.js +++ b/modules/mytargetBidAdapter.js @@ -1,5 +1,4 @@ import * as utils from '../src/utils.js'; -import * as url from '../src/url.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; @@ -29,7 +28,7 @@ function getSiteName(referrer) { let sitename = config.getConfig('mytarget.sitename'); if (!sitename) { - sitename = url.parse(referrer).hostname; + sitename = utils.parseUrl(referrer).hostname; } return sitename; diff --git a/modules/nafdigitalBidAdapter.js b/modules/nafdigitalBidAdapter.js index 2be845d6fdd..d64e079b52a 100644 --- a/modules/nafdigitalBidAdapter.js +++ b/modules/nafdigitalBidAdapter.js @@ -1,5 +1,4 @@ import * as utils from '../src/utils.js'; -import * as url from '../src/url.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; @@ -56,7 +55,7 @@ function buildRequests(bidReqs, bidderRequest) { id: utils.getUniqueIdentifierStr(), imp: nafdigitalImps, site: { - domain: url.parse(referrer).host, + domain: utils.parseUrl(referrer).host, page: referrer, publisher: { id: publisherId diff --git a/modules/nextrollBidAdapter.js b/modules/nextrollBidAdapter.js index e85efceba68..81c48102bb4 100644 --- a/modules/nextrollBidAdapter.js +++ b/modules/nextrollBidAdapter.js @@ -1,7 +1,6 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; -import { parse as parseUrl } from '../src/url.js'; import find from 'core-js/library/fn/array/find.js'; @@ -30,7 +29,7 @@ export const spec = { * @return ServerRequest Info describing the request to the server. */ buildRequests: function (validBidRequests, bidderRequest) { - let topLocation = parseUrl(utils.deepAccess(bidderRequest, 'refererInfo.referer')); + let topLocation = utils.parseUrl(utils.deepAccess(bidderRequest, 'refererInfo.referer')); let consent = hasCCPAConsent(bidderRequest); return validBidRequests.map((bidRequest, index) => { return { diff --git a/modules/openxBidAdapter.js b/modules/openxBidAdapter.js index a469a71ecb2..c4a90fb0930 100644 --- a/modules/openxBidAdapter.js +++ b/modules/openxBidAdapter.js @@ -2,7 +2,6 @@ import {config} from '../src/config.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import * as utils from '../src/utils.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {parse} from '../src/url.js'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BIDDER_CODE = 'openx'; @@ -424,7 +423,7 @@ function createVideoBidResponses(response, {bid, startTime}) { let bidResponses = []; if (response !== undefined && response.vastUrl !== '' && response.pub_rev !== '') { - let vastQueryParams = parse(response.vastUrl).search || {}; + let vastQueryParams = utils.parseUrl(response.vastUrl).search || {}; let bidResponse = {}; bidResponse.requestId = bid.bidId; // default 5 mins diff --git a/modules/priceFloors.js b/modules/priceFloors.js index 2ee5fb3b0fd..0accd48d003 100644 --- a/modules/priceFloors.js +++ b/modules/priceFloors.js @@ -7,7 +7,6 @@ import CONSTANTS from '../src/constants.json'; import { getHook } from '../src/hook.js'; import { createBid } from '../src/bidfactory.js'; import find from 'core-js/library/fn/array/find.js'; -import { parse as urlParse } from '../src/url.js'; import { getRefererInfo } from '../src/refererDetection.js'; /** @@ -61,7 +60,7 @@ function roundUp(number, precision) { let referrerHostname; function getHostNameFromReferer(referer) { - referrerHostname = urlParse(referer, {noDecodeWholeURL: true}).hostname; + referrerHostname = utils.parseUrl(referer, {noDecodeWholeURL: true}).hostname; return referrerHostname; } diff --git a/modules/pubCommonId.js b/modules/pubCommonId.js index d69ce0f2086..174fa6ffe6e 100644 --- a/modules/pubCommonId.js +++ b/modules/pubCommonId.js @@ -6,7 +6,6 @@ import * as utils from '../src/utils.js'; import { config } from '../src/config.js'; import events from '../src/events.js'; -import * as url from '../src/url.js'; import CONSTANTS from '../src/constants.json'; import { getStorageManager } from '../src/storageManager.js'; @@ -142,9 +141,9 @@ function queuePixelCallback(pixelUrl, id) { id = id || ''; // Use pubcid as a cache buster - const urlInfo = url.parse(pixelUrl); + const urlInfo = utils.parseUrl(pixelUrl); urlInfo.search.id = encodeURIComponent('pubcid:' + id); - const targetUrl = url.format(urlInfo); + const targetUrl = utils.buildUrl(urlInfo); events.on(CONSTANTS.EVENTS.AUCTION_END, function auctionEndHandler() { events.off(CONSTANTS.EVENTS.AUCTION_END, auctionEndHandler); diff --git a/modules/pubCommonIdSystem.js b/modules/pubCommonIdSystem.js index b12d981c2ba..8e2be1207f5 100644 --- a/modules/pubCommonIdSystem.js +++ b/modules/pubCommonIdSystem.js @@ -6,7 +6,6 @@ */ import * as utils from '../src/utils.js'; -import * as url from '../src/url.js'; import {submodule} from '../src/hook.js'; const PUB_COMMON_ID = 'PublisherCommonId'; @@ -32,9 +31,9 @@ export const pubCommonIdSubmodule = { } // Use pubcid as a cache buster - const urlInfo = url.parse(pixelUrl); + const urlInfo = utils.parseUrl(pixelUrl); urlInfo.search.id = encodeURIComponent('pubcid:' + id); - const targetUrl = url.format(urlInfo); + const targetUrl = utils.buildUrl(urlInfo); return function () { utils.triggerPixel(targetUrl); diff --git a/modules/readpeakBidAdapter.js b/modules/readpeakBidAdapter.js index 56006aea144..c72bbdd658f 100644 --- a/modules/readpeakBidAdapter.js +++ b/modules/readpeakBidAdapter.js @@ -1,8 +1,7 @@ -import { logError, replaceAuctionPrice } from '../src/utils.js'; +import { logError, replaceAuctionPrice, parseUrl } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; import { NATIVE } from '../src/mediaTypes.js'; -import { parse as parseUrl } from '../src/url.js'; export const ENDPOINT = 'https://app.readpeak.com/header/prebid'; diff --git a/modules/rubiconAnalyticsAdapter.js b/modules/rubiconAnalyticsAdapter.js index 80c881f479a..28c11ef8264 100644 --- a/modules/rubiconAnalyticsAdapter.js +++ b/modules/rubiconAnalyticsAdapter.js @@ -4,7 +4,6 @@ import CONSTANTS from '../src/constants.json'; import { ajax } from '../src/ajax.js'; import { config } from '../src/config.js'; import * as utils from '../src/utils.js'; -import * as urlLib from '../src/url.js' import { getGlobal } from '../src/prebidGlobal.js'; const { @@ -43,7 +42,7 @@ const cache = { export function getHostNameFromReferer(referer) { try { - rubiconAdapter.referrerHostname = urlLib.parse(referer, {noDecodeWholeURL: true}).hostname; + rubiconAdapter.referrerHostname = utils.parseUrl(referer, {noDecodeWholeURL: true}).hostname; } catch (e) { utils.logError('Rubicon Analytics: Unable to parse hostname from supplied url: ', referer, e); rubiconAdapter.referrerHostname = ''; diff --git a/modules/sortableBidAdapter.js b/modules/sortableBidAdapter.js index 9fbb02ad08f..f5d3a6b1bb5 100644 --- a/modules/sortableBidAdapter.js +++ b/modules/sortableBidAdapter.js @@ -1,7 +1,6 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; -import { parse } from '../src/url.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'sortable'; @@ -157,7 +156,7 @@ export const spec = { buildRequests: function(validBidReqs, bidderRequest) { const sortableConfig = config.getConfig('sortable') || {}; const globalSiteId = sortableConfig.siteId; - let loc = parse(bidderRequest.refererInfo.referer); + let loc = utils.parseUrl(bidderRequest.refererInfo.referer); const sortableImps = utils._map(validBidReqs, bid => { const rv = { diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js index 2566f314018..98c8c8e3b33 100644 --- a/modules/sovrnBidAdapter.js +++ b/modules/sovrnBidAdapter.js @@ -1,5 +1,4 @@ import * as utils from '../src/utils.js' -import {parse} from '../src/url.js' import { registerBidder } from '../src/adapters/bidderFactory.js' import { BANNER } from '../src/mediaTypes.js' @@ -62,7 +61,7 @@ export const spec = { const page = bidderRequest.refererInfo.referer // clever trick to get the domain - const domain = parse(page).hostname + const domain = utils.parseUrl(page).hostname const sovrnBidReq = { id: utils.getUniqueIdentifierStr(), diff --git a/modules/staqAnalyticsAdapter.js b/modules/staqAnalyticsAdapter.js index 31b231637f4..4e3914bccdd 100644 --- a/modules/staqAnalyticsAdapter.js +++ b/modules/staqAnalyticsAdapter.js @@ -2,7 +2,6 @@ import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; import adapterManager from '../src/adapterManager.js'; import { getRefererInfo } from '../src/refererDetection.js'; -import { parse } from '../src/url.js'; import * as utils from '../src/utils.js'; import { ajax } from '../src/ajax.js'; import { getStorageManager } from '../src/storageManager.js'; @@ -249,7 +248,7 @@ export function getUmtSource(pageUrl, referrer) { if (se) { return asUtm(se, ORGANIC, ORGANIC); } - let parsedUrl = parse(pageUrl); + let parsedUrl = utils.parseUrl(pageUrl); let [refHost, refPath] = getReferrer(referrer); if (refHost && refHost !== parsedUrl.hostname) { return asUtm(refHost, REFERRAL, REFERRAL, '', refPath); @@ -276,12 +275,12 @@ export function getUmtSource(pageUrl, referrer) { } function getReferrer(referrer) { - let ref = parse(referrer); + let ref = utils.parseUrl(referrer); return [ref.hostname, ref.pathname]; } function getUTM(pageUrl) { - let urlParameters = parse(pageUrl).search; + let urlParameters = utils.parseUrl(pageUrl).search; if (!urlParameters['utm_campaign'] || !urlParameters['utm_source']) { return; } diff --git a/modules/theAdxBidAdapter.js b/modules/theAdxBidAdapter.js index 5306b89a5da..91e36077e88 100644 --- a/modules/theAdxBidAdapter.js +++ b/modules/theAdxBidAdapter.js @@ -7,9 +7,6 @@ import { import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { - parse as parseUrl -} from '../src/url.js'; const BIDDER_CODE = 'theadx'; const ENDPOINT_URL = 'https://ssp.theadx.com/request'; @@ -317,7 +314,7 @@ export const spec = { } let buildSiteComponent = (bidRequest, bidderRequest) => { - let loc = parseUrl(bidderRequest.refererInfo.referer, { + let loc = utils.parseUrl(bidderRequest.refererInfo.referer, { decodeSearchAsString: true }); diff --git a/modules/tpmnBidAdapter.js b/modules/tpmnBidAdapter.js index d80c87987fa..ec9d30c0e29 100644 --- a/modules/tpmnBidAdapter.js +++ b/modules/tpmnBidAdapter.js @@ -2,7 +2,6 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import * as utils from '../src/utils.js'; import { BANNER } from '../src/mediaTypes.js'; -import {parse as parseUrl} from '../src/url.js'; export const ADAPTER_VERSION = '1'; const SUPPORTED_AD_TYPES = [BANNER]; @@ -73,7 +72,7 @@ registerBidder(spec); * Creates site description object */ function createSite(refInfo) { - let url = parseUrl(refInfo.referer); + let url = utils.parseUrl(refInfo.referer); let site = { 'domain': url.hostname, 'page': url.protocol + '://' + url.hostname + url.pathname diff --git a/modules/undertoneBidAdapter.js b/modules/undertoneBidAdapter.js index 923e54183ab..6ead453b622 100644 --- a/modules/undertoneBidAdapter.js +++ b/modules/undertoneBidAdapter.js @@ -2,7 +2,7 @@ * Adapter to send bids to Undertone */ -import * as urlUtils from '../src/url.js'; +import { parseUrl } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'undertone'; @@ -92,7 +92,7 @@ export const spec = { } }; const referer = bidderRequest.refererInfo.referer; - const hostname = urlUtils.parse(referer).hostname; + const hostname = parseUrl(referer).hostname; let domain = extractDomainFromHost(hostname); const pageUrl = getCanonicalUrl() || referer; diff --git a/modules/yuktamediaAnalyticsAdapter.js b/modules/yuktamediaAnalyticsAdapter.js index 268f31ea402..b346a26c843 100644 --- a/modules/yuktamediaAnalyticsAdapter.js +++ b/modules/yuktamediaAnalyticsAdapter.js @@ -2,7 +2,6 @@ import { ajax } from '../src/ajax.js'; import adapter from '../src/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import CONSTANTS from '../src/constants.json'; -import * as url from '../src/url.js'; import * as utils from '../src/utils.js'; const emptyUrl = ''; @@ -115,7 +114,7 @@ function send(data, status) { } data.initOptions = initOptions; - let yuktamediaAnalyticsRequestUrl = url.format({ + let yuktamediaAnalyticsRequestUrl = utils.buildUrl({ protocol: 'https', hostname: 'analytics-prebid.yuktamedia.com', pathname: status == 'auctionEnd' ? '/api/bids' : '/api/bid/won', diff --git a/src/adserver.js b/src/adserver.js index c189037a9da..61af8862972 100644 --- a/src/adserver.js +++ b/src/adserver.js @@ -1,4 +1,4 @@ -import { formatQS } from './url.js'; +import { formatQS } from './utils.js'; import { targeting } from './targeting.js'; // Adserver parent class diff --git a/src/ajax.js b/src/ajax.js index 16f7b365092..b1e4cbdbdff 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -1,4 +1,3 @@ -import {parse as parseURL, format as formatURL} from './url.js'; import { config } from './config.js'; var utils = require('./utils.js'); @@ -61,9 +60,9 @@ export function ajaxBuilder(timeout = 3000, {request, done} = {}) { } if (method === 'GET' && data) { - let urlInfo = parseURL(url, options); + let urlInfo = utils.parseUrl(url, options); Object.assign(urlInfo.search, data); - url = formatURL(urlInfo); + url = utils.buildUrl(urlInfo); } x.open(method, url, true); diff --git a/src/auction.js b/src/auction.js index 628c164a537..d953763cea8 100644 --- a/src/auction.js +++ b/src/auction.js @@ -57,8 +57,7 @@ * @property {function(): void} callBids - sends requests to all adapters for bids */ -import {flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue} from './utils.js'; -import { parse as parseURL } from './url.js'; +import {flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue, parseUrl} from './utils.js'; import { getPriceBucketString } from './cpmBucketManager.js'; import { getNativeTargeting } from './native.js'; import { getCacheUrl, store } from './videoCache.js'; @@ -651,7 +650,7 @@ export function getStandardBidderSettings(mediaType, bidderCode, bidReq) { // Adding hb_cache_host if (config.getConfig('cache.url') && (!bidderCode || utils.deepAccess(bidderSettings, `${bidderCode}.sendStandardTargeting`) !== false)) { - const urlInfo = parseURL(config.getConfig('cache.url')); + const urlInfo = parseUrl(config.getConfig('cache.url')); if (typeof find(adserverTargeting, targetingKeyVal => targetingKeyVal.key === TARGETING_KEYS.CACHE_HOST) === 'undefined') { adserverTargeting.push(createKeyVal(TARGETING_KEYS.CACHE_HOST, function(bidResponse) { diff --git a/src/config.js b/src/config.js index 24962bdff37..521171cbf7d 100644 --- a/src/config.js +++ b/src/config.js @@ -16,13 +16,12 @@ import { isValidPriceConfig } from './cpmBucketManager.js'; import find from 'core-js/library/fn/array/find.js'; import includes from 'core-js/library/fn/array/includes.js'; import Set from 'core-js/library/fn/set.js'; -import { parseQS } from './url.js'; const from = require('core-js/library/fn/array/from.js'); const utils = require('./utils.js'); const CONSTANTS = require('./constants.json'); -const DEFAULT_DEBUG = (parseQS(window.location.search)[CONSTANTS.DEBUG_MODE] || '').toUpperCase() === 'TRUE'; +const DEFAULT_DEBUG = utils.getParameterByName(CONSTANTS.DEBUG_MODE).toUpperCase() === 'TRUE'; const DEFAULT_BIDDER_TIMEOUT = 3000; const DEFAULT_PUBLISHER_DOMAIN = window.location.origin; const DEFAULT_ENABLE_SEND_ALL_BIDS = true; diff --git a/src/events.js b/src/events.js index 2d99ed4c561..e7a11635476 100644 --- a/src/events.js +++ b/src/events.js @@ -113,14 +113,14 @@ module.exports = (function () { utils._each(event[id].que, function (_handler) { var que = event[id].que; if (_handler === handler) { - que.splice(utils.indexOf.call(que, _handler), 1); + que.splice(que.indexOf(_handler), 1); } }); } else { utils._each(event.que, function (_handler) { var que = event.que; if (_handler === handler) { - que.splice(utils.indexOf.call(que, _handler), 1); + que.splice(que.indexOf(_handler), 1); } }); } diff --git a/src/url.js b/src/url.js deleted file mode 100644 index c63bca2ca41..00000000000 --- a/src/url.js +++ /dev/null @@ -1,55 +0,0 @@ -export function parseQS(query) { - return !query ? {} : query - .replace(/^\?/, '') - .split('&') - .reduce((acc, criteria) => { - let [k, v] = criteria.split('='); - if (/\[\]$/.test(k)) { - k = k.replace('[]', ''); - acc[k] = acc[k] || []; - acc[k].push(v); - } else { - acc[k] = v || ''; - } - return acc; - }, {}); -} - -export function formatQS(query) { - return Object - .keys(query) - .map(k => Array.isArray(query[k]) - ? query[k].map(v => `${k}[]=${v}`).join('&') - : `${k}=${query[k]}`) - .join('&'); -} - -export function parse(url, options) { - let parsed = document.createElement('a'); - if (options && 'noDecodeWholeURL' in options && options.noDecodeWholeURL) { - parsed.href = url; - } else { - parsed.href = decodeURIComponent(url); - } - // in window.location 'search' is string, not object - let qsAsString = (options && 'decodeSearchAsString' in options && options.decodeSearchAsString); - return { - href: parsed.href, - protocol: (parsed.protocol || '').replace(/:$/, ''), - hostname: parsed.hostname, - port: +parsed.port, - pathname: parsed.pathname.replace(/^(?!\/)/, '/'), - search: (qsAsString) ? parsed.search : parseQS(parsed.search || ''), - hash: (parsed.hash || '').replace(/^#/, ''), - host: parsed.host || window.location.host - }; -} - -export function format(obj) { - return (obj.protocol || 'http') + '://' + - (obj.host || - obj.hostname + (obj.port ? `:${obj.port}` : '')) + - (obj.pathname || '') + - (obj.search ? `?${formatQS(obj.search || '')}` : '') + - (obj.hash ? `#${obj.hash}` : ''); -} diff --git a/src/utils.js b/src/utils.js index 45822dd7088..0fe924510e0 100644 --- a/src/utils.js +++ b/src/utils.js @@ -38,6 +38,8 @@ export const internal = { logWarn, logMessage, logInfo, + parseQS, + formatQS, deepEqual }; @@ -52,28 +54,6 @@ export let bind = function(a, b) { return b; }.bind(null, 1, uniqueRef)() === un }; }; -/* - * Substitutes into a string from a given map using the token - * Usage - * var str = 'text %%REPLACE%% this text with %%SOMETHING%%'; - * var map = {}; - * map['replace'] = 'it was subbed'; - * map['something'] = 'something else'; - * console.log(replaceTokenInString(str, map, '%%')); => "text it was subbed this text with something else" - */ -export function replaceTokenInString(str, map, token) { - _each(map, function (value, key) { - value = (value === undefined) ? '' : value; - - var keyString = token + key.toUpperCase() + token; - var re = new RegExp(keyString, 'g'); - - str = str.replace(re, value); - }); - - return str; -} - /* utility method to get incremental integer starting from 1 */ var getIncrementalInteger = (function () { var count = 0; @@ -122,7 +102,7 @@ export function getBidIdParameter(key, paramsObj) { export function tryAppendQueryString(existingUrl, key, value) { if (value) { - return existingUrl += key + '=' + encodeURIComponent(value) + '&'; + return existingUrl + key + '=' + encodeURIComponent(value) + '&'; } return existingUrl; @@ -130,14 +110,8 @@ export function tryAppendQueryString(existingUrl, key, value) { // parse a query string object passed in bid params // bid params should be an object such as {key: "value", key1 : "value1"} -export function parseQueryStringParameters(queryObj) { - let result = ''; - for (var k in queryObj) { - if (queryObj.hasOwnProperty(k)) { result += k + '=' + encodeURIComponent(queryObj[k]) + '&'; } - } - - return result; -} +// aliases to formatQS +export let parseQueryStringParameters = internal.formatQS; // transform an AdServer targeting bids into a query string to send to the adserver export function transformAdServerTargetingObj(targeting) { @@ -291,10 +265,6 @@ function decorateLog(args, prefix) { return args; } -export function hasConsoleLogger() { - return consoleLogExists; -} - export function debugTurnedOn() { return !!config.getConfig('debug'); } @@ -322,53 +292,9 @@ export function createInvisibleIframe() { * and if it does return the value */ export function getParameterByName(name) { - var regexS = '[\\?&]' + name + '=([^&#]*)'; - var regex = new RegExp(regexS); - var results = regex.exec(window.location.search); - if (results === null) { - return ''; - } - - return decodeURIComponent(results[1].replace(/\+/g, ' ')); + return parseQS(getWindowLocation().search)[name] || ''; } -/** - * This function validates paramaters. - * @param {Object} paramObj [description] - * @param {string[]} requiredParamsArr [description] - * @return {boolean} Bool if paramaters are valid - */ -export function hasValidBidRequest(paramObj, requiredParamsArr, adapter) { - var found = false; - - function findParam(value, key) { - if (key === requiredParamsArr[i]) { - found = true; - } - } - - for (var i = 0; i < requiredParamsArr.length; i++) { - found = false; - - _each(paramObj, findParam); - - if (!found) { - logError('Params are missing for bid request. One of these required paramaters are missing: ' + requiredParamsArr, adapter); - return false; - } - } - - return true; -} - -// Handle addEventListener gracefully in older browsers -export function addEventHandler(element, event, func) { - if (element.addEventListener) { - element.addEventListener(event, func, true); - } else if (element.attachEvent) { - element.attachEvent('on' + event, func); - } -} /** * Return if the object is of the * given type. @@ -473,15 +399,6 @@ export function contains(a, obj) { return false; } -export let indexOf = (function () { - if (Array.prototype.indexOf) { - return Array.prototype.indexOf; - } - - // ie8 no longer supported - // return polyfills.indexOf; -}()); - /** * Map an array or object into another array * given a function @@ -649,32 +566,6 @@ export function createTrackPixelIframeHtml(url, encodeUri = true, sandbox = '') `; } -/** - * Returns iframe document in a browser agnostic way - * @param {Object} iframe reference - * @return {Object} iframe `document` reference - */ -export function getIframeDocument(iframe) { - if (!iframe) { - return; - } - - let doc; - try { - if (iframe.contentWindow) { - doc = iframe.contentWindow.document; - } else if (iframe.contentDocument.document) { - doc = iframe.contentDocument.document; - } else { - doc = iframe.contentDocument; - } - } catch (e) { - internal.logError('Cannot get iframe document', e); - } - - return doc; -} - export function getValueString(param, val, defaultValue) { if (val === undefined || val === null) { return defaultValue; @@ -794,16 +685,6 @@ export function adUnitsFilter(filter, bid) { return includes(filter, bid && bid.adUnitCode); } -/** - * Check if parent iframe of passed document supports content rendering via 'srcdoc' property - * @param {HTMLDocument} doc document to check support of 'srcdoc' - */ -export function isSrcdocSupported(doc) { - // Firefox is excluded due to https://bugzilla.mozilla.org/show_bug.cgi?id=1265961 - return doc.defaultView && doc.defaultView.frameElement && - 'srcdoc' in doc.defaultView.frameElement && !/firefox/i.test(navigator.userAgent); -} - export function deepClone(obj) { return clone(obj); } @@ -885,19 +766,6 @@ export function groupBy(xs, key) { }, {}); } -/** - * Returns content for a friendly iframe to execute a URL in script tag - * @param {string} url URL to be executed in a script tag in a friendly iframe - * and are macros left to be replaced if required - */ -export function createContentToExecuteExtScriptInFriendlyFrame(url) { - if (!url) { - return ''; - } - - return ``; -} - /** * Build an object consisting of only defined parameters to avoid creating an * object with defined keys and undefined values. @@ -1034,18 +902,6 @@ export function unsupportedBidderMessage(adUnit, bidder) { `; } -/** - * Delete property from object - * @param {Object} object - * @param {string} prop - * @return {Object} object - */ -export function deletePropertyFromObject(object, prop) { - let result = Object.assign({}, object); - delete result[prop]; - return result; -} - /** * Checks input is integer or not * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger @@ -1245,6 +1101,62 @@ export function compareOn(property) { } } +export function parseQS(query) { + return !query ? {} : query + .replace(/^\?/, '') + .split('&') + .reduce((acc, criteria) => { + let [k, v] = criteria.split('='); + if (/\[\]$/.test(k)) { + k = k.replace('[]', ''); + acc[k] = acc[k] || []; + acc[k].push(v); + } else { + acc[k] = v || ''; + } + return acc; + }, {}); +} + +export function formatQS(query) { + return Object + .keys(query) + .map(k => Array.isArray(query[k]) + ? query[k].map(v => `${k}[]=${v}`).join('&') + : `${k}=${query[k]}`) + .join('&'); +} + +export function parseUrl(url, options) { + let parsed = document.createElement('a'); + if (options && 'noDecodeWholeURL' in options && options.noDecodeWholeURL) { + parsed.href = url; + } else { + parsed.href = decodeURIComponent(url); + } + // in window.location 'search' is string, not object + let qsAsString = (options && 'decodeSearchAsString' in options && options.decodeSearchAsString); + return { + href: parsed.href, + protocol: (parsed.protocol || '').replace(/:$/, ''), + hostname: parsed.hostname, + port: +parsed.port, + pathname: parsed.pathname.replace(/^(?!\/)/, '/'), + search: (qsAsString) ? parsed.search : internal.parseQS(parsed.search || ''), + hash: (parsed.hash || '').replace(/^#/, ''), + host: parsed.host || window.location.host + }; +} + +export function buildUrl(obj) { + return (obj.protocol || 'http') + '://' + + (obj.host || + obj.hostname + (obj.port ? `:${obj.port}` : '')) + + (obj.pathname || '') + + (obj.search ? `?${internal.formatQS(obj.search || '')}` : '') + + (obj.hash ? `#${obj.hash}` : ''); +} + /** * This function compares two objects for checking their equivalence. * @param {Object} obj1 diff --git a/test/spec/modules/adformBidAdapter_spec.js b/test/spec/modules/adformBidAdapter_spec.js index 8b7ecb3f9a7..9233ca1dd7a 100644 --- a/test/spec/modules/adformBidAdapter_spec.js +++ b/test/spec/modules/adformBidAdapter_spec.js @@ -1,5 +1,4 @@ import {assert, expect} from 'chai'; -import * as url from 'src/url.js'; import {spec} from 'modules/adformBidAdapter.js'; import { BANNER, VIDEO } from 'src/mediaTypes.js'; import { config } from 'src/config.js'; diff --git a/test/spec/modules/adformOpenRTBBidAdapter_spec.js b/test/spec/modules/adformOpenRTBBidAdapter_spec.js index caa2fc56208..77dbc17cdb2 100644 --- a/test/spec/modules/adformOpenRTBBidAdapter_spec.js +++ b/test/spec/modules/adformOpenRTBBidAdapter_spec.js @@ -1,6 +1,5 @@ // jshint esversion: 6, es3: false, node: true import {assert, expect} from 'chai'; -import * as url from 'src/url.js'; import {spec} from 'modules/adformOpenRTBBidAdapter.js'; import { NATIVE } from 'src/mediaTypes.js'; import { config } from 'src/config.js'; diff --git a/test/spec/modules/adxcgBidAdapter_spec.js b/test/spec/modules/adxcgBidAdapter_spec.js index 3ec6a19d20b..306914960c3 100644 --- a/test/spec/modules/adxcgBidAdapter_spec.js +++ b/test/spec/modules/adxcgBidAdapter_spec.js @@ -1,7 +1,6 @@ import {expect} from 'chai'; -import * as url from 'src/url.js'; import {spec} from 'modules/adxcgBidAdapter.js'; -import {deepClone} from '../../../src/utils.js'; +import {deepClone, parseUrl} from 'src/utils.js'; describe('AdxcgAdapter', function () { let bidBanner = { @@ -119,7 +118,7 @@ describe('AdxcgAdapter', function () { let request = spec.buildRequests([bidBanner]); expect(request).to.exist; expect(request.method).to.equal('GET'); - let parsedRequestUrl = url.parse(request.url); + let parsedRequestUrl = parseUrl(request.url); expect(parsedRequestUrl.hostname).to.equal('hbps.adxcg.net'); expect(parsedRequestUrl.pathname).to.equal('/get/adi'); @@ -152,7 +151,7 @@ describe('AdxcgAdapter', function () { let request = spec.buildRequests([bidVideo]); expect(request).to.exist; expect(request.method).to.equal('GET'); - let parsedRequestUrl = url.parse(request.url); + let parsedRequestUrl = parseUrl(request.url); expect(parsedRequestUrl.hostname).to.equal('hbps.adxcg.net'); expect(parsedRequestUrl.pathname).to.equal('/get/adi'); @@ -191,7 +190,7 @@ describe('AdxcgAdapter', function () { let request = spec.buildRequests([bidNative]); expect(request).to.exist; expect(request.method).to.equal('GET'); - let parsedRequestUrl = url.parse(request.url); + let parsedRequestUrl = parseUrl(request.url); expect(parsedRequestUrl.hostname).to.equal('hbps.adxcg.net'); expect(parsedRequestUrl.pathname).to.equal('/get/adi'); @@ -229,7 +228,7 @@ describe('AdxcgAdapter', function () { consentString: 'consentDataString' } }); - let parsedRequestUrl = url.parse(request.url); + let parsedRequestUrl = parseUrl(request.url); let query = parsedRequestUrl.search; expect(query.gdpr).to.equal('1'); @@ -243,7 +242,7 @@ describe('AdxcgAdapter', function () { consentString: 'consentDataString' } }); - let parsedRequestUrl = url.parse(request.url); + let parsedRequestUrl = parseUrl(request.url); let query = parsedRequestUrl.search; expect(query.gdpr).to.be.undefined; @@ -258,7 +257,7 @@ describe('AdxcgAdapter', function () { it('should send pubcid if available', function () { let request = spec.buildRequests(bid, bidderRequests); - let parsedRequestUrl = url.parse(request.url); + let parsedRequestUrl = parseUrl(request.url); let query = parsedRequestUrl.search; expect(query.pubcid).to.equal('pubcidabcd'); }); @@ -272,7 +271,7 @@ describe('AdxcgAdapter', function () { it('should send pubcid if available', function () { let request = spec.buildRequests(bid, bidderRequests); - let parsedRequestUrl = url.parse(request.url); + let parsedRequestUrl = parseUrl(request.url); let query = parsedRequestUrl.search; expect(query.tdid).to.equal('tdidabcd'); }); @@ -286,7 +285,7 @@ describe('AdxcgAdapter', function () { it('should send pubcid if available', function () { let request = spec.buildRequests(bid, bidderRequests); - let parsedRequestUrl = url.parse(request.url); + let parsedRequestUrl = parseUrl(request.url); let query = parsedRequestUrl.search; expect(query.id5id).to.equal('id5idsample'); }); @@ -300,7 +299,7 @@ describe('AdxcgAdapter', function () { it('should send pubcid if available', function () { let request = spec.buildRequests(bid, bidderRequests); - let parsedRequestUrl = url.parse(request.url); + let parsedRequestUrl = parseUrl(request.url); let query = parsedRequestUrl.search; expect(query.idl_env).to.equal('idl_envsample'); }); diff --git a/test/spec/modules/adyoulikeBidAdapter_spec.js b/test/spec/modules/adyoulikeBidAdapter_spec.js index 0dd6b5ad065..3573681dd17 100644 --- a/test/spec/modules/adyoulikeBidAdapter_spec.js +++ b/test/spec/modules/adyoulikeBidAdapter_spec.js @@ -1,5 +1,4 @@ import { expect } from 'chai'; -import { parse } from '../../../src/url.js'; import { spec } from 'modules/adyoulikeBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; diff --git a/test/spec/modules/beachfrontBidAdapter_spec.js b/test/spec/modules/beachfrontBidAdapter_spec.js index 7879ed37dc0..f7dcc1305e5 100644 --- a/test/spec/modules/beachfrontBidAdapter_spec.js +++ b/test/spec/modules/beachfrontBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import sinon from 'sinon'; import { spec, VIDEO_ENDPOINT, BANNER_ENDPOINT, OUTSTREAM_SRC, DEFAULT_MIMES } from 'modules/beachfrontBidAdapter.js'; -import { parse as parseUrl } from 'src/url.js'; +import { parseUrl } from 'src/utils.js'; describe('BeachfrontAdapter', function () { let bidRequests; diff --git a/test/spec/modules/criteoIdSystem_spec.js b/test/spec/modules/criteoIdSystem_spec.js index 74caef69ccc..aa5807da0da 100644 --- a/test/spec/modules/criteoIdSystem_spec.js +++ b/test/spec/modules/criteoIdSystem_spec.js @@ -1,7 +1,6 @@ import { criteoIdSubmodule, storage } from 'modules/criteoIdSystem.js'; import * as utils from 'src/utils.js'; import * as ajaxLib from 'src/ajax.js'; -import * as urlLib from 'src/url.js'; const pastDateString = new Date(0).toString() @@ -34,7 +33,7 @@ describe('CriteoId module', function () { removeFromLocalStorageStub = sinon.stub(storage, 'removeDataFromLocalStorage'); timeStampStub = sinon.stub(utils, 'timestamp').returns(nowTimestamp); ajaxBuilderStub = sinon.stub(ajaxLib, 'ajaxBuilder').callsFake(mockResponse('{}')); - parseUrlStub = sinon.stub(urlLib, 'parse').returns({protocol: 'https', hostname: 'testdev.com'}) + parseUrlStub = sinon.stub(utils, 'parseUrl').returns({protocol: 'https', hostname: 'testdev.com'}) triggerPixelStub = sinon.stub(utils, 'triggerPixel'); done(); }); diff --git a/test/spec/modules/dfpAdServerVideo_spec.js b/test/spec/modules/dfpAdServerVideo_spec.js index 562c7eb297b..895416bae2b 100644 --- a/test/spec/modules/dfpAdServerVideo_spec.js +++ b/test/spec/modules/dfpAdServerVideo_spec.js @@ -2,7 +2,6 @@ import { expect } from 'chai'; import parse from 'url-parse'; import { buildDfpVideoUrl, buildAdpodVideoUrl } from 'modules/dfpAdServerVideo.js'; -import { parseQS } from 'src/url.js'; import adUnit from 'test/fixtures/video/adUnit.json'; import * as utils from 'src/utils.js'; import { config } from 'src/config.js'; @@ -33,7 +32,7 @@ describe('The DFP video support module', function () { expect(url.protocol).to.equal('https:'); expect(url.host).to.equal('securepubads.g.doubleclick.net'); - const queryParams = parseQS(url.query); + const queryParams = utils.parseQS(url.query); expect(queryParams).to.have.property('correlator'); expect(queryParams).to.have.property('description_url', 'someUrl.com'); expect(queryParams).to.have.property('env', 'vp'); @@ -57,7 +56,7 @@ describe('The DFP video support module', function () { expect(url.host).to.equal('video.adserver.example'); - const queryObject = parseQS(url.query); + const queryObject = utils.parseQS(url.query); expect(queryObject.description_url).to.equal('vastUrl.example'); }); @@ -78,7 +77,7 @@ describe('The DFP video support module', function () { params: { iu: 'my/adUnit' } })); - const queryObject = parseQS(url.query); + const queryObject = utils.parseQS(url.query); expect(queryObject.iu).to.equal('my/adUnit'); }); @@ -92,7 +91,7 @@ describe('The DFP video support module', function () { } })); - expect(parseQS(url.query)).to.have.property('output', 'vast'); + expect(utils.parseQS(url.query)).to.have.property('output', 'vast'); }); it('should include the cache key and adserver targeting in cust_params', function () { @@ -108,8 +107,8 @@ describe('The DFP video support module', function () { 'iu': 'my/adUnit' } })); - const queryObject = parseQS(url.query); - const customParams = parseQS('?' + decodeURIComponent(queryObject.cust_params)); + const queryObject = utils.parseQS(url.query); + const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); expect(customParams).to.have.property('hb_adid', 'ad_id'); expect(customParams).to.have.property('hb_uuid', bid.videoCacheKey); @@ -178,8 +177,8 @@ describe('The DFP video support module', function () { 'iu': 'my/adUnit' } })); - const queryObject = parseQS(url.query); - const customParams = parseQS('?' + decodeURIComponent(queryObject.cust_params)); + const queryObject = utils.parseQS(url.query); + const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); expect(customParams).to.have.property('hb_adid', 'ad_id'); expect(customParams).to.have.property('hb_uuid', bid.videoCacheKey); @@ -205,8 +204,8 @@ describe('The DFP video support module', function () { }, }, })); - const queryObject = parseQS(url.query); - const customParams = parseQS('?' + decodeURIComponent(queryObject.cust_params)); + const queryObject = utils.parseQS(url.query); + const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); expect(customParams).to.have.property('hb_adid', 'ad_id'); expect(customParams).to.have.property('my_targeting', 'foo'); @@ -224,8 +223,8 @@ describe('The DFP video support module', function () { url: 'https://video.adserver.example/ads?sz=640x480&iu=/123/aduniturl&impl=s&cust_params=section%3dblog%26mykey%3dmyvalue' })); - const queryObject = parseQS(url.query); - const customParams = parseQS('?' + decodeURIComponent(queryObject.cust_params)); + const queryObject = utils.parseQS(url.query); + const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); expect(customParams).to.have.property('hb_adid', 'ad_id'); expect(customParams).to.have.property('section', 'blog'); @@ -247,7 +246,7 @@ describe('The DFP video support module', function () { } })); - const queryObject = parseQS(url.query); + const queryObject = utils.parseQS(url.query); expect(queryObject.description_url).to.equal('descriptionurl.example'); }); @@ -272,8 +271,8 @@ describe('The DFP video support module', function () { 'iu': 'my/adUnit' } })); - const queryObject = parseQS(url.query); - const customParams = parseQS('?' + decodeURIComponent(queryObject.cust_params)); + const queryObject = utils.parseQS(url.query); + const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); expect(customParams).to.have.property('hb_uuid', bid.videoCacheKey); expect(customParams).to.have.property('hb_cache_id', bid.videoCacheKey); @@ -293,8 +292,8 @@ describe('The DFP video support module', function () { 'iu': 'my/adUnit' } })); - const queryObject = parseQS(url.query); - const customParams = parseQS('?' + decodeURIComponent(queryObject.cust_params)); + const queryObject = utils.parseQS(url.query); + const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); expect(customParams).to.have.property('hb_uuid', 'def'); expect(customParams).to.have.property('hb_cache_id', 'def'); @@ -370,7 +369,7 @@ describe('The DFP video support module', function () { expect(url.protocol).to.equal('https:'); expect(url.host).to.equal('securepubads.g.doubleclick.net'); - const queryParams = parseQS(url.query); + const queryParams = utils.parseQS(url.query); expect(queryParams).to.have.property('correlator'); expect(queryParams).to.have.property('description_url', 'someUrl.com'); expect(queryParams).to.have.property('env', 'vp'); @@ -382,7 +381,7 @@ describe('The DFP video support module', function () { expect(queryParams).to.have.property('url'); expect(queryParams).to.have.property('cust_params'); - const custParams = parseQS(decodeURIComponent(queryParams.cust_params)); + const custParams = utils.parseQS(decodeURIComponent(queryParams.cust_params)); expect(custParams).to.have.property('hb_cache_id', '123'); expect(custParams).to.have.property('hb_pb_cat_dur', '15.00_395_15s,15.00_406_30s,10.00_395_15s'); } @@ -424,7 +423,7 @@ describe('The DFP video support module', function () { expect(url.protocol).to.equal('https:'); expect(url.host).to.equal('securepubads.g.doubleclick.net'); - const queryParams = parseQS(url.query); + const queryParams = utils.parseQS(url.query); expect(queryParams).to.have.property('correlator'); expect(queryParams).to.have.property('description_url', 'someUrl.com'); expect(queryParams).to.have.property('env', 'vp'); @@ -436,7 +435,7 @@ describe('The DFP video support module', function () { expect(queryParams).to.have.property('url'); expect(queryParams).to.have.property('cust_params'); - const custParams = parseQS(decodeURIComponent(queryParams.cust_params)); + const custParams = utils.parseQS(decodeURIComponent(queryParams.cust_params)); expect(custParams).to.have.property('hb_cache_id', '123'); expect(custParams).to.have.property('hb_pb_cat_dur', '10.00_15s,15.00_15s,15.00_30s'); } diff --git a/test/spec/modules/emoteevBidAdapter_spec.js b/test/spec/modules/emoteevBidAdapter_spec.js index bf5bcc9e063..43ae62f1eb9 100644 --- a/test/spec/modules/emoteevBidAdapter_spec.js +++ b/test/spec/modules/emoteevBidAdapter_spec.js @@ -49,7 +49,6 @@ import { WALLPAPER, storage } from 'modules/emoteevBidAdapter.js'; -import * as url from '../../../src/url.js'; import * as utils from '../../../src/utils.js'; import {config} from '../../../src/config.js'; @@ -330,108 +329,108 @@ describe('emoteevBidAdapter', function () { }); describe('eventsUrl', function () { - expect(eventsUrl(null)).to.deep.equal(url.format({ + expect(eventsUrl(null)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(DEFAULT_ENV), pathname: EVENTS_PATH })); - expect(eventsUrl('anything')).to.deep.equal(url.format({ + expect(eventsUrl('anything')).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(DEFAULT_ENV), pathname: EVENTS_PATH })); - expect(eventsUrl(PRODUCTION)).to.deep.equal(url.format({ + expect(eventsUrl(PRODUCTION)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(PRODUCTION), pathname: EVENTS_PATH })); - expect(eventsUrl(STAGING)).to.deep.equal(url.format({ + expect(eventsUrl(STAGING)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(STAGING), pathname: EVENTS_PATH })); - expect(eventsUrl(DEVELOPMENT)).to.deep.equal(url.format({ + expect(eventsUrl(DEVELOPMENT)).to.deep.equal(utils.buildUrl({ hostname: domain(DEVELOPMENT), pathname: EVENTS_PATH })); }); describe('bidderUrl', function () { - expect(bidderUrl(null)).to.deep.equal(url.format({ + expect(bidderUrl(null)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(DEFAULT_ENV), pathname: BIDDER_PATH })); - expect(bidderUrl('anything')).to.deep.equal(url.format({ + expect(bidderUrl('anything')).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(DEFAULT_ENV), pathname: BIDDER_PATH })); - expect(bidderUrl(PRODUCTION)).to.deep.equal(url.format({ + expect(bidderUrl(PRODUCTION)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(PRODUCTION), pathname: BIDDER_PATH })); - expect(bidderUrl(STAGING)).to.deep.equal(url.format({ + expect(bidderUrl(STAGING)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(STAGING), pathname: BIDDER_PATH })); - expect(bidderUrl(DEVELOPMENT)).to.deep.equal(url.format({ + expect(bidderUrl(DEVELOPMENT)).to.deep.equal(utils.buildUrl({ hostname: domain(DEVELOPMENT), pathname: BIDDER_PATH })); }); describe('userSyncIframeUrl', function () { - expect(userSyncIframeUrl(null)).to.deep.equal(url.format({ + expect(userSyncIframeUrl(null)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(DEFAULT_ENV), pathname: USER_SYNC_IFRAME_PATH })); - expect(userSyncIframeUrl('anything')).to.deep.equal(url.format({ + expect(userSyncIframeUrl('anything')).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(DEFAULT_ENV), pathname: USER_SYNC_IFRAME_PATH })); - expect(userSyncIframeUrl(PRODUCTION)).to.deep.equal(url.format({ + expect(userSyncIframeUrl(PRODUCTION)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(PRODUCTION), pathname: USER_SYNC_IFRAME_PATH })); - expect(userSyncIframeUrl(STAGING)).to.deep.equal(url.format({ + expect(userSyncIframeUrl(STAGING)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(STAGING), pathname: USER_SYNC_IFRAME_PATH })); - expect(userSyncIframeUrl(DEVELOPMENT)).to.deep.equal(url.format({ + expect(userSyncIframeUrl(DEVELOPMENT)).to.deep.equal(utils.buildUrl({ hostname: domain(DEVELOPMENT), pathname: USER_SYNC_IFRAME_PATH })); }); describe('userSyncImageUrl', function () { - expect(userSyncImageUrl(null)).to.deep.equal(url.format({ + expect(userSyncImageUrl(null)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(DEFAULT_ENV), pathname: USER_SYNC_IMAGE_PATH })); - expect(userSyncImageUrl('anything')).to.deep.equal(url.format({ + expect(userSyncImageUrl('anything')).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(DEFAULT_ENV), pathname: USER_SYNC_IMAGE_PATH })); - expect(userSyncImageUrl(PRODUCTION)).to.deep.equal(url.format({ + expect(userSyncImageUrl(PRODUCTION)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(PRODUCTION), pathname: USER_SYNC_IMAGE_PATH })); - expect(userSyncImageUrl(STAGING)).to.deep.equal(url.format({ + expect(userSyncImageUrl(STAGING)).to.deep.equal(utils.buildUrl({ protocol: 'https', hostname: domain(STAGING), pathname: USER_SYNC_IMAGE_PATH })); - expect(userSyncImageUrl(DEVELOPMENT)).to.deep.equal(url.format({ + expect(userSyncImageUrl(DEVELOPMENT)).to.deep.equal(utils.buildUrl({ hostname: domain(DEVELOPMENT), pathname: USER_SYNC_IMAGE_PATH })); diff --git a/test/spec/modules/eplanningAnalyticsAdapter_spec.js b/test/spec/modules/eplanningAnalyticsAdapter_spec.js index e900f7ca31c..9bb71e7033d 100644 --- a/test/spec/modules/eplanningAnalyticsAdapter_spec.js +++ b/test/spec/modules/eplanningAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ import eplAnalyticsAdapter from 'modules/eplanningAnalyticsAdapter.js'; import includes from 'core-js/library/fn/array/includes.js'; import { expect } from 'chai'; -import {parse as parseURL} from 'src/url.js'; +import { parseUrl } from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; let adapterManager = require('src/adapterManager').default; let events = require('src/events'); @@ -118,7 +118,7 @@ describe('eplanning analytics adapter', function () { expect(includes(['https://ads.ar.e-planning.net/hba/1/12345?d='], requests[0].url)); let info = requests[0].url; - let purl = parseURL(info); + let purl = parseUrl(info); let eplData = JSON.parse(decodeURIComponent(purl.search.d)); // Step 8 check that 6 events were sent diff --git a/test/spec/modules/etargetBidAdapter_spec.js b/test/spec/modules/etargetBidAdapter_spec.js index 0d8ad7bcf11..4f5e0c224ec 100644 --- a/test/spec/modules/etargetBidAdapter_spec.js +++ b/test/spec/modules/etargetBidAdapter_spec.js @@ -1,5 +1,4 @@ import {assert, expect} from 'chai'; -import * as url from 'src/url.js'; import {spec} from 'modules/etargetBidAdapter.js'; import { BANNER, VIDEO } from 'src/mediaTypes.js'; diff --git a/test/spec/modules/fintezaAnalyticsAdapter_spec.js b/test/spec/modules/fintezaAnalyticsAdapter_spec.js index 4b58761d8a6..ae9ceceecc3 100644 --- a/test/spec/modules/fintezaAnalyticsAdapter_spec.js +++ b/test/spec/modules/fintezaAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ import fntzAnalyticsAdapter from 'modules/fintezaAnalyticsAdapter.js'; import includes from 'core-js/library/fn/array/includes.js'; import { expect } from 'chai'; -import { parse as parseURL } from 'src/url.js'; +import { parseUrl } from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; let adapterManager = require('src/adapterManager').default; @@ -81,7 +81,7 @@ describe('finteza analytics adapter', function () { expect(server.requests[0].method).to.equal('GET'); expect(server.requests[0].withCredentials).to.equal(true); - const url = parseURL(server.requests[0].url); + const url = parseUrl(server.requests[0].url); expect(url.protocol).to.equal('https'); expect(url.hostname).to.equal('content.mql5.com'); @@ -124,7 +124,7 @@ describe('finteza analytics adapter', function () { expect(server.requests[0].method).to.equal('GET'); expect(server.requests[0].withCredentials).to.equal(true); - let url = parseURL(server.requests[0].url); + let url = parseUrl(server.requests[0].url); expect(url.protocol).to.equal('https'); expect(url.hostname).to.equal('content.mql5.com'); @@ -138,7 +138,7 @@ describe('finteza analytics adapter', function () { expect(server.requests[1].method).to.equal('GET'); expect(server.requests[1].withCredentials).to.equal(true); - url = parseURL(server.requests[1].url); + url = parseUrl(server.requests[1].url); expect(url.protocol).to.equal('https'); expect(url.hostname).to.equal('content.mql5.com'); @@ -178,7 +178,7 @@ describe('finteza analytics adapter', function () { expect(server.requests[0].method).to.equal('GET'); expect(server.requests[0].withCredentials).to.equal(true); - const url = parseURL(server.requests[0].url); + const url = parseUrl(server.requests[0].url); expect(url.protocol).to.equal('https'); expect(url.hostname).to.equal('content.mql5.com'); @@ -217,7 +217,7 @@ describe('finteza analytics adapter', function () { expect(server.requests[0].method).to.equal('GET'); expect(server.requests[0].withCredentials).to.equal(true); - const url = parseURL(server.requests[0].url); + const url = parseUrl(server.requests[0].url); expect(url.protocol).to.equal('https'); expect(url.hostname).to.equal('content.mql5.com'); diff --git a/test/spec/modules/konduitWrapper_spec.js b/test/spec/modules/konduitWrapper_spec.js index bfae5711d32..4a0c627e885 100644 --- a/test/spec/modules/konduitWrapper_spec.js +++ b/test/spec/modules/konduitWrapper_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import parse from 'url-parse'; import { buildVastUrl } from 'modules/konduitWrapper.js'; -import { parseQS } from 'src/url.js'; +import { parseQS } from 'src/utils.js'; import { config } from 'src/config.js'; describe('The Konduit vast wrapper module', function () { diff --git a/test/spec/modules/mgidBidAdapter_spec.js b/test/spec/modules/mgidBidAdapter_spec.js index b96d718ab36..16f4f0b4607 100644 --- a/test/spec/modules/mgidBidAdapter_spec.js +++ b/test/spec/modules/mgidBidAdapter_spec.js @@ -1,7 +1,6 @@ import {assert, expect} from 'chai'; import {spec} from 'modules/mgidBidAdapter.js'; import * as utils from '../../../src/utils.js'; -import * as urlUtils from '../../../src/url.js'; describe('Mgid bid adapter', function () { let sandbox; @@ -361,7 +360,7 @@ describe('Mgid bid adapter', function () { }; let bidRequests = [bid]; const page = top.location.href; - const domain = urlUtils.parse(page).hostname; + const domain = utils.parseUrl(page).hostname; const request = spec.buildRequests(bidRequests); expect(request.url).deep.equal('https://prebid.mgid.com/prebid/1'); expect(request.method).deep.equal('POST'); @@ -409,7 +408,7 @@ describe('Mgid bid adapter', function () { let bidRequests = [bid]; const page = top.location.href; - const domain = urlUtils.parse(page).hostname; + const domain = utils.parseUrl(page).hostname; const request = spec.buildRequests(bidRequests); expect(request).to.be.a('object'); expect(request.url).deep.equal('https://prebid.mgid.com/prebid/1'); @@ -446,7 +445,7 @@ describe('Mgid bid adapter', function () { let bidRequests = [bid]; const page = top.location.href; - const domain = urlUtils.parse(page).hostname; + const domain = utils.parseUrl(page).hostname; const request = spec.buildRequests(bidRequests); expect(request).to.be.a('object'); expect(request.url).deep.equal('https://prebid.mgid.com/prebid/1'); @@ -482,7 +481,7 @@ describe('Mgid bid adapter', function () { let bidRequests = [bid]; const page = top.location.href; - const domain = urlUtils.parse(page).hostname; + const domain = utils.parseUrl(page).hostname; const request = spec.buildRequests(bidRequests); expect(request).to.be.a('object'); expect(request.url).deep.equal('https://prebid.mgid.com/prebid/1'); @@ -516,7 +515,7 @@ describe('Mgid bid adapter', function () { const request = spec.buildRequests(bidRequests); const page = top.location.href; - const domain = urlUtils.parse(page).hostname; + const domain = utils.parseUrl(page).hostname; expect(request.url).deep.equal('https://prebid.mgid.com/prebid/1'); expect(request.method).deep.equal('POST'); const data = JSON.parse(request.data); diff --git a/test/spec/modules/quantcastBidAdapter_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js index 351cea0b086..5e4093c91be 100644 --- a/test/spec/modules/quantcastBidAdapter_spec.js +++ b/test/spec/modules/quantcastBidAdapter_spec.js @@ -10,7 +10,7 @@ import { spec as qcSpec } from '../../../modules/quantcastBidAdapter.js'; import { newBidder } from '../../../src/adapters/bidderFactory.js'; -import { parse } from 'src/url.js'; +import { parseUrl } from 'src/utils.js'; import { config } from 'src/config.js'; describe('Quantcast adapter', function () { @@ -90,13 +90,13 @@ describe('Quantcast adapter', function () { describe('`buildRequests`', function () { it('sends secure bid requests', function () { const requests = qcSpec.buildRequests([bidRequest]); - const url = parse(requests[0]['url']); + const url = parseUrl(requests[0]['url']); expect(url.protocol).to.equal('https'); }); it('sends bid requests to Quantcast Canary Endpoint if `publisherId` is `test-publisher`', function () { const requests = qcSpec.buildRequests([bidRequest]); - const url = parse(requests[0]['url']); + const url = parseUrl(requests[0]['url']); expect(url.hostname).to.equal(QUANTCAST_TEST_DOMAIN); }); diff --git a/test/spec/modules/readpeakBidAdapter_spec.js b/test/spec/modules/readpeakBidAdapter_spec.js index a0cff8a3464..eb9077fac39 100644 --- a/test/spec/modules/readpeakBidAdapter_spec.js +++ b/test/spec/modules/readpeakBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { spec, ENDPOINT } from 'modules/readpeakBidAdapter.js'; import { config } from 'src/config.js'; -import { parse as parseUrl } from 'src/url.js'; +import { parseUrl } from 'src/utils.js'; describe('ReadPeakAdapter', function() { let bidRequest; diff --git a/test/spec/modules/revcontentBidAdapter_spec.js b/test/spec/modules/revcontentBidAdapter_spec.js index 548f3019a4f..1aa08d9469e 100644 --- a/test/spec/modules/revcontentBidAdapter_spec.js +++ b/test/spec/modules/revcontentBidAdapter_spec.js @@ -1,6 +1,5 @@ // jshint esversion: 6, es3: false, node: true import {assert, expect} from 'chai'; -import * as url from 'src/url.js'; import {spec} from 'modules/revcontentBidAdapter.js'; import { NATIVE } from 'src/mediaTypes.js'; import { config } from 'src/config.js'; diff --git a/test/spec/modules/seedingAllianceAdapter_spec.js b/test/spec/modules/seedingAllianceAdapter_spec.js index c5c2a5d682e..e6f96c92fd9 100755 --- a/test/spec/modules/seedingAllianceAdapter_spec.js +++ b/test/spec/modules/seedingAllianceAdapter_spec.js @@ -1,6 +1,5 @@ // jshint esversion: 6, es3: false, node: true import {assert, expect} from 'chai'; -import * as url from 'src/url.js'; import {spec} from 'modules/seedingAllianceBidAdapter.js'; import { NATIVE } from 'src/mediaTypes.js'; import { config } from 'src/config.js'; diff --git a/test/spec/unit/core/bidderFactory_spec.js b/test/spec/unit/core/bidderFactory_spec.js index ccca9bdd0dc..6d0595ba4d8 100644 --- a/test/spec/unit/core/bidderFactory_spec.js +++ b/test/spec/unit/core/bidderFactory_spec.js @@ -247,7 +247,7 @@ describe('bidders created by newBidder', function () { bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); expect(ajaxStub.calledOnce).to.equal(true); - expect(ajaxStub.firstCall.args[0]).to.equal(`${url}?arg=2&`); + expect(ajaxStub.firstCall.args[0]).to.equal(`${url}?arg=2`); expect(ajaxStub.firstCall.args[2]).to.be.undefined; expect(ajaxStub.firstCall.args[3]).to.deep.equal({ method: 'GET', @@ -271,7 +271,7 @@ describe('bidders created by newBidder', function () { bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); expect(ajaxStub.calledOnce).to.equal(true); - expect(ajaxStub.firstCall.args[0]).to.equal(`${url}?arg=2&`); + expect(ajaxStub.firstCall.args[0]).to.equal(`${url}?arg=2`); expect(ajaxStub.firstCall.args[2]).to.be.undefined; expect(ajaxStub.firstCall.args[3]).to.deep.equal({ method: 'GET', diff --git a/test/spec/url_spec.js b/test/spec/url_spec.js deleted file mode 100644 index 842b954c4bc..00000000000 --- a/test/spec/url_spec.js +++ /dev/null @@ -1,94 +0,0 @@ -import {format, parse} from '../../src/url.js'; -import { expect } from 'chai'; - -describe('helpers.url', function () { - describe('parse()', function () { - let parsed; - - beforeEach(function () { - parsed = parse('http://example.com:3000/pathname/?search=test&foo=bar&bar=foo%26foo%3Dxxx#hash'); - }); - - it('extracts the protocol', function () { - expect(parsed).to.have.property('protocol', 'http'); - }); - - it('extracts the hostname', function () { - expect(parsed).to.have.property('hostname', 'example.com'); - }); - - it('extracts the port', function () { - expect(parsed).to.have.property('port', 3000); - }); - - it('extracts the pathname', function () { - expect(parsed).to.have.property('pathname', '/pathname/'); - }); - - it('extracts the search query', function () { - expect(parsed).to.have.property('search'); - expect(parsed.search).to.eql({ - foo: 'xxx', - search: 'test', - bar: 'foo', - }); - }); - - it('extracts the hash', function () { - expect(parsed).to.have.property('hash', 'hash'); - }); - - it('extracts the host', function () { - expect(parsed).to.have.property('host', 'example.com:3000'); - }); - }); - - describe('parse(url, {noDecodeWholeURL: true})', function () { - let parsed; - - beforeEach(function () { - parsed = parse('http://example.com:3000/pathname/?search=test&foo=bar&bar=foo%26foo%3Dxxx#hash', {noDecodeWholeURL: true}); - }); - - it('extracts the search query', function () { - expect(parsed).to.have.property('search'); - expect(parsed.search).to.eql({ - foo: 'bar', - search: 'test', - bar: 'foo%26foo%3Dxxx', - }); - }); - }); - - describe('format()', function () { - it('formats an object in to a URL', function () { - expect(format({ - protocol: 'http', - hostname: 'example.com', - port: 3000, - pathname: '/pathname/', - search: {foo: 'bar', search: 'test', bar: 'foo%26foo%3Dxxx'}, - hash: 'hash' - })).to.equal('http://example.com:3000/pathname/?foo=bar&search=test&bar=foo%26foo%3Dxxx#hash'); - }); - - it('will use defaults for missing properties', function () { - expect(format({ - hostname: 'example.com' - })).to.equal('http://example.com'); - }); - }); - - describe('parse(url, {decodeSearchAsString: true})', function () { - let parsed; - - beforeEach(function () { - parsed = parse('http://example.com:3000/pathname/?search=test&foo=bar&bar=foo%26foo%3Dxxx#hash', {decodeSearchAsString: true}); - }); - - it('extracts the search query', function () { - expect(parsed).to.have.property('search'); - expect(parsed.search).to.equal('?search=test&foo=bar&bar=foo&foo=xxx'); - }); - }); -}); diff --git a/test/spec/utils_spec.js b/test/spec/utils_spec.js old mode 100755 new mode 100644 index 9ba70810a08..2c29877f724 --- a/test/spec/utils_spec.js +++ b/test/spec/utils_spec.js @@ -18,24 +18,6 @@ describe('Utils', function () { type_array = 'Array', type_function = 'Function'; - describe('replaceTokenInString', function () { - it('should replace all given tokens in a String', function () { - var tokensToReplace = { - foo: 'bar', - zap: 'quux' - }; - - var output = utils.replaceTokenInString('hello %FOO%, I am %ZAP%', tokensToReplace, '%'); - assert.equal(output, 'hello bar, I am quux'); - }); - - it('should ignore tokens it does not see', function () { - var output = utils.replaceTokenInString('hello %FOO%', {}, '%'); - - assert.equal(output, 'hello %FOO%'); - }); - }); - describe('getBidIdParameter', function () { it('should return value of the key in input object', function () { var obj = { @@ -86,7 +68,7 @@ describe('Utils', function () { }; var output = utils.parseQueryStringParameters(obj); - var expectedResult = 'a=' + encodeURIComponent('1') + '&b=' + encodeURIComponent('2') + '&'; + var expectedResult = 'a=' + encodeURIComponent('1') + '&b=' + encodeURIComponent('2'); assert.equal(output, expectedResult); }); @@ -699,20 +681,6 @@ describe('Utils', function () { }); }); - describe('createContentToExecuteExtScriptInFriendlyFrame', function () { - it('should return empty string if url is not passed', function () { - var output = utils.createContentToExecuteExtScriptInFriendlyFrame(); - assert.equal(output, ''); - }); - - it('should have URL in returned value if url is passed', function () { - var url = 'https://abcd.com/service?a=1&b=2&c=3'; - var output = utils.createContentToExecuteExtScriptInFriendlyFrame(url); - var expected = ``; - assert.equal(output, expected); - }); - }); - describe('getDefinedParams', function () { it('builds an object consisting of defined params', function () { const adUnit = { @@ -833,6 +801,98 @@ describe('Utils', function () { }); }); + describe('URL helpers', function () { + describe('parseUrl()', function () { + let parsed; + + beforeEach(function () { + parsed = utils.parseUrl('http://example.com:3000/pathname/?search=test&foo=bar&bar=foo%26foo%3Dxxx#hash'); + }); + + it('extracts the protocol', function () { + expect(parsed).to.have.property('protocol', 'http'); + }); + + it('extracts the hostname', function () { + expect(parsed).to.have.property('hostname', 'example.com'); + }); + + it('extracts the port', function () { + expect(parsed).to.have.property('port', 3000); + }); + + it('extracts the pathname', function () { + expect(parsed).to.have.property('pathname', '/pathname/'); + }); + + it('extracts the search query', function () { + expect(parsed).to.have.property('search'); + expect(parsed.search).to.eql({ + foo: 'xxx', + search: 'test', + bar: 'foo', + }); + }); + + it('extracts the hash', function () { + expect(parsed).to.have.property('hash', 'hash'); + }); + + it('extracts the host', function () { + expect(parsed).to.have.property('host', 'example.com:3000'); + }); + }); + + describe('parseUrl(url, {noDecodeWholeURL: true})', function () { + let parsed; + + beforeEach(function () { + parsed = utils.parseUrl('http://example.com:3000/pathname/?search=test&foo=bar&bar=foo%26foo%3Dxxx#hash', {noDecodeWholeURL: true}); + }); + + it('extracts the search query', function () { + expect(parsed).to.have.property('search'); + expect(parsed.search).to.eql({ + foo: 'bar', + search: 'test', + bar: 'foo%26foo%3Dxxx', + }); + }); + }); + + describe('buildUrl()', function () { + it('formats an object in to a URL', function () { + expect(utils.buildUrl({ + protocol: 'http', + hostname: 'example.com', + port: 3000, + pathname: '/pathname/', + search: {foo: 'bar', search: 'test', bar: 'foo%26foo%3Dxxx'}, + hash: 'hash' + })).to.equal('http://example.com:3000/pathname/?foo=bar&search=test&bar=foo%26foo%3Dxxx#hash'); + }); + + it('will use defaults for missing properties', function () { + expect(utils.buildUrl({ + hostname: 'example.com' + })).to.equal('http://example.com'); + }); + }); + + describe('parseUrl(url, {decodeSearchAsString: true})', function () { + let parsed; + + beforeEach(function () { + parsed = utils.parseUrl('http://example.com:3000/pathname/?search=test&foo=bar&bar=foo%26foo%3Dxxx#hash', {decodeSearchAsString: true}); + }); + + it('extracts the search query', function () { + expect(parsed).to.have.property('search'); + expect(parsed.search).to.equal('?search=test&foo=bar&bar=foo&foo=xxx'); + }); + }); + }); + describe('transformBidderParamKeywords', function () { it('returns an array of objects when keyvalue is an array', function () { let keywords = { From 8f8f6f8d69ff0ea2cd340a03d1c562ddd1888497 Mon Sep 17 00:00:00 2001 From: vincentproxistore <56686565+vincentproxistore@users.noreply.github.com> Date: Fri, 10 Apr 2020 15:34:43 +0200 Subject: [PATCH 233/496] change payload (#5105) --- modules/proxistoreBidAdapter.js | 19 ++++++++----------- .../spec/modules/proxistoreBidAdapter_spec.js | 12 ++++++++---- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/modules/proxistoreBidAdapter.js b/modules/proxistoreBidAdapter.js index 6facf5d1480..e8ef4878d8e 100644 --- a/modules/proxistoreBidAdapter.js +++ b/modules/proxistoreBidAdapter.js @@ -2,16 +2,16 @@ const { registerBidder } = require('../src/adapters/bidderFactory.js'); const BIDDER_CODE = 'proxistore'; const PROXISTORE_VENDOR_ID = 418; -function _mapSizes(sizes) { - const flatSize = sizes.reduce((acc, val) => acc.concat(val), []); ; - return flatSize.map(array1d => { return { width: array1d[0], height: array1d[1] } }); -} - function _createServerRequest(bidRequests, bidderRequest) { + const sizeIds = []; + bidRequests.forEach(bid => { + const sizeId = {id: bid.bidId, sizes: bid.sizes.map(size => { return { width: size[0], height: size[1] } })}; + sizeIds.push(sizeId); + }); const payload = { auctionId: bidRequests[0].auctionId, - transactionId: bidRequests[0].transactionId, - sizes: _mapSizes(bidRequests.map(x => x.sizes)), + transactionId: bidRequests[0].auctionId, + bids: sizeIds, website: bidRequests[0].params.website, language: bidRequests[0].params.language, gdpr: { @@ -19,9 +19,6 @@ function _createServerRequest(bidRequests, bidderRequest) { } }; - const bidIds = bidRequests.map(req => req.bidId); - bidIds.length === 1 ? payload.bidId = bidIds[0] : payload.bidIds = bidIds; - const options = { contentType: 'application/json', withCredentials: true @@ -42,7 +39,7 @@ function _createServerRequest(bidRequests, bidderRequest) { return { method: 'POST', - url: bidRequests[0].params.url || 'https://abs.proxistore.com/' + payload.language + '/v3/rtb/prebid', + url: bidRequests[0].params.url || 'https://abs.proxistore.com/' + payload.language + '/v3/rtb/prebid/multi', data: JSON.stringify(payload), options: options }; diff --git a/test/spec/modules/proxistoreBidAdapter_spec.js b/test/spec/modules/proxistoreBidAdapter_spec.js index 579ef5fdb3b..e18262ae797 100644 --- a/test/spec/modules/proxistoreBidAdapter_spec.js +++ b/test/spec/modules/proxistoreBidAdapter_spec.js @@ -34,7 +34,7 @@ describe('ProxistoreBidAdapter', function () { }); describe('buildRequests', function () { - const url = 'https://abs.proxistore.com/fr/v3/rtb/prebid'; + const url = 'https://abs.proxistore.com/fr/v3/rtb/prebid/multi'; const request = spec.buildRequests([bid], bidderRequest); it('should return a valid object', function () { expect(request).to.be.an('object'); @@ -55,10 +55,14 @@ describe('ProxistoreBidAdapter', function () { expect(data.gdpr.applies).to.be.true; expect(data.gdpr.consentGiven).to.be.true; }); - it('should have a property bidId if there is only one bid', function () { + it('should have a property a length of bids equal to one if there is only one bid', function () { const data = JSON.parse(request.data); - expect(data.hasOwnProperty('bidId')).to.be.true; - }) + expect(data.hasOwnProperty('bids')).to.be.true; + expect(data.bids).to.be.an('array'); + expect(data.bids.length).equal(1); + expect(data.bids[0].hasOwnProperty('id')).to.be.true; + expect(data.bids[0].sizes).to.be.an('array'); + }); }); describe('interpretResponse', function () { From 67a1cb134c784fdf99a60b3b349643e21267e557 Mon Sep 17 00:00:00 2001 From: rtuschkany <35923908+rtuschkany@users.noreply.github.com> Date: Fri, 10 Apr 2020 20:30:25 +0200 Subject: [PATCH 234/496] Add new bid adapter for ConnectAd (#4806) * Add new bid adapter for ConnectAd * Add new bid adapter for ConnectAd * Conditional fix * js.fix * js-fix * EOF-fix * EOF-Fix --- modules/connectadBidAdapter.js | 299 ++++++++++++ modules/connectadBidAdapter.md | 46 ++ test/spec/modules/connectadBidAdapter_spec.js | 453 ++++++++++++++++++ 3 files changed, 798 insertions(+) create mode 100644 modules/connectadBidAdapter.js create mode 100644 modules/connectadBidAdapter.md create mode 100644 test/spec/modules/connectadBidAdapter_spec.js diff --git a/modules/connectadBidAdapter.js b/modules/connectadBidAdapter.js new file mode 100644 index 00000000000..3dcb8da9838 --- /dev/null +++ b/modules/connectadBidAdapter.js @@ -0,0 +1,299 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js' +import {config} from '../src/config.js'; + +const BIDDER_CODE = 'connectad'; +const BIDDER_CODE_ALIAS = 'connectadrealtime'; +const ENDPOINT_URL = 'https://i.connectad.io/api/v2'; +const SUPPORTED_MEDIA_TYPES = [BANNER]; + +export const spec = { + code: BIDDER_CODE, + aliases: [ BIDDER_CODE_ALIAS ], + supportedMediaTypes: SUPPORTED_MEDIA_TYPES, + + isBidRequestValid: function(bid) { + return !!(bid.params.networkId && bid.params.siteId); + }, + + buildRequests: function(validBidRequests, bidderRequest) { + let digitrust; + + let ret = { + method: 'POST', + url: '', + data: '', + bidRequest: [] + }; + + if (validBidRequests.length < 1) { + return ret; + } + + const data = Object.assign({ + placements: [], + time: Date.now(), + user: {}, + url: (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) ? bidderRequest.refererInfo.referer : window.location.href, + referrer: window.document.referrer, + referrer_info: bidderRequest.refererInfo, + screensize: getScreenSize(), + dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0, + language: navigator.language, + ua: navigator.userAgent + }); + + // coppa compliance + if (config.getConfig('coppa') === true) { + utils.deepSetValue(data, 'user.coppa', 1); + } + + // adding schain object + if (validBidRequests[0].schain) { + utils.deepSetValue(data, 'source.ext.schain', validBidRequests[0].schain); + } + + // Attaching GDPR Consent Params + if (bidderRequest.gdprConsent) { + let gdprApplies; + if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { + gdprApplies = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; + } + utils.deepSetValue(data, 'user.ext.gdpr', gdprApplies); + utils.deepSetValue(data, 'user.ext.consent', bidderRequest.gdprConsent.consentString); + } + + // CCPA + if (bidderRequest.uspConsent) { + utils.deepSetValue(data, 'user.ext.us_privacy', bidderRequest.uspConsent); + } + + // Digitrust Support + const bidRequestDigitrust = utils.deepAccess(validBidRequests[0], 'userId.digitrustid.data'); + if (bidRequestDigitrust && (!bidRequestDigitrust.privacy || !bidRequestDigitrust.privacy.optout)) { + digitrust = { + id: bidRequestDigitrust.id, + keyv: bidRequestDigitrust.keyv + } + } + + if (digitrust) { + utils.deepSetValue(data, 'user.ext.digitrust', { + id: digitrust.id, + keyv: digitrust.keyv + }) + } + + if (validBidRequests[0].userId && typeof validBidRequests[0].userId === 'object' && (validBidRequests[0].userId.tdid || validBidRequests[0].userId.pubcid || validBidRequests[0].userId.lipb || validBidRequests[0].userId.id5id || validBidRequests[0].userId.parrableid)) { + utils.deepSetValue(data, 'user.ext.eids', []); + + if (validBidRequests[0].userId.tdid) { + data.user.ext.eids.push({ + source: 'adserver.org', + uids: [{ + id: validBidRequests[0].userId.tdid, + ext: { + rtiPartner: 'TDID' + } + }] + }); + } + + if (validBidRequests[0].userId.pubcid) { + data.user.ext.eids.push({ + source: 'pubcommon', + uids: [{ + id: validBidRequests[0].userId.pubcid, + }] + }); + } + + if (validBidRequests[0].userId.id5id) { + data.user.ext.eids.push({ + source: 'id5-sync.com', + uids: [{ + id: validBidRequests[0].userId.id5id, + }] + }); + } + + if (validBidRequests[0].userId.parrableid) { + data.user.ext.eids.push({ + source: 'parrable.com', + uids: [{ + id: validBidRequests[0].userId.parrableid, + }] + }); + } + + if (validBidRequests[0].userId.lipb && validBidRequests[0].userId.lipb.lipbid) { + data.user.ext.eids.push({ + source: 'liveintent.com', + uids: [{ + id: validBidRequests[0].userId.lipb.lipbid + }] + }); + } + } + + validBidRequests.map(bid => { + const placement = Object.assign({ + id: bid.transactionId, + divName: bid.bidId, + sizes: bid.mediaTypes.banner.sizes, + adTypes: getSize(bid.mediaTypes.banner.sizes || bid.sizes) + }, bid.params); + + if (placement.networkId && placement.siteId) { + data.placements.push(placement); + } + }); + + ret.data = JSON.stringify(data); + ret.bidRequest = validBidRequests; + ret.url = ENDPOINT_URL; + + return ret; + }, + + interpretResponse: function(serverResponse, bidRequest, bidderRequest) { + let bid; + let bids; + let bidId; + let bidObj; + let bidResponses = []; + + bids = bidRequest.bidRequest; + + serverResponse = (serverResponse || {}).body; + for (let i = 0; i < bids.length; i++) { + bid = {}; + bidObj = bids[i]; + bidId = bidObj.bidId; + + if (serverResponse) { + const decision = serverResponse.decisions && serverResponse.decisions[bidId]; + const price = decision && decision.pricing && decision.pricing.clearPrice; + + if (decision && price) { + bid.requestId = bidId; + bid.cpm = price; + bid.width = decision.width; + bid.height = decision.height; + bid.dealid = decision.dealid || null; + bid.ad = retrieveAd(decision); + bid.currency = 'USD'; + bid.creativeId = decision.adId; + bid.ttl = 360; + bid.netRevenue = true; + bidResponses.push(bid); + } + } + } + + return bidResponses; + }, + + getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { + let syncEndpoint = 'https://cdn.connectad.io/connectmyusers.php?'; + + if (gdprConsent) { + syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'gdpr', (gdprConsent.gdprApplies ? 1 : 0)); + } + + if (gdprConsent && typeof gdprConsent.consentString === 'string') { + syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'gdpr_consent', gdprConsent.consentString); + } + + if (uspConsent) { + syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'us_privacy', uspConsent); + } + + if (config.getConfig('coppa') === true) { + syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'coppa', 1); + } + + if (syncOptions.iframeEnabled) { + return [{ + type: 'iframe', + url: syncEndpoint + }]; + } else { + utils.logWarn('Bidder ConnectAd: Please activate iFrame Sync'); + } + } +}; + +const sizeMap = [ + null, + '120x90', + '200x200', + '468x60', + '728x90', + '300x250', + '160x600', + '120x600', + '300x100', + '180x150', + '336x280', + '240x400', + '234x60', + '88x31', + '120x60', + '120x240', + '125x125', + '220x250', + '250x250', + '250x90', + '0x0', + '200x90', + '300x50', + '320x50', + '320x480', + '185x185', + '620x45', + '300x125', + '800x250', + '980x120', + '980x150', + '320x150', + '300x300', + '200x600', + '320x500', + '320x320' +]; + +sizeMap[77] = '970x90'; +sizeMap[123] = '970x250'; +sizeMap[43] = '300x600'; +sizeMap[286] = '970x66'; +sizeMap[3230] = '970x280'; +sizeMap[429] = '486x60'; +sizeMap[374] = '700x500'; +sizeMap[934] = '300x1050'; +sizeMap[1578] = '320x100'; +sizeMap[331] = '320x250'; +sizeMap[3301] = '320x267'; +sizeMap[2730] = '728x250'; + +function getSize(sizes) { + const result = []; + sizes.forEach(function(size) { + const index = sizeMap.indexOf(size[0] + 'x' + size[1]); + if (index >= 0) { + result.push(index); + } + }); + return result; +} + +function retrieveAd(decision) { + return decision.contents && decision.contents[0] && decision.contents[0].body; +} + +function getScreenSize() { + return [window.screen.width, window.screen.height].join('x'); +} + +registerBidder(spec); diff --git a/modules/connectadBidAdapter.md b/modules/connectadBidAdapter.md new file mode 100644 index 00000000000..e63494e1add --- /dev/null +++ b/modules/connectadBidAdapter.md @@ -0,0 +1,46 @@ +# Overview + +``` +Module Name: ConnectAd PreBid Adapter +Module Type: Bidder Adapter +Maintainer: support@connectad.io +``` + +# Description + +ConnectAd bid adapter supports only Banner at present. Video and Mobile will follow Q2/2020 + +# Sample Ad Unit: For Publishers +``` +var adUnits = [ +{ + code: 'test-div', + mediaTypes: { + banner: { + sizes: [[300, 250], [300,600]] + } + }, + bids: [{ + bidder: 'connectad', + params: { + siteId: 123456, + networkId: 123456, + bidfloor: 0.20 // Optional: Requested Bidfloor + } + }] +} + +# ## Configuration +ConnectAd recommends the UserSync configuration below otherwise we will not be able to performe user syncs. + +```javascript +pbjs.setConfig({ + userSync: { + filterSettings: { + iframe: { + bidders: ['connectad'], + filter: 'include' + } + } + } +}); \ No newline at end of file diff --git a/test/spec/modules/connectadBidAdapter_spec.js b/test/spec/modules/connectadBidAdapter_spec.js new file mode 100644 index 00000000000..626018241c4 --- /dev/null +++ b/test/spec/modules/connectadBidAdapter_spec.js @@ -0,0 +1,453 @@ +import {expect} from 'chai'; +import {spec} from 'modules/connectadBidAdapter.js'; +import { config } from 'src/config.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; + +describe('ConnectAd Adapter', function () { + let bidRequests; + let bidderRequest; + let bidRequestsUserIds; + + beforeEach(function () { + bidRequests = [ + { + bidder: 'conntectad', + params: { + siteId: 123456, + networkId: 123456 + }, + adUnitCode: '/19968336/header-bid-tag-1', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + } + }, + bidId: '2f95c00074b931', + auctionId: 'e76cbb58-f3e1-4ad9-9f4c-718c1919d0df', + bidderRequestId: '1c56ad30b9b8ca8', + transactionId: 'e76cbb58-f3e1-4ad9-9f4c-718c1919d0df' + } + ]; + + bidRequestsUserIds = [{ + bidder: 'conntectad', + params: { + siteId: 123456, + networkId: 123456 + }, + adUnitCode: '/19968336/header-bid-tag-1', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + } + }, + bidId: '2f95c00074b931', + auctionId: 'e76cbb58-f3e1-4ad9-9f4c-718c1919d0df', + bidderRequestId: '1c56ad30b9b8ca8', + transactionId: 'e76cbb58-f3e1-4ad9-9f4c-718c1919d0df', + userId: { + tdid: '123456', + digitrustid: {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}} + } + }]; + + bidderRequest = { + timeout: 3000, + gdprConsent: { + gdprApplies: true, + consentString: 'consentDataString', + vendorData: {} + } + } + }); + + describe('inherited functions', function () { + it('should exists and is a function', function () { + const adapter = newBidder(spec); + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('implementation', function () { + describe('for requests', function () { + it('should accept bid', function () { + let validBid = { + bidder: 'connectad', + params: { + siteId: 123456, + networkId: 123456 + }, + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]] + } + } + }; + const isValid = spec.isBidRequestValid(validBid); + + expect(isValid).to.equal(true); + }); + + it('should reject if missing sizes', function () { + let invalidBid = { + bidder: 'connectad', + params: { + siteId: 123456, + } + }; + const isValid = spec.isBidRequestValid(invalidBid); + expect(isValid).to.equal(false); + }); + + it('should return true when optional bidFloor params found for an ad', function () { + let validBid = { + bidder: 'connectad', + params: { + siteId: 123456, + networkId: 123456, + bidfloor: 0.20 + }, + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]] + } + } + }; + const isValid = spec.isBidRequestValid(validBid); + expect(isValid).to.equal(true) + }); + + it('should reject if missing siteId/networkId', function () { + let invalidBid = { + bidder: 'connectad', + params: {}, + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + } + } + }; + const isValid = spec.isBidRequestValid(invalidBid); + expect(isValid).to.equal(false); + }); + + it('should reject if missing networkId', function () { + let invalidBid = { + bidder: 'connectad', + params: { + siteId: 123456 + }, + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + } + } + }; + const isValid = spec.isBidRequestValid(invalidBid); + expect(isValid).to.equal(false); + }); + + it('should contain SiteId and NetworkId', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + const requestparse = JSON.parse(request.data); + expect(requestparse.placements[0].siteId).to.equal(123456); + expect(requestparse.placements[0].networkId).to.equal(123456); + }); + + it('should contain gdpr info', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + const requestparse = JSON.parse(request.data); + + expect(requestparse.user.ext.gdpr).to.equal(1); + expect(requestparse.user.ext.consent).to.equal('consentDataString'); + }); + + it('should build a request if Consent but no gdprApplies', function () { + let bidderRequest = { + timeout: 3000, + gdprConsent: { + gdprApplies: false, + consentString: 'consentDataString', + }, + } + const request = spec.buildRequests(bidRequests, bidderRequest); + const requestparse = JSON.parse(request.data); + + expect(requestparse.placements[0].adTypes).to.be.an('array'); + expect(requestparse.placements[0].siteId).to.equal(123456); + expect(requestparse.user.ext.consent).to.equal('consentDataString'); + }); + + it('should build a request if gdprConsent empty', function () { + let bidderRequest = { + timeout: 3000, + gdprConsent: {} + } + const request = spec.buildRequests(bidRequests, bidderRequest); + const requestparse = JSON.parse(request.data); + + expect(requestparse.placements[0].adTypes).to.be.an('array'); + expect(requestparse.placements[0].siteId).to.equal(123456); + }); + + it('should have CCPA Consent if defined', function () { + const uspConsent = '1YYN' + bidderRequest.uspConsent = uspConsent + const request = spec.buildRequests(bidRequests, bidderRequest); + const requestparse = JSON.parse(request.data); + + expect(requestparse.user.ext.us_privacy).to.equal(uspConsent); + }); + + it('should not have CCPA Consent if not defined', function () { + bidderRequest.uspConsent = undefined + const request = spec.buildRequests(bidRequests, bidderRequest); + const requestparse = JSON.parse(request.data); + expect(requestparse.user.ext.us_privacy).to.be.undefined; + }); + + it('should not include schain when not provided', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + const requestparse = JSON.parse(request.data); + expect(requestparse.source).to.not.exist; + }); + + it('should submit coppa if set in config', function () { + sinon.stub(config, 'getConfig') + .withArgs('coppa') + .returns(true); + const request = spec.buildRequests(bidRequests, bidderRequest); + const requestparse = JSON.parse(request.data); + expect(requestparse.user.coppa).to.equal(1); + config.getConfig.restore(); + }); + + it('should send all UserData data', function () { + const request = spec.buildRequests(bidRequestsUserIds, bidderRequest); + const requestparse = JSON.parse(request.data); + expect(requestparse.user.ext.eids).to.be.an('array'); + expect(requestparse.user.ext.eids[0].uids[0].id).to.equal('123456'); + expect(requestparse.user.ext.digitrust.id).to.equal('DTID'); + }); + + it('should add referer info', function () { + const bidRequest = Object.assign({}, bidRequests[0]) + const bidderRequ = { + refererInfo: { + referer: 'https://connectad.io/page.html', + reachedTop: true, + numIframes: 2, + stack: [ + 'https://connectad.io/page.html', + 'https://connectad.io/iframe1.html', + 'https://connectad.io/iframe2.html' + ] + } + } + const request = spec.buildRequests([bidRequest], bidderRequ); + const requestparse = JSON.parse(request.data); + + expect(requestparse.referrer_info).to.exist; + }); + + it('should populate schain', function () { + const bidRequest = Object.assign({}, bidRequests[0], { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + 'asi': 'reseller1.com', + 'sid': 'absc1', + 'hp': 1 + } + ] + } + }); + + const request = spec.buildRequests([bidRequest], bidderRequest); + const requestparse = JSON.parse(request.data); + expect(requestparse.source.ext.schain).to.deep.equal({ + ver: '1.0', + complete: 1, + nodes: [ + { + 'asi': 'reseller1.com', + 'sid': 'absc1', + 'hp': 1 + } + ] + }); + }); + }); + + describe('bid responses', function () { + it('should return complete bid response', function () { + let serverResponse = { + body: { + decisions: { + '2f95c00074b931': { + adId: '0', + contents: [ + { + body: '<<<---- Creative --->>>' + } + ], + height: '250', + width: '300', + pricing: { + clearPrice: 11.899999999999999 + } + } + } + } + }; + const request = spec.buildRequests(bidRequests, bidderRequest); + const bids = spec.interpretResponse(serverResponse, request); + + expect(bids).to.be.lengthOf(1); + expect(bids[0].cpm).to.equal(11.899999999999999); + expect(bids[0].width).to.equal('300'); + expect(bids[0].height).to.equal('250'); + expect(bids[0].ad).to.have.length.above(1); + }); + + it('should return empty bid response', function () { + let serverResponse = { + body: { + decisions: [] + } + }; + const request = spec.buildRequests(bidRequests, bidderRequest); + const bids = spec.interpretResponse(serverResponse, request); + expect(bids).to.be.lengthOf(0); + }); + + it('should return empty bid response on incorrect size', function () { + let serverResponse = { + body: { + decisions: { + '2f95c00074b931': { + adId: '0', + contents: [ + { + body: '<<<---- Creative --->>>' + } + ], + height: '160', + width: '600', + pricing: { + clearPrice: 0 + } + } + } + } + }; + const request = spec.buildRequests(bidRequests, bidderRequest); + const bids = spec.interpretResponse(serverResponse, request); + expect(bids).to.be.lengthOf(0); + }); + + it('should return empty bid response on 0 cpm', function () { + let serverResponse = { + body: { + decisions: { + '2f95c00074b931': { + adId: '0', + contents: [ + { + body: '<<<---- Creative --->>>' + } + ], + height: '300', + width: '250', + pricing: { + clearPrice: 0 + } + } + } + } + }; + const request = spec.buildRequests(bidRequests, bidderRequest); + const bids = spec.interpretResponse(serverResponse, request); + expect(bids).to.be.lengthOf(0); + }); + + it('should process a deal id', function () { + let serverResponse = { + body: { + decisions: { + '2f95c00074b931': { + adId: '0', + dealid: 'ABC90210', + contents: [ + { + body: '<<<---- Creative --->>>' + } + ], + height: '300', + width: '250', + pricing: { + clearPrice: 11.899999999999999 + } + } + } + } + }; + const request = spec.buildRequests(bidRequests, bidderRequest); + const bids = spec.interpretResponse(serverResponse, request); + expect(bids).to.be.lengthOf(1); + expect(bids[0].dealid).to.equal('ABC90210'); + }); + }); + }); + + describe('getUserSyncs', () => { + let testParams = [ + { + name: 'iframe/no gdpr or ccpa', + arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, null], + expect: { + type: 'iframe', + pixels: ['https://cdn.connectad.io/connectmyusers.php?'] + } + }, + { + name: 'iframe/gdpr', + arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, {gdprApplies: true, consentString: '234234'}], + expect: { + type: 'iframe', + pixels: ['https://cdn.connectad.io/connectmyusers.php?gdpr=1&gdpr_consent=234234&'] + } + }, + { + name: 'iframe/ccpa', + arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, null, 'YN12'], + expect: { + type: 'iframe', + pixels: ['https://cdn.connectad.io/connectmyusers.php?us_privacy=YN12&'] + } + }, + { + name: 'iframe/ccpa & gdpr', + arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, {gdprApplies: true, consentString: '234234'}, 'YN12'], + expect: { + type: 'iframe', + pixels: ['https://cdn.connectad.io/connectmyusers.php?gdpr=1&gdpr_consent=234234&us_privacy=YN12&'] + } + } + ]; + + for (let i = 0; i < testParams.length; i++) { + let currParams = testParams[i]; + it(currParams.name, function () { + const result = spec.getUserSyncs.apply(this, currParams.arguments); + expect(result).to.have.lengthOf(currParams.expect.pixels.length); + for (let ix = 0; ix < currParams.expect.pixels.length; ix++) { + expect(result[ix].url).to.equal(currParams.expect.pixels[ix]); + expect(result[ix].type).to.equal(currParams.expect.type); + } + }); + } + }); +}); From 06045585979e00430ef142eb58fa1ee0582fa1a4 Mon Sep 17 00:00:00 2001 From: relaido <63339139+relaido@users.noreply.github.com> Date: Mon, 13 Apr 2020 13:32:05 +0900 Subject: [PATCH 235/496] Add Relaido Adapter (#5101) * add relaido adapter * remove event listener * fixed UserSyncs and e.data Co-authored-by: ishigami_shingo --- modules/relaidoBidAdapter.js | 303 ++++++++++++++++++ modules/relaidoBidAdapter.md | 48 +++ test/spec/modules/relaidoBidAdapter_spec.js | 324 ++++++++++++++++++++ 3 files changed, 675 insertions(+) create mode 100644 modules/relaidoBidAdapter.js create mode 100644 modules/relaidoBidAdapter.md create mode 100644 test/spec/modules/relaidoBidAdapter_spec.js diff --git a/modules/relaidoBidAdapter.js b/modules/relaidoBidAdapter.js new file mode 100644 index 00000000000..22551877a93 --- /dev/null +++ b/modules/relaidoBidAdapter.js @@ -0,0 +1,303 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; +import { getStorageManager } from '../src/storageManager.js'; + +const BIDDER_CODE = 'relaido'; +const BIDDER_DOMAIN = 'api.relaido.jp'; +const ADAPTER_VERSION = '1.0.0'; +const DEFAULT_TTL = 300; +const UUID_KEY = 'relaido_uuid'; + +const storage = getStorageManager(); + +function isBidRequestValid(bid) { + if (!utils.isSafariBrowser() && !hasUuid()) { + utils.logWarn('uuid is not found.'); + return false; + } + if (!utils.deepAccess(bid, 'params.placementId')) { + utils.logWarn('placementId param is reqeuired.'); + return false; + } + if (hasVideoMediaType(bid)) { + if (!isVideoValid(bid)) { + utils.logWarn('Invalid mediaType video.'); + return false; + } + } else if (hasBannerMediaType(bid)) { + if (!isBannerValid(bid)) { + utils.logWarn('Invalid mediaType banner.'); + return false; + } + } else { + utils.logWarn('Invalid mediaTypes input banner or video.'); + return false; + } + return true; +} + +function buildRequests(validBidRequests, bidderRequest) { + let bidRequests = []; + + for (let i = 0; i < validBidRequests.length; i++) { + const bidRequest = validBidRequests[i]; + const placementId = utils.getBidIdParameter('placementId', bidRequest.params); + const bidDomain = bidRequest.params.domain || BIDDER_DOMAIN; + const bidUrl = `https://${bidDomain}/vast/v1/out/bid/${placementId}`; + const uuid = getUuid(); + const mediaType = getMediaType(bidRequest); + + let payload = { + version: ADAPTER_VERSION, + ref: bidderRequest.refererInfo.referer, + timeout_ms: bidderRequest.timeout, + ad_unit_code: bidRequest.adUnitCode, + auction_id: bidRequest.auctionId, + bidder: bidRequest.bidder, + bidder_request_id: bidRequest.bidderRequestId, + bid_requests_count: bidRequest.bidRequestsCount, + bid_id: bidRequest.bidId, + transaction_id: bidRequest.transactionId, + media_type: mediaType, + uuid: uuid, + }; + + if (hasVideoMediaType(bidRequest)) { + const playerSize = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'); + payload.width = playerSize[0][0]; + payload.height = playerSize[0][1]; + } else if (hasBannerMediaType(bidRequest)) { + const sizes = utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes'); + payload.width = sizes[0][0]; + payload.height = sizes[0][1]; + } + + bidRequests.push({ + method: 'GET', + url: bidUrl, + data: payload, + options: { + withCredentials: true + }, + bidId: bidRequest.bidId, + player: bidRequest.params.player, + width: payload.width, + height: payload.height, + mediaType: mediaType, + }); + } + + return bidRequests; +} + +function interpretResponse(serverResponse, bidRequest) { + const bidResponses = []; + const body = serverResponse.body; + if (!body || body.status != 'ok') { + return []; + } + + if (body.uuid) { + storage.setDataInLocalStorage(UUID_KEY, body.uuid); + } + + const playerUrl = bidRequest.player || body.playerUrl; + const mediaType = bidRequest.mediaType || VIDEO; + + let bidResponse = { + requestId: bidRequest.bidId, + width: bidRequest.width, + height: bidRequest.height, + cpm: body.price, + currency: body.currency, + creativeId: body.creativeId, + dealId: body.dealId || '', + ttl: body.ttl || DEFAULT_TTL, + netRevenue: true, + mediaType: mediaType, + }; + if (mediaType === VIDEO) { + bidResponse.vastXml = body.vast; + bidResponse.renderer = newRenderer(bidRequest.bidId, playerUrl); + } else { + const playerTag = createPlayerTag(playerUrl); + const renderTag = createRenderTag(bidRequest.width, bidRequest.height, body.vast); + bidResponse.ad = `
${playerTag}${renderTag}
`; + } + bidResponses.push(bidResponse); + + return bidResponses; +} + +function getUserSyncs(syncOptions, serverResponses) { + if (!syncOptions.iframeEnabled) { + return []; + } + let syncUrl = `https://${BIDDER_DOMAIN}/tr/v1/prebid/sync.html`; + if (serverResponses.length > 0) { + syncUrl = utils.deepAccess(serverResponses, '0.body.syncUrl') || syncUrl; + } + receiveMessage(); + return [{ + type: 'iframe', + url: syncUrl + }]; +} + +function onBidWon(bid) { + let query = utils.parseQueryStringParameters({ + placement_id: utils.deepAccess(bid, 'params.0.placementId'), + creative_id: utils.deepAccess(bid, 'creativeId'), + price: utils.deepAccess(bid, 'cpm'), + auction_id: utils.deepAccess(bid, 'auctionId'), + bid_id: utils.deepAccess(bid, 'requestId'), + ad_id: utils.deepAccess(bid, 'adId'), + ad_unit_code: utils.deepAccess(bid, 'adUnitCode'), + ref: window.location.href, + }).replace(/\&$/, ''); + const bidDomain = utils.deepAccess(bid, 'params.0.domain') || BIDDER_DOMAIN; + const burl = `https://${bidDomain}/tr/v1/prebid/win.gif?${query}`; + utils.triggerPixel(burl); +} + +function onTimeout(data) { + let query = utils.parseQueryStringParameters({ + placement_id: utils.deepAccess(data, '0.params.0.placementId'), + timeout: utils.deepAccess(data, '0.timeout'), + auction_id: utils.deepAccess(data, '0.auctionId'), + bid_id: utils.deepAccess(data, '0.bidId'), + ad_unit_code: utils.deepAccess(data, '0.adUnitCode'), + ref: window.location.href, + }).replace(/\&$/, ''); + const bidDomain = utils.deepAccess(data, '0.params.0.domain') || BIDDER_DOMAIN; + const timeoutUrl = `https://${bidDomain}/tr/v1/prebid/timeout.gif?${query}`; + utils.triggerPixel(timeoutUrl); +} + +function createPlayerTag(playerUrl) { + return ``; +} + +function createRenderTag(width, height, vast) { + return ``; +}; + +function newRenderer(bidId, playerUrl) { + const renderer = Renderer.install({ + id: bidId, + url: playerUrl, + loaded: false + }); + try { + renderer.setRender(outstreamRender); + } catch (err) { + utils.logWarn('renderer.setRender Error', err); + } + return renderer; +} + +function outstreamRender(bid) { + bid.renderer.push(() => { + window.RelaidoPlayer.renderAd({ + adUnitCode: bid.adUnitCode, + width: bid.width, + height: bid.height, + vastXml: bid.vastXml, + mediaType: bid.mediaType, + }); + }); +} + +function receiveMessage() { + window.addEventListener('message', setUuid); +} + +function setUuid(e) { + if (utils.isPlainObject(e.data) && e.data.relaido_uuid) { + storage.setDataInLocalStorage(UUID_KEY, e.data.relaido_uuid); + window.removeEventListener('message', setUuid); + } +} + +function isBannerValid(bid) { + if (!isMobile()) { + return false; + } + const sizes = utils.deepAccess(bid, 'mediaTypes.banner.sizes'); + if (sizes && utils.isArray(sizes)) { + if (utils.isArray(sizes[0])) { + const width = sizes[0][0]; + const height = sizes[0][1]; + if (width >= 300 && height >= 250) { + return true; + } + } + } + return false; +} + +function isVideoValid(bid) { + const playerSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize'); + if (playerSize && utils.isArray(playerSize) && playerSize.length > 0) { + const context = utils.deepAccess(bid, 'mediaTypes.video.context'); + if (context && context === 'outstream') { + return true; + } + } + return false; +} + +function hasUuid() { + return !!storage.getDataFromLocalStorage(UUID_KEY); +} + +function getUuid() { + return storage.getDataFromLocalStorage(UUID_KEY) || ''; +} + +export function isMobile() { + const ua = navigator.userAgent; + if (ua.indexOf('iPhone') > -1 || ua.indexOf('iPod') > -1 || (ua.indexOf('Android') > -1 && ua.indexOf('Tablet') == -1)) { + return true; + } + return false; +} + +function getMediaType(bid) { + if (hasVideoMediaType(bid)) { + return VIDEO; + } else if (hasBannerMediaType(bid)) { + return BANNER; + } + return ''; +} + +function hasBannerMediaType(bid) { + return !!utils.deepAccess(bid, 'mediaTypes.banner'); +} + +function hasVideoMediaType(bid) { + return !!utils.deepAccess(bid, 'mediaTypes.video'); +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], + isBidRequestValid, + buildRequests, + interpretResponse, + getUserSyncs: getUserSyncs, + onBidWon, + onTimeout +} + +registerBidder(spec); diff --git a/modules/relaidoBidAdapter.md b/modules/relaidoBidAdapter.md new file mode 100644 index 00000000000..459f772c66b --- /dev/null +++ b/modules/relaidoBidAdapter.md @@ -0,0 +1,48 @@ +# Overview + +``` +Module Name: Relaido Bidder Adapter +Module Type: Bidder Adapter +Maintainer: video-dev@cg.relaido.co.jp +``` + +# Description + +Connects to Relaido exchange for bids. + +Relaido bid adapter supports Outstream Video. + +# Test Parameters + +```javascript + var adUnits=[{ + code: 'banner-ad-div', + mediaTypes: { + banner: { + sizes: [ + [300, 250] + ] + } + }, + bids: [{ + bidder: 'relaido', + params: { + placementId: '9900' + } + }] + },{ + code: 'video-ad-player', + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 360] + } + }, + bids: [{ + bidder: 'relaido', + params: { + placementId: '9900' + } + }] + }]; +``` \ No newline at end of file diff --git a/test/spec/modules/relaidoBidAdapter_spec.js b/test/spec/modules/relaidoBidAdapter_spec.js new file mode 100644 index 00000000000..8e72548cc1f --- /dev/null +++ b/test/spec/modules/relaidoBidAdapter_spec.js @@ -0,0 +1,324 @@ +import { expect } from 'chai'; +import { spec } from 'modules/relaidoBidAdapter.js'; +import * as url from 'src/url.js'; +import * as utils from 'src/utils.js'; + +const UUID_KEY = 'relaido_uuid'; +const DEFAULT_USER_AGENT = window.navigator.userAgent; +const MOBILE_USER_AGENT = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Mobile/15E148 Safari/604.1'; + +const setUADefault = () => { window.navigator.__defineGetter__('userAgent', function () { return DEFAULT_USER_AGENT }) }; +const setUAMobile = () => { window.navigator.__defineGetter__('userAgent', function () { return MOBILE_USER_AGENT }) }; + +describe('RelaidoAdapter', function () { + const relaido_uuid = 'hogehoge'; + let bidRequest; + let bidderRequest; + let serverResponse; + let serverRequest; + + beforeEach(function () { + bidRequest = { + bidder: 'relaido', + params: { + placementId: '100000', + }, + mediaTypes: { + video: { + context: 'outstream', + playerSize: [ + [640, 360] + ] + } + }, + adUnitCode: 'test', + bidId: '2ed93003f7bb99', + bidderRequestId: '1c50443387a1f2', + auctionId: '413ed000-8c7a-4ba1-a1fa-9732e006f8c3', + transactionId: '5c2d064c-7b76-42e8-a383-983603afdc45', + bidRequestsCount: 1, + bidderRequestsCount: 1, + bidderWinsCount: 0 + }; + bidderRequest = { + timeout: 1000, + refererInfo: { + referer: 'https://publisher.com/home' + } + }; + serverResponse = { + body: { + status: 'ok', + price: 500, + model: 'vcpm', + currency: 'JPY', + creativeId: 1000, + uuid: relaido_uuid, + vast: '', + playerUrl: 'https://relaido/player.js', + syncUrl: 'https://relaido/sync.html' + } + }; + serverRequest = { + method: 'GET', + bidId: bidRequest.bidId, + width: bidRequest.mediaTypes.video.playerSize[0][0], + height: bidRequest.mediaTypes.video.playerSize[0][1], + mediaType: 'video', + }; + localStorage.setItem(UUID_KEY, relaido_uuid); + }); + + describe('spec.isBidRequestValid', function () { + it('should return true when the required params are passed by video', function () { + expect(spec.isBidRequestValid(bidRequest)).to.equal(true); + }); + + it('should return true when the required params are passed by banner', function () { + setUAMobile(); + bidRequest.mediaTypes = { + banner: { + sizes: [ + [300, 250] + ] + } + }; + expect(spec.isBidRequestValid(bidRequest)).to.equal(true); + setUADefault(); + }); + + it('should return false when the uuid are missing', function () { + localStorage.removeItem(UUID_KEY); + const result = !!(utils.isSafariBrowser()); + expect(spec.isBidRequestValid(bidRequest)).to.equal(result); + }); + + it('should return false when the placementId params are missing', function () { + bidRequest.params.placementId = undefined; + expect(spec.isBidRequestValid(bidRequest)).to.equal(false); + }); + + it('should return false when the mediaType video params are missing', function () { + bidRequest.mediaTypes = { + video: {} + }; + expect(spec.isBidRequestValid(bidRequest)).to.equal(false); + }); + + it('should return false when the mediaType banner params are missing', function () { + setUAMobile(); + bidRequest.mediaTypes = { + banner: {} + }; + expect(spec.isBidRequestValid(bidRequest)).to.equal(false); + setUADefault(); + }); + + it('should return false when the non-mobile', function () { + bidRequest.mediaTypes = { + banner: { + sizes: [ + [300, 250] + ] + } + }; + expect(spec.isBidRequestValid(bidRequest)).to.equal(false); + }); + + it('should return false when the mediaTypes params are missing', function () { + bidRequest.mediaTypes = {}; + expect(spec.isBidRequestValid(bidRequest)).to.equal(false); + }); + }); + + describe('spec.buildRequests', function () { + it('should build bid requests by video', function () { + const bidRequests = spec.buildRequests([bidRequest], bidderRequest); + expect(bidRequests).to.have.lengthOf(1); + const request = bidRequests[0]; + expect(request.method).to.equal('GET'); + expect(request.url).to.equal('https://api.relaido.jp/vast/v1/out/bid/100000'); + expect(request.bidId).to.equal(bidRequest.bidId); + expect(request.width).to.equal(bidRequest.mediaTypes.video.playerSize[0][0]); + expect(request.height).to.equal(bidRequest.mediaTypes.video.playerSize[0][1]); + expect(request.mediaType).to.equal('video'); + expect(request.data.ref).to.equal(bidderRequest.refererInfo.referer); + expect(request.data.timeout_ms).to.equal(bidderRequest.timeout); + expect(request.data.ad_unit_code).to.equal(bidRequest.adUnitCode); + expect(request.data.auction_id).to.equal(bidRequest.auctionId); + expect(request.data.bidder).to.equal(bidRequest.bidder); + expect(request.data.bidder_request_id).to.equal(bidRequest.bidderRequestId); + expect(request.data.bid_requests_count).to.equal(bidRequest.bidRequestsCount); + expect(request.data.bid_id).to.equal(bidRequest.bidId); + expect(request.data.transaction_id).to.equal(bidRequest.transactionId); + expect(request.data.media_type).to.equal('video'); + expect(request.data.uuid).to.equal(relaido_uuid); + expect(request.data.width).to.equal(bidRequest.mediaTypes.video.playerSize[0][0]); + expect(request.data.height).to.equal(bidRequest.mediaTypes.video.playerSize[0][1]); + }); + + it('should build bid requests by banner', function () { + bidRequest.mediaTypes = { + banner: { + sizes: [ + [640, 360] + ] + } + }; + const bidRequests = spec.buildRequests([bidRequest], bidderRequest); + expect(bidRequests).to.have.lengthOf(1); + const request = bidRequests[0]; + expect(request.mediaType).to.equal('banner'); + }); + }); + + describe('spec.interpretResponse', function () { + it('should build bid response by video', function () { + const bidResponses = spec.interpretResponse(serverResponse, serverRequest); + expect(bidResponses).to.have.lengthOf(1); + const response = bidResponses[0]; + expect(response.requestId).to.equal(serverRequest.bidId); + expect(response.width).to.equal(serverRequest.width); + expect(response.height).to.equal(serverRequest.height); + expect(response.cpm).to.equal(serverResponse.body.price); + expect(response.currency).to.equal(serverResponse.body.currency); + expect(response.creativeId).to.equal(serverResponse.body.creativeId); + expect(response.vastXml).to.equal(serverResponse.body.vast); + expect(response.ad).to.be.undefined; + }); + + it('should build bid response by banner', function () { + serverRequest.mediaType = 'banner'; + const bidResponses = spec.interpretResponse(serverResponse, serverRequest); + expect(bidResponses).to.have.lengthOf(1); + const response = bidResponses[0]; + expect(response.requestId).to.equal(serverRequest.bidId); + expect(response.width).to.equal(serverRequest.width); + expect(response.height).to.equal(serverRequest.height); + expect(response.cpm).to.equal(serverResponse.body.price); + expect(response.currency).to.equal(serverResponse.body.currency); + expect(response.creativeId).to.equal(serverResponse.body.creativeId); + expect(response.vastXml).to.be.undefined; + expect(response.ad).to.include(`
`); + expect(response.ad).to.include(``); + expect(response.ad).to.include(`window.RelaidoPlayer.renderAd`); + }); + + it('should not build bid response', function () { + serverResponse = {}; + const bidResponses = spec.interpretResponse(serverResponse, serverRequest); + expect(bidResponses).to.have.lengthOf(0); + }); + + it('should not build bid response', function () { + serverResponse = { + body: { + status: 'no_ad', + } + }; + const bidResponses = spec.interpretResponse(serverResponse, serverRequest); + expect(bidResponses).to.have.lengthOf(0); + }); + }); + + describe('spec.getUserSyncs', function () { + it('should choose iframe sync urls', function () { + let userSyncs = spec.getUserSyncs({iframeEnabled: true}, [serverResponse]); + expect(userSyncs).to.deep.equal([{ + type: 'iframe', + url: serverResponse.body.syncUrl + }]); + }); + + it('should choose iframe sync urls if serverResponse are empty', function () { + let userSyncs = spec.getUserSyncs({iframeEnabled: true}, []); + expect(userSyncs).to.deep.equal([{ + type: 'iframe', + url: 'https://api.relaido.jp/tr/v1/prebid/sync.html' + }]); + }); + + it('should choose iframe sync urls if syncUrl are undefined', function () { + serverResponse.body.syncUrl = undefined; + let userSyncs = spec.getUserSyncs({iframeEnabled: true}, [serverResponse]); + expect(userSyncs).to.deep.equal([{ + type: 'iframe', + url: 'https://api.relaido.jp/tr/v1/prebid/sync.html' + }]); + }); + + it('should return empty if iframeEnabled are false', function () { + let userSyncs = spec.getUserSyncs({iframeEnabled: false}, [serverResponse]); + expect(userSyncs).to.have.lengthOf(0); + }); + }); + + describe('spec.onBidWon', function () { + let stub; + beforeEach(() => { + stub = sinon.stub(utils, 'triggerPixel'); + }); + afterEach(() => { + stub.restore(); + }); + + it('Should create nurl pixel if bid nurl', function () { + let bid = { + bidder: bidRequest.bidder, + creativeId: serverResponse.body.creativeId, + cpm: serverResponse.body.price, + params: [bidRequest.params], + auctionId: bidRequest.auctionId, + requestId: bidRequest.bidId, + adId: '3b286a4db7031f', + adUnitCode: bidRequest.adUnitCode, + ref: window.location.href, + } + spec.onBidWon(bid); + const parser = url.parse(stub.getCall(0).args[0]); + const query = parser.search; + expect(parser.hostname).to.equal('api.relaido.jp'); + expect(parser.pathname).to.equal('/tr/v1/prebid/win.gif'); + expect(query.placement_id).to.equal('100000'); + expect(query.creative_id).to.equal('1000'); + expect(query.price).to.equal('500'); + expect(query.auction_id).to.equal('413ed000-8c7a-4ba1-a1fa-9732e006f8c3'); + expect(query.bid_id).to.equal('2ed93003f7bb99'); + expect(query.ad_id).to.equal('3b286a4db7031f'); + expect(query.ad_unit_code).to.equal('test'); + expect(query.ref).to.include(window.location.href); + }); + }); + + describe('spec.onTimeout', function () { + let stub; + beforeEach(() => { + stub = sinon.stub(utils, 'triggerPixel'); + }); + afterEach(() => { + stub.restore(); + }); + + it('Should create nurl pixel if bid nurl', function () { + const data = [{ + bidder: bidRequest.bidder, + bidId: bidRequest.bidId, + adUnitCode: bidRequest.adUnitCode, + auctionId: bidRequest.auctionId, + params: [bidRequest.params], + timeout: bidderRequest.timeout, + }]; + spec.onTimeout(data); + const parser = url.parse(stub.getCall(0).args[0]); + const query = parser.search; + expect(parser.hostname).to.equal('api.relaido.jp'); + expect(parser.pathname).to.equal('/tr/v1/prebid/timeout.gif'); + expect(query.placement_id).to.equal('100000'); + expect(query.timeout).to.equal('1000'); + expect(query.auction_id).to.equal('413ed000-8c7a-4ba1-a1fa-9732e006f8c3'); + expect(query.bid_id).to.equal('2ed93003f7bb99'); + expect(query.ad_unit_code).to.equal('test'); + expect(query.ref).to.include(window.location.href); + }); + }); +}); From 5eac19632da09ed2f4852a0b497a24140ba6a773 Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Mon, 13 Apr 2020 17:43:11 +0530 Subject: [PATCH 236/496] fix circle ci failing tests (#5113) --- test/spec/modules/relaidoBidAdapter_spec.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/spec/modules/relaidoBidAdapter_spec.js b/test/spec/modules/relaidoBidAdapter_spec.js index 8e72548cc1f..f0d3a2fb6d8 100644 --- a/test/spec/modules/relaidoBidAdapter_spec.js +++ b/test/spec/modules/relaidoBidAdapter_spec.js @@ -1,6 +1,5 @@ import { expect } from 'chai'; import { spec } from 'modules/relaidoBidAdapter.js'; -import * as url from 'src/url.js'; import * as utils from 'src/utils.js'; const UUID_KEY = 'relaido_uuid'; @@ -275,7 +274,7 @@ describe('RelaidoAdapter', function () { ref: window.location.href, } spec.onBidWon(bid); - const parser = url.parse(stub.getCall(0).args[0]); + const parser = utils.parseUrl(stub.getCall(0).args[0]); const query = parser.search; expect(parser.hostname).to.equal('api.relaido.jp'); expect(parser.pathname).to.equal('/tr/v1/prebid/win.gif'); @@ -309,7 +308,7 @@ describe('RelaidoAdapter', function () { timeout: bidderRequest.timeout, }]; spec.onTimeout(data); - const parser = url.parse(stub.getCall(0).args[0]); + const parser = utils.parseUrl(stub.getCall(0).args[0]); const query = parser.search; expect(parser.hostname).to.equal('api.relaido.jp'); expect(parser.pathname).to.equal('/tr/v1/prebid/timeout.gif'); From 7438f5a407cbca36ae994a14d39d5f291cbdbba8 Mon Sep 17 00:00:00 2001 From: harpere Date: Mon, 13 Apr 2020 08:21:09 -0400 Subject: [PATCH 237/496] minor consentManagement fix (#5050) Co-authored-by: Eric Harper --- modules/consentManagement.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/consentManagement.js b/modules/consentManagement.js index 39ebea01500..4a1fa9ba8d0 100644 --- a/modules/consentManagement.js +++ b/modules/consentManagement.js @@ -99,7 +99,7 @@ function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { if (success) { if (tcfData.eventStatus === 'tcloaded' || tcfData.eventStatus === 'useractioncomplete') { cmpSuccess(tcfData, hookConfig); - } else if (tcfData.eventStatus === 'cmpuishown' && tcfData.tcString.length > 0 && tcfData.purposeOneTreatment === true) { + } else if (tcfData.eventStatus === 'cmpuishown' && tcfData.tcString && tcfData.purposeOneTreatment === true) { cmpSuccess(tcfData, hookConfig); } } else { From 758abf31b472309a59a87afd9459e49905efc1ad Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Mon, 13 Apr 2020 08:27:26 -0700 Subject: [PATCH 238/496] PubMatic adapter to support image sync (#5104) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * little revamp in iframe user sync code * added support for image based sync as well --- modules/pubmaticBidAdapter.js | 12 +++-- test/spec/modules/pubmaticBidAdapter_spec.js | 49 +++++++++++++++----- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 2c1024b6fe3..e9ae90bdc50 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -6,7 +6,8 @@ import {config} from '../src/config.js'; const BIDDER_CODE = 'pubmatic'; const LOG_WARN_PREFIX = 'PubMatic: '; const ENDPOINT = 'https://hbopenbid.pubmatic.com/translator?source=prebid-client'; -const USYNCURL = 'https://ads.pubmatic.com/AdServer/js/showad.js#PIX&kdntuid=1&p='; +const USER_SYNC_URL_IFRAME = 'https://ads.pubmatic.com/AdServer/js/showad.js#PIX&kdntuid=1&p='; +const USER_SYNC_URL_IMAGE = 'https://image8.pubmatic.com/AdServer/ImgSync?p='; const DEFAULT_CURRENCY = 'USD'; const AUCTION_TYPE = 1; const PUBMATIC_DIGITRUST_KEY = 'nFIn8aLzbd'; @@ -1057,7 +1058,7 @@ export const spec = { * Register User Sync. */ getUserSyncs: (syncOptions, responses, gdprConsent, uspConsent) => { - let syncurl = USYNCURL + publisherId; + let syncurl = '' + publisherId; // Attaching GDPR Consent Params in UserSync url if (gdprConsent) { @@ -1078,10 +1079,13 @@ export const spec = { if (syncOptions.iframeEnabled) { return [{ type: 'iframe', - url: syncurl + url: USER_SYNC_URL_IFRAME + syncurl }]; } else { - utils.logWarn(LOG_WARN_PREFIX + 'Please enable iframe based user sync.'); + return [{ + type: 'image', + url: USER_SYNC_URL_IMAGE + syncurl + }]; } }, diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 533edb33858..d840d2527bd 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -2711,37 +2711,53 @@ describe('PubMatic adapter', function () { }); describe('getUserSyncs', function() { - const syncurl = 'https://ads.pubmatic.com/AdServer/js/showad.js#PIX&kdntuid=1&p=5670'; + const syncurl_iframe = 'https://ads.pubmatic.com/AdServer/js/showad.js#PIX&kdntuid=1&p=5670'; + const syncurl_image = 'https://image8.pubmatic.com/AdServer/ImgSync?p=5670'; let sandbox; beforeEach(function () { sandbox = sinon.sandbox.create(); }); afterEach(function() { sandbox.restore(); - }) + }); - it('execute only if iframeEnabled', function() { + it('execute as per config', function() { expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, undefined)).to.deep.equal([{ - type: 'iframe', url: syncurl + type: 'iframe', url: syncurl_iframe + }]); + expect(spec.getUserSyncs({ iframeEnabled: false }, {}, undefined, undefined)).to.deep.equal([{ + type: 'image', url: syncurl_image }]); - expect(spec.getUserSyncs({ iframeEnabled: false }, {}, undefined, undefined)).to.equal(undefined); }); it('CCPA/USP', function() { expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, '1NYN')).to.deep.equal([{ - type: 'iframe', url: `${syncurl}&us_privacy=1NYN` + type: 'iframe', url: `${syncurl_iframe}&us_privacy=1NYN` + }]); + expect(spec.getUserSyncs({ iframeEnabled: false }, {}, undefined, '1NYN')).to.deep.equal([{ + type: 'image', url: `${syncurl_image}&us_privacy=1NYN` }]); }); it('GDPR', function() { expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, undefined)).to.deep.equal([{ - type: 'iframe', url: `${syncurl}&gdpr=1&gdpr_consent=foo` + type: 'iframe', url: `${syncurl_iframe}&gdpr=1&gdpr_consent=foo` }]); expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: false, consentString: 'foo'}, undefined)).to.deep.equal([{ - type: 'iframe', url: `${syncurl}&gdpr=0&gdpr_consent=foo` + type: 'iframe', url: `${syncurl_iframe}&gdpr=0&gdpr_consent=foo` }]); expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.deep.equal([{ - type: 'iframe', url: `${syncurl}&gdpr=1&gdpr_consent=` + type: 'iframe', url: `${syncurl_iframe}&gdpr=1&gdpr_consent=` + }]); + + expect(spec.getUserSyncs({ iframeEnabled: false }, {}, {gdprApplies: true, consentString: 'foo'}, undefined)).to.deep.equal([{ + type: 'image', url: `${syncurl_image}&gdpr=1&gdpr_consent=foo` + }]); + expect(spec.getUserSyncs({ iframeEnabled: false }, {}, {gdprApplies: false, consentString: 'foo'}, undefined)).to.deep.equal([{ + type: 'image', url: `${syncurl_image}&gdpr=0&gdpr_consent=foo` + }]); + expect(spec.getUserSyncs({ iframeEnabled: false }, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.deep.equal([{ + type: 'image', url: `${syncurl_image}&gdpr=1&gdpr_consent=` }]); }); @@ -2753,7 +2769,10 @@ describe('PubMatic adapter', function () { return config[key]; }); expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, undefined)).to.deep.equal([{ - type: 'iframe', url: `${syncurl}&coppa=1` + type: 'iframe', url: `${syncurl_iframe}&coppa=1` + }]); + expect(spec.getUserSyncs({ iframeEnabled: false }, {}, undefined, undefined)).to.deep.equal([{ + type: 'image', url: `${syncurl_image}&coppa=1` }]); }); @@ -2765,7 +2784,10 @@ describe('PubMatic adapter', function () { return config[key]; }); expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, undefined)).to.deep.equal([{ - type: 'iframe', url: `${syncurl}` + type: 'iframe', url: `${syncurl_iframe}` + }]); + expect(spec.getUserSyncs({ iframeEnabled: false }, {}, undefined, undefined)).to.deep.equal([{ + type: 'image', url: `${syncurl_image}` }]); }); @@ -2777,7 +2799,10 @@ describe('PubMatic adapter', function () { return config[key]; }); expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, '1NYN')).to.deep.equal([{ - type: 'iframe', url: `${syncurl}&gdpr=1&gdpr_consent=foo&us_privacy=1NYN&coppa=1` + type: 'iframe', url: `${syncurl_iframe}&gdpr=1&gdpr_consent=foo&us_privacy=1NYN&coppa=1` + }]); + expect(spec.getUserSyncs({ iframeEnabled: false }, {}, {gdprApplies: true, consentString: 'foo'}, '1NYN')).to.deep.equal([{ + type: 'image', url: `${syncurl_image}&gdpr=1&gdpr_consent=foo&us_privacy=1NYN&coppa=1` }]); }); }); From 6c26b5b286ffe9874dd8e3f5682b82b26aa208df Mon Sep 17 00:00:00 2001 From: vladi-mmg Date: Mon, 13 Apr 2020 20:47:40 +0300 Subject: [PATCH 239/496] Marsmedia - Add vastXml and fix id response (#5067) * Change publisherId to zoneId Add gdpr Add supply chain Add video media type * Remove comments * Fix unit test coverage * fix request id bug add vastXml to video response * Remove bid response default sizes * Change endpoint url * Add unit test for vastXml --- modules/marsmediaBidAdapter.js | 15 ++++--- test/spec/modules/marsmediaBidAdapter_spec.js | 39 +++++++++++++++++-- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/modules/marsmediaBidAdapter.js b/modules/marsmediaBidAdapter.js index 146e1495782..0d0526778ff 100644 --- a/modules/marsmediaBidAdapter.js +++ b/modules/marsmediaBidAdapter.js @@ -16,7 +16,7 @@ function MarsmediaAdapter() { let SUPPORTED_VIDEO_API = [1, 2, 5]; let slotsToBids = {}; let that = this; - let version = '2.1'; + let version = '2.2'; this.isBidRequestValid = function (bid) { return !!(bid.params && bid.params.zoneId); @@ -172,7 +172,7 @@ function MarsmediaAdapter() { } }, at: 1, - tmax: 1000, + tmax: 650, regs: { ext: { gdpr: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? Boolean(bidderRequest.gdprConsent.gdprApplies & 1) : false @@ -203,7 +203,7 @@ function MarsmediaAdapter() { return []; } - var uri = 'https://bid306.rtbsrv.com/bidder/?bid=3mhdom&zoneId=' + fallbackZoneId; + var uri = 'https://hb.azeriondigital.com/bidder/?bid=3mhdom&zoneId=' + fallbackZoneId; var fat = /(^v|(\.0)+$)/gi; var prebidVersion = '$prebid.version$'; @@ -240,7 +240,7 @@ function MarsmediaAdapter() { let bid = responses[i]; let bidRequest = slotsToBids[bid.impid]; let bidResponse = { - requestId: bidRequest.id, + requestId: bidRequest.bidId, bidderCode: that.code, cpm: parseFloat(bid.price), width: bid.w, @@ -252,12 +252,17 @@ function MarsmediaAdapter() { }; if (bidRequest.mediaTypes && bidRequest.mediaTypes.video) { - bidResponse.vastUrl = bid.adm; + if (bid.adm.charAt(0) === '<') { + bidResponse.vastXml = bid.adm; + } else { + bidResponse.vastUrl = bid.adm; + } bidResponse.mediaType = 'video'; bidResponse.ttl = 600; } else { bidResponse.ad = bid.adm; } + bids.push(bidResponse); } diff --git a/test/spec/modules/marsmediaBidAdapter_spec.js b/test/spec/modules/marsmediaBidAdapter_spec.js index 553a3b19c55..c43c5daaa7c 100644 --- a/test/spec/modules/marsmediaBidAdapter_spec.js +++ b/test/spec/modules/marsmediaBidAdapter_spec.js @@ -38,7 +38,7 @@ describe('marsmedia adapter tests', function () { var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - expect(bidRequest.url).to.have.string('https://bid306.rtbsrv.com/bidder/?bid=3mhdom&zoneId=9999&hbv='); + expect(bidRequest.url).to.have.string('https://hb.azeriondigital.com/bidder/?bid=3mhdom&zoneId=9999&hbv='); expect(bidRequest.method).to.equal('POST'); const openrtbRequest = JSON.parse(bidRequest.data); expect(openrtbRequest.site).to.not.equal(null); @@ -108,7 +108,7 @@ describe('marsmedia adapter tests', function () { var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - expect(bidRequest.url).to.have.string('https://bid306.rtbsrv.com/bidder/?bid=3mhdom&zoneId=9999&hbv='); + expect(bidRequest.url).to.have.string('https://hb.azeriondigital.com/bidder/?bid=3mhdom&zoneId=9999&hbv='); expect(bidRequest.method).to.equal('POST'); const openrtbRequest = JSON.parse(bidRequest.data); expect(openrtbRequest.site).to.not.equal(null); @@ -127,7 +127,7 @@ describe('marsmedia adapter tests', function () { expect(openrtbRequest.imp[0].video.api).to.eql([1, 2, 5]); }); - it('interpretResponse works', function() { + it('interpretResponse with vast url works', function() { var bidList = { 'body': [ { @@ -159,6 +159,39 @@ describe('marsmedia adapter tests', function () { expect(bid.cpm).to.equal(1.0); expect(bid.ttl).to.equal(600); }); + + it('interpretResponse with xml works', function() { + var bidList = { + 'body': [ + { + 'impid': 'div-gpt-ad-1438287399331-1', + 'price': 1, + 'adm': '', + 'adomain': [ + 'test.com' + ], + 'cid': '467415', + 'crid': 'cr-vid', + 'w': 800, + 'h': 600 + } + ] + }; + + var videoBids = r1adapter.interpretResponse(bidList); + + expect(videoBids.length).to.equal(1); + const bid = videoBids[0]; + expect(bid.width).to.equal(800); + expect(bid.height).to.equal(600); + expect(bid.vastXml).to.equal(''); + expect(bid.mediaType).to.equal('video'); + expect(bid.creativeId).to.equal('cr-vid'); + expect(bid.currency).to.equal('USD'); + expect(bid.netRevenue).to.equal(true); + expect(bid.cpm).to.equal(1.0); + expect(bid.ttl).to.equal(600); + }); }); describe('misc buildRequests', function() { From bcfca15184892df19265bb6fd98a907974669382 Mon Sep 17 00:00:00 2001 From: Sleiman Jneidi Date: Tue, 14 Apr 2020 05:09:39 +0100 Subject: [PATCH 240/496] Qc/qc usersyncs (#4923) * QC adapter. support usersyncs * cache user sync --- modules/quantcastBidAdapter.js | 23 +++++++ modules/quantcastBidAdapter.md | 10 ++- test/spec/modules/quantcastBidAdapter_spec.js | 62 +++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js index ab7ea54bfb6..fc3c2d400b3 100644 --- a/modules/quantcastBidAdapter.js +++ b/modules/quantcastBidAdapter.js @@ -2,6 +2,7 @@ import * as utils from '../src/utils.js'; import { ajax } from '../src/ajax.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; +import find from 'core-js/library/fn/array/find.js'; const BIDDER_CODE = 'quantcast'; const DEFAULT_BID_FLOOR = 0.0000000001; @@ -80,6 +81,7 @@ export const spec = { code: BIDDER_CODE, GVLID: 11, supportedMediaTypes: ['banner', 'video'], + hasUserSynced: false, /** * Verify the `AdUnits.bids` response with `true` for valid request and `false` @@ -223,6 +225,27 @@ export const spec = { onTimeout(timeoutData) { const url = `${QUANTCAST_PROTOCOL}://${QUANTCAST_DOMAIN}:${QUANTCAST_PORT}/qchb_notify?type=timeout`; ajax(url, null, null); + }, + getUserSyncs(syncOptions, serverResponses) { + const syncs = [] + if (!this.hasUserSynced && syncOptions.pixelEnabled) { + const responseWithUrl = find(serverResponses, serverResponse => + utils.deepAccess(serverResponse.body, 'userSync.url') + ); + + if (responseWithUrl) { + const url = utils.deepAccess(responseWithUrl.body, 'userSync.url') + syncs.push({ + type: 'image', + url: url + }); + } + this.hasUserSynced = true; + } + return syncs; + }, + resetUserSync() { + this.hasUserSynced = false; } }; diff --git a/modules/quantcastBidAdapter.md b/modules/quantcastBidAdapter.md index 2b55eae9026..edbbc538b65 100644 --- a/modules/quantcastBidAdapter.md +++ b/modules/quantcastBidAdapter.md @@ -27,7 +27,10 @@ const adUnits = [{ battr: [1, 2] // OPTIONAL - Array of blocked creative attributes as per OpenRTB Spec List 5.3 } } - ] + ], + userSync: { + url: 'https://quantcast.com/pixelUrl' + } }]; ``` @@ -63,6 +66,9 @@ var adUnits = [{ } } } - ] + ], + userSync: { + url: 'https://quantcast.com/pixelUrl' + } }]; ``` diff --git a/test/spec/modules/quantcastBidAdapter_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js index 5e4093c91be..c02c6fea5a7 100644 --- a/test/spec/modules/quantcastBidAdapter_spec.js +++ b/test/spec/modules/quantcastBidAdapter_spec.js @@ -542,5 +542,67 @@ describe('Quantcast adapter', function () { expect(interpretedResponse.length).to.equal(0); }); + + it('should return pixel url when available userSync available', function () { + const syncOptions = { + pixelEnabled: true + }; + const serverResponses = [ + { + body: { + userSync: { + url: 'http://quantcast.com/pixelUrl' + } + } + }, + { + body: { + + } + } + ]; + + const actualSyncs = qcSpec.getUserSyncs(syncOptions, serverResponses); + const expectedSync = { + type: 'image', + url: 'http://quantcast.com/pixelUrl' + }; + expect(actualSyncs.length).to.equal(1); + expect(actualSyncs[0]).to.deep.equal(expectedSync); + qcSpec.resetUserSync(); + }); + + it('should not return user syncs if done already', function () { + const syncOptions = { + pixelEnabled: true + }; + const serverResponses = [ + { + body: { + userSync: { + url: 'http://quantcast.com/pixelUrl' + } + } + }, + { + body: { + + } + } + ]; + + let actualSyncs = qcSpec.getUserSyncs(syncOptions, serverResponses); + const expectedSync = { + type: 'image', + url: 'http://quantcast.com/pixelUrl' + }; + expect(actualSyncs.length).to.equal(1); + expect(actualSyncs[0]).to.deep.equal(expectedSync); + + actualSyncs = qcSpec.getUserSyncs(syncOptions, serverResponses); + expect(actualSyncs.length).to.equal(0); + + qcSpec.resetUserSync(); + }); }); }); From bddf7e93fbd97c9494db82bd0ad9e35d7118da1c Mon Sep 17 00:00:00 2001 From: Vadim Mazzherin Date: Tue, 14 Apr 2020 15:27:28 +0600 Subject: [PATCH 241/496] ShowHeroes adapter v2 (#5085) * add ShowHeroes Adapter * ShowHeroes adapter - expanded outstream support * Revert "ShowHeroes adapter - expanded outstream support" This reverts commit bfcdb913b52012b5afbf95a84956b906518a4b51. * ShowHeroes adapter - expanded outstream support * ShowHeroes adapter - fixes (#4222) * ShowHeroes adapter - banner and outstream fixes (#4222) * ShowHeroes adapter - description and outstream changes (#4222) * ShowHeroes adapter - increase test coverage and small fix * ShowHeroes Adapter - naming convention issue * Mixed AdUnits declaration support Co-authored-by: veranevera --- modules/showheroes-bsBidAdapter.js | 111 ++++++++++-------- .../modules/showheroes-bsBidAdapter_spec.js | 110 +++++++++++++---- 2 files changed, 153 insertions(+), 68 deletions(-) diff --git a/modules/showheroes-bsBidAdapter.js b/modules/showheroes-bsBidAdapter.js index 2ae7cc56c0f..2831d793aad 100644 --- a/modules/showheroes-bsBidAdapter.js +++ b/modules/showheroes-bsBidAdapter.js @@ -29,6 +29,7 @@ export const spec = { return !!bid.params.playerId; }, buildRequests: function(validBidRequests, bidderRequest) { + let adUnits = []; const pageURL = validBidRequests[0].params.contentPageUrl || bidderRequest.refererInfo.referer; const isStage = !!validBidRequests[0].params.stage; const isOutstream = utils.deepAccess(validBidRequests[0], 'mediaTypes.video.context') === 'outstream'; @@ -38,53 +39,53 @@ export const spec = { const outstreamOptions = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions'); const isBanner = !!validBidRequests[0].mediaTypes.banner || (isOutstream && !(isCustomRender || isNativeRender || isNodeRender)); - let adUnits = validBidRequests.map((bid) => { + validBidRequests.forEach((bid) => { + const videoSizes = getVideoSizes(bid); + const bannerSizes = getBannerSizes(bid); const vpaidMode = utils.getBidIdParameter('vpaidMode', bid.params); - let sizes = bid.sizes.length === 1 ? bid.sizes[0] : bid.sizes; - if (sizes && !sizes.length) { - let mediaSize; - let mediaVideoSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize'); - if (utils.isArray(mediaVideoSize)) { - mediaSize = mediaVideoSize; + const makeBids = (type, size) => { + let context = ''; + let streamType = 2; + + if (type === BANNER) { + streamType = 5; } else { - mediaSize = bid.mediaTypes.banner.sizes; - } - if (utils.isArray(mediaSize[0])) { - sizes = mediaSize[0]; - } else if (utils.isNumber(mediaSize[0])) { - sizes = mediaSize; + context = utils.deepAccess(bid, 'mediaTypes.video.context'); + if (vpaidMode && context === 'instream') { + streamType = 1; + } + if (context === 'outstream') { + streamType = 5; + } } - } - const context = utils.deepAccess(bid, 'mediaTypes.video.context'); - - let streamType = 2; + return { + type: streamType, + bidId: bid.bidId, + mediaType: type, + context: context, + playerId: utils.getBidIdParameter('playerId', bid.params), + auctionId: bidderRequest.auctionId, + bidderCode: BIDDER_CODE, + gdprConsent: bidderRequest.gdprConsent, + start: +new Date(), + timeout: 3000, + size: { + width: size[0], + height: size[1] + }, + params: bid.params, + }; + }; - if (vpaidMode && context === 'instream') { - streamType = 1; - } - if (isBanner || context === 'outstream') { - streamType = 5; - } + videoSizes.forEach((size) => { + adUnits.push(makeBids(VIDEO, size)); + }); - return { - type: streamType, - bidId: bid.bidId, - mediaType: isBanner ? BANNER : VIDEO, - context: context, - playerId: utils.getBidIdParameter('playerId', bid.params), - auctionId: bidderRequest.auctionId, - bidderCode: BIDDER_CODE, - gdprConsent: bidderRequest.gdprConsent, - start: +new Date(), - timeout: 3000, - video: { - width: sizes[0], - height: sizes[1] - }, - params: bid.params, - }; + bannerSizes.forEach((size) => { + adUnits.push(makeBids(BANNER, size)); + }); }); return { @@ -94,6 +95,7 @@ export const spec = { data: { 'user': [], 'meta': { + 'adapterVersion': 2, 'pageURL': encodeURIComponent(pageURL), 'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner && !outstreamOptions) || false, 'isDesktop': utils.getWindowTop().document.documentElement.clientWidth > 700, @@ -156,12 +158,12 @@ function createBids(bidRes, reqData) { bidUnit.cpm = bid.cpm; bidUnit.requestId = bid.bidId; bidUnit.currency = bid.currency; - bidUnit.mediaType = reqBid.mediaType || VIDEO; + bidUnit.mediaType = bid.mediaType || VIDEO; bidUnit.ttl = TTL; bidUnit.creativeId = 'c_' + bid.bidId; bidUnit.netRevenue = true; - bidUnit.width = bid.video.width; - bidUnit.height = bid.video.height; + bidUnit.width = bid.size.width; + bidUnit.height = bid.size.height; if (bid.vastXml) { bidUnit.vastXml = bid.vastXml; bidUnit.adResponse = { @@ -171,16 +173,16 @@ function createBids(bidRes, reqData) { if (bid.vastTag) { bidUnit.vastUrl = bid.vastTag; } - if (reqBid.mediaType === BANNER) { + if (bid.mediaType === BANNER) { bidUnit.ad = getBannerHtml(bid, reqBid, reqData); - } else if (reqBid.context === 'outstream') { + } else if (bid.context === 'outstream') { const renderer = Renderer.install({ id: bid.bidId, url: '//', config: { playerId: reqBid.playerId, - width: bid.video.width, - height: bid.video.height, + width: bid.size.width, + height: bid.size.height, vastUrl: bid.vastTag, vastXml: bid.vastXml, debug: reqData.debug, @@ -267,4 +269,19 @@ function getBannerHtml (bid, reqBid, reqData) { `; } +function getVideoSizes(bidRequest) { + return formatSizes(utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize') || []); +} + +function getBannerSizes(bidRequest) { + return formatSizes(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes || []); +} + +function formatSizes(sizes) { + if (!sizes || !sizes.length) { + return [] + } + return Array.isArray(sizes[0]) ? sizes : [sizes]; +} + registerBidder(spec); diff --git a/test/spec/modules/showheroes-bsBidAdapter_spec.js b/test/spec/modules/showheroes-bsBidAdapter_spec.js index c82042469ef..4f2fd9d641a 100644 --- a/test/spec/modules/showheroes-bsBidAdapter_spec.js +++ b/test/spec/modules/showheroes-bsBidAdapter_spec.js @@ -79,6 +79,22 @@ const bidRequestBanner = { } } +const bidRequestBannerMultiSizes = { + ...bidRequestCommonParams, + ...{ + 'mediaTypes': { + 'banner': { + 'sizes': [[640, 360], [480, 320]] + } + } + } +} + +const bidRequestVideoAndBanner = { + ...bidRequestBanner, + ...bidRequestVideo +} + describe('shBidAdapter', function () { const adapter = newBidder(spec) @@ -120,8 +136,8 @@ describe('shBidAdapter', function () { }], bidderRequest) const payload = request.data.requests[0]; expect(payload).to.be.an('object'); - expect(payload.video).to.have.property('width', 640); - expect(payload.video).to.have.property('height', 480); + expect(payload.size).to.have.property('width', 640); + expect(payload.size).to.have.property('height', 480); const request2 = spec.buildRequests([{ 'params': {}, @@ -130,8 +146,8 @@ describe('shBidAdapter', function () { }], bidderRequest) const payload2 = request2.data.requests[0]; expect(payload).to.be.an('object'); - expect(payload2.video).to.have.property('width', 320); - expect(payload2.video).to.have.property('height', 240); + expect(payload2.size).to.have.property('width', 320); + expect(payload2.size).to.have.property('height', 240); }) it('should get size from mediaTypes when sizes property is empty', function () { @@ -146,8 +162,8 @@ describe('shBidAdapter', function () { }], bidderRequest) const payload = request.data.requests[0]; expect(payload).to.be.an('object'); - expect(payload.video).to.have.property('width', 640); - expect(payload.video).to.have.property('height', 480); + expect(payload.size).to.have.property('width', 640); + expect(payload.size).to.have.property('height', 480); const request2 = spec.buildRequests([{ 'params': {}, @@ -160,8 +176,8 @@ describe('shBidAdapter', function () { }], bidderRequest) const payload2 = request2.data.requests[0]; expect(payload).to.be.an('object'); - expect(payload2.video).to.have.property('width', 320); - expect(payload2.video).to.have.property('height', 240); + expect(payload2.size).to.have.property('width', 320); + expect(payload2.size).to.have.property('height', 240); }) it('should attach valid params to the payload when type is video', function () { @@ -191,6 +207,38 @@ describe('shBidAdapter', function () { expect(payload).to.have.property('type', 5); }) + it('should attach valid params to the payload when type is banner (multi sizes)', function () { + const request = spec.buildRequests([bidRequestBannerMultiSizes], bidderRequest) + const payload = request.data.requests[0]; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd'); + expect(payload).to.have.property('mediaType', BANNER); + expect(payload).to.have.property('type', 5); + expect(payload).to.have.nested.property('size.width', 640); + expect(payload).to.have.nested.property('size.height', 360); + const payload2 = request.data.requests[1]; + expect(payload2).to.be.an('object'); + expect(payload2).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd'); + expect(payload2).to.have.property('mediaType', BANNER); + expect(payload2).to.have.property('type', 5); + expect(payload2).to.have.nested.property('size.width', 480); + expect(payload2).to.have.nested.property('size.height', 320); + }) + + it('should attach valid params to the payload when type is banner and video', function () { + const request = spec.buildRequests([bidRequestVideoAndBanner], bidderRequest) + const payload = request.data.requests[0]; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd'); + expect(payload).to.have.property('mediaType', VIDEO); + expect(payload).to.have.property('type', 2); + const payload2 = request.data.requests[1]; + expect(payload2).to.be.an('object'); + expect(payload2).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd'); + expect(payload2).to.have.property('mediaType', BANNER); + expect(payload2).to.have.property('type', 5); + }) + it('passes gdpr if present', function () { const request = spec.buildRequests([bidRequestVideo], {...bidderRequest, ...gdpr}) const payload = request.data.requests[0]; @@ -208,16 +256,36 @@ describe('shBidAdapter', function () { const vastTag = 'https://video-library.stage.showheroes.com/commercial/wrapper?player_id=47427aa0-f11a-4d24-abca-1295a46a46cd&ad_bidder=showheroes-bs&master_shadt=1&description_url=https%3A%2F%2Fbid-service.stage.showheroes.com%2Fvast%2Fad%2Fcache%2F4840b920-40e1-4e09-9231-60bbf088c8d6' const vastXml = '' - const response = { + const basicResponse = { + 'cpm': 5, + 'currency': 'EUR', + 'mediaType': VIDEO, + 'context': 'instream', + 'bidId': '38b373e1e31c18', + 'size': {'width': 640, 'height': 480}, + 'vastTag': 'https:\/\/video-library.stage.showheroes.com\/commercial\/wrapper?player_id=47427aa0-f11a-4d24-abca-1295a46a46cd&ad_bidder=showheroes-bs&master_shadt=1&description_url=https%3A%2F%2Fbid-service.stage.showheroes.com%2Fvast%2Fad%2Fcache%2F4840b920-40e1-4e09-9231-60bbf088c8d6', + 'vastXml': vastXml, + }; + + const responseVideo = { 'bids': [{ - 'cpm': 5, - 'currency': 'EUR', - 'bidId': '38b373e1e31c18', - 'video': {'width': 640, 'height': 480}, - 'vastTag': 'https:\/\/video-library.stage.showheroes.com\/commercial\/wrapper?player_id=47427aa0-f11a-4d24-abca-1295a46a46cd&ad_bidder=showheroes-bs&master_shadt=1&description_url=https%3A%2F%2Fbid-service.stage.showheroes.com%2Fvast%2Fad%2Fcache%2F4840b920-40e1-4e09-9231-60bbf088c8d6', - 'vastXml': vastXml, + ...basicResponse, }], - } + }; + + const responseVideoOutstream = { + 'bids': [{ + ...basicResponse, + 'context': 'outstream', + }], + }; + + const responseBanner = { + 'bids': [{ + ...basicResponse, + 'mediaType': BANNER, + }], + }; it('should get correct bid response when type is video', function () { const request = spec.buildRequests([bidRequestVideo], bidderRequest) @@ -240,14 +308,14 @@ describe('shBidAdapter', function () { } ] - const result = spec.interpretResponse({'body': response}, request) + const result = spec.interpretResponse({'body': responseVideo}, request) expect(result).to.deep.equal(expectedResponse) }) it('should get correct bid response when type is banner', function () { const request = spec.buildRequests([bidRequestBanner], bidderRequest) - const result = spec.interpretResponse({'body': response}, request) + const result = spec.interpretResponse({'body': responseBanner}, request) expect(result[0]).to.have.property('mediaType', BANNER); expect(result[0].ad).to.include('', 'adId': '33e9500b21129f', @@ -571,7 +659,7 @@ describe('Improve Digital Adapter Tests', function () { } ]; - let expectedTwoBids = [ + const expectedTwoBids = [ expectedBid[0], { 'ad': '', @@ -588,7 +676,7 @@ describe('Improve Digital Adapter Tests', function () { } ]; - let expectedBidNative = [ + const expectedBidNative = [ { mediaType: 'native', adId: '33e9500b21129f', @@ -637,7 +725,7 @@ describe('Improve Digital Adapter Tests', function () { } ]; - let expectedBidVideo = [ + const expectedBidInstreamVideo = [ { 'vastXml': '', 'adId': '33e9500b21129f', @@ -653,60 +741,72 @@ describe('Improve Digital Adapter Tests', function () { } ]; - it('should return a well-formed bid', function () { - const bids = spec.interpretResponse(serverResponse); + const expectedBidOutstreamVideo = utils.deepClone(expectedBidInstreamVideo); + expectedBidOutstreamVideo[0].adResponse = { + content: expectedBidOutstreamVideo[0].vastXml, + height: expectedBidOutstreamVideo[0].height, + width: expectedBidOutstreamVideo[0].width + }; + + it('should return a well-formed display bid', function () { + const bids = spec.interpretResponse(serverResponse, {bidderRequest}); + expect(bids).to.deep.equal(expectedBid); + }); + + it('should return a well-formed display bid for multi-format ad unit', function () { + const bids = spec.interpretResponse(serverResponse, {bidderRequest: multiFormatBidderRequest}); expect(bids).to.deep.equal(expectedBid); }); it('should return two bids', function () { - const bids = spec.interpretResponse(serverResponseTwoBids); + const bids = spec.interpretResponse(serverResponseTwoBids, {bidderRequest}); expect(bids).to.deep.equal(expectedTwoBids); }); it('should set dealId correctly', function () { - let response = JSON.parse(JSON.stringify(serverResponse)); + const response = JSON.parse(JSON.stringify(serverResponse)); let bids; delete response.body.bid[0].lid; response.body.bid[0].buying_type = 'deal_id'; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].dealId).to.not.exist; response.body.bid[0].lid = 268515; delete response.body.bid[0].buying_type; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].dealId).to.not.exist; response.body.bid[0].lid = 268515; response.body.bid[0].buying_type = 'classic'; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].dealId).to.not.exist; response.body.bid[0].lid = 268515; response.body.bid[0].buying_type = 'deal_id'; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].dealId).to.equal(268515); response.body.bid[0].lid = [ 268515, 12456, 34567 ]; response.body.bid[0].buying_type = 'deal_id'; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].dealId).to.not.exist; response.body.bid[0].lid = [ 268515, 12456, 34567 ]; response.body.bid[0].buying_type = [ 'deal_id', 'classic' ]; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].dealId).to.not.exist; response.body.bid[0].lid = [ 268515, 12456, 34567 ]; response.body.bid[0].buying_type = [ 'classic', 'deal_id', 'deal_id' ]; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].dealId).to.equal(12456); }); it('should set currency', function () { - let response = JSON.parse(JSON.stringify(serverResponse)); + const response = JSON.parse(JSON.stringify(serverResponse)); response.body.bid[0].currency = 'eur'; - const bids = spec.interpretResponse(response); + const bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].currency).to.equal('EUR'); }); @@ -716,41 +816,41 @@ describe('Improve Digital Adapter Tests', function () { // Price missing or 0 response.body.bid[0].price = 0; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids).to.deep.equal([]); delete response.body.bid[0].price; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids).to.deep.equal([]); response.body.bid[0].price = null; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids).to.deep.equal([]); // errorCode present response = JSON.parse(JSON.stringify(serverResponse)); response.body.bid[0].errorCode = undefined; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids).to.deep.equal([]); // adm and native missing response = JSON.parse(JSON.stringify(serverResponse)); delete response.body.bid[0].adm; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids).to.deep.equal([]); response.body.bid[0].adm = null; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); expect(bids).to.deep.equal([]); }); it('should set netRevenue', function () { - let response = JSON.parse(JSON.stringify(serverResponse)); + const response = JSON.parse(JSON.stringify(serverResponse)); response.body.bid[0].isNet = true; - const bids = spec.interpretResponse(response); + const bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].netRevenue).to.equal(true); }); // Native ads it('should return a well-formed native ad bid', function () { - let bids = spec.interpretResponse(serverResponseNative); + let bids = spec.interpretResponse(serverResponseNative, {bidderRequest}); expect(bids[0].ortbNative).to.deep.equal(serverResponseNative.body.bid[0].native); delete bids[0].ortbNative; expect(bids).to.deep.equal(expectedBidNative); @@ -764,15 +864,29 @@ describe('Improve Digital Adapter Tests', function () { 'https://www.mytracker.com/imptracker' ]; expectedBids[0].native.javascriptTrackers = ''; - bids = spec.interpretResponse(response); + bids = spec.interpretResponse(response, {bidderRequest}); delete bids[0].ortbNative; expect(bids).to.deep.equal(expectedBids); }); // Video - it('should return a well-formed video bid', function () { - const bids = spec.interpretResponse(serverResponseVideo); - expect(bids).to.deep.equal(expectedBidVideo); + it('should return a well-formed instream video bid', function () { + const bids = spec.interpretResponse(serverResponseVideo, {bidderRequest: instreamBidderRequest}); + expect(bids).to.deep.equal(expectedBidInstreamVideo); + }); + + it('should return a well-formed outstream video bid', function () { + const bids = spec.interpretResponse(serverResponseVideo, {bidderRequest: outstreamBidderRequest}); + expect(bids[0].renderer).to.exist; + delete (bids[0].renderer); + expect(bids).to.deep.equal(expectedBidOutstreamVideo); + }); + + it('should return a well-formed outstream video bid for multi-format ad unit', function () { + const bids = spec.interpretResponse(serverResponseVideo, {bidderRequest: multiFormatBidderRequest}); + expect(bids[0].renderer).to.exist; + delete (bids[0].renderer); + expect(bids).to.deep.equal(expectedBidOutstreamVideo); }); }); From 1e1a720b6e0436cfe7824592f3a44a92b893cb5a Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Tue, 21 Apr 2020 15:37:58 -0700 Subject: [PATCH 265/496] SublimeBidAdapter src/url.js import fix (#5150) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * avoid using src/url.js * avoid using for..of --- modules/sublimeBidAdapter.js | 3 +-- test/spec/modules/colossussspBidAdapter_spec.js | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/sublimeBidAdapter.js b/modules/sublimeBidAdapter.js index 4656eb8d982..1f8cb59f442 100644 --- a/modules/sublimeBidAdapter.js +++ b/modules/sublimeBidAdapter.js @@ -1,7 +1,6 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; import * as utils from '../src/utils.js'; -import * as url from '../src/url.js'; const BIDDER_CODE = 'sublime'; const BIDDER_GVLID = 114; @@ -55,7 +54,7 @@ export function sendEvent(eventName) { log('Sending pixel for event: ' + eventName, eventObject); - const queryString = url.formatQS(eventObject); + const queryString = utils.formatQS(eventObject); utils.triggerPixel('https://' + SUBLIME_ANTENNA + '/?' + queryString); } diff --git a/test/spec/modules/colossussspBidAdapter_spec.js b/test/spec/modules/colossussspBidAdapter_spec.js index bb541d1041d..df9bdcbd47b 100644 --- a/test/spec/modules/colossussspBidAdapter_spec.js +++ b/test/spec/modules/colossussspBidAdapter_spec.js @@ -119,7 +119,8 @@ describe('ColossussspAdapter', function () { expect(placement).to.have.property('eids') expect(placement.eids).to.be.an('array') expect(placement.eids.length).to.be.equal(4) - for (let v of placement.eids) { + for (let index in placement.eids) { + let v = placement.eids[index]; expect(v).to.have.all.keys('source', 'uids') expect(v.source).to.be.oneOf(['britepool.com', 'identityLink', 'adserver.org', 'id5-sync.com']) expect(v.uids).to.be.an('array'); From e8d3119999d19756f426a15d0ba9eb32ad758872 Mon Sep 17 00:00:00 2001 From: redaguermas Date: Wed, 22 Apr 2020 00:50:27 -0700 Subject: [PATCH 266/496] No bid version 1.2.5 (#5137) * Enable supplyChain support * Added support for COPPA * Added support for video ad type * Fix lint errors * Fix lint * Removed "useless condition" * Using ddepAccess and fixed version to 1.2.5 * Fix lint * Fixed vidoe test --- modules/nobidBidAdapter.js | 51 +++++++++---- test/spec/modules/nobidBidAdapter_spec.js | 89 +++++++++++++++++++++++ 2 files changed, 126 insertions(+), 14 deletions(-) diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index dead2d48ed4..dacb76a9a98 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -1,12 +1,12 @@ import * as utils from '../src/utils.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { getStorageManager } from '../src/storageManager.js'; const storage = getStorageManager(); const BIDDER_CODE = 'nobid'; -window.nobidVersion = '1.2.4'; +window.nobidVersion = '1.2.5'; window.nobid = window.nobid || {}; window.nobid.bidResponses = window.nobid.bidResponses || {}; window.nobid.timeoutTotal = 0; @@ -156,9 +156,6 @@ function nobidBuildRequests(bids, bidderRequest) { } else { a.g = {}; } - if (adunitObject.companion) { - a.c = adunitObject.companion; - } if (adunitObject.div) { removeByAttrValue(adunits, 'd', adunitObject.div); } @@ -171,9 +168,11 @@ function nobidBuildRequests(bids, bidderRequest) { if (adunitObject.placementId) { a.pid = adunitObject.placementId; } - /* {"BIDDER_ID":{"WxH":"TAG_ID", "WxH":"TAG_ID"}} */ - if (adunitObject.rtb) { - a.rtb = adunitObject.rtb; + if (adunitObject.ad_type) { + a.at = adunitObject.ad_type; + } + if (adunitObject.params) { + a.params = adunitObject.params; } adunits.push(a); return adunits; @@ -197,10 +196,24 @@ function nobidBuildRequests(bids, bidderRequest) { var sizes = bid.sizes; siteId = (typeof bid.params['siteId'] != 'undefined' && bid.params['siteId']) ? bid.params['siteId'] : siteId; var placementId = bid.params['placementId']; - if (siteId && bid.params && bid.params.tags) { - newAdunit({div: divid, sizes: sizes, rtb: bid.params.tags, siteId: siteId, placementId: placementId}, adunits); - } else if (siteId) { - newAdunit({div: divid, sizes: sizes, siteId: siteId, placementId: placementId}, adunits); + + var adType = 'banner'; + const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video'); + const context = utils.deepAccess(bid, 'mediaTypes.video.context'); + if (bid.mediaType === VIDEO || (videoMediaType && context === 'instream')) { + adType = 'video'; + } + + if (siteId) { + newAdunit({ + div: divid, + sizes: sizes, + siteId: siteId, + placementId: placementId, + ad_type: adType, + params: bid.params + }, + adunits); } } if (siteId) { @@ -246,8 +259,18 @@ function nobidInterpretResponse(response, bidRequest) { netRevenue: true, ttl: 300, ad: bid.adm, - mediaType: BANNER + mediaType: bid.atype || BANNER, }; + if (bid.vastUrl) { + bidResponse.vastUrl = bid.vastUrl; + } + if (bid.vastXml) { + bidResponse.vastXml = bid.vastXml; + } + if (bid.videoCacheKey) { + bidResponse.videoCacheKey = bid.videoCacheKey; + } + bidResponses.push(bidResponse); } return bidResponses; @@ -266,7 +289,7 @@ window.nobid.renderTag = function(doc, id, win) { } export const spec = { code: BIDDER_CODE, - supportedMediaTypes: [BANNER], + supportedMediaTypes: [BANNER, VIDEO], /** * Determines whether or not the given bid request is valid. * diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js index 8d119461d6a..afbc46f862f 100644 --- a/test/spec/modules/nobidBidAdapter_spec.js +++ b/test/spec/modules/nobidBidAdapter_spec.js @@ -50,6 +50,95 @@ describe('Nobid Adapter', function () { }); }); + describe('isVideoBidRequestValid', function () { + let bid = { + bidder: 'nobid', + params: { + siteId: 2, + video: { + skippable: true, + playback_methods: ['auto_play_sound_off'], + position: 'atf', + mimes: ['video/x-flv', 'video/mp4', 'video/x-ms-wmv', 'application/x-shockwave-flash', 'application/javascript'], + minduration: 1, + maxduration: 30, + frameworks: [1, 2, 3, 4, 5, 6] + } + }, + adUnitCode: 'adunit-code', + sizes: [[640, 480]], + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + mediaTypes: { + video: { + context: 'instream' + } + } + }; + const SITE_ID = 2; + const REFERER = 'https://www.examplereferer.com'; + let bidRequests = [ + { + bidder: 'nobid', + params: { + siteId: SITE_ID, + video: { + skippable: true, + playback_methods: ['auto_play_sound_off'], + position: 'atf', + mimes: ['video/x-flv', 'video/mp4', 'video/x-ms-wmv', 'application/x-shockwave-flash', 'application/javascript'], + minduration: 1, + maxduration: 30, + frameworks: [1, 2, 3, 4, 5, 6] + } + }, + adUnitCode: 'adunit-code', + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream' + } + } + } + ]; + + let bidderRequest = { + refererInfo: {referer: REFERER} + } + + it('should add source and version to the tag', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.sid).to.equal(SITE_ID); + expect(payload.l).to.exist.and.to.equal(encodeURIComponent(REFERER)); + expect(payload.a).to.exist; + expect(payload.t).to.exist; + expect(payload.tz).to.exist; + expect(payload.r).to.exist; + expect(payload.lang).to.exist; + expect(payload.ref).to.exist; + expect(payload.a[0].d).to.exist.and.to.equal('adunit-code'); + expect(payload.a[0].at).to.exist.and.to.equal('video'); + expect(payload.a[0].params.video).to.exist; + expect(payload.a[0].params.video.skippable).to.exist.and.to.equal(true); + expect(payload.a[0].params.video.playback_methods).to.exist.and.to.contain('auto_play_sound_off'); + expect(payload.a[0].params.video.position).to.exist.and.to.equal('atf'); + expect(payload.a[0].params.video.mimes).to.exist.and.to.contain('video/x-flv'); + expect(payload.a[0].params.video.minduration).to.exist.and.to.equal(1); + expect(payload.a[0].params.video.maxduration).to.exist.and.to.equal(30); + expect(payload.a[0].params.video.frameworks[0]).to.exist.and.to.equal(1); + expect(payload.a[0].params.video.frameworks[1]).to.exist.and.to.equal(2); + expect(payload.a[0].params.video.frameworks[2]).to.exist.and.to.equal(3); + expect(payload.a[0].params.video.frameworks[3]).to.exist.and.to.equal(4); + expect(payload.a[0].params.video.frameworks[4]).to.exist.and.to.equal(5); + expect(payload.a[0].params.video.frameworks[5]).to.exist.and.to.equal(6); + }); + }); + describe('buildRequests', function () { const SITE_ID = 2; const REFERER = 'https://www.examplereferer.com'; From a7f06034412f256716e846e67667f7a077b98db7 Mon Sep 17 00:00:00 2001 From: Valentin Souche Date: Wed, 22 Apr 2020 17:33:44 +0200 Subject: [PATCH 267/496] Teads fix production GDPR error (#5122) --- modules/teadsBidAdapter.js | 25 ++++++------ test/spec/modules/teadsBidAdapter_spec.js | 48 +++++++++++++++++++++++ 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/modules/teadsBidAdapter.js b/modules/teadsBidAdapter.js index a683eb85cf6..38c261745c7 100644 --- a/modules/teadsBidAdapter.js +++ b/modules/teadsBidAdapter.js @@ -54,7 +54,9 @@ export const spec = { if (bidderRequest && gdpr) { let isCmp = (typeof gdpr.gdprApplies === 'boolean') let isConsentString = (typeof gdpr.consentString === 'string') - let status = isCmp ? findGdprStatus(gdpr) : gdprStatus.CMP_NOT_FOUND_OR_ERROR + let status = isCmp + ? findGdprStatus(gdpr.gdprApplies, gdpr.vendorData, gdpr.apiVersion) + : gdprStatus.CMP_NOT_FOUND_OR_ERROR payload.gdpr_iab = { consent: isConsentString ? gdpr.consentString : '', status: status, @@ -112,21 +114,22 @@ function getReferrerInfo(bidderRequest) { return ref; } -function findGdprStatus(gdprConsent) { - const gdprApplies = gdprConsent.gdprApplies - const gdprData = gdprConsent.vendorData - const apiVersion = gdprConsent.apiVersion - let status = gdprStatus.GDPR_APPLIES_PUBLISHER; - const globalConsent = apiVersion === 1 - ? (gdprData.hasGlobalScope || gdprData.hasGlobalConsent) - : !gdprData.isServiceSpecific - +function findGdprStatus(gdprApplies, gdprData, apiVersion) { + let status = gdprStatus.GDPR_APPLIES_PUBLISHER if (gdprApplies) { - if (globalConsent) status = gdprStatus.GDPR_APPLIES_GLOBAL + if (isGlobalConsent(gdprData, apiVersion)) status = gdprStatus.GDPR_APPLIES_GLOBAL } else status = gdprStatus.GDPR_DOESNT_APPLY return status; } +function isGlobalConsent(gdprData, apiVersion) { + return gdprData && apiVersion === 1 + ? (gdprData.hasGlobalScope || gdprData.hasGlobalConsent) + : gdprData && apiVersion === 2 + ? !gdprData.isServiceSpecific + : false +} + function buildRequestObject(bid) { const reqObj = {}; let placementId = utils.getValue(bid.params, 'placementId'); diff --git a/test/spec/modules/teadsBidAdapter_spec.js b/test/spec/modules/teadsBidAdapter_spec.js index d424e998994..e21dce9135a 100644 --- a/test/spec/modules/teadsBidAdapter_spec.js +++ b/test/spec/modules/teadsBidAdapter_spec.js @@ -264,6 +264,54 @@ describe('teadsBidAdapter', () => { expect(payload.gdpr_iab.apiVersion).to.equal(1); }); + it('should send GDPR to endpoint with 0 status when gdprApplies = false (vendorData = undefined)', function() { + let consentString = 'JRJ8RKfDeBNsERRDCSAAZ+A=='; + let bidderRequest = { + 'auctionId': '1d1a030790a475', + 'bidderRequestId': '22edbae2733bf6', + 'timeout': 3000, + 'gdprConsent': { + 'consentString': undefined, + 'gdprApplies': false, + 'vendorData': undefined, + 'apiVersion': 1 + } + }; + + const request = spec.buildRequests(bidRequests, bidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.gdpr_iab).to.exist; + expect(payload.gdpr_iab.consent).to.equal(''); + expect(payload.gdpr_iab.status).to.equal(0); + expect(payload.gdpr_iab.apiVersion).to.equal(1); + }); + + it('should send GDPR to endpoint with 12 status when apiVersion = 0', function() { + let consentString = 'JRJ8RKfDeBNsERRDCSAAZ+A=='; + let bidderRequest = { + 'auctionId': '1d1a030790a475', + 'bidderRequestId': '22edbae2733bf6', + 'timeout': 3000, + 'gdprConsent': { + 'consentString': consentString, + 'gdprApplies': true, + 'vendorData': { + 'hasGlobalScope': false + }, + 'apiVersion': 0 + } + }; + + const request = spec.buildRequests(bidRequests, bidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.gdpr_iab).to.exist; + expect(payload.gdpr_iab.consent).to.equal(consentString); + expect(payload.gdpr_iab.status).to.equal(12); + expect(payload.gdpr_iab.apiVersion).to.equal(0); + }); + it('should use good mediaTypes video playerSizes', function() { const mediaTypesPlayerSize = { 'mediaTypes': { From 916b1a6e2afe4e26d9460d5bc35023bdc422b6c2 Mon Sep 17 00:00:00 2001 From: Filip Stamenkovic Date: Wed, 22 Apr 2020 17:37:38 +0200 Subject: [PATCH 268/496] use customSlotMatching func for reseting targeting (#5132) --- src/prebid.js | 2 +- src/targeting.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/prebid.js b/src/prebid.js index 480e3afa6fc..aa2f3bad334 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -278,7 +278,7 @@ $$PREBID_GLOBAL$$.setTargetingForGPTAsync = function (adUnit, customSlotMatching let targetingSet = targeting.getAllTargeting(adUnit); // first reset any old targeting - targeting.resetPresetTargeting(adUnit); + targeting.resetPresetTargeting(adUnit, customSlotMatching); // now set new targeting keys targeting.setTargetingForGPT(targetingSet, customSlotMatching); diff --git a/src/targeting.js b/src/targeting.js index d960d800a25..f843dd13a6a 100644 --- a/src/targeting.js +++ b/src/targeting.js @@ -110,16 +110,18 @@ export function newTargeting(auctionManager) { latestAuctionForAdUnit[adUnitCode] = auctionId; }; - targeting.resetPresetTargeting = function(adUnitCode) { + targeting.resetPresetTargeting = function(adUnitCode, customSlotMatching) { if (isGptPubadsDefined()) { const adUnitCodes = getAdUnitCodes(adUnitCode); const adUnits = auctionManager.getAdUnits().filter(adUnit => includes(adUnitCodes, adUnit.code)); window.googletag.pubads().getSlots().forEach(slot => { + let customSlotMatchingFunc = utils.isFn(customSlotMatching) && customSlotMatching(slot); pbTargetingKeys.forEach(function(key) { // reset only registered adunits adUnits.forEach(function(unit) { if (unit.code === slot.getAdUnitPath() || - unit.code === slot.getSlotElementId()) { + unit.code === slot.getSlotElementId() || + (utils.isFn(customSlotMatchingFunc) && customSlotMatchingFunc(unit.code))) { slot.setTargeting(key, null); } }); From 0decdce5ea261e8f60e35f1bf56aedd3e1113fe1 Mon Sep 17 00:00:00 2001 From: oasis <2394426+bmwcmw@users.noreply.github.com> Date: Wed, 22 Apr 2020 19:19:41 +0200 Subject: [PATCH 269/496] Add warning messages for publishers while native ads send assets containing url without sendId (#5096) * Check sendId parameter for native ads and warn if missing on required assets * Extract checking method and test Co-authored-by: mi.chen --- modules/criteoBidAdapter.js | 18 ++- test/spec/modules/criteoBidAdapter_spec.js | 130 ++++++++++++++++++++- 2 files changed, 144 insertions(+), 4 deletions(-) diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js index 6eca0c95dde..eca1000536c 100644 --- a/modules/criteoBidAdapter.js +++ b/modules/criteoBidAdapter.js @@ -8,13 +8,14 @@ import { verify } from 'criteo-direct-rsa-validate/build/verify.js'; import { getStorageManager } from '../src/storageManager.js'; const GVLID = 91; -export const ADAPTER_VERSION = 27; +export const ADAPTER_VERSION = 28; const BIDDER_CODE = 'criteo'; const CDB_ENDPOINT = 'https://bidder.criteo.com/cdb'; const CRITEO_VENDOR_ID = 91; const PROFILE_ID_INLINE = 207; export const PROFILE_ID_PUBLISHERTAG = 185; const storage = getStorageManager(GVLID); +const LOG_PREFIX = 'Criteo: '; // Unminified source code can be found in: https://github.com/Prebid-org/prebid-js-external-js-criteo/blob/master/dist/prod.js const PUBLISHER_TAG_URL = 'https://static.criteo.net/js/ld/publishertag.prebid.js'; @@ -245,6 +246,16 @@ function buildCdbUrl(context) { return url; } +function checkNativeSendId(bidRequest) { + return !(bidRequest.nativeParams && + ((bidRequest.nativeParams.image && bidRequest.nativeParams.image.sendId !== true) || + (bidRequest.nativeParams.icon && bidRequest.nativeParams.icon.sendId !== true) || + (bidRequest.nativeParams.clickUrl && bidRequest.nativeParams.clickUrl.sendId !== true) || + (bidRequest.nativeParams.displayUrl && bidRequest.nativeParams.displayUrl.sendId !== true) || + (bidRequest.nativeParams.privacyLink && bidRequest.nativeParams.privacyLink.sendId !== true) || + (bidRequest.nativeParams.privacyIcon && bidRequest.nativeParams.privacyIcon.sendId !== true))); +} + /** * @param {CriteoContext} context * @param {BidRequest[]} bidRequests @@ -279,6 +290,9 @@ function buildCdbRequest(context, bidRequests, bidderRequest) { } if (bidRequest.params.nativeCallback || utils.deepAccess(bidRequest, `mediaTypes.${NATIVE}`)) { slot.native = true; + if (!checkNativeSendId(bidRequest)) { + utils.logWarn(LOG_PREFIX + 'all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)'); + } } if (hasVideoMediaType(bidRequest)) { const video = { @@ -287,7 +301,7 @@ function buildCdbRequest(context, bidRequests, bidderRequest) { protocols: bidRequest.mediaTypes.video.protocols, maxduration: bidRequest.mediaTypes.video.maxduration, api: bidRequest.mediaTypes.video.api - } + }; video.skip = bidRequest.params.video.skip; video.placement = bidRequest.params.video.placement; diff --git a/test/spec/modules/criteoBidAdapter_spec.js b/test/spec/modules/criteoBidAdapter_spec.js index b1319871b34..10f9bc935eb 100755 --- a/test/spec/modules/criteoBidAdapter_spec.js +++ b/test/spec/modules/criteoBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { tryGetCriteoFastBid, spec, PROFILE_ID_PUBLISHERTAG, ADAPTER_VERSION, PUBLISHER_TAG_URL } from 'modules/criteoBidAdapter.js'; +import { tryGetCriteoFastBid, spec, PROFILE_ID_PUBLISHERTAG, ADAPTER_VERSION } from 'modules/criteoBidAdapter.js'; import { createBid } from 'src/bidfactory.js'; import CONSTANTS from 'src/constants.json'; import * as utils from 'src/utils.js'; @@ -533,7 +533,7 @@ describe('The Criteo bidding adapter', function () { expect(ortbRequest.gdprConsent).to.equal(undefined); }); - it('should properly build request with undefined gdpr consent fields when they are not provided', function () { + it('should properly build a request with undefined gdpr consent fields when they are not provided', function () { const bidRequests = [ { bidder: 'criteo', @@ -1166,6 +1166,132 @@ describe('The Criteo bidding adapter', function () { }); }); + describe('when pubtag prebid adapter is not available', function () { + it('should not warn if sendId is provided on required fields for native bidRequest', () => { + const bidderRequest = { }; + const bidRequestsWithSendId = [ + { + bidder: 'criteo', + adUnitCode: 'bid-123', + transactionId: 'transaction-123', + sizes: [[728, 90]], + params: { + zoneId: 123, + publisherSubId: '123', + nativeCallback: function() {} + }, + nativeParams: { + image: { + sendId: true + }, + icon: { + sendId: true + }, + clickUrl: { + sendId: true + }, + displayUrl: { + sendId: true + }, + privacyLink: { + sendId: true + }, + privacyIcon: { + sendId: true + } + } + } + ]; + + utilsMock.expects('logWarn').withArgs('Criteo: all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)').never(); + const request = spec.buildRequests(bidRequestsWithSendId, bidderRequest); + utilsMock.verify(); + }); + + it('should warn only once if sendId is not provided on required fields for native bidRequest', () => { + const bidderRequest = { }; + const bidRequests = [ + { + bidder: 'criteo', + adUnitCode: 'bid-123', + transactionId: 'transaction-123', + sizes: [[728, 90]], + params: { + zoneId: 123, + publisherSubId: '123', + nativeCallback: function() {} + }, + }, + { + bidder: 'criteo', + adUnitCode: 'bid-456', + transactionId: 'transaction-456', + sizes: [[728, 90]], + params: { + zoneId: 456, + publisherSubId: '456', + nativeCallback: function() {} + }, + }, + ]; + + const nativeParamsWithoutSendId = [ + { + nativeParams: { + image: { + sendId: false + }, + } + }, + { + nativeParams: { + icon: { + sendId: false + }, + } + }, + { + nativeParams: { + clickUrl: { + sendId: false + }, + } + }, + { + nativeParams: { + displayUrl: { + sendId: false + }, + } + }, + { + nativeParams: { + privacyLink: { + sendId: false + }, + } + }, + { + nativeParams: { + privacyIcon: { + sendId: false + }, + } + } + ]; + + utilsMock.expects('logWarn') + .withArgs('Criteo: all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)') + .exactly(nativeParamsWithoutSendId.length * bidRequests.length); + nativeParamsWithoutSendId.forEach(nativeParams => { + let transformedBidRequests = {...bidRequests}; + transformedBidRequests = [Object.assign(transformedBidRequests[0], nativeParams), Object.assign(transformedBidRequests[1], nativeParams)]; + spec.buildRequests(transformedBidRequests, bidderRequest); + }); + utilsMock.verify(); + }); + }); + describe('when pubtag prebid adapter is available', function () { it('should forward response to pubtag when calling interpretResponse', () => { const response = {}; From 2477e86fb606ca263cfd4c9e83fb8c20f105eb80 Mon Sep 17 00:00:00 2001 From: sdao-tl <49252703+sdao-tl@users.noreply.github.com> Date: Wed, 22 Apr 2020 13:02:27 -0700 Subject: [PATCH 270/496] Triplelift: expose tl_souce in bid response (#5139) * expose tl_souce in bid response * update TLL to 300 Co-authored-by: Sy Dao --- modules/tripleliftBidAdapter.js | 3 ++- .../spec/modules/tripleliftBidAdapter_spec.js | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/modules/tripleliftBidAdapter.js b/modules/tripleliftBidAdapter.js index f232915f8f2..8b21f334233 100644 --- a/modules/tripleliftBidAdapter.js +++ b/modules/tripleliftBidAdapter.js @@ -203,7 +203,8 @@ function _buildResponseObject(bidderRequest, bid) { creativeId: creativeId, dealId: dealId, currency: 'USD', - ttl: 33, + ttl: 300, + tl_source: bid.tl_source, }; }; return bidResponse; diff --git a/test/spec/modules/tripleliftBidAdapter_spec.js b/test/spec/modules/tripleliftBidAdapter_spec.js index 428d92345d9..675b8b6c532 100644 --- a/test/spec/modules/tripleliftBidAdapter_spec.js +++ b/test/spec/modules/tripleliftBidAdapter_spec.js @@ -311,7 +311,8 @@ describe('triplelift adapter', function () { width: 300, height: 250, ad: 'ad-markup', - iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg' + iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg', + tl_source: 'tlx', } ] } @@ -327,7 +328,8 @@ describe('triplelift adapter', function () { width: 300, height: 250, ad: 'ad-markup', - iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg' + iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg', + tl_source: 'tlx', } ], refererInfo: { @@ -352,6 +354,7 @@ describe('triplelift adapter', function () { dealId: '', currency: 'USD', ttl: 33, + tl_source: 'tlx', } ]; let result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest}); @@ -369,7 +372,8 @@ describe('triplelift adapter', function () { width: 300, height: 250, ad: 'ad-markup', - iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg' + iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg', + tl_source: 'tlx', }, { imp_id: 0, @@ -377,7 +381,8 @@ describe('triplelift adapter', function () { width: 300, height: 600, ad: 'ad-markup-2', - iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg' + iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg', + tl_source: 'tlx', } ] } @@ -393,7 +398,8 @@ describe('triplelift adapter', function () { width: 300, height: 600, ad: 'ad-markup', - iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg' + iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg', + tl_source: 'tlx', }, { imp_id: 0, @@ -401,7 +407,8 @@ describe('triplelift adapter', function () { width: 300, height: 250, ad: 'ad-markup-2', - iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg' + iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg', + tl_source: 'tlx', } ], refererInfo: { From ae0ab1dd33cdc7d2dad2ad16f3a8a6641f598347 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Wed, 22 Apr 2020 16:36:27 -0700 Subject: [PATCH 271/496] UserId module to export user ids as eids with pbjs.getUserIdsAsEids() (#5108) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * exposing a new function to export userIds in Eids format * added test cases for functions that export userIds * added the missing semicolon :-) --- modules/userId/index.js | 11 +++++++++++ test/spec/modules/userId_spec.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/modules/userId/index.js b/modules/userId/index.js index 4a5c570331f..5de8ad75978 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -382,6 +382,16 @@ function getUserIds() { return getCombinedSubmoduleIds(initializedSubmodules); } +/** + * This function will be exposed in global-name-space so that userIds stored by Prebid UserId module can be used by external codes as well. + * Simple use case will be passing these UserIds to A9 wrapper solution + */ +function getUserIdsAsEids() { + // initialize submodules only when undefined + initializeSubmodulesAndExecuteCallbacks(); + return createEidsArray(getCombinedSubmoduleIds(initializedSubmodules)); +} + /** * This hook returns updated list of submodules which are allowed to do get user id based on TCF 2 enforcement rules configured */ @@ -576,6 +586,7 @@ export function init(config) { // exposing getUserIds function in global-name-space so that userIds stored in Prebid can be used by external codes. (getGlobal()).getUserIds = getUserIds; + (getGlobal()).getUserIdsAsEids = getUserIdsAsEids; } // init config update listener to start the application diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index 41c4841926a..b48d0a9a98c 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -7,10 +7,12 @@ import { syncDelay, coreStorage } from 'modules/userId/index.js'; +import {createEidsArray} from 'modules/userId/eids.js'; import {config} from 'src/config.js'; import * as utils from 'src/utils.js'; import events from 'src/events.js'; import CONSTANTS from 'src/constants.json'; +import {getGlobal} from 'src/prebidGlobal.js'; import {unifiedIdSubmodule} from 'modules/unifiedIdSystem.js'; import {pubCommonIdSubmodule} from 'modules/pubCommonIdSystem.js'; import {britepoolIdSubmodule} from 'modules/britepoolIdSystem.js'; @@ -233,6 +235,36 @@ describe('User ID', function() { }); expect(coreStorage.setCookie.callCount).to.equal(0); }); + + it('pbjs.getUserIds', function() { + setSubmoduleRegistry([pubCommonIdSubmodule]); + init(config); + config.setConfig({ + userSync: { + syncDelay: 0, + userIds: [{ + name: 'pubCommonId', value: {'pubcid': '11111'} + }] + } + }); + expect(typeof (getGlobal()).getUserIds).to.equal('function'); + expect((getGlobal()).getUserIds()).to.deep.equal({pubcid: '11111'}); + }); + + it('pbjs.getUserIdsAsEids', function() { + setSubmoduleRegistry([pubCommonIdSubmodule]); + init(config); + config.setConfig({ + userSync: { + syncDelay: 0, + userIds: [{ + name: 'pubCommonId', value: {'pubcid': '11111'} + }] + } + }); + expect(typeof (getGlobal()).getUserIdsAsEids).to.equal('function'); + expect((getGlobal()).getUserIdsAsEids()).to.deep.equal(createEidsArray((getGlobal()).getUserIds())); + }); }); describe('Opt out', function () { From b5aa77aa13976e53bfbc926d0cf4ac384f17a086 Mon Sep 17 00:00:00 2001 From: trchandraprakash <47793448+trchandraprakash@users.noreply.github.com> Date: Thu, 23 Apr 2020 07:13:59 -0700 Subject: [PATCH 272/496] LunaMedia Adapter (#5110) * Update Bidder Code * LunaMedia Adapater LunaMedia Adapater * Updated LunamediaBidAdapter.md test params and valid pub code for testing Co-authored-by: Chandra Prakash --- modules/advangelistsBidAdapter.js | 0 modules/advangelistsBidAdapter.md | 0 modules/lunamediaBidAdapter.js | 383 ++++++++++++++++++ modules/lunamediaBidAdapter.md | 67 +++ test/spec/modules/lunamediaBidAdapter_spec.js | 137 +++++++ 5 files changed, 587 insertions(+) mode change 100644 => 100755 modules/advangelistsBidAdapter.js mode change 100644 => 100755 modules/advangelistsBidAdapter.md create mode 100755 modules/lunamediaBidAdapter.js create mode 100755 modules/lunamediaBidAdapter.md create mode 100755 test/spec/modules/lunamediaBidAdapter_spec.js diff --git a/modules/advangelistsBidAdapter.js b/modules/advangelistsBidAdapter.js old mode 100644 new mode 100755 diff --git a/modules/advangelistsBidAdapter.md b/modules/advangelistsBidAdapter.md old mode 100644 new mode 100755 diff --git a/modules/lunamediaBidAdapter.js b/modules/lunamediaBidAdapter.js new file mode 100755 index 00000000000..ee431deea1b --- /dev/null +++ b/modules/lunamediaBidAdapter.js @@ -0,0 +1,383 @@ +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; +import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js/library/fn/array/includes.js'; + +const ADAPTER_VERSION = '1.0'; +const BIDDER_CODE = 'lunamedia'; + +export const VIDEO_ENDPOINT = 'https://api.lunamedia.io/xp/get?pubid=';// 0cf8d6d643e13d86a5b6374148a4afac'; +export const BANNER_ENDPOINT = 'https://api.lunamedia.io/xp/get?pubid=';// 0cf8d6d643e13d86a5b6374148a4afac'; +export const OUTSTREAM_SRC = 'https://player-cdn.beachfrontmedia.com/playerapi/loader/outstream.js'; +export const VIDEO_TARGETING = ['mimes', 'playbackmethod', 'maxduration', 'skip']; +export const DEFAULT_MIMES = ['video/mp4', 'application/javascript']; + +let pubid = ''; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], + + isBidRequestValid(bidRequest) { + if (typeof bidRequest != 'undefined') { + if (bidRequest.bidder !== BIDDER_CODE && typeof bidRequest.params === 'undefined') { return false; } + if (bidRequest === '' || bidRequest.params.placement === '' || bidRequest.params.pubid === '') { return false; } + return true; + } else { return false; } + }, + + buildRequests(bids, bidderRequest) { + let requests = []; + let videoBids = bids.filter(bid => isVideoBidValid(bid)); + let bannerBids = bids.filter(bid => isBannerBidValid(bid)); + videoBids.forEach(bid => { + pubid = getVideoBidParam(bid, 'pubid'); + requests.push({ + method: 'POST', + url: VIDEO_ENDPOINT + pubid, + data: createVideoRequestData(bid, bidderRequest), + bidRequest: bid + }); + }); + + bannerBids.forEach(bid => { + pubid = getBannerBidParam(bid, 'pubid'); + requests.push({ + method: 'POST', + url: BANNER_ENDPOINT + pubid, + data: createBannerRequestData(bid, bidderRequest), + bidRequest: bid + }); + }); + return requests; + }, + + interpretResponse(serverResponse, {bidRequest}) { + let response = serverResponse.body; + if (response !== null && utils.isEmpty(response) == false) { + if (isVideoBid(bidRequest)) { + let bidResponse = { + requestId: response.id, + bidderCode: BIDDER_CODE, + cpm: response.seatbid[0].bid[0].price, + width: response.seatbid[0].bid[0].w, + height: response.seatbid[0].bid[0].h, + ttl: response.seatbid[0].bid[0].ttl || 60, + creativeId: response.seatbid[0].bid[0].crid, + currency: response.cur, + mediaType: VIDEO, + netRevenue: true + } + + if (response.seatbid[0].bid[0].adm) { + bidResponse.vastXml = response.seatbid[0].bid[0].adm; + bidResponse.adResponse = { + content: response.seatbid[0].bid[0].adm + }; + } else { + bidResponse.vastUrl = response.seatbid[0].bid[0].nurl; + } + + return bidResponse; + } else { + return { + requestId: response.id, + bidderCode: BIDDER_CODE, + cpm: response.seatbid[0].bid[0].price, + width: response.seatbid[0].bid[0].w, + height: response.seatbid[0].bid[0].h, + ad: response.seatbid[0].bid[0].adm, + ttl: response.seatbid[0].bid[0].ttl || 60, + creativeId: response.seatbid[0].bid[0].crid, + currency: response.cur, + mediaType: BANNER, + netRevenue: true + } + } + } + } +}; + +function isBannerBid(bid) { + return utils.deepAccess(bid, 'mediaTypes.banner') || !isVideoBid(bid); +} + +function isVideoBid(bid) { + return utils.deepAccess(bid, 'mediaTypes.video'); +} + +function isVideoBidValid(bid) { + return isVideoBid(bid) && getVideoBidParam(bid, 'pubid') && getVideoBidParam(bid, 'placement'); +} + +function isBannerBidValid(bid) { + return isBannerBid(bid) && getBannerBidParam(bid, 'pubid') && getBannerBidParam(bid, 'placement'); +} + +function getVideoBidParam(bid, key) { + return utils.deepAccess(bid, 'params.video.' + key) || utils.deepAccess(bid, 'params.' + key); +} + +function getBannerBidParam(bid, key) { + return utils.deepAccess(bid, 'params.banner.' + key) || utils.deepAccess(bid, 'params.' + key); +} + +function isMobile() { + return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent); +} + +function isConnectedTV() { + return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent); +} + +function getDoNotTrack() { + return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNoTrack === '1' || navigator.doNotTrack === 'yes'; +} + +function findAndFillParam(o, key, value) { + try { + if (typeof value === 'function') { + o[key] = value(); + } else { + o[key] = value; + } + } catch (ex) {} +} + +function getOsVersion() { + let clientStrings = [ + { s: 'Android', r: /Android/ }, + { s: 'iOS', r: /(iPhone|iPad|iPod)/ }, + { s: 'Mac OS X', r: /Mac OS X/ }, + { s: 'Mac OS', r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/ }, + { s: 'Linux', r: /(Linux|X11)/ }, + { s: 'Windows 10', r: /(Windows 10.0|Windows NT 10.0)/ }, + { s: 'Windows 8.1', r: /(Windows 8.1|Windows NT 6.3)/ }, + { s: 'Windows 8', r: /(Windows 8|Windows NT 6.2)/ }, + { s: 'Windows 7', r: /(Windows 7|Windows NT 6.1)/ }, + { s: 'Windows Vista', r: /Windows NT 6.0/ }, + { s: 'Windows Server 2003', r: /Windows NT 5.2/ }, + { s: 'Windows XP', r: /(Windows NT 5.1|Windows XP)/ }, + { s: 'UNIX', r: /UNIX/ }, + { s: 'Search Bot', r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/ } + ]; + let cs = find(clientStrings, cs => cs.r.test(navigator.userAgent)); + return cs ? cs.s : 'unknown'; +} + +function getFirstSize(sizes) { + return (sizes && sizes.length) ? sizes[0] : { w: undefined, h: undefined }; +} + +function parseSizes(sizes) { + return utils.parseSizesInput(sizes).map(size => { + let [ width, height ] = size.split('x'); + return { + w: parseInt(width, 10) || undefined, + h: parseInt(height, 10) || undefined + }; + }); +} + +function getVideoSizes(bid) { + return parseSizes(utils.deepAccess(bid, 'mediaTypes.video.playerSize') || bid.sizes); +} + +function getBannerSizes(bid) { + return parseSizes(utils.deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes); +} + +function getTopWindowReferrer() { + try { + return window.top.document.referrer; + } catch (e) { + return ''; + } +} + +function getVideoTargetingParams(bid) { + return Object.keys(Object(bid.params.video)) + .filter(param => includes(VIDEO_TARGETING, param)) + .reduce((obj, param) => { + obj[ param ] = bid.params.video[ param ]; + return obj; + }, {}); +} + +function createVideoRequestData(bid, bidderRequest) { + let topLocation = getTopWindowLocation(bidderRequest); + let topReferrer = getTopWindowReferrer(); + + let sizes = getVideoSizes(bid); + let firstSize = getFirstSize(sizes); + + let video = getVideoTargetingParams(bid); + const o = { + 'device': { + 'langauge': (global.navigator.language).split('-')[0], + 'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0), + 'devicetype': isMobile() ? 4 : isConnectedTV() ? 3 : 2, + 'js': 1, + 'os': getOsVersion() + }, + 'at': 2, + 'site': {}, + 'tmax': 3000, + 'cur': ['USD'], + 'id': bid.bidId, + 'imp': [], + 'regs': { + 'ext': { + } + }, + 'user': { + 'ext': { + } + } + }; + + o.site['page'] = topLocation.href; + o.site['domain'] = topLocation.hostname; + o.site['search'] = topLocation.search; + o.site['domain'] = topLocation.hostname; + o.site['ref'] = topReferrer; + o.site['mobile'] = isMobile() ? 1 : 0; + const secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0; + + o.device['dnt'] = getDoNotTrack() ? 1 : 0; + + findAndFillParam(o.site, 'name', function() { + return global.top.document.title; + }); + + findAndFillParam(o.device, 'h', function() { + return global.screen.height; + }); + findAndFillParam(o.device, 'w', function() { + return global.screen.width; + }); + + let placement = getVideoBidParam(bid, 'placement'); + let floor = getVideoBidParam(bid, 'floor'); + if (floor == null) { floor = 0.5; } + + for (let j = 0; j < sizes.length; j++) { + o.imp.push({ + 'id': '' + j, + 'displaymanager': '' + BIDDER_CODE, + 'displaymanagerver': '' + ADAPTER_VERSION, + 'tagId': placement, + 'bidfloor': floor, + 'bidfloorcur': 'USD', + 'secure': secure, + 'video': Object.assign({ + 'id': utils.generateUUID(), + 'pos': 0, + 'w': firstSize.w, + 'h': firstSize.h, + 'mimes': DEFAULT_MIMES + }, video) + + }); + } + + if (bidderRequest && bidderRequest.gdprConsent) { + let { gdprApplies, consentString } = bidderRequest.gdprConsent; + o.regs.ext = {'gdpr': gdprApplies ? 1 : 0}; + o.user.ext = {'consent': consentString}; + } + + return o; +} + +function getTopWindowLocation(bidderRequest) { + let url = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer; + return utils.parseUrl(config.getConfig('pageUrl') || url, { decodeSearchAsString: true }); +} + +function createBannerRequestData(bid, bidderRequest) { + let topLocation = getTopWindowLocation(bidderRequest); + let topReferrer = getTopWindowReferrer(); + + let sizes = getBannerSizes(bid); + + const o = { + 'device': { + 'langauge': (global.navigator.language).split('-')[0], + 'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0), + 'devicetype': isMobile() ? 4 : isConnectedTV() ? 3 : 2, + 'js': 1 + }, + 'at': 2, + 'site': {}, + 'tmax': 3000, + 'cur': ['USD'], + 'id': bid.bidId, + 'imp': [], + 'regs': { + 'ext': { + } + }, + 'user': { + 'ext': { + } + } + }; + + o.site['page'] = topLocation.href; + o.site['domain'] = topLocation.hostname; + o.site['search'] = topLocation.search; + o.site['domain'] = topLocation.hostname; + o.site['ref'] = topReferrer; + o.site['mobile'] = isMobile() ? 1 : 0; + const secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0; + + o.device['dnt'] = getDoNotTrack() ? 1 : 0; + + findAndFillParam(o.site, 'name', function() { + return global.top.document.title; + }); + + findAndFillParam(o.device, 'h', function() { + return global.screen.height; + }); + findAndFillParam(o.device, 'w', function() { + return global.screen.width; + }); + + let placement = getBannerBidParam(bid, 'placement'); + for (let j = 0; j < sizes.length; j++) { + let size = sizes[j]; + + let floor = getBannerBidParam(bid, 'floor'); + if (floor == null) { floor = 0.1; } + + o.imp.push({ + 'id': '' + j, + 'displaymanager': '' + BIDDER_CODE, + 'displaymanagerver': '' + ADAPTER_VERSION, + 'tagId': placement, + 'bidfloor': floor, + 'bidfloorcur': 'USD', + 'secure': secure, + 'banner': { + 'id': utils.generateUUID(), + 'pos': 0, + 'w': size['w'], + 'h': size['h'] + } + }); + } + + if (bidderRequest && bidderRequest.gdprConsent) { + let { gdprApplies, consentString } = bidderRequest.gdprConsent; + o.regs.ext = {'gdpr': gdprApplies ? 1 : 0}; + o.user.ext = {'consent': consentString}; + } + + return o; +} + +registerBidder(spec); diff --git a/modules/lunamediaBidAdapter.md b/modules/lunamediaBidAdapter.md new file mode 100755 index 00000000000..d0314d0fa41 --- /dev/null +++ b/modules/lunamediaBidAdapter.md @@ -0,0 +1,67 @@ +# Overview + +``` +Module Name: LunaMedia Bidder Adapter +Module Type: Bidder Adapter +Maintainer: lokesh@advangelists.com +``` + +# Description + +Connects to LunaMedia exchange for bids. + +LunaMedia bid adapter supports Banner and Video ads currently. + +For more informatio + +# Sample Display Ad Unit: For Publishers +```javascript + +var displayAdUnit = [ +{ + code: 'display', + mediaTypes: { + banner: { + sizes: [[300, 250],[320, 50]] + } + } + bids: [{ + bidder: 'lunamedia', + params: { + pubid: '121ab139faf7ac67428a23f1d0a9a71b', + placement: 1234 + } + }] +}]; +``` + +# Sample Video Ad Unit: For Publishers +```javascript + +var videoAdUnit = { + code: 'video', + sizes: [320,480], + mediaTypes: { + video: { + playerSize : [[320, 480]], + context: 'instream' + } + }, + bids: [ + { + bidder: 'lunamedia', + params: { + pubid: '121ab139faf7ac67428a23f1d0a9a71b', + placement: 1234, + video: { + id: 123, + skip: 1, + mimes : ['video/mp4', 'application/javascript'], + playbackmethod : [2,6], + maxduration: 30 + } + } + } + ] + }; +``` \ No newline at end of file diff --git a/test/spec/modules/lunamediaBidAdapter_spec.js b/test/spec/modules/lunamediaBidAdapter_spec.js new file mode 100755 index 00000000000..fc8648bf8a0 --- /dev/null +++ b/test/spec/modules/lunamediaBidAdapter_spec.js @@ -0,0 +1,137 @@ +import { expect } from 'chai'; +import { spec } from 'modules/lunamediaBidAdapter.js'; +import { BANNER, VIDEO } from 'src/mediaTypes.js'; + +describe('lunamediaBidAdapter', function () { + let bidRequests; + let bidRequestsVid; + + beforeEach(function () { + bidRequests = [{'bidder': 'lunamedia', 'params': {'pubid': '0cf8d6d643e13d86a5b6374148a4afac', 'floor': 0.5, 'placement': 1234}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'banner': {'sizes': [[300, 250]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': 'f72931e6-2b0e-4e37-a2bc-1ea912141f81', 'sizes': [[300, 250]], 'bidId': '2aa73f571eaf29', 'bidderRequestId': '1bac84515a7af3', 'auctionId': '5dbc60fa-1aa1-41ce-9092-e6bbd4d478f7', 'src': 'client', 'bidRequestsCount': 1, 'pageurl': 'http://google.com'}]; + + bidRequestsVid = [{'bidder': 'lunamedia', 'params': {'pubid': '8537f00948fc37cc03c5f0f88e198a76', 'floor': 1.0, 'placement': 1234, 'video': {'id': 123, 'skip': 1, 'mimes': ['video/mp4', 'application/javascript'], 'playbackmethod': [2, 6], 'maxduration': 30}}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'video': {'playerSize': [[320, 480]], 'context': 'instream'}}, 'adUnitCode': 'video1', 'transactionId': '8b060952-93f7-4863-af44-bb8796b97c42', 'sizes': [], 'bidId': '25c6ab92aa0e81', 'bidderRequestId': '1d420b73a013fc', 'auctionId': '9a69741c-34fb-474c-83e1-cfa003aaee17', 'src': 'client', 'bidRequestsCount': 1, 'pageurl': 'http://google.com'}]; + }); + + describe('spec.isBidRequestValid', function () { + it('should return true when the required params are passed for banner', function () { + const bidRequest = bidRequests[0]; + expect(spec.isBidRequestValid(bidRequest)).to.equal(true); + }); + + it('should return true when the required params are passed for video', function () { + const bidRequests = bidRequestsVid[0]; + expect(spec.isBidRequestValid(bidRequests)).to.equal(true); + }); + + it('should return false when no pub id params are passed', function () { + const bidRequest = bidRequests[0]; + bidRequest.params.pubid = ''; + expect(spec.isBidRequestValid(bidRequest)).to.equal(false); + }); + + it('should return false when no placement params are passed', function () { + const bidRequest = bidRequests[0]; + bidRequest.params.placement = ''; + expect(spec.isBidRequestValid(bidRequest)).to.equal(false); + }); + + it('should return false when a bid request is not passed', function () { + expect(spec.isBidRequestValid()).to.equal(false); + expect(spec.isBidRequestValid({})).to.equal(false); + }); + }); + + describe('spec.buildRequests', function () { + it('should create a POST request for each bid', function () { + const bidRequest = bidRequests[0]; + const requests = spec.buildRequests([ bidRequest ]); + expect(requests[0].method).to.equal('POST'); + }); + + it('should create a POST request for each bid in video request', function () { + const bidRequest = bidRequestsVid[0]; + const requests = spec.buildRequests([ bidRequest ]); + expect(requests[0].method).to.equal('POST'); + }); + + it('should have domain in request', function () { + const bidRequest = bidRequests[0]; + const requests = spec.buildRequests([ bidRequest ]); + expect(requests[0].data.site.domain).length !== 0; + }); + }); + + describe('spec.interpretResponse', function () { + describe('for banner bids', function () { + it('should return no bids if the response is not valid', function () { + const bidRequest = bidRequests[0]; + bidRequest.mediaTypes = { banner: {} }; + const bidResponse = spec.interpretResponse({ body: null }, { bidRequest }); + + if (typeof bidResponse !== 'undefined') { + expect(bidResponse.length).to.equal(0); + } else { + expect(true).to.equal(true); + } + }); + + it('should return no bids if the response is empty', function () { + const bidRequest = bidRequests[0]; + bidRequest.mediaTypes = { banner: {} }; + const bidResponse = spec.interpretResponse({ body: [] }, { bidRequest }); + if (typeof bidResponse !== 'undefined') { + expect(bidResponse.length).to.equal(0); + } else { expect(true).to.equal(true); } + }); + + it('should return valid video bid responses', function () { + let _mediaTypes = VIDEO; + const lunamediabidreqVid = {'bidRequest': {'mediaTypes': {'video': {'w': 320, 'h': 480}}}}; + const serverResponseVid = {'cur': 'USD', 'id': '25c6ab92aa0e81', 'seatbid': [{'seat': '3', 'bid': [{'crid': '1855', 'h': 480, 'protocol': 2, 'nurl': 'http://api.lunamedia.io/xp/evt?pp=1MO1wiaMhhq7wLRzZZwwwPkJxxKpYEnM5k5MH4qSGm1HR8rp3Nl7vDocvzZzSAvE4pnREL9mQ1kf5PDjk6E8em6DOk7vVrYUH1TYQyqCucd58PFpJNN7h30RXKHHFg3XaLuQ3PKfMuI1qZATBJ6WHcu875y0hqRdiewn0J4JsCYF53M27uwmcV0HnQxARQZZ72mPqrW95U6wgkZljziwKrICM3aBV07TU6YK5R5AyzJRuD6mtrQ2xtHlQ3jXVYKE5bvWFiUQd90t0jOGhPtYBNoOfP7uQ4ZZj4pyucxbr96orHe9PSOn9UpCSWArdx7s8lOfDpwOvbMuyGxynbStDWm38sDgd4bMHnIt762m5VMDNJfiUyX0vWzp05OsufJDVEaWhAM62i40lQZo7mWP4ipoOWLkmlaAzFIMsTcNaHAHiKKqGEOZLkCEhFNM0SLcvgN2HFRULOOIZvusq7TydOKxuXgCS91dLUDxDDDFUK83BFKlMkTxnCzkLbIR1bd9GKcr1TRryOrulyvRWAKAIhEsUzsc5QWFUhmI2dZ1eqnBQJ0c89TaPcnoaP2WipF68UgyiOstf2CBy0M34858tC5PmuQwQYwXscg6zyqDwR0i9MzGH4FkTyU5yeOlPcsA0ht6UcoCdFpHpumDrLUwAaxwGk1Nj8S6YlYYT5wNuTifDGbg22QKXzZBkUARiyVvgPn9nRtXnrd7WmiMYq596rya9RQj7LC0auQW8bHVQLEe49shsZDnAwZTWr4QuYKqgRGZcXteG7RVJe0ryBZezOq11ha9C0Lv0siNVBahOXE35Wzoq4c4BDaGpqvhaKN7pjeWLGlQR04ufWekwxiMWAvjmfgAfexBJ7HfbYNZpq__', 'adid': '61_1855', 'adomain': ['chevrolet.com.ar'], 'price': 2, 'w': 320, 'iurl': 'https://daf37cpxaja7f.cloudfront.net/c61/creative_url_14922301369663_1.png', 'cat': ['IAB2'], 'id': '7f570b40-aca1-4806-8ea8-818ea679c82b_0', 'attr': [], 'impid': '0', 'cid': '61'}]}], 'bidid': '7f570b40-aca1-4806-8ea8-818ea679c82b'} + const bidResponseVid = spec.interpretResponse({ body: serverResponseVid }, lunamediabidreqVid); + delete bidResponseVid['vastUrl']; + delete bidResponseVid['ad']; + expect(bidResponseVid).to.deep.equal({ + requestId: bidRequestsVid[0].bidId, + bidderCode: 'lunamedia', + creativeId: serverResponseVid.seatbid[0].bid[0].crid, + cpm: serverResponseVid.seatbid[0].bid[0].price, + width: serverResponseVid.seatbid[0].bid[0].w, + height: serverResponseVid.seatbid[0].bid[0].h, + mediaType: 'video', + currency: 'USD', + netRevenue: true, + ttl: 60 + }); + }); + + it('should return valid banner bid responses', function () { + const lunamediabidreq = {bids: {}}; + bidRequests.forEach(bid => { + let _mediaTypes = (bid.mediaTypes && bid.mediaTypes.video ? VIDEO : BANNER); + lunamediabidreq.bids[bid.bidId] = {mediaTypes: _mediaTypes, + w: _mediaTypes == BANNER ? bid.mediaTypes[_mediaTypes].sizes[0][0] : bid.mediaTypes[_mediaTypes].playerSize[0], + h: _mediaTypes == BANNER ? bid.mediaTypes[_mediaTypes].sizes[0][1] : bid.mediaTypes[_mediaTypes].playerSize[1] + + }; + }); + const serverResponse = {'id': '2aa73f571eaf29', 'seatbid': [{'bid': [{'id': '2c5e8a1a84522d', 'impid': '2c5e8a1a84522d', 'price': 0.81, 'adid': 'abcde-12345', 'nurl': '', 'adm': '
', 'adomain': ['advertiserdomain.com'], 'iurl': '', 'cid': 'campaign1', 'crid': 'abcde-12345', 'w': 300, 'h': 250}], 'seat': '19513bcfca8006'}], 'bidid': '19513bcfca8006', 'cur': 'USD', 'w': 300, 'h': 250}; + + const bidResponse = spec.interpretResponse({ body: serverResponse }, lunamediabidreq); + expect(bidResponse).to.deep.equal({ + requestId: bidRequests[0].bidId, + ad: serverResponse.seatbid[0].bid[0].adm, + bidderCode: 'lunamedia', + creativeId: serverResponse.seatbid[0].bid[0].crid, + cpm: serverResponse.seatbid[0].bid[0].price, + width: serverResponse.seatbid[0].bid[0].w, + height: serverResponse.seatbid[0].bid[0].h, + mediaType: 'banner', + currency: 'USD', + netRevenue: true, + ttl: 60 + }); + }); + }); + }); +}); From 8db2720d60a6533dee52e96f847854ef1c219345 Mon Sep 17 00:00:00 2001 From: Matt Kendall <1870166+mkendall07@users.noreply.github.com> Date: Thu, 23 Apr 2020 16:10:14 -0400 Subject: [PATCH 273/496] Release 3.17.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f8f363cf28f..2bf9219d4ae 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.17.0-pre", + "version": "3.17.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 00a3379aadfcf9cbd0d74c6eb6063dcee9475cff Mon Sep 17 00:00:00 2001 From: Matt Kendall <1870166+mkendall07@users.noreply.github.com> Date: Thu, 23 Apr 2020 16:31:47 -0400 Subject: [PATCH 274/496] 3.18.0-pre --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2bf9219d4ae..79feb816b16 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.17.0", + "version": "3.18.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 7bd447112ec85b752f3ef4a117ede8420e229efa Mon Sep 17 00:00:00 2001 From: vladi-mmg Date: Fri, 24 Apr 2020 01:24:52 +0300 Subject: [PATCH 275/496] Marsmedia Change endpoint URL (#5156) * Change end point * Remove trailing-space --- modules/marsmediaBidAdapter.js | 2 +- test/spec/modules/marsmediaBidAdapter_spec.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/marsmediaBidAdapter.js b/modules/marsmediaBidAdapter.js index 0d0526778ff..b6dc7800dd9 100644 --- a/modules/marsmediaBidAdapter.js +++ b/modules/marsmediaBidAdapter.js @@ -203,7 +203,7 @@ function MarsmediaAdapter() { return []; } - var uri = 'https://hb.azeriondigital.com/bidder/?bid=3mhdom&zoneId=' + fallbackZoneId; + var uri = 'https://hb.go2speed.media/bidder/?bid=3mhdom&zoneId=' + fallbackZoneId; var fat = /(^v|(\.0)+$)/gi; var prebidVersion = '$prebid.version$'; diff --git a/test/spec/modules/marsmediaBidAdapter_spec.js b/test/spec/modules/marsmediaBidAdapter_spec.js index c43c5daaa7c..c0399e5d0a2 100644 --- a/test/spec/modules/marsmediaBidAdapter_spec.js +++ b/test/spec/modules/marsmediaBidAdapter_spec.js @@ -38,7 +38,7 @@ describe('marsmedia adapter tests', function () { var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - expect(bidRequest.url).to.have.string('https://hb.azeriondigital.com/bidder/?bid=3mhdom&zoneId=9999&hbv='); + expect(bidRequest.url).to.have.string('https://hb.go2speed.media/bidder/?bid=3mhdom&zoneId=9999&hbv='); expect(bidRequest.method).to.equal('POST'); const openrtbRequest = JSON.parse(bidRequest.data); expect(openrtbRequest.site).to.not.equal(null); @@ -108,7 +108,7 @@ describe('marsmedia adapter tests', function () { var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - expect(bidRequest.url).to.have.string('https://hb.azeriondigital.com/bidder/?bid=3mhdom&zoneId=9999&hbv='); + expect(bidRequest.url).to.have.string('https://hb.go2speed.media/bidder/?bid=3mhdom&zoneId=9999&hbv='); expect(bidRequest.method).to.equal('POST'); const openrtbRequest = JSON.parse(bidRequest.data); expect(openrtbRequest.site).to.not.equal(null); From e09a2c3fbae4b589fc9114fa03633a5131d7cdb6 Mon Sep 17 00:00:00 2001 From: oasis <2394426+bmwcmw@users.noreply.github.com> Date: Fri, 24 Apr 2020 12:40:54 +0200 Subject: [PATCH 276/496] Improve tcf2 support (#5138) * Fetch gdpr api version from provided consent object * Remove consentGiven boolean * Bump version to 29 and remove unused const Co-authored-by: mi.chen --- modules/criteoBidAdapter.js | 9 +++------ test/spec/modules/criteoBidAdapter_spec.js | 5 ++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js index eca1000536c..5d137c994fe 100644 --- a/modules/criteoBidAdapter.js +++ b/modules/criteoBidAdapter.js @@ -8,10 +8,9 @@ import { verify } from 'criteo-direct-rsa-validate/build/verify.js'; import { getStorageManager } from '../src/storageManager.js'; const GVLID = 91; -export const ADAPTER_VERSION = 28; +export const ADAPTER_VERSION = 29; const BIDDER_CODE = 'criteo'; const CDB_ENDPOINT = 'https://bidder.criteo.com/cdb'; -const CRITEO_VENDOR_ID = 91; const PROFILE_ID_INLINE = 207; export const PROFILE_ID_PUBLISHERTAG = 185; const storage = getStorageManager(GVLID); @@ -259,6 +258,7 @@ function checkNativeSendId(bidRequest) { /** * @param {CriteoContext} context * @param {BidRequest[]} bidRequests + * @param bidderRequest * @return {*} */ function buildCdbRequest(context, bidRequests, bidderRequest) { @@ -328,10 +328,7 @@ function buildCdbRequest(context, bidRequests, bidderRequest) { if (typeof bidderRequest.gdprConsent.gdprApplies !== 'undefined') { request.gdprConsent.gdprApplies = !!(bidderRequest.gdprConsent.gdprApplies); } - if (bidderRequest.gdprConsent.vendorData && bidderRequest.gdprConsent.vendorData.vendorConsents && - typeof bidderRequest.gdprConsent.vendorData.vendorConsents[ CRITEO_VENDOR_ID.toString(10) ] !== 'undefined') { - request.gdprConsent.consentGiven = !!(bidderRequest.gdprConsent.vendorData.vendorConsents[ CRITEO_VENDOR_ID.toString(10) ]); - } + request.gdprConsent.version = bidderRequest.gdprConsent.apiVersion; if (typeof bidderRequest.gdprConsent.consentString !== 'undefined') { request.gdprConsent.consentData = bidderRequest.gdprConsent.consentString; } diff --git a/test/spec/modules/criteoBidAdapter_spec.js b/test/spec/modules/criteoBidAdapter_spec.js index 10f9bc935eb..042f1a4d61d 100755 --- a/test/spec/modules/criteoBidAdapter_spec.js +++ b/test/spec/modules/criteoBidAdapter_spec.js @@ -385,6 +385,7 @@ describe('The Criteo bidding adapter', function () { '91': 1 }, }, + apiVersion: 1, }, }; @@ -436,7 +437,7 @@ describe('The Criteo bidding adapter', function () { expect(ortbRequest.slots[0].zoneid).to.equal(123); expect(ortbRequest.gdprConsent.consentData).to.equal('concentDataString'); expect(ortbRequest.gdprConsent.gdprApplies).to.equal(true); - expect(ortbRequest.gdprConsent.consentGiven).to.equal(true); + expect(ortbRequest.gdprConsent.version).to.equal(1); }); it('should properly build a networkId request', function () { @@ -484,7 +485,6 @@ describe('The Criteo bidding adapter', function () { expect(ortbRequest.slots[0].sizes[1]).to.equal('728x90'); expect(ortbRequest.gdprConsent.consentData).to.equal(undefined); expect(ortbRequest.gdprConsent.gdprApplies).to.equal(false); - expect(ortbRequest.gdprConsent.consentGiven).to.equal(undefined); }); it('should properly build a mixed request', function () { @@ -553,7 +553,6 @@ describe('The Criteo bidding adapter', function () { const ortbRequest = spec.buildRequests(bidRequests, bidderRequest).data; expect(ortbRequest.gdprConsent.consentData).to.equal(undefined); expect(ortbRequest.gdprConsent.gdprApplies).to.equal(undefined); - expect(ortbRequest.gdprConsent.consentGiven).to.equal(undefined); }); it('should properly build a request with ccpa consent field', function () { From 5b8dfa6e5b876eac33a369b1ed677a479a627aea Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Fri, 24 Apr 2020 07:04:04 -0600 Subject: [PATCH 277/496] Remove leftover return value from requestBids (#5160) --- src/prebid.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/prebid.js b/src/prebid.js index aa2f3bad334..f45a15d5f19 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -521,7 +521,6 @@ $$PREBID_GLOBAL$$.requestBids = hook('async', function ({ bidsBackHandler, timeo adUnitCodes.forEach(code => targeting.setLatestAuctionForAdUnit(code, auction.getAuctionId())); auction.callBids(); - return auction; }); export function executeStorageCallbacks(fn, reqBidsConfigObj) { From 0eeaccb41b42b2bd6a5e478a5d63dc8bc0c7ac03 Mon Sep 17 00:00:00 2001 From: gpolaert Date: Mon, 27 Apr 2020 19:06:27 +0200 Subject: [PATCH 278/496] feat: new Pubstack Analytics Module (#5148) * feat: new Pubstack Analytics Module * fix: global name * fix: tests * fix: typo --- modules/pubstackAnalyticsAdapter.js | 15 ++++++++ modules/pubstackAnalyticsAdapter.md | 9 +++++ .../modules/pubstackAnalyticsAdapter_spec.js | 38 +++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 modules/pubstackAnalyticsAdapter.js create mode 100644 modules/pubstackAnalyticsAdapter.md create mode 100644 test/spec/modules/pubstackAnalyticsAdapter_spec.js diff --git a/modules/pubstackAnalyticsAdapter.js b/modules/pubstackAnalyticsAdapter.js new file mode 100644 index 00000000000..b1da40c5b89 --- /dev/null +++ b/modules/pubstackAnalyticsAdapter.js @@ -0,0 +1,15 @@ +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; + +const pubstackAnalytics = adapter({ + global: 'PubstackAnalytics', + handler: 'on', + analyticsType: 'bundle' +}); + +adapterManager.registerAnalyticsAdapter({ + adapter: pubstackAnalytics, + code: 'pubstack', +}); + +export default pubstackAnalytics; diff --git a/modules/pubstackAnalyticsAdapter.md b/modules/pubstackAnalyticsAdapter.md new file mode 100644 index 00000000000..0b473bd39d7 --- /dev/null +++ b/modules/pubstackAnalyticsAdapter.md @@ -0,0 +1,9 @@ +# Overview + +Module Name: Pubstack Analytics Adapter +Module Type: Analytics Adapter +Maintainer: support@pubstack.io + +# Description + +This is the Pubstack Analytics Adapter. [Contact Guillaume from our Support Team](mailto:support@pubstack.io) to start analyzing your HB stack. diff --git a/test/spec/modules/pubstackAnalyticsAdapter_spec.js b/test/spec/modules/pubstackAnalyticsAdapter_spec.js new file mode 100644 index 00000000000..e3db334c888 --- /dev/null +++ b/test/spec/modules/pubstackAnalyticsAdapter_spec.js @@ -0,0 +1,38 @@ +import * as utils from 'src/utils.js'; +import pubstackAnalytics from '../../../modules/pubstackAnalyticsAdapter.js'; +import adapterManager from 'src/adapterManager'; +import events from 'src/events'; +import constants from 'src/constants.json' + +describe('Pubstack Analytics Adapter', () => { + const scope = utils.getWindowSelf(); + let queue = []; + + beforeEach(() => { + scope.PubstackAnalytics = (...args) => queue.push(args); + adapterManager.enableAnalytics({ + provider: 'pubstack' + }); + queue = [] + }); + + afterEach(() => { + pubstackAnalytics.disableAnalytics(); + }); + + it('should forward all events to the queue', () => { + // Given + const args = 'any-args' + + // When + events.emit(constants.EVENTS.AUCTION_END, args) + events.emit(constants.EVENTS.BID_REQUESTED, args) + events.emit(constants.EVENTS.BID_ADJUSTMENT, args) + events.emit(constants.EVENTS.BID_RESPONSE, args) + events.emit(constants.EVENTS.BID_WON, args) + events.emit(constants.EVENTS.NO_BID, args) + + // Then + expect(queue.length).to.eql(6); + }); +}); From a883653965e5067436242e998f3b841491c20e82 Mon Sep 17 00:00:00 2001 From: ColombiaOnline Date: Mon, 27 Apr 2020 22:37:57 +0530 Subject: [PATCH 279/496] New adapter: Colombia (#5158) * Add colombia adapter * Add https in the url * update files * add test cases and update md file * remove native from package.json and update colombia test cases * Use conditions for the size * Use conditions for the size and remove test warnings * remove package.json * Resolved import related errors * update referrer method * remove package json and update referer path * revert package json * Resolved all changes * update version package json * Resolved test cases issues --- modules/colombiaBidAdapter.js | 82 ++++++++++ modules/colombiaBidAdapter.md | 8 +- package-lock.json | 2 +- package.json | 2 +- test/spec/modules/colombiaBidAdapter_spec.js | 152 +++++++++++++++++++ 5 files changed, 242 insertions(+), 4 deletions(-) create mode 100644 modules/colombiaBidAdapter.js mode change 100755 => 100644 package.json create mode 100644 test/spec/modules/colombiaBidAdapter_spec.js diff --git a/modules/colombiaBidAdapter.js b/modules/colombiaBidAdapter.js new file mode 100644 index 00000000000..59257babdbe --- /dev/null +++ b/modules/colombiaBidAdapter.js @@ -0,0 +1,82 @@ +import * as utils from '../src/utils.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +const BIDDER_CODE = 'colombia'; +const ENDPOINT_URL = 'https://ade.clmbtech.com/cde/prebid.htm'; +const HOST_NAME = document.location.protocol + '//' + window.location.host; + +export const spec = { + code: BIDDER_CODE, + aliases: ['clmb'], + supportedMediaTypes: [BANNER], + isBidRequestValid: function(bid) { + return !!(bid.params.placementId); + }, + buildRequests: function(validBidRequests, bidderRequest) { + return validBidRequests.map(bidRequest => { + const params = bidRequest.params; + const sizes = utils.parseSizesInput(bidRequest.sizes)[0]; + const width = sizes.split('x')[0]; + const height = sizes.split('x')[1]; + const placementId = params.placementId; + const cb = Math.floor(Math.random() * 99999999999); + const bidId = bidRequest.bidId; + const referrer = (bidderRequest && bidderRequest.refererInfo) ? bidderRequest.refererInfo.referer : ''; + const payload = { + v: 'hb1', + p: placementId, + w: width, + h: height, + cb: cb, + r: referrer, + uid: bidId, + t: 'i', + d: HOST_NAME, + }; + return { + method: 'POST', + url: ENDPOINT_URL, + data: payload, + } + }); + }, + interpretResponse: function(serverResponse, bidRequest) { + const bidResponses = []; + const response = serverResponse.body; + const crid = response.creativeId || 0; + const width = response.width || 0; + const height = response.height || 0; + let cpm = response.cpm || 0; + if (width == 300 && height == 250) { + cpm = cpm * 0.2; + } + if (width == 320 && height == 50) { + cpm = cpm * 0.55; + } + if (cpm < 1) { + return bidResponses; + } + if (width !== 0 && height !== 0 && cpm !== 0 && crid !== 0) { + const dealId = response.dealid || ''; + const currency = response.currency || 'USD'; + const netRevenue = (response.netRevenue === undefined) ? true : response.netRevenue; + const bidResponse = { + requestId: bidRequest.data.uid, + cpm: cpm, + width: response.width, + height: response.height, + creativeId: crid, + dealId: dealId, + currency: currency, + netRevenue: netRevenue, + ttl: config.getConfig('_bidderTimeout'), + referrer: bidRequest.data.r, + ad: response.ad + }; + bidResponses.push(bidResponse); + } + return bidResponses; + } +} +registerBidder(spec); diff --git a/modules/colombiaBidAdapter.md b/modules/colombiaBidAdapter.md index 2131fcb4c5a..c754e49771d 100644 --- a/modules/colombiaBidAdapter.md +++ b/modules/colombiaBidAdapter.md @@ -10,13 +10,17 @@ Maintainer: colombiaonline@timesinteret.in Connect to COLOMBIA for bids. -THE COLOMBIA adapter requires setup and approval from the COLOMBIA team. Please reach out to your account team or colombiaonline@timesinteret.in for more information. +COLOMBIA adapter requires setup and approval from the COLOMBIA team. Please reach out to your account team or colombiaonline@timesinteret.in for more information. # Test Parameters ``` var adUnits = [{ code: 'test-ad-div', - sizes: [[300, 250]], + mediaTypes: { + banner: { + sizes: [[300, 250],[728,90],[320,50]] + } + }, bids: [{ bidder: 'colombia', params: { diff --git a/package-lock.json b/package-lock.json index 2a9d671e441..0a7b276db79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.12.0", + "version": "3.17.0-pre", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json old mode 100755 new mode 100644 index 79feb816b16..d33d08034f2 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.18.0-pre", + "version": "3.12.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { diff --git a/test/spec/modules/colombiaBidAdapter_spec.js b/test/spec/modules/colombiaBidAdapter_spec.js new file mode 100644 index 00000000000..4e80c6b1d9d --- /dev/null +++ b/test/spec/modules/colombiaBidAdapter_spec.js @@ -0,0 +1,152 @@ +import { expect } from 'chai'; +import { spec } from 'modules/colombiaBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; + +const HOST_NAME = document.location.protocol + '//' + window.location.host; +const ENDPOINT = 'https://ade.clmbtech.com/cde/prebid.htm'; + +describe('colombiaBidAdapter', function() { + const adapter = newBidder(spec); + + describe('isBidRequestValid', function () { + let bid = { + 'bidder': 'colombia', + 'params': { + placementId: '307466' + }, + 'adUnitCode': 'adunit-code', + 'sizes': [ + [300, 250] + ], + 'bidId': '23beaa6af6cdde', + 'bidderRequestId': '19c0c1efdf37e7', + 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', + }; + + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when placementId not passed correctly', function () { + bid.params.placementId = ''; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when require params are not passed', function () { + let bid = Object.assign({}, bid); + bid.params = {}; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + let bidRequests = [ + { + 'bidder': 'colombia', + 'params': { + placementId: '307466' + }, + 'adUnitCode': 'adunit-code1', + 'sizes': [ + [300, 250] + ], + 'bidId': '23beaa6af6cdde', + 'bidderRequestId': '19c0c1efdf37e7', + 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', + }, + { + 'bidder': 'colombia', + 'params': { + placementId: '307466' + }, + 'adUnitCode': 'adunit-code2', + 'sizes': [ + [300, 250] + ], + 'bidId': '382091349b149f"', + 'bidderRequestId': '"1f9c98192de251"', + 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', + } + ]; + + const request = spec.buildRequests(bidRequests); + + it('sends bid request to our endpoint via POST', function () { + expect(request[0].method).to.equal('POST'); + expect(request[1].method).to.equal('POST'); + }); + + it('attaches source and version to endpoint URL as query params', function () { + expect(request[0].url).to.equal(ENDPOINT); + expect(request[1].url).to.equal(ENDPOINT); + }); + }); + + describe('interpretResponse', function () { + let bidRequest = [ + { + 'method': 'POST', + 'url': 'https://ade.clmbtech.com/cde/prebid.htm', + 'data': { + 'v': 'hb1', + 'p': '307466', + 'w': '300', + 'h': '250', + 'cb': 12892917383, + 'r': 'http%3A%2F%2Flocalhost%3A9876%2F%3Fid%3D74552836', + 'uid': '23beaa6af6cdde', + 't': 'i', + } + } + ]; + + let serverResponse = { + body: { + 'ad': '
This is test case for colombia adapter
', + 'cpm': 3.14, + 'creativeId': '6b958110-612c-4b03-b6a9-7436c9f746dc-1sk24', + 'currency': 'USD', + 'uid': '23beaa6af6cdde', + 'width': 728, + 'height': 90, + 'netRevenue': true, + 'ttl': 600, + 'dealid': '', + 'referrer': 'http%3A%2F%2Flocalhost%3A9876%2F%3Fid%3D74552836' + } + }; + + it('should get the correct bid response', function () { + let expectedResponse = [{ + 'requestId': '23beaa6af6cdde', + 'cpm': 3.14, + 'width': 728, + 'height': 90, + 'creativeId': '6b958110-612c-4b03-b6a9-7436c9f746dc-1sk24', + 'dealId': '', + 'currency': 'USD', + 'netRevenue': true, + 'ttl': 300, + 'referrer': 'http%3A%2F%2Flocalhost%3A9876%2F%3Fid%3D74552836', + 'ad': '
This is test case for colombia adapter
' + }]; + let result = spec.interpretResponse(serverResponse, bidRequest[0]); + expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); + }); + + it('handles empty bid response', function () { + let response = { + body: { + 'uid': '23beaa6af6cdde', + 'height': 0, + 'creativeId': '', + 'statusMessage': 'Bid returned empty or error response', + 'width': 0, + 'cpm': 0 + } + }; + let result = spec.interpretResponse(response, bidRequest[0]); + expect(result.length).to.equal(0); + }); + }); +}); From 2621343f06cc362fb87008d3c836a0645f08cde6 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Mon, 27 Apr 2020 11:32:12 -0700 Subject: [PATCH 280/496] PubMatic adding a targeting key for buyid (#5171) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * PubMatic sets bid.adserverTargeting.hb_buyid_pubmatic * documentation note about bid.adserverTargeting.hb_buyid_pubmatic * expect buyid to be in seatbid.ext.buyid --- modules/pubmaticBidAdapter.js | 7 +++++++ modules/pubmaticBidAdapter.md | 4 +++- test/spec/modules/pubmaticBidAdapter_spec.js | 8 ++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index e9ae90bdc50..4502dc66a65 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -1044,6 +1044,13 @@ export const spec = { newBid.meta.clickUrl = bid.adomain[0]; } + // adserverTargeting + if (seatbidder.ext && seatbidder.ext.buyid) { + newBid.adserverTargeting = { + 'hb_buyid_pubmatic': seatbidder.ext.buyid + }; + } + bidResponses.push(newBid); }); }); diff --git a/modules/pubmaticBidAdapter.md b/modules/pubmaticBidAdapter.md index 4a5d881a637..a045bed3e2b 100644 --- a/modules/pubmaticBidAdapter.md +++ b/modules/pubmaticBidAdapter.md @@ -202,5 +202,7 @@ pbjs.setConfig({ ``` Note: Combine the above the configuration with any other UserSync configuration. Multiple setConfig() calls overwrite each other and only last call for a given attribute will take effect. -Note: PubMatic will return a test-bid if "pubmaticTest=true" is present in page URL +# Notes: +- PubMatic will return a test-bid if "pubmaticTest=true" is present in page URL +- PubMatic will set bid.adserverTargeting.hb_buyid_pubmatic targeting key while submitting a bid into Prebid diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index d840d2527bd..817661ef51f 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -534,6 +534,9 @@ describe('PubMatic adapter', function () { 'id': '93D3BAD6-E2E2-49FB-9D89-920B1761C865', 'seatbid': [{ 'seat': 'seat-id', + 'ext': { + 'buyid': 'BUYER-ID-987' + }, 'bid': [{ 'id': '74858439-49D7-4169-BA5D-44A046315B2F', 'impid': '22bddb28db77d', @@ -549,6 +552,9 @@ describe('PubMatic adapter', function () { } }] }, { + 'ext': { + 'buyid': 'BUYER-ID-789' + }, 'bid': [{ 'id': '74858439-49D7-4169-BA5D-44A046315BEF', 'impid': '22bddb28db77e', @@ -2622,6 +2628,7 @@ describe('PubMatic adapter', function () { expect(response[0].netRevenue).to.equal(false); expect(response[0].ttl).to.equal(300); expect(response[0].meta.networkId).to.equal(123); + expect(response[0].adserverTargeting.hb_buyid_pubmatic).to.equal('BUYER-ID-987'); expect(response[0].meta.buyerId).to.equal(976); expect(response[0].meta.clickUrl).to.equal('blackrock.com'); expect(response[0].referrer).to.include(data.site.ref); @@ -2643,6 +2650,7 @@ describe('PubMatic adapter', function () { expect(response[1].netRevenue).to.equal(false); expect(response[1].ttl).to.equal(300); expect(response[1].meta.networkId).to.equal(422); + expect(response[1].adserverTargeting.hb_buyid_pubmatic).to.equal('BUYER-ID-789'); expect(response[1].meta.buyerId).to.equal(832); expect(response[1].meta.clickUrl).to.equal('hivehome.com'); expect(response[1].referrer).to.include(data.site.ref); From 89c72cf17182f1adde832358b975c12c3ebbd150 Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Tue, 28 Apr 2020 17:48:32 +0530 Subject: [PATCH 281/496] restore version property to the latest (#5176) --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a7b276db79..e8387d41383 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.17.0-pre", + "version": "3.18.0-pre", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d33d08034f2..79feb816b16 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.12.0", + "version": "3.18.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 2cfcf9c1acba1fdcbe8f17e94a814311da0602d1 Mon Sep 17 00:00:00 2001 From: kimvc Date: Tue, 28 Apr 2020 16:02:27 +0200 Subject: [PATCH 282/496] Provide more data in Adhese bid response (#5154) * Add support for bidderRequest.refererInfo in Adhese Adapter. * Add support for bidderRequest.refererInfo in Adhese Adapter. * Jira AD-2462 / add tlall is consent string is present * Added 'adhese' attribute to bid that contains meta data - Jira AD-2642 * added DALE to adhese determination * extra config option: no format, but use size array as format string * Added more values to originData * Revert "Added more values to originData" This reverts commit 57f003318cfb7dc2f9d1a97015a7639823b181a6. * Pulled Sander's changes & added more data to originData * Adhese bid adapter - final version Co-authored-by: Mateusz Michalowski Co-authored-by: Mateusz Michalowski Co-authored-by: Tim Sturtewagen Co-authored-by: Kim Van Crombrugge Co-authored-by: Sander --- modules/adheseBidAdapter.js | 6 +++++- test/spec/modules/adheseBidAdapter_spec.js | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js index 2d12f4cdbc2..96a2b52fb9c 100644 --- a/modules/adheseBidAdapter.js +++ b/modules/adheseBidAdapter.js @@ -170,11 +170,15 @@ function getAdDetails(ad) { if (isAdheseAd(ad)) { creativeId = ad.id; dealId = ad.orderId; - originData = { priority: ad.priority, orderProperty: ad.orderProperty, adFormat: ad.adFormat, adType: ad.adType, libId: ad.libId, adspaceId: ad.adspaceId, viewableImpressionCounter: ad.viewableImpressionCounter }; + originData = { priority: ad.priority, orderProperty: ad.orderProperty, adFormat: ad.adFormat, adType: ad.adType, libId: ad.libId, adspaceId: ad.adspaceId, viewableImpressionCounter: ad.viewableImpressionCounter, slotId: ad.slotID, slotName: ad.slotName, advertiserId: ad.advertiserId, adId: ad.id }; } else { creativeId = ad.origin + (ad.originInstance ? '-' + ad.originInstance : ''); if (ad.originData) { originData = ad.originData; + originData.slotId = ad.slotID; + originData.slotName = ad.slotName; + originData.adType = ad.adType; + if (ad.adFormat) originData.adFormat = ad.adFormat; if (ad.originData.seatbid && ad.originData.seatbid.length) { const seatbid = ad.originData.seatbid[0]; if (seatbid.bid && seatbid.bid.length) { diff --git a/test/spec/modules/adheseBidAdapter_spec.js b/test/spec/modules/adheseBidAdapter_spec.js index 81f2a66425f..7392ecd8f4e 100644 --- a/test/spec/modules/adheseBidAdapter_spec.js +++ b/test/spec/modules/adheseBidAdapter_spec.js @@ -120,6 +120,7 @@ describe('AdheseAdapter', function () { origin: 'APPNEXUS', originInstance: '', ext: 'js', + slotID: '10', slotName: '_main_page_-leaderboard', adType: 'leaderboard', originData: { @@ -155,12 +156,15 @@ describe('AdheseAdapter', function () { ttl: TTL, adhese: { originData: { + adType: 'leaderboard', seatbid: [ { bid: [ { crid: '60613369', dealid: null } ], seat: '958' } - ] + ], + slotId: '10', + slotName: '_main_page_-leaderboard' } } }]; @@ -249,12 +253,16 @@ describe('AdheseAdapter', function () { adhese: { originData: { adFormat: 'largeleaderboard', + adId: '742898', adType: 'largeleaderboard', adspaceId: '162363', libId: '90511', orderProperty: undefined, priority: undefined, - viewableImpressionCounter: undefined + viewableImpressionCounter: undefined, + slotId: '29306', + slotName: '_main_page_-leaderboard', + advertiserId: '2081' } }, cpm: 5.96, @@ -304,12 +312,16 @@ describe('AdheseAdapter', function () { adhese: { originData: { adFormat: '', + adId: '742470', adType: 'preroll', adspaceId: '164196', libId: '89860', orderProperty: undefined, priority: undefined, - viewableImpressionCounter: undefined + viewableImpressionCounter: undefined, + slotId: '41711', + slotName: '_main_page_-leaderboard', + advertiserId: '2263', } }, cpm: 0, From a88ff906ab78a43e99f31cdbcfa21706246ed5d3 Mon Sep 17 00:00:00 2001 From: Steve Alliance Date: Tue, 28 Apr 2020 12:43:03 -0400 Subject: [PATCH 283/496] Districtm dmx UID support (#5162) * adding DMX test @97%, two files added one updated * Update districtm_spec.js * Update districtmDMX.js * adding all districtm needed file * remove legacy file * remove typo || 0 in the test method * force default to return a valid width and height * update unit test code for failing test * changed class for an object * remove package-lock.json * change file name for dmx adapter * renamed files * restaure package-lock.json * update to last package-lock state * update gdpr user consent * fix sizes issue * Documentation updates Adding the readme.md info * update file name and update unit testing import file location * current machine state * lint correction * remove variable assigment duplicate * adding CCPA support for DMX * adding test for ccpa and gdpr * districtm dmx adding deal id field * idsync support ccpa & gdpr * adding support uid provide tdid id5 pubCommon digitrust Co-authored-by: Steve Alliance Co-authored-by: Luis Co-authored-by: Steve Alliance Co-authored-by: Steve Alliance Co-authored-by: steve-a-districtm --- modules/districtmDMXBidAdapter.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/districtmDMXBidAdapter.js b/modules/districtmDMXBidAdapter.js index 0dbaf2b2336..03dca0b607d 100644 --- a/modules/districtmDMXBidAdapter.js +++ b/modules/districtmDMXBidAdapter.js @@ -85,6 +85,10 @@ export const spec = { let eids = []; if (bidRequest && bidRequest.userId) { bindUserId(eids, utils.deepAccess(bidRequest, `userId.idl_env`), 'liveramp.com', 1); + bindUserId(eids, utils.deepAccess(bidRequest, `userId.digitrustid.data.id`), 'digitru.st', 1); + bindUserId(eids, utils.deepAccess(bidRequest, `userId.id5id`), 'id5-sync.com', 1); + bindUserId(eids, utils.deepAccess(bidRequest, `userId.pubcid`), 'pubcid.org', 1); + bindUserId(eids, utils.deepAccess(bidRequest, `userId.tdid`), 'adserver.org', 1); dmxRequest.user = dmxRequest.user || {}; dmxRequest.user.ext = dmxRequest.user.ext || {}; dmxRequest.user.ext.eids = eids; From f244450564b95bca27a0bba63d77d2d07c6e6bb5 Mon Sep 17 00:00:00 2001 From: Ignat Khaylov Date: Wed, 29 Apr 2020 05:31:56 +0300 Subject: [PATCH 284/496] Between: fix sizes format & update readme.md (#5168) Co-authored-by: Ignat Khaylov --- modules/betweenBidAdapter.js | 2 +- modules/betweenBidAdapter.md | 191 +++++++++++++------- test/spec/modules/betweenBidAdapter_spec.js | 2 +- 3 files changed, 124 insertions(+), 71 deletions(-) diff --git a/modules/betweenBidAdapter.js b/modules/betweenBidAdapter.js index 521c6cb6f98..72bf592ff77 100644 --- a/modules/betweenBidAdapter.js +++ b/modules/betweenBidAdapter.js @@ -27,7 +27,7 @@ export const spec = { validBidRequests.forEach(i => { let params = { - sizes: parseSizesInput(getAdUnitSizes(i)), + sizes: parseSizesInput(getAdUnitSizes(i)).join('%2C'), jst: 'hb', ord: Math.random() * 10000000000000000, tz: getTz(), diff --git a/modules/betweenBidAdapter.md b/modules/betweenBidAdapter.md index 4aadd31d3a3..4371a8709d8 100644 --- a/modules/betweenBidAdapter.md +++ b/modules/betweenBidAdapter.md @@ -8,94 +8,147 @@ Maintainer: info@betweendigital.com You can use this adapter to get a bid from betweendigital. -About us : http://betweendigital.com +About us : [betweenx.com](https://betweenx.com) +More detailed instructions you can be found on [this page](https://cdn.betweendigital.com/prebid_instructions/index.html) . # Test Parameters + +> The parameters are used as an example: +> s: 3649326 — Between section id; code: ad_slot — id of an iframe element showing prebid ads + ```javascript - var adUnits = [ - { - code: 'ad_slot', - mediaTypes: { - banner: { - sizes: [[970, 250], [240, 400], [728, 90]] - } - }, - bids: [ - { - bidder: "between", - params: { - s: 122938 - } - } - ] - } - ]; +var adUnits = [ + { + code: "ad_slot", + mediaTypes: { + banner: { + sizes: [[240, 400]], + }, + }, + bids: [ + { + bidder: "between", + params: { + s: 3649326, + }, + }, + ], + }, +]; ``` -Where: +### Multisizes -* s - the section id -* code - the id of the iframe tag to which the ads will be rendered +If you specify several sizes in the AdUnits settings in the **mediaTypes.banner.sizes** field, our SSP server will hold an auction with each size and respond with a bid with the maximum CPM. -# Example page +For example, your ad-slot supports three sizes: 970x250, 728x90 and 468x60. Then the AdUnits code will look like this: -```html - - - - +```javascript +{ + bidder: 'between', + params: { + s: BETWEEN_SECTION_ID, + cur: 'USD' + } +} +``` +### GDPR - + + + + }); + -

Prebid.js BetweenBidAdapter Test

- +

Prebid.js BetweenBidAdapter Test

+ - -``` \ No newline at end of file + +``` diff --git a/test/spec/modules/betweenBidAdapter_spec.js b/test/spec/modules/betweenBidAdapter_spec.js index 5dff32ca4d8..94db41ba014 100644 --- a/test/spec/modules/betweenBidAdapter_spec.js +++ b/test/spec/modules/betweenBidAdapter_spec.js @@ -219,6 +219,6 @@ describe('betweenBidAdapterTests', function () { let request = spec.buildRequests(bidRequestData); let req_data = request[0].data; - expect(req_data.sizes).to.deep.equal(['970x250', '240x400', '728x90']); + expect(req_data.sizes).to.deep.equal('970x250%2C240x400%2C728x90'); }); }); From 79e9d75afd0a860afc6f789e7671dad501569c3a Mon Sep 17 00:00:00 2001 From: Pankaj Hasija <43163343+Hassija@users.noreply.github.com> Date: Wed, 29 Apr 2020 16:45:00 +0530 Subject: [PATCH 285/496] Invisibly analytics (#5153) * PUBA-5273:initial commit with analytics adapter, spec & md file * PUBA-5273: updated adapter definition * PUBA-5273: added support contact info * PUBA-5273: adding clearInterval on AUCTION_END * PUBA-5273: reverted last commit as CircleCI job failed * Reverted changes to fix CircleCI build error * Re-commiting invocation of clearInterval on Auction_end * PUBA-7575: updating adapter invocation approach * PUBA-7575: updating the formatting * PUBA-7575: updating adapter logic * Updating filter to 50% from 5% * Removing console * Reducing 50% pass to 1% pass rate * Updating commnet * Making PR review changes * Updating the .md file --- modules/invisiblyAnalyticsAdapter.js | 28 +- modules/invisiblyAnalyticsAdapter.md | 1 + .../modules/invisiblyAnalyticsAdapter_spec.js | 710 ++++++++++-------- 3 files changed, 418 insertions(+), 321 deletions(-) diff --git a/modules/invisiblyAnalyticsAdapter.js b/modules/invisiblyAnalyticsAdapter.js index bb193c16d80..d4fd3831210 100644 --- a/modules/invisiblyAnalyticsAdapter.js +++ b/modules/invisiblyAnalyticsAdapter.js @@ -28,8 +28,8 @@ const { SET_TARGETING, REQUEST_BIDS, ADD_AD_UNITS, - AD_RENDER_FAILED - } + AD_RENDER_FAILED, + }, } = CONSTANTS; const _VERSION = 1; @@ -55,9 +55,12 @@ let _pageView = { language: window.navigator.language, vendor: window.navigator.vendor, screenWidth: x, - screenHeight: y + screenHeight: y, }; +// pass only 1% of events & fail the rest 99% +let weightedFilter = { filter: Math.random() > 0.99 }; + let _eventQueue = [_pageView]; let invisiblyAdapter = Object.assign( @@ -66,15 +69,16 @@ let invisiblyAdapter = Object.assign( track({ eventType, args }) { handleEvent(eventType, args); }, - sendEvent + sendEvent, + weightedFilter, } ); invisiblyAdapter.originEnableAnalytics = invisiblyAdapter.enableAnalytics; -invisiblyAdapter.enableAnalytics = function(config) { +invisiblyAdapter.enableAnalytics = function (config) { initOptions = config.options || {}; initOptions.url = initOptions.url || DEFAULT_EVENT_URL; - if (initOptions.url && initOptions.account) { + if (initOptions.url && initOptions.account && weightedFilter.filter) { invisiblyAnalyticsEnabled = true; invisiblyAdapter.originEnableAnalytics(config); } else { @@ -85,7 +89,7 @@ invisiblyAdapter.enableAnalytics = function(config) { }; invisiblyAdapter.originDisableAnalytics = invisiblyAdapter.disableAnalytics; -invisiblyAdapter.disableAnalytics = function() { +invisiblyAdapter.disableAnalytics = function () { if (!invisiblyAnalyticsEnabled) { return; } @@ -109,12 +113,12 @@ function flush() { pageViewId: _pageViewId, ver: _VERSION, bundleId: initOptions.bundleId, - ...eventFromQue + ...eventFromQue, }; let payload = { event_type: eventtype, - event_data: { ...data } + event_data: { ...data }, }; ajax( initOptions.url, @@ -123,7 +127,7 @@ function flush() { { contentType: 'application/json', method: 'POST', - withCredentials: true + withCredentials: true, } ); } @@ -212,10 +216,10 @@ function sendEvent(event) { adapterManager.registerAnalyticsAdapter({ adapter: invisiblyAdapter, - code: 'invisiblyAnalytics' + code: 'invisiblyAnalytics', }); -invisiblyAdapter.getOptions = function() { +invisiblyAdapter.getOptions = function () { return initOptions; }; diff --git a/modules/invisiblyAnalyticsAdapter.md b/modules/invisiblyAnalyticsAdapter.md index 1023e6baf96..421037226b0 100644 --- a/modules/invisiblyAnalyticsAdapter.md +++ b/modules/invisiblyAnalyticsAdapter.md @@ -11,6 +11,7 @@ Maintainer: sanjay.rawlani@invisibly.com # Description Analytics adapter for Invisibly. Please contact: sanjay.rawlani@invisibly.com for any additional information. Official website link to the vendor: https://invisibly.com/ +We have modified the analytics adapter to fire `Prebid` events only 1% of the time. Most of the time you would not see events getting triggered even though the analyticsAdapter has been enabled. # Test Parameters diff --git a/test/spec/modules/invisiblyAnalyticsAdapter_spec.js b/test/spec/modules/invisiblyAnalyticsAdapter_spec.js index 419d5a29700..e13b16661b0 100644 --- a/test/spec/modules/invisiblyAnalyticsAdapter_spec.js +++ b/test/spec/modules/invisiblyAnalyticsAdapter_spec.js @@ -1,10 +1,11 @@ import invisiblyAdapter from 'modules/invisiblyAnalyticsAdapter.js'; import { expect } from 'chai'; -import { server } from 'test/mocks/xhr.js'; let events = require('src/events'); let constants = require('src/constants.json'); -describe('Invisibly Analytics Adapter test suite', function() { +describe('Invisibly Analytics Adapter test suite', function () { + let xhr; + let requests = []; const BID1 = { width: 980, height: 240, @@ -20,11 +21,11 @@ describe('Invisibly Analytics Adapter test suite', function() { hb_adid: '2ecff0db240757', hb_pb: 1.2, hb_size: '640x480', - hb_source: 'client' + hb_source: 'client', }, getStatusCode() { return CONSTANTS.STATUS.GOOD; - } + }, }; const BID2 = Object.assign({}, BID1, { @@ -34,7 +35,7 @@ describe('Invisibly Analytics Adapter test suite', function() { timeToRespond: 300, bidId: '3ecff0db240757', requestId: '3ecff0db240757', - adId: '3ecff0db240757' + adId: '3ecff0db240757', }); const BID3 = { @@ -48,11 +49,11 @@ describe('Invisibly Analytics Adapter test suite', function() { hb_adid: '3bd4ebb1c900e2', hb_pb: '1.500', hb_size: '728x90', - hb_source: 'server' + hb_source: 'server', }, getStatusCode() { return CONSTANTS.STATUS.NO_BID; - } + }, }; const MOCK = { @@ -60,11 +61,11 @@ describe('Invisibly Analytics Adapter test suite', function() { provider: 'invisiblyAnalytics', options: { bundleId: '', - account: 'invisibly' - } + account: 'invisibly', + }, }, AUCTION_INIT: { - auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa' + auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', }, BID_REQUESTED: { bidder: 'mockBidder', @@ -74,27 +75,27 @@ describe('Invisibly Analytics Adapter test suite', function() { { bidder: 'mockBidder', adUnitCode: 'panorama_d_1', - bidId: '2ecff0db240757' + bidId: '2ecff0db240757', }, { bidder: 'mockBidder', adUnitCode: 'box_d_1', - bidId: '3ecff0db240757' + bidId: '3ecff0db240757', }, { bidder: 'mockBidder', adUnitCode: 'box_d_2', - bidId: '4ecff0db240757' - } + bidId: '4ecff0db240757', + }, ], - start: 1519149562216 + start: 1519149562216, }, BID_RESPONSE: [BID1, BID2], AUCTION_END: { auctionId: 'test_timeout_auction_id', timestamp: 1234567890, timeout: 3000, - auctionEnd: 1234567990 + auctionEnd: 1234567990, }, BID_WON: { bidderCode: 'appnexus', @@ -119,17 +120,17 @@ describe('Invisibly Analytics Adapter test suite', function() { status: 'rendered', eventType: 'bidWon', ad: 'some ad', - adUrl: 'ad url' + adUrl: 'ad url', }, BIDDER_DONE: { bidderCode: 'mockBidder', - bids: [BID1, BID2, BID3] + bids: [BID1, BID2, BID3], }, BID_TIMEOUT: [ { bidId: '2ecff0db240757', - auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa' - } + auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', + }, ], BID_ADJUSTMENT: { ad: 'html', @@ -146,346 +147,437 @@ describe('Invisibly Analytics Adapter test suite', function() { statusMessage: 'Bid available', timeToRespond: 421, ttl: 300, - width: 300 + width: 300, }, NO_BID: { - testKey: false + testKey: false, }, SET_TARGETING: { [BID1.adUnitCode]: BID1.adserverTargeting, - [BID3.adUnitCode]: BID3.adserverTargeting + [BID3.adUnitCode]: BID3.adserverTargeting, }, REQUEST_BIDS: { - call: 'request' + call: 'request', }, ADD_AD_UNITS: { call: 'addAdUnits' }, AD_RENDER_FAILED: { call: 'adRenderFailed' }, INVALID_EVENT: { - mockKey: 'this event should not emit' - } + mockKey: 'this event should not emit', + }, }; - describe('Invisibly Analytic tests specs', function() { - beforeEach(function() { + describe('Invisibly Analytic tests specs', function () { + beforeEach(function () { + xhr = sinon.useFakeXMLHttpRequest(); + requests = []; + xhr.onCreate = (xhr) => { + requests.push(xhr); + }; sinon.stub(events, 'getEvents').returns([]); sinon.spy(invisiblyAdapter, 'track'); }); - afterEach(function() { + afterEach(function () { invisiblyAdapter.disableAnalytics(); events.getEvents.restore(); invisiblyAdapter.track.restore(); + xhr.restore(); }); - // specs to test invisibly account input to enableAnaylitcs - describe('monitor enableAnalytics method', function() { - it('should catch all events triggered with invisibly account config', function() { - invisiblyAdapter.enableAnalytics({ - provider: 'invisiblyAnalytics', - options: { - account: 'invisibly' - } + describe('Send all events as & when they are captured', function () { + beforeEach(function () { + invisiblyAdapter.weightedFilter.filter = true; + }); + // specs to test invisibly account input to enableAnaylitcs + describe('monitor enableAnalytics method', function () { + it('should catch all events triggered with invisibly account config', function () { + invisiblyAdapter.enableAnalytics({ + provider: 'invisiblyAnalytics', + options: { + account: 'invisibly', + }, + }); + events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); + events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); + events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); + events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); + sinon.assert.callCount(invisiblyAdapter.track, 5); + }); + + it('should not catch events triggered without invisibly account config', function () { + invisiblyAdapter.enableAnalytics({ + provider: 'invisiblyAnalytics', + options: {}, + }); + + events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); + events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); + events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); + events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); + invisiblyAdapter.flush(); + sinon.assert.callCount(invisiblyAdapter.track, 0); + }); + // spec to test custom api endpoint + it('support custom endpoint', function () { + let custom_url = 'custom url'; + invisiblyAdapter.enableAnalytics({ + provider: 'invisiblyAnalytics', + options: { + url: custom_url, + bundleId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', + account: 'invisibly', + }, + }); + expect(invisiblyAdapter.getOptions().url).to.equal(custom_url); }); + }); + // spec for auction init event + it('auction init event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); - events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); - events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); - sinon.assert.callCount(invisiblyAdapter.track, 5); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse( + requests[1].requestBody.substring(0) + ); + // pageView is default event initially hence expecting 2 requests + expect(requests.length).to.equal(2); + expect(requests[1].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.auctionId).to.equal( + MOCK.AUCTION_INIT.auctionId + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_type).to.equal('PREBID_auctionInit'); + expect(invisiblyEvents.event_data.ver).to.equal(1); }); - it('should not catch events triggered without invisibly account config', function() { - invisiblyAdapter.enableAnalytics({ - provider: 'invisiblyAnalytics', - options: {} - }); + // spec for bid adjustment event + it('bid adjustment event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.BID_ADJUSTMENT, MOCK.BID_ADJUSTMENT); + invisiblyAdapter.flush(); - events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidAdjustment'); + expect(invisiblyEvents.event_data.bidders.cpm).to.equal( + MOCK.BID_ADJUSTMENT.cpm + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for bid timeout event + it('bid timeout event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.BID_TIMEOUT, MOCK.BID_TIMEOUT); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidTimeout'); + expect(invisiblyEvents.event_data.bidders.bidId).to.equal( + MOCK.BID_TIMEOUT.bidId + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for bid requested event + it('bid requested event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidRequested'); + expect(invisiblyEvents.event_data.auctionId).to.equal( + MOCK.BID_REQUESTED.auctionId + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for bid response event + it('bid response event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidResponse'); + expect(invisiblyEvents.event_data.cpm).to.equal(MOCK.BID_REQUESTED.cpm); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for no bid event + it('no bid event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.NO_BID, MOCK.NO_BID); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_noBid'); + expect(invisiblyEvents.event_data.noBid.testKey).to.equal( + MOCK.NO_BID.testKey + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for bid won event + it('bid won event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); invisiblyAdapter.flush(); - sinon.assert.callCount(invisiblyAdapter.track, 0); + + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidWon'); + sinon.assert.callCount(invisiblyAdapter.track, 1); }); - // spec to test custom api endpoint - it('support custom endpoint', function() { - let custom_url = 'custom url'; - invisiblyAdapter.enableAnalytics({ - provider: 'invisiblyAnalytics', - options: { - url: custom_url, - bundleId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', - account: 'invisibly' - } - }); - expect(invisiblyAdapter.getOptions().url).to.equal(custom_url); + + // spec for bidder done event + it('bidder done event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.BIDDER_DONE, MOCK.BIDDER_DONE); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidderDone'); + expect(invisiblyEvents.event_data.bidderCode).to.equal( + MOCK.BIDDER_DONE.bidderCode + ); + expect(invisiblyEvents.event_data.bids.length).to.equal( + MOCK.BIDDER_DONE.bids.length + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); }); - }); - // spec for auction init event - it('auction init event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[1].requestBody.substring(0)); - // pageView is default event initially hence expecting 2 requests - expect(server.requests.length).to.equal(2); - expect(server.requests[1].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.auctionId).to.equal( - MOCK.AUCTION_INIT.auctionId - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_type).to.equal('PREBID_auctionInit'); - expect(invisiblyEvents.event_data.ver).to.equal(1); - }); + // spec for set targeting event + it('set targeting event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.SET_TARGETING, MOCK.SET_TARGETING); + invisiblyAdapter.flush(); - // spec for bid adjustment event - it('bid adjustment event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BID_ADJUSTMENT, MOCK.BID_ADJUSTMENT); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidAdjustment'); - expect(invisiblyEvents.event_data.bidders.cpm).to.equal( - MOCK.BID_ADJUSTMENT.cpm - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_setTargeting'); + expect( + invisiblyEvents.event_data.targetings[BID1.adUnitCode] + ).to.deep.equal(BID1.adserverTargeting); + expect( + invisiblyEvents.event_data.targetings[BID3.adUnitCode] + ).to.deep.equal(BID3.adserverTargeting); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); - // spec for bid timeout event - it('bid timeout event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BID_TIMEOUT, MOCK.BID_TIMEOUT); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidTimeout'); - expect(invisiblyEvents.event_data.bidders.bidId).to.equal( - MOCK.BID_TIMEOUT.bidId - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + // spec for request bids event + it('request bids event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.REQUEST_BIDS, MOCK.REQUEST_BIDS); + invisiblyAdapter.flush(); - // spec for bid requested event - it('bid requested event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidRequested'); - expect(invisiblyEvents.event_data.auctionId).to.equal( - MOCK.BID_REQUESTED.auctionId - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_requestBids'); + expect(invisiblyEvents.event_data.call).to.equal( + MOCK.REQUEST_BIDS.call + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); - // spec for bid response event - it('bid response event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidResponse'); - expect(invisiblyEvents.event_data.cpm).to.equal(MOCK.BID_REQUESTED.cpm); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + // spec for add ad units event + it('add ad units event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.ADD_AD_UNITS, MOCK.ADD_AD_UNITS); + invisiblyAdapter.flush(); - // spec for no bid event - it('no bid event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.NO_BID, MOCK.NO_BID); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_noBid'); - expect(invisiblyEvents.event_data.noBid.testKey).to.equal( - MOCK.NO_BID.testKey - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_addAdUnits'); + expect(invisiblyEvents.event_data.call).to.equal( + MOCK.ADD_AD_UNITS.call + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); - // spec for bid won event - it('bid won event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidWon'); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + // spec for ad render failed event + it('ad render failed event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.AD_RENDER_FAILED, MOCK.AD_RENDER_FAILED); + invisiblyAdapter.flush(); - // spec for bidder done event - it('bidder done event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BIDDER_DONE, MOCK.BIDDER_DONE); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidderDone'); - expect(invisiblyEvents.event_data.bidderCode).to.equal( - MOCK.BIDDER_DONE.bidderCode - ); - expect(invisiblyEvents.event_data.bids.length).to.equal( - MOCK.BIDDER_DONE.bids.length - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_adRenderFailed'); + expect(invisiblyEvents.event_data.call).to.equal( + MOCK.AD_RENDER_FAILED.call + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); - // spec for set targeting event - it('set targeting event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.SET_TARGETING, MOCK.SET_TARGETING); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_setTargeting'); - expect( - invisiblyEvents.event_data.targetings[BID1.adUnitCode] - ).to.deep.equal(BID1.adserverTargeting); - expect( - invisiblyEvents.event_data.targetings[BID3.adUnitCode] - ).to.deep.equal(BID3.adserverTargeting); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + // spec for auction end event + it('auction end event', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); + invisiblyAdapter.flush(); - // spec for request bids event - it('request bids event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.REQUEST_BIDS, MOCK.REQUEST_BIDS); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_requestBids'); - expect(invisiblyEvents.event_data.call).to.equal(MOCK.REQUEST_BIDS.call); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + const invisiblyEvents = JSON.parse( + requests[0].requestBody.substring(0) + ); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal( + 'https://api.pymx5.com/v1/sites/events' + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_auctionEnd'); + expect(invisiblyEvents.event_data.auctionId).to.equal( + MOCK.AUCTION_END.auctionId + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); - // spec for add ad units event - it('add ad units event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.ADD_AD_UNITS, MOCK.ADD_AD_UNITS); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_addAdUnits'); - expect(invisiblyEvents.event_data.call).to.equal(MOCK.ADD_AD_UNITS.call); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + // should not call sendEvent for events not supported by the adapter + it('it should not call sendEvent for this event emit', function () { + sinon.spy(invisiblyAdapter, 'sendEvent'); + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.INVALID_EVENT, MOCK.INVALID_EVENT); + invisiblyAdapter.flush(); - // spec for ad render failed event - it('ad render failed event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.AD_RENDER_FAILED, MOCK.AD_RENDER_FAILED); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_adRenderFailed'); - expect(invisiblyEvents.event_data.call).to.equal( - MOCK.AD_RENDER_FAILED.call - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + expect(requests.length).to.equal(0); + sinon.assert.callCount(invisiblyAdapter.track, 0); + sinon.assert.callCount(invisiblyAdapter.sendEvent, 0); + }); - // spec for auction end event - it('auction end event', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse(server.requests[0].requestBody.substring(0)); - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_auctionEnd'); - expect(invisiblyEvents.event_data.auctionId).to.equal( - MOCK.AUCTION_END.auctionId - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); + // spec to emit all events + it('track all event without errors', function () { + invisiblyAdapter.enableAnalytics(MOCK.config); - // should not call sendEvent for events not supported by the adapter - it('it should not call sendEvent for this event emit', function() { - sinon.spy(invisiblyAdapter, 'sendEvent'); - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.INVALID_EVENT, MOCK.INVALID_EVENT); - invisiblyAdapter.flush(); + events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); + events.emit(constants.EVENTS.BID_ADJUSTMENT, MOCK.BID_ADJUSTMENT); + events.emit(constants.EVENTS.BID_TIMEOUT, MOCK.BID_TIMEOUT); + events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); + events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); + events.emit(constants.EVENTS.NO_BID, MOCK.NO_BID); + events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); + events.emit(constants.EVENTS.BIDDER_DONE, MOCK.BIDDER_DONE); + events.emit(constants.EVENTS.SET_TARGETING, MOCK.SET_TARGETING); + events.emit(constants.EVENTS.REQUEST_BIDS, MOCK.REQUEST_BIDS); + events.emit(constants.EVENTS.ADD_AD_UNITS, MOCK.ADD_AD_UNITS); + events.emit(constants.EVENTS.AD_RENDER_FAILED, MOCK.AD_RENDER_FAILED); - expect(server.requests.length).to.equal(0); - sinon.assert.callCount(invisiblyAdapter.track, 0); - sinon.assert.callCount(invisiblyAdapter.sendEvent, 0); + sinon.assert.callCount(invisiblyAdapter.track, 13); + }); }); - // spec to emit all events - it('track all event without errors', function() { - invisiblyAdapter.enableAnalytics(MOCK.config); - - events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); - events.emit(constants.EVENTS.BID_ADJUSTMENT, MOCK.BID_ADJUSTMENT); - events.emit(constants.EVENTS.BID_TIMEOUT, MOCK.BID_TIMEOUT); - events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); - events.emit(constants.EVENTS.NO_BID, MOCK.NO_BID); - events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); - events.emit(constants.EVENTS.BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(constants.EVENTS.SET_TARGETING, MOCK.SET_TARGETING); - events.emit(constants.EVENTS.REQUEST_BIDS, MOCK.REQUEST_BIDS); - events.emit(constants.EVENTS.ADD_AD_UNITS, MOCK.ADD_AD_UNITS); - events.emit(constants.EVENTS.AD_RENDER_FAILED, MOCK.AD_RENDER_FAILED); - - sinon.assert.callCount(invisiblyAdapter.track, 13); + describe('Should not send any event even if they are caputured', function () { + beforeEach(function () { + invisiblyAdapter.weightedFilter.filter = false; + }); + it('it should not send any event', function () { + invisiblyAdapter.enableAnalytics({ + provider: 'invisiblyAnalytics', + options: { + account: 'invisibly', + }, + }); + + events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); + events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); + events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); + events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); + invisiblyAdapter.flush(); + + sinon.assert.callCount(invisiblyAdapter.sendEvent, 0); + sinon.assert.callCount(invisiblyAdapter.track, 0); + expect(requests.length).to.equal(0); + }); }); }); }); From 991ad560fc4ac1e031788429228c522be82df9ab Mon Sep 17 00:00:00 2001 From: Itay Nave <38345760+itaynave@users.noreply.github.com> Date: Wed, 29 Apr 2020 21:46:17 +0300 Subject: [PATCH 286/496] Add support for user sync (#5142) * Support new aniview bid adapter * Support new aniview bid adapter * Support new aniview bid adapter * Support new aniview bid adapter * Fix Consent parameters * Update aniviewBidAdapter.js V3 support * Update aniviewBidAdapter.js * Update aniviewBidAdapter.js Update refererInfo * Update aniviewBidAdapter.js Fix tabs and spaces * Update aniviewBidAdapter.js fixes * Update aniviewBidAdapter.js * Update aniviewBidAdapter.js Add ccpa support * Update aniviewBidAdapter.js Typo * Update aniviewBidAdapter.js * Update aniviewBidAdapter.js * Fix size and sample Fixed sizes from playerSize Updated md sample * Fix tabs * Fix sizes * Recheck * Add tgt parameter * Update sample * Add support for cookie sync + tests * Add support for cookie sync + tests * Add support for cookie sync + tests --- modules/aniviewBidAdapter.js | 66 ++++++++++++++++++++- test/spec/modules/aniviewBidAdapter_spec.js | 18 ++++++ 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/modules/aniviewBidAdapter.js b/modules/aniviewBidAdapter.js index 2978117e350..50c403350dd 100644 --- a/modules/aniviewBidAdapter.js +++ b/modules/aniviewBidAdapter.js @@ -43,7 +43,7 @@ function isBidRequestValid(bid) { return true; } - +let irc = 0; function buildRequests(validBidRequests, bidderRequest) { let bidRequests = []; @@ -66,6 +66,7 @@ function buildRequests(validBidRequests, bidderRequest) { let size = sizes[j]; let playerWidth; let playerHeight; + if (size && size.length == 2) { playerWidth = size[0]; playerHeight = size[1]; @@ -102,6 +103,9 @@ function buildRequests(validBidRequests, bidderRequest) { s2sParams.pbjs = 1; s2sParams.tgt = 10; s2sParams.s2s = '1'; + s2sParams.irc = irc; + irc++; + s2sParams.wpm = 1; if (bidderRequest && bidderRequest.gdprConsent) { if (bidderRequest.gdprConsent.gdprApplies) { @@ -191,12 +195,68 @@ function interpretResponse(serverResponse, bidRequest) { return bidResponses; } +function getSyncData(xml, options) { + let ret = []; + if (xml) { + let ext = xml.getElementsByTagName('Extensions'); + if (ext && ext.length > 0) { + ext = ext[0].getElementsByTagName('Extension'); + if (ext && ext.length > 0) { + for (var i = 0; i < ext.length; i++) { + if (ext[i].getAttribute('type') == 'ANIVIEW') { + let syncs = ext[i].getElementsByTagName('AdServingSync'); + if (syncs && syncs.length == 1) { + try { + let data = JSON.parse(syncs[0].textContent); + if (data && data.trackers && data.trackers.length) { + data = data.trackers; + for (var j = 0; j < data.length; j++) { + if (typeof data[j] === 'object' && typeof data[j].url === 'string' && data[j].e === 'inventory') { + if (data[j].t == 1 && options.pixelEnabled) { + ret.push({url: data[j].url, type: 'image'}); + } else { + if (data[j].t == 3 && options.iframeEnabled) { + ret.push({url: data[j].url, type: 'iframe'}); + } + } + } + } + } + } catch (e) {} + } + break; + } + } + } + } + } + return ret; +} + +function getUserSyncs(syncOptions, serverResponses) { + if (serverResponses && serverResponses[0] && serverResponses[0].body) { + if (serverResponses.error) { + return []; + } else { + try { + let xmlStr = serverResponses[0].body; + let xml = new window.DOMParser().parseFromString(xmlStr, 'text/xml'); + if (xml && xml.getElementsByTagName('parsererror').length == 0) { + let syncData = getSyncData(xml, syncOptions); + return syncData; + } + } catch (e) {} + } + } +} + export const spec = { code: BIDDER_CODE, supportedMediaTypes: [VIDEO], isBidRequestValid, buildRequests, - interpretResponse -} + interpretResponse, + getUserSyncs +}; registerBidder(spec); diff --git a/test/spec/modules/aniviewBidAdapter_spec.js b/test/spec/modules/aniviewBidAdapter_spec.js index 56a4dadbde3..0161652505c 100644 --- a/test/spec/modules/aniviewBidAdapter_spec.js +++ b/test/spec/modules/aniviewBidAdapter_spec.js @@ -180,4 +180,22 @@ describe('ANIVIEW Bid Adapter Test', function () { expect(result.length).to.equal(0); }); }); + + describe('getUserSyncs', function () { + it('Check get sync pixels from response', function () { + let pixelUrl = 'https://sync.pixel.url/sync'; + let pixelEvent = 'inventory'; + let pixelType = '3'; + let pixelStr = '{"url":"' + pixelUrl + '", "e":"' + pixelEvent + '", "t":' + pixelType + '}'; + let bidResponse = 'FORDFORD00:00:15'; + let serverResponse = [ + {body: bidResponse} + ]; + let syncPixels = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, serverResponse); + expect(syncPixels.length).to.equal(1); + let pixel = syncPixels[0]; + expect(pixel.url).to.equal(pixelUrl); + expect(pixel.type).to.equal('iframe'); + }); + }); }); From bee999ae65bf24429ad81120dcf12bf1edd535a8 Mon Sep 17 00:00:00 2001 From: Dan Bogdan <43830380+EMXDigital@users.noreply.github.com> Date: Wed, 29 Apr 2020 15:53:01 -0400 Subject: [PATCH 287/496] EMX Digital Adapter Bug Fix - Outstream Renderer (#5161) * adding ccpa support for emx_digital adapter * emx_digital ccpa compliance: lint fix * emx 3.0 compliance update * fix outstream renderer issue, update test spec * refactor formatVideoResponse function to use core-js/find Co-authored-by: Nick Colletti Co-authored-by: Nick Colletti Co-authored-by: Kiyoshi Hara --- modules/emx_digitalBidAdapter.js | 16 ++-- .../modules/emx_digitalBidAdapter_spec.js | 95 ++++++++++++++++--- 2 files changed, 90 insertions(+), 21 deletions(-) diff --git a/modules/emx_digitalBidAdapter.js b/modules/emx_digitalBidAdapter.js index 83689aa76f1..480e98b31d3 100644 --- a/modules/emx_digitalBidAdapter.js +++ b/modules/emx_digitalBidAdapter.js @@ -3,11 +3,12 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { Renderer } from '../src/Renderer.js'; import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js/library/fn/array/find.js'; const BIDDER_CODE = 'emx_digital'; const ENDPOINT = 'hb.emxdgt.com'; const RENDERER_URL = 'https://js.brealtime.com/outstream/1.30.0/bundle.js'; -const ADAPTER_VERSION = '1.5.0'; +const ADAPTER_VERSION = '1.5.1'; const DEFAULT_CUR = 'USD'; export const emxAdapter = { @@ -41,11 +42,14 @@ export const emxAdapter = { }, formatVideoResponse: (bidResponse, emxBid, bidRequest) => { bidResponse.vastXml = emxBid.adm; - if (bidRequest.bidRequest && bidRequest.bidRequest.mediaTypes && bidRequest.bidRequest.mediaTypes.video && bidRequest.bidRequest.mediaTypes.video.context === 'outstream') { - bidResponse.renderer = emxAdapter.createRenderer(bidResponse, { - id: emxBid.id, - url: RENDERER_URL - }); + if (bidRequest.bidderRequest && bidRequest.bidderRequest.bids && bidRequest.bidderRequest.bids.length > 0) { + const matchingBid = find(bidRequest.bidderRequest.bids, bid => bidResponse.requestId && bid.bidId && bidResponse.requestId === bid.bidId && bid.mediaTypes && bid.mediaTypes.video && bid.mediaTypes.video.context === 'outstream'); + if (matchingBid) { + bidResponse.renderer = emxAdapter.createRenderer(bidResponse, { + id: emxBid.id, + url: RENDERER_URL + }); + } } return bidResponse; }, diff --git a/test/spec/modules/emx_digitalBidAdapter_spec.js b/test/spec/modules/emx_digitalBidAdapter_spec.js index e064c4833e6..7be8a2ce5ac 100644 --- a/test/spec/modules/emx_digitalBidAdapter_spec.js +++ b/test/spec/modules/emx_digitalBidAdapter_spec.js @@ -335,11 +335,12 @@ describe('emx_digital Adapter', function () { it('should have the right gdpr info when enabled', function () { let consentString = 'OIJSZsOAFsABAB8EMXZZZZZ+A=='; - bidderRequest.gdprConsent = { + const gdprBidderRequest = utils.deepClone(bidderRequest); + gdprBidderRequest.gdprConsent = { 'consentString': consentString, 'gdprApplies': true }; - let request = spec.buildRequests(bidderRequest.bids, bidderRequest); + let request = spec.buildRequests(gdprBidderRequest.bids, gdprBidderRequest); request = JSON.parse(request.data) expect(request.regs.ext).to.have.property('gdpr', 1); @@ -347,18 +348,21 @@ describe('emx_digital Adapter', function () { }); it('should\'t contain consent string if gdpr isn\'t applied', function () { - bidderRequest.gdprConsent = { + const nonGdprBidderRequest = utils.deepClone(bidderRequest); + nonGdprBidderRequest.gdprConsent = { 'gdprApplies': false }; - let request = spec.buildRequests(bidderRequest.bids, bidderRequest); + let request = spec.buildRequests(nonGdprBidderRequest.bids, nonGdprBidderRequest); request = JSON.parse(request.data) expect(request.regs.ext).to.have.property('gdpr', 0); expect(request).to.not.have.property('user'); }); + it('should add us privacy info to request', function() { + const uspBidderRequest = utils.deepClone(bidderRequest); let consentString = '1YNN'; - bidderRequest.uspConsent = consentString; - let request = spec.buildRequests(bidderRequest.bids, bidderRequest); + uspBidderRequest.uspConsent = consentString; + let request = spec.buildRequests(uspBidderRequest.bids, uspBidderRequest); request = JSON.parse(request.data); expect(request.us_privacy).to.exist; expect(request.us_privacy).to.exist.and.to.equal(consentString); @@ -388,6 +392,52 @@ describe('emx_digital Adapter', function () { 'auctionId': '1d1a01234a475' }; + const bid_outstream = { + 'bidderRequest': { + 'bids': [{ + 'bidder': 'emx_digital', + 'params': { + 'tagid': '25251', + 'video': {} + }, + 'mediaTypes': { + 'video': { + 'context': 'outstream', + 'playerSize': [640, 480] + } + }, + 'adUnitCode': 'adunit-code', + 'sizes': [ + [300, 250], + [300, 600] + ], + 'bidId': '987654321cba', + 'bidderRequestId': '22edbae3120bf6', + 'auctionId': '1d1a01234a475' + }, { + 'bidder': 'emx_digital', + 'params': { + 'tagid': '25252', + 'video': {} + }, + 'mediaTypes': { + 'video': { + 'context': 'instream', + 'playerSize': [640, 480] + } + }, + 'adUnitCode': 'adunit-code', + 'sizes': [ + [300, 250], + [300, 600] + ], + 'bidId': '987654321dcb', + 'bidderRequestId': '22edbae3120bf6', + 'auctionId': '1d1a01234a475' + }] + } + }; + const serverResponse = { 'id': '12819a18-56e1-4256-b836-b69a10202668', 'seatbid': [{ @@ -408,7 +458,7 @@ describe('emx_digital Adapter', function () { 'adm': '', 'crid': '3434abab35', 'h': 600, - 'id': '987654321cba', + 'id': '987654321dcb', 'price': 0.5, 'ttl': 300, 'w': 300 @@ -506,25 +556,39 @@ describe('emx_digital Adapter', function () { }); it('returns a vastXml kvp for video creatives', function () { - serverResponse.seatbid[0].bid[0].adm = ''; - serverResponse.seatbid[1].bid[0].adm = ''; + const vastServerResponse = utils.deepClone(serverResponse); + vastServerResponse.seatbid[0].bid[0].adm = ''; + vastServerResponse.seatbid[1].bid[0].adm = ''; let result = spec.interpretResponse({ - body: serverResponse + body: vastServerResponse }, { bidRequest: bid } ); const ad0 = result[0]; const ad1 = result[1]; expect(ad0.mediaType).to.equal('video'); expect(ad0.ad.indexOf(' -1).to.equal(true); - expect(ad0.vastXml).to.equal(serverResponse.seatbid[0].bid[0].adm); + expect(ad0.vastXml).to.equal(vastServerResponse.seatbid[0].bid[0].adm); expect(ad0.ad).to.exist.and.to.be.a('string'); expect(ad1.mediaType).to.equal('video'); expect(ad1.ad.indexOf(' -1).to.equal(true); - expect(ad1.vastXml).to.equal(serverResponse.seatbid[1].bid[0].adm); + expect(ad1.vastXml).to.equal(vastServerResponse.seatbid[1].bid[0].adm); expect(ad1.ad).to.exist.and.to.be.a('string'); }); + it('returns a renderer for outstream video creatives', function () { + const vastServerResponse = utils.deepClone(serverResponse); + vastServerResponse.seatbid[0].bid[0].adm = ''; + vastServerResponse.seatbid[1].bid[0].adm = ''; + let result = spec.interpretResponse({body: vastServerResponse}, bid_outstream); + const ad0 = result[0]; + const ad1 = result[1]; + expect(ad0.renderer).to.exist.and.to.be.a('object'); + expect(ad0.renderer.url).to.equal('https://js.brealtime.com/outstream/1.30.0/bundle.js'); + expect(ad0.renderer.id).to.equal('987654321cba'); + expect(ad1.renderer).to.equal(undefined); + }); + it('handles nobid responses', function () { let serverResponse = { 'bids': [] @@ -537,11 +601,12 @@ describe('emx_digital Adapter', function () { }); it('should not throw an error when decoding an improperly encoded adm', function () { - serverResponse.seatbid[0].bid[0].adm = '\\<\\/script\\>'; - serverResponse.seatbid[1].bid[0].adm = '%3F%%3Demx%3C3prebid' + const badAdmServerResponse = utils.deepClone(serverResponse); + badAdmServerResponse.seatbid[0].bid[0].adm = '\\<\\/script\\>'; + badAdmServerResponse.seatbid[1].bid[0].adm = '%3F%%3Demx%3C3prebid'; assert.doesNotThrow(() => spec.interpretResponse({ - body: serverResponse + body: badAdmServerResponse })); }); }); From b02914c1f0870d2509cb31b9ba81f1acab8111b6 Mon Sep 17 00:00:00 2001 From: rmartinez Date: Wed, 29 Apr 2020 13:34:33 -0700 Subject: [PATCH 288/496] Prebid 3.18.0 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 79feb816b16..529c639d951 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.18.0-pre", + "version": "3.18.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 5fc2b1eb10853154bb260d0af3c038be9ed5de97 Mon Sep 17 00:00:00 2001 From: rmartinez Date: Wed, 29 Apr 2020 13:42:41 -0700 Subject: [PATCH 289/496] Increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 529c639d951..3b581fec1cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.18.0", + "version": "3.19.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 6aaaf965bb651e288f5fad043e54b7d751315396 Mon Sep 17 00:00:00 2001 From: sumit sharma Date: Thu, 30 Apr 2020 19:20:33 +0530 Subject: [PATCH 290/496] circleci enable pipelines (#5119) Co-authored-by: sumit sharma --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0d48ec13fa1..58e379dced2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -92,3 +92,6 @@ workflows: - master jobs: - e2etest + +experimental: + pipelines: true \ No newline at end of file From 077c910bf666ddd0c8f798fd7da7ceb2bd2c9f66 Mon Sep 17 00:00:00 2001 From: Melody Li Date: Thu, 30 Apr 2020 09:51:27 -0400 Subject: [PATCH 291/496] remove user syncs, fix ccpa approach, and encode brackets and curly braces (#5177) Co-authored-by: Melody Li --- modules/yieldmoBidAdapter.js | 67 ++++++++------------- test/spec/modules/yieldmoBidAdapter_spec.js | 41 ++++--------- 2 files changed, 35 insertions(+), 73 deletions(-) diff --git a/modules/yieldmoBidAdapter.js b/modules/yieldmoBidAdapter.js index 5ef146cb2d0..304cf45e844 100644 --- a/modules/yieldmoBidAdapter.js +++ b/modules/yieldmoBidAdapter.js @@ -5,7 +5,6 @@ const BIDDER_CODE = 'yieldmo'; const CURRENCY = 'USD'; const TIME_TO_LIVE = 300; const NET_REVENUE = true; -const SYNC_ENDPOINT = 'https://static.yieldmo.com/blank.min.html?orig='; const SERVER_ENDPOINT = 'https://ads.yieldmo.com/exchange/prebid'; const localWindow = utils.getWindowTop(); @@ -39,18 +38,23 @@ export const spec = { title: localWindow.document.title || '', w: localWindow.innerWidth, h: localWindow.innerHeight, - userConsent: JSON.stringify({ - // case of undefined, stringify will remove param - gdprApplies: - bidderRequest && bidderRequest.gdprConsent - ? bidderRequest.gdprConsent.gdprApplies - : undefined, - cmp: - bidderRequest && bidderRequest.gdprConsent - ? bidderRequest.gdprConsent.consentString - : undefined - }), - us_privacy: bidderRequest && bidderRequest.us_privacy + userConsent: encodeURIComponent( + JSON.stringify({ + // case of undefined, stringify will remove param + gdprApplies: + bidderRequest && bidderRequest.gdprConsent + ? bidderRequest.gdprConsent.gdprApplies + : '', + cmp: + bidderRequest && bidderRequest.gdprConsent + ? bidderRequest.gdprConsent.consentString + : '', + }) + ), + us_privacy: + bidderRequest && bidderRequest.uspConsent + ? encodeURIComponent(bidderRequest.uspConsent) + : '', }; bidRequests.forEach(request => { @@ -72,10 +76,12 @@ export const spec = { serverRequest.cri_prebid = criteoId; } if (request.schain) { - serverRequest.schain = JSON.stringify(request.schain); + serverRequest.schain = encodeURIComponent( + JSON.stringify(request.schain) + ); } }); - serverRequest.p = '[' + serverRequest.p.toString() + ']'; + serverRequest.p = encodeURIComponent('[' + serverRequest.p.toString() + ']'); return { method: 'GET', url: SERVER_ENDPOINT, @@ -99,17 +105,8 @@ export const spec = { } return bids; }, - getUserSync: function(syncOptions) { - if (trackingEnabled(syncOptions)) { - return [ - { - type: 'iframe', - url: SYNC_ENDPOINT + utils.getOrigin() - } - ]; - } else { - return []; - } + getUserSyncs: function() { + return []; } }; registerBidder(spec); @@ -153,26 +150,10 @@ function createNewBid(response) { currency: CURRENCY, netRevenue: NET_REVENUE, ttl: TIME_TO_LIVE, - ad: response.ad + ad: response.ad, }; } -/** - * Detects if tracking is allowed - * @returns false if dnt or if not iframe/pixel enabled - */ -function trackingEnabled(options) { - return isIOS() && !getDNT() && options.iframeEnabled; -} - -/** - * Detects whether we're in iOS - * @returns true if in iOS - */ -function isIOS() { - return /iPhone|iPad|iPod/i.test(window.navigator.userAgent); -} - /** * Detects whether dnt is true * @returns true if user enabled dnt diff --git a/test/spec/modules/yieldmoBidAdapter_spec.js b/test/spec/modules/yieldmoBidAdapter_spec.js index 5904113bd42..6858fead750 100644 --- a/test/spec/modules/yieldmoBidAdapter_spec.js +++ b/test/spec/modules/yieldmoBidAdapter_spec.js @@ -90,7 +90,7 @@ describe('YieldmoAdapter', function () { it('should place bid information into the p parameter of data', function () { let placementInfo = spec.buildRequests(bidArray, bidderRequest).data.p; expect(placementInfo).to.equal( - '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1}]' + encodeURIComponent('[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1}]') ); bidArray.push({ bidder: 'yieldmo', @@ -117,20 +117,20 @@ describe('YieldmoAdapter', function () { // multiple placements placementInfo = spec.buildRequests(bidArray, bidderRequest).data.p; expect(placementInfo).to.equal( - '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1},{"placement_id":"adunit-code-1","callback_id":"123456789","sizes":[[300,250],[300,600]],"bidFloor":0.2}]' + encodeURIComponent('[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1},{"placement_id":"adunit-code-1","callback_id":"123456789","sizes":[[300,250],[300,600]],"bidFloor":0.2}]') ); }); it('should add placement id if given', function () { bidArray[0].params.placementId = 'ym_1293871298'; let placementInfo = spec.buildRequests(bidArray, bidderRequest).data.p; - expect(placementInfo).to.include('"ym_placement_id":"ym_1293871298"'); - expect(placementInfo).not.to.include('"ym_placement_id":"ym_0987654321"'); + expect(placementInfo).to.include(encodeURIComponent('"ym_placement_id":"ym_1293871298"')); + expect(placementInfo).not.to.include(encodeURIComponent('"ym_placement_id":"ym_0987654321"')); bidArray[1].params.placementId = 'ym_0987654321'; placementInfo = spec.buildRequests(bidArray, bidderRequest).data.p; - expect(placementInfo).to.include('"ym_placement_id":"ym_1293871298"'); - expect(placementInfo).to.include('"ym_placement_id":"ym_0987654321"'); + expect(placementInfo).to.include(encodeURIComponent('"ym_placement_id":"ym_1293871298"')); + expect(placementInfo).to.include(encodeURIComponent('"ym_placement_id":"ym_0987654321"')); }); it('should add additional information to data parameter of request', function () { @@ -230,16 +230,16 @@ describe('YieldmoAdapter', function () { }; const data = spec.buildRequests(bidArray, bidderRequest).data; expect(data.userConsent).equal( - JSON.stringify({ + encodeURIComponent(JSON.stringify({ gdprApplies: true, cmp: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - }) + })) ); }); it('should add ccpa information to request if available', () => { const privacy = '1YNY'; - bidderRequest.us_privacy = privacy; + bidderRequest.uspConsent = privacy; const data = spec.buildRequests(bidArray, bidderRequest).data; expect(data.us_privacy).equal(privacy); }); @@ -252,7 +252,7 @@ describe('YieldmoAdapter', function () { }; bidArray[0].schain = schain; const request = spec.buildRequests([bidArray[0]], bidderRequest); - expect(request.data.schain).equal(JSON.stringify(schain)); + expect(request.data.schain).equal(encodeURIComponent(JSON.stringify(schain))); }); }); @@ -305,27 +305,8 @@ describe('YieldmoAdapter', function () { }); describe('getUserSync', function () { - const SYNC_ENDPOINT = 'https://static.yieldmo.com/blank.min.html?orig='; - let options = { - iframeEnabled: true, - pixelEnabled: true, - }; - it('should return a tracker with type and url as parameters', function () { - if (/iPhone|iPad|iPod/i.test(window.navigator.userAgent)) { - expect(spec.getUserSync(options)).to.deep.equal([ - { - type: 'iframe', - url: SYNC_ENDPOINT + utils.getOrigin(), - }, - ]); - - options.iframeEnabled = false; - expect(spec.getUserSync(options)).to.deep.equal([]); - } else { - // not ios, so tracker will fail - expect(spec.getUserSync(options)).to.deep.equal([]); - } + expect(spec.getUserSyncs()).to.deep.equal([]); }); }); }); From 09634b8351873a3a03d38493ea315e1f40f1e6c3 Mon Sep 17 00:00:00 2001 From: sumit sharma Date: Mon, 4 May 2020 18:48:52 +0530 Subject: [PATCH 292/496] Fix e2e tests (#5183) * update mock requests * update mutiple bidders request Co-authored-by: sumit sharma --- .../expectations/request-response-pairs/banner/index.js | 3 ++- .../expectations/request-response-pairs/currency/index.js | 6 ++++-- .../expectations/request-response-pairs/gdpr/index.js | 3 ++- .../expectations/request-response-pairs/instream/index.js | 3 ++- .../request-response-pairs/multiple-bidders/index-1.js | 3 ++- .../request-response-pairs/multiple-bidders/index-2.js | 6 ++++-- .../expectations/request-response-pairs/native/index.js | 6 ++++-- .../expectations/request-response-pairs/outstream/index.js | 6 ++++-- 8 files changed, 24 insertions(+), 12 deletions(-) diff --git a/test/mock-server/expectations/request-response-pairs/banner/index.js b/test/mock-server/expectations/request-response-pairs/banner/index.js index 17538c8b33d..b34af63cc45 100644 --- a/test/mock-server/expectations/request-response-pairs/banner/index.js +++ b/test/mock-server/expectations/request-response-pairs/banner/index.js @@ -36,7 +36,8 @@ exports.getRequest = function() { 'allow_smaller_sizes': false, 'use_pmt_rule': false, 'prebid': true, - 'disable_psa': true + 'disable_psa': true, + 'hb_source': 1 }], 'user': {} } diff --git a/test/mock-server/expectations/request-response-pairs/currency/index.js b/test/mock-server/expectations/request-response-pairs/currency/index.js index 1f809476afa..d9bdc5af737 100644 --- a/test/mock-server/expectations/request-response-pairs/currency/index.js +++ b/test/mock-server/expectations/request-response-pairs/currency/index.js @@ -35,7 +35,8 @@ exports.getRequest = function() { 'allow_smaller_sizes': false, 'use_pmt_rule': false, 'prebid': true, - 'disable_psa': true + 'disable_psa': true, + 'hb_source': 1 }, { 'sizes': [{ 'width': 1, @@ -65,7 +66,8 @@ exports.getRequest = function() { 'required': false } }] - } + }, + 'hb_source': 1 }], 'user': {} } diff --git a/test/mock-server/expectations/request-response-pairs/gdpr/index.js b/test/mock-server/expectations/request-response-pairs/gdpr/index.js index 646559f2a7f..aa815820873 100644 --- a/test/mock-server/expectations/request-response-pairs/gdpr/index.js +++ b/test/mock-server/expectations/request-response-pairs/gdpr/index.js @@ -35,7 +35,8 @@ exports.getRequest = function() { 'allow_smaller_sizes': false, 'use_pmt_rule': false, 'prebid': true, - 'disable_psa': true + 'disable_psa': true, + 'hb_source': 1 }], 'user': {} } diff --git a/test/mock-server/expectations/request-response-pairs/instream/index.js b/test/mock-server/expectations/request-response-pairs/instream/index.js index 5164e56e093..2c6ca03875b 100644 --- a/test/mock-server/expectations/request-response-pairs/instream/index.js +++ b/test/mock-server/expectations/request-response-pairs/instream/index.js @@ -34,7 +34,8 @@ exports.getRequest = function() { 'prebid': true, 'disable_psa': true, 'require_asset_url': true, - 'video': {} + 'video': {}, + 'hb_source': 1 }], 'user': {} } diff --git a/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js b/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js index 9c4128fc004..deca38b6022 100644 --- a/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js +++ b/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js @@ -41,7 +41,8 @@ exports.getRequest = function() { 'required': true } }] - } + }, + 'hb_source': 1 }], 'user': {} } diff --git a/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js b/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js index d3c8e8ea376..ae09e4ec4a7 100644 --- a/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js +++ b/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js @@ -35,7 +35,8 @@ exports.getRequest = function() { 'allow_smaller_sizes': false, 'use_pmt_rule': false, 'prebid': true, - 'disable_psa': true + 'disable_psa': true, + 'hb_source': 1 }, { 'sizes': [{ 'width': 1, @@ -65,7 +66,8 @@ exports.getRequest = function() { 'required': false } }] - } + }, + 'hb_source': 1 }], 'user': {} } diff --git a/test/mock-server/expectations/request-response-pairs/native/index.js b/test/mock-server/expectations/request-response-pairs/native/index.js index f9a8b9e3585..201e9834b68 100644 --- a/test/mock-server/expectations/request-response-pairs/native/index.js +++ b/test/mock-server/expectations/request-response-pairs/native/index.js @@ -41,7 +41,8 @@ exports.getRequest = function() { 'required': true } }] - } + }, + 'hb_source': 1 }, { 'sizes': [{ 'width': 1, @@ -71,7 +72,8 @@ exports.getRequest = function() { 'required': false } }] - } + }, + 'hb_source': 1 }], 'user': {} } diff --git a/test/mock-server/expectations/request-response-pairs/outstream/index.js b/test/mock-server/expectations/request-response-pairs/outstream/index.js index be5f4654b9f..ad2502aff2d 100644 --- a/test/mock-server/expectations/request-response-pairs/outstream/index.js +++ b/test/mock-server/expectations/request-response-pairs/outstream/index.js @@ -36,7 +36,8 @@ exports.getRequest = function() { 'video': { 'skippable': true, 'playback_method': ['auto_play_sound_off'] - } + }, + 'hb_source': 1 }, { 'sizes': [{ 'width': 640, @@ -55,7 +56,8 @@ exports.getRequest = function() { 'video': { 'skippable': true, 'playback_method': ['auto_play_sound_off'] - } + }, + 'hb_source': 1 }], 'user': {} } From 17e1d803047160646ec0ec93f923755d87473755 Mon Sep 17 00:00:00 2001 From: thuyhq <61451682+thuyhq@users.noreply.github.com> Date: Wed, 6 May 2020 14:14:12 +0700 Subject: [PATCH 293/496] Add Quantumdex Bid Adapter (#5170) * Add Quantumdex Bid Adapter Add Quantumdex Bid Adapter * Update quantumdexBidAdapter.js, quantumdexBidAdapter_spec.js * Update quantumdexBidAdapter.md * Update quantumdexBidAdapter.md * Update quantumdexBidAdapter.js * Update quantumdexBidAdapter.js * Update quantumdexBidAdapter.js --- modules/quantumdexBidAdapter.js | 219 +++++++ modules/quantumdexBidAdapter.md | 56 ++ .../spec/modules/quantumdexBidAdapter_spec.js | 604 ++++++++++++++++++ 3 files changed, 879 insertions(+) create mode 100644 modules/quantumdexBidAdapter.js create mode 100644 modules/quantumdexBidAdapter.md create mode 100644 test/spec/modules/quantumdexBidAdapter_spec.js diff --git a/modules/quantumdexBidAdapter.js b/modules/quantumdexBidAdapter.js new file mode 100644 index 00000000000..c2a130f789d --- /dev/null +++ b/modules/quantumdexBidAdapter.js @@ -0,0 +1,219 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +const BIDDER_CODE = 'quantumdex'; +const ENDPOINT = 'https://useast.quantumdex.io/auction/adapter'; +const USER_SYNC_URL = 'https://useast.quantumdex.io/usersync/adapter'; +var bySlotTargetKey = {}; +var bySlotSizesCount = {} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: ['banner', 'video'], + aliases: ['qde'], + isBidRequestValid: function (bid) { + if (!bid.params) { + return false; + } + if (!bid.params.siteId) { + return false; + } + if (!utils.deepAccess(bid, 'mediaTypes.banner') && !utils.deepAccess(bid, 'mediaTypes.video')) { + return false; + } + if (utils.deepAccess(bid, 'mediaTypes.banner')) { // Quantumdex does not support multi type bids, favor banner over video + if (!utils.deepAccess(bid, 'mediaTypes.banner.sizes')) { + // sizes at the banner is required. + return false; + } + } else if (utils.deepAccess(bid, 'mediaTypes.video')) { + if (!utils.deepAccess(bid, 'mediaTypes.video.playerSize')) { + // playerSize is required for instream adUnits. + return false; + } + } + return true; + }, + + buildRequests: function (validBidRequests, bidderRequest) { + var bids = JSON.parse(JSON.stringify(validBidRequests)) + const payload = {}; + + bids.forEach(bidReq => { + var targetKey = 0; + if (bySlotTargetKey[bidReq.adUnitCode] != undefined) { + targetKey = bySlotTargetKey[bidReq.adUnitCode]; + } else { + var biggestSize = _getBiggestSize(bidReq.sizes); + if (biggestSize) { + if (bySlotSizesCount[biggestSize] != undefined) { + bySlotSizesCount[biggestSize]++ + targetKey = bySlotSizesCount[biggestSize]; + } else { + bySlotSizesCount[biggestSize] = 0; + targetKey = 0 + } + } + } + bySlotTargetKey[bidReq.adUnitCode] = targetKey; + bidReq.targetKey = targetKey; + }); + + payload.device = {}; + payload.device.ua = navigator.userAgent; + payload.device.height = window.top.innerHeight; + payload.device.width = window.top.innerWidth; + payload.device.dnt = _getDoNotTrack(); + payload.device.language = navigator.language; + + payload.site = {}; + payload.site.id = bids[0].params.siteId; + payload.site.page = _extractTopWindowUrlFromBidderRequest(bidderRequest); + payload.site.referrer = _extractTopWindowReferrerFromBidderRequest(bidderRequest); + payload.site.hostname = window.top.location.hostname; + + // Apply GDPR parameters to request. + payload.gdpr = {}; + if (bidderRequest && bidderRequest.gdprConsent) { + payload.gdpr.gdprApplies = bidderRequest.gdprConsent.gdprApplies ? 'true' : 'false'; + if (bidderRequest.gdprConsent.consentString) { + payload.gdpr.consentString = bidderRequest.gdprConsent.consentString; + } + } + // Apply schain. + if (bids[0].schain) { + payload.schain = JSON.stringify(bids[0].schain) + } + // Apply us_privacy. + if (bidderRequest && bidderRequest.uspConsent) { + payload.us_privacy = bidderRequest.uspConsent; + } + + payload.bids = bids; + + return { + method: 'POST', + url: ENDPOINT, + data: payload, + withCredentials: true, + bidderRequests: bids + }; + }, + interpretResponse: function (serverResponse, bidRequest) { + const serverBody = serverResponse.body; + const serverBids = serverBody.bids; + // check overall response + if (!serverBody || typeof serverBody !== 'object') { + return []; + } + if (!serverBids || typeof serverBids !== 'object') { + return []; + } + + const bidResponses = []; + serverBids.forEach(bid => { + const bidResponse = { + requestId: bid.requestId, + cpm: bid.cpm, + width: bid.width, + height: bid.height, + creativeId: bid.creativeId, + dealId: bid.dealId, + currency: bid.currency, + netRevenue: bid.netRevenue, + ttl: bid.ttl, + mediaType: bid.mediaType + }; + if (bid.vastXml) { + bidResponse.vastXml = utils.replaceAuctionPrice(bid.vastXml, bid.cpm); + } else { + bidResponse.ad = utils.replaceAuctionPrice(bid.ad, bid.cpm); + } + bidResponses.push(bidResponse); + }); + return bidResponses; + }, + getUserSyncs: function (syncOptions, serverResponses) { + const syncs = []; + try { + if (syncOptions.iframeEnabled) { + syncs.push({ + type: 'iframe', + url: USER_SYNC_URL + }); + } + if (syncOptions.pixelEnabled && serverResponses.length > 0) { + serverResponses[0].body.pixel.forEach(px => { + syncs.push({ + type: px.type, + url: px.url + }); + }); + } + } catch (e) { } + return syncs; + } +}; + +function _getBiggestSize(sizes) { + if (sizes.length <= 0) return false + var acreage = 0; + var index = 0; + for (var i = 0; i < sizes.length; i++) { + var currentAcreage = sizes[i][0] * sizes[i][1]; + if (currentAcreage >= acreage) { + acreage = currentAcreage; + index = i; + } + } + return sizes[index][0] + 'x' + sizes[index][1]; +} + +function _getDoNotTrack() { + if (window.top.doNotTrack || navigator.doNotTrack || navigator.msDoNotTrack) { + if (window.top.doNotTrack == '1' || navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') { + return 1; + } else { + return 0; + } + } else { + return 0; + } +} + +/** + * Extracts the page url from given bid request or use the (top) window location as fallback + * + * @param {*} bidderRequest + * @returns {string} + */ +function _extractTopWindowUrlFromBidderRequest(bidderRequest) { + if (bidderRequest && utils.deepAccess(bidderRequest, 'refererInfo.canonicalUrl')) { + return bidderRequest.refererInfo.canonicalUrl; + } + + try { + return window.top.location.href; + } catch (e) { + return window.location.href; + } +} + +/** + * Extracts the referrer from given bid request or use the (top) document referrer as fallback + * + * @param {*} bidderRequest + * @returns {string} + */ +function _extractTopWindowReferrerFromBidderRequest(bidderRequest) { + if (bidderRequest && utils.deepAccess(bidderRequest, 'refererInfo.referer')) { + return bidderRequest.refererInfo.referer; + } + + try { + return window.top.document.referrer; + } catch (e) { + return window.document.referrer; + } +} + +registerBidder(spec); diff --git a/modules/quantumdexBidAdapter.md b/modules/quantumdexBidAdapter.md new file mode 100644 index 00000000000..8c35ea8cb05 --- /dev/null +++ b/modules/quantumdexBidAdapter.md @@ -0,0 +1,56 @@ +# Overview + +``` +Module Name: Quantum Digital Exchange Bidder Adapter +Module Type: Bidder Adapter +Maintainer: ken@quantumdex.io +``` + +# Description + +Connects to Quantum Digital Exchange for bids. +Quantumdex bid adapter supports Banner and Video (Instream and Outstream) ads. + +# Test Parameters +``` +var adUnits = [ + { + code: 'test-div', + mediaTypes: { + banner: { + sizes: [[300, 250], [300,600]] + } + }, + bids: [ + { + bidder: 'quantumdex', + params: { + siteId: 'quantumdex-site-id', // siteId provided by Quantumdex + } + } + ] + } +]; +``` + +# Video Test Parameters +``` +var videoAdUnit = { + code: 'test-div', + sizes: [[640, 480]], + mediaTypes: { + video: { + playerSize: [[640, 480]], + context: 'instream' + }, + }, + bids: [ + { + bidder: 'quantumdex', + params: { + siteId: 'quantumdex-site-id', // siteId provided by Quantumdex + } + } + ] +}; +``` \ No newline at end of file diff --git a/test/spec/modules/quantumdexBidAdapter_spec.js b/test/spec/modules/quantumdexBidAdapter_spec.js new file mode 100644 index 00000000000..ef8791cca57 --- /dev/null +++ b/test/spec/modules/quantumdexBidAdapter_spec.js @@ -0,0 +1,604 @@ +import { expect } from 'chai' +import { spec } from 'modules/quantumdexBidAdapter.js' +import { newBidder } from 'src/adapters/bidderFactory.js' +import { userSync } from '../../../src/userSync.js'; + +describe('QuantumdexBidAdapter', function () { + const adapter = newBidder(spec) + + describe('.code', function () { + it('should return a bidder code of quantumdex', function () { + expect(spec.code).to.equal('quantumdex') + }) + }) + + describe('inherited functions', function () { + it('should exist and be a function', function () { + expect(adapter.callBids).to.exist.and.to.be.a('function') + }) + }) + + describe('.isBidRequestValid', function () { + it('should return false if there are no params', () => { + const bid = { + 'bidder': 'quantumdex', + 'adUnitCode': 'adunit-code', + 'mediaTypes': { + banner: { + sizes: [[300, 250], [300, 600]] + } + }, + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false if there is no siteId param', () => { + const bid = { + 'bidder': 'quantumdex', + 'adUnitCode': 'adunit-code', + params: { + site_id: '1a2b3c4d5e6f1a2b3c4d', + }, + 'mediaTypes': { + banner: { + sizes: [[300, 250], [300, 600]] + } + }, + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false if there is no mediaTypes', () => { + const bid = { + 'bidder': 'quantumdex', + 'adUnitCode': 'adunit-code', + params: { + siteId: '1a2b3c4d5e6f1a2b3c4d' + }, + 'mediaTypes': { + }, + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return true if the bid is valid', () => { + const bid = { + 'bidder': 'quantumdex', + 'adUnitCode': 'adunit-code', + params: { + siteId: '1a2b3c4d5e6f1a2b3c4d' + }, + 'mediaTypes': { + banner: { + sizes: [[300, 250], [300, 600]] + } + }, + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + describe('banner', () => { + it('should return false if there are no banner sizes', () => { + const bid = { + 'bidder': 'quantumdex', + 'adUnitCode': 'adunit-code', + params: { + siteId: '1a2b3c4d5e6f1a2b3c4d' + }, + 'mediaTypes': { + banner: { + + } + }, + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return true if there is banner sizes', () => { + const bid = { + 'bidder': 'quantumdex', + 'adUnitCode': 'adunit-code', + params: { + siteId: '1a2b3c4d5e6f1a2b3c4d' + }, + 'mediaTypes': { + banner: { + sizes: [[300, 250], [300, 600]] + } + }, + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + }); + + describe('video', () => { + it('should return false if there is no playerSize defined in the video mediaType', () => { + const bid = { + 'bidder': 'quantumdex', + 'adUnitCode': 'adunit-code', + params: { + siteId: '1a2b3c4d5e6f1a2b3c4d', + sizes: [[300, 250], [300, 600]] + }, + 'mediaTypes': { + video: { + context: 'instream' + } + }, + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return true if there is playerSize defined on the video mediaType', () => { + const bid = { + 'bidder': 'quantumdex', + 'adUnitCode': 'adunit-code', + params: { + siteId: '1a2b3c4d5e6f1a2b3c4d', + }, + 'mediaTypes': { + video: { + context: 'instream', + playerSize: [[640, 480]] + } + }, + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + }); + }); + + describe('.buildRequests', function () { + beforeEach(function () { + sinon.stub(userSync, 'canBidderRegisterSync'); + }); + afterEach(function () { + userSync.canBidderRegisterSync.restore(); + }); + let bidRequest = [{ + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'indirectseller.com', + 'sid': '00001', + 'hp': 1 + }, + { + 'asi': 'indirectseller-2.com', + 'sid': '00002', + 'hp': 0 + }, + ] + }, + 'bidder': 'quantumdex', + 'params': { + 'siteId': '1a2b3c4d5e6f1a2b3c4d', + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'targetKey': 0, + 'bidId': '30b31c1838de1f', + }, + { + 'bidder': 'quantumdex', + 'params': { + 'ad_unit': '/7780971/sparks_prebid_LB', + 'sizes': [[300, 250], [300, 600]], + 'referrer': 'overrides_top_window_location' + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [[120, 600], [300, 600], [160, 600]], + 'targetKey': 1, + 'bidId': '30b31c1838de1e', + }]; + + let bidderRequests = { + 'gdprConsent': { + 'consentString': 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', + 'vendorData': {}, + 'gdprApplies': true + }, + 'refererInfo': { + 'numIframes': 0, + 'reachedTop': true, + 'referer': 'https://example.com', + 'stack': ['https://example.com'] + }, + uspConsent: 'someCCPAString' + }; + + it('should return a properly formatted request', function () { + const bidRequests = spec.buildRequests(bidRequest, bidderRequests) + expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/adapter') + expect(bidRequests.method).to.equal('POST') + expect(bidRequests.bidderRequests).to.eql(bidRequest); + }) + + it('should return a properly formatted request with GDPR applies set to true', function () { + const bidRequests = spec.buildRequests(bidRequest, bidderRequests) + expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/adapter') + expect(bidRequests.method).to.equal('POST') + expect(bidRequests.data.gdpr.gdprApplies).to.equal('true') + expect(bidRequests.data.gdpr.consentString).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A==') + }) + + it('should return a properly formatted request with GDPR applies set to false', function () { + bidderRequests.gdprConsent.gdprApplies = false; + const bidRequests = spec.buildRequests(bidRequest, bidderRequests) + expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/adapter') + expect(bidRequests.method).to.equal('POST') + expect(bidRequests.data.gdpr.gdprApplies).to.equal('false') + expect(bidRequests.data.gdpr.consentString).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A==') + }) + it('should return a properly formatted request with GDPR applies set to false with no consent_string param', function () { + let bidderRequests = { + 'gdprConsent': { + 'consentString': undefined, + 'vendorData': {}, + 'gdprApplies': false + }, + 'refererInfo': { + 'numIframes': 0, + 'reachedTop': true, + 'referer': 'https://example.com', + 'stack': ['https://example.com'] + } + }; + const bidRequests = spec.buildRequests(bidRequest, bidderRequests) + expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/adapter') + expect(bidRequests.method).to.equal('POST') + expect(bidRequests.data.gdpr.gdprApplies).to.equal('false') + expect(bidRequests.data.gdpr).to.not.include.keys('consentString') + }) + it('should return a properly formatted request with GDPR applies set to true with no consentString param', function () { + let bidderRequests = { + 'gdprConsent': { + 'consentString': undefined, + 'vendorData': {}, + 'gdprApplies': true + }, + 'refererInfo': { + 'numIframes': 0, + 'reachedTop': true, + 'referer': 'https://example.com', + 'stack': ['https://example.com'] + } + }; + const bidRequests = spec.buildRequests(bidRequest, bidderRequests) + expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/adapter') + expect(bidRequests.method).to.equal('POST') + expect(bidRequests.data.gdpr.gdprApplies).to.equal('true') + expect(bidRequests.data.gdpr).to.not.include.keys('consentString') + }) + it('should return a properly formatted request with schain defined', function () { + const bidRequests = spec.buildRequests(bidRequest, bidderRequests); + expect(JSON.parse(bidRequests.data.schain)).to.deep.equal(bidRequest[0].schain) + }); + it('should return a properly formatted request with us_privacy included', function () { + const bidRequests = spec.buildRequests(bidRequest, bidderRequests); + expect(bidRequests.data.us_privacy).to.equal('someCCPAString'); + }); + }); + + describe('.interpretResponse', function () { + const bidRequests = { + 'method': 'POST', + 'url': 'https://useast.quantumdex.io/auction/adapter', + 'withCredentials': true, + 'data': { + 'device': { + 'ua': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36', + 'height': 937, + 'width': 1920, + 'dnt': 0, + 'language': 'vi' + }, + 'site': { + 'id': '343', + 'page': 'https://www.example.com/page', + 'referrer': '', + 'hostname': 'www.example.com' + } + }, + 'bidderRequests': [ + { + 'bidder': 'quantumdex', + 'params': { + 'siteId': '343' + }, + 'crumbs': { + 'pubcid': 'c2b2ba08-9954-4850-8ee5-2bf4a2b35eff' + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[160, 600], [120, 600]] + } + }, + 'adUnitCode': 'vi_3431035_1', + 'transactionId': '994d8404-4a28-4c43-98d8-a38dbb061910', + 'sizes': [[160, 600], [120, 600]], + 'bidId': '3000aa31c41a29c21', + 'bidderRequestId': '299926b3d3628cdd7', + 'auctionId': '22445943-a0aa-4c63-a413-4deb64fcff1c', + 'src': 'client', + 'bidRequestsCount': 41, + 'bidderRequestsCount': 41, + 'bidderWinsCount': 0, + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'freegames66.com', + 'sid': '343', + 'hp': 1 + } + ] + } + }, + { + 'bidder': 'quantumdex', + 'params': { + 'siteId': '343' + }, + 'crumbs': { + 'pubcid': 'c2b2ba08-9954-4850-8ee5-2bf4a2b35eff' + }, + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250], [250, 250], [200, 200], [180, 150]] + } + }, + 'adUnitCode': 'vi_3431033_1', + 'transactionId': '800fe87e-bfec-43a5-ace0-c4e2373ff4b5', + 'sizes': [[300, 250], [250, 250], [200, 200], [180, 150]], + 'bidId': '30024615be22ef66a', + 'bidderRequestId': '299926b3d3628cdd7', + 'auctionId': '22445943-a0aa-4c63-a413-4deb64fcff1c', + 'src': 'client', + 'bidRequestsCount': 41, + 'bidderRequestsCount': 41, + 'bidderWinsCount': 0, + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'freegames66.com', + 'sid': '343', + 'hp': 1 + } + ] + } + }, + { + 'bidder': 'quantumdex', + 'params': { + 'siteId': '343' + }, + 'crumbs': { + 'pubcid': 'c2b2ba08-9954-4850-8ee5-2bf4a2b35eff' + }, + 'mediaTypes': { + 'video': { + 'playerSize': [[640, 480]], + 'context': 'instream', + 'mimes': [ + 'video/mp4', + 'video/x-flv', + 'video/x-ms-wmv', + 'application/vnd.apple.mpegurl', + 'application/x-mpegurl', + 'video/3gpp', + 'video/mpeg', + 'video/ogg', + 'video/quicktime', + 'video/webm', + 'video/x-m4v', + 'video/ms-asf', + 'video/x-msvideo' + ], + 'protocols': [1, 2, 3, 4, 5, 6], + 'playbackmethod': [6], + 'maxduration': 120, + 'linearity': 1, + 'api': [2] + } + }, + 'adUnitCode': 'vi_3431909', + 'transactionId': '33d83d87-43cc-499b-aabe-5c22eb6acfbb', + 'sizes': [[640, 480]], + 'bidId': '1854b40107d6745c', + 'bidderRequestId': '1840763b6bda185d', + 'auctionId': 'df495de0-5d42-471f-a501-73bcd7254b80', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0, + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'freegames66.com', + 'sid': '343', + 'hp': 1 + } + ] + } + } + ] + }; + + let serverResponse = { + 'body': { + 'bids': [ + { + 'requestId': '3000aa31c41a29c21', + 'cpm': 1.07, + 'width': 160, + 'height': 600, + 'ad': `
Quantumdex AD
`, + 'ttl': 500, + 'creativeId': '1234abcd', + 'netRevenue': true, + 'currency': 'USD', + 'dealId': 'quantumdex', + 'mediaType': 'banner' + }, + { + 'requestId': '30024615be22ef66a', + 'cpm': 1, + 'width': 300, + 'height': 250, + 'ad': `
Quantumdex AD
`, + 'ttl': 500, + 'creativeId': '1234abcd', + 'netRevenue': true, + 'currency': 'USD', + 'dealId': 'quantumdex', + 'mediaType': 'banner' + }, + { + 'requestId': '1854b40107d6745c', + 'cpm': 1.25, + 'width': 300, + 'height': 250, + 'vastXml': 'quantumdex', + 'ttl': 500, + 'creativeId': '30292e432662bd5f86d90774b944b038', + 'netRevenue': true, + 'currency': 'USD', + 'dealId': 'quantumdex', + 'mediaType': 'video' + } + ], + 'pixel': [{ + 'url': 'https://example.com/pixel.png', + 'type': 'image' + }] + } + }; + + let prebidResponse = [ + { + 'requestId': '3000aa31c41a29c21', + 'cpm': 1.07, + 'width': 160, + 'height': 600, + 'ad': `
Quantumdex AD
`, + 'ttl': 500, + 'creativeId': '1234abcd', + 'netRevenue': true, + 'currency': 'USD', + 'dealId': 'quantumdex', + 'mediaType': 'banner' + }, + { + 'requestId': '30024615be22ef66a', + 'cpm': 1, + 'width': 300, + 'height': 250, + 'ad': `
Quantumdex AD
`, + 'ttl': 500, + 'creativeId': '1234abcd', + 'netRevenue': true, + 'currency': 'USD', + 'dealId': 'quantumdex', + 'mediaType': 'banner' + }, + { + 'requestId': '1854b40107d6745c', + 'cpm': 1.25, + 'width': 300, + 'height': 250, + 'vastXml': 'quantumdex', + 'ttl': 500, + 'creativeId': '30292e432662bd5f86d90774b944b038', + 'netRevenue': true, + 'currency': 'USD', + 'dealId': 'quantumdex', + 'mediaType': 'video' + } + ]; + + it('should map bidResponse to prebidResponse', function () { + const response = spec.interpretResponse(serverResponse, bidRequests); + response.forEach((resp, i) => { + expect(resp.requestId).to.equal(prebidResponse[i].requestId); + expect(resp.cpm).to.equal(prebidResponse[i].cpm); + expect(resp.width).to.equal(prebidResponse[i].width); + expect(resp.height).to.equal(prebidResponse[i].height); + expect(resp.ttl).to.equal(prebidResponse[i].ttl); + expect(resp.creativeId).to.equal(prebidResponse[i].creativeId); + expect(resp.netRevenue).to.equal(prebidResponse[i].netRevenue); + expect(resp.currency).to.equal(prebidResponse[i].currency); + expect(resp.dealId).to.equal(prebidResponse[i].dealId); + if (resp.mediaType === 'video') { + expect(resp.vastXml.indexOf('quantumdex')).to.be.greaterThan(0); + } + if (resp.mediaType === 'banner') { + expect(resp.ad.indexOf('Quantumdex AD')).to.be.greaterThan(0); + } + }); + }); + }); + + describe('.getUserSyncs', function () { + let bidResponse = [{ + 'body': { + 'pixel': [{ + 'url': 'https://pixel-test', + 'type': 'image' + }] + } + }]; + + it('should return one sync pixel', function () { + expect(spec.getUserSyncs({ pixelEnabled: true }, bidResponse)).to.deep.equal([{ + type: 'image', + url: 'https://pixel-test' + }]); + }); + it('should return an empty array when sync is enabled but there are no bidResponses', function () { + expect(spec.getUserSyncs({ pixelEnabled: true }, [])).to.have.length(0); + }); + + it('should return an empty array when sync is enabled but no sync pixel returned', function () { + const pixel = Object.assign({}, bidResponse); + delete pixel[0].body.pixel; + expect(spec.getUserSyncs({ pixelEnabled: true }, bidResponse)).to.have.length(0); + }); + + it('should return an empty array', function () { + expect(spec.getUserSyncs({ pixelEnabled: false }, bidResponse)).to.have.length(0); + expect(spec.getUserSyncs({ pixelEnabled: true }, [])).to.have.length(0); + }); + }); +}); From bb6cb103d8b4e9ecad7254199810b81e4427bb7f Mon Sep 17 00:00:00 2001 From: Galphimbl Date: Wed, 6 May 2020 20:29:31 +0300 Subject: [PATCH 294/496] Admixer Bid Adapter add consent support (#5169) * add gdpr and usp Co-authored-by: atkachov --- modules/admixerBidAdapter.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/modules/admixerBidAdapter.js b/modules/admixerBidAdapter.js index e8a27a033b4..b2f24cfa910 100644 --- a/modules/admixerBidAdapter.js +++ b/modules/admixerBidAdapter.js @@ -20,8 +20,22 @@ export const spec = { buildRequests: function (validRequest, bidderRequest) { const payload = { imps: [], - referrer: encodeURIComponent(bidderRequest.refererInfo.referer), }; + if (bidderRequest) { + if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { + payload.referrer = encodeURIComponent(bidderRequest.refererInfo.referer); + } + if (bidderRequest.gdprConsent) { + payload.gdprConsent = { + consentString: bidderRequest.gdprConsent.consentString, + // will check if the gdprApplies field was populated with a boolean value (ie from page config). If it's undefined, then default to true + gdprApplies: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true + } + } + if (bidderRequest.uspConsent) { + payload.uspConsent = bidderRequest.uspConsent; + } + } validRequest.forEach((bid) => { payload.imps.push(bid); }); From fd26f66c898f89b682fd429bfc7aaf959ffc7677 Mon Sep 17 00:00:00 2001 From: Sourabh Gandhe Date: Wed, 6 May 2020 23:53:45 +0530 Subject: [PATCH 295/496] DeepIntent: Gdpr support (#5147) * feat(gdpr) : gdpr support added * tests fixed --- modules/deepintentBidAdapter.js | 5 +++++ test/spec/modules/deepintentBidAdapter_spec.js | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/modules/deepintentBidAdapter.js b/modules/deepintentBidAdapter.js index d72477a582a..c4dc23cf912 100644 --- a/modules/deepintentBidAdapter.js +++ b/modules/deepintentBidAdapter.js @@ -44,6 +44,11 @@ export const spec = { utils.deepSetValue(openRtbBidRequest, 'regs.ext.us_privacy', bidderRequest.uspConsent); } + if (bidderRequest && bidderRequest.gdprConsent) { + utils.deepSetValue(openRtbBidRequest, 'user.ext.consent', bidderRequest.gdprConsent.consentString); + utils.deepSetValue(openRtbBidRequest, 'regs.ext.gdpr', (bidderRequest.gdprConsent.gdprApplies ? 1 : 0)); + } + return { method: 'POST', url: BIDDER_ENDPOINT, diff --git a/test/spec/modules/deepintentBidAdapter_spec.js b/test/spec/modules/deepintentBidAdapter_spec.js index 8b462b3217d..6d9b883e2bb 100644 --- a/test/spec/modules/deepintentBidAdapter_spec.js +++ b/test/spec/modules/deepintentBidAdapter_spec.js @@ -162,6 +162,23 @@ describe('Deepintent adapter', function () { let data2 = JSON.parse(bRequest2.data); expect(data2.regs).to.equal(undefined); }); + it('bid Request check: GDPR Check', function () { + let bidRequest = { + gdprConsent: { + consentString: 'kjfdnidasd123sadsd', + gdprApplies: true + } + }; + let bRequest = spec.buildRequests(request, bidRequest); + let data = JSON.parse(bRequest.data); + expect(data.user.ext.consent).to.equal('kjfdnidasd123sadsd'); + expect(data.regs.ext.gdpr).to.equal(1); + let bidRequest2 = {}; + let bRequest2 = spec.buildRequests(request, bidRequest2); + let data2 = JSON.parse(bRequest2.data); + expect(data2.regs).to.equal(undefined); + expect(data2.user.ext).to.equal(undefined); + }); }); describe('user sync check', function () { it('user sync url check', function () { From 1fa1ecf8a4d956ed437078ea2ffdb65538e291f1 Mon Sep 17 00:00:00 2001 From: Adprime <64427228+Adprime@users.noreply.github.com> Date: Wed, 6 May 2020 21:39:33 +0300 Subject: [PATCH 296/496] New Adprime bidder adapter (#5172) * initial * fix * remove redundant language mod, use player sizes in video traff * test modify * fix * Adding Tests Co-authored-by: Aigolkin1991 --- modules/adprimeBidAdapter.js | 102 ++++++++ modules/adprimeBidAdapter.md | 53 ++++ test/spec/modules/adprimeBidAdapter_spec.js | 270 ++++++++++++++++++++ 3 files changed, 425 insertions(+) create mode 100644 modules/adprimeBidAdapter.js create mode 100644 modules/adprimeBidAdapter.md create mode 100644 test/spec/modules/adprimeBidAdapter_spec.js diff --git a/modules/adprimeBidAdapter.js b/modules/adprimeBidAdapter.js new file mode 100644 index 00000000000..d324886f7c6 --- /dev/null +++ b/modules/adprimeBidAdapter.js @@ -0,0 +1,102 @@ +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; + +const BIDDER_CODE = 'adprime'; +const AD_URL = 'https://delta.adprime.com/?c=o&m=multi'; + +function isBidResponseValid(bid) { + if (!bid.requestId || !bid.cpm || !bid.creativeId || + !bid.ttl || !bid.currency) { + return false; + } + switch (bid.mediaType) { + case BANNER: + return Boolean(bid.width && bid.height && bid.ad); + case VIDEO: + return Boolean(bid.vastUrl); + case NATIVE: + return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); + default: + return false; + } +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid: (bid) => { + return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId))); + }, + + buildRequests: (validBidRequests = [], bidderRequest) => { + let winTop = window; + let location; + try { + location = new URL(bidderRequest.refererInfo.referer) + winTop = window.top; + } catch (e) { + location = winTop.location; + utils.logMessage(e); + }; + let placements = []; + let request = { + 'deviceWidth': winTop.screen.width, + 'deviceHeight': winTop.screen.height, + 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', + 'secure': 1, + 'host': location.host, + 'page': location.pathname, + 'placements': placements + }; + if (bidderRequest) { + if (bidderRequest.uspConsent) { + request.ccpa = bidderRequest.uspConsent; + } + if (bidderRequest.gdprConsent) { + request.gdpr = bidderRequest.gdprConsent + } + } + const len = validBidRequests.length; + + for (let i = 0; i < len; i++) { + let bid = validBidRequests[i]; + let sizes + if (bid.mediaTypes) { + if (bid.mediaTypes[BANNER] && bid.mediaTypes[BANNER].sizes) { + sizes = bid.mediaTypes[BANNER].sizes + } else if (bid.mediaTypes[VIDEO] && bid.mediaTypes[VIDEO].playerSize) { + sizes = bid.mediaTypes[VIDEO].playerSize + } + } + placements.push({ + placementId: bid.params.placementId, + bidId: bid.bidId, + sizes: sizes || [], + wPlayer: sizes ? sizes[0] : 0, + hPlayer: sizes ? sizes[1] : 0, + traffic: bid.params.traffic || BANNER, + schain: bid.schain || {} + }); + } + return { + method: 'POST', + url: AD_URL, + data: request + }; + }, + + interpretResponse: (serverResponse) => { + let response = []; + for (let i = 0; i < serverResponse.body.length; i++) { + let resItem = serverResponse.body[i]; + if (isBidResponseValid(resItem)) { + response.push(resItem); + } + } + return response; + }, +}; + +registerBidder(spec); diff --git a/modules/adprimeBidAdapter.md b/modules/adprimeBidAdapter.md new file mode 100644 index 00000000000..0c6bed68c13 --- /dev/null +++ b/modules/adprimeBidAdapter.md @@ -0,0 +1,53 @@ +# Overview + +``` +Module Name: adprime Bidder Adapter +Module Type: adprime Bidder Adapter +``` + +# Description + +Module that connects to adprime demand sources + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'placementId_0', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [ + { + bidder: 'adprime', + params: { + placementId: 0, + traffic: 'banner' + } + } + ] + }, + // Will return test vast xml. All video params are stored under placement in publishers UI + { + code: 'placementId_0', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream' + } + }, + bids: [ + { + bidder: 'adprime', + params: { + placementId: 0, + traffic: 'video' + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/adprimeBidAdapter_spec.js b/test/spec/modules/adprimeBidAdapter_spec.js new file mode 100644 index 00000000000..7524665e33f --- /dev/null +++ b/test/spec/modules/adprimeBidAdapter_spec.js @@ -0,0 +1,270 @@ +import {expect} from 'chai'; +import {spec} from '../../../modules/adprimeBidAdapter.js'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; + +describe('AdprimebBidAdapter', function () { + const bid = { + bidId: '23fhj33i987f', + bidder: 'adprime', + params: { + placementId: 0, + traffic: BANNER + } + }; + + const bidderRequest = { + refererInfo: { + referer: 'test.com' + } + }; + + describe('isBidRequestValid', function () { + it('Should return true if there are bidId, params and placementId parameters present', function () { + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + it('Should return false if at least one of parameters is not present', function () { + delete bid.params.placementId; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests([bid], bidderRequest); + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + it('Returns valid URL', function () { + expect(serverRequest.url).to.equal('https://delta.adprime.com/?c=o&m=multi'); + }); + it('Returns valid data if array of bids is valid', function () { + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.language).to.be.a('string'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + expect(data.gdpr).to.not.exist; + expect(data.ccpa).to.not.exist; + let placement = data['placements'][0]; + expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes', 'hPlayer', 'wPlayer', 'schain'); + expect(placement.placementId).to.equal(0); + expect(placement.bidId).to.equal('23fhj33i987f'); + expect(placement.traffic).to.equal(BANNER); + expect(placement.schain).to.be.an('object'); + }); + + it('Returns valid data for mediatype video', function () { + const playerSize = [300, 300]; + bid.mediaTypes = {}; + bid.params.traffic = VIDEO; + bid.mediaTypes[VIDEO] = { + playerSize + }; + serverRequest = spec.buildRequests([bid], bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + let placement = data['placements'][0]; + expect(placement).to.be.an('object'); + expect(placement.traffic).to.equal(VIDEO); + expect(placement.wPlayer).to.equal(playerSize[0]); + expect(placement.hPlayer).to.equal(playerSize[1]); + }); + + it('Returns data with gdprConsent and without uspConsent', function () { + bidderRequest.gdprConsent = 'test'; + serverRequest = spec.buildRequests([bid], bidderRequest); + let data = serverRequest.data; + expect(data.gdpr).to.exist; + expect(data.gdpr).to.be.a('string'); + expect(data.gdpr).to.equal(bidderRequest.gdprConsent); + expect(data.ccpa).to.not.exist; + delete bidderRequest.gdprConsent; + }); + + it('Returns data with uspConsent and without gdprConsent', function () { + bidderRequest.uspConsent = 'test'; + serverRequest = spec.buildRequests([bid], bidderRequest); + let data = serverRequest.data; + expect(data.ccpa).to.exist; + expect(data.ccpa).to.be.a('string'); + expect(data.ccpa).to.equal(bidderRequest.uspConsent); + expect(data.gdpr).to.not.exist; + }); + + it('Returns empty data if no valid requests are passed', function () { + serverRequest = spec.buildRequests([]); + let data = serverRequest.data; + expect(data.placements).to.be.an('array').that.is.empty; + }); + }); + describe('interpretResponse', function () { + it('Should interpret banner response', function () { + const banner = { + body: [{ + mediaType: 'banner', + width: 300, + height: 250, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let bannerResponses = spec.interpretResponse(banner); + expect(bannerResponses).to.be.an('array').that.is.not.empty; + let dataItem = bannerResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.width).to.equal(300); + expect(dataItem.height).to.equal(250); + expect(dataItem.ad).to.equal('Test'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret video response', function () { + const video = { + body: [{ + vastUrl: 'test.com', + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let videoResponses = spec.interpretResponse(video); + expect(videoResponses).to.be.an('array').that.is.not.empty; + + let dataItem = videoResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.5); + expect(dataItem.vastUrl).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret native response', function () { + const native = { + body: [{ + mediaType: 'native', + native: { + clickUrl: 'test.com', + title: 'Test', + image: 'test.com', + impressionTrackers: ['test.com'], + }, + ttl: 120, + cpm: 0.4, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let nativeResponses = spec.interpretResponse(native); + expect(nativeResponses).to.be.an('array').that.is.not.empty; + + let dataItem = nativeResponses[0]; + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); + expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.native.clickUrl).to.equal('test.com'); + expect(dataItem.native.title).to.equal('Test'); + expect(dataItem.native.image).to.equal('test.com'); + expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; + expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should return an empty array if invalid banner response is passed', function () { + const invBanner = { + body: [{ + width: 300, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + + let serverResponses = spec.interpretResponse(invBanner); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid video response is passed', function () { + const invVideo = { + body: [{ + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invVideo); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid native response is passed', function () { + const invNative = { + body: [{ + mediaType: 'native', + clickUrl: 'test.com', + title: 'Test', + impressionTrackers: ['test.com'], + ttl: 120, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let serverResponses = spec.interpretResponse(invNative); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid response is passed', function () { + const invalid = { + body: [{ + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invalid); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); +}); From 065c51e67131d8016bb31809afa225869d8fda63 Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 6 May 2020 15:02:06 -0400 Subject: [PATCH 297/496] Refined the ticket-coordinator role description (#5187) --- PR_REVIEW.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/PR_REVIEW.md b/PR_REVIEW.md index 64635b7fc03..3af98f37be0 100644 --- a/PR_REVIEW.md +++ b/PR_REVIEW.md @@ -46,11 +46,16 @@ For modules and core platform updates, the initial reviewer should request an ad ## Ticket Coordinator -Each week, Prebid Org assigns one person to keep an eye on incoming issues and PRs. That person should: +Each week, Prebid Org assigns one person to keep an eye on incoming issues and PRs. Every Monday morning a reminder is +sent to the prebid-js slack channel with a link to the spreadsheet. If you're on rotation, please check that list each +Monday to see if you're on-duty. + +When on-duty: - Review issues and PRs at least once per weekday for new items. Encourage a 48 "SLA" on PRs/issues assigned. Aim for touchpoint once every 48/hours. -- For PRs: assign PRs to individuals on the PR review list. Try to be equitable -- not all PRs are created equally. Use the "Assigned" field and add the "Needs Review" label. +- For PRs: assign PRs to individuals on the **PR review list**. Try to be equitable -- not all PRs are created equally. Use the "Assigned" field and add the "Needs Review" label. - For Issues: try to address questions and troubleshooting requests on your own, assigning them to others as needed. Please add labels as appropriate (I.E. bug, question, backlog etc). - Issues that are questions or troubleshooting requests may be closed if the originator doesn't respond within a week to requests for confirmation or details. - Issues that are bug reports should be left open and assigned to someone in PR rotation to confirm or deny the bug status. -- It's polite to check with others before assigning them large tasks. -- If possible, check in on older items and see if they can be unstuck. +- It's polite to check with others before assigning them extra-large tasks. +- If possible, check in on older PRs and Issues and see if they can be unstuck. +- Perform the weekly Prebid.js release per instructions at https://github.com/prebid/Prebid.js/blob/master/RELEASE_SCHEDULE.md . This generally takes place on Tues or Weds. From 92d3e3817c278059a6bfa19ba406810e33fa601c Mon Sep 17 00:00:00 2001 From: bjorn-lw <32431346+bjorn-lw@users.noreply.github.com> Date: Thu, 7 May 2020 00:03:30 +0200 Subject: [PATCH 298/496] Send debug info from adapter to external debugger (#5151) * Livewrapped bid and analytics adapter * Fixed some tests for browser compatibility * Fixed some tests for browser compatibility * Changed analytics adapter code name * Fix double quote in debug message * modified how gdpr is being passed * Added support for Publisher Common ID Module * Corrections for ttr in analytics * ANalytics updates * Auction start time stamp changed * Detect recovered ad blocked requests Make it possible to pass dynamic parameters to adapter * Collect info on ad units receiving any valid bid * Support for ID5 Pass metadata from adapter * Typo in test + eids on wrong level * Fix for Prebid 3.0 * Fix get referer * http -> https in tests * Native support * Read sizes from mediatype.banner * Revert accidental commit * Support native data collection + minor refactorings * Set analytics endpoint * Support for app parameters * Fix issue where adunits with bids were not counted on reload * Send debug info from adapter to external debugger --- modules/livewrappedBidAdapter.js | 9 +++++ .../modules/livewrappedBidAdapter_spec.js | 35 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/modules/livewrappedBidAdapter.js b/modules/livewrappedBidAdapter.js index 57e5a5a7c2f..6033a1234e7 100644 --- a/modules/livewrappedBidAdapter.js +++ b/modules/livewrappedBidAdapter.js @@ -84,6 +84,11 @@ export const spec = { adRequests: [...adRequests], rtbData: handleEids(bidRequests) }; + + if (config.getConfig().debug) { + payload.dbg = true; + } + const payloadString = JSON.stringify(payload); return { method: 'POST', @@ -101,6 +106,10 @@ export const spec = { interpretResponse: function(serverResponse) { const bidResponses = []; + if (serverResponse.body.dbg && window.livewrapped && window.livewrapped.s2sDebug) { + window.livewrapped.s2sDebug(serverResponse.body.dbg); + } + serverResponse.body.ads.forEach(function(ad) { var bidResponse = { requestId: ad.bidId, diff --git a/test/spec/modules/livewrappedBidAdapter_spec.js b/test/spec/modules/livewrappedBidAdapter_spec.js index b82bf8db160..800ca744d9c 100644 --- a/test/spec/modules/livewrappedBidAdapter_spec.js +++ b/test/spec/modules/livewrappedBidAdapter_spec.js @@ -11,6 +11,8 @@ describe('Livewrapped adapter tests', function () { beforeEach(function () { sandbox = sinon.sandbox.create(); + window.livewrapped = undefined; + bidderRequest = { bidderCode: 'livewrapped', auctionId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', @@ -970,6 +972,39 @@ describe('Livewrapped adapter tests', function () { expect(bids).to.deep.equal(expectedResponse); }) + + it('should send debug-data to external debugger', function() { + let lwResponse = { + ads: [ + { + id: '28e5ddf4-3c01-11e8-86a7-0a44794250d4', + callerId: 'site_outsider_0', + tag: 'ad', + width: 300, + height: 250, + cpmBid: 2.565917, + bidId: '32e50fad901ae89', + auctionId: '13e674db-d4d8-4e19-9d28-ff38177db8bf', + creativeId: '52cbd598-2715-4c43-a06f-229fc170f945:427077', + ttl: 120 + } + ], + currency: 'USD', + dbg: 'debugdata' + }; + + let debugData; + + window.livewrapped = { + s2sDebug: function(dbg) { + debugData = dbg; + } + }; + + spec.interpretResponse({body: lwResponse}); + + expect(debugData).to.equal(lwResponse.dbg); + }) }); describe('user sync', function () { From 4c8a846e75c54d35828fe8f44fec3ec0d88acff7 Mon Sep 17 00:00:00 2001 From: pratik-synacor <64602199+pratik-synacor@users.noreply.github.com> Date: Thu, 7 May 2020 03:23:53 -0400 Subject: [PATCH 299/496] Add videoCacheKey on the bid object only if the cache url is not set (#5186) * Add videoCacheKey on the bid object only if the cache url is not set * Added test case for the scenario where we don't manually set the videoCacheKey on purpose when the cache url is present. --- modules/synacormediaBidAdapter.js | 5 ++- .../modules/synacormediaBidAdapter_spec.js | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/modules/synacormediaBidAdapter.js b/modules/synacormediaBidAdapter.js index ae2fd91cb6f..c9ee8f54522 100644 --- a/modules/synacormediaBidAdapter.js +++ b/modules/synacormediaBidAdapter.js @@ -4,6 +4,7 @@ import { getAdUnitSizes, logWarn } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import includes from 'core-js/library/fn/array/includes.js'; +import {config} from '../src/config.js'; const BID_HOST = 'https://prebid.technoratimedia.com'; const USER_SYNC_HOST = 'https://ad-cdn.technoratimedia.com'; @@ -156,7 +157,9 @@ export const spec = { }; if (isVideo) { const [, uuid] = nurl.match(/ID=([^&]*)&?/); - bidObj.videoCacheKey = encodeURIComponent(uuid); + if (!config.getConfig('cache.url')) { + bidObj.videoCacheKey = encodeURIComponent(uuid); + } bidObj.vastUrl = nurl; } bids.push(bidObj); diff --git a/test/spec/modules/synacormediaBidAdapter_spec.js b/test/spec/modules/synacormediaBidAdapter_spec.js index b67da86ebf2..f6fa7a20594 100644 --- a/test/spec/modules/synacormediaBidAdapter_spec.js +++ b/test/spec/modules/synacormediaBidAdapter_spec.js @@ -1,5 +1,6 @@ import { assert, expect } from 'chai'; import { BANNER } from 'src/mediaTypes.js'; +import {config} from 'src/config.js'; import { spec } from 'modules/synacormediaBidAdapter.js'; describe('synacormediaBidAdapter ', function () { @@ -779,6 +780,44 @@ describe('synacormediaBidAdapter ', function () { expect(spec.interpretResponse({ body: null })).to.not.exist; expect(spec.interpretResponse({ body: 'some error text' })).to.not.exist; }); + + it('should not include videoCacheKey property on the returned response when cache url is present in the config', function () { + let sandbox = sinon.sandbox.create(); + let serverRespVideo = { + body: { + id: 'abcd1234', + seatbid: [ + { + bid: [ + { + id: '11339128001692337~9999~0', + impid: 'v2da7322b2df61f-640x480', + price: 0.45, + nurl: 'https://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=${AUCTION_PRICE}', + adm: '\n\n\n\nSynacor Media Ad Server - 9999\nhttps://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=${AUCTION_PRICE}\n\n\n', + adomain: [ 'psacentral.org' ], + cid: 'bidder-crid', + crid: 'bidder-cid', + cat: [] + } + ], + seat: '9999' + } + ] + } + }; + + sandbox.stub(config, 'getConfig').callsFake(key => { + const config = { + 'cache.url': 'faKeCacheUrl' + }; + return config[key]; + }); + + let resp = spec.interpretResponse(serverRespVideo); + sandbox.restore(); + expect(resp[0].videoCacheKey).to.not.exist; + }); }); describe('getUserSyncs', function () { it('should return a usersync when iframes is enabled', function () { From 3513d38c120072380c0f4a2376b95f50bb957224 Mon Sep 17 00:00:00 2001 From: vladi-mmg Date: Thu, 7 May 2020 10:27:39 +0300 Subject: [PATCH 300/496] Marsmedia - Add onBidWon function (#5175) * Change publisherId to zoneId Add gdpr Add supply chain Add video media type * Remove comments * Fix unit test coverage * fix request id bug add vastXml to video response * Remove bid response default sizes * Change endpoint url * Add unit test for vastXml * Change end point * Remove trailing-space * Add onBidWon function --- modules/marsmediaBidAdapter.js | 19 ++++++++++++-- test/spec/modules/marsmediaBidAdapter_spec.js | 26 ++++++++++++++++--- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/modules/marsmediaBidAdapter.js b/modules/marsmediaBidAdapter.js index b6dc7800dd9..2a2017c4b5c 100644 --- a/modules/marsmediaBidAdapter.js +++ b/modules/marsmediaBidAdapter.js @@ -16,7 +16,7 @@ function MarsmediaAdapter() { let SUPPORTED_VIDEO_API = [1, 2, 5]; let slotsToBids = {}; let that = this; - let version = '2.2'; + let version = '2.3'; this.isBidRequestValid = function (bid) { return !!(bid.params && bid.params.zoneId); @@ -221,6 +221,20 @@ function MarsmediaAdapter() { }; }; + this.onBidWon = function (bid) { + const cpm = bid.pbMg; + if (typeof bid.nurl !== 'undefined') { + bid.nurl = bid.nurl.replace( + /\$\{AUCTION_PRICE\}/, + cpm + ); + utils.triggerPixel(bid.nurl, null); + }; + const bidString = JSON.stringify(bid); + const encodedBuf = window.btoa(bidString); + utils.triggerPixel('https://ping-hqx-1.go2speed.media/notification/rtb/beacon/?bt=17&hb_j=' + encodedBuf, null); + }; + this.interpretResponse = function (serverResponse) { let responses = serverResponse.body || []; let bids = []; @@ -248,7 +262,8 @@ function MarsmediaAdapter() { creativeId: bid.crid, currency: 'USD', netRevenue: true, - ttl: 350 + ttl: 350, + nurl: bid.nurl }; if (bidRequest.mediaTypes && bidRequest.mediaTypes.video) { diff --git a/test/spec/modules/marsmediaBidAdapter_spec.js b/test/spec/modules/marsmediaBidAdapter_spec.js index c0399e5d0a2..e02870d9890 100644 --- a/test/spec/modules/marsmediaBidAdapter_spec.js +++ b/test/spec/modules/marsmediaBidAdapter_spec.js @@ -61,7 +61,8 @@ describe('marsmedia adapter tests', function () { 'h': 250, 'adm': '
My Compelling Ad
', 'price': 1, - 'crid': 'cr-cfy24' + 'crid': 'cr-cfy24', + 'nurl': '' } ] }; @@ -140,7 +141,8 @@ describe('marsmedia adapter tests', function () { 'cid': '467415', 'crid': 'cr-vid', 'w': 800, - 'h': 600 + 'h': 600, + 'nurl': '' } ] }; @@ -173,7 +175,8 @@ describe('marsmedia adapter tests', function () { 'cid': '467415', 'crid': 'cr-vid', 'w': 800, - 'h': 600 + 'h': 600, + 'nurl': '' } ] }; @@ -604,4 +607,21 @@ describe('marsmedia adapter tests', function () { expect(r1adapter.getUserSyncs()).to.deep.equal([]); }); }); + + describe('on bidWon', function () { + beforeEach(function() { + sinon.stub(utils, 'triggerPixel'); + }); + afterEach(function() { + utils.triggerPixel.restore(); + }); + it('exists and is a function', () => { + expect(spec.onBidWon).to.exist.and.to.be.a('function'); + }); + it('should return nothing', function () { + var response = spec.onBidWon({}); + expect(response).to.be.an('undefined') + expect(utils.triggerPixel.called).to.equal(true); + }); + }); }); From 7167bbe288dff65ce889c0e386acdad97547b70c Mon Sep 17 00:00:00 2001 From: barslev Date: Thu, 7 May 2020 17:02:53 +0200 Subject: [PATCH 301/496] Updates core-js to version 3. (#4984) * Updates core-js to version 3. * More changes related to updating core-js to version 3 * Updated new files from master to also be compatible with core-js v3. * Updated package-lock.json * Revert "Updated new files from master to also be compatible with core-js v3." This reverts commit b2ae8d93aae9eee71f2f99a276462225b96d1582. # Conflicts: # modules/priceFloors.js * Revert "Updates core-js to version 3." This reverts commit a731dce2c5100dc78945929aa59d1fa3566ece25. # Conflicts: # modules/adkernelBidAdapter.js # modules/audienceNetworkBidAdapter.js # modules/emx_digitalBidAdapter.js # modules/widespaceBidAdapter.js # package.json # src/config.js # src/userSync.js # src/utils.js # test/spec/modules/widespaceBidAdapter_spec.js * Updated new files to core-js v3 and imports now end in .js * Import set without .js since set is a module and not a file. * Updated new file from master to also be compatible with core-js v3. --- allowedModules.js | 12 ++++----- modules/1ad4goodBidAdapter.js | 4 +-- modules/adagioBidAdapter.js | 2 +- modules/adkernelBidAdapter.js | 4 +-- modules/adomikAnalyticsAdapter.js | 4 +-- modules/adotBidAdapter.js | 2 +- modules/adpod.js | 6 ++--- modules/adtelligentBidAdapter.js | 2 +- modules/advangelistsBidAdapter.js | 4 +-- modules/adxcgBidAdapter.js | 2 +- modules/adyoulikeBidAdapter.js | 2 +- modules/appnexusBidAdapter.js | 4 +-- modules/audienceNetworkBidAdapter.js | 4 +-- modules/beachfrontBidAdapter.js | 4 +-- modules/bridgewellBidAdapter.js | 2 +- modules/consentManagement.js | 4 +-- modules/criteoBidAdapter.js | 2 +- modules/emx_digitalBidAdapter.js | 4 +-- modules/gdprEnforcement.js | 4 +-- modules/gumgumBidAdapter.js | 2 +- modules/hybridBidAdapter.js | 2 +- modules/ixBidAdapter.js | 4 +-- modules/livewrappedBidAdapter.js | 2 +- modules/lunamediaBidAdapter.js | 4 +-- modules/nextrollBidAdapter.js | 2 +- modules/platformioBidAdapter.js | 2 +- modules/prebidServerBidAdapter/index.js | 4 +-- modules/priceFloors.js | 2 +- modules/quantcastBidAdapter.js | 2 +- modules/roxotAnalyticsAdapter.js | 2 +- modules/rtbhouseBidAdapter.js | 2 +- modules/sigmoidAnalyticsAdapter.js | 2 +- modules/sizeMappingV2.js | 2 +- modules/somoBidAdapter.js | 2 +- modules/sovrnAnalyticsAdapter.js | 4 +-- modules/synacormediaBidAdapter.js | 2 +- modules/userId/index.js | 2 +- modules/viewdeosDXBidAdapter.js | 2 +- modules/widespaceBidAdapter.js | 4 +-- modules/windtalkerBidAdapter.js | 2 +- modules/xhbBidAdapter.js | 4 +-- modules/yieldlabBidAdapter.js | 2 +- package-lock.json | 26 ++++++++++++++++--- package.json | 5 ++-- src/Renderer.js | 2 +- src/adapterManager.js | 4 +-- src/adapters/bidderFactory.js | 2 +- src/adloader.js | 2 +- src/auction.js | 2 +- src/auctionManager.js | 2 +- src/config.js | 8 +++--- src/cpmBucketManager.js | 2 +- src/native.js | 2 +- src/prebid.js | 2 +- src/secureCreatives.js | 4 +-- src/sizeMapping.js | 2 +- src/storageManager.js | 2 +- src/targeting.js | 2 +- src/userSync.js | 2 +- src/utils.js | 4 +-- src/video.js | 2 +- test/spec/auctionmanager_spec.js | 11 +++++--- .../longform/basic_w_bidderSettings.spec.js | 2 +- ...asic_w_custom_adserver_translation.spec.js | 2 +- .../e2e/longform/basic_w_priceGran.spec.js | 2 +- .../basic_w_requireExactDuration.spec.js | 2 +- .../basic_wo_brandCategoryExclusion.spec.js | 2 +- .../basic_wo_requireExactDuration.spec.js | 2 +- .../modules/eplanningAnalyticsAdapter_spec.js | 2 +- .../modules/fintezaAnalyticsAdapter_spec.js | 2 +- test/spec/modules/rubiconBidAdapter_spec.js | 6 +---- test/spec/modules/widespaceBidAdapter_spec.js | 2 +- test/spec/sizeMapping_spec.js | 2 +- test/spec/unit/core/adapterManager_spec.js | 4 +-- test/spec/unit/pbjs_api_spec.js | 10 ++----- 75 files changed, 137 insertions(+), 121 deletions(-) diff --git a/allowedModules.js b/allowedModules.js index 4f8b8039d97..2a521f781f9 100644 --- a/allowedModules.js +++ b/allowedModules.js @@ -1,11 +1,11 @@ const sharedWhiteList = [ - 'core-js/library/fn/array/find', // no ie11 - 'core-js/library/fn/array/includes', // no ie11 - 'core-js/library/fn/set', // ie11 supports Set but not Set#values - 'core-js/library/fn/string/includes', // no ie11 - 'core-js/library/fn/number/is-integer', // no ie11, - 'core-js/library/fn/array/from' // no ie11 + 'core-js-pure/features/array/find', // no ie11 + 'core-js-pure/features/array/includes', // no ie11 + 'core-js-pure/features/set', // ie11 supports Set but not Set#values + 'core-js-pure/features/string/includes', // no ie11 + 'core-js-pure/features/number/is-integer', // no ie11, + 'core-js-pure/features/array/from' // no ie11 ]; module.exports = { diff --git a/modules/1ad4goodBidAdapter.js b/modules/1ad4goodBidAdapter.js index 560808b368f..178f3765587 100644 --- a/modules/1ad4goodBidAdapter.js +++ b/modules/1ad4goodBidAdapter.js @@ -1,8 +1,8 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import find from 'core-js/library/fn/array/find.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; const BIDDER_CODE = '1ad4good'; const URL = 'https://hb.1ad4good.org/prebid'; diff --git a/modules/adagioBidAdapter.js b/modules/adagioBidAdapter.js index a21915e00a9..f144089b2a2 100644 --- a/modules/adagioBidAdapter.js +++ b/modules/adagioBidAdapter.js @@ -1,4 +1,4 @@ -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; import * as utils from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import { loadExternalScript } from '../src/adloader.js' diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index 1a16801ba67..cbd30edb432 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -1,8 +1,8 @@ import * as utils from '../src/utils.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; -import find from 'core-js/library/fn/array/find.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; /* * In case you're AdKernel whitelable platform's client who needs branded adapter to diff --git a/modules/adomikAnalyticsAdapter.js b/modules/adomikAnalyticsAdapter.js index ec5923ea0f8..5bbee86df54 100644 --- a/modules/adomikAnalyticsAdapter.js +++ b/modules/adomikAnalyticsAdapter.js @@ -2,8 +2,8 @@ import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; import adapterManager from '../src/adapterManager.js'; import { logInfo } from '../src/utils.js'; -import find from 'core-js/library/fn/array/find.js'; -import findIndex from 'core-js/library/fn/array/find-index.js'; +import find from 'core-js-pure/features/array/find.js'; +import findIndex from 'core-js-pure/features/array/find-index.js'; // Events used in adomik analytics adapter const auctionInit = CONSTANTS.EVENTS.AUCTION_INIT; diff --git a/modules/adotBidAdapter.js b/modules/adotBidAdapter.js index 94672b20c0c..911da416cfe 100644 --- a/modules/adotBidAdapter.js +++ b/modules/adotBidAdapter.js @@ -2,7 +2,7 @@ import {Renderer} from '../src/Renderer.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; import {isStr, isArray, isNumber, isPlainObject, isBoolean, logError} from '../src/utils.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; const ADAPTER_VERSION = 'v1.0.0'; const BID_METHOD = 'POST'; diff --git a/modules/adpod.js b/modules/adpod.js index a2d5cb4a0ed..1e264365082 100644 --- a/modules/adpod.js +++ b/modules/adpod.js @@ -20,12 +20,12 @@ import { setupBeforeHookFnOnce, module } from '../src/hook.js'; import { store } from '../src/videoCache.js'; import { config } from '../src/config.js'; import { ADPOD } from '../src/mediaTypes.js'; -import Set from 'core-js/library/fn/set.js'; -import find from 'core-js/library/fn/array/find.js'; +import Set from 'core-js-pure/features/set'; +import find from 'core-js-pure/features/array/find.js'; import { auctionManager } from '../src/auctionManager.js'; import CONSTANTS from '../src/constants.json'; -const from = require('core-js/library/fn/array/from.js'); +const from = require('core-js-pure/features/array/from.js'); const TARGETING_KEY_PB_CAT_DUR = 'hb_pb_cat_dur'; const TARGETING_KEY_CACHE_ID = 'hb_cache_id'; diff --git a/modules/adtelligentBidAdapter.js b/modules/adtelligentBidAdapter.js index 82601117017..74bb6dba8d3 100644 --- a/modules/adtelligentBidAdapter.js +++ b/modules/adtelligentBidAdapter.js @@ -2,7 +2,7 @@ import * as utils from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {VIDEO, BANNER} from '../src/mediaTypes.js'; import {Renderer} from '../src/Renderer.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; const URL = 'https://ghb.adtelligent.com/auction/'; const OUTSTREAM_SRC = 'https://player.adtelligent.com/outstream-unit/2.01/outstream.min.js'; diff --git a/modules/advangelistsBidAdapter.js b/modules/advangelistsBidAdapter.js index 64e4c58653b..746baa9ae35 100755 --- a/modules/advangelistsBidAdapter.js +++ b/modules/advangelistsBidAdapter.js @@ -2,8 +2,8 @@ import * as utils from '../src/utils.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { VIDEO, BANNER } from '../src/mediaTypes.js'; -import find from 'core-js/library/fn/array/find.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; const ADAPTER_VERSION = '1.0'; const BIDDER_CODE = 'advangelists'; diff --git a/modules/adxcgBidAdapter.js b/modules/adxcgBidAdapter.js index cc76731836b..2d5c64dfe53 100644 --- a/modules/adxcgBidAdapter.js +++ b/modules/adxcgBidAdapter.js @@ -2,7 +2,7 @@ import { config } from '../src/config.js' import * as utils from '../src/utils.js' import { registerBidder } from '../src/adapters/bidderFactory.js' import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js' -import includes from 'core-js/library/fn/array/includes.js' +import includes from 'core-js-pure/features/array/includes.js' /** * Adapter for requesting bids from adxcg.net diff --git a/modules/adyoulikeBidAdapter.js b/modules/adyoulikeBidAdapter.js index 9391a3fb94f..412acdde3dd 100644 --- a/modules/adyoulikeBidAdapter.js +++ b/modules/adyoulikeBidAdapter.js @@ -1,6 +1,6 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; const VERSION = '1.0'; const BIDDER_CODE = 'adyoulike'; diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 53cfc85389d..2bec1d1f047 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -4,8 +4,8 @@ import { config } from '../src/config.js'; import { registerBidder, getIabSubCategory } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO, ADPOD } from '../src/mediaTypes.js'; import { auctionManager } from '../src/auctionManager.js'; -import find from 'core-js/library/fn/array/find.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; import { OUTSTREAM, INSTREAM } from '../src/video.js'; import { getStorageManager } from '../src/storageManager.js'; diff --git a/modules/audienceNetworkBidAdapter.js b/modules/audienceNetworkBidAdapter.js index 2d7b7eae0dc..816a6abd0e8 100644 --- a/modules/audienceNetworkBidAdapter.js +++ b/modules/audienceNetworkBidAdapter.js @@ -3,8 +3,8 @@ */ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { generateUUID, deepAccess, convertTypes, formatQS } from '../src/utils.js'; -import findIndex from 'core-js/library/fn/array/find-index.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import findIndex from 'core-js-pure/features/array/find-index.js'; +import includes from 'core-js-pure/features/array/includes.js'; const code = 'audienceNetwork'; const currency = 'USD'; diff --git a/modules/beachfrontBidAdapter.js b/modules/beachfrontBidAdapter.js index 9b6c431fdd7..b5ac0321cae 100644 --- a/modules/beachfrontBidAdapter.js +++ b/modules/beachfrontBidAdapter.js @@ -3,8 +3,8 @@ import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { Renderer } from '../src/Renderer.js'; import { VIDEO, BANNER } from '../src/mediaTypes.js'; -import find from 'core-js/library/fn/array/find.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; const ADAPTER_VERSION = '1.9'; const ADAPTER_NAME = 'BFIO_PREBID'; diff --git a/modules/bridgewellBidAdapter.js b/modules/bridgewellBidAdapter.js index a95a19f0402..0303e4f74bd 100644 --- a/modules/bridgewellBidAdapter.js +++ b/modules/bridgewellBidAdapter.js @@ -1,7 +1,7 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE } from '../src/mediaTypes.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; const BIDDER_CODE = 'bridgewell'; const REQUEST_ENDPOINT = 'https://prebid.scupio.com/recweb/prebid.aspx?cb=' + Math.random(); diff --git a/modules/consentManagement.js b/modules/consentManagement.js index 4a1fa9ba8d0..c665eb1a29b 100644 --- a/modules/consentManagement.js +++ b/modules/consentManagement.js @@ -7,8 +7,8 @@ import * as utils from '../src/utils.js'; import { config } from '../src/config.js'; import { gdprDataHandler } from '../src/adapterManager.js'; -import includes from 'core-js/library/fn/array/includes.js'; -import strIncludes from 'core-js/library/fn/string/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; +import strIncludes from 'core-js-pure/features/string/includes.js'; const DEFAULT_CMP = 'iab'; const DEFAULT_CONSENT_TIMEOUT = 10000; diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js index 5d137c994fe..ae48b9664fb 100644 --- a/modules/criteoBidAdapter.js +++ b/modules/criteoBidAdapter.js @@ -3,7 +3,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import * as utils from '../src/utils.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; import { verify } from 'criteo-direct-rsa-validate/build/verify.js'; import { getStorageManager } from '../src/storageManager.js'; diff --git a/modules/emx_digitalBidAdapter.js b/modules/emx_digitalBidAdapter.js index 480e98b31d3..6688d15d8e9 100644 --- a/modules/emx_digitalBidAdapter.js +++ b/modules/emx_digitalBidAdapter.js @@ -2,8 +2,8 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { Renderer } from '../src/Renderer.js'; -import includes from 'core-js/library/fn/array/includes.js'; -import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; const BIDDER_CODE = 'emx_digital'; const ENDPOINT = 'hb.emxdgt.com'; diff --git a/modules/gdprEnforcement.js b/modules/gdprEnforcement.js index 363d0e396f8..e42e55be557 100644 --- a/modules/gdprEnforcement.js +++ b/modules/gdprEnforcement.js @@ -6,8 +6,8 @@ import * as utils from '../src/utils.js'; import { config } from '../src/config.js'; import { hasDeviceAccess } from '../src/utils.js'; import adapterManager, { gdprDataHandler } from '../src/adapterManager.js'; -import find from 'core-js/library/fn/array/find.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; import { registerSyncInner } from '../src/adapters/bidderFactory.js'; import { getHook } from '../src/hook.js'; import { validateStorageEnforcement } from '../src/storageManager.js'; diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index d071127f6b7..cb2401fd90a 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -2,7 +2,7 @@ import * as utils from '../src/utils.js' import { config } from '../src/config.js' import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import { registerBidder } from '../src/adapters/bidderFactory.js' import { getStorageManager } from '../src/storageManager.js'; diff --git a/modules/hybridBidAdapter.js b/modules/hybridBidAdapter.js index 34a4cd9e5d6..5671756e0b2 100644 --- a/modules/hybridBidAdapter.js +++ b/modules/hybridBidAdapter.js @@ -3,7 +3,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js' import { auctionManager } from '../src/auctionManager.js' import { BANNER, VIDEO } from '../src/mediaTypes.js' import {Renderer} from '../src/Renderer.js'; -import find from 'core-js/library/fn/array/find'; +import find from 'core-js-pure/features/array/find.js'; const BIDDER_CODE = 'hybrid'; const DSP_ENDPOINT = 'https://hbe198.hybrid.ai/prebidhb'; diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 2725bafdff8..0ab761b0b7b 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -1,8 +1,8 @@ import * as utils from '../src/utils.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; -import find from 'core-js/library/fn/array/find.js'; -import isInteger from 'core-js/library/fn/number/is-integer.js'; +import find from 'core-js-pure/features/array/find.js'; +import isInteger from 'core-js-pure/features/number/is-integer.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'ix'; diff --git a/modules/livewrappedBidAdapter.js b/modules/livewrappedBidAdapter.js index 6033a1234e7..cda66f5eafd 100644 --- a/modules/livewrappedBidAdapter.js +++ b/modules/livewrappedBidAdapter.js @@ -1,7 +1,7 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; import { BANNER, NATIVE } from '../src/mediaTypes.js'; import { getStorageManager } from '../src/storageManager.js'; diff --git a/modules/lunamediaBidAdapter.js b/modules/lunamediaBidAdapter.js index ee431deea1b..83be806af17 100755 --- a/modules/lunamediaBidAdapter.js +++ b/modules/lunamediaBidAdapter.js @@ -2,8 +2,8 @@ import * as utils from '../src/utils.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { VIDEO, BANNER } from '../src/mediaTypes.js'; -import find from 'core-js/library/fn/array/find.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; const ADAPTER_VERSION = '1.0'; const BIDDER_CODE = 'lunamedia'; diff --git a/modules/nextrollBidAdapter.js b/modules/nextrollBidAdapter.js index 81c48102bb4..0f273792154 100644 --- a/modules/nextrollBidAdapter.js +++ b/modules/nextrollBidAdapter.js @@ -2,7 +2,7 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; const BIDDER_CODE = 'nextroll'; const BIDDER_ENDPOINT = 'https://d.adroll.com/bid/prebid/'; diff --git a/modules/platformioBidAdapter.js b/modules/platformioBidAdapter.js index ad25e262d56..314f738ef81 100644 --- a/modules/platformioBidAdapter.js +++ b/modules/platformioBidAdapter.js @@ -1,6 +1,6 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; const NATIVE_DEFAULTS = { TITLE_LEN: 100, diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js index 56dfe00c6a1..9476b7a76a3 100644 --- a/modules/prebidServerBidAdapter/index.js +++ b/modules/prebidServerBidAdapter/index.js @@ -8,10 +8,10 @@ import { VIDEO, NATIVE } from '../../src/mediaTypes.js'; import { processNativeAdUnitParams } from '../../src/native.js'; import { isValid } from '../../src/adapters/bidderFactory.js'; import events from '../../src/events.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import { S2S_VENDORS } from './config.js'; import { ajax } from '../../src/ajax.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; const getConfig = config.getConfig; diff --git a/modules/priceFloors.js b/modules/priceFloors.js index 0accd48d003..9e9ed1e0d23 100644 --- a/modules/priceFloors.js +++ b/modules/priceFloors.js @@ -6,7 +6,7 @@ import events from '../src/events.js'; import CONSTANTS from '../src/constants.json'; import { getHook } from '../src/hook.js'; import { createBid } from '../src/bidfactory.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; import { getRefererInfo } from '../src/refererDetection.js'; /** diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js index 63d0a6f54e5..91022d70df9 100644 --- a/modules/quantcastBidAdapter.js +++ b/modules/quantcastBidAdapter.js @@ -2,7 +2,7 @@ import * as utils from '../src/utils.js'; import { ajax } from '../src/ajax.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; const BIDDER_CODE = 'quantcast'; const DEFAULT_BID_FLOOR = 0.0000000001; diff --git a/modules/roxotAnalyticsAdapter.js b/modules/roxotAnalyticsAdapter.js index 0e9cda9b6bc..b6857d69f45 100644 --- a/modules/roxotAnalyticsAdapter.js +++ b/modules/roxotAnalyticsAdapter.js @@ -1,7 +1,7 @@ import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; import adapterManager from '../src/adapterManager.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import {ajaxBuilder} from '../src/ajax.js'; import { getStorageManager } from '../src/storageManager.js'; diff --git a/modules/rtbhouseBidAdapter.js b/modules/rtbhouseBidAdapter.js index b0d7c0e04de..ca760ca49eb 100644 --- a/modules/rtbhouseBidAdapter.js +++ b/modules/rtbhouseBidAdapter.js @@ -1,7 +1,7 @@ import * as utils from '../src/utils.js'; import { BANNER, NATIVE } from '../src/mediaTypes.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; const BIDDER_CODE = 'rtbhouse'; const REGIONS = ['prebid-eu', 'prebid-us', 'prebid-asia']; diff --git a/modules/sigmoidAnalyticsAdapter.js b/modules/sigmoidAnalyticsAdapter.js index 88bb5eb23a9..303fbbc8995 100644 --- a/modules/sigmoidAnalyticsAdapter.js +++ b/modules/sigmoidAnalyticsAdapter.js @@ -1,6 +1,6 @@ /* Sigmoid Analytics Adapter for prebid.js v1.1.0-pre Updated : 2018-03-28 */ -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import adapter from '../src/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; import adapterManager from '../src/adapterManager.js'; diff --git a/modules/sizeMappingV2.js b/modules/sizeMappingV2.js index 98effb301fb..339a598bae5 100644 --- a/modules/sizeMappingV2.js +++ b/modules/sizeMappingV2.js @@ -6,7 +6,7 @@ import * as utils from '../src/utils.js'; import { processNativeAdUnitParams } from '../src/native.js'; import { adunitCounter } from '../src/adUnits.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import { getHook } from '../src/hook.js'; import { adUnitSetupChecks diff --git a/modules/somoBidAdapter.js b/modules/somoBidAdapter.js index 298b1c3050e..c6e31790005 100644 --- a/modules/somoBidAdapter.js +++ b/modules/somoBidAdapter.js @@ -1,6 +1,6 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; const VIDEO_TARGETING = ['mimes', 'minduration', 'maxduration', 'protocols', diff --git a/modules/sovrnAnalyticsAdapter.js b/modules/sovrnAnalyticsAdapter.js index 8a712680dac..0d2576edb05 100644 --- a/modules/sovrnAnalyticsAdapter.js +++ b/modules/sovrnAnalyticsAdapter.js @@ -4,8 +4,8 @@ import CONSTANTS from '../src/constants.json' import {ajaxBuilder} from '../src/ajax.js' import * as utils from '../src/utils.js' import {config} from '../src/config.js' -import find from 'core-js/library/fn/array/find.js' -import includes from 'core-js/library/fn/array/includes.js' +import find from 'core-js-pure/features/array/find.js' +import includes from 'core-js-pure/features/array/includes.js' const ajax = ajaxBuilder(0) diff --git a/modules/synacormediaBidAdapter.js b/modules/synacormediaBidAdapter.js index c9ee8f54522..2ca2aeeae82 100644 --- a/modules/synacormediaBidAdapter.js +++ b/modules/synacormediaBidAdapter.js @@ -3,7 +3,7 @@ import { getAdUnitSizes, logWarn } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import {config} from '../src/config.js'; const BID_HOST = 'https://prebid.technoratimedia.com'; diff --git a/modules/userId/index.js b/modules/userId/index.js index 5de8ad75978..f18888c398e 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -108,7 +108,7 @@ * @property {(function|undefined)} callback - function that will return an id */ -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; import {config} from '../../src/config.js'; import events from '../../src/events.js'; import * as utils from '../../src/utils.js'; diff --git a/modules/viewdeosDXBidAdapter.js b/modules/viewdeosDXBidAdapter.js index fb028fca8c8..52894ef2dd9 100644 --- a/modules/viewdeosDXBidAdapter.js +++ b/modules/viewdeosDXBidAdapter.js @@ -2,7 +2,7 @@ import * as utils from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {VIDEO, BANNER} from '../src/mediaTypes.js'; import {Renderer} from '../src/Renderer.js'; -import findIndex from 'core-js/library/fn/array/find-index.js'; +import findIndex from 'core-js-pure/features/array/find-index.js'; const URL = 'https://ghb.sync.viewdeos.com/auction/'; const OUTSTREAM_SRC = 'https://player.sync.viewdeos.com/outstream-unit/2.01/outstream.min.js'; diff --git a/modules/widespaceBidAdapter.js b/modules/widespaceBidAdapter.js index 5165b00a98c..3cea5ca57a1 100644 --- a/modules/widespaceBidAdapter.js +++ b/modules/widespaceBidAdapter.js @@ -4,8 +4,8 @@ import { parseQueryStringParameters, parseSizesInput } from '../src/utils.js'; -import includes from 'core-js/library/fn/array/includes.js'; -import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; import { getStorageManager } from '../src/storageManager.js'; export const storage = getStorageManager(); diff --git a/modules/windtalkerBidAdapter.js b/modules/windtalkerBidAdapter.js index 0c0ef571954..512cc7f839b 100644 --- a/modules/windtalkerBidAdapter.js +++ b/modules/windtalkerBidAdapter.js @@ -1,6 +1,6 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; const NATIVE_DEFAULTS = { TITLE_LEN: 100, diff --git a/modules/xhbBidAdapter.js b/modules/xhbBidAdapter.js index 0f7669f6eeb..55e5495f505 100644 --- a/modules/xhbBidAdapter.js +++ b/modules/xhbBidAdapter.js @@ -2,8 +2,8 @@ import { Renderer } from '../src/Renderer.js'; import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import find from 'core-js/library/fn/array/find.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; const BIDDER_CODE = 'xhb'; const URL = 'https://ib.adnxs.com/ut/v3/prebid'; diff --git a/modules/yieldlabBidAdapter.js b/modules/yieldlabBidAdapter.js index e1e491cdce9..6cfa0c1a548 100644 --- a/modules/yieldlabBidAdapter.js +++ b/modules/yieldlabBidAdapter.js @@ -1,6 +1,6 @@ import * as utils from '../src/utils.js' import { registerBidder } from '../src/adapters/bidderFactory.js' -import find from 'core-js/library/fn/array/find.js' +import find from 'core-js-pure/features/array/find.js' import { VIDEO, BANNER } from '../src/mediaTypes.js' import { Renderer } from '../src/Renderer.js' diff --git a/package-lock.json b/package-lock.json index e8387d41383..146fb49c435 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3035,6 +3035,14 @@ "lodash": "^4.17.4", "mkdirp": "^0.5.1", "source-map-support": "^0.4.15" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + } } }, "babel-runtime": { @@ -3044,6 +3052,13 @@ "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + } } }, "babel-template": { @@ -4359,9 +4374,9 @@ } }, "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", + "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==" }, "core-js-compat": { "version": "3.6.4", @@ -4381,6 +4396,11 @@ } } }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", diff --git a/package.json b/package.json index 3b581fec1cb..75238ca9872 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ }, "dependencies": { "babel-plugin-transform-object-assign": "^6.22.0", - "core-js": "^2.4.1", + "core-js": "^3.0.0", "criteo-direct-rsa-validate": "^1.1.0", "crypto-js": "^3.3.0", "deep-equal": "^1.0.1", @@ -106,6 +106,7 @@ "fun-hooks": "^0.9.8", "jsencrypt": "^3.0.0-rc.1", "just-clone": "^1.0.2", - "live-connect-js": "1.1.1" + "live-connect-js": "1.1.1", + "core-js-pure": "^3.6.5" } } diff --git a/src/Renderer.js b/src/Renderer.js index 2efe717eca4..b4a912d5714 100644 --- a/src/Renderer.js +++ b/src/Renderer.js @@ -1,6 +1,6 @@ import { loadExternalScript } from './adloader.js'; import * as utils from './utils.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; const moduleCode = 'outstream'; /** diff --git a/src/adapterManager.js b/src/adapterManager.js index f658a36aeda..2108bb7a4f6 100644 --- a/src/adapterManager.js +++ b/src/adapterManager.js @@ -7,8 +7,8 @@ import { newBidder } from './adapters/bidderFactory.js'; import { ajaxBuilder } from './ajax.js'; import { config, RANDOM } from './config.js'; import { hook } from './hook.js'; -import includes from 'core-js/library/fn/array/includes.js'; -import find from 'core-js/library/fn/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; import { adunitCounter } from './adUnits.js'; import { getRefererInfo } from './refererDetection.js'; diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index af3ab5ed8c1..42aa91fa74a 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -7,7 +7,7 @@ import { nativeBidIsValid } from '../native.js'; import { isValidVideoBid } from '../video.js'; import CONSTANTS from '../constants.json'; import events from '../events.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import { ajax } from '../ajax.js'; import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, deepAccess, isArray } from '../utils.js'; import { ADPOD } from '../mediaTypes.js'; diff --git a/src/adloader.js b/src/adloader.js index ce21d763797..1c18ce82b16 100644 --- a/src/adloader.js +++ b/src/adloader.js @@ -1,4 +1,4 @@ -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import * as utils from './utils.js'; const _requestCache = {}; diff --git a/src/auction.js b/src/auction.js index d953763cea8..6166e59bbf0 100644 --- a/src/auction.js +++ b/src/auction.js @@ -65,7 +65,7 @@ import { Renderer } from './Renderer.js'; import { config } from './config.js'; import { userSync } from './userSync.js'; import { hook } from './hook.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; import { OUTSTREAM } from './video.js'; import { VIDEO } from './mediaTypes.js'; diff --git a/src/auctionManager.js b/src/auctionManager.js index bf95f0ab05e..3d4bd0afe99 100644 --- a/src/auctionManager.js +++ b/src/auctionManager.js @@ -18,7 +18,7 @@ import { uniques, flatten, logWarn } from './utils.js'; import { newAuction, getStandardBidderSettings, AUCTION_COMPLETED } from './auction.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; const CONSTANTS = require('./constants.json'); diff --git a/src/config.js b/src/config.js index af0fd12de88..3284be52296 100644 --- a/src/config.js +++ b/src/config.js @@ -13,12 +13,12 @@ */ import { isValidPriceConfig } from './cpmBucketManager.js'; -import find from 'core-js/library/fn/array/find.js'; -import includes from 'core-js/library/fn/array/includes.js'; -import Set from 'core-js/library/fn/set.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; +import Set from 'core-js-pure/features/set'; import { mergeDeep } from './utils.js'; -const from = require('core-js/library/fn/array/from.js'); +const from = require('core-js-pure/features/array/from.js'); const utils = require('./utils.js'); const CONSTANTS = require('./constants.json'); diff --git a/src/cpmBucketManager.js b/src/cpmBucketManager.js index 2f0ae4312e9..a6b76cc38e2 100644 --- a/src/cpmBucketManager.js +++ b/src/cpmBucketManager.js @@ -1,4 +1,4 @@ -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; const utils = require('./utils.js'); const _defaultPrecision = 2; diff --git a/src/native.js b/src/native.js index 0d8461a5b6f..e41d7740ffa 100644 --- a/src/native.js +++ b/src/native.js @@ -1,5 +1,5 @@ import { deepAccess, getBidRequest, getKeyByValue, insertHtmlIntoIframe, logError, triggerPixel } from './utils.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; const CONSTANTS = require('./constants.json'); diff --git a/src/prebid.js b/src/prebid.js index f45a15d5f19..1710849ba92 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -9,7 +9,7 @@ import { auctionManager } from './auctionManager.js'; import { targeting } from './targeting.js'; import { hook } from './hook.js'; import { sessionLoader } from './debugging.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import { adunitCounter } from './adUnits.js'; import { isRendererRequired, executeRenderer } from './Renderer.js'; import { createBid } from './bidfactory.js'; diff --git a/src/secureCreatives.js b/src/secureCreatives.js index 36e5efe22cd..060a30b0a98 100644 --- a/src/secureCreatives.js +++ b/src/secureCreatives.js @@ -8,9 +8,9 @@ import { fireNativeTrackers, getAssetMessage } from './native.js'; import { EVENTS } from './constants.json'; import { logWarn, replaceAuctionPrice } from './utils.js'; import { auctionManager } from './auctionManager.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; import { isRendererRequired, executeRenderer } from './Renderer.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; const BID_WON = EVENTS.BID_WON; diff --git a/src/sizeMapping.js b/src/sizeMapping.js index ff54ff8f251..313da3f422a 100644 --- a/src/sizeMapping.js +++ b/src/sizeMapping.js @@ -1,6 +1,6 @@ import { config } from './config.js'; import {logWarn, isPlainObject, deepAccess, deepClone, getWindowTop} from './utils.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; let sizeConfig = []; diff --git a/src/storageManager.js b/src/storageManager.js index 75ad10908dc..0d88a8ccea1 100644 --- a/src/storageManager.js +++ b/src/storageManager.js @@ -1,6 +1,6 @@ import { hook } from './hook.js'; import * as utils from './utils.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; const moduleTypeWhiteList = ['core', 'prebid-module']; diff --git a/src/targeting.js b/src/targeting.js index f843dd13a6a..45c098554a5 100644 --- a/src/targeting.js +++ b/src/targeting.js @@ -4,7 +4,7 @@ import { NATIVE_TARGETING_KEYS } from './native.js'; import { auctionManager } from './auctionManager.js'; import { sizeSupported } from './sizeMapping.js'; import { ADPOD } from './mediaTypes.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; const utils = require('./utils.js'); var CONSTANTS = require('./constants.json'); diff --git a/src/userSync.js b/src/userSync.js index 5da22254f2c..fceeb1d722d 100644 --- a/src/userSync.js +++ b/src/userSync.js @@ -1,6 +1,6 @@ import * as utils from './utils.js'; import { config } from './config.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import { getCoreStorageManager } from './storageManager.js'; export const USERSYNC_DEFAULT_CONFIG = { diff --git a/src/utils.js b/src/utils.js index e7b937a970d..38ab6d88e12 100644 --- a/src/utils.js +++ b/src/utils.js @@ -2,8 +2,8 @@ import { config } from './config.js'; import clone from 'just-clone'; import deepequal from 'deep-equal'; -import find from 'core-js/library/fn/array/find.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; const CONSTANTS = require('./constants.json'); diff --git a/src/video.js b/src/video.js index c3deb73ad4d..befeb2ded39 100644 --- a/src/video.js +++ b/src/video.js @@ -1,7 +1,7 @@ import adapterManager from './adapterManager.js'; import { getBidRequest, deepAccess, logError } from './utils.js'; import { config } from '../src/config.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import { hook } from './hook.js'; const VIDEO_MEDIA_TYPE = 'video'; diff --git a/test/spec/auctionmanager_spec.js b/test/spec/auctionmanager_spec.js index 3ec3d67e448..35a29727614 100644 --- a/test/spec/auctionmanager_spec.js +++ b/test/spec/auctionmanager_spec.js @@ -1,13 +1,18 @@ -import { getKeyValueTargetingPairs, auctionCallbacks, AUCTION_COMPLETED } from 'src/auction.js'; +import { + getKeyValueTargetingPairs, + auctionCallbacks, + AUCTION_COMPLETED, + adjustBids, + getMediaTypeGranularity, +} from 'src/auction.js'; import CONSTANTS from 'src/constants.json'; -import { adjustBids, getMediaTypeGranularity } from 'src/auction.js'; import * as auctionModule from 'src/auction.js'; import { registerBidder } from 'src/adapters/bidderFactory.js'; import { createBid } from 'src/bidfactory.js'; import { config } from 'src/config.js'; import * as store from 'src/videoCache.js'; import * as ajaxLib from 'src/ajax.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; import { server } from 'test/mocks/xhr.js'; var assert = require('assert'); diff --git a/test/spec/e2e/longform/basic_w_bidderSettings.spec.js b/test/spec/e2e/longform/basic_w_bidderSettings.spec.js index 06413fb809a..684f5acab17 100644 --- a/test/spec/e2e/longform/basic_w_bidderSettings.spec.js +++ b/test/spec/e2e/longform/basic_w_bidderSettings.spec.js @@ -1,4 +1,4 @@ -const includes = require('core-js/library/fn/array/includes'); +const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; const testServer = require('../../../helpers/testing-utils'); diff --git a/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js b/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js index 82310738246..175e5d041d9 100644 --- a/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js +++ b/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js @@ -1,4 +1,4 @@ -const includes = require('core-js/library/fn/array/includes'); +const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; const testServer = require('../../../helpers/testing-utils'); diff --git a/test/spec/e2e/longform/basic_w_priceGran.spec.js b/test/spec/e2e/longform/basic_w_priceGran.spec.js index 696b7fa3359..294557193b4 100644 --- a/test/spec/e2e/longform/basic_w_priceGran.spec.js +++ b/test/spec/e2e/longform/basic_w_priceGran.spec.js @@ -1,4 +1,4 @@ -const includes = require('core-js/library/fn/array/includes'); +const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; const testServer = require('../../../helpers/testing-utils'); diff --git a/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js b/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js index 224ff1cbc34..d92e5361ae3 100644 --- a/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js +++ b/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js @@ -1,4 +1,4 @@ -const includes = require('core-js/library/fn/array/includes'); +const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; const testServer = require('../../../helpers/testing-utils'); diff --git a/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js b/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js index 95237366d0e..de3e334e755 100644 --- a/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js +++ b/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js @@ -1,4 +1,4 @@ -const includes = require('core-js/library/fn/array/includes'); +const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; const testServer = require('../../../helpers/testing-utils'); diff --git a/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js b/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js index 6b628067138..849eb5ade4d 100644 --- a/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js +++ b/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js @@ -1,4 +1,4 @@ -const includes = require('core-js/library/fn/array/includes'); +const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; const testServer = require('../../../helpers/testing-utils'); diff --git a/test/spec/modules/eplanningAnalyticsAdapter_spec.js b/test/spec/modules/eplanningAnalyticsAdapter_spec.js index 9bb71e7033d..255d116a0ff 100644 --- a/test/spec/modules/eplanningAnalyticsAdapter_spec.js +++ b/test/spec/modules/eplanningAnalyticsAdapter_spec.js @@ -1,5 +1,5 @@ import eplAnalyticsAdapter from 'modules/eplanningAnalyticsAdapter.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import { expect } from 'chai'; import { parseUrl } from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; diff --git a/test/spec/modules/fintezaAnalyticsAdapter_spec.js b/test/spec/modules/fintezaAnalyticsAdapter_spec.js index ae9ceceecc3..29136c85241 100644 --- a/test/spec/modules/fintezaAnalyticsAdapter_spec.js +++ b/test/spec/modules/fintezaAnalyticsAdapter_spec.js @@ -1,5 +1,5 @@ import fntzAnalyticsAdapter from 'modules/fintezaAnalyticsAdapter.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; import { expect } from 'chai'; import { parseUrl } from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 29cc6cb2c0a..bfc8de0f20d 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -2,13 +2,9 @@ import {expect} from 'chai'; import adapterManager from 'src/adapterManager.js'; import {spec, getPriceGranularity, masSizeOrdering, resetUserSync, hasVideoMediaType, FASTLANE_ENDPOINT} from 'modules/rubiconBidAdapter.js'; import {parse as parseQuery} from 'querystring'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {userSync} from 'src/userSync.js'; import {config} from 'src/config.js'; import * as utils from 'src/utils.js'; -import find from 'core-js/library/fn/array/find.js'; - -var CONSTANTS = require('src/constants.json'); +import find from 'core-js-pure/features/array/find.js'; const INTEGRATION = `pbjs_lite_v$prebid.version$`; // $prebid.version$ will be substituted in by gulp in built prebid diff --git a/test/spec/modules/widespaceBidAdapter_spec.js b/test/spec/modules/widespaceBidAdapter_spec.js index 95f0117e5d1..382bf2c593e 100644 --- a/test/spec/modules/widespaceBidAdapter_spec.js +++ b/test/spec/modules/widespaceBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; import {spec, storage} from 'modules/widespaceBidAdapter.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; describe('+widespaceAdatperTest', function () { // Dummy bid request diff --git a/test/spec/sizeMapping_spec.js b/test/spec/sizeMapping_spec.js index b6b8c00ada3..78dd9797c36 100644 --- a/test/spec/sizeMapping_spec.js +++ b/test/spec/sizeMapping_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { resolveStatus, setSizeConfig, sizeSupported } from 'src/sizeMapping.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import includes from 'core-js-pure/features/array/includes.js'; let utils = require('src/utils'); let deepClone = utils.deepClone; diff --git a/test/spec/unit/core/adapterManager_spec.js b/test/spec/unit/core/adapterManager_spec.js index 8ee345166e1..9ccdd6aef59 100644 --- a/test/spec/unit/core/adapterManager_spec.js +++ b/test/spec/unit/core/adapterManager_spec.js @@ -11,8 +11,8 @@ import * as utils from 'src/utils.js'; import { config } from 'src/config.js'; import { registerBidder } from 'src/adapters/bidderFactory.js'; import { setSizeConfig } from 'src/sizeMapping.js'; -import find from 'core-js/library/fn/array/find.js'; -import includes from 'core-js/library/fn/array/includes.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; import s2sTesting from 'modules/s2sTesting.js'; var events = require('../../../../src/events'); diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index 252c074cd61..7b4061850cb 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -13,22 +13,16 @@ import { targeting, newTargeting, filters } from 'src/targeting.js'; import { config as configObj } from 'src/config.js'; import * as ajaxLib from 'src/ajax.js'; import * as auctionModule from 'src/auction.js'; -import { newBidder, registerBidder } from 'src/adapters/bidderFactory.js'; +import { registerBidder } from 'src/adapters/bidderFactory.js'; import { _sendAdToCreative } from 'src/secureCreatives.js'; -import find from 'core-js/library/fn/array/find.js'; +import find from 'core-js-pure/features/array/find.js'; var assert = require('chai').assert; var expect = require('chai').expect; -var urlParse = require('url-parse'); - -var prebid = require('src/prebid'); var utils = require('src/utils'); -var bidfactory = require('src/bidfactory'); -var adloader = require('test/mocks/adloaderStub'); var adapterManager = require('src/adapterManager').default; var events = require('src/events'); -var adserver = require('src/adserver'); var CONSTANTS = require('src/constants.json'); // These bid adapters are required to be loaded for the following tests to work From 9c8aa0400d2e235ad18be3daeb79024ffe1eb1a2 Mon Sep 17 00:00:00 2001 From: Klaas-Jan Boon Date: Thu, 7 May 2020 19:33:35 +0200 Subject: [PATCH 302/496] Blue Billywig bid adapter (#5118) * add Blue Billywig adapter * Blue Billywig Adapter - update according to review feedback * Blue Billywig Adapter - update to try and pass CircleCI * Remove the last for .. of in bluebillywigBidAdapter.js, hopefully... * Update bluebillywigBidAdapter test parameters to match renderer to rendererCode rename Co-authored-by: Klaas-Jan Boon --- modules/bluebillywigBidAdapter.js | 386 ++++++++ modules/bluebillywigBidAdapter.md | 38 + .../modules/bluebillywigBidAdapter_spec.js | 898 ++++++++++++++++++ 3 files changed, 1322 insertions(+) create mode 100644 modules/bluebillywigBidAdapter.js create mode 100644 modules/bluebillywigBidAdapter.md create mode 100644 test/spec/modules/bluebillywigBidAdapter_spec.js diff --git a/modules/bluebillywigBidAdapter.js b/modules/bluebillywigBidAdapter.js new file mode 100644 index 00000000000..9e4f5b62e48 --- /dev/null +++ b/modules/bluebillywigBidAdapter.js @@ -0,0 +1,386 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { Renderer } from '../src/Renderer.js'; +import { createEidsArray } from './userId/eids.js'; + +const DEV_MODE = window.location.search.match(/bbpbs_debug=true/); + +// Blue Billywig Constants +const BB_CONSTANTS = { + BIDDER_CODE: 'bluebillywig', + AUCTION_URL: '$$URL_STARTpbs.bluebillywig.com/openrtb2/auction?pub=$$PUBLICATION', + SYNC_URL: '$$URL_STARTpbs.bluebillywig.com/static/cookie-sync.html?pub=$$PUBLICATION', + RENDERER_URL: 'https://$$PUBLICATION.bbvms.com/r/$$RENDERER.js', + DEFAULT_TIMEOUT: 5000, + DEFAULT_TTL: 300, + DEFAULT_WIDTH: 768, + DEFAULT_HEIGHT: 432, + DEFAULT_NET_REVENUE: true +}; + +// Aliasing +const getConfig = config.getConfig; + +// Helper Functions +export const BB_HELPERS = { + addSiteAppDevice: function(request, pageUrl) { + if (!request) return; + + if (typeof getConfig('app') === 'object') request.app = getConfig('app'); + else if (pageUrl) request.site = { page: pageUrl }; + + if (typeof getConfig('device') === 'object') request.device = getConfig('device'); + if (!request.device) request.device = {}; + if (!request.device.w) request.device.w = window.innerWidth; + if (!request.device.h) request.device.h = window.innerHeight; + }, + addSchain: function(request, validBidRequests) { + if (!request) return; + + const schain = utils.deepAccess(validBidRequests, '0.schain'); + if (schain) request.source.ext = { schain: schain }; + }, + addCurrency: function(request) { + if (!request) return; + + const adServerCur = getConfig('currency.adServerCurrency'); + if (adServerCur && typeof adServerCur === 'string') request.cur = [adServerCur]; + else if (Array.isArray(adServerCur) && adServerCur.length) request.cur = [adServerCur[0]]; + }, + addUserIds: function(request, validBidRequests) { + if (!request) return; + + const bidUserId = utils.deepAccess(validBidRequests, '0.userId'); + const eids = createEidsArray(bidUserId); + + if (eids.length) { + utils.deepSetValue(request, 'user.ext.eids', eids); + } + }, + addDigiTrust: function(request, bidRequests) { + const digiTrust = BB_HELPERS.getDigiTrustParams(bidRequests && bidRequests[0]); + if (digiTrust) utils.deepSetValue(request, 'user.ext.digitrust', digiTrust); + }, + substituteUrl: function (url, publication, renderer) { + return url.replace('$$URL_START', (DEV_MODE) ? 'https://dev.' : 'https://').replace('$$PUBLICATION', publication).replace('$$RENDERER', renderer); + }, + getAuctionUrl: function(publication) { + return BB_HELPERS.substituteUrl(BB_CONSTANTS.AUCTION_URL, publication); + }, + getSyncUrl: function(publication) { + return BB_HELPERS.substituteUrl(BB_CONSTANTS.SYNC_URL, publication); + }, + getRendererUrl: function(publication, renderer) { + return BB_HELPERS.substituteUrl(BB_CONSTANTS.RENDERER_URL, publication, renderer); + }, + getDigiTrustParams: function(bidRequest) { + const digiTrustId = BB_HELPERS.getDigiTrustId(bidRequest); + + if (!digiTrustId || (digiTrustId.privacy && digiTrustId.privacy.optout)) return null; + return { + id: digiTrustId.id, + keyv: digiTrustId.keyv + } + }, + getDigiTrustId: function(bidRequest) { + const bidRequestDigiTrust = utils.deepAccess(bidRequest, 'userId.digitrustid.data'); + if (bidRequestDigiTrust) return bidRequestDigiTrust; + + const digiTrustUser = getConfig('digiTrustId'); + return (digiTrustUser && digiTrustUser.success && digiTrustUser.identity) || null; + }, + transformRTBToPrebidProps: function(bid, serverResponse) { + bid.cpm = bid.price; delete bid.price; + bid.bidId = bid.impid; + bid.requestId = bid.impid; delete bid.impid; + bid.width = bid.w || BB_CONSTANTS.DEFAULT_WIDTH; + bid.height = bid.h || BB_CONSTANTS.DEFAULT_HEIGHT; + if (bid.adm) { + bid.ad = bid.adm; + bid.vastXml = bid.adm; + delete bid.adm; + } + if (bid.nurl && !bid.adm) { // ad markup is on win notice url, and adm is ommited according to OpenRTB 2.5 + bid.vastUrl = bid.nurl; + delete bid.nurl; + } + bid.netRevenue = BB_CONSTANTS.DEFAULT_NET_REVENUE; + bid.creativeId = bid.crid; delete bid.crid; + bid.currency = serverResponse.cur; + bid.ttl = BB_CONSTANTS.DEFAULT_TTL; + }, +}; + +// Renderer Functions +const BB_RENDERER = { + bootstrapPlayer: function(bid) { + const config = { + code: bid.adUnitCode, + }; + + if (bid.vastXml) config.vastXml = bid.vastXml; + else if (bid.vastUrl) config.vastUrl = bid.vastUrl; + + if (!bid.vastXml && !bid.vastUrl) { + utils.logWarn(`${BB_CONSTANTS.BIDDER_CODE}: No vastXml or vastUrl on bid, bailing...`); + return; + } + + const rendererId = BB_RENDERER.getRendererId(bid.publicationName, bid.rendererCode); + + const ele = document.getElementById(bid.adUnitCode); // NB convention + + let renderer; + + for (let rendererIndex = 0; rendererIndex < window.bluebillywig.renderers.length; rendererIndex++) { + if (window.bluebillywig.renderers[rendererIndex]._id === rendererId) { + renderer = window.bluebillywig.renderers[rendererIndex]; + break; + } + } + + if (renderer) renderer.bootstrap(config, ele); + else utils.logWarn(`${BB_CONSTANTS.BIDDER_CODE}: Couldn't find a renderer with ${rendererId}`); + }, + newRenderer: function(rendererUrl, adUnitCode) { + const renderer = Renderer.install({ + url: rendererUrl, + loaded: false, + adUnitCode + }); + + try { + renderer.setRender(BB_RENDERER.outstreamRender); + } catch (err) { + utils.logWarn(`${BB_CONSTANTS.BIDDER_CODE}: Error tying to setRender on renderer`, err); + } + + return renderer; + }, + outstreamRender: function(bid) { + bid.renderer.push(function() { BB_RENDERER.bootstrapPlayer(bid) }); + }, + getRendererId: function(pub, renderer) { + return `${pub}-${renderer}`; // NB convention! + } +}; + +// Spec Functions +// These functions are used to construct the core spec for the adapter +export const spec = { + code: BB_CONSTANTS.BIDDER_CODE, + supportedMediaTypes: [VIDEO], + syncStore: { bidders: [], }, + isBidRequestValid(bid) { + const publicationNameRegex = /^\w+\.?\w+$/; + const rendererRegex = /^[\w+_]+$/; + + if (!bid.params) { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no params set on bid. Rejecting bid: `, bid); + return false; + } + + if (!bid.params.hasOwnProperty('publicationName') || typeof bid.params.publicationName !== 'string') { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no publicationName specified in bid params, or it's not a string. Rejecting bid: `, bid); + return false; + } else if (!publicationNameRegex.test(bid.params.publicationName)) { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: publicationName must be in format 'publication' or 'publication.environment'. Rejecting bid: `, bid); + return false; + } + + if ((!bid.params.hasOwnProperty('rendererCode') || typeof bid.params.rendererCode !== 'string')) { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no rendererCode was specified in bid params. Rejecting bid: `, bid); + return false; + } else if (!rendererRegex.test(bid.params.rendererCode)) { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: rendererCode must be alphanumeric, including underscores. Rejecting bid: `, bid); + return false; + } + + if (!bid.params.accountId) { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no accountId specified in bid params. Rejecting bid: `, bid); + return false; + } + + if (bid.params.hasOwnProperty('connections')) { + if (!Array.isArray(bid.params.connections)) { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: connections is not of type array. Rejecting bid: `, bid); + return false; + } else { + for (let connectionIndex = 0; connectionIndex < bid.params.connections.length; connectionIndex++) { + const connection = bid.params.connections[connectionIndex]; + if (!bid.params.hasOwnProperty(connection)) { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: connection specified in params.connections, but not configured in params. Rejecting bid: `, bid); + return false; + } + } + } + } else { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no connections specified in bid. Rejecting bid: `, bid); + return false; + } + + if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) { + if (!bid.mediaTypes[VIDEO].hasOwnProperty('context')) { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no context specified in bid. Rejecting bid: `, bid); + return false; + } + + if (bid.mediaTypes[VIDEO].context !== 'outstream') { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: video.context is invalid, must be "outstream". Rejecting bid: `, bid); + return false; + } + } else { + utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: mediaTypes or mediaTypes.video is not specified. Rejecting bid: `, bid); + return false; + } + + return true; + }, + buildRequests(validBidRequests, bidderRequest) { + const imps = []; + + for (let validBidRequestIndex = 0; validBidRequestIndex < validBidRequests.length; validBidRequestIndex++) { + const validBidRequest = validBidRequests[validBidRequestIndex]; + const _this = this; + + const ext = validBidRequest.params.connections.reduce(function(extBuilder, connection) { + extBuilder[connection] = validBidRequest.params[connection]; + + if (_this.syncStore.bidders.indexOf(connection) === -1) _this.syncStore.bidders.push(connection); + + return extBuilder; + }, {}); + + imps.push({ id: validBidRequest.bidId, ext, secure: window.location.protocol === 'https' ? 1 : 0, video: utils.deepAccess(validBidRequest, 'mediaTypes.video') }); + } + + const request = { + id: bidderRequest.auctionId, + source: {tid: bidderRequest.auctionId}, + tmax: BB_CONSTANTS.DEFAULT_TIMEOUT, + imp: imps, + test: DEV_MODE ? 1 : 0, + ext: { + prebid: { + targeting: { includewinners: true, includebidderkeys: false } + } + } + }; + + // handle privacy settings for GDPR/CCPA/COPPA + if (bidderRequest.gdprConsent) { + let gdprApplies = 0; + if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') gdprApplies = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; + utils.deepSetValue(request, 'regs.ext.gdpr', gdprApplies); + utils.deepSetValue(request, 'user.ext.consent', bidderRequest.gdprConsent.consentString); + } + + if (bidderRequest.uspConsent) { + utils.deepSetValue(request, 'regs.ext.us_privacy', bidderRequest.uspConsent); + this.syncStore.uspConsent = bidderRequest.uspConsent; + } + + if (getConfig('coppa') == true) utils.deepSetValue(request, 'regs.coppa', 1); + + // Enrich the request with any external data we may have + BB_HELPERS.addSiteAppDevice(request, bidderRequest.refererInfo && bidderRequest.refererInfo.referer); + BB_HELPERS.addSchain(request, validBidRequests); + BB_HELPERS.addCurrency(request); + BB_HELPERS.addUserIds(request, validBidRequests); + BB_HELPERS.addDigiTrust(request, validBidRequests); + + return { + method: 'POST', + url: BB_HELPERS.getAuctionUrl(validBidRequests[0].params.publicationName), + data: JSON.stringify(request), + bidderRequest: bidderRequest + }; + }, + interpretResponse(serverResponse, request) { + serverResponse = serverResponse.body || {}; + + if (!serverResponse.hasOwnProperty('seatbid') || !Array.isArray(serverResponse.seatbid)) { + return []; + } + + const bids = []; + + for (let seatbidIndex = 0; seatbidIndex < serverResponse.seatbid.length; seatbidIndex++) { + const seatbid = serverResponse.seatbid[seatbidIndex]; + if (!seatbid.bid || !Array.isArray(seatbid.bid)) continue; + for (let bidIndex = 0; bidIndex < seatbid.bid.length; bidIndex++) { + const bid = seatbid.bid[bidIndex]; + BB_HELPERS.transformRTBToPrebidProps(bid, serverResponse); + + let bidParams; + for (let bidderRequestBidsIndex = 0; bidderRequestBidsIndex < request.bidderRequest.bids.length; bidderRequestBidsIndex++) { + if (request.bidderRequest.bids[bidderRequestBidsIndex].bidId === bid.bidId) { + bidParams = request.bidderRequest.bids[bidderRequestBidsIndex].params; + } + } + + if (bidParams) { + bid.publicationName = bidParams.publicationName; + bid.rendererCode = bidParams.rendererCode; + bid.accountId = bidParams.accountId; + } + + const rendererUrl = BB_HELPERS.getRendererUrl(bid.publicationName, bid.rendererCode); + + bid.renderer = BB_RENDERER.newRenderer(rendererUrl, bid.adUnitCode); + + bids.push(bid); + } + } + + return bids; + }, + getUserSyncs(syncOptions, serverResponses, gdpr) { + if (!serverResponses || !serverResponses.length) return []; + if (!syncOptions.iframeEnabled) return []; + + const queryString = []; + let accountId; + let publication; + + const serverResponse = serverResponses[0]; + if (!serverResponse.body || !serverResponse.body.seatbid) return []; + + for (let seatbidIndex = 0; seatbidIndex < serverResponse.body.seatbid.length; seatbidIndex++) { + const seatbid = serverResponse.body.seatbid[seatbidIndex]; + for (let bidIndex = 0; bidIndex < seatbid.bid.length; bidIndex++) { + const bid = seatbid.bid[bidIndex]; + accountId = bid.accountId || null; + publication = bid.publicationName || null; + + if (publication && accountId) break; + } + if (publication && accountId) break; + } + + if (!publication || !accountId) return []; + + if (gdpr.gdprApplies) queryString.push(`gdpr=${gdpr.gdprApplies ? 1 : 0}`); + if (gdpr.gdprApplies && gdpr.consentString) queryString.push(`gdpr_consent=${gdpr.consentString}`); + + if (this.syncStore.uspConsent) queryString.push(`usp_consent=${this.syncStore.uspConsent}`); + + queryString.push(`accountId=${accountId}`); + queryString.push(`bidders=${btoa(JSON.stringify(this.syncStore.bidders))}`); + queryString.push(`cb=${Date.now()}-${Math.random().toString().replace('.', '')}`); + + if (DEV_MODE) queryString.push('bbpbs_debug=true'); + + // NB syncUrl by default starts with ?pub=$$PUBLICATION + const syncUrl = `${BB_HELPERS.getSyncUrl(publication)}&${queryString.join('&')}`; + + return [{ + type: 'iframe', + url: syncUrl + }]; + } +}; + +registerBidder(spec); diff --git a/modules/bluebillywigBidAdapter.md b/modules/bluebillywigBidAdapter.md new file mode 100644 index 00000000000..7879697baf5 --- /dev/null +++ b/modules/bluebillywigBidAdapter.md @@ -0,0 +1,38 @@ +# Overview + +``` +Module Name: Blue Billywig Adapter +Module Type: Bidder Adapter +Maintainer: dev+prebid@bluebillywig.com +``` + +# Description + +Prebid Blue Billywig Bidder Adapter + +# Test Parameters + +``` + const adUnits = [{ + code: 'ad-unit', + sizes: [[[768,432],[640,480],[640,360]]], + mediaTypes: { + video: { + playerSize: [768, 432], + context: 'outstream', + mimes: ['video/mp4'], + protocols: [ 2,3,5,6] + } + }, + bids: [{ + bidder: 'bluebillywig', + params: { + publicationName: "bbprebid", + rendererCode: "renderer", + accountId: 642, + connections: [ 'bluebillywig' ], + bluebillywig: {} + } + }] + }]; +``` diff --git a/test/spec/modules/bluebillywigBidAdapter_spec.js b/test/spec/modules/bluebillywigBidAdapter_spec.js new file mode 100644 index 00000000000..fcf3e16ad8b --- /dev/null +++ b/test/spec/modules/bluebillywigBidAdapter_spec.js @@ -0,0 +1,898 @@ +import { expect } from 'chai'; +import { spec } from 'modules/bluebillywigBidAdapter.js'; +import * as bidderFactory from 'src/adapters/bidderFactory.js'; +import { auctionManager } from 'src/auctionManager.js'; +import { deepClone, deepAccess } from 'src/utils.js'; +import { config } from 'src/config.js'; +import { VIDEO } from 'src/mediaTypes.js'; + +const BB_CONSTANTS = { + BIDDER_CODE: 'bluebillywig', + AUCTION_URL: '$$URL_STARTpbs.bluebillywig.com/openrtb2/auction?pub=$$PUBLICATION', + SYNC_URL: '$$URL_STARTpbs.bluebillywig.com/static/cookie-sync.html?pub=$$PUBLICATION', + RENDERER_URL: 'https://$$PUBLICATION.bbvms.com/r/$$RENDERER.js', + DEFAULT_TIMEOUT: 5000, + DEFAULT_TTL: 300, + DEFAULT_WIDTH: 768, + DEFAULT_HEIGHT: 432, + DEFAULT_NET_REVENUE: true +}; + +describe('BlueBillywigAdapter', () => { + describe('isBidRequestValid', () => { + const baseValidBid = { + bidder: BB_CONSTANTS.BIDDER_CODE, + params: { + accountId: 123, + publicationName: 'bbprebid.dev', + rendererCode: 'glorious_renderer', + connections: [ BB_CONSTANTS.BIDDER_CODE ], + bluebillywig: {} + }, + mediaTypes: { + video: { + context: 'outstream' + } + } + }; + + it('should return true when required params found', () => { + expect(spec.isBidRequestValid(baseValidBid)).to.equal(true); + }); + + it('should return false when publicationName is missing', () => { + const bid = deepClone(baseValidBid); + delete bid.params.publicationName; + + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when publicationName is not a string', () => { + const bid = deepClone(baseValidBid); + + bid.params.publicationName = 123; + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.publicationName = false; + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.publicationName = void (0); + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.publicationName = {}; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when publicationName is formatted poorly', () => { + const bid = deepClone(baseValidBid); + + bid.params.publicationName = 'bb.'; + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.publicationName = 'bb-test'; + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.publicationName = '?'; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when renderer is not specified', () => { + const bid = deepClone(baseValidBid); + + delete bid.params.rendererCode; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when renderer is not a string', () => { + const bid = deepClone(baseValidBid); + + bid.params.rendererCode = 123; + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.rendererCode = false; + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.rendererCode = void (0); + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.rendererCode = {}; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when renderer is formatted poorly', () => { + const bid = deepClone(baseValidBid); + + bid.params.rendererCode = 'bb.'; + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.rendererCode = 'bb-test'; + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.rendererCode = '?'; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when accountId is not specified', () => { + const bid = deepClone(baseValidBid); + + delete bid.params.accountId; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when connections is not specified', () => { + const bid = deepClone(baseValidBid); + + delete bid.params.connections; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when connections is not an array', () => { + const bid = deepClone(baseValidBid); + + bid.params.connections = 123; + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.connections = false; + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.connections = void (0); + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.connections = {}; + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.connections = 'string'; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when a connection is missing', () => { + const bid = deepClone(baseValidBid); + + bid.params.connections.push('potatoes'); + expect(spec.isBidRequestValid(bid)).to.equal(false); + + bid.params.connections.pop(); + + delete bid.params[BB_CONSTANTS.BIDDER_CODE]; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should fail if bid has no mediaTypes', () => { + const bid = deepClone(baseValidBid); + + delete bid.mediaTypes; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should fail if bid has no mediaTypes.video', () => { + const bid = deepClone(baseValidBid); + + delete bid.mediaTypes[VIDEO]; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should fail if bid has no mediaTypes.video.context', () => { + const bid = deepClone(baseValidBid); + + delete bid.mediaTypes[VIDEO].context; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should fail if mediaTypes.video.context is not "outstream"', () => { + const bid = deepClone(baseValidBid); + + bid.mediaTypes[VIDEO].context = 'instream'; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', () => { + const publicationName = 'bbprebid.dev'; + const rendererCode = 'glorious_renderer'; + + const baseValidBid = { + bidder: BB_CONSTANTS.BIDDER_CODE, + params: { + accountId: 123, + publicationName: publicationName, + rendererCode: rendererCode, + connections: [ BB_CONSTANTS.BIDDER_CODE ], + bluebillywig: {} + }, + mediaTypes: { + video: { + context: 'outstream' + } + } + }; + + const baseValidBidRequests = [baseValidBid]; + + const validBidderRequest = { + auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', + auctionStart: 1585918458868, + bidderCode: BB_CONSTANTS.BIDDER_CODE, + bidderRequestId: '1a2345b67c8d9e0', + bids: [{ + adUnitCode: 'ad-unit-test', + auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', + bidId: '1234ab567c89de0', + bidRequestsCount: 1, + bidder: BB_CONSTANTS.BIDDER_CODE, + bidderRequestId: '1a2345b67c8d9e0', + params: baseValidBid.params, + sizes: [[768, 432], [640, 480], [630, 360]], + transactionId: '2b34c5de-f67a-8901-bcd2-34567efabc89' + }], + start: 11585918458869, + timeout: 3000 + }; + + it('sends bid request to AUCTION_URL via POST', () => { + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + expect(request.url).to.equal(`https://pbs.bluebillywig.com/openrtb2/auction?pub=${publicationName}`); + expect(request.method).to.equal('POST'); + }); + + it('sends data as a string', () => { + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + expect(request.data).to.be.a('string'); + }); + + it('sends all bid parameters', () => { + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); + }); + + it('builds the base request properly', () => { + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.id).to.equal(validBidderRequest.auctionId); + expect(payload.source).to.be.an('object'); + expect(payload.source.tid).to.equal(validBidderRequest.auctionId); + expect(payload.tmax).to.equal(BB_CONSTANTS.DEFAULT_TIMEOUT); + expect(payload.imp).to.be.an('array'); + expect(payload.test).to.be.a('number'); + expect(payload).to.have.nested.property('ext.prebid.targeting'); + expect(payload.ext.prebid.targeting).to.be.an('object'); + expect(payload.ext.prebid.targeting.includewinners).to.equal(true); + expect(payload.ext.prebid.targeting.includebidderkeys).to.equal(false); + }); + + it('adds an impression to the payload', () => { + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.imp.length).to.equal(1); + }); + + it('adds connections to ext', () => { + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.imp[0].ext).to.have.all.keys(['bluebillywig']); + }); + + it('adds gdpr when present', () => { + const newValidBidderRequest = deepClone(validBidderRequest); + newValidBidderRequest.gdprConsent = { + consentString: 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA', + gdprApplies: true + }; + + const request = spec.buildRequests(baseValidBidRequests, newValidBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.nested.property('regs.ext.gdpr'); + expect(payload.regs.ext.gdpr).to.be.a('number'); + expect(payload.regs.ext.gdpr).to.equal(1); + expect(payload).to.have.nested.property('user.ext.consent'); + expect(payload.user.ext.consent).to.equal(newValidBidderRequest.gdprConsent.consentString); + }); + + it('sets gdpr to 0 when explicitly gdprApplies: false', () => { + const newValidBidderRequest = deepClone(validBidderRequest); + newValidBidderRequest.gdprConsent = { + gdprApplies: false + }; + + const request = spec.buildRequests(baseValidBidRequests, newValidBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.nested.property('regs.ext.gdpr'); + expect(payload.regs.ext.gdpr).to.be.a('number'); + expect(payload.regs.ext.gdpr).to.equal(0); + }); + + it('adds usp_consent when present', () => { + const newValidBidderRequest = deepClone(validBidderRequest); + newValidBidderRequest.uspConsent = '1YYY'; + + const request = spec.buildRequests(baseValidBidRequests, newValidBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.nested.property('regs.ext.us_privacy'); + expect(payload.regs.ext.us_privacy).to.equal(newValidBidderRequest.uspConsent); + }); + + it('sets coppa to 1 when specified in config', () => { + config.setConfig({'coppa': true}); + + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.nested.property('regs.coppa'); + expect(payload.regs.coppa).to.equal(1); + + config.resetConfig(); + }); + + it('does not set coppa when disabled in the config', () => { + config.setConfig({'coppa': false}); + + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(deepAccess(payload, 'regs.coppa')).to.be.undefined; + + config.resetConfig(); + }); + + it('does not set coppa when not specified in config', () => { + config.resetConfig(); + + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(deepAccess(payload, 'regs.coppa')).to.be.undefined; + }); + + it('should add window size to request by default', () => { + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.nested.property('device.w'); + expect(payload).to.have.nested.property('device.h'); + expect(payload.device.w).to.be.a('number'); + expect(payload.device.h).to.be.a('number'); + }); + + it('should add app when specified in config', () => { + config.setConfig({ app: { bundle: 'org.prebid.mobile.demoapp', domain: 'prebid.org' } }); + + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.property('app'); + expect(payload).to.have.nested.property('app.bundle'); + expect(payload).to.have.nested.property('app.domain'); + expect(payload.app.bundle).to.equal('org.prebid.mobile.demoapp'); + expect(payload.app.domain).to.equal('prebid.org'); + + config.resetConfig(); + }); + + it('should add referrerInfo as site when no app is set', () => { + const newValidBidderRequest = deepClone(validBidderRequest); + + newValidBidderRequest.refererInfo = { referer: 'https://www.bluebillywig.com' }; + + const request = spec.buildRequests(baseValidBidRequests, newValidBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.nested.property('site.page'); + expect(payload.site.page).to.equal('https://www.bluebillywig.com'); + }); + + it('should not add referrerInfo as site when app is set', () => { + config.setConfig({ app: { bundle: 'org.prebid.mobile.demoapp', domain: 'prebid.org' } }); + + const newValidBidderRequest = deepClone(validBidderRequest); + newValidBidderRequest.refererInfo = { referer: 'https://www.bluebillywig.com' }; + + const request = spec.buildRequests(baseValidBidRequests, newValidBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.site).to.be.undefined; + config.resetConfig(); + }); + + it('should add device size to request when specified in config', () => { + config.setConfig({ device: { w: 1, h: 1 } }); + + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.nested.property('device.w'); + expect(payload).to.have.nested.property('device.h'); + expect(payload.device.w).to.be.a('number'); + expect(payload.device.h).to.be.a('number'); + expect(payload.device.w).to.equal(1); + expect(payload.device.h).to.equal(1); + + config.resetConfig(); + }); + + it('should set schain on the request when set on config', () => { + const schain = { + validation: 'lax', + config: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + hp: 1 + } + ] + } + }; + + const newBaseValidBidRequests = deepClone(baseValidBidRequests); + newBaseValidBidRequests[0].schain = schain; + + const request = spec.buildRequests(newBaseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.nested.property('source.ext.schain'); + expect(payload.source.ext.schain).to.deep.equal(schain); + }); + + it('should add currency when specified on the config', () => { + config.setConfig({ currency: { adServerCurrency: 'USD' } }); + + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.property('cur'); + expect(payload.cur).to.eql(['USD']); // NB not equal, eql to check for same array because [1] === [1] fails normally + + config.resetConfig(); + }); + + it('should also take in array for currency on the config', () => { + config.setConfig({ currency: { adServerCurrency: ['USD', 'PHP'] } }); + + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.property('cur'); + expect(payload.cur).to.eql(['USD']); // NB not equal, eql to check for same array because [1] === [1] fails normally + + config.resetConfig(); + }); + + it('should not set cur when currency is not specified on the config', () => { + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.cur).to.be.undefined; + }); + + it('should set user ids when present', () => { + const userId = { tdid: 123 }; + + const newBaseValidBidRequests = deepClone(baseValidBidRequests); + newBaseValidBidRequests[0].userId = { criteoId: 'sample-userid' }; + + const request = spec.buildRequests(newBaseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.nested.property('user.ext.eids'); + expect(payload.user.ext.eids).to.be.an('array'); + expect(payload.user.ext.eids.length).to.equal(1); + }); + + it('should not set user ids when none present', () => { + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(deepAccess(payload, 'user.ext.eids')).to.be.undefined; + }); + + it('should set digitrust when present on bid', () => { + const digiTrust = {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}}; + + const newBaseValidBidRequests = deepClone(baseValidBidRequests); + newBaseValidBidRequests[0].userId = { digitrustid: digiTrust }; + + const request = spec.buildRequests(newBaseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.nested.property('user.ext.digitrust'); + expect(payload.user.ext.digitrust.id).to.equal(digiTrust.data.id); + expect(payload.user.ext.digitrust.keyv).to.equal(digiTrust.data.keyv); + }); + + it('should not set digitrust when opted out', () => { + const digiTrust = {data: {id: 'DTID', keyv: 4, privacy: {optout: true}, producer: 'ABC', version: 2}}; + + const newBaseValidBidRequests = deepClone(baseValidBidRequests); + newBaseValidBidRequests[0].userId = { digitrustid: digiTrust }; + + const request = spec.buildRequests(newBaseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(deepAccess(payload, 'user.ext.digitrust')).to.be.undefined; + }); + }); + describe('interpretResponse', () => { + const publicationName = 'bbprebid.dev'; + const rendererCode = 'glorious_renderer'; + + const baseValidBid = { + bidder: BB_CONSTANTS.BIDDER_CODE, + params: { + accountId: 123, + publicationName: publicationName, + rendererCode: rendererCode, + connections: [ BB_CONSTANTS.BIDDER_CODE ], + bluebillywig: {} + }, + mediaTypes: { + video: { + context: 'outstream' + } + } + }; + + const baseValidBidRequests = [baseValidBid]; + + const validBidderRequest = { + auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', + auctionStart: 1585918458868, + bidderCode: BB_CONSTANTS.BIDDER_CODE, + bidderRequestId: '1a2345b67c8d9e0', + bids: [{ + adUnitCode: 'ad-unit-test', + auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', + bidId: '1234ab567c89de0', + bidRequestsCount: 1, + bidder: BB_CONSTANTS.BIDDER_CODE, + bidderRequestId: '1a2345b67c8d9e0', + params: baseValidBid.params, + sizes: [[768, 432], [640, 480], [630, 360]], + transactionId: '2b34c5de-f67a-8901-bcd2-34567efabc89' + }], + start: 11585918458869, + timeout: 3000 + }; + + const validResponse = { + id: 'a12abc345-67d8-9012-e345-6f78901a2b34', + seatbid: [ + { + bid: [ + { + id: '1', + impid: '1234ab567c89de0', + price: 1, + adm: '\r\nBB Adserver00:00:51', + adid: '67069817', + adomain: [ + 'bluebillywig.com' + ], + cid: '3535', + crid: '67069817', + w: 1, + h: 1, + publicationName: 'bbprebid', + accountId: 123, + ext: { + prebid: { + targeting: { + hb_bidder: 'bluebillywig', + hb_pb: '1.00', + hb_size: '1x1' + }, + type: 'video' + }, + bidder: { + prebid: { + targeting: { + hb_bidder: 'bluebillywig', + hb_pb: '10.00', + hb_size: '1x1' + }, + type: 'video', + video: { + duration: 51, + primary_category: '' + } + }, + bidder: { + bluebillywig: { + brand_id: 1, + auction_id: 1, + bid_ad_type: 1, + creative_info: { + video: { + duration: 51, + mimes: [ + 'video/x-flv', + 'video/mp4', + 'video/webm' + ] + } + } + } + } + } + } + } + ], + seat: 'bluebillywig' + } + ], + cur: 'USD', + ext: { + responsetimemillis: { + bluebillywig: 0 + }, + tmaxrequest: 5000 + } + }; + + const serverResponse = { body: validResponse }; + + it('should build bid array', () => { + const response = deepClone(serverResponse); + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const result = spec.interpretResponse(response, request); + + expect(result.length).to.equal(1); + }); + + it('should have all relevant fields', () => { + const response = deepClone(serverResponse); + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const result = spec.interpretResponse(response, request); + const bid = result[0]; + + // BB_HELPERS.transformRTBToPrebidProps + expect(bid.cpm).to.equal(serverResponse.body.seatbid[0].bid[0].price); + expect(bid.bidId).to.equal(serverResponse.body.seatbid[0].bid[0].impid); + expect(bid.requestId).to.equal(serverResponse.body.seatbid[0].bid[0].impid); + expect(bid.width).to.equal(serverResponse.body.seatbid[0].bid[0].w || BB_CONSTANTS.DEFAULT_WIDTH); + expect(bid.height).to.equal(serverResponse.body.seatbid[0].bid[0].h || BB_CONSTANTS.DEFAULT_HEIGHT); + expect(bid.ad).to.equal(serverResponse.body.seatbid[0].bid[0].adm); + expect(bid.netRevenue).to.equal(BB_CONSTANTS.DEFAULT_NET_REVENUE); + expect(bid.creativeId).to.equal(serverResponse.body.seatbid[0].bid[0].crid); + expect(bid.currency).to.equal(serverResponse.body.cur); + expect(bid.ttl).to.equal(BB_CONSTANTS.DEFAULT_TTL); + + expect(bid.publicationName).to.equal(validBidderRequest.bids[0].params.publicationName); + expect(bid.rendererCode).to.equal(validBidderRequest.bids[0].params.rendererCode); + expect(bid.accountId).to.equal(validBidderRequest.bids[0].params.accountId); + }); + + it('should not give anything when seatbid is an empty array', () => { + const seatbidEmptyArray = deepClone(serverResponse); + seatbidEmptyArray.body.seatbid = []; + + const response = seatbidEmptyArray; + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const result = spec.interpretResponse(response, request); + + expect(result.length).to.equal(0); + }); + + it('should not give anything when seatbid is missing', () => { + const seatbidMissing = deepClone(serverResponse); + delete seatbidMissing.body.seatbid; + + const response = seatbidMissing; + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const result = spec.interpretResponse(response, request); + + expect(result.length).to.equal(0); + }); + + const seatbidNotArrayResponse = deepClone(serverResponse); + it('should not give anything when seatbid is not an array', () => { + const invalidValues = [ false, null, {}, void (0), 123, 'string' ]; + + for (const invalidValue of invalidValues) { + seatbidNotArrayResponse.body.seatbid = invalidValue + const response = deepClone(seatbidNotArrayResponse); // interpretResponse is destructive + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const result = spec.interpretResponse(response, request); + + expect(result.length).to.equal(0); + } + }); + + it('should not give anything when seatbid.bid is an empty array', () => { + const seatbidBidEmpty = deepClone(serverResponse); + seatbidBidEmpty.body.seatbid[0].bid = []; + + const response = seatbidBidEmpty; + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const result = spec.interpretResponse(response, request); + + expect(result.length).to.equal(0); + }); + + it('should not give anything when seatbid.bid is missing', () => { + const seatbidBidMissing = deepClone(serverResponse); + delete seatbidBidMissing.body.seatbid[0].bid; + + const response = seatbidBidMissing; + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const result = spec.interpretResponse(response, request); + + expect(result.length).to.equal(0); + }); + + it('should not give anything when seatbid.bid is not an array', () => { + const seatbidBidNotArray = deepClone(serverResponse); + + const invalidValues = [ false, null, {}, void (0), 123, 'string' ]; + + for (const invalidValue of invalidValues) { + seatbidBidNotArray.body.seatbid[0].bid = invalidValue; + + const response = deepClone(seatbidBidNotArray); // interpretResponse is destructive + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const result = spec.interpretResponse(response, request); + + expect(result.length).to.equal(0); + } + }); + }); + describe('getUserSyncs', () => { + const publicationName = 'bbprebid.dev'; + const rendererCode = 'glorious_renderer'; + + const baseValidBid = { + bidder: BB_CONSTANTS.BIDDER_CODE, + params: { + accountId: 123, + publicationName: publicationName, + rendererCode: rendererCode, + connections: [ BB_CONSTANTS.BIDDER_CODE ], + bluebillywig: {} + }, + mediaTypes: { + video: { + context: 'outstream' + } + } + }; + + const validBidRequests = [baseValidBid]; + + const validBidderRequest = { + auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', + auctionStart: 1585918458868, + bidderCode: BB_CONSTANTS.BIDDER_CODE, + bidderRequestId: '1a2345b67c8d9e0', + bids: [{ + adUnitCode: 'ad-unit-test', + auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', + bidId: '1234ab567c89de0', + bidRequestsCount: 1, + bidder: BB_CONSTANTS.BIDDER_CODE, + bidderRequestId: '1a2345b67c8d9e0', + params: baseValidBid.params, + sizes: [[768, 432], [640, 480], [630, 360]], + transactionId: '2b34c5de-f67a-8901-bcd2-34567efabc89' + }], + start: 11585918458869, + timeout: 3000 + }; + const validResponse = { + id: 'a12abc345-67d8-9012-e345-6f78901a2b34', + seatbid: [ + { + bid: [ + { + id: '1', + impid: '1234ab567c89de0', + price: 1, + adm: '\r\nBB Adserver00:00:51', + adid: '67069817', + adomain: [ + 'bluebillywig.com' + ], + cid: '3535', + crid: '67069817', + w: 1, + h: 1, + publicationName: 'bbprebid', + accountId: 123, + ext: { + prebid: { + targeting: { + hb_bidder: 'bluebillywig', + hb_pb: '1.00', + hb_size: '1x1' + }, + type: 'video' + }, + bidder: { + prebid: { + targeting: { + hb_bidder: 'bluebillywig', + hb_pb: '10.00', + hb_size: '1x1' + }, + type: 'video', + video: { + duration: 51, + primary_category: '' + } + }, + bidder: { + bluebillywig: { + brand_id: 1, + auction_id: 1, + bid_ad_type: 1, + creative_info: { + video: { + duration: 51, + mimes: [ + 'video/x-flv', + 'video/mp4', + 'video/webm' + ] + } + } + } + } + } + } + } + ], + seat: 'bluebillywig' + } + ], + cur: 'USD', + ext: { + responsetimemillis: { + bluebillywig: 0 + }, + tmaxrequest: 5000 + } + }; + + const serverResponse = { body: validResponse }; + + const gdpr = { + consentString: 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAA AAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA', + gdprApplies: true + }; + + it('should return empty if no server response', function () { + const result = spec.getUserSyncs({}, false, gdpr); + expect(result).to.be.empty; + }); + + it('should return empty if server response is empty', function () { + const result = spec.getUserSyncs({}, [], gdpr); + expect(result).to.be.empty; + }); + + it('should return empty if iframeEnabled is not true', () => { + const result = spec.getUserSyncs({iframeEnabled: false}, [serverResponse], gdpr); + expect(result).to.be.empty; + }); + + it('should append the various values if they exist', function() { + // push data to syncStore + spec.buildRequests(validBidRequests, validBidderRequest); + + const result = spec.getUserSyncs({iframeEnabled: true}, [serverResponse], gdpr); + + expect(result).to.not.be.empty; + + expect(result[0].url).to.include('gdpr=1'); + expect(result[0].url).to.include(gdpr.consentString); + expect(result[0].url).to.include('accountId=123'); + expect(result[0].url).to.include(`bidders=${btoa(JSON.stringify(validBidRequests[0].params.connections))}`); + expect(result[0].url).to.include('cb='); + }); + }); +}); From 14e4a941c0514090de4d27bceb3ca91a616c0d7b Mon Sep 17 00:00:00 2001 From: Konduit <55142865+konduit-dev@users.noreply.github.com> Date: Thu, 7 May 2020 20:38:50 +0300 Subject: [PATCH 303/496] New version of Konduit Accelerate module (#5164) * Adding Konduit module * Removed superfluous arguments passed to obtainVastUrl function * Removed superfluous arguments passed to obtainVastUrl function. * Build trigger (empty commit) * Module documentation updated according to the comments * Logic in obtainVastUrl function updated according to the review comment. * Removed hook, enabled eslint * Merged recent prebid changes * New method is introduced to process a bid and return dynamic CPM data * New Konduit Analytics adapter responsible for client auction stats collection * Updated konduit analytics adapter .md file * Fixed linter issue with more than 1 blank line used * Use '$prebid.version$' instead of the $$PREBID_GLOBAL$$.version * Updated unit tests Co-authored-by: Max Shevchenko Co-authored-by: Alexander Kislitsyn --- modules/konduitAnalyticsAdapter.js | 225 ++++++++++++++++++ modules/konduitAnalyticsAdapter.md | 32 +++ modules/konduitWrapper.js | 203 ++++++++++++---- modules/konduitWrapper.md | 137 ++++++++--- .../modules/konduitAnalyticsAdapter_spec.js | 126 ++++++++++ test/spec/modules/konduitWrapper_spec.js | 143 +++++++---- 6 files changed, 740 insertions(+), 126 deletions(-) create mode 100644 modules/konduitAnalyticsAdapter.js create mode 100644 modules/konduitAnalyticsAdapter.md create mode 100644 test/spec/modules/konduitAnalyticsAdapter_spec.js diff --git a/modules/konduitAnalyticsAdapter.js b/modules/konduitAnalyticsAdapter.js new file mode 100644 index 00000000000..00df790b18a --- /dev/null +++ b/modules/konduitAnalyticsAdapter.js @@ -0,0 +1,225 @@ +import { ajax } from '../src/ajax.js'; +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; +import * as utils from '../src/utils.js'; +import { targeting } from '../src/targeting.js'; +import { config } from '../src/config.js'; +import CONSTANTS from '../src/constants.json'; + +const TRACKER_HOST = 'tracker.konduit.me'; + +const analyticsType = 'endpoint'; + +const eventDataComposerMap = { + [CONSTANTS.EVENTS.AUCTION_INIT]: obtainAuctionInfo, + [CONSTANTS.EVENTS.AUCTION_END]: obtainAuctionInfo, + [CONSTANTS.EVENTS.BID_REQUESTED]: obtainBidRequestsInfo, + [CONSTANTS.EVENTS.BID_TIMEOUT]: obtainBidTimeoutInfo, + [CONSTANTS.EVENTS.BID_RESPONSE]: obtainBidResponseInfo, + [CONSTANTS.EVENTS.BID_WON]: obtainWinnerBidInfo, + [CONSTANTS.EVENTS.NO_BID]: obtainNoBidInfo, +}; + +// This function is copy from prebid core +function formatQS(query) { + return Object + .keys(query) + .map(k => Array.isArray(query[k]) + ? query[k].map(v => `${k}[]=${v}`).join('&') + : `${k}=${query[k]}`) + .join('&'); +} + +// This function is copy from prebid core +function buildUrl(obj) { + return (obj.protocol || 'http') + '://' + + (obj.host || + obj.hostname + (obj.port ? `:${obj.port}` : '')) + + (obj.pathname || '') + + (obj.search ? `?${formatQS(obj.search || '')}` : '') + + (obj.hash ? `#${obj.hash}` : ''); +} + +const getWinnerBidFromAggregatedEvents = () => { + return konduitAnalyticsAdapter.context.aggregatedEvents + .filter(evt => evt.eventType === CONSTANTS.EVENTS.BID_WON)[0]; +}; + +const isWinnerBidDetected = () => { + return !!getWinnerBidFromAggregatedEvents(); +}; +const isWinnerBidExist = () => { + return !!targeting.getWinningBids()[0]; +}; + +const konduitAnalyticsAdapter = Object.assign( + adapter({ analyticsType }), + { + track ({ eventType, args }) { + if (CONSTANTS.EVENTS.AUCTION_INIT === eventType) { + konduitAnalyticsAdapter.context.aggregatedEvents.splice(0); + } + + if (eventDataComposerMap[eventType]) { + konduitAnalyticsAdapter.context.aggregatedEvents.push({ + eventType, + data: eventDataComposerMap[eventType](args), + }); + } + + if (eventType === CONSTANTS.EVENTS.AUCTION_END) { + if (!isWinnerBidDetected() && isWinnerBidExist()) { + const bidWonData = eventDataComposerMap[CONSTANTS.EVENTS.BID_WON](targeting.getWinningBids()[0]); + + konduitAnalyticsAdapter.context.aggregatedEvents.push({ + eventType: CONSTANTS.EVENTS.BID_WON, + data: bidWonData, + }); + } + sendRequest({ method: 'POST', path: '/analytics-initial-event', payload: composeRequestPayload() }); + } + } + } +); + +function obtainBidTimeoutInfo (args) { + return args.map(item => item.bidder).filter(utils.uniques); +} + +function obtainAuctionInfo (auction) { + return { + auctionId: auction.auctionId, + timestamp: auction.timestamp, + auctionEnd: auction.auctionEnd, + auctionStatus: auction.auctionStatus, + adUnitCodes: auction.adUnitCodes, + labels: auction.labels, + timeout: auction.timeout + }; +} + +function obtainBidRequestsInfo (bidRequests) { + return { + bidderCode: bidRequests.bidderCode, + time: bidRequests.start, + bids: bidRequests.bids.map(function (bid) { + return { + transactionId: bid.transactionId, + adUnitCode: bid.adUnitCode, + bidId: bid.bidId, + startTime: bid.startTime, + sizes: utils.parseSizesInput(bid.sizes).toString(), + params: bid.params + }; + }), + }; +} + +function obtainBidResponseInfo (bidResponse) { + return { + bidderCode: bidResponse.bidder, + transactionId: bidResponse.transactionId, + adUnitCode: bidResponse.adUnitCode, + statusMessage: bidResponse.statusMessage, + mediaType: bidResponse.mediaType, + renderedSize: bidResponse.size, + cpm: bidResponse.cpm, + currency: bidResponse.currency, + netRevenue: bidResponse.netRevenue, + timeToRespond: bidResponse.timeToRespond, + bidId: bidResponse.bidId, + requestId: bidResponse.requestId, + creativeId: bidResponse.creativeId + }; +} + +function obtainNoBidInfo (bidResponse) { + return { + bidderCode: bidResponse.bidder, + transactionId: bidResponse.transactionId, + adUnitCode: bidResponse.adUnitCode, + bidId: bidResponse.bidId, + }; +} + +function obtainWinnerBidInfo (bidResponse) { + return { + adId: bidResponse.adId, + bidderCode: bidResponse.bidder, + adUnitCode: bidResponse.adUnitCode, + statusMessage: bidResponse.statusMessage, + mediaType: bidResponse.mediaType, + renderedSize: bidResponse.size, + cpm: bidResponse.cpm, + currency: bidResponse.currency, + netRevenue: bidResponse.netRevenue, + timeToRespond: bidResponse.timeToRespond, + bidId: bidResponse.requestId, + dealId: bidResponse.dealId, + status: bidResponse.status, + creativeId: bidResponse.creativeId + }; +} + +function composeRequestPayload () { + const konduitId = config.getConfig('konduit.konduitId'); + const { width, height } = window.screen; + + return { + konduitId, + prebidVersion: '$prebid.version$', + environment: { + screen: { width, height }, + language: navigator.language, + }, + events: konduitAnalyticsAdapter.context.aggregatedEvents, + }; +} + +function sendRequest ({ host = TRACKER_HOST, method, path, payload }) { + const formattedUrlOptions = { + protocol: 'https', + hostname: host, + pathname: path, + }; + if (method === 'GET') { + formattedUrlOptions.search = payload; + } + + let konduitAnalyticsRequestUrl = buildUrl(formattedUrlOptions); + + ajax( + konduitAnalyticsRequestUrl, + undefined, + method === 'POST' ? JSON.stringify(payload) : null, + { + contentType: 'application/json', + method, + withCredentials: true + } + ); +} + +konduitAnalyticsAdapter.originEnableAnalytics = konduitAnalyticsAdapter.enableAnalytics; + +konduitAnalyticsAdapter.enableAnalytics = function (analyticsConfig) { + const konduitId = config.getConfig('konduit.konduitId'); + + if (!konduitId) { + utils.logError('A konduitId in config is required to use konduitAnalyticsAdapter'); + return; + } + + konduitAnalyticsAdapter.context = { + aggregatedEvents: [], + }; + + konduitAnalyticsAdapter.originEnableAnalytics(analyticsConfig); +}; + +adapterManager.registerAnalyticsAdapter({ + adapter: konduitAnalyticsAdapter, + code: 'konduit' +}); + +export default konduitAnalyticsAdapter; diff --git a/modules/konduitAnalyticsAdapter.md b/modules/konduitAnalyticsAdapter.md new file mode 100644 index 00000000000..c5854b77ccd --- /dev/null +++ b/modules/konduitAnalyticsAdapter.md @@ -0,0 +1,32 @@ +# Overview +​ +``` +Module Name: Konduit Analytics Adapter +Module Type: Analytics Adapter +Maintainer: support@konduit.me +``` +​ +​ +# Description +​ +Konduit Analytics adapter pushes Prebid events into Konduit platform, which is then organizes the data and presents it to a client in different insightful views. +​ +For more information, visit the [official Konduit website](https://konduitvideo.com/). +​ +​ +# Usage +​ +Konduit Analytics can be enabled with a standard `enableAnalytics` call. +Note it is also important to provide a valid Konduit identifier as a config parameter. +​ +```javascript +pbjs.setConfig({ + konduit: { + konduitId: your_konduit_id, + } +}); +​ +pbjs.enableAnalytics({ + provider: 'konduit' +}) +``` diff --git a/modules/konduitWrapper.js b/modules/konduitWrapper.js index 33bc45f7566..e015fb93616 100644 --- a/modules/konduitWrapper.js +++ b/modules/konduitWrapper.js @@ -2,87 +2,192 @@ import { registerVideoSupport } from '../src/adServerManager.js'; import { targeting } from '../src/targeting.js'; import * as utils from '../src/utils.js'; import { config } from '../src/config.js'; +import { ajaxBuilder } from '../src/ajax.js'; +import { getPriceBucketString } from '../src/cpmBucketManager.js'; +import { getPriceByGranularity } from '../src/auction.js'; + +const SERVER_PROTOCOL = 'https'; +const SERVER_HOST = 'p.konduit.me'; const MODULE_NAME = 'Konduit'; +const KONDUIT_ID_CONFIG = 'konduit.konduitId'; + +export const errorMessages = { + NO_KONDUIT_ID: 'A konduitId param is required to be in configs', + NO_BID: 'A bid was not found', + CACHE_FAILURE: 'A bid was not cached', +}; + +// This function is copy from prebid core +function formatQS(query) { + return Object + .keys(query) + .map(k => Array.isArray(query[k]) + ? query[k].map(v => `${k}[]=${v}`).join('&') + : `${k}=${query[k]}`) + .join('&'); +} + +// This function is copy from prebid core +function buildUrl(obj) { + return (obj.protocol || 'http') + '://' + + (obj.host || + obj.hostname + (obj.port ? `:${obj.port}` : '')) + + (obj.pathname || '') + + (obj.search ? `?${formatQS(obj.search || '')}` : '') + + (obj.hash ? `#${obj.hash}` : ''); +} + function addLogLabel(args) { args = [].slice.call(args); args.unshift(`${MODULE_NAME}: `); return args; } -export function logInfo() { +function logInfo() { utils.logInfo(...addLogLabel(arguments)); } -export function logError() { +function logError() { utils.logError(...addLogLabel(arguments)); } -export function buildVastUrl(options) { - if (!options.params || !options.params.konduit_id) { - logError(`'konduit_id' parameter is required for $$PREBID_GLOBAL$$.adServers.konduit.buildVastUrl function`); - - return null; +function sendRequest ({ host = SERVER_HOST, protocol = SERVER_PROTOCOL, method = 'GET', path, payload, callbacks, timeout }) { + const formattedUrlOptions = { + protocol: protocol, + hostname: host, + pathname: path, + }; + if (method === 'GET') { + formattedUrlOptions.search = payload; } - const bid = options.bid || targeting.getWinningBids()[0]; + let konduitAnalyticsRequestUrl = buildUrl(formattedUrlOptions); + const ajax = ajaxBuilder(timeout); + + ajax( + konduitAnalyticsRequestUrl, + callbacks, + method === 'POST' ? JSON.stringify(payload) : null, + { + contentType: 'application/json', + method, + withCredentials: true + } + ); +} - if (!bid) { - logError('Bid is not provided or not found'); +/** + * This function accepts an object with bid and tries to cache it while generating konduit_cache_key for it. + * In addition, it returns a list with updated bid objects where k_cpm key is added + * @param {Object} options + * @param {Object} [options.bid] - winner bid from publisher + * @param {string} [options.adUnitCode] - to look for winner bid + * @param {string} [options.timeout] - timeout for bidsProcessor request + * @param {function} [options.callback] - callback will be called in the end of the request + */ +export function processBids(options = {}) { + const konduitId = config.getConfig(KONDUIT_ID_CONFIG); + options = options || {}; + + if (!konduitId) { + logError(errorMessages.NO_KONDUIT_ID); + + if (options.callback) { + options.callback(new Error(errorMessages.NO_KONDUIT_ID)); + } return null; } - logInfo('The following bid will be wrapped: ', bid); - - const queryParams = {}; + const bid = options.bid || targeting.getWinningBids(options.adUnitCode)[0]; - const vastUrl = obtainVastUrl(bid); - - if (vastUrl) { - queryParams.konduit_id = options.params.konduit_id; - queryParams.konduit_header_bidding = 1; - queryParams.konduit_url = vastUrl; - } else { - logError('No VAST url found in the bid'); - } - - let resultingUrl = null; + if (!bid) { + logError(errorMessages.NO_BID); - if (queryParams.konduit_url) { - resultingUrl = utils.buildUrl({ - protocol: 'https', - host: 'p.konduit.me', - pathname: '/api/vastProxy', - search: queryParams - }); + if (options.callback) { + options.callback(new Error(errorMessages.NO_BID)); + } - logInfo(`Konduit wrapped VAST url: ${resultingUrl}`); + return null; } - return resultingUrl; -} - -function obtainVastUrl(bid) { - const vastUrl = bid && bid.vastUrl; + const priceGranularity = config.getConfig('priceGranularity'); - if (vastUrl) { - logInfo(`VAST url found in the bid - ${vastUrl}`); + bid.kCpm = bid.cpm; - return encodeURIComponent(vastUrl); + if (!bid.adserverTargeting) { + bid.adserverTargeting = {}; } - const cacheUrl = config.getConfig('cache.url'); - if (cacheUrl) { - const composedCacheUrl = `${cacheUrl}?uuid=${bid.videoCacheKey}`; - - logInfo(`VAST url is taken from cache.url: ${composedCacheUrl}`); - - return encodeURIComponent(composedCacheUrl); - } + bid.adserverTargeting.k_cpm = getPriceByGranularity(priceGranularity)(bid); + + const bidsToProcess = [{ + auctionId: bid.auctionId, + vastUrl: bid.vastUrl, + bidderCode: bid.bidderCode, + creativeId: bid.creativeId, + adUnitCode: bid.adUnitCode, + cpm: bid.cpm, + currency: bid.currency, + }]; + + sendRequest({ + method: 'POST', + path: '/api/bidsProcessor', + timeout: options.timeout || 1000, + payload: { + clientId: konduitId, + bids: bidsToProcess, + }, + callbacks: { + success: (data) => { + let error = null; + logInfo('Bids processed successfully ', data); + try { + const { kCpmData, cacheData } = JSON.parse(data); + const processedBidKey = `${bid.bidderCode}:${bid.creativeId}`; + + if (!utils.isEmpty(cacheData)) { + bid.adserverTargeting.konduit_id = konduitId; + } else { + error = new Error(errorMessages.CACHE_FAILURE); + } + + if (utils.isNumber(kCpmData[processedBidKey])) { + bid.kCpm = kCpmData[processedBidKey]; + const priceStringsObj = getPriceBucketString( + bid.kCpm, + config.getConfig('customPriceBucket'), + config.getConfig('currency.granularityMultiplier') + ); + bid.adserverTargeting.k_cpm = priceStringsObj.custom || priceStringsObj[priceGranularity] || priceStringsObj.med; + } + + if (utils.isStr(cacheData[processedBidKey])) { + bid.konduitCacheKey = cacheData[processedBidKey]; + bid.adserverTargeting.konduit_cache_key = cacheData[processedBidKey]; + } + } catch (err) { + error = err; + logError('Error parsing JSON response for bidsProcessor data: ', err) + } + + if (options.callback) { + options.callback(error, [bid]); + } + }, + error: (error) => { + logError('Bid was not processed successfully ', error); + if (options.callback) { + options.callback(utils.isStr(error) ? new Error(error) : error, [bid]); + } + } + } + }); } registerVideoSupport('konduit', { - buildVastUrl: buildVastUrl, + processBids: processBids, }); diff --git a/modules/konduitWrapper.md b/modules/konduitWrapper.md index adbb50487da..3097801ffab 100644 --- a/modules/konduitWrapper.md +++ b/modules/konduitWrapper.md @@ -1,11 +1,84 @@ -## Konduit video tags wrapper +# Overview + +``` +Module Name: Konduit Accelerate +Module Type: Video Module +Maintainer: support@konduit.me +``` + +# Description + +Konduit Wrapper is a prebid module that allows +- wrapping a bid response so that it is processed through Konduit platform +- obtaining a historical performance indicator for a bid + + +# Configuration + +## Building Prebid with the Konduit wrapper function + +Your Prebid build must include the **konduitWrapper** module. Follow the build instructions for Prebid as explained in the top level README.md file of the Prebid source tree. + +ex: $ gulp build --modules=konduitWrapper -Konduit Wrapper is a prebid module to generate Konduit wrapped VAST tag URLs for a provided bid or a winning bid. +## Prebid related configuration -### Setup +Konduit module should be used with a valid Konduit identifier. +```javascript +pbjs.setConfig({ + konduit: { + konduitId: your_konduit_id, + } +}); +``` + +Please contact support@konduit.me for assistance. + + +## GAM related configuration + +It is important to configure your GAM line items. +Please contact support@konduit.me for assistance. + +In most cases it would require only Creative VAST URL update with the following URL: +``` +https://p.konduit.me/api/vastProxy?konduit_hb=1&konduit_hb_awarded=1&konduit_cache_key=%%PATTERN:konduit_cache_key%%&konduit_id=%%PATTERN:konduit_id%% ``` + + +# Usage + +Konduit module contains a single function that accepts an `options` parameter. + +The `options` parameter can include: +* `bid` - prebid object with VAST url that should be cached (if not passed first winning bid from `auctionManager.getWinningBids()` will be used) +* `adUnitCode` - adUnitCode where a winner bid can be found +* `timeout` - max time to wait for Konduit response with cache key and kCpm data +* `callback` - callback function is called once Konduit cache data for the bid. Arguments of this function are - `error` and `bids` (error should be `null` if Konduit request is successful) + +The function adds two parameters into the passed bid - kCpm and konduitCacheKey. Additionally `processBids` updates bid's `adserverTargeting` with `k_cpm`, `konduti_cache_key` and `konduit_id` fields. + + +```javascript +pbjs.requestBids({ + bidsBackHandler: function (bids) { + pbjs.adServers.konduit.processBids({ + callback: function (error, bids) { + var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ + ... + }); + } + }); + } +}) +``` + + +# Sample code + +```javascript var videoAdUnit = [{ code: 'videoAd', mediaTypes: { @@ -28,46 +101,48 @@ var videoAdUnit = [{ pbjs.que.push(function(){ pbjs.addAdUnits(videoAdUnit); + pbjs.setConfig({ + konduit: { + konduitId: 'your_konduit_id', + }, + }); + pbjs.requestBids({ - timeout : 700, bidsBackHandler : function(bids) { var winnerBid = pbjs.getHighestCpmBids('videoAd')[0]; - var vastTagUrl = pbjs.adServers.konduit.buildVastUrl({ - bid: winnerBid, // just in case if you want to pass your bid - params: { - konduit_id: 'your_konduit_id' + pbjs.adServers.konduit.processBids({ + bid: winnerBid, + adUnitCode: videoAdUnit[0].code, + timeout: 2000, + callback: function (error, processedBids) { + var vastTagUrl = pbjs.adServers.dfp.buildVideoUrl({ + adUnit: videoAdUnit, + params: { + iu: '', + output: 'vast', + }, + }); + + invokeVideoPlayer(vastTagUrl); } }); - - invokeVideoPlayer(vastTagUrl); } }); }); function invokeVideoPlayer(vastTagUrl) { - videojs("video_player_id").ready(function() { - this.vastClient({ - adTagUrl: vastTagUrl, - playAdAlways: true, - verbosity: 4, - autoplay: true - }); - - this.play(); + videojs("video_player_id").ready(function() { + this.vastClient({ + adTagUrl: vastTagUrl, + playAdAlways: true, + verbosity: 4, + autoplay: true }); - } -``` - -Function parameters: -* `bid` - prebid object with VAST url that should be wrapped (if not passed first winning bid from `auctionManager.getWinningBids()` is used) -* `konduit_id` - your personal unique Konduit identifier (required) - -The function returns a Konduit wrapped VAST url if valid parameters are passed in. If some of the parameters are not passed or are invalid the function returns 'null' along with related error logs providing more details. + this.play(); + }); +} +``` -### Building Prebid with the Konduit wrapper function -Your Prebid build must include the **konduitWrapper** module. Follow the build instructions for Prebid as explained in the top level README.md file of the Prebid source tree. - -ex: $ gulp build --modules=konduitWrapper diff --git a/test/spec/modules/konduitAnalyticsAdapter_spec.js b/test/spec/modules/konduitAnalyticsAdapter_spec.js new file mode 100644 index 00000000000..ac557d27f90 --- /dev/null +++ b/test/spec/modules/konduitAnalyticsAdapter_spec.js @@ -0,0 +1,126 @@ +import konduitAnalyticsAdapter from 'modules/konduitAnalyticsAdapter'; +import { expect } from 'chai'; +import { config } from '../../../src/config.js'; +import { server } from 'test/mocks/xhr.js'; +let events = require('src/events'); +let adapterManager = require('src/adapterManager').default; +let CONSTANTS = require('src/constants.json'); + +const eventsData = { + [CONSTANTS.EVENTS.AUCTION_INIT]: { + 'auctionId': 'test_auction_id', + 'timestamp': Date.now(), + 'auctionStatus': 'inProgress', + 'adUnitCodes': ['video-test'], + 'timeout': 700 + }, + [CONSTANTS.EVENTS.BID_REQUESTED]: { + 'bidderCode': 'test_bidder_code', + 'time': Date.now(), + 'bids': [{ + 'transactionId': 'test_transaction_id', + 'adUnitCode': 'video-test', + 'bidId': 'test_bid_id', + 'sizes': '640x480', + 'params': { 'testParam': 'test_param' } + }] + }, + [CONSTANTS.EVENTS.NO_BID]: { + 'bidderCode': 'test_bidder_code2', + 'transactionId': 'test_transaction_id', + 'adUnitCode': 'video-test', + 'bidId': 'test_bid_id' + }, + [CONSTANTS.EVENTS.BID_RESPONSE]: { + 'bidderCode': 'test_bidder_code', + 'adUnitCode': 'video-test', + 'statusMessage': 'Bid available', + 'mediaType': 'video', + 'renderedSize': '640x480', + 'cpm': 0.5, + 'currency': 'USD', + 'netRevenue': true, + 'timeToRespond': 124, + 'requestId': 'test_request_id', + 'creativeId': 144876543 + }, + [CONSTANTS.EVENTS.AUCTION_END]: { + 'auctionId': 'test_auction_id', + 'timestamp': Date.now(), + 'auctionEnd': Date.now() + 400, + 'auctionStatus': 'completed', + 'adUnitCodes': ['video-test'], + 'timeout': 700 + }, + [CONSTANTS.EVENTS.BID_WON]: { + 'bidderCode': 'test_bidder_code', + 'adUnitCode': 'video-test', + 'statusMessage': 'Bid available', + 'mediaType': 'video', + 'renderedSize': '640x480', + 'cpm': 0.5, + 'currency': 'USD', + 'netRevenue': true, + 'timeToRespond': 124, + 'requestId': 'test_request_id', + 'creativeId': 144876543 + }, +}; + +describe(`Konduit Analytics Adapter`, () => { + const konduitId = 'test'; + + beforeEach(function () { + sinon.spy(konduitAnalyticsAdapter, 'track'); + sinon.stub(events, 'getEvents').returns([]); + config.setConfig({ konduit: { konduitId } }); + }); + + afterEach(function () { + events.getEvents.restore(); + konduitAnalyticsAdapter.track.restore(); + konduitAnalyticsAdapter.disableAnalytics(); + }); + + it(`should add all events to an aggregatedEvents queue + inside konduitAnalyticsAdapter.context and send a request with correct data`, function () { + server.respondWith(JSON.stringify({ key: 'test' })); + + adapterManager.registerAnalyticsAdapter({ + code: 'konduit', + adapter: konduitAnalyticsAdapter + }); + + adapterManager.enableAnalytics({ + provider: 'konduit', + }); + + expect(konduitAnalyticsAdapter.context).to.be.an('object'); + expect(konduitAnalyticsAdapter.context.aggregatedEvents).to.be.an('array'); + + const eventTypes = [ + CONSTANTS.EVENTS.AUCTION_INIT, + CONSTANTS.EVENTS.BID_REQUESTED, + CONSTANTS.EVENTS.NO_BID, + CONSTANTS.EVENTS.BID_RESPONSE, + CONSTANTS.EVENTS.BID_WON, + CONSTANTS.EVENTS.AUCTION_END, + ]; + const args = eventTypes.map(eventType => eventsData[eventType]); + + eventTypes.forEach((eventType, i) => { + events.emit(eventType, args[i]); + }); + + server.respond(); + + expect(konduitAnalyticsAdapter.context.aggregatedEvents.length).to.be.equal(6); + expect(server.requests[0].url).to.match(/http(s):\/\/\w*\.konduit\.me\/analytics-initial-event/); + + const requestBody = JSON.parse(server.requests[0].requestBody); + expect(requestBody.konduitId).to.be.equal(konduitId); + expect(requestBody.prebidVersion).to.be.equal('$prebid.version$'); + expect(requestBody.environment).to.be.an('object'); + sinon.assert.callCount(konduitAnalyticsAdapter.track, 6); + }); +}); diff --git a/test/spec/modules/konduitWrapper_spec.js b/test/spec/modules/konduitWrapper_spec.js index 4a0c627e885..d70cb7a6c60 100644 --- a/test/spec/modules/konduitWrapper_spec.js +++ b/test/spec/modules/konduitWrapper_spec.js @@ -1,72 +1,123 @@ import { expect } from 'chai'; -import parse from 'url-parse'; -import { buildVastUrl } from 'modules/konduitWrapper.js'; -import { parseQS } from 'src/utils.js'; +import { processBids, errorMessages } from 'modules/konduitWrapper.js'; import { config } from 'src/config.js'; +import { server } from 'test/mocks/xhr.js'; describe('The Konduit vast wrapper module', function () { - it('should make a wrapped request url when `bid` passed', function () { - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + const konduitId = 'test'; + beforeEach(function() { + config.setConfig({ konduit: { konduitId } }); + }); - const url = parse(buildVastUrl({ - bid, - params: { 'konduit_id': 'testId' }, - })); + describe('processBids function', () => { + it(`should make a correct processBids request and add kCpm and konduitCacheKey + to the passed bids and to the adserverTargeting object`, function () { + const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); - expect(url.protocol).to.equal('https:'); - expect(url.host).to.equal('p.konduit.me'); + server.respondWith(JSON.stringify({ + kCpmData: { [`${bid.bidderCode}:${bid.creativeId}`]: bid.cpm }, + cacheData: { [`${bid.bidderCode}:${bid.creativeId}`]: 'test_cache_key' }, + })); - const queryParams = parseQS(url.query); - expect(queryParams).to.have.property('konduit_url', encodeURIComponent('http://some-vast-url.com')); - expect(queryParams).to.have.property('konduit_header_bidding', '1'); - expect(queryParams).to.have.property('konduit_id', 'testId'); - }); + processBids({ bid }); + server.respond(); - it('should return null when no `konduit_id` (required param) passed', function () { - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + expect(server.requests.length).to.equal(1); - const url = buildVastUrl({ bid }); + const requestBody = JSON.parse(server.requests[0].requestBody); - expect(url).to.equal(null); - }); + expect(requestBody.clientId).to.equal(konduitId); - it('should return null when either bid or adUnit is not passed', function () { - const url = buildVastUrl({ params: { 'konduit_id': 'testId' } }); + expect(bid.konduitCacheKey).to.equal('test_cache_key'); + expect(bid.kCpm).to.equal(bid.cpm); - expect(url).to.equal(null); - }); + expect(bid.adserverTargeting).to.be.an('object'); + + expect(bid.adserverTargeting.k_cpm).to.equal(bid.pbCg || bid.pbAg); + expect(bid.adserverTargeting.konduit_cache_key).to.equal('test_cache_key'); + expect(bid.adserverTargeting.konduit_id).to.equal(konduitId); + }); + + it(`should call callback with error object in arguments if cacheData is empty in the response`, function () { + const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + + server.respondWith(JSON.stringify({ + kCpmData: { [`${bid.bidderCode}:${bid.creativeId}`]: bid.cpm }, + cacheData: {}, + })); + const callback = sinon.spy(); + processBids({ bid, callback }); + server.respond(); - it('should return null when bid does not contain vastUrl', function () { - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + expect(server.requests.length).to.equal(1); - delete bid.vastUrl; + const requestBody = JSON.parse(server.requests[0].requestBody); - const url = buildVastUrl({ - bid, - params: { 'konduit_id': 'testId' }, + expect(requestBody.clientId).to.equal(konduitId); + + expect(bid.konduitCacheKey).to.be.undefined; + expect(bid.kCpm).to.equal(bid.cpm); + + expect(bid.adserverTargeting.k_cpm).to.equal(bid.pbCg || bid.pbAg); + expect(bid.adserverTargeting.konduit_cache_key).to.be.undefined; + expect(bid.adserverTargeting.konduit_id).to.be.undefined; + + expect(callback.firstCall.args[0]).to.be.an('error'); }); - expect(url).to.equal(null); - }); + it('should call callback if processBids request is sent successfully', function () { + const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + server.respondWith(JSON.stringify({ key: 'test' })); + const callback = sinon.spy(); + processBids({ + bid, + callback + }); + server.respond(); + + expect(callback.calledOnce).to.be.true; + }); - it('should return wrapped vastUrl based on cached url in params', function () { - config.setConfig({ cache: { url: 'https://cached.url.com' } }); - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + it('should call callback with error object in arguments if processBids request is failed', function () { + const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + const callback = sinon.spy(); + processBids({ + bid, + callback + }); + server.respond(); + + expect(callback.calledOnce).to.be.true; + expect(callback.firstCall.args[0]).to.be.an('error'); + }); - delete bid.vastUrl; + it('should call callback with error object in arguments if no konduitId in configs', function () { + config.setConfig({ konduit: { konduitId: null } }); - const expectedUrl = encodeURIComponent(`https://cached.url.com?uuid=${bid.videoCacheKey}`); + const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + const callback = sinon.spy(); + processBids({ + bid, + callback + }); - const url = parse(buildVastUrl({ - bid, - params: { 'konduit_id': 'testId' }, - })); - const queryParams = parseQS(url.query); + expect(callback.calledOnce).to.be.true; + expect(callback.firstCall.args[0]).to.be.an('error'); + expect(callback.firstCall.args[0].message).to.equal(errorMessages.NO_KONDUIT_ID); + }); - expect(queryParams).to.have.property('konduit_url', expectedUrl); + it('should call callback with error object in arguments if no bids found', function () { + const callback = sinon.spy(); + processBids({ + bid: null, + callback + }); - config.resetConfig(); + expect(callback.calledOnce).to.be.true; + expect(callback.firstCall.args[0]).to.be.an('error'); + expect(callback.firstCall.args[0].message).to.equal(errorMessages.NO_BID); + }); }); }); @@ -103,7 +154,7 @@ function createBid(cpm, adUnitCode, durationBucket, priceIndustryDuration, uuid, 'pbLg': '5.00', 'pbMg': '5.00', 'pbHg': '5.00', - 'pbAg': '5.00', + 'pbAg': `${cpm}.00`, 'pbDg': '5.00', 'pbCg': '', 'size': '640x360', From 1b88276e4ee708f1071948a0828d8af03dbcaefc Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Thu, 7 May 2020 13:39:20 -0400 Subject: [PATCH 304/496] Delete audience network integration example. (#5190) Audience Network for prebid has been removed. --- .../gpt/audienceNetwork_dfp.html | 83 ------------------- 1 file changed, 83 deletions(-) delete mode 100644 integrationExamples/gpt/audienceNetwork_dfp.html diff --git a/integrationExamples/gpt/audienceNetwork_dfp.html b/integrationExamples/gpt/audienceNetwork_dfp.html deleted file mode 100644 index b30df31b276..00000000000 --- a/integrationExamples/gpt/audienceNetwork_dfp.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - -

Prebid.js Test

-
- -
-
-

Audience Network quick start

-
    -
  1. Create a new App at https://developers.facebook.com/apps
  2. -
  3. Add the Audience Network product to it
  4. -
  5. Create a new Placement to generate your placementId
  6. -
  7. To test, ensure the User-Agent request header represents a mobile device
  8. -
-
- - From 89d9c259e660e987326ff263eea9c228286c9931 Mon Sep 17 00:00:00 2001 From: Vadim Mazzherin Date: Thu, 7 May 2020 23:46:28 +0600 Subject: [PATCH 305/496] ShowHeroes - schain support (#5193) * ITDEV-4723 PrebidJS adapter support with SupplyChain module object * ITDEV-4723 Fix tests * ITDEV-4723 New entry point Co-authored-by: veranevera Co-authored-by: Elizaveta Voziyanova <44549195+h2p4x8@users.noreply.github.com> --- modules/showheroes-bsBidAdapter.js | 8 ++- .../modules/showheroes-bsBidAdapter_spec.js | 56 +++++++++++++++---- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/modules/showheroes-bsBidAdapter.js b/modules/showheroes-bsBidAdapter.js index 2831d793aad..d0eb8c6a589 100644 --- a/modules/showheroes-bsBidAdapter.js +++ b/modules/showheroes-bsBidAdapter.js @@ -5,7 +5,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { VIDEO, BANNER } from '../src/mediaTypes.js'; import { loadExternalScript } from '../src/adloader.js'; -const PROD_ENDPOINT = 'https://bs1.showheroes.com/api/v1/bid'; +const PROD_ENDPOINT = 'https://bs.showheroes.com/api/v1/bid'; const STAGE_ENDPOINT = 'https://bid-service.stage.showheroes.com/api/v1/bid'; const PROD_PUBLISHER_TAG = 'https://static.showheroes.com/publishertag.js'; const STAGE_PUBLISHER_TAG = 'https://pubtag.stage.showheroes.com/publishertag.js'; @@ -38,6 +38,7 @@ export const spec = { const isNativeRender = utils.deepAccess(validBidRequests[0], 'renderer'); const outstreamOptions = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions'); const isBanner = !!validBidRequests[0].mediaTypes.banner || (isOutstream && !(isCustomRender || isNativeRender || isNodeRender)); + const defaultSchain = validBidRequests[0].schain || {}; validBidRequests.forEach((bid) => { const videoSizes = getVideoSizes(bid); @@ -76,6 +77,7 @@ export const spec = { height: size[1] }, params: bid.params, + schain: bid.schain || defaultSchain, }; }; @@ -215,7 +217,7 @@ function outstreamRender(bid) { return; } - const slot = utils.getBidIdParameter('slot', bid.renderer.config); + const slot = utils.getBidIdParameter('slot', bid.renderer.config) || bid.adUnitCode; if (slot && window.document.getElementById(slot)) { window.document.getElementById(slot).appendChild(embedCode); } else if (slot) { @@ -274,7 +276,7 @@ function getVideoSizes(bidRequest) { } function getBannerSizes(bidRequest) { - return formatSizes(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes || []); + return formatSizes(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || []); } function formatSizes(sizes) { diff --git a/test/spec/modules/showheroes-bsBidAdapter_spec.js b/test/spec/modules/showheroes-bsBidAdapter_spec.js index 4f2fd9d641a..9525146a629 100644 --- a/test/spec/modules/showheroes-bsBidAdapter_spec.js +++ b/test/spec/modules/showheroes-bsBidAdapter_spec.js @@ -16,6 +16,23 @@ const gdpr = { } } +const schain = { + 'schain': { + 'validation': 'strict', + 'config': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'some.com', + 'sid': '00001', + 'hp': 1 + } + ] + } + } +} + const bidRequestCommonParams = { 'bidder': 'showheroes-bs', 'params': { @@ -91,8 +108,11 @@ const bidRequestBannerMultiSizes = { } const bidRequestVideoAndBanner = { - ...bidRequestBanner, - ...bidRequestVideo + ...bidRequestCommonParams, + 'mediaTypes': { + ...bidRequestBanner.mediaTypes, + ...bidRequestVideo.mediaTypes + } } describe('shBidAdapter', function () { @@ -131,23 +151,29 @@ describe('shBidAdapter', function () { it('check sizes formats', function () { const request = spec.buildRequests([{ 'params': {}, - 'mediaTypes': {}, - 'sizes': [[640, 480]], + 'mediaTypes': { + 'banner': { + 'sizes': [[320, 240]] + } + }, }], bidderRequest) const payload = request.data.requests[0]; expect(payload).to.be.an('object'); - expect(payload.size).to.have.property('width', 640); - expect(payload.size).to.have.property('height', 480); + expect(payload.size).to.have.property('width', 320); + expect(payload.size).to.have.property('height', 240); const request2 = spec.buildRequests([{ 'params': {}, - 'mediaTypes': {}, - 'sizes': [320, 240], + 'mediaTypes': { + 'video': { + 'playerSize': [640, 360] + } + }, }], bidderRequest) const payload2 = request2.data.requests[0]; expect(payload).to.be.an('object'); - expect(payload2.size).to.have.property('width', 320); - expect(payload2.size).to.have.property('height', 240); + expect(payload2.size).to.have.property('width', 640); + expect(payload2.size).to.have.property('height', 360); }) it('should get size from mediaTypes when sizes property is empty', function () { @@ -245,6 +271,16 @@ describe('shBidAdapter', function () { expect(payload).to.be.an('object'); expect(payload.gdprConsent).to.eql(gdpr.gdprConsent) }) + + it('passes schain object if present', function() { + const request = spec.buildRequests([{ + ...bidRequestVideo, + ...schain + }], bidderRequest) + const payload = request.data.requests[0]; + expect(payload).to.be.an('object'); + expect(payload.schain).to.eql(schain.schain); + }) }) describe('interpretResponse', function () { From 8a35a06d54f7b76dcfd7a03ae05a228479f63eaf Mon Sep 17 00:00:00 2001 From: Vedant Seta Date: Fri, 8 May 2020 13:00:56 +0530 Subject: [PATCH 306/496] Media.net adapter & analytics improvements (#5195) Co-authored-by: vedant.s --- modules/medianetAnalyticsAdapter.js | 44 +++++++++++++++++--- modules/medianetBidAdapter.js | 2 + test/spec/modules/medianetBidAdapter_spec.js | 12 ++++++ 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/modules/medianetAnalyticsAdapter.js b/modules/medianetAnalyticsAdapter.js index 3da69be92eb..d31b62ca2dd 100644 --- a/modules/medianetAnalyticsAdapter.js +++ b/modules/medianetAnalyticsAdapter.js @@ -119,7 +119,7 @@ class Configure { init() { // Forces Logging % to 100% - let urlObj = utils.parseUrl(pageDetails.page); + let urlObj = URL.parseUrl(pageDetails.page); if (utils.deepAccess(urlObj, 'search.medianet_test') || urlObj.hostname === 'localhost') { this.loggingPercent = 100; this.ajaxState = CONFIG_PASS; @@ -143,7 +143,7 @@ class PageDetail { const twitterUrl = this._getUrlFromSelector('meta[name="twitter:url"]', 'content'); const refererInfo = getRefererInfo(); - this.domain = utils.parseUrl(refererInfo.referer).host; + this.domain = URL.parseUrl(refererInfo.referer).host; this.page = refererInfo.referer; this.is_top = refererInfo.reachedTop; this.referrer = this._getTopWindowReferrer(); @@ -208,6 +208,7 @@ class AdSlot { this.adext = adext; this.logged = false; this.targeting = undefined; + this.medianetPresent = 0; } getLoggingData() { @@ -216,7 +217,8 @@ class AdSlot { mediaTypes: this.mediaTypes && this.mediaTypes.join('|'), szs: this.bannerSizes.join('|'), tmax: this.tmax, - targ: JSON.stringify(this.targeting) + targ: JSON.stringify(this.targeting), + ismn: this.medianetPresent }, this.adext && {'adext': JSON.stringify(this.adext)}, ); @@ -259,6 +261,7 @@ class Bid { getLoggingData() { return { + adid: this.adId, pvnm: this.bidder, src: this.src, ogbdp: this.originalCpm, @@ -304,7 +307,8 @@ class Auction { ets: this.auctionEndTime - this.auctionInitTime, tts: this.setTargetingTime - this.auctionInitTime, wts: this.bidWonTime - this.auctionInitTime, - aucstatus: this.status + aucstatus: this.status, + acid: this.acid } } @@ -375,6 +379,7 @@ function bidRequestedHandler({ auctionId, auctionStart, bids, start, timeout, us if (bidder === MEDIANET_BIDDER_CODE) { bidObj.crid = utils.deepAccess(bid, 'params.crid'); bidObj.pubcrid = utils.deepAccess(bid, 'params.crid'); + auctions[auctionId].adSlots[adUnitCode].medianetPresent = 1; } }); } @@ -393,8 +398,9 @@ function bidResponseHandler(bid) { Object.assign( bidObj, { cpm, width, height, mediaType, timeToRespond, dealId, creativeId }, - { adId, currency, originalCpm } + { adId, currency } ); + bidObj.originalCpm = originalCpm || cpm; let dfpbd = utils.deepAccess(bid, 'adserverTargeting.hb_pb'); if (!dfpbd) { let priceGranularity = getPriceGranularity(mediaType, bid); @@ -561,6 +567,34 @@ function firePixel(qs) { utils.triggerPixel(ENDPOINT + '&' + qs); } +class URL { + static parseUrl(url) { + let parsed = document.createElement('a'); + parsed.href = decodeURIComponent(url); + return { + hostname: parsed.hostname, + search: URL.parseQS(parsed.search || ''), + host: parsed.host || window.location.host + }; + } + static parseQS(query) { + return !query ? {} : query + .replace(/^\?/, '') + .split('&') + .reduce((acc, criteria) => { + let [k, v] = criteria.split('='); + if (/\[\]$/.test(k)) { + k = k.replace('[]', ''); + acc[k] = acc[k] || []; + acc[k].push(v); + } else { + acc[k] = v || ''; + } + return acc; + }, {}); + } +} + let medianetAnalytics = Object.assign(adapter({URL, analyticsType}), { getlogsQueue() { return logsQueue; diff --git a/modules/medianetBidAdapter.js b/modules/medianetBidAdapter.js index a7434cac6ab..edc34f8c9c3 100644 --- a/modules/medianetBidAdapter.js +++ b/modules/medianetBidAdapter.js @@ -135,6 +135,7 @@ function extParams(params, gdpr, uspConsent, userId) { let windowSize = spec.getWindowSize(); let gdprApplies = !!(gdpr && gdpr.gdprApplies); let uspApplies = !!(uspConsent); + let coppaApplies = !!(config.getConfig('coppa')); return Object.assign({}, { customer_id: params.cid }, { prebid_version: $$PREBID_GLOBAL$$.version }, @@ -142,6 +143,7 @@ function extParams(params, gdpr, uspConsent, userId) { (gdprApplies) && { gdpr_consent_string: gdpr.consentString || '' }, { usp_applies: uspApplies }, uspApplies && { usp_consent_string: uspConsent || '' }, + {coppa_applies: coppaApplies}, windowSize.w !== -1 && windowSize.h !== -1 && { screen: windowSize }, userId && { user_id: userId } ); diff --git a/test/spec/modules/medianetBidAdapter_spec.js b/test/spec/modules/medianetBidAdapter_spec.js index 22e2b1117d5..cf23bc62655 100644 --- a/test/spec/modules/medianetBidAdapter_spec.js +++ b/test/spec/modules/medianetBidAdapter_spec.js @@ -309,6 +309,7 @@ let VALID_BID_REQUEST = [{ 'prebid_version': $$PREBID_GLOBAL$$.version, 'gdpr_applies': false, 'usp_applies': false, + 'coppa_applies': false, 'screen': { 'w': 1000, 'h': 1000 @@ -393,6 +394,7 @@ let VALID_BID_REQUEST = [{ 'prebid_version': $$PREBID_GLOBAL$$.version, 'gdpr_applies': false, 'usp_applies': false, + 'coppa_applies': false, 'screen': { 'w': 1000, 'h': 1000 @@ -478,6 +480,7 @@ let VALID_BID_REQUEST = [{ 'prebid_version': $$PREBID_GLOBAL$$.version, 'gdpr_applies': false, 'usp_applies': false, + 'coppa_applies': false, 'screen': { 'w': 1000, 'h': 1000 @@ -564,6 +567,7 @@ let VALID_BID_REQUEST = [{ britepoolid: '82efd5e1-816b-4f87-97f8-044f407e2911' }, 'usp_applies': false, + 'coppa_applies': false, 'screen': { 'w': 1000, 'h': 1000 @@ -651,6 +655,7 @@ let VALID_BID_REQUEST = [{ 'prebid_version': $$PREBID_GLOBAL$$.version, 'gdpr_applies': false, 'usp_applies': false, + 'coppa_applies': true, 'screen': { 'w': 1000, 'h': 1000 @@ -992,6 +997,7 @@ let VALID_BID_REQUEST = [{ 'gdpr_consent_string': 'consentString', 'gdpr_applies': true, 'usp_applies': true, + 'coppa_applies': false, 'usp_consent_string': '1NYN', 'screen': { 'w': 1000, @@ -1149,6 +1155,12 @@ describe('Media.net bid adapter', function () { }); it('should have valid crid present in bid request', function() { + sandbox.stub(config, 'getConfig').callsFake((key) => { + const config = { + 'coppa': true + }; + return config[key]; + }); let bidreq = spec.buildRequests(VALID_BID_REQUEST_WITH_CRID, VALID_AUCTIONDATA); expect(JSON.parse(bidreq.data)).to.deep.equal(VALID_PAYLOAD_WITH_CRID); }); From b05b60c9bc1169e78af7cb57771328ee87c2ac82 Mon Sep 17 00:00:00 2001 From: Mike Chowla Date: Fri, 8 May 2020 12:03:07 -0700 Subject: [PATCH 307/496] Prebid 3.19.0 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 75238ca9872..89770d55667 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.19.0-pre", + "version": "3.19.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 1e590902177d57adef519382b59b3d5b0e499800 Mon Sep 17 00:00:00 2001 From: Mike Chowla Date: Fri, 8 May 2020 12:17:03 -0700 Subject: [PATCH 308/496] Increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 89770d55667..ed2d5508dfa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.19.0", + "version": "3.20.0i-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 2dc1125d74f20a9264d0fecf9657994e23c05347 Mon Sep 17 00:00:00 2001 From: Mike Chowla Date: Fri, 8 May 2020 12:18:37 -0700 Subject: [PATCH 309/496] Fix pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ed2d5508dfa..464e1515877 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.20.0i-pre", + "version": "3.20.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From c867e7d10916416f5d072029b62e3743d1affcac Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Mon, 11 May 2020 10:38:13 -0400 Subject: [PATCH 310/496] parrableIdSystem: Consume US Privacy consent data (#5197) * Add unit coverage for parrableIdSystem getId callback * PBID-14: Pass uspString to Parrable as us_privacy query parameter * PBID-14: Simplify parrableIdSystem us_privacy test * PBID-14: Only send us_privacy to Parrable when a value exists * Remove path check from parrableIdSystem url test * Add missing extension to mock xhr import --- modules/parrableIdSystem.js | 12 +++- test/spec/modules/parrableIdSystem_spec.js | 83 +++++++++++++++++++--- 2 files changed, 82 insertions(+), 13 deletions(-) diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js index cc569a79062..ba5fae81952 100644 --- a/modules/parrableIdSystem.js +++ b/modules/parrableIdSystem.js @@ -9,6 +9,7 @@ import * as utils from '../src/utils.js' import { ajax } from '../src/ajax.js'; import { submodule } from '../src/hook.js'; import { getRefererInfo } from '../src/refererDetection.js'; +import { uspDataHandler } from '../src/adapterManager.js'; const PARRABLE_URL = 'https://h.parrable.com/prebid'; @@ -24,10 +25,11 @@ function isValidConfig(configParams) { return true; } -function fetchId(configParams, consentData, currentStoredId) { +function fetchId(configParams, currentStoredId) { if (!isValidConfig(configParams)) return; const refererInfo = getRefererInfo(); + const uspString = uspDataHandler.getConsentData(); const data = { eid: currentStoredId || null, @@ -40,6 +42,10 @@ function fetchId(configParams, consentData, currentStoredId) { _rand: Math.random() }; + if (uspString) { + searchParams.us_privacy = uspString; + } + const options = { method: 'GET', withCredentials: true @@ -88,8 +94,8 @@ export const parrableIdSubmodule = { * @param {ConsentData} [consentData] * @returns {function(callback:function)} */ - getId(configParams, consentData, currentStoredId) { - return fetchId(configParams, consentData, currentStoredId); + getId(configParams, gdprConsentData, currentStoredId) { + return fetchId(configParams, currentStoredId); } }; diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js index 93415126a0a..662f63f6638 100644 --- a/test/spec/modules/parrableIdSystem_spec.js +++ b/test/spec/modules/parrableIdSystem_spec.js @@ -1,15 +1,19 @@ import { expect } from 'chai'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; +import { newStorageManager } from 'src/storageManager.js'; +import { getRefererInfo } from 'src/refererDetection.js'; +import { uspDataHandler } from 'src/adapterManager.js'; import { init, requestBidsHook, setSubmoduleRegistry } from 'modules/userId/index.js'; import { parrableIdSubmodule } from 'modules/parrableIdSystem.js'; -import { newStorageManager } from 'src/storageManager.js'; +import { server } from 'test/mocks/xhr.js'; const storage = newStorageManager(); const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; const P_COOKIE_NAME = '_parrable_eid'; -const P_COOKIE_VALUE = '01.1563917337.test-eid'; +const P_COOKIE_EID = '01.1563917337.test-eid'; +const P_XHR_EID = '01.1588030911.test-new-eid' const P_CONFIG_MOCK = { name: 'parrableId', params: { @@ -31,6 +35,7 @@ describe('Parrable ID System', function() { } } } + function getAdUnitMock(code = 'adUnit-code') { return { code, @@ -46,33 +51,91 @@ describe('Parrable ID System', function() { }; } + describe('parrableIdSystem.getId()', function() { + let callbackSpy = sinon.spy(); + + beforeEach(function() { + callbackSpy.resetHistory(); + }); + + it('returns a callback used to refresh the ID', function() { + let getIdResponse = parrableIdSubmodule.getId( + P_CONFIG_MOCK.params, + null, + P_COOKIE_EID + ); + expect(getIdResponse.callback).to.be.a('function'); + }); + + it('callback creates xhr to Parrable that synchronizes the ID', function() { + let getIdCallback = parrableIdSubmodule.getId( + P_CONFIG_MOCK.params, + null, + P_COOKIE_EID + ).callback; + + getIdCallback(callbackSpy); + + let request = server.requests[0]; + let queryParams = utils.parseQS(request.url.split('?')[1]); + let data = JSON.parse(atob(queryParams.data)); + + expect(request.url).to.contain('h.parrable.com'); + expect(queryParams).to.not.have.property('us_privacy'); + expect(data).to.deep.equal({ + eid: P_COOKIE_EID, + trackers: P_CONFIG_MOCK.params.partner.split(','), + url: getRefererInfo().referer + }); + + server.requests[0].respond(200, + { 'Content-Type': 'text/plain' }, + JSON.stringify({ eid: P_XHR_EID }) + ); + + expect(callbackSpy.calledWith(P_XHR_EID)).to.be.true; + }); + + it('passes the uspString to Parrable', function() { + let uspString = '1YNN'; + uspDataHandler.setConsentData(uspString); + parrableIdSubmodule.getId( + P_CONFIG_MOCK.params, + null, + P_COOKIE_EID + ).callback(callbackSpy); + expect(server.requests[0].url).to.contain('us_privacy=' + uspString); + }); + }); + describe('Parrable ID in Bid Request', function() { let adUnits; beforeEach(function() { adUnits = [getAdUnitMock()]; - }); - - it('should append parrableid to bid request', function(done) { // simulate existing browser local storage values storage.setCookie( P_COOKIE_NAME, - P_COOKIE_VALUE, + P_COOKIE_EID, (new Date(Date.now() + 5000).toUTCString()) ); - setSubmoduleRegistry([parrableIdSubmodule]); init(config); config.setConfig(getConfigMock()); + }); + + afterEach(function() { + storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); + }); + it('provides the parrableid in the bid request', function(done) { requestBidsHook(function() { adUnits.forEach(unit => { unit.bids.forEach(bid => { expect(bid).to.have.deep.nested.property('userId.parrableid'); - expect(bid.userId.parrableid).to.equal(P_COOKIE_VALUE); + expect(bid.userId.parrableid).to.equal(P_COOKIE_EID); }); }); - storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); done(); }, { adUnits }); }); From 42e41a0c06de915e359d60b6571acaf74374a08d Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Mon, 11 May 2020 15:04:09 -0600 Subject: [PATCH 311/496] Rakuten bid adapter (#5191) * add typescript definitions * add rakuten bid adapter * add generated notice * add gdpr and ccpa support to rakuten * add typescript notice * update default rakuten currency to USD * fix folder name rakuten -> rakutenBidAdapter * remove typescript types for now --- gulpHelpers.js | 4 +- modules/rakutenBidAdapter/index.js | 80 +++++++++ modules/rakutenBidAdapter/index.md | 33 ++++ test/spec/modules/rakutenBidAdapter_spec.js | 171 ++++++++++++++++++++ 4 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 modules/rakutenBidAdapter/index.js create mode 100644 modules/rakutenBidAdapter/index.md create mode 100644 test/spec/modules/rakutenBidAdapter_spec.js diff --git a/gulpHelpers.js b/gulpHelpers.js index aabd28ced02..bcaf3736f15 100644 --- a/gulpHelpers.js +++ b/gulpHelpers.js @@ -84,7 +84,9 @@ module.exports = { if (fs.lstatSync(modulePath).isDirectory()) { modulePath = path.join(modulePath, 'index.js') } - memo[modulePath] = moduleName; + if (fs.existsSync(modulePath)) { + memo[modulePath] = moduleName; + } return memo; }, {}); } catch (err) { diff --git a/modules/rakutenBidAdapter/index.js b/modules/rakutenBidAdapter/index.js new file mode 100644 index 00000000000..e567509b3c1 --- /dev/null +++ b/modules/rakutenBidAdapter/index.js @@ -0,0 +1,80 @@ +import { registerBidder } from '../../src/adapters/bidderFactory.js'; +import { BANNER } from '../../src/mediaTypes.js'; +import { config } from '../../src/config.js'; +const BIDDER_CODE = 'rakuten'; +const ENDPOINT = 'https://s-bid.rmp.rakuten.com/h'; +export const spec = { + code: BIDDER_CODE, + isBidRequestValid: bid => !!bid.params.adSpotId, + buildRequests: (validBidRequests, bidderRequest) => { + const bidRequests = []; + validBidRequests.forEach(bid => { + var _a, _b; + const params = bid.params; + bidRequests.push({ + method: 'GET', + url: config.getConfig('rakuten.endpoint') || ENDPOINT, + data: { + bi: bid.bidId, + t: params.adSpotId, + s: document.location.protocol, + ua: navigator.userAgent, + l: navigator.browserLanguage || + navigator.language, + d: document.domain, + tp: bidderRequest.refererInfo.stack[0] || window.location.href, + pp: bidderRequest.refererInfo.referer, + gdpr: ((_a = bidderRequest.gdprConsent) === null || _a === void 0 ? void 0 : _a.gdprApplies) ? 1 : 0, + ...((_b = bidderRequest.gdprConsent) === null || _b === void 0 ? void 0 : _b.consentString) && { + cd: bidderRequest.gdprConsent.consentString + }, + ...bidderRequest.uspConsent && { + ccpa: bidderRequest.uspConsent + } + } + }); + }); + return bidRequests; + }, + interpretResponse: (response, request) => { + const sb = response.body; + const bidResponses = []; + if (sb.cpm && sb.ad) { + bidResponses.push({ + requestId: sb.bid_id, + cpm: sb.cpm, + width: sb.width || 0, + height: sb.height || 0, + creativeId: sb.creative_id || 0, + dealId: sb.deal_id || '', + currency: sb.currency || 'USD', + netRevenue: (typeof sb.net_revenue === 'undefined') ? true : !!sb.net_revenue, + mediaType: BANNER, + ttl: sb.ttl, + ad: sb.ad + }); + } + return bidResponses; + }, + getUserSyncs: function (syncOptions, serverResponses) { + const syncs = []; + if (syncOptions.pixelEnabled && serverResponses[0].body !== undefined) { + const bidResponseObj = serverResponses[0].body; + if (!bidResponseObj) { + return []; + } + if (bidResponseObj.sync_urls && bidResponseObj.sync_urls.length > 0) { + bidResponseObj.sync_urls.forEach(syncUrl => { + if (syncUrl && syncUrl !== 'null' && syncUrl.length > 0) { + syncs.push({ + type: 'image', + url: syncUrl + }); + } + }); + } + } + return syncs; + } +}; +registerBidder(spec); diff --git a/modules/rakutenBidAdapter/index.md b/modules/rakutenBidAdapter/index.md new file mode 100644 index 00000000000..cc6aa68151d --- /dev/null +++ b/modules/rakutenBidAdapter/index.md @@ -0,0 +1,33 @@ +# Overview + +``` +Module Name: Rakuten Bidder Adapter +Module Type: Bidder Adapter +Maintainer: @snapwich +``` + +# Description + +Bid adapter for Rakuten RSSP + +Rakuten bid adapter supports Banner currently. + +# Test Parameters + +``` + var adUnits = [ + { + code: 'test-ad-div', + sizes: [[300, 250]], + mediaTypes: {banner: {}}, + bids: [ + { + bidder: 'rakuten', + params: { + adSpotId: 42 + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/rakutenBidAdapter_spec.js b/test/spec/modules/rakutenBidAdapter_spec.js new file mode 100644 index 00000000000..15b22afbe29 --- /dev/null +++ b/test/spec/modules/rakutenBidAdapter_spec.js @@ -0,0 +1,171 @@ +import { expect } from 'chai' +import { spec } from 'modules/rakutenBidAdapter/index.js' +import { newBidder } from 'src/adapters/bidderFactory.js' +import {config} from '../../../src/config.js'; + +describe('rakutenBidAdapter', function() { + const adapter = newBidder(spec); + const ENDPOINT = 'https://s-bid.rmp.rakuten.com/h'; + let sandbox; + + beforeEach(function() { + config.resetConfig(); + }); + + afterEach(function () { + config.resetConfig(); + }); + + describe('inherited functions', () => { + it('exists and is a function', () => { + expect(adapter.callBids).to.exist.and.to.be.a('function') + }) + }); + + describe('isBidRequestValid', () => { + let bid = { + bidder: 'rakuten', + params: { + adSpotId: '56789' + } + }; + + it('should return true when required params found', () => { + expect(spec.isBidRequestValid(bid)).to.equal(true) + }); + + it('should return false when required params are not passed', () => { + bid.params.adSpotId = ''; + expect(spec.isBidRequestValid(bid)).to.equal(false) + }); + + it('should return false when required params are not passed', () => { + let bid = Object.assign({}, bid); + delete bid.params; + bid.params = {}; + expect(spec.isBidRequestValid(bid)).to.equal(false) + }) + }); + + describe('buildRequests', () => { + const bidRequests = [ + { + // banner + params: { + adSpotId: '58278' + } + } + ]; + + const bidderRequest = { + bids: bidRequests, + refererInfo: { + referer: 'http://test.com', + stack: ['http://test.com'] + }, + gdprConsent: { + consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', + vendorData: {}, + gdprApplies: true + }, + uspConsent: '1YN-' + }; + + it('sends bid request to ENDPOINT via GET', () => { + const request = spec.buildRequests(bidRequests, bidderRequest)[0]; + expect(request.url).to.equal(ENDPOINT); + expect(request.method).to.equal('GET') + expect(request.data.gdpr).to.equal(1); + expect(request.data.cd).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); + expect(request.data.ccpa).to.equal('1YN-'); + }); + + it('allows url override', () => { + config.setConfig({ + rakuten: { + endpoint: '//test.rakuten.com' + } + }); + const request = spec.buildRequests(bidRequests, bidderRequest)[0]; + expect(request.url).to.equal('//test.rakuten.com'); + }) + }); + + describe('interpretResponse', () => { + const bidRequests = { + banner: { + method: 'GET', + url: '', + data: { + t: '56789', + s: 'https', + ua: + 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Mobile Safari/537.36', + l: 'ja', + d: 'examples.com', + tp: 'https://examples.com/foo/fuga', + pp: 'https://examples.com/hoge/muga' + } + } + }; + + const serverResponse = { + noAd: [], + noAd2: { + requestId: 'biequa9oaph4we' + }, + banner: { + requestId: 'biequa9oaph4we', + cpm: 37.66, + width: 300, + height: 250, + creativeId: 140281, + dealId: 'phoh3pad-ai4ah-xoh7x-ahk7cheasae3oh', + currency: 'USD', + netRevenue: 300, + ttl: 3000, + ad: '' + } + }; + + it('handles nobid responses', () => { + const result = spec.interpretResponse( + { body: serverResponse.noAd }, + bidRequests.banner + ); + expect(result.length).to.equal(0); + + const result2 = spec.interpretResponse( + { body: serverResponse.noAd2 }, + bidRequests.banner + ); + expect(result2.length).to.equal(0); + }) + }); + describe('spec.getUserSyncs', function () { + const syncResponse = [{ + body: { + request_id: 'biequa9oaph4we', + sync_urls: ['https://rdn1.test/sync?uid=9876543210', 'https://rdn2.test/sync?uid=9876543210'] + } + }]; + const nosyncResponse = [{ + body: { + request_id: 'biequa9oaph4we', + sync_urls: [] + } + }]; + let syncOptions + beforeEach(function () { + syncOptions = { + pixelEnabled: true + } + }); + it('sucess usersync url', function () { + const result = []; + result.push({type: 'image', url: 'https://rdn1.test/sync?uid=9876543210'}); + result.push({type: 'image', url: 'https://rdn2.test/sync?uid=9876543210'}); + expect(spec.getUserSyncs(syncOptions, syncResponse)).to.deep.equal(result); + }); + }); +}); From 004440e607aacfc72eb4de3e085e8e427b213a5a Mon Sep 17 00:00:00 2001 From: xwang202 <57196235+xwang202@users.noreply.github.com> Date: Thu, 14 May 2020 18:18:06 +0800 Subject: [PATCH 312/496] Freewheel add dealId property in bidResponse (#5200) * freewheel-ssp fix issue on playerSize of bidRequest * freewheel-ssp fix issue on playerSize of bidRequest * freewheel add dealId property in bidResponse --- modules/freewheel-sspBidAdapter.js | 22 ++++++++++++++++++- .../modules/freewheel-sspBidAdapter_spec.js | 12 ++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/modules/freewheel-sspBidAdapter.js b/modules/freewheel-sspBidAdapter.js index 34724658631..e1db7d5e1d3 100644 --- a/modules/freewheel-sspBidAdapter.js +++ b/modules/freewheel-sspBidAdapter.js @@ -102,6 +102,24 @@ function getCreativeId(xmlNode) { return creaId; } +function getDealId(xmlNode) { + var dealId = ''; + var impNodes = xmlNode.querySelectorAll('Impression'); // Nodelist.forEach is not supported in IE and Edge + // Workaround given here https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10638731/ + + Array.prototype.forEach.call(impNodes, function (el) { + var queries = el.textContent.substring(el.textContent.indexOf('?') + 1).split('&'); + Array.prototype.forEach.call(queries, function (item) { + var split = item.split('='); + if (split[0] == 'dealId') { + dealId = split[1]; + } + }); + }); + + return dealId; +} + /** * returns the top most accessible window */ @@ -353,6 +371,7 @@ export const spec = { const princingData = getPricing(xmlDoc); const creativeId = getCreativeId(xmlDoc); + const dealId = getDealId(xmlDoc); const topWin = getTopMostWindow(); if (!topWin.freewheelssp_cache) { @@ -371,7 +390,8 @@ export const spec = { creativeId: creativeId, currency: princingData.currency, netRevenue: true, - ttl: 360 + ttl: 360, + dealId: dealId }; if (bidrequest.mediaTypes.video) { diff --git a/test/spec/modules/freewheel-sspBidAdapter_spec.js b/test/spec/modules/freewheel-sspBidAdapter_spec.js index 4b80cce8017..ffb9f1fe431 100644 --- a/test/spec/modules/freewheel-sspBidAdapter_spec.js +++ b/test/spec/modules/freewheel-sspBidAdapter_spec.js @@ -290,6 +290,8 @@ describe('freewheelSSP BidAdapter Test', () => { '' + ' ' + ' Adswizz' + + ' ' + + ' https://ads.stickyadstv.com/auto-user-sync?dealId=NRJ-PRO-00008' + ' ' + ' ' + ' ' + @@ -323,12 +325,14 @@ describe('freewheelSSP BidAdapter Test', () => { currency: 'EUR', netRevenue: true, ttl: 360, + dealId: 'NRJ-PRO-00008', ad: ad } ]; let result = spec.interpretResponse(response, request[0]); expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); + expect(result[0].dealId).to.equal('NRJ-PRO-00008'); }); it('should get correct bid response with formated ad', () => { @@ -344,12 +348,14 @@ describe('freewheelSSP BidAdapter Test', () => { currency: 'EUR', netRevenue: true, ttl: 360, + dealId: 'NRJ-PRO-00008', ad: formattedAd } ]; let result = spec.interpretResponse(response, request[0]); expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); + expect(result[0].dealId).to.equal('NRJ-PRO-00008'); }); it('handles nobid responses', () => { @@ -421,6 +427,8 @@ describe('freewheelSSP BidAdapter Test', () => { '' + ' ' + ' Adswizz' + + ' ' + + ' https://ads.stickyadstv.com/auto-user-sync?dealId=NRJ-PRO-00008' + ' ' + ' ' + ' ' + @@ -454,6 +462,7 @@ describe('freewheelSSP BidAdapter Test', () => { currency: 'EUR', netRevenue: true, ttl: 360, + dealId: 'NRJ-PRO-00008', vastXml: response, mediaType: 'video', ad: ad @@ -462,6 +471,7 @@ describe('freewheelSSP BidAdapter Test', () => { let result = spec.interpretResponse(response, request[0]); expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); + expect(result[0].dealId).to.equal('NRJ-PRO-00008'); }); it('should get correct bid response with formated ad', () => { @@ -477,6 +487,7 @@ describe('freewheelSSP BidAdapter Test', () => { currency: 'EUR', netRevenue: true, ttl: 360, + dealId: 'NRJ-PRO-00008', vastXml: response, mediaType: 'video', ad: formattedAd @@ -485,6 +496,7 @@ describe('freewheelSSP BidAdapter Test', () => { let result = spec.interpretResponse(response, request[0]); expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); + expect(result[0].dealId).to.equal('NRJ-PRO-00008'); }); it('handles nobid responses', () => { From 18cf2f75d69d7fa19a26ddc1b808a9c16f7a3205 Mon Sep 17 00:00:00 2001 From: Dylan Hrebenach Date: Thu, 14 May 2020 05:00:36 -0700 Subject: [PATCH 313/496] updating ttl variable in underdogmediaBidAdapter.js (#5220) --- modules/underdogmediaBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/underdogmediaBidAdapter.js b/modules/underdogmediaBidAdapter.js index d6ccafe7174..8368077a627 100644 --- a/modules/underdogmediaBidAdapter.js +++ b/modules/underdogmediaBidAdapter.js @@ -119,7 +119,7 @@ export const spec = { creativeId: mid.mid, currency: 'USD', netRevenue: false, - ttl: config.getConfig('_bidderTimeout'), + ttl: mid.ttl || 60, }; if (bidResponse.cpm <= 0) { From 810737312a7feb3572c9f8c016494a72fbe0fae5 Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Thu, 14 May 2020 09:29:46 -0700 Subject: [PATCH 314/496] Gdpr vendor exceptions (#5201) * vendorExceptions is a global check * two allowed vars not one duh --- modules/gdprEnforcement.js | 50 ++++++-------------------------------- 1 file changed, 8 insertions(+), 42 deletions(-) diff --git a/modules/gdprEnforcement.js b/modules/gdprEnforcement.js index e42e55be557..4818bbf8ec9 100644 --- a/modules/gdprEnforcement.js +++ b/modules/gdprEnforcement.js @@ -36,49 +36,15 @@ function getGvlid() { * @returns {boolean} */ function validateRules(rule, consentData, currentModule, gvlid) { - let isAllowed = false; - if (!rule.vendorExceptions) rule.vendorExceptions = []; - if (rule.enforcePurpose && rule.enforceVendor) { - if ( - includes(rule.vendorExceptions, currentModule) || - ( - utils.deepAccess(consentData, 'vendorData.purpose.consents.1') === true && - utils.deepAccess(consentData, `vendorData.vendor.consents.${gvlid}`) === true - ) - ) { - isAllowed = true; - } - } else if (rule.enforcePurpose === false && rule.enforceVendor === true) { - if ( - includes(rule.vendorExceptions, currentModule) || - ( - utils.deepAccess(consentData, `vendorData.vendor.consents.${gvlid}`) === true - ) - ) { - isAllowed = true; - } - } else if (rule.enforcePurpose === false && rule.enforceVendor === false) { - if ( - !includes(rule.vendorExceptions, currentModule) || - ( - (utils.deepAccess(consentData, 'vendorData.purpose.consents.1') === true) && - (utils.deepAccess(consentData, `vendorData.vendor.consents.${gvlid}`) === true) - ) - ) { - isAllowed = true; - } - } else if (rule.enforcePurpose === true && rule.enforceVendor === false) { - if ( - (utils.deepAccess(consentData, 'vendorData.purpose.consents.1') === true) && - ( - !includes(rule.vendorExceptions, currentModule) || - (utils.deepAccess(consentData, `vendorData.vendor.consents.${gvlid}`) === true) - ) - ) { - isAllowed = true; - } + // if vendor has exception => always true + if (includes(rule.vendorExceptions || [], currentModule)) { + return true; } - return isAllowed; + // if enforcePurpose is false or purpose was granted isAllowed is true, otherwise false + const purposeAllowed = rule.enforcePurpose === false || utils.deepAccess(consentData, 'vendorData.purpose.consents.1') === true; + // if enforceVendor is false or vendor was granted isAllowed is true, otherwise false + const vendorAllowed = rule.enforceVendor === false || utils.deepAccess(consentData, `vendorData.vendor.consents.${gvlid}`) === true; + return purposeAllowed && vendorAllowed; } /** From 2fe9d786d8af2d32e86bf5793df67087dfafb37b Mon Sep 17 00:00:00 2001 From: msm0504 <51493331+msm0504@users.noreply.github.com> Date: Thu, 14 May 2020 12:45:58 -0400 Subject: [PATCH 315/496] PBJS RP adapter: pass integration type into video calls (#5231) * Add microadBidAdapter * Remove unnecessary encodeURIComponent from microadBidAdapter * Submit Advangelists Prebid Adapter * Submit Advangelists Prebid Adapter 1.1 * Correct procudtion endpoint for prebid * analytics update with wrapper name * reverted error merge * update changed default value of netRevenue to true * Re-add rubicon analytics without deprecated getTopWindowUrl util * Cache referrer on auction_init instead of bid_requested * merged remote master changes * Include integration type in video OpenRTB requests Co-authored-by: nakamoto Co-authored-by: Chandra Prakash Co-authored-by: Isaac Dettman Co-authored-by: Eric Harper Co-authored-by: TJ Eastmond Co-authored-by: Mark Monday --- modules/rubiconBidAdapter.js | 6 ++++++ test/spec/modules/rubiconBidAdapter_spec.js | 22 +++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index 9131a8cb581..3c17f609a37 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -4,6 +4,7 @@ import {config} from '../src/config.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; const DEFAULT_INTEGRATION = 'pbjs_lite'; +const DEFAULT_PBS_INTEGRATION = 'pbjs'; // always use https, regardless of whether or not current page is secure export const FASTLANE_ENDPOINT = 'https://fastlane.rubiconproject.com/a/api/fastlane.json'; @@ -182,6 +183,11 @@ export const spec = { // includebidderkeys always false for openrtb includebidderkeys: false, pricegranularity: getPriceGranularity(config) + }, + bidders: { + rubicon: { + integration: config.getConfig('rubicon.int_type') || DEFAULT_PBS_INTEGRATION + } } } } diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index bfc8de0f20d..99928b41d7b 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -7,6 +7,7 @@ import * as utils from 'src/utils.js'; import find from 'core-js-pure/features/array/find.js'; const INTEGRATION = `pbjs_lite_v$prebid.version$`; // $prebid.version$ will be substituted in by gulp in built prebid +const PBS_INTEGRATION = 'pbjs'; describe('the rubicon adapter', function () { let sandbox, @@ -1478,10 +1479,11 @@ describe('the rubicon adapter', function () { expect(post.regs.ext.us_privacy).to.equal('1NYN'); expect(post).to.have.property('ext').that.is.an('object'); expect(post.ext.prebid.targeting.includewinners).to.equal(true); - expect(post.ext.prebid).to.have.property('cache').that.is.an('object') - expect(post.ext.prebid.cache).to.have.property('vastxml').that.is.an('object') - expect(post.ext.prebid.cache.vastxml).to.have.property('returnCreative').that.is.an('boolean') - expect(post.ext.prebid.cache.vastxml.returnCreative).to.equal(false) + expect(post.ext.prebid).to.have.property('cache').that.is.an('object'); + expect(post.ext.prebid.cache).to.have.property('vastxml').that.is.an('object'); + expect(post.ext.prebid.cache.vastxml).to.have.property('returnCreative').that.is.an('boolean'); + expect(post.ext.prebid.cache.vastxml.returnCreative).to.equal(false); + expect(post.ext.prebid.bidders.rubicon.integration).to.equal(PBS_INTEGRATION); }); it('should correctly set bidfloor on imp when getfloor in scope', function () { @@ -1839,6 +1841,18 @@ describe('the rubicon adapter', function () { const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); expect(request.data.imp[0].ext.context.data.adslot).to.equal('1234567890'); }); + + it('should use the integration type provided in the config instead of the default', () => { + createVideoBidderRequest(); + sandbox.stub(config, 'getConfig').callsFake(function (key) { + const config = { + 'rubicon.int_type': 'testType' + }; + return config[key]; + }); + const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); + expect(request.data.ext.prebid.bidders.rubicon.integration).to.equal('testType'); + }); }); it('should include pbAdSlot in bid request', function () { From 0d40c28e7965f3b7fb65fe1bfb0fff1776430671 Mon Sep 17 00:00:00 2001 From: oasis <2394426+bmwcmw@users.noreply.github.com> Date: Thu, 14 May 2020 20:57:00 +0200 Subject: [PATCH 316/496] Use default native size if received size is undefined (#5192) Co-authored-by: mi.chen --- modules/criteoBidAdapter.js | 36 +++++++------- test/spec/modules/criteoBidAdapter_spec.js | 56 ++++++++++++++++++++++ 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js index ae48b9664fb..17277ca0fb2 100644 --- a/modules/criteoBidAdapter.js +++ b/modules/criteoBidAdapter.js @@ -1,14 +1,14 @@ -import { loadExternalScript } from '../src/adloader.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import {loadExternalScript} from '../src/adloader.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {config} from '../src/config.js'; +import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; import * as utils from '../src/utils.js'; import find from 'core-js-pure/features/array/find.js'; import { verify } from 'criteo-direct-rsa-validate/build/verify.js'; import { getStorageManager } from '../src/storageManager.js'; const GVLID = 91; -export const ADAPTER_VERSION = 29; +export const ADAPTER_VERSION = 31; const BIDDER_CODE = 'criteo'; const CDB_ENDPOINT = 'https://bidder.criteo.com/cdb'; const PROFILE_ID_INLINE = 207; @@ -274,7 +274,6 @@ function buildCdbRequest(context, bidRequests, bidderRequest) { impid: bidRequest.adUnitCode, transactionid: bidRequest.transactionId, auctionId: bidRequest.auctionId, - sizes: getBannerSizes(bidRequest), }; if (bidRequest.params.zoneId) { slot.zoneid = bidRequest.params.zoneId; @@ -293,10 +292,13 @@ function buildCdbRequest(context, bidRequests, bidderRequest) { if (!checkNativeSendId(bidRequest)) { utils.logWarn(LOG_PREFIX + 'all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)'); } + slot.sizes = parseSizes(retrieveBannerSizes(bidRequest), parseNativeSize); + } else { + slot.sizes = parseSizes(retrieveBannerSizes(bidRequest), parseSize); } if (hasVideoMediaType(bidRequest)) { const video = { - playersizes: getVideoSizes(bidRequest), + playersizes: parseSizes(utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'), parseSize), mimes: bidRequest.mediaTypes.video.mimes, protocols: bidRequest.mediaTypes.video.protocols, maxduration: bidRequest.mediaTypes.video.maxduration, @@ -339,24 +341,26 @@ function buildCdbRequest(context, bidRequests, bidderRequest) { return request; } -function getVideoSizes(bidRequest) { - return parseSizes(utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize')); +function retrieveBannerSizes(bidRequest) { + return utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes; } -function getBannerSizes(bidRequest) { - return parseSizes(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes); +function parseSizes(sizes, parser) { + if (Array.isArray(sizes[0])) { // is there several sizes ? (ie. [[728,90],[200,300]]) + return sizes.map(size => parser(size)); + } + return [parser(sizes)]; // or a single one ? (ie. [728,90]) } function parseSize(size) { return size[0] + 'x' + size[1]; } -function parseSizes(sizes) { - if (Array.isArray(sizes[0])) { // is there several sizes ? (ie. [[728,90],[200,300]]) - return sizes.map(size => parseSize(size)); +function parseNativeSize(size) { + if (size[0] === undefined && size[1] === undefined) { + return '2x2'; } - - return [parseSize(sizes)]; // or a single one ? (ie. [728,90]) + return size[0] + 'x' + size[1]; } function hasVideoMediaType(bidRequest) { diff --git a/test/spec/modules/criteoBidAdapter_spec.js b/test/spec/modules/criteoBidAdapter_spec.js index 042f1a4d61d..6ab0159e901 100755 --- a/test/spec/modules/criteoBidAdapter_spec.js +++ b/test/spec/modules/criteoBidAdapter_spec.js @@ -440,6 +440,62 @@ describe('The Criteo bidding adapter', function () { expect(ortbRequest.gdprConsent.version).to.equal(1); }); + it('should keep undefined sizes for non native banner', function () { + const bidRequests = [ + { + sizes: [[undefined, undefined]], + params: {}, + }, + ]; + const request = spec.buildRequests(bidRequests, bidderRequest); + const ortbRequest = request.data; + expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1); + expect(ortbRequest.slots[0].sizes[0]).to.equal('undefinedxundefined'); + }); + + it('should keep undefined size for non native banner', function () { + const bidRequests = [ + { + sizes: [undefined, undefined], + params: {}, + }, + ]; + const request = spec.buildRequests(bidRequests, bidderRequest); + const ortbRequest = request.data; + expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1); + expect(ortbRequest.slots[0].sizes[0]).to.equal('undefinedxundefined'); + }); + + it('should properly detect and get sizes of native sizeless banner', function () { + const bidRequests = [ + { + sizes: [[undefined, undefined]], + params: { + nativeCallback: function() {} + }, + }, + ]; + const request = spec.buildRequests(bidRequests, bidderRequest); + const ortbRequest = request.data; + expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1); + expect(ortbRequest.slots[0].sizes[0]).to.equal('2x2'); + }); + + it('should properly detect and get size of native sizeless banner', function () { + const bidRequests = [ + { + sizes: [undefined, undefined], + params: { + nativeCallback: function() {} + }, + }, + ]; + const request = spec.buildRequests(bidRequests, bidderRequest); + const ortbRequest = request.data; + expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1); + expect(ortbRequest.slots[0].sizes[0]).to.equal('2x2'); + }); + it('should properly build a networkId request', function () { const bidderRequest = { refererInfo: { From 09314590f3ded44027186179887635f974e58c4c Mon Sep 17 00:00:00 2001 From: Trendqube-ssp <65278311+Trendqube-ssp@users.noreply.github.com> Date: Fri, 15 May 2020 13:43:07 +0300 Subject: [PATCH 317/496] New adapter - Trendqube (#5225) Co-authored-by: Aigolkin1991 --- modules/trendqubeBidAdapter.js | 102 +++++++ modules/trendqubeBidAdapter.md | 53 ++++ test/spec/modules/trendqubeBidAdapter_spec.js | 270 ++++++++++++++++++ 3 files changed, 425 insertions(+) create mode 100644 modules/trendqubeBidAdapter.js create mode 100644 modules/trendqubeBidAdapter.md create mode 100644 test/spec/modules/trendqubeBidAdapter_spec.js diff --git a/modules/trendqubeBidAdapter.js b/modules/trendqubeBidAdapter.js new file mode 100644 index 00000000000..d0364b4acec --- /dev/null +++ b/modules/trendqubeBidAdapter.js @@ -0,0 +1,102 @@ +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; + +const BIDDER_CODE = 'trendqube'; +const AD_URL = 'https://ads.trendqube.com/?c=o&m=multi'; + +function isBidResponseValid(bid) { + if (!bid.requestId || !bid.cpm || !bid.creativeId || + !bid.ttl || !bid.currency) { + return false; + } + switch (bid.mediaType) { + case BANNER: + return Boolean(bid.width && bid.height && bid.ad); + case VIDEO: + return Boolean(bid.vastUrl); + case NATIVE: + return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); + default: + return false; + } +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid: (bid) => { + return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId))); + }, + + buildRequests: (validBidRequests = [], bidderRequest) => { + let winTop = window; + let location; + try { + location = new URL(bidderRequest.refererInfo.referer) + winTop = window.top; + } catch (e) { + location = winTop.location; + utils.logMessage(e); + }; + let placements = []; + let request = { + 'deviceWidth': winTop.screen.width, + 'deviceHeight': winTop.screen.height, + 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', + 'secure': 1, + 'host': location.host, + 'page': location.pathname, + 'placements': placements + }; + if (bidderRequest) { + if (bidderRequest.uspConsent) { + request.ccpa = bidderRequest.uspConsent; + } + if (bidderRequest.gdprConsent) { + request.gdpr = bidderRequest.gdprConsent + } + } + const len = validBidRequests.length; + + for (let i = 0; i < len; i++) { + let bid = validBidRequests[i]; + let sizes + if (bid.mediaTypes) { + if (bid.mediaTypes[BANNER] && bid.mediaTypes[BANNER].sizes) { + sizes = bid.mediaTypes[BANNER].sizes + } else if (bid.mediaTypes[VIDEO] && bid.mediaTypes[VIDEO].playerSize) { + sizes = bid.mediaTypes[VIDEO].playerSize + } + } + placements.push({ + placementId: bid.params.placementId, + bidId: bid.bidId, + sizes: sizes || [], + wPlayer: sizes ? sizes[0] : 0, + hPlayer: sizes ? sizes[1] : 0, + traffic: bid.params.traffic || BANNER, + schain: bid.schain || {} + }); + } + return { + method: 'POST', + url: AD_URL, + data: request + }; + }, + + interpretResponse: (serverResponse) => { + let response = []; + for (let i = 0; i < serverResponse.body.length; i++) { + let resItem = serverResponse.body[i]; + if (isBidResponseValid(resItem)) { + response.push(resItem); + } + } + return response; + }, +}; + +registerBidder(spec); diff --git a/modules/trendqubeBidAdapter.md b/modules/trendqubeBidAdapter.md new file mode 100644 index 00000000000..8b72c225575 --- /dev/null +++ b/modules/trendqubeBidAdapter.md @@ -0,0 +1,53 @@ +# Overview + +``` +Module Name: trendqube Bidder Adapter +Module Type: trendqube Bidder Adapter +``` + +# Description + +Module that connects to trendqube demand sources + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'placementId_0', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [ + { + bidder: 'trendqube', + params: { + placementId: 0, + traffic: 'banner' + } + } + ] + }, + // Will return test vast xml. All video params are stored under placement in publishers UI + { + code: 'placementId_0', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream' + } + }, + bids: [ + { + bidder: 'trendqube', + params: { + placementId: 0, + traffic: 'video' + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/trendqubeBidAdapter_spec.js b/test/spec/modules/trendqubeBidAdapter_spec.js new file mode 100644 index 00000000000..f2ce95832ff --- /dev/null +++ b/test/spec/modules/trendqubeBidAdapter_spec.js @@ -0,0 +1,270 @@ +import {expect} from 'chai'; +import {spec} from '../../../modules/trendqubeBidAdapter.js'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; + +describe('TrendqubebBidAdapter', function () { + const bid = { + bidId: '23fhj33i987f', + bidder: 'trendqube', + params: { + placementId: 0, + traffic: BANNER + } + }; + + const bidderRequest = { + refererInfo: { + referer: 'test.com' + } + }; + + describe('isBidRequestValid', function () { + it('Should return true if there are bidId, params and placementId parameters present', function () { + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + it('Should return false if at least one of parameters is not present', function () { + delete bid.params.placementId; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests([bid], bidderRequest); + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + it('Returns valid URL', function () { + expect(serverRequest.url).to.equal('https://ads.trendqube.com/?c=o&m=multi'); + }); + it('Returns valid data if array of bids is valid', function () { + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.language).to.be.a('string'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + expect(data.gdpr).to.not.exist; + expect(data.ccpa).to.not.exist; + let placement = data['placements'][0]; + expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes', 'hPlayer', 'wPlayer', 'schain'); + expect(placement.placementId).to.equal(0); + expect(placement.bidId).to.equal('23fhj33i987f'); + expect(placement.traffic).to.equal(BANNER); + expect(placement.schain).to.be.an('object'); + }); + + it('Returns valid data for mediatype video', function () { + const playerSize = [300, 300]; + bid.mediaTypes = {}; + bid.params.traffic = VIDEO; + bid.mediaTypes[VIDEO] = { + playerSize + }; + serverRequest = spec.buildRequests([bid], bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + let placement = data['placements'][0]; + expect(placement).to.be.an('object'); + expect(placement.traffic).to.equal(VIDEO); + expect(placement.wPlayer).to.equal(playerSize[0]); + expect(placement.hPlayer).to.equal(playerSize[1]); + }); + + it('Returns data with gdprConsent and without uspConsent', function () { + bidderRequest.gdprConsent = 'test'; + serverRequest = spec.buildRequests([bid], bidderRequest); + let data = serverRequest.data; + expect(data.gdpr).to.exist; + expect(data.gdpr).to.be.a('string'); + expect(data.gdpr).to.equal(bidderRequest.gdprConsent); + expect(data.ccpa).to.not.exist; + delete bidderRequest.gdprConsent; + }); + + it('Returns data with uspConsent and without gdprConsent', function () { + bidderRequest.uspConsent = 'test'; + serverRequest = spec.buildRequests([bid], bidderRequest); + let data = serverRequest.data; + expect(data.ccpa).to.exist; + expect(data.ccpa).to.be.a('string'); + expect(data.ccpa).to.equal(bidderRequest.uspConsent); + expect(data.gdpr).to.not.exist; + }); + + it('Returns empty data if no valid requests are passed', function () { + serverRequest = spec.buildRequests([]); + let data = serverRequest.data; + expect(data.placements).to.be.an('array').that.is.empty; + }); + }); + describe('interpretResponse', function () { + it('Should interpret banner response', function () { + const banner = { + body: [{ + mediaType: 'banner', + width: 300, + height: 250, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let bannerResponses = spec.interpretResponse(banner); + expect(bannerResponses).to.be.an('array').that.is.not.empty; + let dataItem = bannerResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.width).to.equal(300); + expect(dataItem.height).to.equal(250); + expect(dataItem.ad).to.equal('Test'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret video response', function () { + const video = { + body: [{ + vastUrl: 'test.com', + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let videoResponses = spec.interpretResponse(video); + expect(videoResponses).to.be.an('array').that.is.not.empty; + + let dataItem = videoResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.5); + expect(dataItem.vastUrl).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should interpret native response', function () { + const native = { + body: [{ + mediaType: 'native', + native: { + clickUrl: 'test.com', + title: 'Test', + image: 'test.com', + impressionTrackers: ['test.com'], + }, + ttl: 120, + cpm: 0.4, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let nativeResponses = spec.interpretResponse(native); + expect(nativeResponses).to.be.an('array').that.is.not.empty; + + let dataItem = nativeResponses[0]; + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); + expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.native.clickUrl).to.equal('test.com'); + expect(dataItem.native.title).to.equal('Test'); + expect(dataItem.native.image).to.equal('test.com'); + expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; + expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + }); + it('Should return an empty array if invalid banner response is passed', function () { + const invBanner = { + body: [{ + width: 300, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + + let serverResponses = spec.interpretResponse(invBanner); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid video response is passed', function () { + const invVideo = { + body: [{ + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invVideo); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid native response is passed', function () { + const invNative = { + body: [{ + mediaType: 'native', + clickUrl: 'test.com', + title: 'Test', + impressionTrackers: ['test.com'], + ttl: 120, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + let serverResponses = spec.interpretResponse(invNative); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid response is passed', function () { + const invalid = { + body: [{ + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + let serverResponses = spec.interpretResponse(invalid); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); +}); From 3737fc41e7195d69995c53027d490041c03646d1 Mon Sep 17 00:00:00 2001 From: Jeremy Blencowe Date: Fri, 15 May 2020 12:43:21 -0700 Subject: [PATCH 318/496] Roll back breaking change to utils.parseQueryStringParameters (#5230) * Add AOL defaults for currency and creative ID until fix issued server-side * Satisfy linter single quotes * Roll back breaking change to utils.parseQueryStringParameters and add a better test to catch this in future * utils.parseQueryStringParameters - add stripping of trailing ampersand to alleviate all tests amended in utils update --- src/utils.js | 9 ++++++++- test/spec/utils_spec.js | 6 +++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/utils.js b/src/utils.js index 38ab6d88e12..88328ff10aa 100644 --- a/src/utils.js +++ b/src/utils.js @@ -111,7 +111,14 @@ export function tryAppendQueryString(existingUrl, key, value) { // parse a query string object passed in bid params // bid params should be an object such as {key: "value", key1 : "value1"} // aliases to formatQS -export let parseQueryStringParameters = internal.formatQS; +export function parseQueryStringParameters(queryObj) { + let result = ''; + for (var k in queryObj) { + if (queryObj.hasOwnProperty(k)) { result += k + '=' + encodeURIComponent(queryObj[k]) + '&'; } + } + result = result.replace(/&$/, ''); + return result; +} // transform an AdServer targeting bids into a query string to send to the adserver export function transformAdServerTargetingObj(targeting) { diff --git a/test/spec/utils_spec.js b/test/spec/utils_spec.js index 96df3cf996c..4dbb40557af 100644 --- a/test/spec/utils_spec.js +++ b/test/spec/utils_spec.js @@ -63,12 +63,12 @@ describe('Utils', function () { describe('parseQueryStringParameters', function () { it('should append query string to existing using the input obj', function () { var obj = { - a: '1', - b: '2' + a: 'http://example.com/?foo=bar&bar=foo', + b: 'abc["def"]' }; var output = utils.parseQueryStringParameters(obj); - var expectedResult = 'a=' + encodeURIComponent('1') + '&b=' + encodeURIComponent('2'); + var expectedResult = 'a=' + encodeURIComponent('http://example.com/?foo=bar&bar=foo') + '&b=' + encodeURIComponent('abc["def"]'); assert.equal(output, expectedResult); }); From 8bfd2d67bf4bf8e98a633fab8a479dcc9cdda8fe Mon Sep 17 00:00:00 2001 From: Adam Browning <19834421+adam-browning@users.noreply.github.com> Date: Mon, 18 May 2020 12:29:55 +0300 Subject: [PATCH 319/496] One Video: Added banner support for Dynamic Ad Placement (DAP) (#5199) * Added banner support for Dynamic Ad Placement (DAP) * updated version number * changed version to 3.0.2 in both adapter and tests _spec * Added DAP Banner test for interpretResponse & isBidRequestValid * Updated DAP tests - video and banner validations * updated adapter examples .md file * Updated ternary operator for bidResponse.mediaType setting * removing redundant display parameter validation * Update package-lock.json --- modules/oneVideoBidAdapter.js | 27 ++- modules/oneVideoBidAdapter.md | 217 +++++++++++++------ test/spec/modules/oneVideoBidAdapter_spec.js | 98 ++++++++- 3 files changed, 263 insertions(+), 79 deletions(-) diff --git a/modules/oneVideoBidAdapter.js b/modules/oneVideoBidAdapter.js index 5747c5e848d..e43e7eff0f8 100644 --- a/modules/oneVideoBidAdapter.js +++ b/modules/oneVideoBidAdapter.js @@ -3,12 +3,12 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'oneVideo'; export const spec = { code: 'oneVideo', - VERSION: '3.0.1', + VERSION: '3.0.2', ENDPOINT: 'https://ads.adaptv.advertising.com/rtb/openrtb?ext_id=', SYNC_ENDPOINT1: 'https://cm.g.doubleclick.net/pixel?google_nid=adaptv_dbm&google_cm&google_sc', SYNC_ENDPOINT2: 'https://pr-bh.ybp.yahoo.com/sync/adaptv_ortb/{combo_uid}', SYNC_ENDPOINT3: 'https://match.adsrvr.org/track/cmf/generic?ttd_pid=adaptv&ttd_tpi=1', - supportedMediaTypes: ['video'], + supportedMediaTypes: ['video', 'banner'], /** * Determines whether or not the given bid request is valid. * @@ -25,6 +25,17 @@ export const spec = { return false; } + // Prevend DAP Outstream validation + if (bid.mediaTypes.video) { + if (bid.mediaTypes.video.context === 'outstream' && bid.params.video.display === 1) { + return false; + } + } + // Banner DAP validation + if (bid.mediaTypes.banner && (!bid.params.video.display)) { + return false; + } + // Pub Id validation if (typeof bid.params.pubId === 'undefined') { return false; @@ -82,18 +93,26 @@ export const spec = { creativeId: bid.crid, width: size.width, height: size.height, - mediaType: 'video', currency: response.cur, ttl: 100, netRevenue: true, adUnitCode: bidRequest.adUnitCode }; + + bidResponse.mediaType = (bidRequest.mediaTypes.banner) ? 'banner' : 'video' + if (bid.nurl) { bidResponse.vastUrl = bid.nurl; + } else if (bid.adm && bidRequest.params.video.display === 1) { + bidResponse.ad = bid.adm } else if (bid.adm) { bidResponse.vastXml = bid.adm; } - bidResponse.renderer = (bidRequest.mediaTypes.video.context === 'outstream') ? newRenderer(bidRequest, bidResponse) : undefined; + + if (bidRequest.mediaTypes.video) { + bidResponse.renderer = (bidRequest.mediaTypes.video.context === 'outstream') ? newRenderer(bidRequest, bidResponse) : undefined; + } + return bidResponse; }, /** diff --git a/modules/oneVideoBidAdapter.md b/modules/oneVideoBidAdapter.md index 656f81733a0..1805a6869d3 100644 --- a/modules/oneVideoBidAdapter.md +++ b/modules/oneVideoBidAdapter.md @@ -1,89 +1,168 @@ # Overview **Module Name**: One Video Bidder Adapter -**Module Type**: Bidder Adapter +**Module Type**: Bidder Adapter **Maintainer**: deepthi.neeladri.sravana@verizonmedia.com # Description -Connects to One Video demand source to fetch bids. +Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to fetch bids. -# Test Parameters for Video +# Instream Video adUnit example & parameters +*Note:* The Video SSP ad server will respond with an VAST XML to load into your defined player. +``` + var adUnits = [ + { + code: 'video1', + mediaTypes: { + video: { + context: 'instream', + playerSize: [480, 640] + } + }, + bids: [ + { + bidder: 'oneVideo', + params: { + video: { + playerWidth: 480, + playerHeight: 640, + mimes: ['video/mp4', 'application/javascript'], + protocols: [2,5], + api: [2], + position: 1, + delivery: [2], + playbackmethod: [1,5], + sid: , + rewarded: 1, + placement: 1, + inventoryid: 123, + minduration: 10, + maxduration: 30, + }, + site: { + id: 1, + page: 'https://verizonmedia.com', + referrer: 'https://verizonmedia.com' + }, + pubId: 'HBExchange' + } + } + ] + } + ] +``` +# Outstream Video adUnit example & parameters +*Note:* The Video SSP ad server will load it's own Outstream Renderer (player) as a fallback if no player is defined on the publisher page. The Outstream player will inject into the div id that has an identical adUnit code. +``` + var adUnits = [ + { + code: 'video1', + mediaTypes: { + video: { + context: 'outstream', + playerSize: [480, 640] + } + }, + bids: [ + { + bidder: 'oneVideo', + params: { + video: { + playerWidth: 480, + playerHeight: 640, + mimes: ['video/mp4', 'application/javascript'], + protocols: [2,5], + api: [2], + position: 1, + delivery: [2], + playbackmethod: [1,5], + sid: , + rewarded: 1, + placement: 1, + inventoryid: 123, + minduration: 10, + maxduration: 30, + }, + site: { + id: 1, + page: 'https://verizonmedia.com', + referrer: 'https://verizonmedia.com' + }, + pubId: 'HBExchange' + } + } + ] + } + ] ``` - var adUnits = [ - { +# S2S / Video: Dynamic Ad Placement (DAP) adUnit example & parameters +*Note:* The Video SSP ad server will respond with HTML embed tag to be injected into an iFrame you create. +``` + var adUnits = [ + { code: 'video1', - sizes: [640,480], - mediaTypes: { - video: { - context: "instream" + mediaTypes: { + video: { + context: "instream", + playerSize: [480, 640] + } + }, + bids: [ + { + bidder: 'oneVideo', + params: { + video: { + playerWidth: 480, + playerHeight: 640, + mimes: ['video/mp4', 'application/javascript'], + position: 1, + display: 1 + }, + site: { + id: 1, + page: 'https://verizonmedia.com', + referrer: 'https://verizonmedia.com' + }, + pubId: 'HBExchangeDAP' } - }, - bids: [ - { - bidder: 'oneVideo', - params: { - video: { - playerWidth: 480, - playerHeight: 640, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2,5], - api: [2], - position: 1, - delivery: [2], - playbackmethod: [1,5], - sid: , - rewarded: 1, - placement: 1, - inventoryid: 123, - minduration: 10, - maxduration: 30, - }, - site: { - id: 1, - page: 'http://abhi12345.com', - referrer: 'http://abhi12345.com' - }, - pubId: 'brxd' - } - } - ] + } + ] } ] ``` -# Test Parameters for banner request +# Prebid.js / Banner: Dynamic Ad Placement (DAP) adUnit example & parameters +*Note:* The Video SSP ad server will respond with HTML embed tag to be injected into an iFrame created by Google Ad Manager (GAM). ``` - var adUnits = [ + var adUnits = [ + { + code: 'banner-1', + mediaTypes: { + banner: { + sizes: [300, 250] + } + }, + bids: [ { - code: 'video1', - sizes: [640,480], - mediaTypes: { - video: { - context: "instream" - } - }, - bids: [ - { - bidder: 'oneVideo', - params: { - video: { - playerWidth: 480, - playerHeight: 640, - mimes: ['video/mp4', 'application/javascript'], - position: 1, - display: 1 - }, - site: { - id: 1, - page: 'http://abhi12345.com', - referrer: 'http://abhi12345.com' - }, - pubId: 'OneMDisplay' - } - } - ] - } + bidder: 'oneVideo', + params: { + video: { + playerWidth: 300, + playerHeight: 250, + mimes: ['video/mp4', 'application/javascript'], + display: 1 + }, + site: { + id: 1, + page: 'https://verizonmedia.com', + referrer: 'https://verizonmedia.com' + }, + pubId: 'HBExchangeDAP' + } + } + ] + } ] ``` diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js index 82546f2e96d..45d59683942 100644 --- a/test/spec/modules/oneVideoBidAdapter_spec.js +++ b/test/spec/modules/oneVideoBidAdapter_spec.js @@ -90,7 +90,7 @@ describe('OneVideoBidAdapter', function () { }; expect(spec.isBidRequestValid(bidRequest)).to.equal(false); }); - it('should return true when the "pubId" param is missing', function () { + it('should return true when the "pubId" param exists', function () { bidRequest.params = { video: { playerWidth: 480, @@ -115,6 +115,72 @@ describe('OneVideoBidAdapter', function () { bidRequest.params = {}; expect(spec.isBidRequestValid(bidRequest)).to.equal(false); }); + + it('should return false when the mediaType is "banner" and display="undefined" (DAP 3P)', function () { + bidRequest = { + mediaTypes: { + banner: { + sizes: [640, 480] + } + } + } + expect(spec.isBidRequestValid(bidRequest)).to.equal(false); + }) + + it('should return true when the mediaType is "banner" and display=1 (DAP 3P)', function () { + bidRequest = { + mediaTypes: { + banner: { + sizes: [640, 480] + } + }, + bidder: 'oneVideo', + sizes: [640, 480], + bidId: '30b3efwfwe1e', + adUnitCode: 'video1', + params: { + video: { + playerWidth: 640, + playerHeight: 480, + mimes: ['video/mp4', 'application/javascript'], + protocols: [2, 5], + api: [2], + position: 1, + delivery: [2], + playbackmethod: [1, 5], + sid: 134, + rewarded: 1, + placement: 1, + inventoryid: 123, + display: 1 + }, + site: { + id: 1, + page: 'https://news.yahoo.com/portfolios', + referrer: 'http://www.yahoo.com' + }, + pubId: 'brxd' + } + }; + expect(spec.isBidRequestValid(bidRequest)).to.equal(true); + }) + + it('should return false when the mediaType is "video" and context="outstream" and display=1 (DAP 3P)', function () { + bidRequest = { + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 480] + } + }, + params: { + video: { + display: 1 + } + } + } + expect(spec.isBidRequestValid(bidRequest)).to.equal(false); + }) }); describe('spec.buildRequests', function () { @@ -136,7 +202,7 @@ describe('OneVideoBidAdapter', function () { const placement = bidRequest.params.video.placement; const rewarded = bidRequest.params.video.rewarded; const inventoryid = bidRequest.params.video.inventoryid; - const VERSION = '3.0.1'; + const VERSION = '3.0.2'; expect(data.imp[0].video.w).to.equal(width); expect(data.imp[0].video.h).to.equal(height); expect(data.imp[0].bidfloor).to.equal(bidRequest.params.bidfloor); @@ -176,7 +242,7 @@ describe('OneVideoBidAdapter', function () { expect(bidResponse.length).to.equal(0); }); - it('should return a valid bid response with just "adm"', function () { + it('should return a valid video bid response with just "adm"', function () { const serverResponse = {seatbid: [{bid: [{id: 1, adid: 123, crid: 2, price: 6.01, adm: ''}]}], cur: 'USD'}; const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); let o = { @@ -197,6 +263,26 @@ describe('OneVideoBidAdapter', function () { }; expect(bidResponse).to.deep.equal(o); }); + // @abrowning14 check that banner DAP response is appended to o.ad + mediaType: 'banner' + it('should return a valid DAP banner bid-response', function () { + bidRequest = { + mediaTypes: { + banner: { + sizes: [640, 480] + } + }, + params: { + video: { + display: 1 + } + } + } + const serverResponse = {seatbid: [{bid: [{id: 1, adid: 123, crid: 2, price: 6.01, adm: '
DAP UNIT HERE
'}]}], cur: 'USD'}; + const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); + expect(bidResponse.ad).to.equal('
DAP UNIT HERE
'); + expect(bidResponse.mediaType).to.equal('banner'); + expect(bidResponse.renderer).to.be.undefined; + }); }); describe('when GDPR and uspConsent applies', function () { @@ -267,7 +353,7 @@ describe('OneVideoBidAdapter', function () { }); }); describe('should send banner object', function () { - it('should send banner object when display is 1', function () { + it('should send banner object when display is 1 and context="instream" (DAP O&O)', function () { bidRequest = { mediaTypes: { video: { @@ -320,7 +406,7 @@ describe('OneVideoBidAdapter', function () { expect(data.imp[0].banner.ext.maxduration).to.equal(bidRequest.params.video.maxduration); expect(data.site.id).to.equal(bidRequest.params.site.id); }); - it('should send video object when display is other than 1', function () { + it('should send video object when display is other than 1 (VAST for All)', function () { bidRequest = { mediaTypes: { video: { @@ -365,7 +451,7 @@ describe('OneVideoBidAdapter', function () { expect(data.imp[0].video.pos).to.equal(position); expect(data.imp[0].video.mimes).to.equal(bidRequest.params.video.mimes); }); - it('should send video object when display is not passed', function () { + it('should send video object when display is not passed (VAST for All)', function () { bidRequest = { mediaTypes: { video: { From 200ab99840e6566d52f3543e240a3d628fe8e0e7 Mon Sep 17 00:00:00 2001 From: TheMediaGrid <44166371+TheMediaGrid@users.noreply.github.com> Date: Mon, 18 May 2020 16:23:37 +0300 Subject: [PATCH 320/496] Added support of multi-format ads in TheMediaGrid Bid Adapter (#5217) * Added TheMediaGridNM Bid Adapter * Updated required params for TheMediaGridNM Bid Adapter * Update TheMediGridNM Bid Adapter * Fix tests for TheMediaGridNM Bid Adapter * Fixes after review for TheMediaGridNM Bid Adapter * Add support of multi-format in TheMediaGrid Bid Adapter --- modules/gridBidAdapter.js | 15 ++++++++++++- test/spec/modules/gridBidAdapter_spec.js | 28 +++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/modules/gridBidAdapter.js b/modules/gridBidAdapter.js index e19d8cc68a7..4ca631b23e5 100644 --- a/modules/gridBidAdapter.js +++ b/modules/gridBidAdapter.js @@ -51,10 +51,23 @@ export const spec = { bids.forEach(bid => { reqId = bid.bidderRequestId; - const {params: {uid}, adUnitCode} = bid; + const {params: {uid}, adUnitCode, mediaTypes} = bid; auids.push(uid); const sizesId = utils.parseSizesInput(bid.sizes); + const addedSizes = {}; + sizesId.forEach((sizeId) => { + addedSizes[sizeId] = true; + }); + const bannerSizesId = utils.parseSizesInput(utils.deepAccess(mediaTypes, 'banner.sizes')); + const videoSizesId = utils.parseSizesInput(utils.deepAccess(mediaTypes, 'video.playerSize')); + bannerSizesId.concat(videoSizesId).forEach((sizeId) => { + if (!addedSizes[sizeId]) { + addedSizes[sizeId] = true; + sizesId.push(sizeId); + } + }); + if (!slotsMapByUid[uid]) { slotsMapByUid[uid] = {}; } diff --git a/test/spec/modules/gridBidAdapter_spec.js b/test/spec/modules/gridBidAdapter_spec.js index 26ab27f5273..4f53d9dcb25 100644 --- a/test/spec/modules/gridBidAdapter_spec.js +++ b/test/spec/modules/gridBidAdapter_spec.js @@ -68,6 +68,14 @@ describe('TheMediaGrid Adapter', function () { }, 'adUnitCode': 'adunit-code-2', 'sizes': [[728, 90]], + 'mediaTypes': { + 'video': { + 'playerSize': [400, 600] + }, + 'banner': { + 'sizes': [[728, 90]] + } + }, 'bidId': '3150ccb55da321', 'bidderRequestId': '22edbae2733bf6', 'auctionId': '1d1a030790a475', @@ -79,6 +87,14 @@ describe('TheMediaGrid Adapter', function () { }, 'adUnitCode': 'adunit-code-1', 'sizes': [[300, 250], [300, 600]], + 'mediaTypes': { + 'video': { + 'playerSize': [400, 600] + }, + 'banner': { + 'sizes': [[300, 250], [300, 600]] + } + }, 'bidId': '42dbe3a7168a6a', 'bidderRequestId': '22edbae2733bf6', 'auctionId': '1d1a030790a475', @@ -97,13 +113,23 @@ describe('TheMediaGrid Adapter', function () { expect(payload).to.have.property('wrapperVersion', '$prebid.version$'); }); + it('sizes must be added from mediaTypes', function () { + const request = spec.buildRequests([bidRequests[0], bidRequests[1]], bidderRequest); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload).to.have.property('u', referrer); + expect(payload).to.have.property('auids', '1,1'); + expect(payload).to.have.property('sizes', '300x250,300x600,728x90,400x600'); + expect(payload).to.have.property('r', '22edbae2733bf6'); + }); + it('sizes must not be duplicated', function () { const request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data).to.be.an('string'); const payload = parseRequest(request.data); expect(payload).to.have.property('u', referrer); expect(payload).to.have.property('auids', '1,1,2'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); + expect(payload).to.have.property('sizes', '300x250,300x600,728x90,400x600'); expect(payload).to.have.property('r', '22edbae2733bf6'); }); From 49d5d46ba1dfa9f809dceff0d0ab541381009a92 Mon Sep 17 00:00:00 2001 From: Kotaro Shikata Date: Tue, 19 May 2020 04:05:33 +0900 Subject: [PATCH 321/496] add publisherId & mediaId (#5184) --- modules/unicornBidAdapter.js | 7 +++++-- modules/unicornBidAdapter.md | 2 ++ test/spec/modules/unicornBidAdapter_spec.js | 12 ++++++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/modules/unicornBidAdapter.js b/modules/unicornBidAdapter.js index cc320dc68a8..33e60ad2789 100644 --- a/modules/unicornBidAdapter.js +++ b/modules/unicornBidAdapter.js @@ -65,9 +65,9 @@ function buildOpenRtbBidRequestPayload(validBidRequests, bidderRequest) { imp, cur: UNICORN_DEFAULT_CURRENCY, site: { - id: window.location.hostname, + id: utils.deepAccess(validBidRequests[0], 'params.mediaId') || '', publisher: { - id: utils.deepAccess(validBidRequests[0], 'params.accountId') + id: utils.deepAccess(validBidRequests[0], 'params.publisherId') || 0 }, domain: window.location.hostname, page: window.location.href, @@ -86,6 +86,9 @@ function buildOpenRtbBidRequestPayload(validBidRequests, bidderRequest) { stype: 'prebid_uncn', bidder: BIDDER_CODE } + }, + ext: { + accountId: utils.deepAccess(validBidRequests[0], 'params.accountId') } }; utils.logInfo('[UNICORN] OpenRTB Formatted Request:', request); diff --git a/modules/unicornBidAdapter.md b/modules/unicornBidAdapter.md index 25f027ae9f6..5b8c8268bcf 100644 --- a/modules/unicornBidAdapter.md +++ b/modules/unicornBidAdapter.md @@ -23,6 +23,8 @@ Module that connects to UNICORN. params: { placementId: 'rectangle-ad-1', // OPTIONAL: If placementId is empty, adunit code will be used as placementId. bidfloorCpm: 0.2, // OPTIONAL: Floor CPM (JPY) defaults to 0 + publisherId: 99999 // OPTIONAL: Account specific publisher id + mediaId: "uc" // OPTIONAL: Publisher specific media id accountId: 12345, // REQUIRED: Account ID for charge request bcat: ['IAB-1', 'IAB-2'] // OPTIONAL: blocked IAB categories } diff --git a/test/spec/modules/unicornBidAdapter_spec.js b/test/spec/modules/unicornBidAdapter_spec.js index 4699a81853a..4c56c37700b 100644 --- a/test/spec/modules/unicornBidAdapter_spec.js +++ b/test/spec/modules/unicornBidAdapter_spec.js @@ -75,7 +75,9 @@ const validBidRequests = [ params: { placementId: 'rectangle-ad-1', bidfloorCpm: 0, - accountId: 12345 + accountId: 12345, + publisherId: 99999, + mediaId: 'example' }, mediaTypes: { banner: { @@ -261,10 +263,13 @@ const openRTBRequest = { } ], cur: 'JPY', + ext: { + accountId: 12345 + }, site: { - id: 'uni-corn.net', + id: 'example', publisher: { - id: 12345 + id: 99999 }, domain: 'uni-corn.net', page: 'https://uni-corn.net/', @@ -427,7 +432,6 @@ describe('unicornBidAdapterTest', () => { const removeUntestableAttrs = data => { delete data['device']; delete data['site']['domain']; - delete data['site']['id']; delete data['site']['page']; delete data['id']; data['imp'].forEach(imp => { From 334cb01b3753cb9e9c331e52be7f59c59fc01538 Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Mon, 18 May 2020 12:10:54 -0700 Subject: [PATCH 322/496] User id fetch error (#5166) * Update Bidder Code * LunaMedia Adapater LunaMedia Adapater * Updated LunamediaBidAdapter.md test params and valid pub code for testing * Updating User ID submodules to execute callback onError AJAX * fix parrable test when IE * parrable spec all messed up after merge, fixed now Co-authored-by: Chandra Prakash Co-authored-by: trchandraprakash <47793448+trchandraprakash@users.noreply.github.com> Co-authored-by: rmartinez --- modules/id5IdSystem.js | 25 ++++++++++++------- modules/identityLinkIdSystem.js | 25 ++++++++++++------- modules/liveIntentIdSystem.js | 25 ++++++++++++------- modules/parrableIdSystem.js | 26 ++++++++++++-------- modules/unifiedIdSystem.js | 25 ++++++++++++------- test/spec/modules/liveIntentIdSystem_spec.js | 16 ++++++++++++ test/spec/modules/parrableIdSystem_spec.js | 18 ++++++++++++++ 7 files changed, 114 insertions(+), 46 deletions(-) diff --git a/modules/id5IdSystem.js b/modules/id5IdSystem.js index 1d55450239b..151782791af 100644 --- a/modules/id5IdSystem.js +++ b/modules/id5IdSystem.js @@ -49,17 +49,24 @@ export const id5IdSubmodule = { const url = `https://id5-sync.com/g/v1/${configParams.partner}.json?1puid=${storedUserId ? storedUserId.id5id : ''}&gdpr=${hasGdpr}&gdpr_consent=${gdprConsentString}`; const resp = function (callback) { - ajax(url, response => { - let responseObj; - if (response) { - try { - responseObj = JSON.parse(response); - } catch (error) { - utils.logError(error); + const callbacks = { + success: response => { + let responseObj; + if (response) { + try { + responseObj = JSON.parse(response); + } catch (error) { + utils.logError(error); + } } + callback(responseObj); + }, + error: error => { + utils.logError(`id5Id: ID fetch encountered an error`, error); + callback(); } - callback(responseObj); - }, undefined, { method: 'GET', withCredentials: true }); + }; + ajax(url, callbacks, undefined, { method: 'GET', withCredentials: true }); }; return {callback: resp}; } diff --git a/modules/identityLinkIdSystem.js b/modules/identityLinkIdSystem.js index 47d8ad9ac05..a7114c2a147 100644 --- a/modules/identityLinkIdSystem.js +++ b/modules/identityLinkIdSystem.js @@ -63,17 +63,24 @@ export const identityLinkSubmodule = { }; // return envelope from third party endpoint function getEnvelope(url, callback) { - ajax(url, response => { - let responseObj; - if (response) { - try { - responseObj = JSON.parse(response); - } catch (error) { - utils.logError(error); + const callbacks = { + success: response => { + let responseObj; + if (response) { + try { + responseObj = JSON.parse(response); + } catch (error) { + utils.logError(error); + } } + callback(responseObj.envelope); + }, + error: error => { + utils.logError(`identityLink: ID fetch encountered an error`, error); + callback(); } - callback(responseObj.envelope); - }, undefined, {method: 'GET', withCredentials: true}); + }; + ajax(url, callbacks, undefined, {method: 'GET', withCredentials: true}); } submodule('userId', identityLinkSubmodule); diff --git a/modules/liveIntentIdSystem.js b/modules/liveIntentIdSystem.js index 3f5d0602166..b0e8cfc1c0f 100644 --- a/modules/liveIntentIdSystem.js +++ b/modules/liveIntentIdSystem.js @@ -143,17 +143,24 @@ export const liveIntentIdSubmodule = { // Don't do the internal ajax call, but use the composed url and fire it via PBJS ajax module const url = liveConnect.resolutionCallUrl(); const result = function (callback) { - ajax(url, response => { - let responseObj = {}; - if (response) { - try { - responseObj = JSON.parse(response); - } catch (error) { - utils.logError(error); + const callbacks = { + success: response => { + let responseObj = {}; + if (response) { + try { + responseObj = JSON.parse(response); + } catch (error) { + utils.logError(error); + } } + callback(responseObj); + }, + error: error => { + utils.logError(`${MODULE_NAME}: ID fetch encountered an error: `, error); + callback(); } - callback(responseObj); - }, undefined, { method: 'GET', withCredentials: true }); + }; + ajax(url, callbacks, undefined, { method: 'GET', withCredentials: true }); }; return {callback: result}; } diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js index ba5fae81952..8c487c783ae 100644 --- a/modules/parrableIdSystem.js +++ b/modules/parrableIdSystem.js @@ -52,19 +52,25 @@ function fetchId(configParams, currentStoredId) { }; const callback = function (cb) { - const onSuccess = (response) => { - let eid; - if (response) { - try { - let responseObj = JSON.parse(response); - eid = responseObj ? responseObj.eid : undefined; - } catch (error) { - utils.logError(error); + const callbacks = { + success: response => { + let eid; + if (response) { + try { + let responseObj = JSON.parse(response); + eid = responseObj ? responseObj.eid : undefined; + } catch (error) { + utils.logError(error); + } } + cb(eid); + }, + error: error => { + utils.logError(`parrableId: ID fetch encountered an error`, error); + cb(); } - cb(eid); }; - ajax(PARRABLE_URL, onSuccess, searchParams, options); + ajax(PARRABLE_URL, callbacks, searchParams, options); }; return { callback }; diff --git a/modules/unifiedIdSystem.js b/modules/unifiedIdSystem.js index 9995a260c26..f916030d643 100644 --- a/modules/unifiedIdSystem.js +++ b/modules/unifiedIdSystem.js @@ -42,17 +42,24 @@ export const unifiedIdSubmodule = { const url = configParams.url || `https://match.adsrvr.org/track/rid?ttd_pid=${configParams.partner}&fmt=json`; const resp = function (callback) { - ajax(url, response => { - let responseObj; - if (response) { - try { - responseObj = JSON.parse(response); - } catch (error) { - utils.logError(error); + const callbacks = { + success: response => { + let responseObj; + if (response) { + try { + responseObj = JSON.parse(response); + } catch (error) { + utils.logError(error); + } } + callback(responseObj); + }, + error: error => { + utils.logError(`${MODULE_NAME}: ID fetch encountered an error`, error); + callback(); } - callback(responseObj); - }, undefined, {method: 'GET', withCredentials: true}); + }; + ajax(url, callbacks, undefined, {method: 'GET', withCredentials: true}); }; return {callback: resp}; } diff --git a/test/spec/modules/liveIntentIdSystem_spec.js b/test/spec/modules/liveIntentIdSystem_spec.js index c3c9c8dc38d..85e0d30b348 100644 --- a/test/spec/modules/liveIntentIdSystem_spec.js +++ b/test/spec/modules/liveIntentIdSystem_spec.js @@ -158,6 +158,22 @@ describe('LiveIntentId', function () { expect(callBackSpy.calledOnce).to.be.true; }); + it('should log an error and continue to callback if ajax request errors', function () { + getCookieStub.returns(null); + let callBackSpy = sinon.spy(); + let submoduleCallback = liveIntentIdSubmodule.getId(defaultConfigParams).callback; + submoduleCallback(callBackSpy); + let request = server.requests[0]; + expect(request.url).to.be.eq('https://idx.liadm.com/idex/prebid/89899'); + request.respond( + 503, + responseHeader, + 'Unavailable' + ); + expect(logErrorStub.calledOnce).to.be.true; + expect(callBackSpy.calledOnce).to.be.true; + }); + it('should include the LiveConnect identifier when calling the LiveIntent Identity Exchange endpoint', function () { const oldCookie = 'a-xxxx--123e4567-e89b-12d3-a456-426655440000' getDataFromLocalStorageStub.withArgs('_li_duid').returns(oldCookie); diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js index 662f63f6638..0183a6f79d4 100644 --- a/test/spec/modules/parrableIdSystem_spec.js +++ b/test/spec/modules/parrableIdSystem_spec.js @@ -110,6 +110,7 @@ describe('Parrable ID System', function() { describe('Parrable ID in Bid Request', function() { let adUnits; + let logErrorStub; beforeEach(function() { adUnits = [getAdUnitMock()]; @@ -122,10 +123,12 @@ describe('Parrable ID System', function() { setSubmoduleRegistry([parrableIdSubmodule]); init(config); config.setConfig(getConfigMock()); + logErrorStub = sinon.stub(utils, 'logError'); }); afterEach(function() { storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); + logErrorStub.restore(); }); it('provides the parrableid in the bid request', function(done) { @@ -139,5 +142,20 @@ describe('Parrable ID System', function() { done(); }, { adUnits }); }); + + it('should log an error and continue to callback if ajax request errors', function () { + let callBackSpy = sinon.spy(); + let submoduleCallback = parrableIdSubmodule.getId({partner: 'prebid'}).callback; + submoduleCallback(callBackSpy); + let request = server.requests[0]; + expect(request.url).to.contain('h.parrable.com'); + request.respond( + 503, + null, + 'Unavailable' + ); + expect(logErrorStub.calledOnce).to.be.true; + expect(callBackSpy.calledOnce).to.be.true; + }); }); }); From 60c83ea8585298540bcc55562a7703fa4d48dd4f Mon Sep 17 00:00:00 2001 From: Rich Audience Date: Tue, 19 May 2020 07:20:38 +0200 Subject: [PATCH 323/496] RichAudience BidAdapter - Changes video Adapter (#5213) * Changes video Adapter * Update MD Richaudience Co-authored-by: sgimenez --- modules/richaudienceBidAdapter.js | 43 +++++++++-- modules/richaudienceBidAdapter.md | 21 +++++- .../modules/richaudienceBidAdapter_spec.js | 74 ++++++++----------- 3 files changed, 84 insertions(+), 54 deletions(-) diff --git a/modules/richaudienceBidAdapter.js b/modules/richaudienceBidAdapter.js index 535834ddbad..22db9709c7c 100755 --- a/modules/richaudienceBidAdapter.js +++ b/modules/richaudienceBidAdapter.js @@ -45,7 +45,9 @@ export const spec = { numIframes: (typeof bidderRequest.refererInfo.numIframes != 'undefined' ? bidderRequest.refererInfo.numIframes : null), transactionId: bid.transactionId, timeout: config.getConfig('bidderTimeout'), - user: raiSetEids(bid) + user: raiSetEids(bid), + demand: raiGetDemandType(bid) ? 'video' : 'display', + videoData: raiGetVideoInfo(bid) }; REFERER = (typeof bidderRequest.refererInfo.referer != 'undefined' ? encodeURIComponent(bidderRequest.refererInfo.referer) : null) @@ -116,16 +118,28 @@ export const spec = { var rand = Math.floor(Math.random() * 9999999999); var syncUrl = ''; + var consent = ''; - gdprConsent && typeof gdprConsent.consentString === 'string' ? syncUrl = 'https://sync.richaudience.com/dcf3528a0b8aa83634892d50e91c306e/?ord=' + rand + '&pubconsent=' + gdprConsent.consentString + '&euconsent=' + gdprConsent.consentString : syncUrl = 'https://sync.richaudience.com/dcf3528a0b8aa83634892d50e91c306e/?ord=' + rand; + if (gdprConsent && typeof gdprConsent.consentString === 'string' && typeof gdprConsent.consentString != 'undefined') { + consent = `pubconsent='${gdprConsent.consentString}'&euconsent='${gdprConsent.consentString}'` + } if (syncOptions.iframeEnabled) { + syncUrl = 'https://sync.richaudience.com/dcf3528a0b8aa83634892d50e91c306e/?ord=' + rand + if (consent != '') { + syncUrl += `&${consent}` + } syncs.push({ type: 'iframe', url: syncUrl }); - } else if (syncOptions.pixelEnabled && REFERER != null) { - typeof gdprConsent != 'undefined' && typeof gdprConsent.consentString != 'undefined' ? syncUrl = `https://sync.richaudience.com/bf7c142f4339da0278e83698a02b0854/?euconsent=${gdprConsent.consentString}&referrer=${REFERER}` : syncUrl = `https://sync.richaudience.com/bf7c142f4339da0278e83698a02b0854/?referrer=${REFERER}`; + } + + if (syncOptions.pixelEnabled && REFERER != null && syncs.length == 0) { + syncUrl = `https://sync.richaudience.com/bf7c142f4339da0278e83698a02b0854/?referrer=${REFERER}`; + if (consent != '') { + syncUrl += `&${consent}` + } syncs.push({ type: 'image', url: syncUrl @@ -141,8 +155,6 @@ function raiGetSizes(bid) { let raiNewSizes; if (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) { raiNewSizes = bid.mediaTypes.banner.sizes - } else { - raiNewSizes = bid.sizes } if (raiNewSizes != null) { return raiNewSizes.map(size => ({ @@ -152,6 +164,25 @@ function raiGetSizes(bid) { } } +function raiGetDemandType(bid) { + if (bid.mediaTypes != undefined) { + if (bid.mediaTypes.video != undefined) { + return true; + } + } + return false; +} + +function raiGetVideoInfo(bid) { + let videoData = []; + if (raiGetDemandType(bid)) { + videoData.push({format: bid.mediaTypes.video.context}); + videoData.push({playerSize: bid.mediaTypes.video.playerSize}); + videoData.push({mimes: bid.mediaTypes.video.mimes}); + } + return videoData; +} + function raiSetEids(bid) { let eids = []; diff --git a/modules/richaudienceBidAdapter.md b/modules/richaudienceBidAdapter.md index 11c60efc9dc..852af5f1844 100644 --- a/modules/richaudienceBidAdapter.md +++ b/modules/richaudienceBidAdapter.md @@ -50,7 +50,11 @@ Please reach out to your account manager for more information. var adUnits = [ { code: 'test-div1', - sizes: [[300, 250],[300, 600]], + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]] + } + }, bids: [{ bidder: 'richaudience', params: { @@ -85,7 +89,18 @@ Rich Audience strongly recommends enabling user syncing through iframes. Be sure ```javascript pbjs.setConfig({ userSync: { - iframeEnabled: true - } + filterSettings: { + iframe: { + bidders: '*', + filter: 'include' + }, + image: { + bidders: '*', + filter: 'include' + } + }, + syncsPerBidder: 3, + syncDelay: 6000, + } }); ``` diff --git a/test/spec/modules/richaudienceBidAdapter_spec.js b/test/spec/modules/richaudienceBidAdapter_spec.js index 9772e8d717a..2bc699b4640 100644 --- a/test/spec/modules/richaudienceBidAdapter_spec.js +++ b/test/spec/modules/richaudienceBidAdapter_spec.js @@ -5,18 +5,17 @@ import { } from 'modules/richaudienceBidAdapter.js'; import {config} from 'src/config.js'; import * as utils from 'src/utils.js'; -import { getGlobal } from 'src/prebidGlobal.js'; describe('Richaudience adapter tests', function () { - var DEFAULT_PARAMS = [{ + var DEFAULT_PARAMS_NEW_SIZES = [{ adUnitCode: 'test-div', bidId: '2c7c8e9c900244', - sizes: [ - [300, 250], - [300, 600], - [728, 90], - [970, 250] - ], + mediaTypes: { + banner: { + sizes: [ + [300, 250], [300, 600], [728, 90], [970, 250]] + } + }, bidder: 'richaudience', params: { bidfloor: 0.5, @@ -30,13 +29,14 @@ describe('Richaudience adapter tests', function () { user: {} }]; - var DEFAULT_PARAMS_NEW_SIZES = [{ + var DEFAULT_PARAMS_VIDEO = [{ adUnitCode: 'test-div', bidId: '2c7c8e9c900244', mediaTypes: { - banner: { - sizes: [ - [300, 250], [300, 600], [728, 90], [970, 250]] + video: { + context: 'instream', // or 'outstream' + playerSize: [640, 480], + mimes: ['video/mp4'] } }, bidder: 'richaudience', @@ -136,34 +136,12 @@ describe('Richaudience adapter tests', function () { } } - it('Verify build request', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'USD' - } - }); - - const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_PARAMS_GDPR); - - expect(request[0]).to.have.property('method').and.to.equal('POST'); - const requestContent = JSON.parse(request[0].data); - expect(requestContent).to.have.property('sizes'); - expect(requestContent.sizes[0]).to.have.property('w').and.to.equal(300); - expect(requestContent.sizes[0]).to.have.property('h').and.to.equal(250); - expect(requestContent.sizes[1]).to.have.property('w').and.to.equal(300); - expect(requestContent.sizes[1]).to.have.property('h').and.to.equal(600); - expect(requestContent.sizes[2]).to.have.property('w').and.to.equal(728); - expect(requestContent.sizes[2]).to.have.property('h').and.to.equal(90); - expect(requestContent.sizes[3]).to.have.property('w').and.to.equal(970); - expect(requestContent.sizes[3]).to.have.property('h').and.to.equal(250); - }); - it('Referer undefined', function() { config.setConfig({ 'currency': {'adServerCurrency': 'USD'} }) - const request = spec.buildRequests(DEFAULT_PARAMS, { + const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { gdprConsent: { consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', gdprApplies: true @@ -175,7 +153,7 @@ describe('Richaudience adapter tests', function () { expect(requestContent).to.have.property('referer').and.to.equal(null); }) - it('Verify build request to prebid 3.0', function() { + it('Verify build request to prebid 3.0 display test', function() { const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { gdprConsent: { consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', @@ -280,7 +258,7 @@ describe('Richaudience adapter tests', function () { }); describe('UID test', function () { - getGlobal().setConfig({ + pbjs.setConfig({ consentManagement: { cmpApi: 'iab', timeout: 5000, @@ -498,7 +476,7 @@ describe('Richaudience adapter tests', function () { }); it('Verify interprete response', function () { - const request = spec.buildRequests(DEFAULT_PARAMS, { + const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { gdprConsent: { consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', gdprApplies: true @@ -525,7 +503,7 @@ describe('Richaudience adapter tests', function () { }); it('no banner media response', function () { - const request = spec.buildRequests(DEFAULT_PARAMS, { + const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { gdprConsent: { consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', gdprApplies: true @@ -551,7 +529,7 @@ describe('Richaudience adapter tests', function () { }); it('Verifies if bid request is valid', function () { - expect(spec.isBidRequestValid(DEFAULT_PARAMS[0])).to.equal(true); + expect(spec.isBidRequestValid(DEFAULT_PARAMS_NEW_SIZES[0])).to.equal(true); expect(spec.isBidRequestValid(DEFAULT_PARAMS_WO_OPTIONAL[0])).to.equal(true); expect(spec.isBidRequestValid({})).to.equal(false); expect(spec.isBidRequestValid({ @@ -613,13 +591,14 @@ describe('Richaudience adapter tests', function () { })).to.equal(true); }); - it('Verifies user sync', function () { + it('Verifies user syncs iframe', function () { var syncs = spec.getUserSyncs({ iframeEnabled: true }, [BID_RESPONSE], { consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', gdprApplies: true }); + expect(syncs).to.have.lengthOf(1); expect(syncs[0].type).to.equal('iframe'); syncs = spec.getUserSyncs({ @@ -640,7 +619,7 @@ describe('Richaudience adapter tests', function () { }, [], {consentString: '', gdprApplies: true}); expect(syncs).to.have.lengthOf(0); - getGlobal().setConfig({ + pbjs.setConfig({ consentManagement: { cmpApi: 'iab', timeout: 5000, @@ -648,10 +627,13 @@ describe('Richaudience adapter tests', function () { pixelEnabled: true } }); + }); - syncs = spec.getUserSyncs({ + it('Verifies user syncs image', function () { + var syncs = spec.getUserSyncs({ + iframeEnabled: false, pixelEnabled: true - }, [], { + }, [BID_RESPONSE], { consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', referer: 'http://domain.com', gdprApplies: true @@ -660,8 +642,9 @@ describe('Richaudience adapter tests', function () { expect(syncs[0].type).to.equal('image'); syncs = spec.getUserSyncs({ + iframeEnabled: false, pixelEnabled: true - }, [], { + }, [BID_RESPONSE], { consentString: '', referer: 'http://domain.com', gdprApplies: true @@ -670,6 +653,7 @@ describe('Richaudience adapter tests', function () { expect(syncs[0].type).to.equal('image'); syncs = spec.getUserSyncs({ + iframeEnabled: false, pixelEnabled: true }, [], { consentString: null, From 3c1c0bf57a0d4ed28ada1b9625aa0d0b83af7d26 Mon Sep 17 00:00:00 2001 From: Adnan Miljkovic Date: Tue, 19 May 2020 18:19:36 +0200 Subject: [PATCH 324/496] tribeOS change endpoint URL (#5243) * initial tribeOS bidder adapter commit * initial tests for tribeOS bidder adapter * removed unimplemented "getUserSyncs" function * removed unimplemented "onBidWon" function * tribeOS - change end point URL * force commit * Revert "tribeOS - change end point URL" This reverts commit 680c7d4fcc5c8f72711c8b2de45c9aa2671b2bdd. * tribeOS - change end point URL * restore .js extensions * fixed issue "newline required at end of file" --- modules/tribeosBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tribeosBidAdapter.js b/modules/tribeosBidAdapter.js index 201e71ad2d1..80361aa3fdb 100644 --- a/modules/tribeosBidAdapter.js +++ b/modules/tribeosBidAdapter.js @@ -5,7 +5,7 @@ import {BANNER} from '../src/mediaTypes.js'; var CONSTANTS = require('../src/constants.json'); const BIDDER_CODE = 'tribeos'; -const ENDPOINT_URL = 'https://bidder-api-us-east.tribeos.io/prebid/'; +const ENDPOINT_URL = 'https://bidder.tribeos.tech/prebid/'; const LOG_PREFIX = 'TRIBEOS: '; export const spec = { code: BIDDER_CODE, From 198c53bb83d659f073bf0faa515c9045c576331c Mon Sep 17 00:00:00 2001 From: "Evgen A. Epanchin" Date: Tue, 19 May 2020 22:36:13 +0300 Subject: [PATCH 325/496] LoopMe adapter: Added mediaType field into bid response (#5233) --- modules/loopmeBidAdapter.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/loopmeBidAdapter.js b/modules/loopmeBidAdapter.js index c0112bc174a..919e0b17294 100644 --- a/modules/loopmeBidAdapter.js +++ b/modules/loopmeBidAdapter.js @@ -123,6 +123,7 @@ export const spec = { dealId: responseObj.dealId, netRevenue: responseObj.netRevenue, vastUrl: responseObj.vastUrl, + mediaType: VIDEO, renderer } ]; @@ -139,7 +140,8 @@ export const spec = { currency: responseObj.currency, creativeId: responseObj.creativeId, dealId: responseObj.dealId, - netRevenue: responseObj.netRevenue + netRevenue: responseObj.netRevenue, + mediaType: BANNER } ]; } From b404d20f69be374840cad53651c9baffc7282052 Mon Sep 17 00:00:00 2001 From: Kanchika - Automatad Date: Wed, 20 May 2020 03:24:02 +0530 Subject: [PATCH 326/496] Automatad Bid Adapter: Update CPM sent with WinNotification (#5267) * updated winurl params * lint fixes --- modules/automatadBidAdapter.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/automatadBidAdapter.js b/modules/automatadBidAdapter.js index 4a9e6b6a1e4..95d225cb5f7 100644 --- a/modules/automatadBidAdapter.js +++ b/modules/automatadBidAdapter.js @@ -99,15 +99,17 @@ export const spec = { }, onBidWon: function(bid) { if (!bid.nurl) { return } + const winCpm = (bid.hasOwnProperty('originalCpm')) ? bid.originalCpm : bid.cpm + const winCurr = (bid.hasOwnProperty('originalCurrency') && bid.hasOwnProperty('originalCpm')) ? bid.originalCurrency : bid.currency const winUrl = bid.nurl.replace( /\$\{AUCTION_PRICE\}/, - bid.cpm + winCpm ).replace( /\$\{AUCTION_IMP_ID\}/, bid.requestId ).replace( /\$\{AUCTION_CURRENCY\}/, - bid.currency + winCurr ).replace( /\$\{AUCTION_ID\}/, bid.auctionId From 35417e2627b00f9c97555c2825a8ae7b872ad515 Mon Sep 17 00:00:00 2001 From: DeepthiNeeladri Date: Wed, 20 May 2020 14:34:42 +0530 Subject: [PATCH 327/496] Onevideo Adaptor -Hp param support (#5257) * outstream changes * removing global filtet * reverting page * message * adapter change * remove space * testcases * testpage * spaces for test page * renderer exist case * reverting package-lock.json * adding schain object * adding tagid * syntaxx error fix * video.html * space trailing * space * tagid * inventoryId and placement * rewarded video * added unit test case * comment * hp param * test cases * version * .md file * Indention Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana Co-authored-by: Deepthi Neeladri Sravana --- modules/oneVideoBidAdapter.js | 5 ++++- modules/oneVideoBidAdapter.md | 2 ++ test/spec/modules/oneVideoBidAdapter_spec.js | 4 +++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/oneVideoBidAdapter.js b/modules/oneVideoBidAdapter.js index e43e7eff0f8..fdeeaf68581 100644 --- a/modules/oneVideoBidAdapter.js +++ b/modules/oneVideoBidAdapter.js @@ -3,7 +3,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'oneVideo'; export const spec = { code: 'oneVideo', - VERSION: '3.0.2', + VERSION: '3.0.3', ENDPOINT: 'https://ads.adaptv.advertising.com/rtb/openrtb?ext_id=', SYNC_ENDPOINT1: 'https://cm.g.doubleclick.net/pixel?google_nid=adaptv_dbm&google_cm&google_sc', SYNC_ENDPOINT2: 'https://pr-bh.ybp.yahoo.com/sync/adaptv_ortb/{combo_uid}', @@ -257,6 +257,9 @@ function getRequestData(bid, consentData, bidRequest) { } } } + if (bid.params.video.hp == 1) { + bidData.source.ext.schain.nodes[0].hp = bid.params.video.hp; + } } if (bid.params.site && bid.params.site.id) { bidData.site.id = bid.params.site.id diff --git a/modules/oneVideoBidAdapter.md b/modules/oneVideoBidAdapter.md index 1805a6869d3..d50d57a4628 100644 --- a/modules/oneVideoBidAdapter.md +++ b/modules/oneVideoBidAdapter.md @@ -35,6 +35,7 @@ Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to delivery: [2], playbackmethod: [1,5], sid: , + hp: 1, rewarded: 1, placement: 1, inventoryid: 123, @@ -79,6 +80,7 @@ Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to delivery: [2], playbackmethod: [1,5], sid: , + hp: 1, rewarded: 1, placement: 1, inventoryid: 123, diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js index 45d59683942..b65bf02562b 100644 --- a/test/spec/modules/oneVideoBidAdapter_spec.js +++ b/test/spec/modules/oneVideoBidAdapter_spec.js @@ -47,6 +47,7 @@ describe('OneVideoBidAdapter', function () { sid: 134, rewarded: 1, placement: 1, + hp: 1, inventoryid: 123 }, site: { @@ -202,7 +203,7 @@ describe('OneVideoBidAdapter', function () { const placement = bidRequest.params.video.placement; const rewarded = bidRequest.params.video.rewarded; const inventoryid = bidRequest.params.video.inventoryid; - const VERSION = '3.0.2'; + const VERSION = '3.0.3'; expect(data.imp[0].video.w).to.equal(width); expect(data.imp[0].video.h).to.equal(height); expect(data.imp[0].bidfloor).to.equal(bidRequest.params.bidfloor); @@ -350,6 +351,7 @@ describe('OneVideoBidAdapter', function () { const data = requests[0].data; expect(data.source.ext.schain.nodes[0].sid).to.equal(bidRequest.params.video.sid); expect(data.source.ext.schain.nodes[0].rid).to.equal(data.id); + expect(data.source.ext.schain.nodes[0].hp).to.equal(bidRequest.params.video.hp); }); }); describe('should send banner object', function () { From ee0fae970e45d03ffd5a1cd815d8f675d37da3fa Mon Sep 17 00:00:00 2001 From: Meng <5110935+edmonl@users.noreply.github.com> Date: Wed, 20 May 2020 07:46:40 -0400 Subject: [PATCH 328/496] New bidder adapter: pubgenius (#5206) * add bid adapter * fix doc * fix endpoint and add user syncs * fix endpoint in tests * send user id and time out * more tests * fix PR feedback * add test bidder param * send test as numeric boolean * add comment about test bid CPM * actually the mime type should be text/plain --- modules/pubgeniusBidAdapter.js | 208 +++++++++ modules/pubgeniusBidAdapter.md | 65 +++ test/spec/modules/pubgeniusBidAdapter_spec.js | 439 ++++++++++++++++++ 3 files changed, 712 insertions(+) create mode 100644 modules/pubgeniusBidAdapter.js create mode 100644 modules/pubgeniusBidAdapter.md create mode 100644 test/spec/modules/pubgeniusBidAdapter_spec.js diff --git a/modules/pubgeniusBidAdapter.js b/modules/pubgeniusBidAdapter.js new file mode 100644 index 00000000000..d42073b3da5 --- /dev/null +++ b/modules/pubgeniusBidAdapter.js @@ -0,0 +1,208 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { + deepAccess, + deepSetValue, + inIframe, + isArrayOfNums, + isInteger, + isNumber, + isStr, + logError, + parseQueryStringParameters, +} from '../src/utils.js'; + +const BIDDER_VERSION = '1.0.0'; +const BASE_URL = 'https://ortb.adpearl.io'; +const AUCTION_URL = BASE_URL + '/prebid/auction'; + +export const spec = { + code: 'pubgenius', + + supportedMediaTypes: [ BANNER ], + + isBidRequestValid(bid) { + const adUnitId = bid.params.adUnitId; + if (!isStr(adUnitId) && !isInteger(adUnitId)) { + logError('pubgenius bidder params: adUnitId must be a string or integer.'); + return false; + } + + const sizes = deepAccess(bid, 'mediaTypes.banner.sizes'); + return Boolean(sizes && sizes.length) && sizes.every(size => isArrayOfNums(size, 2)); + }, + + buildRequests: function (bidRequests, bidderRequest) { + const data = { + id: bidderRequest.auctionId, + imp: bidRequests.map(buildImp), + tmax: config.getConfig('bidderTimeout'), + ext: { + pbadapter: { + version: BIDDER_VERSION, + }, + }, + }; + + const site = buildSite(bidderRequest); + if (site) { + data.site = site; + } + + const gdpr = bidderRequest.gdprConsent; + if (gdpr) { + const applies = gdpr.gdprApplies; + const consent = gdpr.consentString; + deepSetValue(data, 'regs.ext.gdpr', numericBoolean(applies)); + if (applies && consent) { + deepSetValue(data, 'user.ext.consent', consent); + } + } + + const usp = bidderRequest.uspConsent; + if (usp) { + deepSetValue(data, 'regs.ext.us_privacy', usp); + } + + const schain = bidderRequest.schain; + if (schain) { + deepSetValue(data, 'source.ext.schain', schain); + } + + if (config.getConfig('coppa')) { + deepSetValue(data, 'regs.coppa', 1); + } + + const bidUserIdAsEids = deepAccess(bidRequests, '0.userIdAsEids'); + if (bidUserIdAsEids && bidUserIdAsEids.length) { + const eids = bidUserIdAsEids.filter(eid => eid.source === 'adserver.org'); + if (eids.length) { + deepSetValue(data, 'user.ext.eids', eids); + } + } + + return { + method: 'POST', + url: AUCTION_URL, + data, + }; + }, + + interpretResponse({ body }) { + const bidResponses = []; + const currency = body.cur || 'USD'; + const seatbids = body.seatbid; + + if (seatbids) { + seatbids.forEach(seatbid => { + seatbid.bid.forEach(bid => { + const bidResponse = interpretBid(bid); + bidResponse.currency = currency; + bidResponses.push(bidResponse); + }); + }); + } + + return bidResponses; + }, + + getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) { + const syncs = [] + + if (syncOptions.iframeEnabled) { + let params = {}; + + if (gdprConsent) { + params.gdpr = numericBoolean(gdprConsent.gdprApplies); + if (gdprConsent.consentString) { + params.consent = gdprConsent.consentString; + } + } + + if (uspConsent) { + params.us_privacy = uspConsent; + } + + const qs = parseQueryStringParameters(params); + syncs.push({ + type: 'iframe', + url: `${BASE_URL}/usersync/pixels.html?${qs}`, + }); + } + + return syncs; + }, + + onTimeout(data) { + ajax(`${BASE_URL}/prebid/events?type=timeout`, null, JSON.stringify(data), { + method: 'POST', + }); + }, +}; + +function buildImp(bid) { + const imp = { + id: bid.bidId, + banner: { + format: deepAccess(bid, 'mediaTypes.banner.sizes').map(size => ({ w: size[0], h: size[1] })), + topframe: numericBoolean(!inIframe()), + }, + tagid: String(bid.params.adUnitId), + }; + + const bidFloor = bid.params.bidFloor; + if (isNumber(bidFloor)) { + imp.bidfloor = bidFloor; + } + + const pos = bid.params.position; + if (isInteger(pos)) { + imp.banner.pos = pos; + } + + if (bid.params.test) { + deepSetValue(imp, 'ext.test', 1); + } + + return imp; +} + +function buildSite(bidderRequest) { + const pageUrl = config.getConfig('pageUrl') || bidderRequest.refererInfo.referer; + if (pageUrl) { + return { + page: pageUrl, + }; + } + + return null; +} + +function interpretBid(bid) { + const bidResponse = { + requestId: bid.impid, + cpm: bid.price, + width: bid.w, + height: bid.h, + ad: bid.adm, + ttl: bid.exp, + creativeId: bid.crid, + netRevenue: true, + }; + + if (bid.adomain && bid.adomain.length) { + bidResponse.meta = { + advertiserDomains: bid.adomain, + }; + } + + return bidResponse; +} + +function numericBoolean(value) { + return value ? 1 : 0; +} + +registerBidder(spec); diff --git a/modules/pubgeniusBidAdapter.md b/modules/pubgeniusBidAdapter.md new file mode 100644 index 00000000000..66851af9c3f --- /dev/null +++ b/modules/pubgeniusBidAdapter.md @@ -0,0 +1,65 @@ +# Overview + +``` +Module Name: pubGENIUS Bidder Adapter +Module Type: Bidder Adapter +Maintainer: meng@pubgenius.io +``` + +# Description + +Module that connects to pubGENIUS's demand sources + +# Test Parameters + +Test bids have $0.01 CPM by default. Use `bidFloor` in bidder params to control CPM for testing purposes. + +``` +var adUnits = [ + { + code: 'test-desktop-banner', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bids: [ + { + bidder: 'pubgenius', + params: { + adUnitId: '1000', + test: true + } + } + ] + }, + { + code: 'test-mobile-banner', + mediaTypes: { + banner: { + sizes: [[320, 50]] + } + }, + bids: [ + { + bidder: 'pubgenius', + params: { + adUnitId: '1000', + bidFloor: 0.5, + test: true + } + } + ] + } +]; +``` + +# Optional Config + +By default, the adapter uses the page URL as provided in referer info by Prebid.js. +The following config overrides this behavior and specifies the URL to be used: +``` +pbjs.setConfig({ + pageUrl: 'https://example.com/top-page-url/' +}); +``` diff --git a/test/spec/modules/pubgeniusBidAdapter_spec.js b/test/spec/modules/pubgeniusBidAdapter_spec.js new file mode 100644 index 00000000000..c510be99402 --- /dev/null +++ b/test/spec/modules/pubgeniusBidAdapter_spec.js @@ -0,0 +1,439 @@ +import { expect } from 'chai'; + +import { spec } from 'modules/pubgeniusBidAdapter.js'; +import { deepClone, parseQueryStringParameters } from 'src/utils.js'; +import { config } from 'src/config.js'; +import { server } from 'test/mocks/xhr.js'; + +const { + code, + supportedMediaTypes, + isBidRequestValid, + buildRequests, + interpretResponse, + getUserSyncs, + onTimeout, +} = spec; + +describe('pubGENIUS adapter', () => { + describe('code', () => { + it('should be pubgenius', () => { + expect(code).to.equal('pubgenius'); + }); + }); + + describe('supportedMediaTypes', () => { + it('should contain only banner', () => { + expect(supportedMediaTypes).to.deep.equal(['banner']); + }); + }); + + describe('isBidRequestValid', () => { + let bid = null; + + beforeEach(() => { + bid = { + mediaTypes: { + banner: { + sizes: [[300, 600], [300, 250]], + }, + }, + params: { + adUnitId: 1112, + }, + }; + }); + + it('should return true with numeric adUnitId ', () => { + expect(isBidRequestValid(bid)).to.be.true; + }); + + it('should return true with string adUnitId ', () => { + bid.params.adUnitId = '1112'; + + expect(isBidRequestValid(bid)).to.be.true; + }); + + it('should return false without adUnitId', () => { + delete bid.params.adUnitId; + + expect(isBidRequestValid(bid)).to.be.false; + }); + + it('should return false with adUnitId of invalid type', () => { + bid.params.adUnitId = [1112]; + + expect(isBidRequestValid(bid)).to.be.false; + }); + + it('should return false with empty sizes', () => { + bid.mediaTypes.banner.sizes = []; + + expect(isBidRequestValid(bid)).to.be.false; + }); + + it('should return false with invalid size', () => { + bid.mediaTypes.banner.sizes = [[300, 600, 250]]; + + expect(isBidRequestValid(bid)).to.be.false; + }); + }); + + describe('buildRequests', () => { + const origBidderTimeout = config.getConfig('bidderTimeout'); + const origPageUrl = config.getConfig('pageUrl'); + const origCoppa = config.getConfig('coppa'); + + after(() => { + config.setConfig({ + bidderTimeout: origBidderTimeout, + pageUrl: origPageUrl, + coppa: origCoppa, + }); + }); + + let bidRequest = null; + let bidderRequest = null; + let expectedRequest = null; + + beforeEach(() => { + bidRequest = { + adUnitCode: 'test-div', + auctionId: 'fake-auction-id', + bidId: 'fakebidid', + bidder: 'pubgenius', + bidderRequestId: 'fakebidderrequestid', + bidRequestsCount: 1, + bidderRequestsCount: 1, + bidderWinsCount: 0, + mediaTypes: { + banner: { + sizes: [[300, 600], [300, 250]], + }, + }, + params: { + adUnitId: 1112, + }, + transactionId: 'fake-transaction-id', + }; + + bidderRequest = { + auctionId: 'fake-auction-id', + bidderCode: 'pubgenius', + bidderRequestId: 'fakebidderrequestid', + refererInfo: {}, + }; + + expectedRequest = { + method: 'POST', + url: 'https://ortb.adpearl.io/prebid/auction', + data: { + id: 'fake-auction-id', + imp: [ + { + id: 'fakebidid', + banner: { + format: [{ w: 300, h: 600 }, { w: 300, h: 250 }], + topframe: 0, + }, + tagid: '1112', + }, + ], + tmax: 1200, + ext: { + pbadapter: { + version: '1.0.0', + }, + }, + }, + }; + + config.setConfig({ + bidderTimeout: 1200, + pageUrl: undefined, + coppa: undefined, + }); + }); + + it('should build basic requests correctly', () => { + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should build requests with multiple ad units', () => { + const bidRequest1 = deepClone(bidRequest); + bidRequest1.adUnitCode = 'test-div-1'; + bidRequest1.bidId = 'fakebidid1'; + bidRequest1.mediaTypes.banner.sizes = [[728, 90]]; + bidRequest1.params.adUnitId = '1111'; + + expectedRequest.data.imp.push({ + id: 'fakebidid1', + banner: { + format: [{ w: 728, h: 90 }], + topframe: 0, + }, + tagid: '1111', + }); + + expect(buildRequests([bidRequest, bidRequest1], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should take bid floor in bidder params', () => { + bidRequest.params.bidFloor = 0.5; + expectedRequest.data.imp[0].bidfloor = 0.5; + + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should take position in bidder params', () => { + bidRequest.params.position = 3; + expectedRequest.data.imp[0].banner.pos = 3; + + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should take pageUrl in config over referer in refererInfo', () => { + config.setConfig({ pageUrl: 'http://pageurl.org' }); + bidderRequest.refererInfo.referer = 'http://referer.org'; + expectedRequest.data.site = { page: 'http://pageurl.org' }; + + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should take gdprConsent when GDPR does not apply', () => { + bidderRequest.gdprConsent = { + gdprApplies: false, + consentString: 'fakeconsent', + }; + expectedRequest.data.regs = { + ext: { gdpr: 0 }, + }; + + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should take gdprConsent when GDPR applies', () => { + bidderRequest.gdprConsent = { + gdprApplies: true, + consentString: 'fakeconsent', + }; + expectedRequest.data.regs = { + ext: { gdpr: 1 }, + }; + expectedRequest.data.user = { + ext: { consent: 'fakeconsent' }, + }; + + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should take uspConsent', () => { + bidderRequest.uspConsent = '1---'; + expectedRequest.data.regs = { + ext: { us_privacy: '1---' }, + }; + + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should take schain', () => { + const schain = { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '0001', + hp: 1 + } + ] + }; + bidderRequest.schain = deepClone(schain); + expectedRequest.data.source = { + ext: { schain: deepClone(schain) }, + }; + + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should take coppa', () => { + config.setConfig({ coppa: true }); + expectedRequest.data.regs = { coppa: 1 }; + + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should take user IDs', () => { + const eid = { + source: 'adserver.org', + uids: [ + { + id: 'fake-user-id', + atype: 1, + ext: { rtiPartner: 'TDID' }, + }, + ], + }; + bidRequest.userIdAsEids = [deepClone(eid)]; + expectedRequest.data.user = { + ext: { + eids: [deepClone(eid)], + }, + }; + + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should not take unsupported user IDs', () => { + bidRequest.userIdAsEids = [ + { + source: 'pubcid.org', + uids: [ + { + id: 'fake-user-id', + atype: 1, + }, + ], + }, + ]; + + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + + it('should not take empty user IDs', () => { + bidRequest.userIdAsEids = []; + + expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); + }); + }); + + describe('interpretResponse', () => { + let serverResponse = null; + let expectedBidResponse = null; + + beforeEach(() => { + serverResponse = { + body: { + seatbid: [ + { + seat: 'pubgenius', + bid: [ + { + impid: 'fakebidid', + price: 0.3, + w: 300, + h: 250, + adm: 'fake_creative', + exp: 60, + crid: 'fakecreativeid', + }, + ], + }, + ], + }, + }; + expectedBidResponse = { + requestId: 'fakebidid', + cpm: 0.3, + currency: 'USD', + width: 300, + height: 250, + ad: 'fake_creative', + ttl: 60, + creativeId: 'fakecreativeid', + netRevenue: true, + }; + }); + + it('should interpret response correctly', () => { + expect(interpretResponse(serverResponse)).to.deep.equal([expectedBidResponse]); + }); + + it('should interpret response with adomain', () => { + serverResponse.body.seatbid[0].bid[0].adomain = ['fakeaddomain']; + expectedBidResponse.meta = { + advertiserDomains: ['fakeaddomain'], + }; + + expect(interpretResponse(serverResponse)).to.deep.equal([expectedBidResponse]); + }); + + it('should interpret no bids', () => { + expect(interpretResponse({ body: {} })).to.deep.equal([]); + }); + }); + + describe('getUserSyncs', () => { + let syncOptions = null; + let expectedSync = null; + + beforeEach(() => { + syncOptions = { + iframeEnabled: true, + pixelEnabled: true, + }; + expectedSync = { + type: 'iframe', + url: 'https://ortb.adpearl.io/usersync/pixels.html?', + }; + }); + + it('should return iframe pixels', () => { + expect(getUserSyncs(syncOptions)).to.deep.equal([expectedSync]); + }); + + it('should return empty when iframe is not enabled', () => { + syncOptions.iframeEnabled = false; + + expect(getUserSyncs(syncOptions)).to.deep.equal([]); + }); + + it('should return sync when GDPR applies', () => { + const gdprConsent = { + gdprApplies: true, + consentString: 'fake-gdpr-consent', + }; + expectedSync.url = expectedSync.url + parseQueryStringParameters({ + gdpr: 1, + consent: 'fake-gdpr-consent', + }); + + expect(getUserSyncs(syncOptions, [], gdprConsent)).to.deep.equal([expectedSync]); + }); + + it('should return sync when GDPR does not apply', () => { + const gdprConsent = { + gdprApplies: false, + }; + expectedSync.url = expectedSync.url + parseQueryStringParameters({ gdpr: 0 }); + + expect(getUserSyncs(syncOptions, [], gdprConsent)).to.deep.equal([expectedSync]); + }); + + it('should return sync with US privacy', () => { + expectedSync.url = expectedSync.url + parseQueryStringParameters({ us_privacy: '1---' }); + + expect(getUserSyncs(syncOptions, [], undefined, '1---')).to.deep.equal([expectedSync]); + }); + }); + + describe('onTimeout', () => { + it('should send timeout data', () => { + const timeoutData = { + bidder: 'pubgenius', + bidId: 'fakebidid', + params: { + adUnitId: 1234, + }, + adUnitCode: 'fake-ad-unit-code', + timeout: 3000, + auctionId: 'fake-auction-id', + }; + onTimeout(timeoutData); + + expect(server.requests[0].method).to.equal('POST'); + expect(server.requests[0].url).to.equal('https://ortb.adpearl.io/prebid/events?type=timeout'); + expect(JSON.parse(server.requests[0].requestBody)).to.deep.equal(timeoutData); + }); + }); +}); From 37526dcbff6d3ad2a8d6772845bc19fe765dde7a Mon Sep 17 00:00:00 2001 From: bjorn-lw <32431346+bjorn-lw@users.noreply.github.com> Date: Wed, 20 May 2020 14:58:16 +0200 Subject: [PATCH 329/496] SChain support (#5272) * Livewrapped bid and analytics adapter * Fixed some tests for browser compatibility * Fixed some tests for browser compatibility * Changed analytics adapter code name * Fix double quote in debug message * modified how gdpr is being passed * Added support for Publisher Common ID Module * Corrections for ttr in analytics * ANalytics updates * Auction start time stamp changed * Detect recovered ad blocked requests Make it possible to pass dynamic parameters to adapter * Collect info on ad units receiving any valid bid * Support for ID5 Pass metadata from adapter * Typo in test + eids on wrong level * Fix for Prebid 3.0 * Fix get referer * http -> https in tests * Native support * Read sizes from mediatype.banner * Revert accidental commit * Support native data collection + minor refactorings * Set analytics endpoint * Support for app parameters * Fix issue where adunits with bids were not counted on reload * Send debug info from adapter to external debugger * SChain support --- modules/livewrappedBidAdapter.js | 4 ++- .../modules/livewrappedBidAdapter_spec.js | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/modules/livewrappedBidAdapter.js b/modules/livewrappedBidAdapter.js index cda66f5eafd..78b29ab5016 100644 --- a/modules/livewrappedBidAdapter.js +++ b/modules/livewrappedBidAdapter.js @@ -58,6 +58,7 @@ export const spec = { const ifa = find(bidRequests, hasIfaParam); const bundle = find(bidRequests, hasBundleParam); const tid = find(bidRequests, hasTidParam); + const schain = bidRequests[0].schain; bidUrl = bidUrl ? bidUrl.params.bidUrl : URL; url = url ? url.params.url : (getAppDomain() || getTopWindowLocation(bidderRequest)); test = test ? test.params.test : undefined; @@ -82,7 +83,8 @@ export const spec = { cookieSupport: !utils.isSafariBrowser() && storage.cookiesAreEnabled(), rcv: getAdblockerRecovered(), adRequests: [...adRequests], - rtbData: handleEids(bidRequests) + rtbData: handleEids(bidRequests), + schain: schain }; if (config.getConfig().debug) { diff --git a/test/spec/modules/livewrappedBidAdapter_spec.js b/test/spec/modules/livewrappedBidAdapter_spec.js index 800ca744d9c..fb676f75343 100644 --- a/test/spec/modules/livewrappedBidAdapter_spec.js +++ b/test/spec/modules/livewrappedBidAdapter_spec.js @@ -788,6 +788,31 @@ describe('Livewrapped adapter tests', function () { }]); }); + it('should send schain object if available', function() { + sandbox.stub(utils, 'isSafariBrowser').callsFake(() => false); + sandbox.stub(storage, 'cookiesAreEnabled').callsFake(() => true); + let testbidRequest = clone(bidderRequest); + let schain = { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'directseller.com', + 'sid': '00001', + 'rid': 'BidRequest1', + 'hp': 1 + } + ] + }; + + testbidRequest.bids[0].schain = schain; + + let result = spec.buildRequests(testbidRequest.bids, testbidRequest); + let data = JSON.parse(result.data); + + expect(data.schain).to.deep.equal(schain); + }); + describe('interpretResponse', function () { it('should handle single success response', function() { let lwResponse = { From 8eb8d2d1691155476daa565e63a9e387fd19d881 Mon Sep 17 00:00:00 2001 From: Jimmy Tu Date: Wed, 20 May 2020 08:43:51 -0700 Subject: [PATCH 330/496] clean(openxBidderAdaptor): converted video size to numbers from strings to keep consistency between banner and video. (#5240) (cherry picked from commit bc4217b2160531ddc559dcf85b1c875588e1e9a3) --- modules/openxBidAdapter.js | 8 +++--- test/spec/modules/openxBidAdapter_spec.js | 35 +++++++++++------------ 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/modules/openxBidAdapter.js b/modules/openxBidAdapter.js index c4a90fb0930..d5630c2fad4 100644 --- a/modules/openxBidAdapter.js +++ b/modules/openxBidAdapter.js @@ -422,7 +422,7 @@ function generateVideoParameters(bid, bidderRequest) { function createVideoBidResponses(response, {bid, startTime}) { let bidResponses = []; - if (response !== undefined && response.vastUrl !== '' && response.pub_rev !== '') { + if (response !== undefined && response.vastUrl !== '' && response.pub_rev > 0) { let vastQueryParams = utils.parseUrl(response.vastUrl).search || {}; let bidResponse = {}; bidResponse.requestId = bid.bidId; @@ -431,9 +431,9 @@ function createVideoBidResponses(response, {bid, startTime}) { // true is net, false is gross bidResponse.netRevenue = true; bidResponse.currency = response.currency; - bidResponse.cpm = Number(response.pub_rev) / 1000; - bidResponse.width = response.width; - bidResponse.height = response.height; + bidResponse.cpm = parseInt(response.pub_rev, 10) / 1000; + bidResponse.width = parseInt(response.width, 10); + bidResponse.height = parseInt(response.height, 10); bidResponse.creativeId = response.adid; bidResponse.vastUrl = response.vastUrl; bidResponse.mediaType = VIDEO; diff --git a/test/spec/modules/openxBidAdapter_spec.js b/test/spec/modules/openxBidAdapter_spec.js index 49584ea8b43..a6fbc9666b9 100644 --- a/test/spec/modules/openxBidAdapter_spec.js +++ b/test/spec/modules/openxBidAdapter_spec.js @@ -1155,7 +1155,7 @@ describe('OpenxAdapter', function () { 'bidderRequestId': '22edbae2733bf6', 'auctionId': '1d1a030790a475', 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e' - } + }; mockBidderRequest = {refererInfo: {}}; }); @@ -1587,32 +1587,31 @@ describe('OpenxAdapter', function () { payload: {'bid': bidsWithMediaType[0], 'startTime': new Date()} }; const bidResponse = { - 'pub_rev': '1', + 'pub_rev': '1000', 'width': '640', 'height': '480', 'adid': '5678', - 'vastUrl': 'https://testvast.com/vastpath?colo=https://test-colo.com&ph=test-ph&ts=test-ts', + 'currency': 'AUD', + 'vastUrl': 'https://testvast.com', 'pixels': 'https://testpixels.net' }; it('should return correct bid response with MediaTypes', function () { - const expectedResponse = [ - { - 'requestId': '30b31c1838de1e', - 'cpm': 1, - 'width': '640', - 'height': '480', - 'mediaType': 'video', - 'creativeId': '5678', - 'vastUrl': 'https://testvast.com', - 'ttl': 300, - 'netRevenue': true, - 'currency': 'USD' - } - ]; + const expectedResponse = { + 'requestId': '30b31c1838de1e', + 'cpm': 1, + 'width': 640, + 'height': 480, + 'mediaType': 'video', + 'creativeId': '5678', + 'vastUrl': 'https://testvast.com', + 'ttl': 300, + 'netRevenue': true, + 'currency': 'AUD' + }; const result = spec.interpretResponse({body: bidResponse}, bidRequestsWithMediaTypes); - expect(JSON.stringify(Object.keys(result[0]).sort())).to.eql(JSON.stringify(Object.keys(expectedResponse[0]).sort())); + expect(result[0]).to.eql(expectedResponse); }); it('should return correct bid response with MediaType', function () { From a68c2f8f93b7f8bc5ad1d982f57ec729b42ac792 Mon Sep 17 00:00:00 2001 From: Scott Menzer Date: Wed, 20 May 2020 18:10:38 +0200 Subject: [PATCH 331/496] Prebid 3.20.0 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 464e1515877..3144be745f8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.20.0-pre", + "version": "3.20.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From b26a54167cce555c2f12205aba4ff1543addca8b Mon Sep 17 00:00:00 2001 From: Scott Menzer Date: Wed, 20 May 2020 18:57:41 +0200 Subject: [PATCH 332/496] Increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3144be745f8..1bee18242f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.20.0", + "version": "3.21.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From ef7acc206ec0e6c64b7619b6a87de7e179fa83b6 Mon Sep 17 00:00:00 2001 From: Aziz Saleh Date: Thu, 21 May 2020 02:57:01 -0400 Subject: [PATCH 333/496] Update onBidWon method to only execute 1 url (#5238) * Update onBidWon method to only execute 1 url * Remove un-unsed function that onBidWon was using * Switch onBidWon to use utils.triggerPixel so we can test how many times its being called (only want it called once) Co-authored-by: Aziz Hussain --- .../gpt/revcontent_example.html | 2 +- modules/revcontentBidAdapter.js | 20 +----------------- .../spec/modules/revcontentBidAdapter_spec.js | 21 +++++++++++++++++++ 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/integrationExamples/gpt/revcontent_example.html b/integrationExamples/gpt/revcontent_example.html index ad0933885f3..d7a44df3014 100644 --- a/integrationExamples/gpt/revcontent_example.html +++ b/integrationExamples/gpt/revcontent_example.html @@ -45,7 +45,7 @@ apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', userId: 673, domain: 'test.com', - endpoint: 'trends-s0.revcontent.com' + endpoint: 'trends.revcontent.com' } }] }]; diff --git a/modules/revcontentBidAdapter.js b/modules/revcontentBidAdapter.js index 270302fd617..b429f94eae0 100644 --- a/modules/revcontentBidAdapter.js +++ b/modules/revcontentBidAdapter.js @@ -3,7 +3,6 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import * as utils from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; const BIDDER_CODE = 'revcontent'; const NATIVE_PARAMS = { @@ -223,13 +222,7 @@ export const spec = { return bidResponses; }, onBidWon: function (bid) { - var winUrl = bid.nurl; - winUrl = winUrl.replace(/\$\{AUCTION_PRICE\}/, bid.cpm); - var host = extractHostname(winUrl); - - ajax(winUrl + '&viewed=1', null, {withCredentials: true}); - ajax('https://' + host + '/imp.php', null, 'v=' + encodeURIComponent(encodeURIComponent(getQueryVariable('d', winUrl))) + '&i=' + encodeURIComponent(window.location.href), {method: 'POST', contentType: 'application/x-www-form-urlencoded'}); - + utils.triggerPixel(bid.nurl); return true; } }; @@ -280,14 +273,3 @@ function extractHostname(url) { return hostname; } - -function getQueryVariable(variable, url) { - var query = url; - var vars = query.split('&'); - for (var i = 0; i < vars.length; i++) { - var pair = vars[i].split('='); - if (decodeURIComponent(pair[0]) == variable) { - return decodeURIComponent(pair[1]); - } - } -} diff --git a/test/spec/modules/revcontentBidAdapter_spec.js b/test/spec/modules/revcontentBidAdapter_spec.js index 1aa08d9469e..0a0263837c6 100644 --- a/test/spec/modules/revcontentBidAdapter_spec.js +++ b/test/spec/modules/revcontentBidAdapter_spec.js @@ -3,6 +3,7 @@ import {assert, expect} from 'chai'; import {spec} from 'modules/revcontentBidAdapter.js'; import { NATIVE } from 'src/mediaTypes.js'; import { config } from 'src/config.js'; +import * as utils from 'src/utils.js'; describe('revcontent adapter', function () { let serverResponse, bidRequest, bidResponses; @@ -327,4 +328,24 @@ describe('revcontent adapter', function () { assert.ok(result); }); }); + + describe('onBidWon', function() { + const bid = { + nurl: 'https://trends-s0.revcontent.com/push/track/?p=${AUCTION_PRICE}&d=nTCdHIfsgKOLFuV7DS1LF%2FnTk5HiFduGU65BgKgB%2BvKyG9YV7ceQWN76HMbBE0C6gwQeXUjravv3Hq5x9TT8CM6r2oUNgkGC9mhgv2yroTH9i3cSoH%2BilxyY19fMXFirtBz%2BF%2FEXKi4bsNh%2BDMPfj0L4elo%2FJEZmx4nslvOneJJjsFjJJtUJc%2F3UPivOisSCa%2B36mAgFQqt%2FSWBriYB%2BVAufz70LaGspF6T6jDzuIyVFJUpLhZVDtLRSJEzh7Lyzzw1FmYarp%2FPg0gZDY48aDdjw5A3Tlj%2Bap0cPHLDprNOyF0dmHDn%2FOVJEDRTWvrQ2JNK1t%2Fg1bGHIih0ec6XBVIBNurqRpLFBuUY6LgXCt0wRZWTByTEZ8AEv8IoYVILJAL%2BXL%2F9IyS4eTcdOUfn5X7gT8QBghCrAFrsCg8ZXKgWddTEXbpN1lU%2FzHdI5eSHkxkJ6WcYxSkY9PyripaIbmKiyb98LQMgTD%2B20RJO5dAmXTQTAcauw6IUPTjgSPEU%2Bd6L5Txd3CM00Hbd%2Bw1bREIQcpKEmlMwrRSwe4bu1BCjlh5A9gvU9Xc2sf7ekS3qPPmtp059r5IfzdNFQJB5aH9HqeDEU%2FxbMHx4ggMgojLBBL1fKrCKLAteEDQxd7PVmFJv7GHU2733vt5TnjKiEhqxHVFyi%2B0MIYMGIziM5HfUqfq3KUf%2F%2FeiCtJKXjg7FS6hOambdimSt7BdGDIZq9QECWdXsXcQqqVLwli27HYDMFVU3TWWRyjkjbhnQID9gQJlcpwIi87jVAODb6qP%2FKGQ%3D%3D', + cpm: '0.1' + }; + + beforeEach(function() { + sinon.stub(utils, 'triggerPixel'); + }); + + afterEach(function() { + utils.triggerPixel.restore(); + }); + + it('make sure only 1 ajax call is happening', function() { + spec.onBidWon(bid); + expect(utils.triggerPixel.calledOnce).to.equal(true); + }); + }); }); From 25b7189e480dd08bbb7a34d060dc2c5396ed056b Mon Sep 17 00:00:00 2001 From: CPMStar Date: Thu, 21 May 2020 06:21:18 -0700 Subject: [PATCH 334/496] Added support for GDPR, COPPA, and USP (#5210) * Added CPMStar Bid Adapter * Updated getPlayerSize for cpmstarBidAdapter * Improved cpmstarBidAdapter code coverage * updated test spec, removed empty functions, made imports relative, added warnings to erroneous server responses, and removed the default value for ad in bid response. * added test video ad unit * added support for gdpr and coppa * changed != undefined to != null * changed let to var * added unit for GDPR, COPPA, and USP. Co-authored-by: Nicholas Elek --- modules/cpmstarBidAdapter.js | 33 ++++++++++++-- modules/cpmstarBidAdapter.md | 3 ++ test/spec/modules/cpmstarBidAdapter_spec.js | 50 ++++++++++++++++----- 3 files changed, 72 insertions(+), 14 deletions(-) mode change 100644 => 100755 modules/cpmstarBidAdapter.js mode change 100644 => 100755 modules/cpmstarBidAdapter.md diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js old mode 100644 new mode 100755 index 6146e704448..b416c00c2d0 --- a/modules/cpmstarBidAdapter.js +++ b/modules/cpmstarBidAdapter.js @@ -1,7 +1,8 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import {VIDEO, BANNER} from '../src/mediaTypes.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'cpmstar'; @@ -17,12 +18,12 @@ export const spec = { supportedMediaTypes: [BANNER, VIDEO], pageID: Math.floor(Math.random() * 10e6), - getMediaType: function(bidRequest) { + getMediaType: function (bidRequest) { if (bidRequest == null) return BANNER; return !utils.deepAccess(bidRequest, 'mediaTypes.video') ? BANNER : VIDEO; }, - getPlayerSize: function(bidRequest) { + getPlayerSize: function (bidRequest) { var playerSize = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'); if (playerSize == null) return [640, 440]; if (playerSize[0] != null) playerSize = playerSize[0]; @@ -46,9 +47,33 @@ export const spec = { var mediaType = spec.getMediaType(bidRequest); var playerSize = spec.getPlayerSize(bidRequest); var videoArgs = '&fv=0' + (playerSize ? ('&w=' + playerSize[0] + '&h=' + playerSize[1]) : ''); + + var url = ENDPOINT + '?media=' + mediaType + (mediaType == VIDEO ? videoArgs : '') + + '&json=c_b&mv=1&poolid=' + utils.getBidIdParameter('placementId', bidRequest.params) + + '&reachedTop=' + encodeURIComponent(bidderRequest.refererInfo.reachedTop) + + '&requestid=' + bidRequest.bidId + + '&referer=' + encodeURIComponent(referer); + + if (bidderRequest.gdprConsent) { + if (bidderRequest.gdprConsent.consentString != null) { + url += '&gdpr_consent=' + bidderRequest.gdprConsent.consentString; + } + if (bidderRequest.gdprConsent.gdprApplies != null) { + url += '&gdpr=' + (bidderRequest.gdprConsent.gdprApplies ? 1 : 0); + } + } + + if (bidderRequest.uspConsent != null) { + url += '&us_privacy=' + bidderRequest.uspConsent; + } + + if (config.getConfig('coppa')) { + url += '&tfcd=' + (config.getConfig('coppa') ? 1 : 0); + } + requests.push({ method: 'GET', - url: ENDPOINT + '?media=' + mediaType + (mediaType == VIDEO ? videoArgs : '') + '&json=c_b&mv=1&poolid=' + utils.getBidIdParameter('placementId', bidRequest.params) + '&reachedTop=' + encodeURIComponent(bidderRequest.refererInfo.reachedTop) + '&requestid=' + bidRequest.bidId + '&referer=' + referer, + url: url, bidRequest: bidRequest, }); } diff --git a/modules/cpmstarBidAdapter.md b/modules/cpmstarBidAdapter.md old mode 100644 new mode 100755 index 7dab435b0f0..c227f19bfaf --- a/modules/cpmstarBidAdapter.md +++ b/modules/cpmstarBidAdapter.md @@ -4,6 +4,9 @@ Module Name: Cpmstar Bidder Adapter Module Type: Bidder Adapter Maintainer: josh@cpmstar.com +gdpr_supported: true +usp_supported: true +coppa_supported: true ``` # Description diff --git a/test/spec/modules/cpmstarBidAdapter_spec.js b/test/spec/modules/cpmstarBidAdapter_spec.js index 9e794d3e098..1993f28e5d5 100755 --- a/test/spec/modules/cpmstarBidAdapter_spec.js +++ b/test/spec/modules/cpmstarBidAdapter_spec.js @@ -1,6 +1,7 @@ import { expect } from 'chai'; import { spec } from 'modules/cpmstarBidAdapter.js'; import { deepClone } from 'src/utils.js'; +import { config } from 'src/config.js'; describe('Cpmstar Bid Adapter', function () { describe('isBidRequestValid', function () { @@ -15,22 +16,26 @@ describe('Cpmstar Bid Adapter', function () { expect(spec.isBidRequestValid(bid)).to.equal(false); }) - it('should return a valid player size', function() { - var bid = { mediaTypes: { - video: { - playerSize: [[960, 540]] + it('should return a valid player size', function () { + var bid = { + mediaTypes: { + video: { + playerSize: [[960, 540]] + } } - }} + } expect(spec.getPlayerSize(bid)[0]).to.equal(960); expect(spec.getPlayerSize(bid)[1]).to.equal(540); }) - it('should return a default player size', function() { - var bid = { mediaTypes: { - video: { - playerSize: null + it('should return a default player size', function () { + var bid = { + mediaTypes: { + video: { + playerSize: null + } } - }} + } expect(spec.getPlayerSize(bid)[0]).to.equal(640); expect(spec.getPlayerSize(bid)[1]).to.equal(440); }) @@ -79,6 +84,31 @@ describe('Cpmstar Bid Adapter', function () { expect(requests[0]).to.have.property('bidRequest'); expect(requests[0].url).to.include('https://dev.server.cpmstar.com/view.aspx'); }); + it('should produce a request with support for GDPR', function () { + var gdpr_bidderRequest = deepClone(bidderRequest); + gdpr_bidderRequest.gdprConsent = { + consentString: 'consentString', + gdprApplies: true + }; + var requests = spec.buildRequests(valid_bid_requests, gdpr_bidderRequest); + expect(requests[0]).to.have.property('url'); + expect(requests[0].url).to.include('gdpr_consent=consentString'); + expect(requests[0].url).to.include('gdpr=1'); + }); + it('should produce a request with support for USP', function () { + var usp_bidderRequest = deepClone(bidderRequest); + usp_bidderRequest.uspConsent = '1YYY'; + var requests = spec.buildRequests(valid_bid_requests, usp_bidderRequest); + expect(requests[0]).to.have.property('url'); + expect(requests[0].url).to.include('us_privacy=1YYY'); + }); + it('should produce a request with support for COPPA', function () { + sinon.stub(config, 'getConfig').withArgs('coppa').returns(true); + var requests = spec.buildRequests(valid_bid_requests, bidderRequest); + config.getConfig.restore(); + expect(requests[0]).to.have.property('url'); + expect(requests[0].url).to.include('tfcd=1'); + }); }) describe('interpretResponse', function () { From 67a1b1e796ca8fbf816cbea664a40f8065c2ddb0 Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Thu, 21 May 2020 21:26:10 +0530 Subject: [PATCH 335/496] Stabilize Circle CI Build Job (#5208) * run only userId module tests * stub call to coreStorage.getCookie * remove setCookie statement that adds nothing to the test --- test/spec/modules/userId_spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index b48d0a9a98c..02f65a6e53d 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -453,6 +453,7 @@ describe('User ID', function() { sandbox = sinon.createSandbox(); sandbox.stub(global, 'setTimeout').returns(2); sandbox.stub(events, 'on'); + sandbox.stub(coreStorage, 'getCookie'); // remove cookie coreStorage.setCookie('MOCKID', '', EXPIRED_COOKIE_DATE); @@ -626,11 +627,10 @@ describe('User ID', function() { }); it('does not delay auction if there are no ids to fetch', function() { - coreStorage.setCookie('MOCKID', JSON.stringify({'MOCKID': '123456778'}), new Date(Date.now() + 5000).toUTCString()); - + coreStorage.getCookie.withArgs('MOCKID').returns('123456778'); config.setConfig({ usersync: { - auctionDelay: 200, + auctionDelay: 33, syncDelay: 77, userIds: [{ name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } From 9ca46df6be4847dfddfcbdce0a66ab5a30937cbc Mon Sep 17 00:00:00 2001 From: Edge Query <52324444+edgequery@users.noreply.github.com> Date: Fri, 22 May 2020 09:42:49 +0200 Subject: [PATCH 336/496] Adding Edge Query X Adapter (with right md file) (#5266) * Add files via upload * Bug fixed * Remove some new lines * Correction Circle * Test Unit * Indent * Indent 2 space * Single quote * test unit * requestID * Rename mb to md * add md * Correcting md file * Improving gulp test to get more than 80% * Correcting double lines * Update package-lock.json * Back to original lock version * Back to original package-lock.json version Co-authored-by: Olivier --- modules/edgequeryxBidAdapter.js | 98 +++++++++++++++ modules/edgequeryxBidAdapter.md | 39 ++++++ .../spec/modules/edgequeryxBidAdapter_spec.js | 116 ++++++++++++++++++ 3 files changed, 253 insertions(+) create mode 100644 modules/edgequeryxBidAdapter.js create mode 100644 modules/edgequeryxBidAdapter.md create mode 100644 test/spec/modules/edgequeryxBidAdapter_spec.js diff --git a/modules/edgequeryxBidAdapter.js b/modules/edgequeryxBidAdapter.js new file mode 100644 index 00000000000..ee50946ee18 --- /dev/null +++ b/modules/edgequeryxBidAdapter.js @@ -0,0 +1,98 @@ +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; + +const BIDDER_CODE = 'edgequeryx'; + +export const spec = { + code: BIDDER_CODE, + aliases: ['eqx'], // short code + supportedMediaTypes: [BANNER, VIDEO], + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bid) { + return !!(bid.params && bid.params.accountId && bid.params.widgetId); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @param {BidRequest[]} validBidRequests an array of bids + * @param {BidderRequest} bidderRequest bidder request object + * @return {ServerRequest[]} Info describing the request to the server. + */ + buildRequests: function (validBidRequests, bidderRequest) { + // use bidderRequest.bids[] to get bidder-dependent request info + // if your bidder supports multiple currencies, use config.getConfig(currency) + // to find which one the ad server needs + + // pull requested transaction ID from bidderRequest.bids[].transactionId + return validBidRequests.map(bid => { + // Common bid request attributes for banner, outstream and instream. + let payload = { + accountId: bid.params.accountId, + widgetId: bid.params.widgetId, + currencyCode: 'EUR', + tagId: bid.adUnitCode, + transactionId: bid.transactionId, + timeout: config.getConfig('bidderTimeout'), + bidId: bid.bidId, + prebidVersion: '$prebid.version$' + }; + + const bannerMediaType = utils.deepAccess(bid, 'mediaTypes.banner'); + payload.sizes = bannerMediaType.sizes.map(size => ({ + w: size[0], + h: size[1] + })); + + var payloadString = JSON.stringify(payload); + + return { + method: 'POST', + url: (bid.params.domain !== undefined ? bid.params.domain : 'https://deep.edgequery.io') + '/prebid/x', + data: payloadString, + }; + }); + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @param {*} bidRequestString + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function (serverResponse, bidRequestString) { + const bidResponses = []; + let response = serverResponse.body; + try { + if (response) { + let bidResponse = { + requestId: response.requestId, + cpm: response.cpm, + currency: response.currency, + width: response.width, + height: response.height, + ad: response.ad, + ttl: response.ttl, + creativeId: response.creativeId, + netRevenue: response.netRevenue + }; + + bidResponses.push(bidResponse); + } + } catch (error) { + utils.logError('Error while parsing Edge Query X response', error); + } + return bidResponses; + } + +}; + +registerBidder(spec); diff --git a/modules/edgequeryxBidAdapter.md b/modules/edgequeryxBidAdapter.md new file mode 100644 index 00000000000..265120dfaba --- /dev/null +++ b/modules/edgequeryxBidAdapter.md @@ -0,0 +1,39 @@ +# Overview + +``` +Module Name: Edge Query X Bidder Adapter +Module Type: Bidder Adapter +Maintainer: contact@edgequery.com +``` + +# Description + +Connect to Edge Query X for bids. + +The Edge Query X adapter requires setup and approval from the Edge Query team. +Please reach out to your Technical account manager for more information. + +# Test Parameters + +## Web +``` + var adUnits = [ + { + code: 'test-div', + mediaTypes: { + banner: { + sizes: [[1, 1]] + } + }, + bids: [ + { + bidder: "edgequeryx", + params: { + accountId: "test", + widgetId: "test" + } + } + ] + } + ]; +``` \ No newline at end of file diff --git a/test/spec/modules/edgequeryxBidAdapter_spec.js b/test/spec/modules/edgequeryxBidAdapter_spec.js new file mode 100644 index 00000000000..a66c546bd7c --- /dev/null +++ b/test/spec/modules/edgequeryxBidAdapter_spec.js @@ -0,0 +1,116 @@ +import { + expect +} from 'chai'; +import { + spec +} from 'modules/edgequeryxBidAdapter.js'; +import { + newBidder +} from 'src/adapters/bidderFactory.js'; +import { + config +} from 'src/config.js'; +import * as utils from 'src/utils.js'; +import { requestBidsHook } from 'modules/consentManagement.js'; + +// Default params with optional ones +describe('Edge Query X bid adapter tests', function () { + var DEFAULT_PARAMS = [{ + bidId: 'abcd1234', + mediaTypes: { + banner: { + sizes: [ + [1, 1] + ] + } + }, + bidder: 'edgequeryx', + params: { + accountId: 'test', + widgetId: 'test' + }, + requestId: 'efgh5678', + transactionId: 'zsfgzzg' + }]; + var BID_RESPONSE = { + body: { + requestId: 'abcd1234', + cpm: 22, + width: 1, + height: 1, + creativeId: 'EQXTest', + currency: 'EUR', + netRevenue: true, + ttl: 360, + ad: '< --- awesome script --- >' + } + }; + + it('Verify build request', function () { + config.setConfig({ + 'currency': { + 'adServerCurrency': 'EUR' + } + }); + const request = spec.buildRequests(DEFAULT_PARAMS); + expect(request[0]).to.have.property('url').and.to.equal('https://deep.edgequery.io/prebid/x'); + expect(request[0]).to.have.property('method').and.to.equal('POST'); + const requestContent = JSON.parse(request[0].data); + + expect(requestContent).to.have.property('accountId').and.to.equal('test'); + expect(requestContent).to.have.property('widgetId').and.to.equal('test'); + expect(requestContent).to.have.property('sizes'); + expect(requestContent.sizes[0]).to.have.property('w').and.to.equal(1); + expect(requestContent.sizes[0]).to.have.property('h').and.to.equal(1); + }); + + it('Verify parse response', function () { + const request = spec.buildRequests(DEFAULT_PARAMS); + const bids = spec.interpretResponse(BID_RESPONSE, request[0]); + expect(bids).to.have.lengthOf(1); + const bid = bids[0]; + expect(bid.cpm).to.equal(22); + expect(bid.ad).to.equal('< --- awesome script --- >'); + expect(bid.width).to.equal(1); + expect(bid.height).to.equal(1); + expect(bid.creativeId).to.equal('EQXTest'); + expect(bid.currency).to.equal('EUR'); + expect(bid.netRevenue).to.equal(true); + expect(bid.ttl).to.equal(360); + expect(bid.requestId).to.equal(DEFAULT_PARAMS[0].bidId); + + expect(function () { + spec.interpretResponse(BID_RESPONSE, { + data: 'invalid Json' + }) + }).to.not.throw(); + }); + + it('Verifies bidder code', function () { + expect(spec.code).to.equal('edgequeryx'); + }); + + it('Verifies bidder aliases', function () { + expect(spec.aliases).to.have.lengthOf(1); + expect(spec.aliases[0]).to.equal('eqx'); + }); + + it('Verifies if bid request valid', function () { + expect(spec.isBidRequestValid(DEFAULT_PARAMS[0])).to.equal(true); + expect(spec.isBidRequestValid({})).to.equal(false); + expect(spec.isBidRequestValid({ + params: {} + })).to.equal(false); + expect(spec.isBidRequestValid({ + params: { + widgetyId: 'abcdef' + } + })).to.equal(false); + expect(spec.isBidRequestValid({ + params: { + widgetId: 'test', + accountId: 'test' + } + })).to.equal(true); + }); +}); From d59be7519acfb619f9765f5585d8b92f8515a589 Mon Sep 17 00:00:00 2001 From: hbanalytics <55453525+hbanalytics@users.noreply.github.com> Date: Fri, 22 May 2020 10:45:31 +0300 Subject: [PATCH 337/496] Update Platform One Analytics Adapter (#5265) * Added Y1 Analytics Adapter * rename y1AnalyticsAdapter in yieldoneAnalyticsAdapter * Yieldone Bid Adapter: fixes from lint check * Yieldone Analytics Adapter: fix endpoint protocol * Added spec file for yieldone Analytics Adapter * Add adUnitName to analytics data for Yieldone Analytics Adapter * Fix yieldone Analytics Adapter to log only id from adUnitPath * Fix bug with timeout event in Yieldone Analytics Adapter * Update yieldone analytics adapter to remove excess 'ad' field from data * Update yieldone analytics adapter * Yieldone Analytics Adapter: remove dispensable events from log * Platform One Analytics Adapter: fixes after review --- modules/yieldoneAnalyticsAdapter.js | 18 ++++++++++++------ .../modules/yieldoneAnalyticsAdapter_spec.js | 8 -------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/modules/yieldoneAnalyticsAdapter.js b/modules/yieldoneAnalyticsAdapter.js index b3f89610b72..dd40e205b07 100644 --- a/modules/yieldoneAnalyticsAdapter.js +++ b/modules/yieldoneAnalyticsAdapter.js @@ -13,6 +13,10 @@ const defaultUrl = 'https://pool.tsukiji.iponweb.net/hba'; const requestedBidders = {}; const requestedBids = {}; const referrers = {}; +const ignoredEvents = {}; +ignoredEvents[CONSTANTS.EVENTS.BID_ADJUSTMENT] = true; +ignoredEvents[CONSTANTS.EVENTS.BIDDER_DONE] = true; +ignoredEvents[CONSTANTS.EVENTS.AUCTION_END] = true; let currentAuctionId = ''; let url = defaultUrl; @@ -108,7 +112,9 @@ const yieldoneAnalytics = Object.assign(adapter({analyticsType}), { return res; }); } - eventsStorage[currentAuctionId].events.push({eventType, params}); + if (!ignoredEvents[eventType]) { + eventsStorage[currentAuctionId].events.push({eventType, params}); + } if ( eventType === CONSTANTS.EVENTS.AUCTION_END || eventType === CONSTANTS.EVENTS.BID_WON @@ -121,12 +127,12 @@ const yieldoneAnalytics = Object.assign(adapter({analyticsType}), { yieldoneAnalytics.eventsStorage[currentAuctionId].page = {url: referrers[currentAuctionId]}; yieldoneAnalytics.eventsStorage[currentAuctionId].pubId = pubId; yieldoneAnalytics.eventsStorage[currentAuctionId].wrapper_version = '$prebid.version$'; - yieldoneAnalytics.eventsStorage[currentAuctionId].events.forEach((it) => { - const adUnitNameMap = makeAdUnitNameMap(); - if (adUnitNameMap) { + const adUnitNameMap = makeAdUnitNameMap(); + if (adUnitNameMap) { + yieldoneAnalytics.eventsStorage[currentAuctionId].events.forEach((it) => { addAdUnitName(it.params, adUnitNameMap); - } - }); + }); + } } yieldoneAnalytics.sendStat(yieldoneAnalytics.eventsStorage[currentAuctionId], currentAuctionId); } diff --git a/test/spec/modules/yieldoneAnalyticsAdapter_spec.js b/test/spec/modules/yieldoneAnalyticsAdapter_spec.js index bc1001cc6c1..81a6365bba2 100644 --- a/test/spec/modules/yieldoneAnalyticsAdapter_spec.js +++ b/test/spec/modules/yieldoneAnalyticsAdapter_spec.js @@ -219,14 +219,6 @@ describe('Yieldone Prebid Analytic', function () { { eventType: constants.EVENTS.BID_TIMEOUT, params: Object.assign(request[2]) - }, - { - eventType: constants.EVENTS.AUCTION_END, - params: { - auctionId: auctionId, - adServerTargeting: fakeTargeting, - bidsReceived: preparedResponses.slice(0, 3) - } } ]; const expectedResult = { From b717cdcfa432b03972cac8543f79985410569af9 Mon Sep 17 00:00:00 2001 From: sumit sharma Date: Fri, 22 May 2020 15:13:50 +0530 Subject: [PATCH 338/496] Fix mapping data (#5271) * update mapping data refresh logic * add unit tests * put parsing in try catch block * refactor Co-authored-by: sumit sharma Co-authored-by: sumit sharma --- modules/categoryTranslation.js | 35 ++++--- src/adapters/bidderFactory.js | 39 ++++---- test/spec/modules/categoryTranslation_spec.js | 15 ++- test/spec/unit/core/bidderFactory_spec.js | 96 ++++++++++--------- 4 files changed, 108 insertions(+), 77 deletions(-) diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index 5342220d13a..23aa83cf7b0 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -68,23 +68,28 @@ export function getAdserverCategoryHook(fn, adUnitCode, bid) { export function initTranslation(url, localStorageKey) { setupBeforeHookFnOnce(addBidResponse, getAdserverCategoryHook, 50); let mappingData = storage.getDataFromLocalStorage(localStorageKey); - if (!mappingData || timestamp() < mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { - ajax(url, - { - success: (response) => { - try { - response = JSON.parse(response); - response['lastUpdated'] = timestamp(); - storage.setDataInLocalStorage(localStorageKey, JSON.stringify(response)); - } catch (error) { - logError('Failed to parse translation mapping file'); + try { + mappingData = mappingData ? JSON.parse(mappingData) : undefined; + if (!mappingData || timestamp() > mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { + ajax(url, + { + success: (response) => { + try { + response = JSON.parse(response); + response['lastUpdated'] = timestamp(); + storage.setDataInLocalStorage(localStorageKey, JSON.stringify(response)); + } catch (error) { + logError('Failed to parse translation mapping file'); + } + }, + error: () => { + logError('Failed to load brand category translation file.') } }, - error: () => { - logError('Failed to load brand category translation file.') - } - }, - ); + ); + } + } catch (error) { + logError('Failed to parse translation mapping file'); } } diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index 42aa91fa74a..85dd557a725 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -382,26 +382,31 @@ export function preloadBidderMappingFile(fn, adUnits) { let refreshInDays = (info.refreshInDays) ? info.refreshInDays : DEFAULT_REFRESHIN_DAYS; let key = (info.localStorageKey) ? info.localStorageKey : bidderSpec.getSpec().code; let mappingData = storage.getDataFromLocalStorage(key); - if (!mappingData || timestamp() < mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { - ajax(info.url, - { - success: (response) => { - try { - response = JSON.parse(response); - let mapping = { - lastUpdated: timestamp(), - mapping: response.mapping + try { + mappingData = mappingData ? JSON.parse(mappingData) : undefined; + if (!mappingData || timestamp() > mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { + ajax(info.url, + { + success: (response) => { + try { + response = JSON.parse(response); + let mapping = { + lastUpdated: timestamp(), + mapping: response.mapping + } + storage.setDataInLocalStorage(key, JSON.stringify(mapping)); + } catch (error) { + logError(`Failed to parse ${bidder} bidder translation mapping file`); } - storage.setDataInLocalStorage(key, JSON.stringify(mapping)); - } catch (error) { - logError(`Failed to parse ${bidder} bidder translation mapping file`); + }, + error: () => { + logError(`Failed to load ${bidder} bidder translation file`) } }, - error: () => { - logError(`Failed to load ${bidder} bidder translation file`) - } - }, - ); + ); + } + } catch (error) { + logError(`Failed to parse ${bidder} bidder translation mapping file`); } } }); diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js index 555fe3d6357..d4be6839e98 100644 --- a/test/spec/modules/categoryTranslation_spec.js +++ b/test/spec/modules/categoryTranslation_spec.js @@ -77,6 +77,19 @@ describe('category translation', function () { clock.restore(); }); + it('should make ajax call to update mapping file if data found in localstorage is expired', function () { + let clock = sinon.useFakeTimers(utils.timestamp()); + getLocalStorageStub.returns(JSON.stringify({ + lastUpdated: utils.timestamp() - 2 * 24 * 60 * 60 * 1000, + mapping: { + 'iab-1': '1' + } + })); + initTranslation(); + expect(fakeTranslationServer.requests.length).to.equal(1); + clock.restore(); + }); + it('should use default mapping file if publisher has not defined in config', function () { getLocalStorageStub.returns(null); initTranslation('http://sample.com', 'somekey'); @@ -84,7 +97,7 @@ describe('category translation', function () { expect(fakeTranslationServer.requests[0].url).to.equal('http://sample.com'); }); - it('should use publisher defined defined mapping file', function () { + it('should use publisher defined mapping file', function () { config.setConfig({ 'brandCategoryTranslation': { 'translationFile': 'http://sample.com' diff --git a/test/spec/unit/core/bidderFactory_spec.js b/test/spec/unit/core/bidderFactory_spec.js index 6d0595ba4d8..cab0655a29d 100644 --- a/test/spec/unit/core/bidderFactory_spec.js +++ b/test/spec/unit/core/bidderFactory_spec.js @@ -841,42 +841,32 @@ describe('preload mapping url hook', function() { let fakeTranslationServer; let getLocalStorageStub; let adapterManagerStub; + let adUnits = [{ + code: 'midroll_1', + mediaTypes: { + video: { + context: 'adpod' + } + }, + bids: [ + { + bidder: 'sampleBidder1', + params: { + placementId: 14542875, + } + } + ] + }]; beforeEach(function () { fakeTranslationServer = server; getLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); adapterManagerStub = sinon.stub(adapterManager, 'getBidAdapter'); - }); - - afterEach(function() { - getLocalStorageStub.restore(); - adapterManagerStub.restore(); - config.resetConfig(); - }); - - it('should preload mapping url file', function() { config.setConfig({ 'adpod': { 'brandCategoryExclusion': true } }); - let adUnits = [{ - code: 'midroll_1', - mediaTypes: { - video: { - context: 'adpod' - } - }, - bids: [ - { - bidder: 'sampleBidder1', - params: { - placementId: 14542875, - } - } - ] - }]; - getLocalStorageStub.returns(null); adapterManagerStub.withArgs('sampleBidder1').returns({ getSpec: function() { return { @@ -890,16 +880,21 @@ describe('preload mapping url hook', function() { } } }); + }); + + afterEach(function() { + getLocalStorageStub.restore(); + adapterManagerStub.restore(); + config.resetConfig(); + }); + + it('should preload mapping url file', function() { + getLocalStorageStub.returns(null); preloadBidderMappingFile(sinon.spy(), adUnits); expect(fakeTranslationServer.requests.length).to.equal(1); }); it('should preload mapping url file for all bidders', function() { - config.setConfig({ - 'adpod': { - 'brandCategoryExclusion': true - } - }); let adUnits = [{ code: 'midroll_1', mediaTypes: { @@ -923,19 +918,6 @@ describe('preload mapping url hook', function() { ] }]; getLocalStorageStub.returns(null); - adapterManagerStub.withArgs('sampleBidder1').returns({ - getSpec: function() { - return { - 'getMappingFileInfo': function() { - return { - url: 'http://sample.com', - refreshInDays: 7, - key: `sampleBidder1MappingFile` - } - } - } - } - }); adapterManagerStub.withArgs('sampleBidder2').returns({ getSpec: function() { return { @@ -960,4 +942,30 @@ describe('preload mapping url hook', function() { preloadBidderMappingFile(sinon.spy(), adUnits); expect(fakeTranslationServer.requests.length).to.equal(2); }); + + it('should make ajax call to update mapping file if data found in localstorage is expired', function() { + let clock = sinon.useFakeTimers(utils.timestamp()); + getLocalStorageStub.returns(JSON.stringify({ + lastUpdated: utils.timestamp() - 8 * 24 * 60 * 60 * 1000, + mapping: { + 'iab-1': '1' + } + })); + preloadBidderMappingFile(sinon.spy(), adUnits); + expect(fakeTranslationServer.requests.length).to.equal(1); + clock.restore(); + }); + + it('should not make ajax call to update mapping file if data found in localstorage and is not expired', function () { + let clock = sinon.useFakeTimers(utils.timestamp()); + getLocalStorageStub.returns(JSON.stringify({ + lastUpdated: utils.timestamp(), + mapping: { + 'iab-1': '1' + } + })); + preloadBidderMappingFile(sinon.spy(), adUnits); + expect(fakeTranslationServer.requests.length).to.equal(0); + clock.restore(); + }); }); From 0f45a8ab91b3fa4fa7e207d8d144810f322d6635 Mon Sep 17 00:00:00 2001 From: Hiroaki Kubota Date: Fri, 22 May 2020 22:23:42 +0900 Subject: [PATCH 339/496] Add craftBidAdapter (#5260) --- modules/craftBidAdapter.js | 238 ++++++++++++++++++++++ modules/craftBidAdapter.md | 35 ++++ test/spec/modules/craftBidAdapter_spec.js | 152 ++++++++++++++ 3 files changed, 425 insertions(+) create mode 100644 modules/craftBidAdapter.js create mode 100644 modules/craftBidAdapter.md create mode 100644 test/spec/modules/craftBidAdapter_spec.js diff --git a/modules/craftBidAdapter.js b/modules/craftBidAdapter.js new file mode 100644 index 00000000000..3838f5dee59 --- /dev/null +++ b/modules/craftBidAdapter.js @@ -0,0 +1,238 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { auctionManager } from '../src/auctionManager.js'; +import find from 'core-js-pure/features/array/find.js'; +import includes from 'core-js-pure/features/array/includes.js'; +import { getStorageManager } from '../src/storageManager.js'; + +const BIDDER_CODE = 'craft'; +const URL = 'https://gacraft.jp/prebid-v3'; +const TTL = 360; +const storage = getStorageManager(); + +export const spec = { + code: BIDDER_CODE, + aliases: ['craft'], + supportedMediaTypes: [BANNER], + + isBidRequestValid: function(bid) { + return !!bid.params.sitekey && !!bid.params.placementId && !isAmp(); + }, + + buildRequests: function(bidRequests, bidderRequest) { + const tags = bidRequests.map(bidToTag); + const schain = bidRequests[0].schain; + const payload = { + tags: [...tags], + ua: navigator.userAgent, + sdk: { + version: '$prebid.version$' + }, + schain: schain + }; + if (bidderRequest && bidderRequest.gdprConsent) { + payload.gdpr_consent = { + consent_string: bidderRequest.gdprConsent.consentString, + consent_required: bidderRequest.gdprConsent.gdprApplies + }; + } + if (bidderRequest && bidderRequest.uspConsent) { + payload.us_privacy = bidderRequest.uspConsent; + } + if (bidderRequest && bidderRequest.refererInfo) { + let refererinfo = { + rd_ref: bidderRequest.refererInfo.referer, + rd_top: bidderRequest.refererInfo.reachedTop, + rd_ifs: bidderRequest.refererInfo.numIframes, + }; + if (bidderRequest.refererInfo.stack) { + refererinfo.rd_stk = bidderRequest.refererInfo.stack.join(','); + } + payload.referrer_detection = refererinfo; + } + const request = formatRequest(payload, bidderRequest); + return request; + }, + + interpretResponse: function(serverResponse, {bidderRequest}) { + try { + serverResponse = serverResponse.body; + const bids = []; + if (!serverResponse) { + return []; + } + if (serverResponse.error) { + let errorMessage = `in response for ${bidderRequest.bidderCode} adapter`; + if (serverResponse.error) { + errorMessage += `: ${serverResponse.error}`; + } + utils.logError(errorMessage); + return bids; + } + if (serverResponse.tags) { + serverResponse.tags.forEach(serverBid => { + const rtbBid = getRtbBid(serverBid); + if (rtbBid) { + if (rtbBid.cpm !== 0 && includes(this.supportedMediaTypes, rtbBid.ad_type)) { + const bid = newBid(serverBid, rtbBid, bidderRequest); + bid.mediaType = parseMediaType(rtbBid); + bids.push(bid); + } + } + }); + } + return bids; + } catch (e) { + return []; + } + }, + + transformBidParams: function(params, isOpenRtb) { + params = utils.convertTypes({ + 'sitekey': 'string', + 'placementId': 'string', + 'keywords': utils.transformBidderParamKeywords + }, params); + if (isOpenRtb) { + if (isPopulatedArray(params.keywords)) { + params.keywords.forEach(deleteValues); + } + Object.keys(params).forEach(paramKey => { + let convertedKey = utils.convertCamelToUnderscore(paramKey); + if (convertedKey !== paramKey) { + params[convertedKey] = params[paramKey]; + delete params[paramKey]; + } + }); + } + return params; + }, + + onBidWon: function(bid) { + var xhr = new XMLHttpRequest(); + xhr.open('POST', bid._prebidWon); + xhr.send(); + } +}; + +function isPopulatedArray(arr) { + return !!(utils.isArray(arr) && arr.length > 0); +} + +function deleteValues(keyPairObj) { + if (isPopulatedArray(keyPairObj.value) && keyPairObj.value[0] === '') { + delete keyPairObj.value; + } +} + +function hasPurpose1Consent(bidderRequest) { + let result = true; + if (bidderRequest && bidderRequest.gdprConsent) { + if (bidderRequest.gdprConsent.gdprApplies && bidderRequest.gdprConsent.apiVersion === 2) { + result = !!(utils.deepAccess(bidderRequest.gdprConsent, 'vendorData.purpose.consents.1') === true); + } + } + return result; +} + +function formatRequest(payload, bidderRequest) { + let options = {}; + if (!hasPurpose1Consent(bidderRequest)) { + options = { + withCredentials: false + }; + } + const payloadString = JSON.stringify(payload); + return { + method: 'POST', + url: URL, + data: payloadString, + bidderRequest, + options + }; +} + +function newBid(serverBid, rtbBid, bidderRequest) { + const bidRequest = utils.getBidRequest(serverBid.uuid, [bidderRequest]); + const bid = { + requestId: serverBid.uuid, + cpm: rtbBid.cpm, + currency: 'JPY', + width: rtbBid.rtb.banner.width, + height: rtbBid.rtb.banner.height, + ad: rtbBid.rtb.banner.content, + ttl: TTL, + creativeId: rtbBid.creative_id, + netRevenue: false, // ??? + dealId: rtbBid.deal_id, + meta: null, + _adUnitCode: bidRequest.adUnitCode, + _bidKey: serverBid.bid_key, + _prebidWon: serverBid.won_url, + }; + return bid; +} + +function bidToTag(bid) { + const tag = {}; + for (var k in bid.params) { + tag[k] = bid.params[k]; + } + try { + if (storage.hasLocalStorage()) { + tag.uid = JSON.parse(storage.getDataFromLocalStorage(`${bid.params.sitekey}_uid`)); + } + } catch (e) { + } + tag.sizes = bid.sizes; + tag.primary_size = tag.sizes[0]; + tag.ad_types = []; + tag.uuid = bid.bidId; + if (!utils.isEmpty(bid.params.keywords)) { + let keywords = utils.transformBidderParamKeywords(bid.params.keywords); + if (keywords.length > 0) { + keywords.forEach(deleteValues); + } + tag.keywords = keywords; + } + let adUnit = find(auctionManager.getAdUnits(), au => bid.transactionId === au.transactionId); + if (adUnit && adUnit.mediaTypes && adUnit.mediaTypes.banner) { + tag.ad_types.push(BANNER); + } + + if (tag.ad_types.length === 0) { + delete tag.ad_types; + } + + return tag; +} + +function getRtbBid(tag) { + return tag && tag.ads && tag.ads.length && find(tag.ads, ad => ad.rtb); +} + +function parseMediaType(rtbBid) { + const adType = rtbBid.ad_type; + if (adType === VIDEO) { + return VIDEO; + } else if (adType === NATIVE) { + return NATIVE; + } else { + return BANNER; + } +} + +function isAmp() { + try { + const ampContext = window.context || window.parent.context; + if (ampContext && ampContext.pageViewId) { + return ampContext; + } + return false; + } catch (e) { + return false; + } +} + +registerBidder(spec); diff --git a/modules/craftBidAdapter.md b/modules/craftBidAdapter.md new file mode 100644 index 00000000000..d1a8daeab73 --- /dev/null +++ b/modules/craftBidAdapter.md @@ -0,0 +1,35 @@ +# Overview + +``` +Module Name: Craft Bid Adapter +Module Type: Bidder Adapter +Maintainer: system@gacraft.jp +``` + +# Description + +Connects to craft exchange for bids. + +Craft bid adapter supports Banner. + +# Test Parameters +``` +var adUnits = [ + // Banner adUnit + { + code: '/21998384947/prebid-example', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bids: [{ + bidder: 'craft', + params: { + sitekey: 'craft-prebid-example', + placementId: '1234abcd' + } + }] + } +]; +``` diff --git a/test/spec/modules/craftBidAdapter_spec.js b/test/spec/modules/craftBidAdapter_spec.js new file mode 100644 index 00000000000..ef7dd7c3232 --- /dev/null +++ b/test/spec/modules/craftBidAdapter_spec.js @@ -0,0 +1,152 @@ +import {expect} from 'chai'; +import {spec} from 'modules/craftBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; +import {config} from 'src/config.js'; + +describe('craftAdapter', function () { + let adapter = newBidder(spec); + + describe('inherited functions', function () { + it('exists and is a function', function () { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', function () { + before(function() { + this.windowContext = window.context; + window.context = null; + }); + + after(function() { + window.context = this.windowContext; + }); + let bid = { + bidder: 'craft', + params: { + sitekey: 'craft-prebid-example', + placementId: '1234abcd' + }, + }; + + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when params.sitekey not found', function () { + let bid = Object.assign({}, bid); + delete bid.params; + bid.params = { + placementId: '1234abcd' + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when params.placementId not found', function () { + let bid = Object.assign({}, bid); + delete bid.params; + bid.params = { + sitekey: 'craft-prebid-example' + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when AMP cotext found', function () { + window.context = { + pageViewId: 'xxx' + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + let bidRequests = [{ + bidder: 'craft', + params: { + 'sitekey': 'craft-prebid-example', + 'placementId': '1234abcd' + }, + adUnitCode: '/21998384947/prebid-example', + sizes: [[300, 250]], + bidId: '0396fae4eb5f47', + bidderRequestId: '4a859978b5d4bd', + auctionId: '8720f980-4639-4150-923a-e96da2f1de36', + transactionId: 'e0c52da2-c008-491c-a910-c6765d948700', + }]; + let bidderRequest = { + refererInfo: { + referer: 'https://www.gacraft.jp/publish/craft-prebid-example.html' + } + }; + it('sends bid request to ENDPOINT via POST', function () { + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.method).to.equal('POST'); + expect(request.url).to.equal('https://gacraft.jp/prebid-v3'); + let data = JSON.parse(request.data); + expect(data.tags).to.deep.equals([{ + sitekey: 'craft-prebid-example', + placementId: '1234abcd', + uid: null, + sizes: [[300, 250]], + primary_size: [300, 250], + uuid: '0396fae4eb5f47' + }]); + expect(data.referrer_detection).to.deep.equals({ + rd_ref: 'https://www.gacraft.jp/publish/craft-prebid-example.html' + }); + }); + }); + + describe('interpretResponse', function() { + let serverResponse = { + body: { + tags: [{ + uuid: '0396fae4eb5f47', + bid_key: '72038482-c4c3-4055-9e7e-0579585bb421', + won_url: 'https://www.gacraft.jp/publish/won', + ads: [{ + content_source: 'rtb', + ad_type: 'banner', + creative_id: 9999, + cpm: 10.01, + deal_id: '8DEF60EFDFB5', + rtb: { + banner: { + content: '', + width: 300, + height: 250 + }, + } + }] + }], + } + }; + let bidderRequest = { + bids: [{ + bidId: '0396fae4eb5f47', + adUnitCode: 'craft-prebid-example' + }] + }; + it('should get correct bid response', function() { + let bids = spec.interpretResponse(serverResponse, {bidderRequest: bidderRequest}); + expect(bids).to.have.lengthOf(1); + expect(bids[0]).to.deep.equals({ + _adUnitCode: 'craft-prebid-example', + _bidKey: '72038482-c4c3-4055-9e7e-0579585bb421', + _prebidWon: 'https://www.gacraft.jp/publish/won', + ad: '', + cpm: 10.01, + creativeId: 9999, + currency: 'JPY', + dealId: '8DEF60EFDFB5', + height: 250, + mediaType: 'banner', + meta: null, + netRevenue: false, + requestId: '0396fae4eb5f47', + ttl: 360, + width: 300, + }); + }); + }); +}); From 9bbc8106545cf73b3fb54eab9587d3b3594862bb Mon Sep 17 00:00:00 2001 From: Nick Peceniak Date: Fri, 22 May 2020 07:29:44 -0600 Subject: [PATCH 340/496] Add min_duration and max_duration parameter to spotxBidAdapter (#5286) Co-authored-by: Nick Peceniak --- modules/spotxBidAdapter.js | 8 ++++++++ test/spec/modules/spotxBidAdapter_spec.js | 20 +++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/modules/spotxBidAdapter.js b/modules/spotxBidAdapter.js index 210153548b2..515360d482e 100644 --- a/modules/spotxBidAdapter.js +++ b/modules/spotxBidAdapter.js @@ -160,6 +160,14 @@ export const spec = { spotxReq.video.startdelay = 0 + Boolean(utils.getBidIdParameter('start_delay', bid.params)); } + if (utils.getBidIdParameter('min_duration', bid.params) != '') { + spotxReq.video.minduration = utils.getBidIdParameter('min_duration', bid.params); + } + + if (utils.getBidIdParameter('max_duration', bid.params) != '') { + spotxReq.video.maxduration = utils.getBidIdParameter('max_duration', bid.params); + } + if (bid.crumbs && bid.crumbs.pubcid) { pubcid = bid.crumbs.pubcid; } diff --git a/test/spec/modules/spotxBidAdapter_spec.js b/test/spec/modules/spotxBidAdapter_spec.js index 9c6e6071155..56936dcfc62 100644 --- a/test/spec/modules/spotxBidAdapter_spec.js +++ b/test/spec/modules/spotxBidAdapter_spec.js @@ -144,7 +144,9 @@ describe('the spotx adapter', function () { price_floor: 123, start_delay: true, number_of_ads: 2, - spotx_all_google_consent: 1 + spotx_all_google_consent: 1, + min_duration: 5, + max_duration: 10 }; bid.userId = { @@ -169,6 +171,10 @@ describe('the spotx adapter', function () { request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.id).to.equal(54321); + expect(request.data.imp.video).to.contain({ + minduration: 5, + maxduration: 10 + }) expect(request.data.imp.video.ext).to.deep.equal({ ad_volume: 1, hide_skin: 1, @@ -297,6 +303,18 @@ describe('the spotx adapter', function () { expect(request.data.user.ext.consent).to.equal('consent123'); expect(request.data.regs.ext.us_privacy).to.equal('1YYY'); }); + + it('should pass min and max duration params', function() { + var request; + + bid.params.min_duration = 3 + bid.params.max_duration = 15 + + request = spec.buildRequests([bid], bidRequestObj)[0]; + + expect(request.data.imp.video.minduration).to.equal(3); + expect(request.data.imp.video.maxduration).to.equal(15); + }); }); describe('interpretResponse', function() { From 03d9d15f1cedefcb803016cb3281ba03b1a2fd72 Mon Sep 17 00:00:00 2001 From: Kamoris Date: Fri, 22 May 2020 16:09:00 +0200 Subject: [PATCH 341/496] [rtbhouse] Add schain support (#5281) --- modules/rtbhouseBidAdapter.js | 50 ++++++++++++++++++-- test/spec/modules/rtbhouseBidAdapter_spec.js | 42 ++++++++++++++++ 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/modules/rtbhouseBidAdapter.js b/modules/rtbhouseBidAdapter.js index ca760ca49eb..3337c3f1b59 100644 --- a/modules/rtbhouseBidAdapter.js +++ b/modules/rtbhouseBidAdapter.js @@ -46,9 +46,7 @@ export const spec = { site: mapSite(validBidRequests, bidderRequest), cur: DEFAULT_CURRENCY_ARR, test: validBidRequests[0].params.test || 0, - source: { - tid: validBidRequests[0].transactionId - } + source: mapSource(validBidRequests[0]), }; if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { const consentStr = (bidderRequest.gdprConsent.consentString) @@ -145,6 +143,52 @@ function mapSite(slot, bidderRequest) { } } +/** + * @param {object} slot Ad Unit Params by Prebid + * @returns {object} Source by OpenRTB 2.5 §3.2.2 + */ +function mapSource(slot) { + const source = { + tid: slot.transactionId, + }; + const schain = mapSchain(slot.schain); + if (schain) { + source.ext = { + schain: schain + } + } + return source; +} + +/** + * @param {object} schain object set by Publisher + * @returns {object} OpenRTB SupplyChain object + */ +function mapSchain(schain) { + if (!schain) { + return null; + } + if (!validateSchain(schain)) { + utils.logError('RTB House: required schain params missing'); + return null; + } + return schain; +} + +/** + * @param {object} schain object set by Publisher + * @returns {object} bool + */ +function validateSchain(schain) { + if (!schain.nodes) { + return false; + } + const requiredFields = ['asi', 'sid', 'hp']; + return schain.nodes.every(node => { + return requiredFields.every(field => node[field]); + }); +} + /** * @param {object} slot Ad Unit Params by Prebid * @returns {object} Request by OpenRTB Native Ads 1.1 §4 diff --git a/test/spec/modules/rtbhouseBidAdapter_spec.js b/test/spec/modules/rtbhouseBidAdapter_spec.js index 93b9692d2e2..efaed87dd15 100644 --- a/test/spec/modules/rtbhouseBidAdapter_spec.js +++ b/test/spec/modules/rtbhouseBidAdapter_spec.js @@ -69,6 +69,18 @@ describe('RTBHouseAdapter', () => { 'bidderRequestId': '22edbae2733bf6', 'auctionId': '1d1a030790a475', 'transactionId': 'example-transaction-id', + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'directseller.com', + 'sid': '00001', + 'rid': 'BidRequest1', + 'hp': 1 + } + ] + } } ]; const bidderRequest = { @@ -173,6 +185,36 @@ describe('RTBHouseAdapter', () => { expect(data.imp[0].bidfloor).to.equal(0.01) }); + it('should include source.ext.schain in request', () => { + const bidRequest = Object.assign([], bidRequests); + const request = spec.buildRequests(bidRequest, bidderRequest); + const data = JSON.parse(request.data); + expect(data.source.ext.schain).to.deep.equal({ + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'directseller.com', + 'sid': '00001', + 'rid': 'BidRequest1', + 'hp': 1 + } + ] + }); + }); + + it('should not include invalid schain', () => { + const bidRequest = Object.assign([], bidRequests); + bidRequest[0].schain = { + 'nodes': [{ + 'unknown_key': 1 + }] + }; + const request = spec.buildRequests(bidRequest, bidderRequest); + const data = JSON.parse(request.data); + expect(data.source).to.not.have.property('ext'); + }); + describe('native imp', () => { function basicRequest(extension) { return Object.assign({ From 565b941bb6d1a935f9fddcb8ed2483d4591b8024 Mon Sep 17 00:00:00 2001 From: relaido <63339139+relaido@users.noreply.github.com> Date: Sat, 23 May 2020 05:07:29 +0900 Subject: [PATCH 342/496] Fix referer (#5274) * add relaido adapter * remove event listener * fixed UserSyncs and e.data * fix conflicts * add referer at the end of the payload * add test Co-authored-by: ishigami_shingo --- modules/relaidoBidAdapter.js | 6 ++++-- test/spec/modules/relaidoBidAdapter_spec.js | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/modules/relaidoBidAdapter.js b/modules/relaidoBidAdapter.js index 22551877a93..a2c97495a7e 100644 --- a/modules/relaidoBidAdapter.js +++ b/modules/relaidoBidAdapter.js @@ -6,7 +6,7 @@ import { getStorageManager } from '../src/storageManager.js'; const BIDDER_CODE = 'relaido'; const BIDDER_DOMAIN = 'api.relaido.jp'; -const ADAPTER_VERSION = '1.0.0'; +const ADAPTER_VERSION = '1.0.1'; const DEFAULT_TTL = 300; const UUID_KEY = 'relaido_uuid'; @@ -51,7 +51,6 @@ function buildRequests(validBidRequests, bidderRequest) { let payload = { version: ADAPTER_VERSION, - ref: bidderRequest.refererInfo.referer, timeout_ms: bidderRequest.timeout, ad_unit_code: bidRequest.adUnitCode, auction_id: bidRequest.auctionId, @@ -74,6 +73,9 @@ function buildRequests(validBidRequests, bidderRequest) { payload.height = sizes[0][1]; } + // It may not be encoded, so add it at the end of the payload + payload.ref = bidderRequest.refererInfo.referer; + bidRequests.push({ method: 'GET', url: bidUrl, diff --git a/test/spec/modules/relaidoBidAdapter_spec.js b/test/spec/modules/relaidoBidAdapter_spec.js index f0d3a2fb6d8..492f7d2ca08 100644 --- a/test/spec/modules/relaidoBidAdapter_spec.js +++ b/test/spec/modules/relaidoBidAdapter_spec.js @@ -169,6 +169,15 @@ describe('RelaidoAdapter', function () { const request = bidRequests[0]; expect(request.mediaType).to.equal('banner'); }); + + it('The referrer should be the last', function () { + const bidRequests = spec.buildRequests([bidRequest], bidderRequest); + expect(bidRequests).to.have.lengthOf(1); + const request = bidRequests[0]; + const keys = Object.keys(request.data); + expect(keys[0]).to.equal('version'); + expect(keys[keys.length - 1]).to.equal('ref'); + }); }); describe('spec.interpretResponse', function () { From 269178478d9cfa04729d5f77cda3a92451ec0853 Mon Sep 17 00:00:00 2001 From: Adprime <64427228+Adprime@users.noreply.github.com> Date: Mon, 25 May 2020 13:01:32 +0300 Subject: [PATCH 343/496] Add keywordsparametr (#5227) * initial * fix * remove redundant language mod, use player sizes in video traff * test modify * fix * Adding Tests * add keywords param * log * log * log * fix Co-authored-by: Aigolkin1991 --- modules/adprimeBidAdapter.js | 4 +++- modules/adprimeBidAdapter.md | 8 ++++++-- test/spec/modules/adprimeBidAdapter_spec.js | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/adprimeBidAdapter.js b/modules/adprimeBidAdapter.js index d324886f7c6..306ab76f512 100644 --- a/modules/adprimeBidAdapter.js +++ b/modules/adprimeBidAdapter.js @@ -70,6 +70,7 @@ export const spec = { sizes = bid.mediaTypes[VIDEO].playerSize } } + placements.push({ placementId: bid.params.placementId, bidId: bid.bidId, @@ -77,7 +78,8 @@ export const spec = { wPlayer: sizes ? sizes[0] : 0, hPlayer: sizes ? sizes[1] : 0, traffic: bid.params.traffic || BANNER, - schain: bid.schain || {} + schain: bid.schain || {}, + keywords: bid.params.keywords || [] }); } return { diff --git a/modules/adprimeBidAdapter.md b/modules/adprimeBidAdapter.md index 0c6bed68c13..913b768d8e9 100644 --- a/modules/adprimeBidAdapter.md +++ b/modules/adprimeBidAdapter.md @@ -25,7 +25,9 @@ Module that connects to adprime demand sources bidder: 'adprime', params: { placementId: 0, - traffic: 'banner' + traffic: 'banner', + keywords: ['cat_1', 'cat_2'] + } } ] @@ -44,7 +46,9 @@ Module that connects to adprime demand sources bidder: 'adprime', params: { placementId: 0, - traffic: 'video' + traffic: 'video', + keywords: ['cat_1', 'cat_2'] + } } ] diff --git a/test/spec/modules/adprimeBidAdapter_spec.js b/test/spec/modules/adprimeBidAdapter_spec.js index 7524665e33f..3508a1175a6 100644 --- a/test/spec/modules/adprimeBidAdapter_spec.js +++ b/test/spec/modules/adprimeBidAdapter_spec.js @@ -55,7 +55,7 @@ describe('AdprimebBidAdapter', function () { expect(data.gdpr).to.not.exist; expect(data.ccpa).to.not.exist; let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes', 'hPlayer', 'wPlayer', 'schain'); + expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes', 'hPlayer', 'wPlayer', 'schain', 'keywords'); expect(placement.placementId).to.equal(0); expect(placement.bidId).to.equal('23fhj33i987f'); expect(placement.traffic).to.equal(BANNER); From 52b894414812b6b2f01bb0c6f80ef39818248de2 Mon Sep 17 00:00:00 2001 From: mamatic <52153441+mamatic@users.noreply.github.com> Date: Mon, 25 May 2020 14:39:07 +0200 Subject: [PATCH 344/496] Identity link id system - handle empty response (#5279) * IdentityLinkIdSystem - handle empty response * IdentityLinkIdSystem - add tests * IdentityLinkIdSystem - rename describe in tests --- modules/identityLinkIdSystem.js | 2 +- .../spec/modules/identityLinkIdSystem_spec.js | 92 +++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 test/spec/modules/identityLinkIdSystem_spec.js diff --git a/modules/identityLinkIdSystem.js b/modules/identityLinkIdSystem.js index a7114c2a147..7f70b7329e7 100644 --- a/modules/identityLinkIdSystem.js +++ b/modules/identityLinkIdSystem.js @@ -73,7 +73,7 @@ function getEnvelope(url, callback) { utils.logError(error); } } - callback(responseObj.envelope); + callback((responseObj && responseObj.envelope) ? responseObj.envelope : ''); }, error: error => { utils.logError(`identityLink: ID fetch encountered an error`, error); diff --git a/test/spec/modules/identityLinkIdSystem_spec.js b/test/spec/modules/identityLinkIdSystem_spec.js new file mode 100644 index 00000000000..e6850fc77b0 --- /dev/null +++ b/test/spec/modules/identityLinkIdSystem_spec.js @@ -0,0 +1,92 @@ +import {identityLinkSubmodule} from 'modules/identityLinkIdSystem.js'; +import * as utils from 'src/utils.js'; +import {server} from 'test/mocks/xhr.js'; + +const pid = '14'; +const defaultConfigParams = {pid: pid}; +const responseHeader = {'Content-Type': 'application/json'} + +describe('IdentityLinkId tests', function () { + let logErrorStub; + + beforeEach(function () { + logErrorStub = sinon.stub(utils, 'logError'); + }); + + afterEach(function () { + logErrorStub.restore(); + }); + + it('should log an error if no configParams were passed when getId', function () { + identityLinkSubmodule.getId(); + expect(logErrorStub.calledOnce).to.be.true; + }); + + it('should log an error if pid configParam was not passed when getId', function () { + identityLinkSubmodule.getId({}); + expect(logErrorStub.calledOnce).to.be.true; + }); + + it('should call the LiveRamp envelope endpoint', function () { + let callBackSpy = sinon.spy(); + let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams).callback; + submoduleCallback(callBackSpy); + let request = server.requests[0]; + expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14'); + request.respond( + 200, + responseHeader, + JSON.stringify({}) + ); + expect(callBackSpy.calledOnce).to.be.true; + }); + + it('should call the LiveRamp envelope endpoint with consent string', function () { + let callBackSpy = sinon.spy(); + let consentData = { + gdprApplies: true, + consentString: 'BOkIpDSOkIpDSADABAENCc-AAAApOAFAAMAAsAMIAcAA_g' + }; + let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, consentData).callback; + submoduleCallback(callBackSpy); + let request = server.requests[0]; + expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14&ct=1&cv=BOkIpDSOkIpDSADABAENCc-AAAApOAFAAMAAsAMIAcAA_g'); + request.respond( + 200, + responseHeader, + JSON.stringify({}) + ); + expect(callBackSpy.calledOnce).to.be.true; + }); + + it('should not throw Uncaught TypeError when envelope endpoint returns empty response', function () { + let callBackSpy = sinon.spy(); + let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams).callback; + submoduleCallback(callBackSpy); + let request = server.requests[0]; + expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14'); + request.respond( + 204, + responseHeader, + '' + ); + expect(callBackSpy.calledOnce).to.be.true; + expect(request.response).to.equal(''); + expect(logErrorStub.calledOnce).to.not.be.true; + }); + + it('should log an error and continue to callback if ajax request errors', function () { + let callBackSpy = sinon.spy(); + let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams).callback; + submoduleCallback(callBackSpy); + let request = server.requests[0]; + expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14'); + request.respond( + 503, + responseHeader, + 'Unavailable' + ); + expect(logErrorStub.calledOnce).to.be.true; + expect(callBackSpy.calledOnce).to.be.true; + }); +}); From 13c985943a837bd89e5ea8d5102dd1848e47f80e Mon Sep 17 00:00:00 2001 From: ColombiaOnline Date: Mon, 25 May 2020 23:00:07 +0530 Subject: [PATCH 345/496] update bid vlues (#5301) --- modules/colombiaBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/colombiaBidAdapter.js b/modules/colombiaBidAdapter.js index 59257babdbe..55109dbaab2 100644 --- a/modules/colombiaBidAdapter.js +++ b/modules/colombiaBidAdapter.js @@ -54,7 +54,7 @@ export const spec = { if (width == 320 && height == 50) { cpm = cpm * 0.55; } - if (cpm < 1) { + if (cpm <= 0) { return bidResponses; } if (width !== 0 && height !== 0 && cpm !== 0 && crid !== 0) { From 2b428bc60f5a4a3e043f1ef465cef969ab9aba7a Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Mon, 25 May 2020 13:33:13 -0400 Subject: [PATCH 346/496] Update ixBidAdapter.js (#5289) * Update ixBidAdapter.js If the Index adapter is aliased, this gathers the alias instead of using the hard coded 'ix' value for bidder code. * check for existence of bidderrequest bidderrequest object doesn't exist in the test spec; IX team may want to write a more extensive test here. --- modules/ixBidAdapter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 0ab761b0b7b..f4c42080f58 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -287,7 +287,8 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { const payload = {}; // Parse additional runtime configs. - const otherIxConfig = config.getConfig('ix'); + const bidderCode = (bidderRequest && bidderRequest.bidderCode) || 'ix'; + const otherIxConfig = config.getConfig(bidderCode); if (otherIxConfig) { // Append firstPartyData to r.site.page if firstPartyData exists. if (typeof otherIxConfig.firstPartyData === 'object') { From 88033c07f941b503059a392dea8c25302294e88c Mon Sep 17 00:00:00 2001 From: nyakove <43004249+nyakove@users.noreply.github.com> Date: Tue, 26 May 2020 16:16:39 +0300 Subject: [PATCH 347/496] add adWMGAnalyticsAdapter (#5261) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add adWMGAnalyticaAdapter adWMG Analytics is a module for collecting dynamic data and analytics acquisition developed by WMG. It enables compiling and saving of the auction history, its results, users’ data (geo, browser, operation system). With the access to the platform, the customer may explore the product in a preferable way. * add file extensions to imported modules circleci requirement * Update unit tests and fix LGTM alerts Update unit tests and fix LGTM alerts * Use Prebid ajaxBuilder instead of XHR Use Prebid ajaxBuilder instead of XHR --- modules/adWMGAnalyticsAdapter.js | 441 ++++++++++++++++++ modules/adWMGAnalyticsAdapter.md | 23 + .../modules/adWMGAnalyticsAdapter_spec.js | 181 +++++++ 3 files changed, 645 insertions(+) create mode 100644 modules/adWMGAnalyticsAdapter.js create mode 100644 modules/adWMGAnalyticsAdapter.md create mode 100644 test/spec/modules/adWMGAnalyticsAdapter_spec.js diff --git a/modules/adWMGAnalyticsAdapter.js b/modules/adWMGAnalyticsAdapter.js new file mode 100644 index 00000000000..8183187eb73 --- /dev/null +++ b/modules/adWMGAnalyticsAdapter.js @@ -0,0 +1,441 @@ +import adapter from '../src/AnalyticsAdapter.js'; +import adapterManager from '../src/adapterManager.js'; +import CONSTANTS from '../src/constants.json'; +import { ajax } from '../src/ajax.js'; +const analyticsType = 'endpoint'; +const url = 'https://analytics.wmgroup.us/analytic/collection'; +const { + EVENTS: { + AUCTION_INIT, + AUCTION_END, + BID_REQUESTED, + BID_WON, + BID_TIMEOUT, + NO_BID, + BID_RESPONSE + } +} = CONSTANTS; + +let timestampInit = null; + +let noBidArray = []; +let noBidObject = {}; + +let isBidArray = []; +let isBidObject = {}; + +let bidTimeOutArray = []; +let bidTimeOutObject = {}; + +let bidWonArray = []; +let bidWonObject = {}; + +let initOptions = {}; + +function postAjax(url, data) { + ajax(url, function () {}, data, {contentType: 'application/json', method: 'POST'}); +} + +function handleInitSizes(adUnits) { + return adUnits.map(function (adUnit) { + return adUnit.sizes.toString() || '' + }); +} + +function handleInitTypes(adUnits) { + return adUnits.map(function (adUnit) { + return Object.keys(adUnit.mediaTypes).toString(); + }); +} + +function detectDevice() { + if ( + /ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test( + navigator.userAgent.toLowerCase() + ) + ) { + return 'tablet'; + } + if ( + /iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test( + navigator.userAgent.toLowerCase() + ) + ) { + return 'mobile'; + } + return 'desktop'; +} + +function detectOsAndBrowser() { + var module = { + options: [], + header: [navigator.platform, navigator.userAgent, navigator.appVersion, navigator.vendor, window.opera], + dataos: [ + { + name: 'Windows Phone', + value: 'Windows Phone', + version: 'OS' + }, + { + name: 'Windows', + value: 'Win', + version: 'NT' + }, + { + name: 'iOS', + value: 'iPhone', + version: 'OS' + }, + { + name: 'iOS', + value: 'iPad', + version: 'OS' + }, + { + name: 'Kindle', + value: 'Silk', + version: 'Silk' + }, + { + name: 'Android', + value: 'Android', + version: 'Android' + }, + { + name: 'PlayBook', + value: 'PlayBook', + version: 'OS' + }, + { + name: 'BlackBerry', + value: 'BlackBerry', + version: '/' + }, + { + name: 'Macintosh', + value: 'Mac', + version: 'OS X' + }, + { + name: 'Linux', + value: 'Linux', + version: 'rv' + }, + { + name: 'Palm', + value: 'Palm', + version: 'PalmOS' + } + ], + databrowser: [ + { + name: 'Yandex Browser', + value: 'YaBrowser', + version: 'YaBrowser' + }, + { + name: 'Opera Mini', + value: 'Opera Mini', + version: 'Opera Mini' + }, + { + name: 'Amigo', + value: 'Amigo', + version: 'Amigo' + }, + { + name: 'Atom', + value: 'Atom', + version: 'Atom' + }, + { + name: 'Opera', + value: 'OPR', + version: 'OPR' + }, + { + name: 'Edge', + value: 'Edge', + version: 'Edge' + }, + { + name: 'Internet Explorer', + value: 'Trident', + version: 'rv' + }, + { + name: 'Chrome', + value: 'Chrome', + version: 'Chrome' + }, + { + name: 'Firefox', + value: 'Firefox', + version: 'Firefox' + }, + { + name: 'Safari', + value: 'Safari', + version: 'Version' + }, + { + name: 'Internet Explorer', + value: 'MSIE', + version: 'MSIE' + }, + { + name: 'Opera', + value: 'Opera', + version: 'Opera' + }, + { + name: 'BlackBerry', + value: 'CLDC', + version: 'CLDC' + }, + { + name: 'Mozilla', + value: 'Mozilla', + version: 'Mozilla' + } + ], + init: function () { + var agent = this.header.join(' '); + var os = this.matchItem(agent, this.dataos); + var browser = this.matchItem(agent, this.databrowser); + + return { + os: os, + browser: browser + }; + }, + + getVersion: function (name, version) { + if (name === 'Windows') { + switch (parseFloat(version).toFixed(1)) { + case '5.0': + return '2000'; + case '5.1': + return 'XP'; + case '5.2': + return 'Server 2003'; + case '6.0': + return 'Vista'; + case '6.1': + return '7'; + case '6.2': + return '8'; + case '6.3': + return '8.1'; + default: + return parseInt(version) || 'other'; + } + } else return parseInt(version) || 'other'; + }, + + matchItem: function (string, data) { + var i = 0; + var j = 0; + var regex, regexv, match, matches, version; + + for (i = 0; i < data.length; i += 1) { + regex = new RegExp(data[i].value, 'i'); + match = regex.test(string); + if (match) { + regexv = new RegExp(data[i].version + '[- /:;]([\\d._]+)', 'i'); + matches = string.match(regexv); + version = ''; + if (matches) { + if (matches[1]) { + matches = matches[1]; + } + } + if (matches) { + matches = matches.split(/[._]+/); + for (j = 0; j < matches.length; j += 1) { + if (j === 0) { + version += matches[j] + '.'; + } else { + version += matches[j]; + } + } + } else { + version = 'other'; + } + return { + name: data[i].name, + version: this.getVersion(data[i].name, version) + }; + } + } + return { + name: 'unknown', + version: 'other' + }; + } + }; + + var e = module.init(); + + var result = {}; + result.os = e.os.name + ' ' + e.os.version; + result.browser = e.browser.name + ' ' + e.browser.version; + return result; +} + +function handleAuctionInit(eventType, args) { + initOptions.c_timeout = args.timeout; + initOptions.ad_unit_size = handleInitSizes(args.adUnits); + initOptions.ad_unit_type = handleInitTypes(args.adUnits); + initOptions.device = detectDevice(); + initOptions.os = detectOsAndBrowser().os; + initOptions.browser = detectOsAndBrowser().browser; + timestampInit = args.timestamp; +} + +function parseBidType(mediaTypes, mediaType) { + if (!mediaTypes) { + return [mediaType]; + } else { + return Object.keys(mediaTypes) || ['']; + } +} + +function parseSizes(sizes, width, height) { + if (sizes !== undefined) { + return sizes.map(s => { + return s.toString(); + }); + } else { + return [`${width},${height}`]; + } +} + +function mapObject({ + bidder, + adUnitCode, + auctionId, + transactionId, + sizes, + size, + mediaTypes, + mediaType, + cpm, + currency, + originalCpm, + originalCurrency, + height, + width +}) { + return { + bidder: bidder, + auction_id: auctionId, + ad_unit_code: adUnitCode, + transaction_id: transactionId || '', + bid_size: size || sizes || (width && height !== undefined) ? parseSizes(sizes, width, height) : [''], + bid_type: mediaType || mediaTypes ? parseBidType(mediaTypes, mediaType) : [''], + time_ms: Date.now() - timestampInit, + cur: originalCurrency !== undefined ? originalCurrency : (currency || ''), + price: cpm !== undefined ? cpm.toString().substring(0, 4) : '', + cur_native: originalCurrency || '', + price_native: originalCpm !== undefined ? originalCpm.toString().substring(0, 4) : '' + }; +} + +function mapUpLevelObject(object, eventType, array) { + Object.assign(object, { + status: eventType || '', + bids: array || [] + }); +} + +function handleEvent(array, object, eventType, args) { + array.push(mapObject(args)); + mapUpLevelObject(object, eventType, array); +} + +function handleNoBid(eventType, args) { + handleEvent(noBidArray, noBidObject, eventType, args); +} + +function handleBidResponse(eventType, args) { + handleEvent(isBidArray, isBidObject, eventType, args); +} + +function handleBidTimeout(eventType, args) { + args.forEach(bid => { + bidTimeOutArray.push(mapObject(bid)); + }); + mapUpLevelObject(bidTimeOutObject, eventType, bidTimeOutArray); +} + +function handleBidWon(eventType, args) { + handleEvent(bidWonArray, bidWonObject, eventType, args); + sendRequest(bidWonObject); +} + +function handleBidRequested(args) {} + +function sendRequest(...objects) { + let obj = { + publisher_id: initOptions.publisher_id.toString() || '', + site: initOptions.site || '', + ad_unit_size: initOptions.ad_unit_size || [''], + ad_unit_type: initOptions.ad_unit_type || [''], + device: initOptions.device || '', + os: initOptions.os || '', + browser: initOptions.browser || '', + c_timeout: initOptions.c_timeout || 0, + events: Object.keys(objects).length ? objects : [] + }; + postAjax(url, JSON.stringify(obj)); +} + +function handleAuctionEnd() { + sendRequest(noBidObject, isBidObject, bidTimeOutObject); +} + +let adWMGAnalyticsAdapter = Object.assign(adapter({ + url, + analyticsType +}), { + track({ + eventType, + args + }) { + switch (eventType) { + case AUCTION_INIT: + handleAuctionInit(eventType, args); + break; + case BID_REQUESTED: + handleBidRequested(args); + break; + case BID_RESPONSE: + handleBidResponse(eventType, args); + break; + case NO_BID: + handleNoBid(eventType, args); + break; + case BID_TIMEOUT: + handleBidTimeout(eventType, args); + break; + case BID_WON: + handleBidWon(eventType, args); + break; + case AUCTION_END: + handleAuctionEnd(); + } + } +}); + +adWMGAnalyticsAdapter.originEnableAnalytics = adWMGAnalyticsAdapter.enableAnalytics; + +adWMGAnalyticsAdapter.enableAnalytics = function (config) { + initOptions = config.options; + adWMGAnalyticsAdapter.originEnableAnalytics(config); +}; +adapterManager.registerAnalyticsAdapter({ + adapter: adWMGAnalyticsAdapter, + code: 'adWMG' +}); +export default adWMGAnalyticsAdapter; diff --git a/modules/adWMGAnalyticsAdapter.md b/modules/adWMGAnalyticsAdapter.md new file mode 100644 index 00000000000..42a1543cf08 --- /dev/null +++ b/modules/adWMGAnalyticsAdapter.md @@ -0,0 +1,23 @@ +# Overview +Module Name: adWMG Analytics Adapter + +Module Type: Analytics Adapter + +Maintainer: wbid@adwmg.com + +# Description + +Analytics adapter for adWMG. + +# Test Parameters + +``` +{ + provider: 'adWMG', + options : { + site: 'test.com', + publisher_id: '5abd0543ba45723db49d97ea' + } +} + +``` diff --git a/test/spec/modules/adWMGAnalyticsAdapter_spec.js b/test/spec/modules/adWMGAnalyticsAdapter_spec.js new file mode 100644 index 00000000000..f24fe4d6d39 --- /dev/null +++ b/test/spec/modules/adWMGAnalyticsAdapter_spec.js @@ -0,0 +1,181 @@ +import adWMGAnalyticsAdapter from 'modules/adWMGAnalyticsAdapter.js'; +import { expect } from 'chai'; +const sinon = require('sinon'); +let adapterManager = require('src/adapterManager').default; +let events = require('src/events'); +let constants = require('src/constants.json'); + +describe('adWMG Analytics', function () { + let xhr = sinon.useFakeXMLHttpRequest(); + let requests = []; + + let timestamp = new Date() - 256; + let auctionId = '5018eb39-f900-4370-b71e-3bb5b48d324f'; + let timeout = 1500; + + let bidTimeoutArgs = [ + { + bidId: '2baa51527bd015', + bidder: 'bidderA', + adUnitCode: '/19968336/header-bid-tag-0', + auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' + }, + { + bidId: '6fe3b4c2c23092', + bidder: 'bidderB', + adUnitCode: '/19968336/header-bid-tag-0', + auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' + } + ]; + + const bidResponse = { + bidderCode: 'bidderA', + adId: '208750227436c1', + mediaTypes: ['banner'], + cpm: 0.015, + auctionId: auctionId, + responseTimestamp: 1509369418832, + requestTimestamp: 1509369418389, + bidder: 'bidderA', + timeToRespond: 443, + size: '300x250', + width: 300, + height: 250, + }; + + let wonRequest = { + 'adId': '4587fec4900b81', + 'mediaType': 'banner', + 'requestId': '4587fec4900b81', + 'cpm': 1.962, + 'creativeId': 2126, + 'currency': 'USD', + 'netRevenue': true, + 'ttl': 302, + 'auctionId': '914bedad-b145-4e46-ba58-51365faea6cb', + 'statusMessage': 'Bid available', + 'responseTimestamp': 1530628534437, + 'requestTimestamp': 1530628534219, + 'bidder': 'bidderB', + 'adUnitCode': 'div-gpt-ad-1438287399331-0', + 'sizes': [[300, 250]], + 'size': [300, 250], + }; + + let expectedBidWonData = { + publisher_id: '5abd0543ba45723db49d97ea', + site: 'test.com', + ad_unit_size: ['300,250'], + ad_unit_type: ['banner'], + c_timeout: 1500, + events: [ + { + status: 'bidWon', + bids: [ + { + bidder: 'bidderB', + auction_id: '914bedad-b145-4e46-ba58-51365faea6cb', + ad_unit_code: 'div-gpt-ad-1438287399331-0', + transaction_id: '', + bid_size: ['300,250'], + bid_type: ['banner'], + time_ms: 256, + cur: 'USD', + price: '1.96', + cur_native: '', + price_native: '' + } + ] + } + ] + } + + let adUnits = [{ + code: 'ad-slot-1', + sizes: [[300, 250]], + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bids: [ + { + bidder: 'bidderA', + params: { + placement: '1000' + } + }, + { + bidder: 'bidderB', + params: { + placement: '56656' + } + } + ] + }]; + + before(function () { + xhr.onCreate = function (request) { + requests.push(request); + }; + }); + + after(function () { + xhr.restore(); + adWMGAnalyticsAdapter.disableAnalytics(); + }); + + describe('main test flow', function () { + beforeEach(function () { + global.XMLHttpRequest = sinon.useFakeXMLHttpRequest(); + sinon.stub(events, 'getEvents').returns([]); + }); + + afterEach(function () { + events.getEvents.restore(); + }); + + it('should catch all events', function () { + sinon.spy(adWMGAnalyticsAdapter, 'track'); + + adapterManager.registerAnalyticsAdapter({ + code: 'adWMG', + adapter: adWMGAnalyticsAdapter + }); + + adapterManager.enableAnalytics({ + provider: 'adWMG', + options: { + site: 'test.com', + publisher_id: '5abd0543ba45723db49d97ea' + } + }); + + events.emit(constants.EVENTS.AUCTION_INIT, {timestamp, auctionId, timeout, adUnits}); + events.emit(constants.EVENTS.BID_REQUESTED, {}); + events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); + events.emit(constants.EVENTS.NO_BID, {}); + events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeoutArgs); + events.emit(constants.EVENTS.AUCTION_END, {}); + events.emit(constants.EVENTS.BID_WON, wonRequest); + sinon.assert.callCount(adWMGAnalyticsAdapter.track, 7); + }); + + it('should be two xhr requests', function () { + expect(requests.length).to.equal(2); + }); + + it('second request should be bidWon', function () { + expect(JSON.parse(requests[1].requestBody).events[0].status).to.equal(expectedBidWonData.events[0].status); + }); + + it('check bidWon data', function () { + let realBidWonData = JSON.parse(requests[1].requestBody); + expect(realBidWonData.publisher_id).to.equal(expectedBidWonData.publisher_id); + expect(realBidWonData.site).to.equal(expectedBidWonData.site); + expect(realBidWonData.ad_unit_type[0]).to.equal(expectedBidWonData.ad_unit_type[0]); + expect(realBidWonData.ad_unit_size[0]).to.equal(expectedBidWonData.ad_unit_size[0]); + expect(realBidWonData.events[0].bids[0].bidder).to.equal(expectedBidWonData.events[0].bids[0].bidder); + }); + }); +}); From 0b52d6a7033a9deb73fc37220638eb593dea972e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Girault?= Date: Tue, 26 May 2020 17:11:22 +0200 Subject: [PATCH 348/496] fix(Renderer): load script only on render (#5235) --- src/Renderer.js | 23 ++++++++++++++++------- test/spec/renderer_spec.js | 8 +++++++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/Renderer.js b/src/Renderer.js index b4a912d5714..85bcbb383e8 100644 --- a/src/Renderer.js +++ b/src/Renderer.js @@ -37,12 +37,21 @@ export function Renderer(options) { this.process(); }); - if (!isRendererDefinedOnAdUnit(adUnitCode)) { - // we expect to load a renderer url once only so cache the request to load script - loadExternalScript(url, moduleCode, this.callback); - } else { - utils.logWarn(`External Js not loaded by Renderer since renderer url and callback is already defined on adUnit ${adUnitCode}`); - } + // use a function, not an arrow, in order to be able to pass "arguments" through + this.render = function () { + if (!isRendererDefinedOnAdUnit(adUnitCode)) { + // we expect to load a renderer url once only so cache the request to load script + loadExternalScript(url, moduleCode, this.callback); + } else { + utils.logWarn(`External Js not loaded by Renderer since renderer url and callback is already defined on adUnit ${adUnitCode}`); + } + + if (this._render) { + this._render.apply(this, arguments) // _render is expected to use push as appropriate + } else { + utils.logWarn(`No render function was provided, please use .setRender on the renderer`); + } + }.bind(this) // bind the function to this object to avoid 'this' errors } Renderer.install = function({ url, config, id, callback, loaded, adUnitCode }) { @@ -54,7 +63,7 @@ Renderer.prototype.getConfig = function() { }; Renderer.prototype.setRender = function(fn) { - this.render = fn; + this._render = fn; }; Renderer.prototype.setEventHandlers = function(handlers) { diff --git a/test/spec/renderer_spec.js b/test/spec/renderer_spec.js index 2688c6437fe..77d806e4dbc 100644 --- a/test/spec/renderer_spec.js +++ b/test/spec/renderer_spec.js @@ -126,10 +126,13 @@ describe('Renderer', function () { id: 1, adUnitCode: 'video1' }); + testRenderer.setRender(() => {}) + + testRenderer.render() expect(utilsSpy.callCount).to.equal(1); }); - it('should call loadExternalScript() for script not defined on adUnit', function() { + it('should call loadExternalScript() for script not defined on adUnit, only when .render() is called', function() { $$PREBID_GLOBAL$$.adUnits = [{ code: 'video1', renderer: { @@ -143,6 +146,9 @@ describe('Renderer', function () { id: 1, adUnitCode: undefined }); + expect(loadExternalScript.called).to.be.false; + + testRenderer.render() expect(loadExternalScript.called).to.be.true; }); }); From 458d457e920ad33bc68cb90f9cf7fa681af754ad Mon Sep 17 00:00:00 2001 From: Oleg Naydenov Date: Tue, 26 May 2020 22:05:56 +0200 Subject: [PATCH 349/496] Fidelity adapter: TCFv2 support, kubient alias. (#5302) * TCFv2 support, kubient alias * TCFv2 support, kubient alias --- modules/fidelityBidAdapter.js | 6 +++- test/spec/modules/fidelityBidAdapter_spec.js | 34 ++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/modules/fidelityBidAdapter.js b/modules/fidelityBidAdapter.js index f16a8ea96be..baf5384fbfe 100644 --- a/modules/fidelityBidAdapter.js +++ b/modules/fidelityBidAdapter.js @@ -6,6 +6,7 @@ const BIDDER_SERVER = 'x.fidelity-media.com'; const FIDELITY_VENDOR_ID = 408; export const spec = { code: BIDDER_CODE, + aliases: ['kubient'], gvlid: 408, isBidRequestValid: function isBidRequestValid(bid) { return !!(bid && bid.params && bid.params.zoneid); @@ -110,9 +111,12 @@ function setConsentParams(gdprConsent, uspConsent, payload) { if (typeof gdprConsent.consentString !== 'undefined') { payload.consent_str = gdprConsent.consentString; } - if (gdprConsent.vendorData && gdprConsent.vendorData.vendorConsents && typeof gdprConsent.vendorData.vendorConsents[FIDELITY_VENDOR_ID.toString(10)] !== 'undefined') { + if (gdprConsent.apiVersion === 1 && gdprConsent.vendorData && gdprConsent.vendorData.vendorConsents && typeof gdprConsent.vendorData.vendorConsents[FIDELITY_VENDOR_ID.toString(10)] !== 'undefined') { payload.consent_given = gdprConsent.vendorData.vendorConsents[FIDELITY_VENDOR_ID.toString(10)] ? 1 : 0; } + if (gdprConsent.apiVersion === 2 && gdprConsent.vendorData && gdprConsent.vendorData.vendor && gdprConsent.vendorData.vendor.consents && typeof gdprConsent.vendorData.vendor.consents[FIDELITY_VENDOR_ID.toString(10)] !== 'undefined') { + payload.consent_given = gdprConsent.vendorData.vendor.consents[FIDELITY_VENDOR_ID.toString(10)] ? 1 : 0; + } } if (typeof uspConsent !== 'undefined') { payload.us_privacy = uspConsent; diff --git a/test/spec/modules/fidelityBidAdapter_spec.js b/test/spec/modules/fidelityBidAdapter_spec.js index 1232c20b0d7..304a98675b3 100644 --- a/test/spec/modules/fidelityBidAdapter_spec.js +++ b/test/spec/modules/fidelityBidAdapter_spec.js @@ -109,7 +109,7 @@ describe('FidelityAdapter', function () { expect(payload.schain).to.equal(schainString); }); - it('should add consent information to the request', function () { + it('should add consent information to the request - TCF v1', function () { let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; let uspConsentString = '1YN-'; bidderRequest.gdprConsent = { @@ -118,9 +118,39 @@ describe('FidelityAdapter', function () { consentString: consentString, vendorData: { vendorConsents: { - '408': 1 + '408': true }, }, + apiVersion: 1 + }; + bidderRequest.uspConsent = uspConsentString; + const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); + const payload = request.data; + expect(payload.gdpr).to.exist.and.to.be.a('number'); + expect(payload.gdpr).to.equal(1); + expect(payload.consent_str).to.exist.and.to.be.a('string'); + expect(payload.consent_str).to.equal(consentString); + expect(payload.consent_given).to.exist.and.to.be.a('number'); + expect(payload.consent_given).to.equal(1); + expect(payload.us_privacy).to.exist.and.to.be.a('string'); + expect(payload.us_privacy).to.equal(uspConsentString); + }); + + it('should add consent information to the request - TCF v2', function () { + let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; + let uspConsentString = '1YN-'; + bidderRequest.gdprConsent = { + gdprApplies: true, + allowAuctionWithoutConsent: true, + consentString: consentString, + vendorData: { + vendor: { + consents: { + '408': true + } + }, + }, + apiVersion: 2 }; bidderRequest.uspConsent = uspConsentString; const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); From 78330dd39802a911fc85da5cf0bd1a678cade179 Mon Sep 17 00:00:00 2001 From: TheMediaGrid <44166371+TheMediaGrid@users.noreply.github.com> Date: Tue, 26 May 2020 23:08:26 +0300 Subject: [PATCH 350/496] Update sync url for grid and gridNM Bid Adapters (#5304) * Added TheMediaGridNM Bid Adapter * Updated required params for TheMediaGridNM Bid Adapter * Update TheMediGridNM Bid Adapter * Fix tests for TheMediaGridNM Bid Adapter * Fixes after review for TheMediaGridNM Bid Adapter * Add support of multi-format in TheMediaGrid Bid Adapter * Update sync url for grid and gridNM Bid Adapters --- modules/gridBidAdapter.js | 2 +- modules/gridNMBidAdapter.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/gridBidAdapter.js b/modules/gridBidAdapter.js index 4ca631b23e5..3a78a5fcf20 100644 --- a/modules/gridBidAdapter.js +++ b/modules/gridBidAdapter.js @@ -5,7 +5,7 @@ import { VIDEO, BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'grid'; const ENDPOINT_URL = 'https://grid.bidswitch.net/hb'; -const SYNC_URL = 'https://x.bidswitch.net/sync?ssp=iow_labs'; +const SYNC_URL = 'https://x.bidswitch.net/sync?ssp=themediagrid'; const TIME_TO_LIVE = 360; const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; diff --git a/modules/gridNMBidAdapter.js b/modules/gridNMBidAdapter.js index 7e244f8293c..ffd6c1b250c 100644 --- a/modules/gridNMBidAdapter.js +++ b/modules/gridNMBidAdapter.js @@ -5,7 +5,7 @@ import { VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'gridNM'; const ENDPOINT_URL = 'https://grid.bidswitch.net/hbnm'; -const SYNC_URL = 'https://x.bidswitch.net/sync?ssp=iponweblabs'; +const SYNC_URL = 'https://x.bidswitch.net/sync?ssp=themediagrid'; const TIME_TO_LIVE = 360; const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; From c2c32633b9f332f504a46a47781b6235621b7686 Mon Sep 17 00:00:00 2001 From: Estavillo Date: Wed, 27 May 2020 11:26:37 +0200 Subject: [PATCH 351/496] Gumgum add in video (#5284) * add in-video product line * add in-video product line * add unit tests and fix dependencies. Co-authored-by: Estavillo --- modules/gumgumBidAdapter.js | 16 ++++++++--- modules/gumgumBidAdapter.md | 12 ++++++++ test/spec/modules/gumgumBidAdapter_spec.js | 32 ++++++++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index cb2401fd90a..ae8c15c8e84 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -1,10 +1,11 @@ import * as utils from '../src/utils.js' -import { config } from '../src/config.js' import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js' + +import { config } from '../src/config.js' import { getStorageManager } from '../src/storageManager.js'; +import includes from 'core-js-pure/features/array/includes'; +import { registerBidder } from '../src/adapters/bidderFactory.js' const storage = getStorageManager(); @@ -142,6 +143,8 @@ function isBidRequestValid (bid) { case !!(params.inSlot): break; case !!(params.ICV): break; case !!(params.video): break; + case !!(params.inVideo): break; + default: utils.logWarn(`[GumGum] No product selected for the placement ${adUnitCode}, please check your implementation.`); return false; @@ -241,7 +244,11 @@ function buildRequests (validBidRequests, bidderRequest) { data.t = params.video; data.pi = 7; } - + if (params.inVideo) { + data = Object.assign(data, _getVidParams(mediaTypes.video)); + data.t = params.inVideo; + data.pi = 6; + } if (gdprConsent) { data.gdprApplies = gdprConsent.gdprApplies ? 1 : 0; } @@ -322,6 +329,7 @@ function interpretResponse (serverResponse, bidRequest) { // referrer: REFERER, ...(product === 7 && { vastXml: markup }), ad: wrapper ? getWrapperCode(wrapper, Object.assign({}, serverResponseBody, { bidRequest })) : markup, + ...(product === 6 && {ad: markup}), cpm: isTestUnit ? 0.1 : cpm, creativeId, currency: cur || 'USD', diff --git a/modules/gumgumBidAdapter.md b/modules/gumgumBidAdapter.md index 3abc8a246c9..f47666e9628 100644 --- a/modules/gumgumBidAdapter.md +++ b/modules/gumgumBidAdapter.md @@ -37,6 +37,18 @@ var adUnits = [ } } ] + },{ + code: 'test-div', + sizes: [[300, 50]], + bids: [ + { + bidder: 'gumgum', + params: { + inVideo: 'ggumtest', // GumGum Zone ID given to the client + bidfloor: 0.03 // CPM bid floor + } + } + ] } ]; ``` diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index a2fbc2cf029..c2fb7f26559 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -159,6 +159,7 @@ describe('gumgumAdapter', function () { 'video': '10433395' }; const bidRequest = spec.buildRequests([request])[0]; + // 7 is video product line expect(bidRequest.data.pi).to.eq(7); expect(bidRequest.data.mind).to.eq(videoVals.minduration); expect(bidRequest.data.maxd).to.eq(videoVals.maxduration); @@ -169,6 +170,37 @@ describe('gumgumAdapter', function () { expect(bidRequest.data.viw).to.eq(videoVals.playerSize[0].toString()); expect(bidRequest.data.vih).to.eq(videoVals.playerSize[1].toString()); }); + it('should add parameters associated with invideo if invideo request param is found', function () { + const inVideoVals = { + playerSize: [640, 480], + context: 'instream', + minduration: 1, + maxduration: 2, + linearity: 1, + startdelay: 1, + placement: 123456, + protocols: [1, 2] + }; + const request = Object.assign({}, bidRequests[0]); + delete request.params; + request.mediaTypes = { + video: inVideoVals + }; + request.params = { + 'inVideo': '10433395' + }; + const bidRequest = spec.buildRequests([request])[0]; + // 6 is invideo product line + expect(bidRequest.data.pi).to.eq(6); + expect(bidRequest.data.mind).to.eq(inVideoVals.minduration); + expect(bidRequest.data.maxd).to.eq(inVideoVals.maxduration); + expect(bidRequest.data.li).to.eq(inVideoVals.linearity); + expect(bidRequest.data.sd).to.eq(inVideoVals.startdelay); + expect(bidRequest.data.pt).to.eq(inVideoVals.placement); + expect(bidRequest.data.pr).to.eq(inVideoVals.protocols.join(',')); + expect(bidRequest.data.viw).to.eq(inVideoVals.playerSize[0].toString()); + expect(bidRequest.data.vih).to.eq(inVideoVals.playerSize[1].toString()); + }); it('should not add additional parameters depending on params field', function () { const request = spec.buildRequests(bidRequests)[0]; expect(request.data).to.not.include.any.keys('ni'); From f4dc9c443729e757bd5b2206f1de277fa01cfdfe Mon Sep 17 00:00:00 2001 From: Montu Thakore Date: Wed, 27 May 2020 18:26:05 +0530 Subject: [PATCH 352/496] DailyhuntBid Adapter: Add video support with Refactor/Optimizing (#5226) * dailyhunt bidder refactor * refactor dailyhunt bid adapter support * native prebid server support * video support * native support * win notice url support * fix undefined object access issues * dh bidder small bug fixes * change endpoint * added basic gulp test for dailyhunt * adding test case and support for outstream * body2 support in native request * create md * test mode support * chnage endpoint to prod and remove console log * change md * adding accept-encoding:gzip * chnage eslint to default * remove array.prototype.find * fix review changes Co-authored-by: Mitesh Thakor --- modules/dailyhuntBidAdapter.js | 509 ++++++++++++------ modules/dailyhuntBidAdapter.md | 48 +- test/spec/modules/dailyhuntBidAdapter_spec.js | 473 +++++++++------- 3 files changed, 688 insertions(+), 342 deletions(-) diff --git a/modules/dailyhuntBidAdapter.js b/modules/dailyhuntBidAdapter.js index 5b28f086938..1018417300a 100644 --- a/modules/dailyhuntBidAdapter.js +++ b/modules/dailyhuntBidAdapter.js @@ -1,55 +1,337 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import * as mediaTypes from '../src/mediaTypes.js'; import * as utils from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import find from 'core-js-pure/features/array/find.js'; +import { OUTSTREAM, INSTREAM } from '../src/video.js'; const BIDDER_CODE = 'dailyhunt'; const BIDDER_ALIAS = 'dh'; -const SUPPORTED_MEDIA_TYPES = [mediaTypes.BANNER, mediaTypes.NATIVE]; +const SUPPORTED_MEDIA_TYPES = [mediaTypes.BANNER, mediaTypes.NATIVE, mediaTypes.VIDEO]; -const PROD_PREBID_ENDPOINT_URL = 'https://money.dailyhunt.in/openrtb2/auction'; +const PROD_PREBID_ENDPOINT_URL = 'https://pbs.dailyhunt.in/openrtb2/auction?partner='; +const PROD_PREBID_TEST_ENDPOINT_URL = 'https://qa-pbs-van.dailyhunt.in/openrtb2/auction?partner='; -const PROD_ENDPOINT_URL = 'https://money.dailyhunt.in/openx/ads/index.php'; +const ORTB_NATIVE_TYPE_MAPPING = { + img: { + '3': 'image', + '1': 'icon' + }, + data: { + '1': 'sponsoredBy', + '2': 'body', + '3': 'rating', + '4': 'likes', + '5': 'downloads', + '6': 'price', + '7': 'salePrice', + '8': 'phone', + '9': 'address', + '10': 'body2', + '11': 'displayUrl', + '12': 'cta' + } +} + +const ORTB_NATIVE_PARAMS = { + title: { + id: 0, + name: 'title' + }, + icon: { + id: 1, + type: 1, + name: 'img' + }, + image: { + id: 2, + type: 3, + name: 'img' + }, + sponsoredBy: { + id: 3, + name: 'data', + type: 1 + }, + body: { + id: 4, + name: 'data', + type: 2 + }, + cta: { + id: 5, + type: 12, + name: 'data' + }, + body2: { + id: 4, + name: 'data', + type: 10 + }, +}; -function buildParams(bid) { - let params = { ...bid.params }; - params.pagetype = 'sources'; - params.placementId = 12345; - params.env = 'prod'; - if (params.testmode && params.testmode === true) { - params.customEvent = 'pb-testmode'; +// Encode URI. +const _encodeURIComponent = function (a) { + let b = window.encodeURIComponent(a); + b = b.replace(/'/g, '%27'); + return b; +} + +// Extract key from collections. +const extractKeyInfo = (collection, key) => { + for (let i = 0, result; i < collection.length; i++) { + result = utils.deepAccess(collection[i].params, key); + if (result) { + return result; + } } - let hasWeb5Size = false; - let hasWeb3Size = false; - bid && bid.sizes && bid.sizes.forEach((size, i) => { - if (!hasWeb3Size && size[0] == 300 && size[1] == 250) { - hasWeb3Size = true; + return undefined +} + +// Flattern Array. +const flatten = (arr) => { + return [].concat(...arr); +} + +const createOrtbRequest = (validBidRequests, bidderRequest) => { + let device = createOrtbDeviceObj(validBidRequests); + let user = createOrtbUserObj(validBidRequests) + let site = createOrtbSiteObj(validBidRequests, bidderRequest.refererInfo.referer) + return { + id: bidderRequest.auctionId, + imp: [], + site, + device, + user, + }; +} + +const createOrtbDeviceObj = (validBidRequests) => { + let device = { ...extractKeyInfo(validBidRequests, `device`) }; + device.ua = navigator.userAgent; + return device; +} + +const createOrtbUserObj = (validBidRequests) => ({ ...extractKeyInfo(validBidRequests, `user`) }) + +const createOrtbSiteObj = (validBidRequests, page) => { + let site = { ...extractKeyInfo(validBidRequests, `site`), page }; + let publisher = createOrtbPublisherObj(validBidRequests); + if (publisher) { + site.publisher = publisher + } + return site +} + +const createOrtbPublisherObj = (validBidRequests) => ({ ...extractKeyInfo(validBidRequests, `publisher`) }) + +const createOrtbImpObj = (bid) => { + let params = bid.params + let testMode = !!bid.params.test_mode + + // Validate Banner Request. + let bannerObj = utils.deepAccess(bid.mediaTypes, `banner`); + let nativeObj = utils.deepAccess(bid.mediaTypes, `native`); + let videoObj = utils.deepAccess(bid.mediaTypes, `video`); + + let imp = { + id: bid.bidId, + bidfloor: params.bidfloor ? params.bidfloor : 0, + ext: { + dailyhunt: { + placement_id: params.placement_id, + publisher_id: params.publisher_id, + partner: params.partner_name + } } - if (!hasWeb5Size && (size[0] == 300 || size[0] == 320) && size[1] == 50) { - hasWeb5Size = true; + }; + + // Test Mode Campaign. + if (testMode) { + imp.ext.test_mode = testMode; + } + + if (bannerObj) { + imp.banner = { + ...createOrtbImpBannerObj(bid, bannerObj) + } + } else if (nativeObj) { + imp.native = { + ...createOrtbImpNativeObj(bid, nativeObj) + } + } else if (videoObj) { + imp.video = { + ...createOrtbImpVideoObj(bid, videoObj) + } + } + return imp; +} + +const createOrtbImpBannerObj = (bid, bannerObj) => { + let format = []; + bannerObj.sizes.forEach(size => format.push({ w: size[0], h: size[1] })) + + return { + id: 'banner-' + bid.bidId, + format + } +} + +const createOrtbImpNativeObj = (bid, nativeObj) => { + const assets = utils._map(bid.nativeParams, (bidParams, key) => { + const props = ORTB_NATIVE_PARAMS[key]; + const asset = { + required: bidParams.required & 1, + }; + if (props) { + let h = 0; + let w = 0; + + asset.id = props.id; + + if (bidParams.sizes) { + const sizes = flatten(bidParams.sizes); + w = sizes[0]; + h = sizes[1]; + } + + asset[props.name] = { + len: bidParams.len ? bidParams.len : 20, + type: props.type, + w, + h + }; + + return asset; + } + }).filter(Boolean); + let request = { + assets, + ver: '1,0' + } + return { request: JSON.stringify(request) }; +} + +const createOrtbImpVideoObj = (bid, videoObj) => { + let obj = {}; + let params = bid.params + if (!utils.isEmpty(bid.params.video)) { + obj = { + ...params.video, } - }) - params.zone = 'web'; - if (!hasWeb3Size && hasWeb5Size) { - params.subSlots = 'web-5'; } else { - params.subSlots = 'web-3'; + obj = { + mimes: ['video/mp4'], + }; } - if (bid.nativeParams) { - params.subSlots = 'web-3'; - params.ad_type = '2,3'; + obj.ext = { + ...videoObj, } - if (!params.partnerId) { - params.partnerId = 'unknown-pb-partner'; + return obj; +} + +const createServerRequest = (ortbRequest, validBidRequests, isTestMode = 'false') => ({ + method: 'POST', + url: isTestMode === 'true' ? PROD_PREBID_TEST_ENDPOINT_URL + validBidRequests[0].params.partner_name : PROD_PREBID_ENDPOINT_URL + validBidRequests[0].params.partner_name, + data: JSON.stringify(ortbRequest), + options: { + contentType: 'application/json', + withCredentials: true + }, + bids: validBidRequests +}) + +const createPrebidBannerBid = (bid, bidResponse) => ({ + requestId: bid.bidId, + cpm: bidResponse.price.toFixed(2), + creativeId: bidResponse.crid, + width: bidResponse.w, + height: bidResponse.h, + ttl: 360, + netRevenue: bid.netRevenue === 'net', + currency: 'USD', + ad: bidResponse.adm, + mediaType: 'banner', + winUrl: bidResponse.nurl +}) + +const createPrebidNativeBid = (bid, bidResponse) => ({ + requestId: bid.bidId, + cpm: bidResponse.price.toFixed(2), + creativeId: bidResponse.crid, + currency: 'USD', + ttl: 360, + netRevenue: bid.netRevenue === 'net', + native: parseNative(bidResponse), + mediaType: 'native', + winUrl: bidResponse.nurl, + width: bidResponse.w, + height: bidResponse.h, +}) + +const parseNative = (bid) => { + let adm = JSON.parse(bid.adm) + const { assets, link, imptrackers, jstracker } = adm.native; + const result = { + clickUrl: _encodeURIComponent(link.url), + clickTrackers: link.clicktrackers || [], + impressionTrackers: imptrackers || [], + javascriptTrackers: jstracker ? [ jstracker ] : [] + }; + assets.forEach(asset => { + if (!utils.isEmpty(asset.title)) { + result.title = asset.title.text + } else if (!utils.isEmpty(asset.img)) { + result[ORTB_NATIVE_TYPE_MAPPING.img[asset.img.type]] = { + url: asset.img.url, + height: asset.img.h, + width: asset.img.w + } + } else if (!utils.isEmpty(asset.data)) { + result[ORTB_NATIVE_TYPE_MAPPING.data[asset.data.type]] = asset.data.value + } + }); + + return result; +} + +const createPrebidVideoBid = (bid, bidResponse) => { + let videoBid = { + requestId: bid.bidId, + cpm: bidResponse.price.toFixed(2), + creativeId: bidResponse.crid, + width: bidResponse.w, + height: bidResponse.h, + ttl: 360, + netRevenue: bid.netRevenue === 'net', + currency: 'USD', + mediaType: 'video', + winUrl: bidResponse.nurl, + }; + + let videoContext = bid.mediaTypes.video.context; + switch (videoContext) { + case OUTSTREAM: + videoBid.vastXml = bidResponse.adm; + break; + case INSTREAM: + videoBid.videoCacheKey = bidResponse.ext.bidder.cacheKey; + videoBid.vastUrl = bidResponse.ext.bidder.vastUrl; + break; } - params.pbRequestId = bid.bidId; - params.format = 'json'; - return params; + return videoBid; } -const _encodeURIComponent = function (a) { - let b = window.encodeURIComponent(a); - b = b.replace(/'/g, '%27'); - return b; +const getQueryVariable = (variable) => { + let query = window.location.search.substring(1); + let vars = query.split('&'); + for (var i = 0; i < vars.length; i++) { + let pair = vars[i].split('='); + if (decodeURIComponent(pair[0]) == variable) { + return decodeURIComponent(pair[1]); + } + } + return false; } export const spec = { @@ -59,134 +341,55 @@ export const spec = { supportedMediaTypes: SUPPORTED_MEDIA_TYPES, - isBidRequestValid: bid => !!bid.params.partnerId, + isBidRequestValid: bid => !!bid.params.placement_id && !!bid.params.publisher_id && !!bid.params.partner_name, buildRequests: function (validBidRequests, bidderRequest) { let serverRequests = []; - const userAgent = navigator.userAgent; - const page = bidderRequest.refererInfo.referer; - - validBidRequests.forEach((bid, i) => { - let params = buildParams(bid); - let request = ''; - if (bid.nativeParams) { - request = { - method: 'GET', - url: PROD_ENDPOINT_URL, - data: utils.parseQueryStringParameters(params) - }; - } else { - let ortbReq = { - id: bidderRequest.auctionId, - imp: [{ - id: i.toString(), - banner: { - id: 'banner-' + bidderRequest.auctionId, - format: [ - { - 'h': 250, - 'w': 300 - }, - { - 'h': 50, - 'w': 320 - } - ] - }, - bidfloor: 0, - ext: { - dailyhunt: { - ...params - } - } - }], - site: { id: i.toString(), page }, - device: { userAgent }, - user: { - id: params.clientId || '', - } - }; - request = { - method: 'POST', - url: PROD_PREBID_ENDPOINT_URL, - data: JSON.stringify(ortbReq), - options: { - contentType: 'application/json', - withCredentials: true - }, - bids: validBidRequests - }; - } - serverRequests.push(request); + + // ORTB Request. + let ortbReq = createOrtbRequest(validBidRequests, bidderRequest); + + validBidRequests.forEach((bid) => { + let imp = createOrtbImpObj(bid) + ortbReq.imp.push(imp); }); + + serverRequests.push({ ...createServerRequest(ortbReq, validBidRequests, getQueryVariable('dh_test')) }); + return serverRequests; }, interpretResponse: function (serverResponse, request) { - let bidResponses = []; - if (!request.bids) { - let bid = serverResponse.body[0][0].ad; - if (bid.typeId != 2 && bid.typeId != 3) { - return bidResponses; - } - let impTrackers = []; - impTrackers.push(bid.beaconUrl); - impTrackers = (bid.beaconUrlAdditional && bid.beaconUrlAdditional.length !== 0) ? impTrackers.concat(bid.beaconUrlAdditional) : impTrackers; - let bidResponse = { - requestId: bid.pbRequestId, - cpm: bid.price, - creativeId: bid.bannerid, - currency: 'USD', - ttl: 360, - netRevenue: true, - }; - bidResponse.mediaType = 'native' - bidResponse.native = { - title: bid.content.itemTitle.data, - body: bid.content.itemSubtitle1.data, - body2: bid.content.itemSubtitle1.data, - cta: bid.content.itemSubtitle2.data, - clickUrl: _encodeURIComponent(bid.action), - impressionTrackers: impTrackers, - clickTrackers: bid.landingUrlAdditional && bid.landingUrlAdditional.length !== 0 ? bid.landingUrlAdditional : [], - image: { - url: bid.content.iconLink, - height: bid.height, - width: bid.width - }, - icon: { - url: bid.content.iconLink, - height: bid.height, - width: bid.width - } - } - bidResponses.push(bidResponse); - return bidResponses; - } else { - if (!serverResponse.body) { - return; + const { seatbid } = serverResponse.body; + let bids = request.bids; + let prebidResponse = []; + + let seatBids = seatbid[0].bid; + + seatBids.forEach(ortbResponseBid => { + let bidId = ortbResponseBid.impid; + let actualBid = find(bids, (bid) => bid.bidId === bidId); + let bidMediaType = ortbResponseBid.ext.prebid.type + switch (bidMediaType) { + case mediaTypes.BANNER: + prebidResponse.push(createPrebidBannerBid(actualBid, ortbResponseBid)); + break; + case mediaTypes.NATIVE: + prebidResponse.push(createPrebidNativeBid(actualBid, ortbResponseBid)); + break; + case mediaTypes.VIDEO: + prebidResponse.push(createPrebidVideoBid(actualBid, ortbResponseBid)); + break; } - const { seatbid } = serverResponse.body; - let bids = request.bids; - return bids.reduce((accumulator, bid, index) => { - const _cbid = seatbid && seatbid[index] && seatbid[index].bid; - const bidResponse = _cbid && _cbid[0]; - if (bidResponse) { - accumulator.push({ - requestId: bid.bidId, - cpm: bidResponse.price, - creativeId: bidResponse.crid, - width: bidResponse.w, - height: bidResponse.h, - ttl: 360, - netRevenue: bid.netRevenue === 'net', - currency: 'USD', - ad: bidResponse.adm - }); - } - return accumulator; - }, []); - } + }) + return prebidResponse; }, + + onBidWon: function(bid) { + ajax(bid.winUrl, null, null, { + method: 'GET' + }) + } } + registerBidder(spec); diff --git a/modules/dailyhuntBidAdapter.md b/modules/dailyhuntBidAdapter.md index d860d0817c2..acfd20a4de0 100644 --- a/modules/dailyhuntBidAdapter.md +++ b/modules/dailyhuntBidAdapter.md @@ -10,7 +10,7 @@ Maintainer: Dailyhunt Connects to dailyhunt for bids. -Dailyhunt bid adapter supports Banner and Native. +Dailyhunt bid adapter supports Banner, Native and Video. # Test Parameters ``` @@ -27,7 +27,12 @@ Dailyhunt bid adapter supports Banner and Native. { bidder: 'dailyhunt', params: { - partnerId: 'pb-partnerId' + placement_id: 1, + publisher_id: 1, + partner_name: 'dailyhunt', + device: { + ip: "182.23.143.212" + } } } ] @@ -55,15 +60,42 @@ Dailyhunt bid adapter supports Banner and Native. { bidder: 'dailyhunt', params: { - partnerId: 'pb-partnerId' + placement_id: 1, + publisher_id: 1, + partner_name: 'dailyhunt', + device: { + ip: "182.23.143.212" + } + } + } + ] + }, + { + code: '/83414793/prebid_test_video', + mediaTypes: { + video: { + playerSize: [1280, 720], + context: 'instream' + } + }, + bids: [ + { + bidder: 'dailyhunt', + params: { + placement_id: 1, + publisher_id: 1, + partner_name: 'dailyhunt', + device: { + ip: "182.23.143.212" + }, + video: { + mimes: [ + 'video/mp4' + ] + } } } ] } ]; ``` - -# CheckList -``` -https://drive.google.com/open?id=1t4rmcyHl5OmRF3sYiqBi-VKEjzX6iN-A -``` diff --git a/test/spec/modules/dailyhuntBidAdapter_spec.js b/test/spec/modules/dailyhuntBidAdapter_spec.js index de384d0a1f7..d571150dbee 100644 --- a/test/spec/modules/dailyhuntBidAdapter_spec.js +++ b/test/spec/modules/dailyhuntBidAdapter_spec.js @@ -1,9 +1,8 @@ import { expect } from 'chai'; import { spec } from 'modules/dailyhuntBidAdapter.js'; -const PROD_PREBID_ENDPOINT_URL = 'https://money.dailyhunt.in/openrtb2/auction'; - -const PROD_ENDPOINT_URL = 'https://money.dailyhunt.in/openx/ads/index.php'; +const PROD_PREBID_ENDPOINT_URL = 'https://pbs.dailyhunt.in/openrtb2/auction?partner=dailyhunt'; +const PROD_PREBID_TEST_ENDPOINT_URL = 'https://qa-pbs-van.dailyhunt.in/openrtb2/auction?partner=dailyhunt'; const _encodeURIComponent = function (a) { if (!a) { return } @@ -17,7 +16,9 @@ describe('DailyhuntAdapter', function () { let bid = { 'bidder': 'dailyhunt', 'params': { - partnerId: 'pb-partnerId' + placement_id: 1, + publisher_id: 1, + partner_name: 'dailyhunt' } }; @@ -32,20 +33,92 @@ describe('DailyhuntAdapter', function () { expect(spec.isBidRequestValid(bid)).to.equal(false); }); }); - - describe('buildRequests', function () { + describe('buildRequests', function() { let bidRequests = [ { - 'bidder': 'dailyhunt', - 'params': { - 'placementId': '10433394' + bidder: 'dailyhunt', + params: { + placement_id: 1, + publisher_id: 1, + partner_name: 'dailyhunt', + bidfloor: 0.1, + device: { + ip: '47.9.247.217' + }, + site: { + cat: ['1', '2', '3'] + } }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 50]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': '04f2659e-c005-4eb1-a57c-fa93145e3843' + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + adUnitCode: 'adunit-code', + sizes: [[300, 50]], + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + transactionId: '04f2659e-c005-4eb1-a57c-fa93145e3843' + } + ]; + let nativeBidRequests = [ + { + bidder: 'dailyhunt', + params: { + placement_id: 1, + publisher_id: 1, + partner_name: 'dailyhunt', + }, + nativeParams: { + title: { + required: true, + len: 80 + }, + image: { + required: true, + sizes: [150, 50] + }, + }, + mediaTypes: { + native: { + title: { + required: true + }, + } + }, + adUnitCode: 'adunit-code', + sizes: [[300, 250], [300, 50]], + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + transactionId: '04f2659e-c005-4eb1-a57c-fa93145e3843' + } + ]; + let videoBidRequests = [ + { + bidder: 'dailyhunt', + params: { + placement_id: 1, + publisher_id: 1, + partner_name: 'dailyhunt' + }, + nativeParams: { + video: { + context: 'instream' + } + }, + mediaTypes: { + video: { + context: 'instream' + } + }, + adUnitCode: 'adunit-code', + sizes: [[300, 250], [300, 50]], + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + transactionId: '04f2659e-c005-4eb1-a57c-fa93145e3843' } ]; let bidderRequest = { @@ -61,29 +134,6 @@ describe('DailyhuntAdapter', function () { 'referer': 'http://m.dailyhunt.in/' } }; - - let nativeBidRequests = [ - { - 'bidder': 'dailyhunt', - 'params': { - 'placementId': '10433394' - }, - nativeParams: { - image: { - required: true, - }, - title: { - required: true, - }, - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 50]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': '04f2659e-c005-4eb1-a57c-fa93145e3843' - } - ]; let nativeBidderRequest = { 'bidderRequestId': '22edbae2733bf6', 'auctionId': '1d1a030790a475', @@ -97,6 +147,19 @@ describe('DailyhuntAdapter', function () { 'referer': 'http://m.dailyhunt.in/' } }; + let videoBidderRequest = { + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + 'bidderCode': 'dailyhunt', + 'bids': [ + { + ...videoBidRequests[0] + } + ], + 'refererInfo': { + 'referer': 'http://m.dailyhunt.in/' + } + }; it('sends display bid request to ENDPOINT via POST', function () { const request = spec.buildRequests(bidRequests, bidderRequest)[0]; @@ -104,186 +167,234 @@ describe('DailyhuntAdapter', function () { expect(request.method).to.equal('POST'); }); - it('sends native bid request to ENDPOINT via GET', function () { + it('sends native bid request to ENDPOINT via POST', function () { const request = spec.buildRequests(nativeBidRequests, nativeBidderRequest)[0]; - expect(request.url).to.equal(PROD_ENDPOINT_URL); - expect(request.method).to.equal('GET'); + expect(request.url).to.equal(PROD_PREBID_ENDPOINT_URL); + expect(request.method).to.equal('POST'); }); - }) + it('sends video bid request to ENDPOINT via POST', function () { + const request = spec.buildRequests(videoBidRequests, videoBidderRequest)[0]; + expect(request.url).to.equal(PROD_PREBID_ENDPOINT_URL); + expect(request.method).to.equal('POST'); + }); + }); describe('interpretResponse', function () { - let nativeResponse = [ - [ + let bidResponses = { + id: 'da32def7-6779-403c-ada7-0b201dbc9744', + seatbid: [ { - 'ad': { - 'requestId': '12345', - 'type': 'native-banner', - 'aduid': 'notId=ad-123679', - 'srcUrlExpiry': '60', - 'position': 'web', - 'width': 300, - 'height': 250, - 'card-position': 6, - 'positionWithTicker': 6, - 'min-ad-distance': 9, - 'banner-fill': 'fill-width', - 'bannerid': '70459', - 'adTemplate': 'H', - 'showOnlyImage': 'false', - 'id': '4210005ddbed0f096078.05613283', - 'span': 60, - 'useInternalBrowser': 'false', - 'useWideViewPort': 'true', - 'adCacheGood': '1', - 'adCacheAverage': '1', - 'adCacheSlow': '1', - 'allowDelayedAdInsert': 'true', - 'adGroupId': '4210005ddbed0f0982f4.86287578', - 'adContext': null, - 'showPlayIcon': 'false', - 'showBorder': 'false', - 'adid': '123679', - 'typeId': '3', - 'subTypeId': '0', - 'orderId': '1', - 'data-subSlot': 'web-3', - 'data-partner': 'DH', - 'data-origin': 'pbs', - 'pbAdU': '0', - 'price': '1.4', - 'beaconUrl': 'beacon-url', - 'landingUrl': null, - 'content': { - 'bg-color': '#ffffff', - 'bg-color-night': '#000000', - 'language': 'en', - 'sourceAlphabet': 'A', - 'iconLink': 'icon-link', - 'itemTag': { - 'color': '#0889ac', - 'color-night': '#a5a5a5', - 'data': 'Promoted' - }, - 'itemTitle': { - 'color': '#000000', - 'color-night': '#ffffff', - 'data': 'PREBID TEST' - }, - 'itemSubtitle1': { - 'color': '#000000', - 'color-night': '#ffffff', - 'data': 'Lorem Ipsum lorem ipsum' - }, - 'itemSubtitle2': { - 'color': '#4caf79', - 'color-night': '#ffffff', - 'data': 'CLICK ME' + bid: [ + { + id: 'id1', + impid: 'banner-impid', + price: 1.4, + adm: 'adm', + adid: '66658', + crid: 'asd5ddbf014cac993.66466212', + dealid: 'asd5ddbf014cac993.66466212', + w: 300, + h: 250, + nurl: 'winUrl', + ext: { + prebid: { + type: 'banner' + } } }, - 'action': 'action-url', - 'shareability': null - } - } - ] - ]; - - let bannerResponse = { - 'id': 'da32def7-6779-403c-ada7-0b201dbc9744', - 'seatbid': [ - { - 'bid': [ { - 'id': '3db3773286ee59', - 'impid': '1', - 'price': 0.14, - 'adm': "\r\n\r\n\r\n\t\r\n\tWidgets Magazine\r\n\t\r\n\t\r\n\t\r\n\t\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n\r\n
\r\n\r\n\r\n", - 'adid': '66658', - 'crid': 'asd5ddbf014cac993.66466212', - 'dealid': 'asd5ddbf014cac993.66466212', - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' + id: '5caccc1f-94a6-4230-a1f9-6186ee65da99', + impid: 'video-impid', + price: 1.4, + nurl: 'winUrl', + adm: 'adm', + adid: '980', + crid: '2394', + w: 300, + h: 250, + ext: { + prebid: { + 'type': 'video' + }, + bidder: { + cacheKey: 'cache_key', + vastUrl: 'vastUrl' } } - } + }, + { + id: '74973faf-cce7-4eff-abd0-b59b8e91ca87', + impid: 'native-impid', + price: 50, + nurl: 'winUrl', + adm: '{"native":{"link":{"url":"url","clicktrackers":[]},"assets":[{"id":1,"required":1,"img":{},"video":{},"data":{},"title":{"text":"TITLE"},"link":{}},{"id":1,"required":1,"img":{},"video":{},"data":{"type":2,"value":"Lorem Ipsum Lorem Ipsum Lorem Ipsum."},"title":{},"link":{}},{"id":1,"required":1,"img":{},"video":{},"data":{"type":12,"value":"Install Here"},"title":{},"link":{}},{"id":1,"required":1,"img":{"type":3,"url":"urk","w":990,"h":505},"video":{},"data":{},"title":{},"link":{}}],"imptrackers":[]}}', + adid: '968', + crid: '2370', + w: 300, + h: 250, + ext: { + prebid: { + type: 'native' + }, + bidder: null + } + }, + { + id: '5caccc1f-94a6-4230-a1f9-6186ee65da99', + impid: 'video-outstream-impid', + price: 1.4, + nurl: 'winUrl', + adm: 'adm', + adid: '980', + crid: '2394', + w: 300, + h: 250, + ext: { + prebid: { + 'type': 'video' + }, + bidder: { + cacheKey: 'cache_key', + vastUrl: 'vastUrl' + } + } + }, ], - 'seat': 'dailyhunt' + seat: 'dailyhunt' } ], - 'ext': { - 'responsetimemillis': { - 'dailyhunt': 119 + ext: { + responsetimemillis: { + dailyhunt: 119 } } }; - it('should get correct native bid response', function () { + it('should get correct bid response', function () { let expectedResponse = [ { - requestId: '12345', - cpm: '10', - creativeId: '70459', + requestId: '1', + cpm: 1.4, + creativeId: 'asd5ddbf014cac993.66466212', + width: 300, + height: 250, + ttl: 360, + netRevenue: true, + currency: 'USD', + ad: 'adm', + mediaType: 'banner', + winUrl: 'winUrl' + }, + { + requestId: '2', + cpm: 1.4, + creativeId: '2394', + width: 300, + height: 250, + ttl: 360, + netRevenue: true, currency: 'USD', + mediaType: 'video', + winUrl: 'winUrl', + videoCacheKey: 'cache_key', + vastUrl: 'vastUrl', + }, + { + requestId: '3', + cpm: 1.4, + creativeId: '2370', + width: 300, + height: 250, ttl: 360, netRevenue: true, + currency: 'USD', mediaType: 'native', + winUrl: 'winUrl', native: { - title: 'PREBID TEST', - body: 'Lorem Ipsum lorem ipsum', - body2: 'Lorem Ipsum lorem ipsum', - cta: 'CLICK ME', - clickUrl: _encodeURIComponent('action-url'), - impressionTrackers: [], + clickUrl: 'https%3A%2F%2Fmontu1996.github.io%2F', clickTrackers: [], + impressionTrackers: [], + javascriptTrackers: [], + title: 'TITLE', + body: 'Lorem Ipsum Lorem Ipsum Lorem Ipsum.', + cta: 'Install Here', image: { - url: 'icon-link', - height: 250, - width: 300 - }, - icon: { - url: 'icon-link', - height: 300, - width: 250 + url: 'url', + height: 505, + width: 990 } } - } - ]; - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code', - 'requestId': '12345' - }] - } - let result = spec.interpretResponse({ body: nativeResponse }, { bidderRequest }); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('should get correct banner bid response', function () { - let expectedResponse = [ + }, { - requestId: '12345', - cpm: 0.14, - creativeId: 'asd5ddbf014cac993.66466212', + requestId: '4', + cpm: 1.4, + creativeId: '2394', width: 300, height: 250, ttl: 360, netRevenue: true, currency: 'USD', - ad: "\r\n\r\n\r\n\t\r\n\tWidgets Magazine\r\n\t\r\n\t\r\n\t\r\n\t\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n\r\n
\r\n\r\n\r\n", - } + mediaType: 'video', + winUrl: 'winUrl', + vastXml: 'adm', + }, ]; let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code', - 'requestId': '12345' - }] + bids: [ + { + bidId: 'banner-impid', + adUnitCode: 'code1', + requestId: '1' + }, + { + bidId: 'video-impid', + adUnitCode: 'code2', + requestId: '2', + mediaTypes: { + video: { + context: 'instream' + } + } + }, + { + bidId: 'native-impid', + adUnitCode: 'code3', + requestId: '3' + }, + { + bidId: 'video-outstream-impid', + adUnitCode: 'code4', + requestId: '4', + mediaTypes: { + video: { + context: 'outstream' + } + } + }, + ] } - let result = spec.interpretResponse({ body: bannerResponse }, bidderRequest); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); + let result = spec.interpretResponse({ body: bidResponses }, bidderRequest); + result.forEach((r, i) => { + expect(Object.keys(r)).to.have.members(Object.keys(expectedResponse[i])); + }); + }); + }) + describe('onBidWon', function () { + it('should hit win url when bid won', function () { + let bid = { + requestId: '1', + cpm: 1.4, + creativeId: 'asd5ddbf014cac993.66466212', + width: 300, + height: 250, + ttl: 360, + netRevenue: true, + currency: 'USD', + ad: 'adm', + mediaType: 'banner', + winUrl: 'winUrl' + }; + expect(spec.onBidWon(bid)).to.equal(undefined); }); }) }) From efcba5aab4d4acfeeb14a315fb6a367b82c4c789 Mon Sep 17 00:00:00 2001 From: Gena Date: Wed, 27 May 2020 17:26:23 +0300 Subject: [PATCH 353/496] Adtelligent new features (#5203) * Adtelligent support adpods * Adtelligent support bid chunks * Adtelligent support userId, schain * Adtelligent Rename params to be supported in post * Coppa support * Rewritten tests * Add param transform for aid for ServerAdapter * Lint --- modules/adtelligentBidAdapter.js | 168 +++++---- .../modules/adtelligentBidAdapter_spec.js | 351 +++++++++++------- 2 files changed, 322 insertions(+), 197 deletions(-) diff --git a/modules/adtelligentBidAdapter.js b/modules/adtelligentBidAdapter.js index 74bb6dba8d3..807c2608ae2 100644 --- a/modules/adtelligentBidAdapter.js +++ b/modules/adtelligentBidAdapter.js @@ -1,10 +1,17 @@ import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {VIDEO, BANNER} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ADPOD, BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { Renderer } from '../src/Renderer.js'; import find from 'core-js-pure/features/array/find.js'; -const URL = 'https://ghb.adtelligent.com/auction/'; +const subdomainSuffixes = ['', 1, 2]; +const getUri = (function () { + let num = 0; + return function () { + return 'https://ghb' + subdomainSuffixes[num++ % subdomainSuffixes.length] + '.adtelligent.com/v2/auction/' + } +}()) const OUTSTREAM_SRC = 'https://player.adtelligent.com/outstream-unit/2.01/outstream.min.js'; const BIDDER_CODE = 'adtelligent'; const OUTSTREAM = 'outstream'; @@ -30,8 +37,8 @@ export const spec = { uris.forEach((uri, i) => { const type = types[i] || 'image'; - if ((!syncOptions.pixelEnabled && type == 'image') || - (!syncOptions.iframeEnabled && type == 'iframe') || + if ((!syncOptions.pixelEnabled && type === 'image') || + (!syncOptions.iframeEnabled && type === 'iframe') || syncsCache[uri]) { return; } @@ -63,15 +70,21 @@ export const spec = { /** * Make a server request from the list of BidRequests * @param bidRequests - * @param bidderRequest + * @param adapterRequest */ - buildRequests: function (bidRequests, bidderRequest) { - return { - data: bidToTag(bidRequests, bidderRequest), - bidderRequest, - method: 'GET', - url: URL - }; + buildRequests: function (bidRequests, adapterRequest) { + const adapterSettings = config.getConfig(adapterRequest.bidderCode) + const chunkSize = utils.deepAccess(adapterSettings, 'chunkSize', 10); + const { tag, bids } = bidToTag(bidRequests, adapterRequest); + const bidChunks = utils.chunk(bids, chunkSize); + return utils._map(bidChunks, (bids) => { + return { + data: Object.assign({}, tag, { BidRequests: bids }), + adapterRequest, + method: 'POST', + url: getUri() + }; + }) }, /** @@ -80,43 +93,43 @@ export const spec = { * @param bidderRequest * @return {Bid[]} An array of bids which were nested inside the server */ - interpretResponse: function (serverResponse, {bidderRequest}) { + interpretResponse: function (serverResponse, { adapterRequest }) { serverResponse = serverResponse.body; let bids = []; if (!utils.isArray(serverResponse)) { - return parseRTBResponse(serverResponse, bidderRequest); + return parseRTBResponse(serverResponse, adapterRequest); } serverResponse.forEach(serverBidResponse => { - bids = utils.flatten(bids, parseRTBResponse(serverBidResponse, bidderRequest)); + bids = utils.flatten(bids, parseRTBResponse(serverBidResponse, adapterRequest)); }); return bids; + }, + + transformBidParams(params) { + return utils.convertTypes({ + 'aid': 'number', + }, params); } }; -function parseRTBResponse(serverResponse, bidderRequest) { - const isInvalidValidResp = !serverResponse || !utils.isArray(serverResponse.bids); - +function parseRTBResponse(serverResponse, adapterRequest) { + const isEmptyResponse = !serverResponse || !utils.isArray(serverResponse.bids); const bids = []; - if (isInvalidValidResp) { - const extMessage = serverResponse && serverResponse.ext && serverResponse.ext.message ? `: ${serverResponse.ext.message}` : ''; - const errorMessage = `in response for ${bidderRequest.bidderCode} adapter ${extMessage}`; - - utils.logError(errorMessage); - + if (isEmptyResponse) { return bids; } serverResponse.bids.forEach(serverBid => { - const request = find(bidderRequest.bids, (bidRequest) => { + const request = find(adapterRequest.bids, (bidRequest) => { return bidRequest.bidId === serverBid.requestId; }); if (serverBid.cpm !== 0 && request !== undefined) { - const bid = createBid(serverBid, getMediaType(request)); + const bid = createBid(serverBid, request); bids.push(bid); } @@ -125,43 +138,59 @@ function parseRTBResponse(serverResponse, bidderRequest) { return bids; } -function bidToTag(bidRequests, bidderRequest) { +function bidToTag(bidRequests, adapterRequest) { + // start publisher env const tag = { - domain: utils.deepAccess(bidderRequest, 'refererInfo.referer') + Domain: utils.deepAccess(adapterRequest, 'refererInfo.referer') }; - - if (utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies')) { - tag.gdpr = 1; - tag.gdpr_consent = utils.deepAccess(bidderRequest, 'gdprConsent.consentString'); + if (config.getConfig('coppa') === true) { + tag.Coppa = 1; } - - if (utils.deepAccess(bidderRequest, 'bidderRequest.uspConsent')) { - tag.us_privacy = bidderRequest.uspConsent; + if (utils.deepAccess(adapterRequest, 'gdprConsent.gdprApplies')) { + tag.GDPR = 1; + tag.GDPRConsent = utils.deepAccess(adapterRequest, 'gdprConsent.consentString'); + } + if (utils.deepAccess(adapterRequest, 'uspConsent')) { + tag.USP = utils.deepAccess(adapterRequest, 'uspConsent'); } + if (utils.deepAccess(bidRequests[0], 'schain')) { + tag.Schain = utils.deepAccess(bidRequests[0], 'schain'); + } + if (utils.deepAccess(bidRequests[0], 'userId')) { + tag.UserIds = utils.deepAccess(bidRequests[0], 'userId'); + } + // end publisher env + const bids = [] for (let i = 0, length = bidRequests.length; i < length; i++) { - Object.assign(tag, prepareRTBRequestParams(i, bidRequests[i])); + const bid = prepareBidRequests(bidRequests[i]); + bids.push(bid); } - return tag; + return { tag, bids }; } /** * Parse mediaType - * @param _index {number} - * @param bid {object} + * @param bidReq {object} * @returns {object} */ -function prepareRTBRequestParams(_index, bid) { - const mediaType = utils.deepAccess(bid, 'mediaTypes.video') ? VIDEO : DISPLAY; - const index = !_index ? '' : `${_index + 1}`; - const sizes = mediaType === VIDEO ? utils.deepAccess(bid, 'mediaTypes.video.playerSize') : utils.deepAccess(bid, 'mediaTypes.banner.sizes'); - return { - ['callbackId' + index]: bid.bidId, - ['aid' + index]: bid.params.aid, - ['ad_type' + index]: mediaType, - ['sizes' + index]: utils.parseSizesInput(sizes).join() +function prepareBidRequests(bidReq) { + const mediaType = utils.deepAccess(bidReq, 'mediaTypes.video') ? VIDEO : DISPLAY; + const sizes = mediaType === VIDEO ? utils.deepAccess(bidReq, 'mediaTypes.video.playerSize') : utils.deepAccess(bidReq, 'mediaTypes.banner.sizes'); + const bidReqParams = { + 'CallbackId': bidReq.bidId, + 'Aid': bidReq.params.aid, + 'AdType': mediaType, + 'Sizes': utils.parseSizesInput(sizes).join(',') }; + if (mediaType === VIDEO) { + const context = utils.deepAccess(bidReq, 'mediaTypes.video.context'); + if (context === ADPOD) { + bidReqParams.Adpod = utils.deepAccess(bidReq, 'mediaTypes.video'); + } + } + return bidReqParams; } /** @@ -170,19 +199,18 @@ function prepareRTBRequestParams(_index, bid) { * @returns {object} */ function getMediaType(bidderRequest) { - const videoMediaType = utils.deepAccess(bidderRequest, 'mediaTypes.video'); - const context = utils.deepAccess(bidderRequest, 'mediaTypes.video.context'); - - return !videoMediaType ? DISPLAY : context === OUTSTREAM ? OUTSTREAM : VIDEO; + return utils.deepAccess(bidderRequest, 'mediaTypes.video') ? VIDEO : BANNER; } /** * Configure new bid by response * @param bidResponse {object} - * @param mediaType {Object} + * @param bidRequest {Object} * @returns {object} */ -function createBid(bidResponse, mediaType) { +function createBid(bidResponse, bidRequest) { + const mediaType = getMediaType(bidRequest) + const context = utils.deepAccess(bidRequest, 'mediaTypes.video.context'); const bid = { requestId: bidResponse.requestId, creativeId: bidResponse.cmpId, @@ -192,24 +220,34 @@ function createBid(bidResponse, mediaType) { cpm: bidResponse.cpm, netRevenue: true, mediaType, - ttl: 3600 + ttl: 300 }; - if (mediaType === DISPLAY) { + if (mediaType === BANNER) { return Object.assign(bid, { ad: bidResponse.ad }); } + if (context === ADPOD) { + Object.assign(bid, { + meta: { + iabSubCatId: bidResponse.iabSubCatId, + }, + video: { + context: ADPOD, + durationSeconds: bidResponse.durationSeconds + } + }); + } Object.assign(bid, { vastUrl: bidResponse.vastUrl }); - if (mediaType === OUTSTREAM) { + if (context === OUTSTREAM) { Object.assign(bid, { - mediaType: 'video', adResponse: bidResponse, - renderer: newRenderer(bidResponse.requestId) + renderer: newRenderer(bidResponse.requestId, bidRequest.params) }); } @@ -221,10 +259,11 @@ function createBid(bidResponse, mediaType) { * @param requestId * @returns {*} */ -function newRenderer(requestId) { +function newRenderer(requestId, bidderParams) { const renderer = Renderer.install({ id: requestId, url: OUTSTREAM_SRC, + config: bidderParams.outstream || {}, loaded: false }); @@ -239,12 +278,13 @@ function newRenderer(requestId) { */ function outstreamRender(bid) { bid.renderer.push(() => { - window.VOutstreamAPI.initOutstreams([{ + const opts = Object.assign({}, bid.renderer.getConfig(), { width: bid.width, height: bid.height, vastUrl: bid.vastUrl, elId: bid.adUnitCode - }]); + }); + window.VOutstreamAPI.initOutstreams([opts]); }); } diff --git a/test/spec/modules/adtelligentBidAdapter_spec.js b/test/spec/modules/adtelligentBidAdapter_spec.js index ad81795d0e9..9c694668703 100644 --- a/test/spec/modules/adtelligentBidAdapter_spec.js +++ b/test/spec/modules/adtelligentBidAdapter_spec.js @@ -1,15 +1,23 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adtelligentBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; - -const ENDPOINT = 'https://ghb.adtelligent.com/auction/'; +import { expect } from 'chai'; +import { spec } from 'modules/adtelligentBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { config } from 'src/config.js'; + +const EXPECTED_ENDPOINTS = [ + 'https://ghb.adtelligent.com/v2/auction/', + 'https://ghb1.adtelligent.com/v2/auction/', + 'https://ghb2.adtelligent.com/v2/auction/', + 'https://ghb.adtelligent.com/v2/auction/' +]; const DISPLAY_REQUEST = { 'bidder': 'adtelligent', 'params': { 'aid': 12345 }, - 'mediaTypes': {'banner': {'sizes': [300, 250]}}, + 'schain': { ver: 1 }, + 'userId': { criteo: 2 }, + 'mediaTypes': { 'banner': { 'sizes': [300, 250] } }, 'bidderRequestId': '7101db09af0db2', 'auctionId': '2e41f65424c87c', 'adUnitCode': 'adunit-code', @@ -32,13 +40,32 @@ const VIDEO_REQUEST = { 'bidId': '84ab500420319d' }; +const ADPOD_REQUEST = { + 'bidder': 'adtelligent', + 'mediaTypes': { + 'video': { + 'context': 'adpod', + 'playerSize': [[640, 480]], + 'anyField': 10 + } + }, + 'params': { + 'aid': 12345 + }, + 'bidderRequestId': '7101db09af0db2', + 'auctionId': '2e41f65424c87c', + 'adUnitCode': 'adunit-code', + 'bidId': '2e41f65424c87c' +}; + const SERVER_VIDEO_RESPONSE = { - 'source': {'aid': 12345, 'pubId': 54321}, + 'source': { 'aid': 12345, 'pubId': 54321 }, 'bids': [{ 'vastUrl': 'http://rtb.adtelligent.com/vast/?adid=44F2AEB9BFC881B3', 'requestId': '2e41f65424c87c', 'url': '44F2AEB9BFC881B3', 'creative_id': 342516, + 'durationSeconds': 30, 'cmpId': 342516, 'height': 480, 'cur': 'USD', @@ -47,9 +74,9 @@ const SERVER_VIDEO_RESPONSE = { } ] }; - +const SERVER_OUSTREAM_VIDEO_RESPONSE = SERVER_VIDEO_RESPONSE; const SERVER_DISPLAY_RESPONSE = { - 'source': {'aid': 12345, 'pubId': 54321}, + 'source': { 'aid': 12345, 'pubId': 54321 }, 'bids': [{ 'ad': '', 'requestId': '2e41f65424c87c', @@ -63,7 +90,7 @@ const SERVER_DISPLAY_RESPONSE = { 'cookieURLs': ['link1', 'link2'] }; const SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS = { - 'source': {'aid': 12345, 'pubId': 54321}, + 'source': { 'aid': 12345, 'pubId': 54321 }, 'bids': [{ 'ad': '', 'requestId': '2e41f65424c87c', @@ -77,24 +104,42 @@ const SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS = { 'cookieURLs': ['link3', 'link4'], 'cookieURLSTypes': ['image', 'iframe'] }; - +const outstreamVideoBidderRequest = { + bidderCode: 'bidderCode', + bids: [{ + 'params': { + 'aid': 12345, + 'outstream': { + 'video_controls': 'show' + } + }, + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 480] + } + }, + bidId: '2e41f65424c87c' + }] +}; const videoBidderRequest = { bidderCode: 'bidderCode', - bids: [{mediaTypes: {video: {}}, bidId: '2e41f65424c87c'}] + bids: [{ mediaTypes: { video: {} }, bidId: '2e41f65424c87c' }] }; const displayBidderRequest = { bidderCode: 'bidderCode', - bids: [{bidId: '2e41f65424c87c'}] + bids: [{ bidId: '2e41f65424c87c' }] }; -const displayBidderRequestWithGdpr = { +const displayBidderRequestWithConsents = { bidderCode: 'bidderCode', - bids: [{bidId: '2e41f65424c87c'}], + bids: [{ bidId: '2e41f65424c87c' }], gdprConsent: { gdprApplies: true, consentString: 'test' - } + }, + uspConsent: 'iHaveIt' }; const videoEqResponse = [{ @@ -106,219 +151,259 @@ const videoEqResponse = [{ currency: 'USD', height: 480, width: 640, - ttl: 3600, + ttl: 300, cpm: 0.9 }]; const displayEqResponse = [{ requestId: '2e41f65424c87c', creativeId: 342516, - mediaType: 'display', + mediaType: 'banner', netRevenue: true, currency: 'USD', ad: '', height: 250, width: 300, - ttl: 3600, + ttl: 300, cpm: 0.9 }]; -describe('adtelligentBidAdapter', function () { +describe('adtelligentBidAdapter', () => { const adapter = newBidder(spec); + describe('inherited functions', () => { + it('exists and is a function', () => { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); - describe('user syncs as image', function () { - it('should be returned if pixel enabled', function () { - const syncs = spec.getUserSyncs({pixelEnabled: true}, [{body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS}]); + describe('user syncs', () => { + describe('as image', () => { + it('should be returned if pixel enabled', () => { + const syncs = spec.getUserSyncs({ pixelEnabled: true }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[0]]); - expect(syncs.map(s => s.type)).to.deep.equal(['image']); + expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[0]]); + expect(syncs.map(s => s.type)).to.deep.equal(['image']); + }) }) - }) - describe('user syncs as iframe', function () { - it('should be returned if iframe enabled', function () { - const syncs = spec.getUserSyncs({iframeEnabled: true}, [{body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS}]); + describe('as iframe', () => { + it('should be returned if iframe enabled', () => { + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[1]]); - expect(syncs.map(s => s.type)).to.deep.equal(['iframe']); + expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[1]]); + expect(syncs.map(s => s.type)).to.deep.equal(['iframe']); + }) }) - }) - describe('user sync', function () { - it('should not be returned if passed syncs where already used', function () { - const syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [{body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS}]); + describe('user sync', () => { + it('should not be returned if passed syncs where already used', () => { + const syncs = spec.getUserSyncs({ + iframeEnabled: true, + pixelEnabled: true + }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - expect(syncs).to.deep.equal([]); - }) - }); + expect(syncs).to.deep.equal([]); + }) - describe('user syncs with both types', function () { - it('should be returned if pixel and iframe enabled', function () { - const mockedServerResponse = Object.assign({}, SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS, {'cookieURLs': ['link5', 'link6']}); - const syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [{body: mockedServerResponse}]); + it('should not be returned if pixel not set', () => { + const syncs = spec.getUserSyncs({}, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - expect(syncs.map(s => s.url)).to.deep.equal(mockedServerResponse.cookieURLs); - expect(syncs.map(s => s.type)).to.deep.equal(mockedServerResponse.cookieURLSTypes); + expect(syncs).to.be.empty; + }); }); - }); - - describe('user syncs', function () { - it('should not be returned if pixel not set', function () { - const syncs = spec.getUserSyncs({}, [{body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS}]); - - expect(syncs).to.be.empty; + describe('user syncs with both types', () => { + it('should be returned if pixel and iframe enabled', () => { + const mockedServerResponse = Object.assign({}, SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS, { 'cookieURLs': ['link5', 'link6'] }); + const syncs = spec.getUserSyncs({ + iframeEnabled: true, + pixelEnabled: true + }, [{ body: mockedServerResponse }]); + + expect(syncs.map(s => s.url)).to.deep.equal(mockedServerResponse.cookieURLs); + expect(syncs.map(s => s.type)).to.deep.equal(mockedServerResponse.cookieURLSTypes); + }); }); }); - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { + describe('isBidRequestValid', () => { + it('should return true when required params found', () => { expect(spec.isBidRequestValid(VIDEO_REQUEST)).to.equal(true); }); - it('should return false when required params are not passed', function () { + it('should return false when required params are not passed', () => { let bid = Object.assign({}, VIDEO_REQUEST); delete bid.params; expect(spec.isBidRequestValid(bid)).to.equal(false); }); }); - describe('buildRequests', function () { + describe('buildRequests', () => { let videoBidRequests = [VIDEO_REQUEST]; let displayBidRequests = [DISPLAY_REQUEST]; let videoAndDisplayBidRequests = [DISPLAY_REQUEST, VIDEO_REQUEST]; - const displayRequest = spec.buildRequests(displayBidRequests, {}); const videoRequest = spec.buildRequests(videoBidRequests, {}); const videoAndDisplayRequests = spec.buildRequests(videoAndDisplayBidRequests, {}); + const rotatingRequest = spec.buildRequests(displayBidRequests, {}); + it('rotates endpoints', () => { + const bidReqUrls = [displayRequest[0], videoRequest[0], videoAndDisplayRequests[0], rotatingRequest[0]].map(br => br.url); + expect(bidReqUrls).to.deep.equal(EXPECTED_ENDPOINTS); + }) - it('sends bid request to ENDPOINT via GET', function () { - expect(videoRequest.method).to.equal('GET'); - expect(displayRequest.method).to.equal('GET'); - expect(videoAndDisplayRequests.method).to.equal('GET'); - }); + it('building requests as arrays', () => { + expect(videoRequest).to.be.a('array'); + expect(displayRequest).to.be.a('array'); + expect(videoAndDisplayRequests).to.be.a('array'); + }) - it('sends bid request to correct ENDPOINT', function () { - expect(videoRequest.url).to.equal(ENDPOINT); - expect(displayRequest.url).to.equal(ENDPOINT); - expect(videoAndDisplayRequests.url).to.equal(ENDPOINT); + it('sending as POST', () => { + const postActionMethod = 'POST' + const comparator = br => br.method === postActionMethod; + expect(videoRequest.every(comparator)).to.be.true; + expect(displayRequest.every(comparator)).to.be.true; + expect(videoAndDisplayRequests.every(comparator)).to.be.true; }); - - it('sends correct video bid parameters', function () { - const bid = Object.assign({}, videoRequest.data); - delete bid.domain; + it('forms correct ADPOD request', () => { + const pbBidReqData = spec.buildRequests([ADPOD_REQUEST], {})[0].data; + const impRequest = pbBidReqData.BidRequests[0] + expect(impRequest.AdType).to.be.equal('video'); + expect(impRequest.Adpod).to.be.a('object'); + expect(impRequest.Adpod.anyField).to.be.equal(10); + }) + it('sends correct video bid parameters', () => { + const data = videoRequest[0].data; const eq = { - callbackId: '84ab500420319d', - ad_type: 'video', - aid: 12345, - sizes: '480x360,640x480' + CallbackId: '84ab500420319d', + AdType: 'video', + Aid: 12345, + Sizes: '480x360,640x480' }; - - expect(bid).to.deep.equal(eq); + expect(data.BidRequests[0]).to.deep.equal(eq); }); - it('sends correct display bid parameters', function () { - const bid = Object.assign({}, displayRequest.data); - delete bid.domain; + it('sends correct display bid parameters', () => { + const data = displayRequest[0].data; const eq = { - callbackId: '84ab500420319d', - ad_type: 'display', - aid: 12345, - sizes: '300x250' + CallbackId: '84ab500420319d', + AdType: 'display', + Aid: 12345, + Sizes: '300x250' }; - expect(bid).to.deep.equal(eq); + expect(data.BidRequests[0]).to.deep.equal(eq); }); - it('sends correct video and display bid parameters', function () { - const bid = Object.assign({}, videoAndDisplayRequests.data); - delete bid.domain; - - const eq = { - callbackId: '84ab500420319d', - ad_type: 'display', - aid: 12345, - sizes: '300x250', - callbackId2: '84ab500420319d', - ad_type2: 'video', - aid2: 12345, - sizes2: '480x360,640x480' - }; - - expect(bid).to.deep.equal(eq); + it('sends correct video and display bid parameters', () => { + const bidRequests = videoAndDisplayRequests[0].data; + const expectedBidReqs = [{ + CallbackId: '84ab500420319d', + AdType: 'display', + Aid: 12345, + Sizes: '300x250' + }, { + CallbackId: '84ab500420319d', + AdType: 'video', + Aid: 12345, + Sizes: '480x360,640x480' + }] + + expect(bidRequests.BidRequests).to.deep.equal(expectedBidReqs); }); + + describe('publisher environment', () => { + const sandbox = sinon.sandbox.create(); + sandbox.stub(config, 'getConfig').callsFake((key) => { + const config = { + 'coppa': true + }; + return config[key]; + }); + const bidRequestWithPubSettingsData = spec.buildRequests([DISPLAY_REQUEST], displayBidderRequestWithConsents)[0].data; + sandbox.restore(); + it('sets GDPR', () => { + expect(bidRequestWithPubSettingsData.GDPR).to.be.equal(1); + expect(bidRequestWithPubSettingsData.GDPRConsent).to.be.equal(displayBidderRequestWithConsents.gdprConsent.consentString); + }); + it('sets USP', () => { + expect(bidRequestWithPubSettingsData.USP).to.be.equal(displayBidderRequestWithConsents.uspConsent); + }) + it('sets Coppa', () => { + expect(bidRequestWithPubSettingsData.Coppa).to.be.equal(1); + }) + it('sets Schain', () => { + expect(bidRequestWithPubSettingsData.Schain).to.be.deep.equal(DISPLAY_REQUEST.schain); + }) + it('sets UserId\'s', () => { + expect(bidRequestWithPubSettingsData.UserIds).to.be.deep.equal(DISPLAY_REQUEST.userId); + }) + }) }); - describe('interpretResponse', function () { + describe('interpretResponse', () => { let serverResponse; - let bidderRequest; + let adapterRequest; let eqResponse; - afterEach(function () { + afterEach(() => { serverResponse = null; - bidderRequest = null; + adapterRequest = null; eqResponse = null; }); - it('should get correct video bid response', function () { + it('should get correct video bid response', () => { serverResponse = SERVER_VIDEO_RESPONSE; - bidderRequest = videoBidderRequest; + adapterRequest = videoBidderRequest; eqResponse = videoEqResponse; bidServerResponseCheck(); }); - it('should get correct display bid response', function () { + it('should get correct display bid response', () => { serverResponse = SERVER_DISPLAY_RESPONSE; - bidderRequest = displayBidderRequest; + adapterRequest = displayBidderRequest; eqResponse = displayEqResponse; bidServerResponseCheck(); }); - it('should set gdpr data correctly', function () { - const builtRequestData = spec.buildRequests([DISPLAY_REQUEST], displayBidderRequestWithGdpr); - - expect(builtRequestData.data.gdpr).to.be.equal(1); - expect(builtRequestData.data.gdpr_consent).to.be.equal(displayBidderRequestWithGdpr.gdprConsent.consentString); - }); - function bidServerResponseCheck() { - const result = spec.interpretResponse({body: serverResponse}, {bidderRequest}); + const result = spec.interpretResponse({ body: serverResponse }, { adapterRequest }); expect(result).to.deep.equal(eqResponse); } function nobidServerResponseCheck() { - const noBidServerResponse = {bids: []}; - const noBidResult = spec.interpretResponse({body: noBidServerResponse}, {bidderRequest}); + const noBidServerResponse = { bids: [] }; + const noBidResult = spec.interpretResponse({ body: noBidServerResponse }, { adapterRequest }); expect(noBidResult.length).to.equal(0); } - it('handles video nobid responses', function () { - bidderRequest = videoBidderRequest; + it('handles video nobid responses', () => { + adapterRequest = videoBidderRequest; nobidServerResponseCheck(); }); - it('handles display nobid responses', function () { - bidderRequest = displayBidderRequest; + it('handles display nobid responses', () => { + adapterRequest = displayBidderRequest; nobidServerResponseCheck(); }); + + it('forms correct ADPOD response', () => { + const videoBids = spec.interpretResponse({ body: SERVER_VIDEO_RESPONSE }, { adapterRequest: { bids: [ADPOD_REQUEST] } }); + expect(videoBids[0].video.durationSeconds).to.be.equal(30); + expect(videoBids[0].video.context).to.be.equal('adpod'); + }) + describe('outstream setup', () => { + const videoBids = spec.interpretResponse({ body: SERVER_OUSTREAM_VIDEO_RESPONSE }, { adapterRequest: outstreamVideoBidderRequest }); + it('should return renderer with expected outstream params config', () => { + expect(!!videoBids[0].renderer).to.be.true; + expect(videoBids[0].renderer.getConfig().video_controls).to.equal('show'); + }) + }) }); }); From b4b6e134badd6e9f3d2dd7951d271efd095a99ba Mon Sep 17 00:00:00 2001 From: vladi-mmg Date: Wed, 27 May 2020 18:41:00 +0300 Subject: [PATCH 354/496] New adapter - videofy (#5259) * Change publisherId to zoneId Add gdpr Add supply chain Add video media type * Remove comments * Fix unit test coverage * fix request id bug add vastXml to video response * Remove bid response default sizes * Change endpoint url * Add unit test for vastXml * Change end point * Remove trailing-space * Add onBidWon function * New adapter - videofy --- modules/videofyBidAdapter.js | 262 ++++++++++++++++++++ modules/videofyBidAdapter.md | 36 +++ test/spec/modules/videofyBidAdapter_spec.js | 200 +++++++++++++++ 3 files changed, 498 insertions(+) create mode 100644 modules/videofyBidAdapter.js create mode 100644 modules/videofyBidAdapter.md create mode 100644 test/spec/modules/videofyBidAdapter_spec.js diff --git a/modules/videofyBidAdapter.js b/modules/videofyBidAdapter.js new file mode 100644 index 00000000000..07e95689ab4 --- /dev/null +++ b/modules/videofyBidAdapter.js @@ -0,0 +1,262 @@ +import { VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; + +const BIDDER_CODE = 'videofy'; +const TTL = 600; + +function avRenderer(bid) { + bid.renderer.push(function() { + let eventCallback = bid && bid.renderer && bid.renderer.handleVideoEvent ? bid.renderer.handleVideoEvent : null; + window.aniviewRenderer.renderAd({ + id: bid.adUnitCode + '_' + bid.adId, + debug: window.location.href.indexOf('pbjsDebug') >= 0, + placement: bid.adUnitCode, + width: bid.width, + height: bid.height, + vastUrl: bid.vastUrl, + vastXml: bid.vastXml, + config: bid.params[0].rendererConfig, + eventsCallback: eventCallback, + bid: bid + }); + }); +} + +function newRenderer(bidRequest) { + const renderer = Renderer.install({ + url: 'https://player.srv-mars.com/script/6.1/prebidRenderer.js', + config: {}, + loaded: false, + }); + + try { + renderer.setRender(avRenderer); + } catch (err) { + } + + return renderer; +} + +function isBidRequestValid(bid) { + if (!bid.params || !bid.params.AV_PUBLISHERID || !bid.params.AV_CHANNELID) { return false; } + + return true; +} +let irc = 0; +function buildRequests(validBidRequests, bidderRequest) { + let bidRequests = []; + + for (let i = 0; i < validBidRequests.length; i++) { + let bidRequest = validBidRequests[i]; + var sizes = [[640, 480]]; + + if (bidRequest.mediaTypes && bidRequest.mediaTypes.video && bidRequest.mediaTypes.video.playerSize) { + sizes = bidRequest.mediaTypes.video.playerSize; + } else { + if (bidRequest.sizes) { + sizes = bidRequest.sizes; + } + } + if (sizes.length === 2 && typeof sizes[0] === 'number') { + sizes = [[sizes[0], sizes[1]]]; + } + + for (let j = 0; j < sizes.length; j++) { + let size = sizes[j]; + let playerWidth; + let playerHeight; + + if (size && size.length == 2) { + playerWidth = size[0]; + playerHeight = size[1]; + } else { + playerWidth = 640; + playerHeight = 480; + } + + let s2sParams = {}; + + for (var attrname in bidRequest.params) { + if (bidRequest.params.hasOwnProperty(attrname) && attrname.indexOf('AV_') == 0) { + s2sParams[attrname] = bidRequest.params[attrname]; + } + }; + + if (s2sParams.AV_APPPKGNAME && !s2sParams.AV_URL) { s2sParams.AV_URL = s2sParams.AV_APPPKGNAME; } + if (!s2sParams.AV_IDFA && !s2sParams.AV_URL) { + if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { + s2sParams.AV_URL = bidderRequest.refererInfo.referer; + } else { + s2sParams.AV_URL = window.location.href; + } + } + if (s2sParams.AV_IDFA && !s2sParams.AV_AID) { s2sParams.AV_AID = s2sParams.AV_IDFA; } + if (s2sParams.AV_AID && !s2sParams.AV_IDFA) { s2sParams.AV_IDFA = s2sParams.AV_AID; } + + s2sParams.cb = Math.floor(Math.random() * 999999999); + s2sParams.AV_WIDTH = playerWidth; + s2sParams.AV_HEIGHT = playerHeight; + s2sParams.bidWidth = playerWidth; + s2sParams.bidHeight = playerHeight; + s2sParams.bidId = bidRequest.bidId; + s2sParams.pbjs = 1; + s2sParams.tgt = 10; + s2sParams.s2s = '1'; + s2sParams.irc = irc; + irc++; + s2sParams.wpm = 1; + + if (bidderRequest && bidderRequest.gdprConsent) { + if (bidderRequest.gdprConsent.gdprApplies) { + s2sParams.AV_GDPR = 1; + s2sParams.AV_CONSENT = bidderRequest.gdprConsent.consentString; + } + } + if (bidderRequest && bidderRequest.uspConsent) { + s2sParams.AV_CCPA = bidderRequest.uspConsent; + } + + let serverDomain = (bidRequest.params && bidRequest.params.serverDomain) ? bidRequest.params.serverDomain : 'servx.srv-mars.com'; + let servingUrl = 'https://' + serverDomain + '/api/adserver/vast3/'; + + bidRequests.push({ + method: 'GET', + url: servingUrl, + data: s2sParams, + bidRequest + }); + } + } + + return bidRequests; +} +function getCpmData(xml) { + let ret = {cpm: 0, currency: 'USD'}; + if (xml) { + let ext = xml.getElementsByTagName('Extensions'); + if (ext && ext.length > 0) { + ext = ext[0].getElementsByTagName('Extension'); + if (ext && ext.length > 0) { + for (var i = 0; i < ext.length; i++) { + if (ext[i].getAttribute('type') == 'ANIVIEW') { + let price = ext[i].getElementsByTagName('Cpm'); + if (price && price.length == 1) { + ret.cpm = price[0].textContent; + } + break; + } + } + } + } + } + return ret; +} +function interpretResponse(serverResponse, bidRequest) { + let bidResponses = []; + if (serverResponse && serverResponse.body) { + if (serverResponse.error) { + return bidResponses; + } else { + try { + let bidResponse = {}; + if (bidRequest && bidRequest.data && bidRequest.data.bidId && bidRequest.data.bidId !== '') { + let xmlStr = serverResponse.body; + let xml = new window.DOMParser().parseFromString(xmlStr, 'text/xml'); + if (xml && xml.getElementsByTagName('parsererror').length == 0) { + let cpmData = getCpmData(xml); + if (cpmData && cpmData.cpm > 0) { + bidResponse.requestId = bidRequest.data.bidId; + bidResponse.bidderCode = BIDDER_CODE; + bidResponse.ad = ''; + bidResponse.cpm = cpmData.cpm; + bidResponse.width = bidRequest.data.AV_WIDTH; + bidResponse.height = bidRequest.data.AV_HEIGHT; + bidResponse.ttl = TTL; + bidResponse.creativeId = xml.getElementsByTagName('Ad') && xml.getElementsByTagName('Ad')[0] && xml.getElementsByTagName('Ad')[0].getAttribute('id') ? xml.getElementsByTagName('Ad')[0].getAttribute('id') : 'creativeId'; + bidResponse.currency = cpmData.currency; + bidResponse.netRevenue = true; + var blob = new Blob([xmlStr], { + type: 'application/xml' + }); + bidResponse.vastUrl = window.URL.createObjectURL(blob); + bidResponse.vastXml = xmlStr; + bidResponse.mediaType = VIDEO; + if (bidRequest.bidRequest && bidRequest.bidRequest.mediaTypes && bidRequest.bidRequest.mediaTypes.video && bidRequest.bidRequest.mediaTypes.video.context === 'outstream') { bidResponse.renderer = newRenderer(bidRequest); } + + bidResponses.push(bidResponse); + } + } else {} + } else {} + } catch (e) {} + } + } else {} + + return bidResponses; +} + +function getSyncData(xml, options) { + let ret = []; + if (xml) { + let ext = xml.getElementsByTagName('Extensions'); + if (ext && ext.length > 0) { + ext = ext[0].getElementsByTagName('Extension'); + if (ext && ext.length > 0) { + for (var i = 0; i < ext.length; i++) { + if (ext[i].getAttribute('type') == 'ANIVIEW') { + let syncs = ext[i].getElementsByTagName('AdServingSync'); + if (syncs && syncs.length == 1) { + try { + let data = JSON.parse(syncs[0].textContent); + if (data && data.trackers && data.trackers.length) { + data = data.trackers; + for (var j = 0; j < data.length; j++) { + if (typeof data[j] === 'object' && typeof data[j].url === 'string' && data[j].e === 'inventory') { + if (data[j].t == 1 && options.pixelEnabled) { + ret.push({url: data[j].url, type: 'image'}); + } else { + if (data[j].t == 3 && options.iframeEnabled) { + ret.push({url: data[j].url, type: 'iframe'}); + } + } + } + } + } + } catch (e) {} + } + break; + } + } + } + } + } + return ret; +} + +function getUserSyncs(syncOptions, serverResponses) { + if (serverResponses && serverResponses[0] && serverResponses[0].body) { + if (serverResponses.error) { + return []; + } else { + try { + let xmlStr = serverResponses[0].body; + let xml = new window.DOMParser().parseFromString(xmlStr, 'text/xml'); + if (xml && xml.getElementsByTagName('parsererror').length == 0) { + let syncData = getSyncData(xml, syncOptions); + return syncData; + } + } catch (e) {} + } + } +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [VIDEO], + isBidRequestValid, + buildRequests, + interpretResponse, + getUserSyncs +}; + +registerBidder(spec); diff --git a/modules/videofyBidAdapter.md b/modules/videofyBidAdapter.md new file mode 100644 index 00000000000..b50eaf5672e --- /dev/null +++ b/modules/videofyBidAdapter.md @@ -0,0 +1,36 @@ +# Overview + +``` +Module Name: Videofy Bidder Adapter +Module Type: Bidder Adapter +Maintainer: support1@videofy.ai +``` + +# Description + +Connects to Videofy for bids. + +Videofy bid adapter supports Video ads currently. + +# Sample Ad Unit: For Publishers +```javascript +var videoAdUnit = [ +{ + code: 'video1', + mediaTypes: { + video: { + playerSize: [[640, 480]], + context: 'outstream' + }, + }, + bids: [{ + bidder: 'videofy', + params: { + AV_PUBLISHERID: '55b78633181f4603178b4568', + AV_CHANNELID: '5d19dfca4b6236688c0a2fc4' + } + }] +}]; +``` + +``` diff --git a/test/spec/modules/videofyBidAdapter_spec.js b/test/spec/modules/videofyBidAdapter_spec.js new file mode 100644 index 00000000000..e221ece45b8 --- /dev/null +++ b/test/spec/modules/videofyBidAdapter_spec.js @@ -0,0 +1,200 @@ +import { spec } from 'modules/videofyBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +const { expect } = require('chai'); + +describe('Videofy Bid Adapter Test', function () { + const adapter = newBidder(spec); + + describe('inherited functions', function () { + it('exists and is a function', function () { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', function () { + let bid = { + 'bidder': 'videofy', + 'params': { + 'AV_PUBLISHERID': '123456', + 'AV_CHANNELID': '123456' + }, + 'adUnitCode': 'video1', + 'sizes': [[300, 250], [640, 480]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'requestId': 'a09c66c3-53e3-4428-b296-38fc08e7cd2a', + 'transactionId': 'd6f6b392-54a9-454c-85fb-a2fd882c4a2d', + }; + + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when required params are not passed', function () { + let bid = Object.assign({}, bid); + delete bid.params; + bid.params = { + something: 'is wrong' + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + let bid2Requests = [ + { + 'bidder': 'videofy', + 'params': { + 'AV_PUBLISHERID': '123456', + 'AV_CHANNELID': '123456' + }, + 'adUnitCode': 'test1', + 'sizes': [[300, 250], [640, 480]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'requestId': 'a09c66c3-53e3-4428-b296-38fc08e7cd2a', + 'transactionId': 'd6f6b392-54a9-454c-85fb-a2fd882c4a2d', + } + ]; + let bid1Request = [ + { + 'bidder': 'videofy', + 'params': { + 'AV_PUBLISHERID': '123456', + 'AV_CHANNELID': '123456' + }, + 'adUnitCode': 'test1', + 'sizes': [640, 480], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'requestId': 'a09c66c3-53e3-4428-b296-38fc08e7cd2a', + 'transactionId': 'd6f6b392-54a9-454c-85fb-a2fd882c4a2d', + } + ]; + + it('Test 2 requests', function () { + const requests = spec.buildRequests(bid2Requests); + expect(requests.length).to.equal(2); + const r1 = requests[0]; + const d1 = requests[0].data; + expect(d1).to.have.property('AV_PUBLISHERID'); + expect(d1.AV_PUBLISHERID).to.equal('123456'); + expect(d1).to.have.property('AV_CHANNELID'); + expect(d1.AV_CHANNELID).to.equal('123456'); + expect(d1).to.have.property('AV_WIDTH'); + expect(d1.AV_WIDTH).to.equal(300); + expect(d1).to.have.property('AV_HEIGHT'); + expect(d1.AV_HEIGHT).to.equal(250); + expect(d1).to.have.property('AV_URL'); + expect(d1).to.have.property('cb'); + expect(d1).to.have.property('s2s'); + expect(d1.s2s).to.equal('1'); + expect(d1).to.have.property('pbjs'); + expect(d1.pbjs).to.equal(1); + expect(r1).to.have.property('url'); + expect(r1.url).to.contain('https://servx.srv-mars.com/api/adserver/vast3/'); + const r2 = requests[1]; + const d2 = requests[1].data; + expect(d2).to.have.property('AV_PUBLISHERID'); + expect(d2.AV_PUBLISHERID).to.equal('123456'); + expect(d2).to.have.property('AV_CHANNELID'); + expect(d2.AV_CHANNELID).to.equal('123456'); + expect(d2).to.have.property('AV_WIDTH'); + expect(d2.AV_WIDTH).to.equal(640); + expect(d2).to.have.property('AV_HEIGHT'); + expect(d2.AV_HEIGHT).to.equal(480); + expect(d2).to.have.property('AV_URL'); + expect(d2).to.have.property('cb'); + expect(d2).to.have.property('s2s'); + expect(d2.s2s).to.equal('1'); + expect(d2).to.have.property('pbjs'); + expect(d2.pbjs).to.equal(1); + expect(r2).to.have.property('url'); + expect(r2.url).to.contain('https://servx.srv-mars.com/api/adserver/vast3/'); + }); + + it('Test 1 request', function () { + const requests = spec.buildRequests(bid1Request); + expect(requests.length).to.equal(1); + const r = requests[0]; + const d = requests[0].data; + expect(d).to.have.property('AV_PUBLISHERID'); + expect(d.AV_PUBLISHERID).to.equal('123456'); + expect(d).to.have.property('AV_CHANNELID'); + expect(d.AV_CHANNELID).to.equal('123456'); + expect(d).to.have.property('AV_WIDTH'); + expect(d.AV_WIDTH).to.equal(640); + expect(d).to.have.property('AV_HEIGHT'); + expect(d.AV_HEIGHT).to.equal(480); + expect(d).to.have.property('AV_URL'); + expect(d).to.have.property('cb'); + expect(d).to.have.property('s2s'); + expect(d.s2s).to.equal('1'); + expect(d).to.have.property('pbjs'); + expect(d.pbjs).to.equal(1); + expect(r).to.have.property('url'); + expect(r.url).to.contain('https://servx.srv-mars.com/api/adserver/vast3/'); + }); + }); + + describe('interpretResponse', function () { + let bidRequest = { + 'url': 'https://servx.srv-mars.com/api/adserver/vast3/', + 'data': { + 'bidId': '253dcb69fb2577', + AV_PUBLISHERID: '55b78633181f4603178b4568', + AV_CHANNELID: '55b7904d181f46410f8b4568', + } + }; + let serverResponse = {}; + serverResponse.body = 'FORDFORD00:00:15'; + + it('Check bid interpretResponse', function () { + const BIDDER_CODE = 'videofy'; + let bidResponses = spec.interpretResponse(serverResponse, bidRequest); + expect(bidResponses.length).to.equal(1); + let bidResponse = bidResponses[0]; + expect(bidResponse.requestId).to.equal(bidRequest.data.bidId); + expect(bidResponse.bidderCode).to.equal(BIDDER_CODE); + expect(bidResponse.cpm).to.equal('2'); + expect(bidResponse.ttl).to.equal(600); + expect(bidResponse.currency).to.equal('USD'); + expect(bidResponse.netRevenue).to.equal(true); + expect(bidResponse.mediaType).to.equal('video'); + }); + + it('safely handles XML parsing failure from invalid bid response', function () { + let invalidServerResponse = {}; + invalidServerResponse.body = ''; + + let result = spec.interpretResponse(invalidServerResponse, bidRequest); + expect(result.length).to.equal(0); + }); + + it('handles nobid responses', function () { + let nobidResponse = {}; + nobidResponse.body = ''; + + let result = spec.interpretResponse(nobidResponse, bidRequest); + expect(result.length).to.equal(0); + }); + }); + + describe('getUserSyncs', function () { + it('Check get sync pixels from response', function () { + let pixelUrl = 'https://sync.pixel.url/sync'; + let pixelEvent = 'inventory'; + let pixelType = '3'; + let pixelStr = '{"url":"' + pixelUrl + '", "e":"' + pixelEvent + '", "t":' + pixelType + '}'; + let bidResponse = 'FORDFORD00:00:15'; + let serverResponse = [ + {body: bidResponse} + ]; + let syncPixels = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, serverResponse); + expect(syncPixels.length).to.equal(1); + let pixel = syncPixels[0]; + expect(pixel.url).to.equal(pixelUrl); + expect(pixel.type).to.equal('iframe'); + }); + }); +}); From e7b565f13c6ae6fd2fcf26cf746994640680f5a0 Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Wed, 27 May 2020 10:22:20 -0700 Subject: [PATCH 355/496] fallback to defaultGdprScope if cmp undefined (#5291) --- modules/consentManagement.js | 5 ++-- test/spec/modules/consentManagement_spec.js | 29 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/modules/consentManagement.js b/modules/consentManagement.js index c665eb1a29b..53e97006bd1 100644 --- a/modules/consentManagement.js +++ b/modules/consentManagement.js @@ -301,7 +301,8 @@ function processCmpData(consentObject, hookConfig) { } function checkV2Data() { - let gdprApplies = consentObject && consentObject.gdprApplies; + // if CMP does not respond with a gdprApplies boolean, use defaultGdprScope (gdprScope) + let gdprApplies = consentObject && typeof consentObject.gdprApplies === 'boolean' ? consentObject.gdprApplies : gdprScope; let tcString = consentObject && consentObject.tcString; return !!( (typeof gdprApplies !== 'boolean') || @@ -372,7 +373,7 @@ function storeConsentData(cmpConsentObject) { consentData = { consentString: (cmpConsentObject) ? cmpConsentObject.tcString : undefined, vendorData: (cmpConsentObject) || undefined, - gdprApplies: (cmpConsentObject) ? cmpConsentObject.gdprApplies : gdprScope + gdprApplies: cmpConsentObject && typeof cmpConsentObject.gdprApplies === 'boolean' ? cmpConsentObject.gdprApplies : gdprScope }; } consentData.apiVersion = cmpVersion; diff --git a/test/spec/modules/consentManagement_spec.js b/test/spec/modules/consentManagement_spec.js index fb33094e151..c4f6fe70dd1 100644 --- a/test/spec/modules/consentManagement_spec.js +++ b/test/spec/modules/consentManagement_spec.js @@ -655,6 +655,35 @@ describe('consentManagement', function () { expect(consent).to.be.null; }); + it('It still considers it a valid cmp response if gdprApplies is not a boolean', function () { + // gdprApplies is undefined, should just still store consent response but use whatever defaultGdprScope was + let testConsentData = { + tcString: 'abc12345234', + purposeOneTreatment: false, + eventStatus: 'tcloaded' + }; + cmpStub = sinon.stub(window, '__tcfapi').callsFake((...args) => { + args[2](testConsentData, true); + }); + + setConsentConfig({ + cmpApi: 'iab', + timeout: 7500, + defaultGdprScope: true + }); + + requestBidsHook(() => { + didHookReturn = true; + }, {}); + let consent = gdprDataHandler.getConsentData(); + sinon.assert.notCalled(utils.logWarn); + sinon.assert.notCalled(utils.logError); + expect(didHookReturn).to.be.true; + expect(consent.consentString).to.equal(testConsentData.tcString); + expect(consent.gdprApplies).to.be.true; + expect(consent.apiVersion).to.equal(2); + }); + it('throws a warning + stores consentData + calls callback when processCmpData check failed while config had allowAuction set to true', function () { let testConsentData = {}; From 1f1b4fe50c85e6fcde74c5b9c54f0f46e7bde413 Mon Sep 17 00:00:00 2001 From: omerBrowsi <54346241+omerBrowsi@users.noreply.github.com> Date: Wed, 27 May 2020 20:23:51 +0300 Subject: [PATCH 356/496] RTD bug fix (#5087) * real time data module, browsi sub module for real time data, new hook bidsBackCallback, fix for config unsubscribe * change timeout&primary ad server only to auctionDelay update docs * support multiple providers * change promise to callbacks configure submodule on submodules.json * bug fixes * use Prebid ajax * tests fix * browsi real time data provider improvements * real time data module, browsi sub module for real time data, new hook bidsBackCallback, fix for config unsubscribe * change timeout&primary ad server only to auctionDelay update docs * support multiple providers * change promise to callbacks configure submodule on submodules.json * bug fixes * use Prebid ajax * tests fix * browsi real time data provider improvements * RTD bug fixes * #5087 review fixes * RTD fixes * use core-js lib find init googletag if needed --- modules/browsiRtdProvider.js | 36 +++++++---------- modules/rtdModule/index.js | 39 ++++++++++++++++-- test/spec/modules/realTimeModule_spec.js | 51 ++++++++++++++++++++---- 3 files changed, 94 insertions(+), 32 deletions(-) diff --git a/modules/browsiRtdProvider.js b/modules/browsiRtdProvider.js index 3765b6603af..9317786fb8d 100644 --- a/modules/browsiRtdProvider.js +++ b/modules/browsiRtdProvider.js @@ -23,6 +23,7 @@ import {submodule} from '../src/hook.js'; import {ajaxBuilder} from '../src/ajax.js'; import {loadExternalScript} from '../src/adloader.js'; import { getStorageManager } from '../src/storageManager.js'; +import find from 'core-js-pure/features/array/find.js'; const storage = getStorageManager(); @@ -75,7 +76,7 @@ function collectData() { sk: _moduleParams.siteKey, sw: (win.screen && win.screen.width) || -1, sh: (win.screen && win.screen.height) || -1, - url: encodeURIComponent(`${doc.location.protocol}//${doc.location.host}${doc.location.pathname}`), + url: `${doc.location.protocol}//${doc.location.host}${doc.location.pathname}`, }, ...(browsiData ? {us: browsiData} : {us: '{}'}), ...(document.referrer ? {r: document.referrer} : {}), @@ -120,21 +121,16 @@ function sendDataToModule(adUnits, onDone) { if (!_predictions || !Object.keys(_predictions).length) { return onDone({}); } - const slots = getAllSlots(); - if (!slots || !slots.length) { - return onDone({}); - } let dataToReturn = adUnits.reduce((rp, cau) => { const adUnitCode = cau && cau.code; if (!adUnitCode) { return rp } - const adSlot = getSlotById(adUnitCode); - if (!adSlot) { return rp } - const macroId = getMacroId(_predictionsData.pmd, adUnitCode, adSlot); - const predictionData = _predictions[macroId]; + const adSlot = getSlotByCode(adUnitCode); + const identifier = adSlot ? getMacroId(_predictionsData.pmd, adSlot) : adUnitCode; + const predictionData = _predictions[identifier]; if (!predictionData) { return rp } if (predictionData.p) { - if (!isIdMatchingAdUnit(adUnitCode, adSlot, predictionData.w)) { + if (!isIdMatchingAdUnit(adSlot, predictionData.w)) { return rp; } rp[adUnitCode] = getKVObject(predictionData.p, _predictionsData.kn); @@ -153,7 +149,7 @@ function sendDataToModule(adUnits, onDone) { * @return {Object[]} slot GoogleTag slots */ function getAllSlots() { - return utils.isGptPubadsDefined && window.googletag.pubads().getSlots(); + return utils.isGptPubadsDefined() && window.googletag.pubads().getSlots(); } /** * get prediction and return valid object for key value set @@ -169,13 +165,12 @@ function getKVObject(p, keyName) { } /** * check if placement id matches one of given ad units - * @param {number} id placement id * @param {Object} slot google slot * @param {string[]} whitelist ad units * @return {boolean} */ -export function isIdMatchingAdUnit(id, slot, whitelist) { - if (!whitelist || !whitelist.length) { +export function isIdMatchingAdUnit(slot, whitelist) { + if (!whitelist || !whitelist.length || !slot) { return true; } const slotAdUnits = slot.getAdUnitPath(); @@ -184,25 +179,24 @@ export function isIdMatchingAdUnit(id, slot, whitelist) { /** * get GPT slot by placement id - * @param {string} id placement id + * @param {string} code placement id * @return {?Object} */ -function getSlotById(id) { +function getSlotByCode(code) { const slots = getAllSlots(); if (!slots || !slots.length) { return null; } - return slots.filter(s => s.getSlotElementId() === id)[0] || null; + return find(slots, s => s.getSlotElementId() === code || s.getAdUnitPath() === code) || null; } /** * generate id according to macro script - * @param {string} macro replacement macro - * @param {string} id placement id + * @param {Object} macro replacement macro * @param {Object} slot google slot * @return {?Object} */ -function getMacroId(macro, id, slot) { +export function getMacroId(macro, slot) { if (macro) { try { const macroResult = evaluate(macro, slot.getSlotElementId(), slot.getAdUnitPath(), (match, p1) => { @@ -213,7 +207,7 @@ function getMacroId(macro, id, slot) { utils.logError(`failed to evaluate: ${macro}`); } } - return id; + return slot.getSlotElementId(); } function evaluate(macro, divId, adUnit, replacer) { diff --git a/modules/rtdModule/index.js b/modules/rtdModule/index.js index cff09fbd4fb..3aa7753d204 100644 --- a/modules/rtdModule/index.js +++ b/modules/rtdModule/index.js @@ -128,6 +128,32 @@ function getProviderData(adUnits, callback) { } } +/** + * delete invalid data received from provider + * this is to ensure working flow for GPT + * @param {Object} data received from provider + * @return {Object} valid data for GPT targeting + */ +export function validateProviderDataForGPT(data) { + // data must be an object, contains object with string as value + if (typeof data !== 'object') { + return {}; + } + for (let key in data) { + if (data.hasOwnProperty(key)) { + for (let innerKey in data[key]) { + if (data[key].hasOwnProperty(innerKey)) { + if (typeof data[key][innerKey] !== 'string') { + utils.logWarn(`removing ${key}: {${innerKey}:${data[key][innerKey]} } from GPT targeting because of invalid type (must be string)`); + delete data[key][innerKey]; + } + } + } + } + } + return data; +} + /** * run hook after bids request and before callback * get data from provider and set key values to primary ad server @@ -196,11 +222,16 @@ export function requestBidsHook(fn, reqBidsConfigObj) { * @param {Object} data - key values to set */ function setDataForPrimaryAdServer(data) { - if (!utils.isGptPubadsDefined()) { - utils.logError('window.googletag is not defined on the page'); - return; + data = validateProviderDataForGPT(data); + if (utils.isGptPubadsDefined()) { + targeting.setTargetingForGPT(data, null) + } else { + window.googletag = window.googletag || {}; + window.googletag.cmd = window.googletag.cmd || []; + window.googletag.cmd.push(() => { + targeting.setTargetingForGPT(data, null); + }); } - targeting.setTargetingForGPT(data, null); } /** diff --git a/test/spec/modules/realTimeModule_spec.js b/test/spec/modules/realTimeModule_spec.js index 27440a3ec23..ca149fe7a44 100644 --- a/test/spec/modules/realTimeModule_spec.js +++ b/test/spec/modules/realTimeModule_spec.js @@ -2,13 +2,15 @@ import { init, requestBidsHook, setTargetsAfterRequestBids, - deepMerge + deepMerge, + validateProviderDataForGPT } from 'modules/rtdModule/index.js'; import { init as browsiInit, addBrowsiTag, isIdMatchingAdUnit, - setData + setData, + getMacroId } from 'modules/browsiRtdProvider.js'; import { init as audigentInit, @@ -78,7 +80,8 @@ describe('Real time module', function () { function createSlots() { const slot1 = makeSlot({ code: '/57778053/Browsi_Demo_300x250', divId: 'browsiAd_1' }); - return [slot1]; + const slot2 = makeSlot({ code: '/57778053/Browsi', divId: 'browsiAd_1' }); + return [slot1, slot2]; } describe('Real time module with browsi provider', function () { @@ -181,6 +184,28 @@ describe('Real time module', function () { assert.deepEqual(expected, merged); }); + it('check data validation for GPT targeting', function () { + // non strings values should be removed + const obj = { + valid: {'key': 'value'}, + invalid: {'key': ['value']}, + combine: { + 'a': 'value', + 'b': [] + } + }; + + const expected = { + valid: {'key': 'value'}, + invalid: {}, + combine: { + 'a': 'value', + } + }; + const validationResult = validateProviderDataForGPT(obj); + assert.deepEqual(expected, validationResult); + }); + it('check browsi sub module', function () { const script = addBrowsiTag('scriptUrl.com'); expect(script.getAttribute('data-sitekey')).to.equal('testKey'); @@ -188,15 +213,27 @@ describe('Real time module', function () { expect(script.async).to.equal(true); const slots = createSlots(); - const test1 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_300x250']); // true - const test2 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_300x250', '/57778053/Browsi']); // true - const test3 = isIdMatchingAdUnit('browsiAd_1', slots[0], ['/57778053/Browsi_Demo_Low']); // false - const test4 = isIdMatchingAdUnit('browsiAd_1', slots[0], []); // true + const test1 = isIdMatchingAdUnit(slots[0], ['/57778053/Browsi_Demo_300x250']); // true + const test2 = isIdMatchingAdUnit(slots[0], ['/57778053/Browsi_Demo_300x250', '/57778053/Browsi']); // true + const test3 = isIdMatchingAdUnit(slots[0], ['/57778053/Browsi_Demo_Low']); // false + const test4 = isIdMatchingAdUnit(slots[0], []); // true expect(test1).to.equal(true); expect(test2).to.equal(true); expect(test3).to.equal(false); expect(test4).to.equal(true); + + // macro results + slots[0].setTargeting('test', ['test', 'value']); + // slot getTargeting doesn't act like GPT so we can't expect real value + const macroResult = getMacroId({p: '/'}, slots[0]); + expect(macroResult).to.equal('/57778053/Browsi_Demo_300x250/NA'); + + const macroResultB = getMacroId({}, slots[0]); + expect(macroResultB).to.equal('browsiAd_1'); + + const macroResultC = getMacroId({p: '', s: {s: 0, e: 1}}, slots[0]); + expect(macroResultC).to.equal('/'); }) }); From 874c482f68b100762e4346416bda35e2c2e3db8d Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Wed, 27 May 2020 10:24:07 -0700 Subject: [PATCH 357/496] adding check if gdpr module ran enforcment logic (#5178) * adding check if gdpr module ran enforcment logic * adding tests for new hasValidated flag Co-authored-by: rmartinez --- modules/gdprEnforcement.js | 2 +- modules/userId/index.js | 6 ++-- test/spec/modules/gdprEnforcement_spec.js | 35 +++++++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/modules/gdprEnforcement.js b/modules/gdprEnforcement.js index 4818bbf8ec9..6a3fbdce1f2 100644 --- a/modules/gdprEnforcement.js +++ b/modules/gdprEnforcement.js @@ -147,7 +147,7 @@ export function userIdHook(fn, submodules, consentData) { } return undefined; }).filter(module => module) - fn.call(this, userIdModules, consentData); + fn.call(this, userIdModules, {...consentData, hasValidated: true}); } else { utils.logInfo('Enforcing TCF2 only'); fn.call(this, submodules, consentData); diff --git a/modules/userId/index.js b/modules/userId/index.js index f18888c398e..7f7fec291ed 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -396,7 +396,7 @@ function getUserIdsAsEids() { * This hook returns updated list of submodules which are allowed to do get user id based on TCF 2 enforcement rules configured */ export const validateGdprEnforcement = hook('sync', function (submodules, consentData) { - return submodules; + return {userIdModules: submodules, hasValidated: consentData && consentData.hasValidated}; }, 'validateGdprEnforcement'); /** @@ -406,8 +406,8 @@ export const validateGdprEnforcement = hook('sync', function (submodules, consen */ function initSubmodules(submodules, consentData) { // gdpr consent with purpose one is required, otherwise exit immediately - let userIdModules = validateGdprEnforcement(submodules, consentData); - if (!hasGDPRConsent(consentData)) { + let {userIdModules, hasValidated} = validateGdprEnforcement(submodules, consentData); + if (!hasValidated && !hasGDPRConsent(consentData)) { utils.logWarn(`${MODULE_NAME} - gdpr permission not valid for local storage or cookies, exit module`); return []; } diff --git a/test/spec/modules/gdprEnforcement_spec.js b/test/spec/modules/gdprEnforcement_spec.js index 5b46441cbbb..7f4828267a9 100644 --- a/test/spec/modules/gdprEnforcement_spec.js +++ b/test/spec/modules/gdprEnforcement_spec.js @@ -362,6 +362,9 @@ describe('gdpr enforcement', function() { } }] userIdHook(nextFnSpy, submodules, consentData); + // Should pass back hasValidated flag since version 2 + const args = nextFnSpy.getCalls()[0].args; + expect(args[1].hasValidated).to.be.true; expect(nextFnSpy.calledOnce).to.equal(true); }); @@ -374,10 +377,42 @@ describe('gdpr enforcement', function() { }]; let consentData = null; userIdHook(nextFnSpy, submodules, consentData); + // Should not pass back hasValidated flag since version 2 + const args = nextFnSpy.getCalls()[0].args; + expect(args[1]).to.be.null; expect(nextFnSpy.calledOnce).to.equal(true); expect(nextFnSpy.calledWith(undefined, submodules, consentData)); }); + it('should not enforce if not apiVersion 2', function() { + setEnforcementConfig({ + gdpr: { + rules: [{ + purpose: 'storage', + enforcePurpose: false, + enforceVendor: true, + vendorExceptions: [] + }] + } + }); + let consentData = {} + consentData.vendorData = staticConfig.consentData.getTCData; + consentData.apiVersion = 1; + consentData.gdprApplies = true; + let submodules = [{ + submodule: { + gvlid: 1, + name: 'sampleUserId' + } + }] + userIdHook(nextFnSpy, submodules, consentData); + // Should not pass back hasValidated flag since version 1 + const args = nextFnSpy.getCalls()[0].args; + expect(args[1].hasValidated).to.be.undefined; + expect(args[0]).to.deep.equal(submodules); + expect(nextFnSpy.calledOnce).to.equal(true); + }); + it('should not allow user id module if user denied consent', function() { setEnforcementConfig({ gdpr: { From 883662a07444697111d99e0f36b3a0548b79c62a Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Wed, 27 May 2020 10:32:04 -0700 Subject: [PATCH 358/496] Floors new signals (#5295) * Price Floors skipRate debug by query string Rubicon Analytics log floors skipRate * new floor signal fetchFailed * change fetchFailed to fetchStatus * rubi analytics looks for fetchStatus --- modules/priceFloors.js | 34 ++++--- modules/rubiconAnalyticsAdapter.js | 6 +- test/spec/modules/priceFloors_spec.js | 89 ++++++++++++++++++- .../modules/rubiconAnalyticsAdapter_spec.js | 8 +- 4 files changed, 120 insertions(+), 17 deletions(-) diff --git a/modules/priceFloors.js b/modules/priceFloors.js index 9e9ed1e0d23..dfc857bed6c 100644 --- a/modules/priceFloors.js +++ b/modules/priceFloors.js @@ -274,10 +274,10 @@ export function getFloorDataFromAdUnits(adUnits) { /** * @summary This function takes the adUnits for the auction and update them accordingly as well as returns the rules hashmap for the auction */ -export function updateAdUnitsForAuction(adUnits, floorData, skipped, auctionId) { +export function updateAdUnitsForAuction(adUnits, floorData, auctionId) { adUnits.forEach((adUnit) => { adUnit.bids.forEach(bid => { - if (skipped) { + if (floorData.skipped) { delete bid.getFloor; } else { bid.getFloor = getFloor; @@ -285,9 +285,11 @@ export function updateAdUnitsForAuction(adUnits, floorData, skipped, auctionId) // information for bid and analytics adapters bid.auctionId = auctionId; bid.floorData = { - skipped, - modelVersion: utils.deepAccess(floorData, 'data.modelVersion') || '', - location: floorData.data.location, + skipped: floorData.skipped, + modelVersion: utils.deepAccess(floorData, 'data.modelVersion'), + location: utils.deepAccess(floorData, 'data.location'), + skipRate: floorData.skipRate, + fetchStatus: _floorsConfig.fetchStatus } }); }); @@ -306,14 +308,17 @@ export function createFloorsDataForAuction(adUnits, auctionId) { } else { resolvedFloorsData.data = getFloorsDataForAuction(resolvedFloorsData.data); } - // if we still do not have a valid floor data then floors is not on for this auction + // if we still do not have a valid floor data then floors is not on for this auction, so skip if (Object.keys(utils.deepAccess(resolvedFloorsData, 'data.values') || {}).length === 0) { - return; + resolvedFloorsData.skipped = true; + } else { + // determine the skip rate now + const auctionSkipRate = utils.getParameterByName('pbjs_skipRate') || resolvedFloorsData.skipRate; + const isSkipped = Math.random() * 100 < parseFloat(auctionSkipRate); + resolvedFloorsData.skipped = isSkipped; } - // determine the skip rate now - const isSkipped = Math.random() * 100 < parseFloat(utils.deepAccess(resolvedFloorsData, 'data.skipRate') || 0); - resolvedFloorsData.skipped = isSkipped; - updateAdUnitsForAuction(adUnits, resolvedFloorsData, isSkipped, auctionId); + // add floorData to bids + updateAdUnitsForAuction(adUnits, resolvedFloorsData, auctionId); return resolvedFloorsData; } @@ -389,6 +394,7 @@ export function isFloorsDataValid(floorsData) { */ export function parseFloorData(floorsData, location) { if (floorsData && typeof floorsData === 'object' && isFloorsDataValid(floorsData)) { + utils.logInfo(`${MODULE_NAME}: A ${location} set the auction floor data set to `, floorsData); return { ...floorsData, location @@ -416,6 +422,7 @@ export function requestBidsHook(fn, reqBidsConfigObj) { if (_floorsConfig.auctionDelay > 0 && fetching) { hookConfig.timer = setTimeout(() => { utils.logWarn(`${MODULE_NAME}: Fetch attempt did not return in time for auction`); + _floorsConfig.fetchStatus = 'timeout'; continueAuction(hookConfig); }, _floorsConfig.auctionDelay); _delayedAuctions.push(hookConfig); @@ -443,6 +450,7 @@ function resumeDelayedAuctions() { */ export function handleFetchResponse(fetchResponse) { fetching = false; + _floorsConfig.fetchStatus = 'success'; let floorResponse; try { floorResponse = JSON.parse(fetchResponse); @@ -458,7 +466,8 @@ export function handleFetchResponse(fetchResponse) { function handleFetchError(status) { fetching = false; - utils.logError(`${MODULE_NAME}: Fetch errored with: ${status}`); + _floorsConfig.fetchStatus = 'error'; + utils.logError(`${MODULE_NAME}: Fetch errored with: `, status); // if any auctions are waiting for fetch to finish, we need to continue them! resumeDelayedAuctions(); @@ -505,6 +514,7 @@ export function handleSetFloorsConfig(config) { 'enabled', enabled => enabled !== false, // defaults to true 'auctionDelay', auctionDelay => auctionDelay || 0, 'endpoint', endpoint => endpoint || {}, + 'skipRate', () => !isNaN(utils.deepAccess(config, 'data.skipRate')) ? config.data.skipRate : config.skipRate || 0, 'enforcement', enforcement => utils.pick(enforcement || {}, [ 'enforceJS', enforceJS => enforceJS !== false, // defaults to true 'enforcePBS', enforcePBS => enforcePBS === true, // defaults to false diff --git a/modules/rubiconAnalyticsAdapter.js b/modules/rubiconAnalyticsAdapter.js index 28c11ef8264..8f30a38723b 100644 --- a/modules/rubiconAnalyticsAdapter.js +++ b/modules/rubiconAnalyticsAdapter.js @@ -197,10 +197,12 @@ function sendMessage(auctionId, bidWonId) { if (auctionCache.floorData) { auction.floors = utils.pick(auctionCache.floorData, [ 'location', - 'modelName', () => auctionCache.floorData.modelVersion || '', + 'modelName', () => auctionCache.floorData.modelVersion, 'skipped', 'enforcement', () => utils.deepAccess(auctionCache.floorData, 'enforcements.enforceJS'), - 'dealsEnforced', () => utils.deepAccess(auctionCache.floorData, 'enforcements.floorDeals') + 'dealsEnforced', () => utils.deepAccess(auctionCache.floorData, 'enforcements.floorDeals'), + 'skipRate', skipRate => !isNaN(skipRate) ? skipRate : 0, + 'fetchStatus' ]); } diff --git a/test/spec/modules/priceFloors_spec.js b/test/spec/modules/priceFloors_spec.js index 55aa7900252..0d02b7f9772 100644 --- a/test/spec/modules/priceFloors_spec.js +++ b/test/spec/modules/priceFloors_spec.js @@ -314,7 +314,13 @@ describe('the price floors module', function () { data: undefined }); runStandardAuction(); - validateBidRequests(false, undefined); + validateBidRequests(false, { + skipped: true, + modelVersion: undefined, + location: undefined, + skipRate: 0, + fetchStatus: undefined + }); }); it('should use adUnit level data if not setConfig or fetch has occured', function () { handleSetFloorsConfig({ @@ -344,6 +350,8 @@ describe('the price floors module', function () { skipped: false, modelVersion: 'adUnit Model Version', location: 'adUnit', + skipRate: 0, + fetchStatus: undefined }); }); it('bidRequests should have getFloor function and flooring meta data when setConfig occurs', function () { @@ -353,6 +361,53 @@ describe('the price floors module', function () { skipped: false, modelVersion: 'basic model', location: 'setConfig', + skipRate: 0, + fetchStatus: undefined + }); + }); + it('should take the right skipRate depending on input', function () { + // first priority is data object + sandbox.stub(Math, 'random').callsFake(() => 0.99); + let inputFloors = { + ...basicFloorConfig, + skipRate: 10, + data: { + ...basicFloorData, + skipRate: 50 + } + }; + handleSetFloorsConfig(inputFloors); + runStandardAuction(); + validateBidRequests(true, { + skipped: false, + modelVersion: 'basic model', + location: 'setConfig', + skipRate: 50, + fetchStatus: undefined + }); + + // if that does not exist uses topLevel skipRate setting + delete inputFloors.data.skipRate; + handleSetFloorsConfig(inputFloors); + runStandardAuction(); + validateBidRequests(true, { + skipped: false, + modelVersion: 'basic model', + location: 'setConfig', + skipRate: 10, + fetchStatus: undefined + }); + + // if that is not there defaults to zero + delete inputFloors.skipRate; + handleSetFloorsConfig(inputFloors); + runStandardAuction(); + validateBidRequests(true, { + skipped: false, + modelVersion: 'basic model', + location: 'setConfig', + skipRate: 0, + fetchStatus: undefined }); }); it('should not overwrite previous data object if the new one is bad', function () { @@ -378,6 +433,8 @@ describe('the price floors module', function () { skipped: false, modelVersion: 'basic model', location: 'setConfig', + skipRate: 0, + fetchStatus: undefined }); }); it('should dynamically add new schema fileds and functions if added via setConfig', function () { @@ -453,6 +510,8 @@ describe('the price floors module', function () { skipped: false, modelVersion: 'basic model', location: 'setConfig', + skipRate: 0, + fetchStatus: 'timeout' }); fakeFloorProvider.respond(); }); @@ -482,10 +541,33 @@ describe('the price floors module', function () { expect(exposedAdUnits).to.not.be.undefined; // the exposedAdUnits should be from the fetch not setConfig level data + // and fetchStatus is success since fetch worked validateBidRequests(true, { skipped: false, modelVersion: 'fetch model name', location: 'fetch', + skipRate: 0, + fetchStatus: 'success' + }); + }); + it('Should not break if floor provider returns 404', function () { + // run setConfig indicating fetch + handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakeFloorProvider.json'}}); + + // run the auction and make server respond with 404 + fakeFloorProvider.respond(); + runStandardAuction(); + + // error should have been called for fetch error + expect(logErrorSpy.calledOnce).to.equal(true); + // should have caught the response error and still used setConfig data + // and fetch failed is true + validateBidRequests(true, { + skipped: false, + modelVersion: 'basic model', + location: 'setConfig', + skipRate: 0, + fetchStatus: 'error' }); }); it('Should not break if floor provider returns non json', function () { @@ -498,11 +580,16 @@ describe('the price floors module', function () { fakeFloorProvider.respond(); runStandardAuction(); + // error should have been called for response floor data not being valid + expect(logErrorSpy.calledOnce).to.equal(true); // should have caught the response error and still used setConfig data + // and fetchStatus is 'success' but location is setConfig since it had bad data validateBidRequests(true, { skipped: false, modelVersion: 'basic model', location: 'setConfig', + skipRate: 0, + fetchStatus: 'success' }); }); it('should handle not using fetch correctly', function () { diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js index 9dc228ed288..1639389fe24 100644 --- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js +++ b/test/spec/modules/rubiconAnalyticsAdapter_spec.js @@ -664,7 +664,9 @@ describe('rubicon analytics adapter', function () { auctionInit.bidderRequests[0].bids[0].floorData = { skipped: false, modelVersion: 'someModelName', - location: 'setConfig' + location: 'setConfig', + skipRate: 15, + fetchStatus: 'error' }; let flooredResponse = { ...BID, @@ -733,7 +735,9 @@ describe('rubicon analytics adapter', function () { modelName: 'someModelName', skipped: false, enforcement: true, - dealsEnforced: false + dealsEnforced: false, + skipRate: 15, + fetchStatus: 'error' }); // first adUnit's adSlot expect(message.auctions[0].adUnits[0].adSlot).to.equal('12345/sports'); From c44a74dbce183a0becee57705ce33b4e31107fb8 Mon Sep 17 00:00:00 2001 From: sumit sharma Date: Wed, 27 May 2020 23:51:45 +0530 Subject: [PATCH 359/496] change iabSubCatId name to primaryCatId (#5303) * change iabSubCatId name to primaryCatId * change in adapter Co-authored-by: sumit sharma --- modules/adpod.js | 2 +- modules/adtelligentBidAdapter.js | 2 +- modules/appnexusBidAdapter.js | 6 +++--- modules/categoryTranslation.js | 4 ++-- src/adapters/bidderFactory.js | 2 +- test/spec/modules/adpod_spec.js | 8 ++++---- test/spec/modules/categoryTranslation_spec.js | 4 ++-- test/spec/modules/dfpAdServerVideo_spec.js | 2 +- test/spec/modules/freeWheelAdserverVideo_spec.js | 2 +- test/spec/modules/konduitWrapper_spec.js | 2 +- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/modules/adpod.js b/modules/adpod.js index 1e264365082..57baf5b5fc6 100644 --- a/modules/adpod.js +++ b/modules/adpod.js @@ -352,7 +352,7 @@ export function checkVideoBidSetupHook(fn, bid, bidRequest, videoMediaType, cont if (context === ADPOD) { let result = true; let brandCategoryExclusion = config.getConfig('adpod.brandCategoryExclusion'); - if (brandCategoryExclusion && !utils.deepAccess(bid, 'meta.iabSubCatId')) { + if (brandCategoryExclusion && !utils.deepAccess(bid, 'meta.primaryCatId')) { result = false; } diff --git a/modules/adtelligentBidAdapter.js b/modules/adtelligentBidAdapter.js index 807c2608ae2..e22aafb73fc 100644 --- a/modules/adtelligentBidAdapter.js +++ b/modules/adtelligentBidAdapter.js @@ -231,7 +231,7 @@ function createBid(bidResponse, bidRequest) { if (context === ADPOD) { Object.assign(bid, { meta: { - iabSubCatId: bidResponse.iabSubCatId, + primaryCatId: bidResponse.primaryCatId, }, video: { context: ADPOD, diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 2bec1d1f047..db5b6d61ff2 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -264,7 +264,7 @@ export const spec = { getMappingFileInfo: function() { return { url: mappingFileUrl, - refreshInDays: 7 + refreshInDays: 2 } }, @@ -525,8 +525,8 @@ function newBid(serverBid, rtbBid, bidderRequest) { const videoContext = utils.deepAccess(bidRequest, 'mediaTypes.video.context'); switch (videoContext) { case ADPOD: - const iabSubCatId = getIabSubCategory(bidRequest.bidder, rtbBid.brand_category_id); - bid.meta = Object.assign({}, bid.meta, { iabSubCatId }); + const primaryCatId = getIabSubCategory(bidRequest.bidder, rtbBid.brand_category_id); + bid.meta = Object.assign({}, bid.meta, { primaryCatId }); const dealTier = rtbBid.deal_priority; bid.video = { context: ADPOD, diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index 23aa83cf7b0..9a9289fcd73 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -52,8 +52,8 @@ export function getAdserverCategoryHook(fn, adUnitCode, bid) { } catch (error) { logError('Failed to parse translation mapping file'); } - if (bid.meta.iabSubCatId && mapping['mapping'] && mapping['mapping'][bid.meta.iabSubCatId]) { - bid.meta.adServerCatId = mapping['mapping'][bid.meta.iabSubCatId]['id']; + if (bid.meta.primaryCatId && mapping['mapping'] && mapping['mapping'][bid.meta.primaryCatId]) { + bid.meta.adServerCatId = mapping['mapping'][bid.meta.primaryCatId]['id']; } else { // This bid will be automatically ignored by adpod module as adServerCatId was not found bid.meta.adServerCatId = undefined; diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index 85dd557a725..8dd351563be 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -106,7 +106,7 @@ export const storage = getCoreStorageManager('bidderFactory'); * @property {object} [native] Object for storing native creative assets * @property {object} [video] Object for storing video response data * @property {object} [meta] Object for storing bid meta data - * @property {string} [meta.iabSubCatId] The IAB subcategory ID + * @property {string} [meta.primaryCatId] The IAB primary category ID * @property [Renderer] renderer A Renderer which can be used as a default for this bid, * if the publisher doesn't override it. This is only relevant for Outstream Video bids. */ diff --git a/test/spec/modules/adpod_spec.js b/test/spec/modules/adpod_spec.js index ff416e05522..5e4bcce1fe6 100644 --- a/test/spec/modules/adpod_spec.js +++ b/test/spec/modules/adpod_spec.js @@ -981,7 +981,7 @@ describe('adpod.js', function () { durationBucket: 15 }, meta: { - iabSubCatId: 'testCategory_123' + primaryCatId: 'testCategory_123' }, vastXml: 'test XML here' }; @@ -1050,7 +1050,7 @@ describe('adpod.js', function () { }); let goodBid = utils.deepClone(adpodTestBid); - goodBid.meta.iabSubCatId = undefined; + goodBid.meta.primaryCatId = undefined; checkVideoBidSetupHook(callbackFn, goodBid, bidderRequestNoExact, {}, ADPOD); expect(callbackResult).to.be.null; expect(bailResult).to.equal(true); @@ -1074,7 +1074,7 @@ describe('adpod.js', function () { } let noCatBid = utils.deepClone(adpodTestBid); - noCatBid.meta.iabSubCatId = undefined; + noCatBid.meta.primaryCatId = undefined; testInvalidAdpodBid(noCatBid, false); let noContextBid = utils.deepClone(adpodTestBid); @@ -1101,7 +1101,7 @@ describe('adpod.js', function () { durationSeconds: 30 }, meta: { - iabSubCatId: 'testCategory_123' + primaryCatId: 'testCategory_123' }, vastXml: '' }; diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js index d4be6839e98..2301d6aab1b 100644 --- a/test/spec/modules/categoryTranslation_spec.js +++ b/test/spec/modules/categoryTranslation_spec.js @@ -34,7 +34,7 @@ describe('category translation', function () { })); let bid = { meta: { - iabSubCatId: 'iab-1' + primaryCatId: 'iab-1' } } getAdserverCategoryHook(sinon.spy(), 'code', bid); @@ -57,7 +57,7 @@ describe('category translation', function () { })); let bid = { meta: { - iabSubCatId: 'iab-2' + primaryCatId: 'iab-2' } } getAdserverCategoryHook(sinon.spy(), 'code', bid); diff --git a/test/spec/modules/dfpAdServerVideo_spec.js b/test/spec/modules/dfpAdServerVideo_spec.js index 895416bae2b..cd412530d2b 100644 --- a/test/spec/modules/dfpAdServerVideo_spec.js +++ b/test/spec/modules/dfpAdServerVideo_spec.js @@ -528,7 +528,7 @@ function createBid(cpm, adUnitCode, durationBucket, priceIndustryDuration, uuid, }, 'customCacheKey': `${priceIndustryDuration}_${uuid}`, 'meta': { - 'iabSubCatId': 'iab-1', + 'primaryCatId': 'iab-1', 'adServerCatId': label }, 'videoCacheKey': '4cf395af-8fee-4960-af0e-88d44e399f14' diff --git a/test/spec/modules/freeWheelAdserverVideo_spec.js b/test/spec/modules/freeWheelAdserverVideo_spec.js index 172909f99ca..0a215092e18 100644 --- a/test/spec/modules/freeWheelAdserverVideo_spec.js +++ b/test/spec/modules/freeWheelAdserverVideo_spec.js @@ -342,7 +342,7 @@ function createBid(cpm, adUnitCode, durationBucket, priceIndustryDuration, uuid, }, 'customCacheKey': `${priceIndustryDuration}_${uuid}`, 'meta': { - 'iabSubCatId': 'iab-1', + 'primaryCatId': 'iab-1', 'adServerCatId': industry }, 'videoCacheKey': '4cf395af-8fee-4960-af0e-88d44e399f14' diff --git a/test/spec/modules/konduitWrapper_spec.js b/test/spec/modules/konduitWrapper_spec.js index d70cb7a6c60..9fa2a66f50c 100644 --- a/test/spec/modules/konduitWrapper_spec.js +++ b/test/spec/modules/konduitWrapper_spec.js @@ -170,7 +170,7 @@ function createBid(cpm, adUnitCode, durationBucket, priceIndustryDuration, uuid, }, 'customCacheKey': `${priceIndustryDuration}_${uuid}`, 'meta': { - 'iabSubCatId': 'iab-1', + 'primaryCatId': 'iab-1', 'adServerCatId': label }, 'videoCacheKey': '4cf395af-8fee-4960-af0e-88d44e399f14' From cd35077463c878c16de8a3b45f156fa2cec9ccb9 Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 27 May 2020 14:48:55 -0400 Subject: [PATCH 360/496] Prebid 3.21.0 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1bee18242f5..d6d2a4e2af5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.21.0-pre", + "version": "3.21.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From f874a179bab87dde7ba82ed09863948b98499bbe Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 27 May 2020 15:26:40 -0400 Subject: [PATCH 361/496] Increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d6d2a4e2af5..4ad20e0bf13 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.21.0", + "version": "3.22.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 707a103488b8c1f0717cdec6d4832eed9272a42f Mon Sep 17 00:00:00 2001 From: sumit sharma Date: Thu, 28 May 2020 19:35:28 +0530 Subject: [PATCH 362/496] Add publisher_id to appnexus adapter (#5244) * Add publisher_id to appnexus adapter * update transformBidParams fn Co-authored-by: sumit sharma --- modules/appnexusBidAdapter.js | 10 +++++++++- test/spec/modules/appnexusBidAdapter_spec.js | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index db5b6d61ff2..5e3b6a06011 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -199,6 +199,10 @@ export const spec = { payload.tpuids = tpuids; } + if (tags[0].publisher_id) { + payload.publisher_id = tags[0].publisher_id; + } + const request = formatRequest(payload, bidderRequest); return request; }, @@ -282,7 +286,8 @@ export const spec = { 'member': 'string', 'invCode': 'string', 'placementId': 'number', - 'keywords': utils.transformBidderParamKeywords + 'keywords': utils.transformBidderParamKeywords, + 'publisherId': 'number' }, params); if (isOpenRtb) { @@ -657,6 +662,9 @@ function bidToTag(bid) { if (bid.params.extInvCode) { tag.ext_inv_code = bid.params.extInvCode; } + if (bid.params.publisherId) { + tag.publisher_id = parseInt(bid.params.publisherId, 10); + } if (bid.params.externalImpId) { tag.external_imp_id = bid.params.externalImpId; } diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js index 8934d1cdaef..7d6f9c6789c 100644 --- a/test/spec/modules/appnexusBidAdapter_spec.js +++ b/test/spec/modules/appnexusBidAdapter_spec.js @@ -100,6 +100,24 @@ describe('AppNexusAdapter', function () { expect(payload.tags[0].private_sizes).to.deep.equal([{width: 300, height: 250}]); }); + it('should add publisher_id in request', function() { + let bidRequest = Object.assign({}, + bidRequests[0], + { + params: { + placementId: '10433394', + publisherId: '1231234' + } + }); + const request = spec.buildRequests([bidRequest]); + const payload = JSON.parse(request.data); + + expect(payload.tags[0].publisher_id).to.exist; + expect(payload.tags[0].publisher_id).to.deep.equal(1231234); + expect(payload.publisher_id).to.exist; + expect(payload.publisher_id).to.deep.equal(1231234); + }) + it('should add source and verison to the tag', function () { const request = spec.buildRequests(bidRequests); const payload = JSON.parse(request.data); From ededaa0f0a7c83627dd4089fe9bfe83bea064d35 Mon Sep 17 00:00:00 2001 From: Vladislav Yatsun Date: Thu, 28 May 2020 20:31:38 +0400 Subject: [PATCH 363/496] Add Onomagic Bidder Adapter (#5155) --- modules/onomagicBidAdapter.js | 246 ++++++++++++++++ modules/onomagicBidAdapter.md | 46 +++ test/spec/modules/onomagicBidAdapter_spec.js | 285 +++++++++++++++++++ 3 files changed, 577 insertions(+) create mode 100644 modules/onomagicBidAdapter.js create mode 100644 modules/onomagicBidAdapter.md create mode 100644 test/spec/modules/onomagicBidAdapter_spec.js diff --git a/modules/onomagicBidAdapter.js b/modules/onomagicBidAdapter.js new file mode 100644 index 00000000000..55fca29fbf3 --- /dev/null +++ b/modules/onomagicBidAdapter.js @@ -0,0 +1,246 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; + +const BIDDER_CODE = 'onomagic'; +const URL = 'https://bidder.onomagic.com/hb'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER], + isBidRequestValid, + buildRequests, + interpretResponse, + getUserSyncs +}; + +function buildRequests(bidReqs, bidderRequest) { + try { + let referrer = ''; + if (bidderRequest && bidderRequest.refererInfo) { + referrer = bidderRequest.refererInfo.referer; + } + const onomagicImps = []; + const publisherId = utils.getBidIdParameter('publisherId', bidReqs[0].params); + utils._each(bidReqs, function (bid) { + let bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes; + bidSizes = ((utils.isArray(bidSizes) && utils.isArray(bidSizes[0])) ? bidSizes : [bidSizes]); + bidSizes = bidSizes.filter(size => utils.isArray(size)); + const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)})); + + const element = document.getElementById(bid.adUnitCode); + const minSize = _getMinSize(processedSizes); + const viewabilityAmount = _isViewabilityMeasurable(element) + ? _getViewability(element, utils.getWindowTop(), minSize) + : 'na'; + const viewabilityAmountRounded = isNaN(viewabilityAmount) ? viewabilityAmount : Math.round(viewabilityAmount); + + const imp = { + id: bid.bidId, + banner: { + format: processedSizes, + ext: { + viewability: viewabilityAmountRounded + } + }, + tagid: String(bid.adUnitCode) + }; + const bidFloor = utils.getBidIdParameter('bidFloor', bid.params); + if (bidFloor) { + imp.bidfloor = bidFloor; + } + onomagicImps.push(imp); + }); + const onomagicBidReq = { + id: utils.getUniqueIdentifierStr(), + imp: onomagicImps, + site: { + domain: utils.parseUrl(referrer).host, + page: referrer, + publisher: { + id: publisherId + } + }, + device: { + devicetype: _getDeviceType(), + w: screen.width, + h: screen.height + }, + tmax: config.getConfig('bidderTimeout') + }; + + return { + method: 'POST', + url: URL, + data: JSON.stringify(onomagicBidReq), + options: {contentType: 'text/plain', withCredentials: false} + }; + } catch (e) { + utils.logError(e, {bidReqs, bidderRequest}); + } +} + +function isBidRequestValid(bid) { + if (bid.bidder !== BIDDER_CODE || typeof bid.params === 'undefined') { + return false; + } + + if (typeof bid.params.publisherId === 'undefined') { + return false; + } + + return true; +} + +function interpretResponse(serverResponse) { + if (!serverResponse.body || typeof serverResponse.body != 'object') { + utils.logWarn('Onomagic server returned empty/non-json response: ' + JSON.stringify(serverResponse.body)); + return []; + } + const { body: {id, seatbid} } = serverResponse; + try { + const onomagicBidResponses = []; + if (id && + seatbid && + seatbid.length > 0 && + seatbid[0].bid && + seatbid[0].bid.length > 0) { + seatbid[0].bid.map(onomagicBid => { + onomagicBidResponses.push({ + requestId: onomagicBid.impid, + cpm: parseFloat(onomagicBid.price), + width: parseInt(onomagicBid.w), + height: parseInt(onomagicBid.h), + creativeId: onomagicBid.crid || onomagicBid.id, + currency: 'USD', + netRevenue: true, + mediaType: BANNER, + ad: _getAdMarkup(onomagicBid), + ttl: 60 + }); + }); + } + return onomagicBidResponses; + } catch (e) { + utils.logError(e, {id, seatbid}); + } +} + +// Don't do user sync for now +function getUserSyncs(syncOptions, responses, gdprConsent) { + return []; +} + +function _isMobile() { + return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent); +} + +function _isConnectedTV() { + return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent); +} + +function _getDeviceType() { + return _isMobile() ? 1 : _isConnectedTV() ? 3 : 2; +} + +function _getAdMarkup(bid) { + let adm = bid.adm; + if ('nurl' in bid) { + adm += utils.createTrackPixelHtml(bid.nurl); + } + return adm; +} + +function _isViewabilityMeasurable(element) { + return !_isIframe() && element !== null; +} + +function _getViewability(element, topWin, { w, h } = {}) { + return utils.getWindowTop().document.visibilityState === 'visible' + ? _getPercentInView(element, topWin, { w, h }) + : 0; +} + +function _isIframe() { + try { + return utils.getWindowSelf() !== utils.getWindowTop(); + } catch (e) { + return true; + } +} + +function _getMinSize(sizes) { + return sizes.reduce((min, size) => size.h * size.w < min.h * min.w ? size : min); +} + +function _getBoundingBox(element, { w, h } = {}) { + let { width, height, left, top, right, bottom } = element.getBoundingClientRect(); + + if ((width === 0 || height === 0) && w && h) { + width = w; + height = h; + right = left + w; + bottom = top + h; + } + + return { width, height, left, top, right, bottom }; +} + +function _getIntersectionOfRects(rects) { + const bbox = { + left: rects[0].left, + right: rects[0].right, + top: rects[0].top, + bottom: rects[0].bottom + }; + + for (let i = 1; i < rects.length; ++i) { + bbox.left = Math.max(bbox.left, rects[i].left); + bbox.right = Math.min(bbox.right, rects[i].right); + + if (bbox.left >= bbox.right) { + return null; + } + + bbox.top = Math.max(bbox.top, rects[i].top); + bbox.bottom = Math.min(bbox.bottom, rects[i].bottom); + + if (bbox.top >= bbox.bottom) { + return null; + } + } + + bbox.width = bbox.right - bbox.left; + bbox.height = bbox.bottom - bbox.top; + + return bbox; +} + +function _getPercentInView(element, topWin, { w, h } = {}) { + const elementBoundingBox = _getBoundingBox(element, { w, h }); + + // Obtain the intersection of the element and the viewport + const elementInViewBoundingBox = _getIntersectionOfRects([ { + left: 0, + top: 0, + right: topWin.innerWidth, + bottom: topWin.innerHeight + }, elementBoundingBox ]); + + let elementInViewArea, elementTotalArea; + + if (elementInViewBoundingBox !== null) { + // Some or all of the element is in view + elementInViewArea = elementInViewBoundingBox.width * elementInViewBoundingBox.height; + elementTotalArea = elementBoundingBox.width * elementBoundingBox.height; + + return ((elementInViewArea / elementTotalArea) * 100); + } + + // No overlap between element and the viewport; therefore, the element + // lies completely out of view + return 0; +} + +registerBidder(spec); diff --git a/modules/onomagicBidAdapter.md b/modules/onomagicBidAdapter.md new file mode 100644 index 00000000000..7222a506b2c --- /dev/null +++ b/modules/onomagicBidAdapter.md @@ -0,0 +1,46 @@ +# Overview + +``` +Module Name: Onomagic Bid Adapter +Module Type: Bidder Adapter +Maintainer: vyatsun@gmail.com +``` + +# Description + +Onomagic's adapter integration to the Prebid library. + +# Test Parameters + +``` +var adUnits = [ + { + code: 'test-leaderboard', + mediaTypes: { + banner: { + sizes: [[728, 90]] + } + }, + bids: [{ + bidder: 'onomagic', + params: { + publisherId: 20167, + bidFloor: 0.01 + } + }] + }, { + code: 'test-banner', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bids: [{ + bidder: 'onomagic', + params: { + publisherId: 20167 + } + }] + } +] +``` diff --git a/test/spec/modules/onomagicBidAdapter_spec.js b/test/spec/modules/onomagicBidAdapter_spec.js new file mode 100644 index 00000000000..7c71c3e5764 --- /dev/null +++ b/test/spec/modules/onomagicBidAdapter_spec.js @@ -0,0 +1,285 @@ +import { expect } from 'chai'; +import * as utils from 'src/utils.js'; +import { spec } from 'modules/onomagicBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; + +const URL = 'https://bidder.onomagic.com/hb'; + +describe('onomagicBidAdapter', function() { + const adapter = newBidder(spec); + let element, win; + let bidRequests; + let sandbox; + + beforeEach(function() { + element = { + x: 0, + y: 0, + + width: 0, + height: 0, + + getBoundingClientRect: () => { + return { + width: element.width, + height: element.height, + + left: element.x, + top: element.y, + right: element.x + element.width, + bottom: element.y + element.height + }; + } + }; + win = { + document: { + visibilityState: 'visible' + }, + + innerWidth: 800, + innerHeight: 600 + }; + bidRequests = [{ + 'bidder': 'onomagic', + 'params': { + 'publisherId': 1234567 + }, + 'adUnitCode': 'adunit-code', + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250], [300, 600]] + } + }, + 'bidId': '5fb26ac22bde4', + 'bidderRequestId': '4bf93aeb730cb9', + 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e' + }]; + + sandbox = sinon.sandbox.create(); + sandbox.stub(document, 'getElementById').withArgs('adunit-code').returns(element); + sandbox.stub(utils, 'getWindowTop').returns(win); + sandbox.stub(utils, 'getWindowSelf').returns(win); + }); + + afterEach(function() { + sandbox.restore(); + }); + + describe('isBidRequestValid', function () { + let bid = { + 'bidder': 'onomagic', + 'params': { + 'publisherId': 1234567 + }, + 'adUnitCode': 'adunit-code', + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250], [300, 600]] + } + }, + 'bidId': '5fb26ac22bde4', + 'bidderRequestId': '4bf93aeb730cb9', + 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e', + }; + + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when publisherId not passed correctly', function () { + bid.params.publisherId = undefined; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when require params are not passed', function () { + let bid = Object.assign({}, bid); + bid.params = {}; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + it('sends bid request to our endpoint via POST', function () { + const request = spec.buildRequests(bidRequests); + expect(request.method).to.equal('POST'); + }); + + it('request url should match our endpoint url', function () { + const request = spec.buildRequests(bidRequests); + expect(request.url).to.equal(URL); + }); + + it('sets the proper banner object', function() { + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]); + }); + + it('accepts a single array as a size', function() { + bidRequests[0].mediaTypes.banner.sizes = [300, 250]; + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}]); + }); + + it('sends bidfloor param if present', function () { + bidRequests[0].params.bidFloor = 0.05; + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.imp[0].bidfloor).to.equal(0.05); + }); + + it('sends tagid', function () { + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.imp[0].tagid).to.equal('adunit-code'); + }); + + it('sends publisher id', function () { + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.site.publisher.id).to.equal(1234567); + }); + + context('when element is fully in view', function() { + it('returns 100', function() { + Object.assign(element, { width: 600, height: 400 }); + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.imp[0].banner.ext.viewability).to.equal(100); + }); + }); + + context('when element is out of view', function() { + it('returns 0', function() { + Object.assign(element, { x: -300, y: 0, width: 207, height: 320 }); + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.imp[0].banner.ext.viewability).to.equal(0); + }); + }); + + context('when element is partially in view', function() { + it('returns percentage', function() { + Object.assign(element, { width: 800, height: 800 }); + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.imp[0].banner.ext.viewability).to.equal(75); + }); + }); + + context('when width or height of the element is zero', function() { + it('try to use alternative values', function() { + Object.assign(element, { width: 0, height: 0 }); + bidRequests[0].mediaTypes.banner.sizes = [[800, 2400]]; + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.imp[0].banner.ext.viewability).to.equal(25); + }); + }); + + context('when nested iframes', function() { + it('returns \'na\'', function() { + Object.assign(element, { width: 600, height: 400 }); + + utils.getWindowTop.restore(); + utils.getWindowSelf.restore(); + sandbox.stub(utils, 'getWindowTop').returns(win); + sandbox.stub(utils, 'getWindowSelf').returns({}); + + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.imp[0].banner.ext.viewability).to.equal('na'); + }); + }); + + context('when tab is inactive', function() { + it('returns 0', function() { + Object.assign(element, { width: 600, height: 400 }); + + utils.getWindowTop.restore(); + win.document.visibilityState = 'hidden'; + sandbox.stub(utils, 'getWindowTop').returns(win); + + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.imp[0].banner.ext.viewability).to.equal(0); + }); + }); + }); + + describe('interpretResponse', function () { + let response; + beforeEach(function () { + response = { + body: { + 'id': '37386aade21a71', + 'seatbid': [{ + 'bid': [{ + 'id': '376874781', + 'impid': '283a9f4cd2415d', + 'price': 0.35743275, + 'nurl': '', + 'adm': '', + 'w': 300, + 'h': 250 + }] + }] + } + }; + }); + + it('should get the correct bid response', function () { + let expectedResponse = [{ + 'requestId': '283a9f4cd2415d', + 'cpm': 0.35743275, + 'width': 300, + 'height': 250, + 'creativeId': '376874781', + 'currency': 'USD', + 'netRevenue': true, + 'mediaType': 'banner', + 'ad': `
`, + 'ttl': 60 + }]; + + let result = spec.interpretResponse(response); + expect(result[0]).to.deep.equal(expectedResponse[0]); + }); + + it('crid should default to the bid id if not on the response', function () { + let expectedResponse = [{ + 'requestId': '283a9f4cd2415d', + 'cpm': 0.35743275, + 'width': 300, + 'height': 250, + 'creativeId': response.body.seatbid[0].bid[0].id, + 'currency': 'USD', + 'netRevenue': true, + 'mediaType': 'banner', + 'ad': `
`, + 'ttl': 60 + }]; + + let result = spec.interpretResponse(response); + expect(result[0]).to.deep.equal(expectedResponse[0]); + }); + + it('handles empty bid response', function () { + let response = { + body: '' + }; + let result = spec.interpretResponse(response); + expect(result.length).to.equal(0); + }); + }); + + describe('getUserSyncs ', () => { + let syncOptions = {iframeEnabled: true, pixelEnabled: true}; + + it('should not return', () => { + let returnStatement = spec.getUserSyncs(syncOptions, []); + expect(returnStatement).to.be.empty; + }); + }); +}); From 2fe57c39299d6afc65e9ed17d88f6f5253906ad5 Mon Sep 17 00:00:00 2001 From: preved-medved Date: Thu, 28 May 2020 17:47:12 +0100 Subject: [PATCH 364/496] AdPartner bidadapter init (#5196) * AdPartner bidadapter init * Change endpoint path and domain * Add mock banner for test launch * Add mock banner for test launch --- modules/adpartnerBidAdapter.js | 124 ++++++++++ modules/adpartnerBidAdapter.md | 32 +++ test/spec/modules/adpartnerBidAdapter_spec.js | 234 ++++++++++++++++++ 3 files changed, 390 insertions(+) create mode 100644 modules/adpartnerBidAdapter.js create mode 100644 modules/adpartnerBidAdapter.md create mode 100644 test/spec/modules/adpartnerBidAdapter_spec.js diff --git a/modules/adpartnerBidAdapter.js b/modules/adpartnerBidAdapter.js new file mode 100644 index 00000000000..2180b472120 --- /dev/null +++ b/modules/adpartnerBidAdapter.js @@ -0,0 +1,124 @@ +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js' +import {ajax} from '../src/ajax.js'; + +const BIDDER_CODE = 'adpartner'; +export const ENDPOINT_PROTOCOL = 'https'; +export const ENDPOINT_DOMAIN = 'a4p.adpartner.pro'; +export const ENDPOINT_PATH = '/hb/bid'; + +export const spec = { + code: BIDDER_CODE, + + isBidRequestValid: function (bidRequest) { + return !!parseInt(bidRequest.params.unitId); + }, + + buildRequests: function (validBidRequests, bidderRequest) { + let referer = window.location.href; + try { + referer = typeof bidderRequest.refererInfo === 'undefined' + ? window.top.location.href + : bidderRequest.refererInfo.referer; + } catch (e) {} + + let bidRequests = []; + let beaconParams = { + tag: [], + sizes: [], + referer: '' + }; + + validBidRequests.forEach(function(validBidRequest) { + bidRequests.push({ + unitId: parseInt(validBidRequest.params.unitId), + adUnitCode: validBidRequest.adUnitCode, + sizes: validBidRequest.sizes, + bidId: validBidRequest.bidId, + referer: referer + }); + + beaconParams.tag.push(validBidRequest.params.unitId); + beaconParams.sizes.push(spec.joinSizesToString(validBidRequest.sizes)); + beaconParams.referer = encodeURIComponent(referer); + }); + + beaconParams.tag = beaconParams.tag.join(','); + beaconParams.sizes = beaconParams.sizes.join(','); + + let adPartnerRequestUrl = utils.buildUrl({ + protocol: ENDPOINT_PROTOCOL, + hostname: ENDPOINT_DOMAIN, + pathname: ENDPOINT_PATH, + search: beaconParams + }); + + return { + method: 'POST', + url: adPartnerRequestUrl, + data: JSON.stringify(bidRequests) + }; + }, + + joinSizesToString: function(sizes) { + let res = []; + sizes.forEach(function(size) { + res.push(size.join('x')); + }); + + return res.join('|'); + }, + + interpretResponse: function (serverResponse, bidRequest) { + const validBids = JSON.parse(bidRequest.data); + + if (typeof serverResponse.body === 'undefined') { + return []; + } + + return validBids + .map(bid => ({ + bid: bid, + ad: serverResponse.body[bid.adUnitCode] + })) + .filter(item => item.ad) + .map(item => spec.adResponse(item.bid, item.ad)); + }, + + adResponse: function(bid, ad) { + return { + requestId: bid.bidId, + ad: ad.ad, + cpm: ad.cpm, + width: ad.width, + height: ad.height, + ttl: 60, + creativeId: ad.creativeId, + netRevenue: ad.netRevenue, + currency: ad.currency, + winNotification: ad.winNotification + }; + }, + + onBidWon: function(data) { + data.winNotification.forEach(function(unitWon) { + let adPartnerBidWonUrl = utils.buildUrl({ + protocol: ENDPOINT_PROTOCOL, + hostname: ENDPOINT_DOMAIN, + pathname: unitWon.path + }); + + if (unitWon.method === 'POST') { + spec.postRequest(adPartnerBidWonUrl, JSON.stringify(unitWon.data)); + } + }); + + return true; + }, + + postRequest(endpoint, data) { + ajax(endpoint, null, data, {method: 'POST'}); + } +} + +registerBidder(spec); diff --git a/modules/adpartnerBidAdapter.md b/modules/adpartnerBidAdapter.md new file mode 100644 index 00000000000..ad105c43a8a --- /dev/null +++ b/modules/adpartnerBidAdapter.md @@ -0,0 +1,32 @@ +# Overview + +Module Name: AdPartner Bidder Adapter + +Module Type: Bidder Adapter + +Maintainer: info@adpartner.pro + +# Description + +You can use this adapter to get a bid from adpartner.pro. + +About us : https://adpartner.pro + + +# Test Parameters +```javascript + var adUnits = [ + { + code: 'div-adpartner-example', + sizes: [[300, 250]], + bids: [ + { + bidder: "adpartner", + params: { + unitId: 5809 + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/adpartnerBidAdapter_spec.js b/test/spec/modules/adpartnerBidAdapter_spec.js new file mode 100644 index 00000000000..d30ef7ebf71 --- /dev/null +++ b/test/spec/modules/adpartnerBidAdapter_spec.js @@ -0,0 +1,234 @@ +import {expect} from 'chai'; +import {spec, ENDPOINT_PROTOCOL, ENDPOINT_DOMAIN, ENDPOINT_PATH} from 'modules/adpartnerBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; + +const BIDDER_CODE = 'adpartner'; + +describe('AdpartnerAdapter', function () { + const adapter = newBidder(spec); + + describe('inherited functions', function () { + it('exists and is a function', function () { + expect(adapter.callBids).to.be.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', function () { + it('should return true when required params found', function () { + let validRequest = { + 'params': { + 'unitId': 123 + } + }; + expect(spec.isBidRequestValid(validRequest)).to.equal(true); + }); + + it('should return true when required params is srting', function () { + let validRequest = { + 'params': { + 'unitId': '456' + } + }; + expect(spec.isBidRequestValid(validRequest)).to.equal(true); + }); + + it('should return false when required params are not passed', function () { + let validRequest = { + 'params': { + 'unknownId': 123 + } + }; + expect(spec.isBidRequestValid(validRequest)).to.equal(false); + }); + + it('should return false when required params is 0', function () { + let validRequest = { + 'params': { + 'unitId': 0 + } + }; + expect(spec.isBidRequestValid(validRequest)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + let validEndpoint = ENDPOINT_PROTOCOL + '://' + ENDPOINT_DOMAIN + ENDPOINT_PATH + '?tag=123,456&sizes=300x250|300x600,728x90&referer=https%3A%2F%2Ftest.domain'; + + let validRequest = [ + { + 'bidder': BIDDER_CODE, + 'params': { + 'unitId': 123 + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '30b31c1838de1e' + }, + { + 'bidder': BIDDER_CODE, + 'params': { + 'unitId': '456' + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [[728, 90]], + 'bidId': '22aidtbx5eabd9' + } + ]; + + let bidderRequest = { + refererInfo: { + referer: 'https://test.domain' + } + }; + + it('bidRequest HTTP method', function () { + const request = spec.buildRequests(validRequest, bidderRequest); + expect(request.method).to.equal('POST'); + }); + + it('bidRequest url', function () { + const request = spec.buildRequests(validRequest, bidderRequest); + expect(request.url).to.equal(validEndpoint); + }); + + it('bidRequest data', function () { + const request = spec.buildRequests(validRequest, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload[0].unitId).to.equal(123); + expect(payload[0].sizes).to.deep.equal([[300, 250], [300, 600]]); + expect(payload[0].bidId).to.equal('30b31c1838de1e'); + expect(payload[1].unitId).to.equal(456); + expect(payload[1].sizes).to.deep.equal([[728, 90]]); + expect(payload[1].bidId).to.equal('22aidtbx5eabd9'); + }); + }); + + describe('joinSizesToString', function () { + it('success convert sizes list to string', function () { + const sizesStr = spec.joinSizesToString([[300, 250], [300, 600]]); + expect(sizesStr).to.equal('300x250|300x600'); + }); + }); + + describe('interpretResponse', function () { + const bidRequest = { + 'method': 'POST', + 'url': ENDPOINT_PROTOCOL + '://' + ENDPOINT_DOMAIN + ENDPOINT_PATH + '?tag=123,456&code=adunit-code-1,adunit-code-2&bid=30b31c1838de1e,22aidtbx5eabd9&sizes=300x250|300x600,728x90&referer=https%3A%2F%2Ftest.domain', + 'data': '[{"unitId": 13144370,"adUnitCode": "div-gpt-ad-1460505748561-0","sizes": [[300, 250], [300, 600]],"bidId": "2bdcb0b203c17d","referer": "https://test.domain/index.html"},{"unitId": 13144370,"adUnitCode":"div-gpt-ad-1460505748561-1","sizes": [[768, 90]],"bidId": "3dc6b8084f91a8","referer": "https://test.domain/index.html"}]' + }; + + const bidResponse = { + body: { + 'div-gpt-ad-1460505748561-0': + { + 'ad': '
ad
', + 'width': 300, + 'height': 250, + 'creativeId': '8:123456', + 'syncs': [ + {'type': 'image', 'url': 'https://test.domain/tracker_1.gif'}, + {'type': 'image', 'url': 'https://test.domain/tracker_2.gif'}, + {'type': 'image', 'url': 'https://test.domain/tracker_3.gif'} + ], + 'winNotification': [ + { + 'method': 'POST', + 'path': '/hb/bid_won?test=1', + 'data': { + 'ad': [ + {'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/'} + ], + 'unit_id': 1234, + 'site_id': 123 + } + } + ], + 'cpm': 0.01, + 'currency': 'USD', + 'netRevenue': true + } + }, + headers: {} + }; + + it('result is correct', function () { + const result = spec.interpretResponse(bidResponse, bidRequest); + expect(result[0].requestId).to.equal('2bdcb0b203c17d'); + expect(result[0].cpm).to.equal(0.01); + expect(result[0].width).to.equal(300); + expect(result[0].height).to.equal(250); + expect(result[0].creativeId).to.equal('8:123456'); + expect(result[0].currency).to.equal('USD'); + expect(result[0].ttl).to.equal(60); + expect(result[0].winNotification[0]).to.deep.equal({'method': 'POST', 'path': '/hb/bid_won?test=1', 'data': {'ad': [{'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/'}], 'unit_id': 1234, 'site_id': 123}}); + }); + }); + + describe('adResponse', function () { + const bid = { + 'unitId': 13144370, + 'adUnitCode': 'div-gpt-ad-1460505748561-0', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '2bdcb0b203c17d', + 'referer': 'https://test.domain/index.html' + }; + const ad = { + 'ad': '
ad
', + 'width': 300, + 'height': 250, + 'creativeId': '8:123456', + 'syncs': [], + 'winNotification': [], + 'cpm': 0.01, + 'currency': 'USD', + 'netRevenue': true + }; + + it('fill ad for response', function () { + const result = spec.adResponse(bid, ad); + expect(result.requestId).to.equal('2bdcb0b203c17d'); + expect(result.cpm).to.equal(0.01); + expect(result.width).to.equal(300); + expect(result.height).to.equal(250); + expect(result.creativeId).to.equal('8:123456'); + expect(result.currency).to.equal('USD'); + expect(result.ttl).to.equal(60); + }); + }); + + describe('onBidWon', function () { + const bid = { + winNotification: [ + { + 'method': 'POST', + 'path': '/hb/bid_won?test=1', + 'data': { + 'ad': [ + {'dsp': 8, 'id': 800008, 'cost': 0.01, 'nurl': 'http://test.domain/'} + ], + 'unit_id': 1234, + 'site_id': 123 + } + } + ] + }; + + let ajaxStub; + + beforeEach(() => { + ajaxStub = sinon.stub(spec, 'postRequest') + }) + + afterEach(() => { + ajaxStub.restore() + }) + + it('calls adpartner\'s callback endpoint', () => { + const result = spec.onBidWon(bid); + expect(result).to.equal(true); + expect(ajaxStub.calledOnce).to.equal(true); + expect(ajaxStub.firstCall.args[0]).to.equal(ENDPOINT_PROTOCOL + '://' + ENDPOINT_DOMAIN + '/hb/bid_won?test=1'); + expect(ajaxStub.firstCall.args[1]).to.deep.equal(JSON.stringify(bid.winNotification[0].data)); + }); + }); +}); From c577d768a0e552f94573f72b03d9a843e678a268 Mon Sep 17 00:00:00 2001 From: Klaas-Jan Boon Date: Thu, 28 May 2020 18:51:52 +0200 Subject: [PATCH 365/496] Blue Billywig adapter - Add site config to request similarly to app config (#5273) * add Blue Billywig adapter * Blue Billywig Adapter - update according to review feedback * Blue Billywig Adapter - update to try and pass CircleCI * Remove the last for .. of in bluebillywigBidAdapter.js, hopefully... * Update bluebillywigBidAdapter test parameters to match renderer to rendererCode rename * Blue Billywig - Also pass through site config with OpenRTB request Co-authored-by: Klaas-Jan Boon --- modules/bluebillywigBidAdapter.js | 6 +++++- .../modules/bluebillywigBidAdapter_spec.js | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/modules/bluebillywigBidAdapter.js b/modules/bluebillywigBidAdapter.js index 9e4f5b62e48..4d40d931e1d 100644 --- a/modules/bluebillywigBidAdapter.js +++ b/modules/bluebillywigBidAdapter.js @@ -29,7 +29,11 @@ export const BB_HELPERS = { if (!request) return; if (typeof getConfig('app') === 'object') request.app = getConfig('app'); - else if (pageUrl) request.site = { page: pageUrl }; + else { + request.site = {}; + if (typeof getConfig('site') === 'object') request.site = getConfig('site'); + if (pageUrl) request.site.page = pageUrl; + } if (typeof getConfig('device') === 'object') request.device = getConfig('device'); if (!request.device) request.device = {}; diff --git a/test/spec/modules/bluebillywigBidAdapter_spec.js b/test/spec/modules/bluebillywigBidAdapter_spec.js index fcf3e16ad8b..73bd4803358 100644 --- a/test/spec/modules/bluebillywigBidAdapter_spec.js +++ b/test/spec/modules/bluebillywigBidAdapter_spec.js @@ -358,6 +358,24 @@ describe('BlueBillywigAdapter', () => { expect(payload.device.h).to.be.a('number'); }); + it('should add site when specified in config', () => { + config.setConfig({ site: { name: 'Blue Billywig', domain: 'bluebillywig.com', page: 'https://bluebillywig.com/', publisher: { id: 'abc', name: 'Blue Billywig', domain: 'bluebillywig.com' } } }); + + const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); + const payload = JSON.parse(request.data); + + expect(payload).to.have.property('site'); + expect(payload).to.have.nested.property('site.name'); + expect(payload).to.have.nested.property('site.domain'); + expect(payload).to.have.nested.property('site.page'); + expect(payload).to.have.nested.property('site.publisher'); + expect(payload).to.have.nested.property('site.publisher.id'); + expect(payload).to.have.nested.property('site.publisher.name'); + expect(payload).to.have.nested.property('site.publisher.domain'); + + config.resetConfig(); + }); + it('should add app when specified in config', () => { config.setConfig({ app: { bundle: 'org.prebid.mobile.demoapp', domain: 'prebid.org' } }); From 943034ea10be75c95e1d50d6c20c5a3cff2664dc Mon Sep 17 00:00:00 2001 From: Melody Li Date: Thu, 28 May 2020 12:52:58 -0400 Subject: [PATCH 366/496] remove uri-encoding (#5307) Co-authored-by: Melody Li --- modules/yieldmoBidAdapter.js | 14 ++++++-------- test/spec/modules/yieldmoBidAdapter_spec.js | 18 +++++++++--------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/modules/yieldmoBidAdapter.js b/modules/yieldmoBidAdapter.js index 304cf45e844..55495979ea4 100644 --- a/modules/yieldmoBidAdapter.js +++ b/modules/yieldmoBidAdapter.js @@ -38,7 +38,7 @@ export const spec = { title: localWindow.document.title || '', w: localWindow.innerWidth, h: localWindow.innerHeight, - userConsent: encodeURIComponent( + userConsent: JSON.stringify({ // case of undefined, stringify will remove param gdprApplies: @@ -49,11 +49,10 @@ export const spec = { bidderRequest && bidderRequest.gdprConsent ? bidderRequest.gdprConsent.consentString : '', - }) - ), + }), us_privacy: bidderRequest && bidderRequest.uspConsent - ? encodeURIComponent(bidderRequest.uspConsent) + ? bidderRequest.uspConsent : '', }; @@ -76,12 +75,11 @@ export const spec = { serverRequest.cri_prebid = criteoId; } if (request.schain) { - serverRequest.schain = encodeURIComponent( - JSON.stringify(request.schain) - ); + serverRequest.schain = + JSON.stringify(request.schain); } }); - serverRequest.p = encodeURIComponent('[' + serverRequest.p.toString() + ']'); + serverRequest.p = '[' + serverRequest.p.toString() + ']'; return { method: 'GET', url: SERVER_ENDPOINT, diff --git a/test/spec/modules/yieldmoBidAdapter_spec.js b/test/spec/modules/yieldmoBidAdapter_spec.js index 6858fead750..1c4c4812680 100644 --- a/test/spec/modules/yieldmoBidAdapter_spec.js +++ b/test/spec/modules/yieldmoBidAdapter_spec.js @@ -90,7 +90,7 @@ describe('YieldmoAdapter', function () { it('should place bid information into the p parameter of data', function () { let placementInfo = spec.buildRequests(bidArray, bidderRequest).data.p; expect(placementInfo).to.equal( - encodeURIComponent('[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1}]') + '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1}]' ); bidArray.push({ bidder: 'yieldmo', @@ -117,20 +117,20 @@ describe('YieldmoAdapter', function () { // multiple placements placementInfo = spec.buildRequests(bidArray, bidderRequest).data.p; expect(placementInfo).to.equal( - encodeURIComponent('[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1},{"placement_id":"adunit-code-1","callback_id":"123456789","sizes":[[300,250],[300,600]],"bidFloor":0.2}]') + '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1},{"placement_id":"adunit-code-1","callback_id":"123456789","sizes":[[300,250],[300,600]],"bidFloor":0.2}]' ); }); it('should add placement id if given', function () { bidArray[0].params.placementId = 'ym_1293871298'; let placementInfo = spec.buildRequests(bidArray, bidderRequest).data.p; - expect(placementInfo).to.include(encodeURIComponent('"ym_placement_id":"ym_1293871298"')); - expect(placementInfo).not.to.include(encodeURIComponent('"ym_placement_id":"ym_0987654321"')); + expect(placementInfo).to.include('"ym_placement_id":"ym_1293871298"'); + expect(placementInfo).not.to.include('"ym_placement_id":"ym_0987654321"'); bidArray[1].params.placementId = 'ym_0987654321'; placementInfo = spec.buildRequests(bidArray, bidderRequest).data.p; - expect(placementInfo).to.include(encodeURIComponent('"ym_placement_id":"ym_1293871298"')); - expect(placementInfo).to.include(encodeURIComponent('"ym_placement_id":"ym_0987654321"')); + expect(placementInfo).to.include('"ym_placement_id":"ym_1293871298"'); + expect(placementInfo).to.include('"ym_placement_id":"ym_0987654321"'); }); it('should add additional information to data parameter of request', function () { @@ -230,10 +230,10 @@ describe('YieldmoAdapter', function () { }; const data = spec.buildRequests(bidArray, bidderRequest).data; expect(data.userConsent).equal( - encodeURIComponent(JSON.stringify({ + JSON.stringify({ gdprApplies: true, cmp: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - })) + }) ); }); @@ -252,7 +252,7 @@ describe('YieldmoAdapter', function () { }; bidArray[0].schain = schain; const request = spec.buildRequests([bidArray[0]], bidderRequest); - expect(request.data.schain).equal(encodeURIComponent(JSON.stringify(schain))); + expect(request.data.schain).equal(JSON.stringify(schain)); }); }); From 62ef1ff2e90784c159f8e926c4154257a7b13f5e Mon Sep 17 00:00:00 2001 From: Vedant Seta Date: Thu, 28 May 2020 22:45:40 +0530 Subject: [PATCH 367/496] Media.net improvements (#5282) Co-authored-by: vedant.s --- modules/medianetAnalyticsAdapter.js | 16 +++++++++++++++- modules/medianetBidAdapter.js | 11 ++++++++--- test/spec/modules/medianetBidAdapter_spec.js | 2 ++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/modules/medianetAnalyticsAdapter.js b/modules/medianetAnalyticsAdapter.js index d31b62ca2dd..849954fa072 100644 --- a/modules/medianetAnalyticsAdapter.js +++ b/modules/medianetAnalyticsAdapter.js @@ -11,6 +11,7 @@ const ENDPOINT = 'https://pb-logs.media.net/log?logid=kfk&evtid=prebid_analytics const CONFIG_URL = 'https://prebid.media.net/rtb/prebid/analytics/config'; const EVENT_PIXEL_URL = 'https://qsearch-a.akamaihd.net/log'; const DEFAULT_LOGGING_PERCENT = 50; + const PRICE_GRANULARITY = { 'auto': 'pbAg', 'custom': 'pbCg', @@ -209,6 +210,16 @@ class AdSlot { this.logged = false; this.targeting = undefined; this.medianetPresent = 0; + // shouldBeLogged is assigned when requested, + // since we are waiting for logging percent response + this.shouldBeLogged = undefined; + } + + getShouldBeLogged() { + if (this.shouldBeLogged === undefined) { + this.shouldBeLogged = isSampled(); + } + return this.shouldBeLogged; } getLoggingData() { @@ -508,7 +519,7 @@ function sendEvent(id, adunit, isBidWonEvent) { } if (isBidWonEvent) { fireAuctionLog(id, adunit, isBidWonEvent); - } else if (isSampled() && !auctions[id].adSlots[adunit].logged) { + } else if (auctions[id].adSlots[adunit].getShouldBeLogged() && !auctions[id].adSlots[adunit].logged) { auctions[id].adSlots[adunit].logged = true; fireAuctionLog(id, adunit, isBidWonEvent); } @@ -650,6 +661,9 @@ medianetAnalytics.enableAnalytics = function (configuration) { utils.logError('Media.net Analytics adapter: cid is required.'); return; } + $$PREBID_GLOBAL$$.medianetGlobals = $$PREBID_GLOBAL$$.medianetGlobals || {}; + $$PREBID_GLOBAL$$.medianetGlobals.analyticsEnabled = true; + pageDetails = new PageDetail(); config = new Configure(configuration.options.cid); diff --git a/modules/medianetBidAdapter.js b/modules/medianetBidAdapter.js index edc34f8c9c3..5cc18acb424 100644 --- a/modules/medianetBidAdapter.js +++ b/modules/medianetBidAdapter.js @@ -26,7 +26,7 @@ mnData.urlData = { isTop: refererInfo.reachedTop } -$$PREBID_GLOBAL$$.medianetGlobals = {}; +$$PREBID_GLOBAL$$.medianetGlobals = $$PREBID_GLOBAL$$.medianetGlobals || {}; function getTopWindowReferrer() { try { @@ -145,7 +145,8 @@ function extParams(params, gdpr, uspConsent, userId) { uspApplies && { usp_consent_string: uspConsent || '' }, {coppa_applies: coppaApplies}, windowSize.w !== -1 && windowSize.h !== -1 && { screen: windowSize }, - userId && { user_id: userId } + userId && { user_id: userId }, + $$PREBID_GLOBAL$$.medianetGlobals.analyticsEnabled && { analytics: true } ); } @@ -238,6 +239,10 @@ function normalizeCoordinates(coordinates) { } } +function getBidderURL(cid) { + return BID_URL + '?cid=' + encodeURIComponent(cid); +} + function generatePayload(bidRequests, bidderRequests) { return { site: siteDetails(bidRequests[0].params.site), @@ -335,7 +340,7 @@ export const spec = { let payload = generatePayload(bidRequests, bidderRequests); return { method: 'POST', - url: BID_URL, + url: getBidderURL(payload.ext.customer_id), data: JSON.stringify(payload) }; }, diff --git a/test/spec/modules/medianetBidAdapter_spec.js b/test/spec/modules/medianetBidAdapter_spec.js index cf23bc62655..fcfdcdf8c2f 100644 --- a/test/spec/modules/medianetBidAdapter_spec.js +++ b/test/spec/modules/medianetBidAdapter_spec.js @@ -1109,6 +1109,8 @@ describe('Media.net bid adapter', function () { describe('buildRequests', function () { beforeEach(function () { + $$PREBID_GLOBAL$$.medianetGlobals = {}; + let documentStub = sandbox.stub(document, 'getElementById'); let boundingRect = { top: 50, From 9388a0deb21af1635fab7a2acec42286b18c76ba Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Fri, 29 May 2020 13:24:44 +0530 Subject: [PATCH 368/496] adWMGAnalytics - refactor unit tests (#5310) --- .../modules/adWMGAnalyticsAdapter_spec.js | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/test/spec/modules/adWMGAnalyticsAdapter_spec.js b/test/spec/modules/adWMGAnalyticsAdapter_spec.js index f24fe4d6d39..ab8336c7126 100644 --- a/test/spec/modules/adWMGAnalyticsAdapter_spec.js +++ b/test/spec/modules/adWMGAnalyticsAdapter_spec.js @@ -1,14 +1,11 @@ import adWMGAnalyticsAdapter from 'modules/adWMGAnalyticsAdapter.js'; import { expect } from 'chai'; -const sinon = require('sinon'); +import { server } from 'test/mocks/xhr.js'; let adapterManager = require('src/adapterManager').default; let events = require('src/events'); let constants = require('src/constants.json'); describe('adWMG Analytics', function () { - let xhr = sinon.useFakeXMLHttpRequest(); - let requests = []; - let timestamp = new Date() - 256; let auctionId = '5018eb39-f900-4370-b71e-3bb5b48d324f'; let timeout = 1500; @@ -114,20 +111,12 @@ describe('adWMG Analytics', function () { ] }]; - before(function () { - xhr.onCreate = function (request) { - requests.push(request); - }; - }); - after(function () { - xhr.restore(); adWMGAnalyticsAdapter.disableAnalytics(); }); describe('main test flow', function () { beforeEach(function () { - global.XMLHttpRequest = sinon.useFakeXMLHttpRequest(); sinon.stub(events, 'getEvents').returns([]); }); @@ -162,15 +151,21 @@ describe('adWMG Analytics', function () { }); it('should be two xhr requests', function () { - expect(requests.length).to.equal(2); + events.emit(constants.EVENTS.AUCTION_END, {}); + events.emit(constants.EVENTS.BID_WON, wonRequest); + expect(server.requests.length).to.equal(2); }); it('second request should be bidWon', function () { - expect(JSON.parse(requests[1].requestBody).events[0].status).to.equal(expectedBidWonData.events[0].status); + events.emit(constants.EVENTS.AUCTION_END, {}); + events.emit(constants.EVENTS.BID_WON, wonRequest); + expect(JSON.parse(server.requests[1].requestBody).events[0].status).to.equal(expectedBidWonData.events[0].status); }); it('check bidWon data', function () { - let realBidWonData = JSON.parse(requests[1].requestBody); + events.emit(constants.EVENTS.AUCTION_END, {}); + events.emit(constants.EVENTS.BID_WON, wonRequest); + let realBidWonData = JSON.parse(server.requests[1].requestBody); expect(realBidWonData.publisher_id).to.equal(expectedBidWonData.publisher_id); expect(realBidWonData.site).to.equal(expectedBidWonData.site); expect(realBidWonData.ad_unit_type[0]).to.equal(expectedBidWonData.ad_unit_type[0]); From 6288944ac5b4488b7df75324c1410d3c44317c96 Mon Sep 17 00:00:00 2001 From: Michael Kuryshev Date: Fri, 29 May 2020 13:54:52 +0200 Subject: [PATCH 369/496] VIS.X: remove bidderCode from bidResponse (#5313) --- modules/visxBidAdapter.js | 1 - test/spec/modules/visxBidAdapter_spec.js | 12 ------------ 2 files changed, 13 deletions(-) diff --git a/modules/visxBidAdapter.js b/modules/visxBidAdapter.js index e76b6035cd3..511e658c947 100644 --- a/modules/visxBidAdapter.js +++ b/modules/visxBidAdapter.js @@ -203,7 +203,6 @@ function _addBidResponse(serverBid, bidsMap, currency, bidResponses, bidsWithout const bid = slot.bids.shift(); bidResponses.push({ requestId: bid.bidId, - bidderCode: spec.code, cpm: serverBid.price, width: serverBid.w, height: serverBid.h, diff --git a/test/spec/modules/visxBidAdapter_spec.js b/test/spec/modules/visxBidAdapter_spec.js index 7720bb2a3e4..2a4f8e4c7b5 100755 --- a/test/spec/modules/visxBidAdapter_spec.js +++ b/test/spec/modules/visxBidAdapter_spec.js @@ -282,7 +282,6 @@ describe('VisxAdapter', function () { 'width': 300, 'height': 250, 'ad': '
test content 1
', - 'bidderCode': 'visx', 'currency': 'EUR', 'netRevenue': true, 'ttl': 360, @@ -339,7 +338,6 @@ describe('VisxAdapter', function () { 'width': 300, 'height': 250, 'ad': '
test content 1
', - 'bidderCode': 'visx', 'currency': 'EUR', 'netRevenue': true, 'ttl': 360, @@ -352,7 +350,6 @@ describe('VisxAdapter', function () { 'width': 300, 'height': 600, 'ad': '
test content 2
', - 'bidderCode': 'visx', 'currency': 'EUR', 'netRevenue': true, 'ttl': 360, @@ -365,7 +362,6 @@ describe('VisxAdapter', function () { 'width': 728, 'height': 90, 'ad': '
test content 3
', - 'bidderCode': 'visx', 'currency': 'EUR', 'netRevenue': true, 'ttl': 360, @@ -401,7 +397,6 @@ describe('VisxAdapter', function () { 'width': 300, 'height': 250, 'ad': '
test content 1
', - 'bidderCode': 'visx', 'currency': 'PLN', 'netRevenue': true, 'ttl': 360, @@ -531,7 +526,6 @@ describe('VisxAdapter', function () { 'width': 300, 'height': 250, 'ad': '
test content 1
', - 'bidderCode': 'visx', 'currency': 'EUR', 'netRevenue': true, 'ttl': 360, @@ -544,7 +538,6 @@ describe('VisxAdapter', function () { 'width': 300, 'height': 600, 'ad': '
test content 2
', - 'bidderCode': 'visx', 'currency': 'EUR', 'netRevenue': true, 'ttl': 360, @@ -557,7 +550,6 @@ describe('VisxAdapter', function () { 'width': 728, 'height': 90, 'ad': '
test content 3
', - 'bidderCode': 'visx', 'currency': 'EUR', 'netRevenue': true, 'ttl': 360, @@ -570,7 +562,6 @@ describe('VisxAdapter', function () { 'width': 300, 'height': 600, 'ad': '
test content 4
', - 'bidderCode': 'visx', 'currency': 'EUR', 'netRevenue': true, 'ttl': 360, @@ -583,7 +574,6 @@ describe('VisxAdapter', function () { 'width': 350, 'height': 600, 'ad': '
test content 5
', - 'bidderCode': 'visx', 'currency': 'EUR', 'netRevenue': true, 'ttl': 360, @@ -644,7 +634,6 @@ describe('VisxAdapter', function () { 'width': 300, 'height': 250, 'ad': '
test content 1
', - 'bidderCode': 'visx', 'currency': 'EUR', 'netRevenue': true, 'ttl': 360, @@ -657,7 +646,6 @@ describe('VisxAdapter', function () { 'width': 300, 'height': 250, 'ad': '
test content 2
', - 'bidderCode': 'visx', 'currency': 'EUR', 'netRevenue': true, 'ttl': 360, From d71257ef0c0fdc69415522b723d8f04ccc19b777 Mon Sep 17 00:00:00 2001 From: Adam Browning <19834421+adam-browning@users.noreply.github.com> Date: Fri, 29 May 2020 15:19:20 +0300 Subject: [PATCH 370/496] OneVideo: Excluded DAP validation for Multi-Format adUnits support (#5309) * Excluded DAP validation if publisher is using Multi-Format adUnits * Update package-lock.json * refractoring of if statement to check bid.mediaTypes.video just once * removed redundent statement --- modules/oneVideoBidAdapter.js | 6 ++---- test/spec/modules/oneVideoBidAdapter_spec.js | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/modules/oneVideoBidAdapter.js b/modules/oneVideoBidAdapter.js index fdeeaf68581..00f7086e7fb 100644 --- a/modules/oneVideoBidAdapter.js +++ b/modules/oneVideoBidAdapter.js @@ -25,14 +25,12 @@ export const spec = { return false; } - // Prevend DAP Outstream validation + // Prevend DAP Outstream validation, Banner DAP validation & Multi-Format adUnit support if (bid.mediaTypes.video) { if (bid.mediaTypes.video.context === 'outstream' && bid.params.video.display === 1) { return false; } - } - // Banner DAP validation - if (bid.mediaTypes.banner && (!bid.params.video.display)) { + } else if (bid.mediaTypes.banner && !bid.params.video.display) { return false; } diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js index b65bf02562b..26412634200 100644 --- a/test/spec/modules/oneVideoBidAdapter_spec.js +++ b/test/spec/modules/oneVideoBidAdapter_spec.js @@ -182,6 +182,21 @@ describe('OneVideoBidAdapter', function () { } expect(spec.isBidRequestValid(bidRequest)).to.equal(false); }) + + it('should return true for Multi-Format AdUnits, when the mediaTypes are both "banner" and "video" (Multi-Format Support)', function () { + bidRequest = { + mediaTypes: { + banner: { + sizes: [640, 480] + }, + video: { + context: 'outstream', + playerSize: [640, 480] + } + } + } + expect(spec.isBidRequestValid(bidRequest)).to.equal(false); + }) }); describe('spec.buildRequests', function () { From 7bbc5ab4608ea0f5c690b9f0dfc5671838395f01 Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Fri, 29 May 2020 23:36:35 +0530 Subject: [PATCH 371/496] Improvements for SizeMappingV2 (advanced size mapping) module (#5283) * basic implementatino done * fix indentical ad unit count bug * modules/sizeMappingV2.js * revert change * add missing log message * fix existing failing test cases * add additional tests for function getAdUnitDetail particularly for cacheHits and instance check * add instructive comments and rename file to advanced_size_mapping * flatten ternary operator call --- ...pingV2.html => advanced_size_mapping.html} | 39 +++- modules/sizeMappingV2.js | 80 +++---- test/spec/modules/sizeMappingV2_spec.js | 203 ++++++++++++------ 3 files changed, 209 insertions(+), 113 deletions(-) rename integrationExamples/gpt/{responsiveAds_sizeMappingV2.html => advanced_size_mapping.html} (62%) diff --git a/integrationExamples/gpt/responsiveAds_sizeMappingV2.html b/integrationExamples/gpt/advanced_size_mapping.html similarity index 62% rename from integrationExamples/gpt/responsiveAds_sizeMappingV2.html rename to integrationExamples/gpt/advanced_size_mapping.html index d262af5199a..4f1ba085c77 100644 --- a/integrationExamples/gpt/responsiveAds_sizeMappingV2.html +++ b/integrationExamples/gpt/advanced_size_mapping.html @@ -1,3 +1,6 @@ + + @@ -8,15 +11,16 @@ const FAILSAFE_TIMEOUT = 3300; const PREBID_TIMEOUT = 1000; + // Example of a multi-format ad unit setup with uses the module `sizeMappingV2.js`. const adUnits = [{ code: 'div-gpt-ad-1460505748561-0', mediaTypes: { banner: { sizeConfig: [ { minViewPort: [0, 0], sizes: [] }, // remove if < 750px - { minViewPort: [750, 0], sizes: [[300, 250], [300, 600]] }, // between 750px and 1199px - { minViewPort: [1200, 0], sizes: [[970, 90], [728, 90], [300, 250]] }, // between 1200px and 1599px - { minViewPort: [1600, 0], sizes: [[1000, 300], [970, 90], [728, 90], [300, 250]] } // greater than 1600px + { minViewPort: [750, 0], sizes: [[300, 250], [300, 600]] }, // between 750px and 1199px, use sizes: [[300, 250], [300, 600]] + { minViewPort: [1200, 0], sizes: [[970, 90], [728, 90], [300, 250]] }, // between 1200px and 1599px, use sizes: [[970, 90], [728, 90], [300, 250]] + { minViewPort: [1600, 0], sizes: [[1000, 300], [970, 90], [728, 90], [300, 250]] } // greater than 1600px, use sizes: [[1000, 300], [970, 90], [728, 90], [300, 250]] ] }, video: { @@ -31,9 +35,9 @@ required: true, sizes: [150, 50] }, - + // native media type enters auction only if device width is > 600px sizeConfig: [ - { minViewPort: [0, 0], active: false }, + { minViewPort: [0, 0], active: false }, { minViewPort: [600, 0], active: true } ] } @@ -54,12 +58,33 @@ siteId: 70608, zoneId: 498816 }, + // example of a bidder level size config. In the scenario below, bidder 'rubicon' enters auction only if the device width + // is between 850-1200 and it'll only send request for the 'native' media type. sizeConfig: [ { minViewPort: [0, 0], relevantMediaTypes: ['none'] }, { minViewPort: [850, 0], relevantMediaTypes: ['native'] }, { minViewPort: [1200, 0], relevantMediaTypes: ['none'] } ] }] + }, { + // Example of an 'Identical Ad Unit' (same 'code' as previous ad unit but different 'mediaTypes' object) + // Ad Unit makes use of the 'labelAll' operator. (the label operators can be applied at the bidder lever as well) + code: 'div-gpt-ad-1460505748561-0', + labelAll: ['tablet'], // Label check fails since labels passed to pbjs.requestBids() equals ['mobile']. This disables the entire ad unit. + mediaTypes: { + banner: { + sizeConfig: [ + { minViewPort: [800, 0], sizes: [[360, 400], [640, 200]] }, + { minViewPort: [1000, 0], sizes: [] } + ] + } + }, + bids: [{ + bidder: 'appnexus', + params: { + placementId: 4232323 + } + }] }]; var pbjs = pbjs || {}; pbjs.que = pbjs.que || []; @@ -75,9 +100,11 @@ pbjs.que.push(function () { pbjs.addAdUnits(adUnits); + pbjs.setConfig({debug: true}); pbjs.requestBids({ bidsBackHandler: sendAdserverRequest, - timeout: PREBID_TIMEOUT + timeout: PREBID_TIMEOUT, + labels: ['mobile'] }); }); diff --git a/modules/sizeMappingV2.js b/modules/sizeMappingV2.js index 339a598bae5..20ab640990b 100644 --- a/modules/sizeMappingV2.js +++ b/modules/sizeMappingV2.js @@ -31,16 +31,16 @@ function createSizeMappingInternalStore() { const sizeMappingInternalStore = {}; return { - initializeStore: function(auctionId, isUsingSizeMappingBool) { + initializeStore: function (auctionId, isUsingSizeMappingBool) { sizeMappingInternalStore[auctionId] = { usingSizeMappingV2: isUsingSizeMappingBool, adUnits: [] }; }, - getAuctionDetail: function(auctionId) { + getAuctionDetail: function (auctionId) { return sizeMappingInternalStore[auctionId]; }, - setAuctionDetail: function(auctionId, adUnitDetail) { + setAuctionDetail: function (auctionId, adUnitDetail) { sizeMappingInternalStore[auctionId].adUnits.push(adUnitDetail); } } @@ -231,7 +231,7 @@ export function checkBidderSizeConfigFormat(sizeConfig) { Array.isArray(config.relevantMediaTypes) && config.relevantMediaTypes.length > 0 && (config.relevantMediaTypes.length > 1 ? (config.relevantMediaTypes.every(mt => (includes(['banner', 'video', 'native'], mt)))) - : (['none', 'banner', 'video', 'native'].indexOf(config.relevantMediaTypes[0] > -1)))) { + : (['none', 'banner', 'video', 'native'].indexOf(config.relevantMediaTypes[0]) > -1))) { didCheckPass = didCheckPass && true; } else { didCheckPass = false; @@ -254,6 +254,7 @@ getHook('getBids').before(function (fn, bidderInfo) { if (sizeMappingInternalStore.getAuctionDetail(bidderInfo.auctionId).usingSizeMappingV2) { // if adUnit is found using sizeMappingV2 specs, run the getBids function which processes the sizeConfig object // and returns the bids array for a particular bidder. + const bids = getBids(bidderInfo); return fn.bail(bids); } else { @@ -264,30 +265,38 @@ getHook('getBids').before(function (fn, bidderInfo) { /** * Given an Ad Unit or a Bid as an input, returns a boolean telling if the Ad Unit/ Bid is active based on label checks - * @param {Object} bidOrAdUnit Either the Ad Unit object or the Bid object - * @param {Array} activeLabels List of active labels passed as an argument to pbjs.requestBids function - * @param {string} adUnitCode Unique string identifier for an Ad Unit. + * @param {Object} bidOrAdUnit - Either the Ad Unit object or the Bid object + * @param {Array} activeLabels - List of active labels passed as an argument to pbjs.requestBids function + * @param {string} adUnitCode - Unique string identifier for an Ad Unit. + * @param {number} adUnitInstance - Instance count of an 'Identical' ad unit. * @returns {boolean} Represents if the Ad Unit or the Bid is active or not */ -export function isLabelActivated(bidOrAdUnit, activeLabels, adUnitCode) { +export function isLabelActivated(bidOrAdUnit, activeLabels, adUnitCode, adUnitInstance) { let labelOperator; const labelsFound = Object.keys(bidOrAdUnit).filter(prop => prop === 'labelAny' || prop === 'labelAll'); if (labelsFound && labelsFound.length > 1) { utils.logWarn(`Size Mapping V2:: ${(bidOrAdUnit.code) - ? (`Ad Unit: ${bidOrAdUnit.code} => Ad unit has multiple label operators. Using the first declared operator: ${labelsFound[0]}`) - : (`Ad Unit: ${adUnitCode}, Bidder: ${bidOrAdUnit.bidder} => Bidder has multiple label operators. Using the first declared operator: ${labelsFound[0]}`)}`); + ? (`Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Ad unit has multiple label operators. Using the first declared operator: ${labelsFound[0]}`) + : (`Ad Unit: ${adUnitCode}(${adUnitInstance}), Bidder: ${bidOrAdUnit.bidder} => Bidder has multiple label operators. Using the first declared operator: ${labelsFound[0]}`)}`); } labelOperator = labelsFound[0]; + if (labelOperator && !activeLabels) { + utils.logWarn(`Size Mapping V2:: ${(bidOrAdUnit.code) + ? (`Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Found '${labelOperator}' on ad unit, but 'labels' is not set. Did you pass 'labels' to pbjs.requestBids() ?`) + : (`Ad Unit: ${adUnitCode}(${adUnitInstance}), Bidder: ${bidOrAdUnit.bidder} => Found '${labelOperator}' on bidder, but 'labels' is not set. Did you pass 'labels' to pbjs.requestBids() ?`)}`); + return true; + } + if (labelOperator === 'labelAll' && Array.isArray(bidOrAdUnit[labelOperator])) { if (bidOrAdUnit.labelAll.length === 0) { - utils.logWarn(`Size Mapping V2:: Ad Unit: ${bidOrAdUnit.code} => Ad unit has declared property 'labelAll' with an empty array. Ad Unit is still enabled!`); + utils.logWarn(`Size Mapping V2:: Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Ad unit has declared property 'labelAll' with an empty array.`); return true; } return bidOrAdUnit.labelAll.every(label => includes(activeLabels, label)); } else if (labelOperator === 'labelAny' && Array.isArray(bidOrAdUnit[labelOperator])) { if (bidOrAdUnit.labelAny.length === 0) { - utils.logWarn(`Size Mapping V2:: Ad Unit: ${bidOrAdUnit.code} => Ad unit has declared property 'labelAny' with an empty array. Ad Unit is still enabled!`); + utils.logWarn(`Size Mapping V2:: Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Ad unit has declared property 'labelAny' with an empty array.`); return true; } return bidOrAdUnit.labelAny.some(label => includes(activeLabels, label)); @@ -361,7 +370,7 @@ export function getFilteredMediaTypes(mediaTypes) { // banner mediaType gets deleted incase no sizes are specified for a given size bucket, that's why this check is necessary (transformedMediaTypes.banner) ? (transformedMediaTypes.banner.sizes) : ([]) ) : ((mediaType === 'video') ? ( - // video mediaType gets deleted incase no playerSize is specified for a given size bucket, that's why this check is necessary + // video mediaType gets deleted incase no playerSize is specified for a given size bucket, that's why this check is necessary (transformedMediaTypes.video) ? (transformedMediaTypes.video.playerSize) : ([]) ) : ('NA')) }; @@ -429,7 +438,7 @@ export function getRelevantMediaTypesForBidder(sizeConfig, activeViewport) { // sets sizeMappingInternalStore for a given auctionId with relevant adUnit information returned from the call to 'getFilteredMediaTypes' function // returns adUnit details object. -export function getAdUnitDetail(auctionId, adUnit) { +export function getAdUnitDetail(auctionId, adUnit, labels) { // fetch all adUnits for an auction from the sizeMappingInternalStore const adUnitsForAuction = sizeMappingInternalStore.getAuctionDetail(auctionId).adUnits; @@ -437,28 +446,28 @@ export function getAdUnitDetail(auctionId, adUnit) { const adUnitDetail = adUnitsForAuction.filter(adUnitDetail => adUnitDetail.adUnitCode === adUnit.code && utils.deepEqual(adUnitDetail.mediaTypes, adUnit.mediaTypes)); if (adUnitDetail.length > 0) { + adUnitDetail[0].cacheHits++; return adUnitDetail[0]; } else { - const { mediaTypes, sizeBucketToSizeMap, activeViewport, transformedMediaTypes } = internal.getFilteredMediaTypes(adUnit.mediaTypes); + const identicalAdUnit = adUnitsForAuction.filter(adUnitDetail => adUnitDetail.adUnitCode === adUnit.code); + const adUnitInstance = identicalAdUnit.length > 0 && typeof identicalAdUnit[0].instance === 'number' ? identicalAdUnit[identicalAdUnit.length - 1].instance + 1 : 1; + const isLabelActivated = internal.isLabelActivated(adUnit, labels, adUnit.code, adUnitInstance); + const { mediaTypes = adUnit.mediaTypes, sizeBucketToSizeMap, activeViewport, transformedMediaTypes } = isLabelActivated && internal.getFilteredMediaTypes(adUnit.mediaTypes); const adUnitDetail = { adUnitCode: adUnit.code, mediaTypes, sizeBucketToSizeMap, activeViewport, - transformedMediaTypes + transformedMediaTypes, + instance: adUnitInstance, + isLabelActivated, + cacheHits: 0 }; // set adUnitDetail in sizeMappingInternalStore against the correct 'auctionId'. sizeMappingInternalStore.setAuctionDetail(auctionId, adUnitDetail); - - // 'filteredMediaTypes' are the mediaTypes that got removed/filtered-out from adUnit.mediaTypes after sizeConfig filtration. - const filteredMediaTypes = Object.keys(mediaTypes).filter(mt => Object.keys(transformedMediaTypes).indexOf(mt) === -1); - - utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Active size buckets after filtration: `, sizeBucketToSizeMap); - if (filteredMediaTypes.length > 0) { - utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Media types that got filtered out: ${filteredMediaTypes}`); - } + isLabelActivated && utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}) => Active size buckets after filtration: `, sizeBucketToSizeMap); return adUnitDetail; } @@ -466,20 +475,19 @@ export function getAdUnitDetail(auctionId, adUnit) { export function getBids({ bidderCode, auctionId, bidderRequestId, adUnits, labels, src }) { return adUnits.reduce((result, adUnit) => { - if (internal.isLabelActivated(adUnit, labels, adUnit.code)) { - if (adUnit.mediaTypes && utils.isValidMediaTypes(adUnit.mediaTypes)) { - const { activeViewport, transformedMediaTypes } = internal.getAdUnitDetail(auctionId, adUnit); - + if (adUnit.mediaTypes && utils.isValidMediaTypes(adUnit.mediaTypes)) { + const { activeViewport, transformedMediaTypes, instance: adUnitInstance, isLabelActivated, cacheHits } = internal.getAdUnitDetail(auctionId, adUnit, labels); + if (isLabelActivated) { // check if adUnit has any active media types remaining, if not drop the adUnit from auction, // else proceed to evaluate the bids object. if (Object.keys(transformedMediaTypes).length === 0) { - utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Ad unit disabled since there are no active media types after sizeConfig filtration.`); + cacheHits === 0 && utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}) => Ad unit disabled since there are no active media types after sizeConfig filtration.`); return result; } result .push(adUnit.bids.filter(bid => bid.bidder === bidderCode) .reduce((bids, bid) => { - if (internal.isLabelActivated(bid, labels, adUnit.code)) { + if (internal.isLabelActivated(bid, labels, adUnit.code, adUnitInstance)) { // handle native params const nativeParams = adUnit.nativeParams || utils.deepAccess(adUnit, 'mediaTypes.native'); if (nativeParams) { @@ -493,7 +501,7 @@ export function getBids({ bidderCode, auctionId, bidderRequestId, adUnits, label if (bid.sizeConfig) { const relevantMediaTypes = internal.getRelevantMediaTypesForBidder(bid.sizeConfig, activeViewport); if (relevantMediaTypes.length === 0) { - utils.logError(`Size Mapping V2:: Ad Unit: ${adUnit.code}, Bidder: ${bidderCode} => 'sizeConfig' is not configured properly. This bidder won't be eligible for sizeConfig checks and will remail active.`); + utils.logError(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}), Bidder: ${bidderCode} => 'sizeConfig' is not configured properly. This bidder won't be eligible for sizeConfig checks and will remail active.`); bid = Object.assign({}, bid); } else if (relevantMediaTypes[0] !== 'none') { const bidderMediaTypes = Object @@ -507,11 +515,11 @@ export function getBids({ bidderCode, auctionId, bidderRequestId, adUnits, label if (Object.keys(bidderMediaTypes).length > 0) { bid = Object.assign({}, bid, { mediaTypes: bidderMediaTypes }); } else { - utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}, Bidder: ${bid.bidder} => 'relevantMediaTypes' does not match with any of the active mediaTypes at the Ad Unit level. This bidder is disabled.`); + utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}), Bidder: ${bid.bidder} => 'relevantMediaTypes' does not match with any of the active mediaTypes at the Ad Unit level. This bidder is disabled.`); return bids; } } else { - utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}, Bidder: ${bid.bidder} => 'relevantMediaTypes' is set to 'none' in sizeConfig for current viewport size. This bidder is disabled.`); + utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}), Bidder: ${bid.bidder} => 'relevantMediaTypes' is set to 'none' in sizeConfig for current viewport size. This bidder is disabled.`); return bids; } } @@ -530,15 +538,15 @@ export function getBids({ bidderCode, auctionId, bidderRequestId, adUnits, label })); return bids; } else { - utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}, Bidder: ${bid.bidder} => Label check for this bidder has failed. This bidder is disabled.`); + utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}), Bidder: ${bid.bidder} => Label check for this bidder has failed. This bidder is disabled.`); return bids; } }, [])); } else { - utils.logWarn(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Ad unit has declared invalid 'mediaTypes' or has not declared a 'mediaTypes' property`); + cacheHits === 0 && utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}) => Ad unit is disabled due to failing label check.`); } } else { - utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Ad unit is disabled due to failing label check.`); + utils.logWarn(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Ad unit has declared invalid 'mediaTypes' or has not declared a 'mediaTypes' property`); return result; } return result; diff --git a/test/spec/modules/sizeMappingV2_spec.js b/test/spec/modules/sizeMappingV2_spec.js index cbfc02752a8..2462db3b144 100644 --- a/test/spec/modules/sizeMappingV2_spec.js +++ b/test/spec/modules/sizeMappingV2_spec.js @@ -722,10 +722,15 @@ describe('sizeMappingV2', function () { { minViewPort: [1600, 0], relevantMediaTypes: ['native', 'video'] } ]; + // relevantMediaTypes can only include one or more of these values: 'none', 'banner', 'video', 'native' + const sizeConfig_5 = [ + { minViewPort: [0, 0], relevantMediaTypes: ['wrong'] } + ] expect(checkBidderSizeConfigFormat(sizeConfig_1)).to.equal(false); expect(checkBidderSizeConfigFormat(sizeConfig_2)).to.equal(false); expect(checkBidderSizeConfigFormat(sizeConfig_3)).to.equal(false); expect(checkBidderSizeConfigFormat(sizeConfig_4)).to.equal(false); + expect(checkBidderSizeConfigFormat(sizeConfig_5)).to.equal(false); }); it('should return "true" if the sizeConfig object is being configured properly at the Bidder level', function () { @@ -738,11 +743,12 @@ describe('sizeMappingV2', function () { }); }); - describe('isLabelActivated(bidOrAdUnit, activeLabels, adUnitCode)', function () { + describe('isLabelActivated(bidOrAdUnit, activeLabels, adUnitCode, adUnitInstance)', function () { const labelAny = ['mobile', 'tablet']; const labelAll = ['mobile', 'tablet', 'desktop', 'HD-Tv']; const activeLabels = ['mobile', 'tablet', 'desktop']; const adUnitCode = 'div-gpt-ad-1460505748561-0'; + const adUnitInstance = 1; beforeEach(function () { sinon.spy(utils, 'logWarn'); @@ -757,10 +763,10 @@ describe('sizeMappingV2', function () { adUnits.labelAny = labelAny; adUnits.labelAll = labelAll; - isLabelActivated(adUnits, activeLabels, adUnitCode); + isLabelActivated(adUnits, activeLabels, adUnitCode, adUnitInstance); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0 => Ad unit has multiple label operators. Using the first declared operator: labelAny`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0(1) => Ad unit has multiple label operators. Using the first declared operator: labelAny`); }); it('should throw a warning message if both the label operator, "labelAny"/"labelAll" are configured for an Bidder', function () { @@ -769,10 +775,10 @@ describe('sizeMappingV2', function () { adUnits.bids[0].labelAny = labelAny; adUnits.bids[0].labelAll = labelAll; - isLabelActivated(adUnits.bids[0], activeLabels, adUnitCode); + isLabelActivated(adUnits.bids[0], activeLabels, adUnitCode, adUnitInstance); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0, Bidder: appnexus => Bidder has multiple label operators. Using the first declared operator: labelAny`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0(1), Bidder: appnexus => Bidder has multiple label operators. Using the first declared operator: labelAny`); }); it('should give priority to the label operator declared first incase two label operators are found on the same Ad Unit or Bidder', function () { @@ -783,7 +789,7 @@ describe('sizeMappingV2', function () { // activeAdUnit should be "false" // 'labelAll' -> ['mobile', 'tablet', 'desktop', 'HD-Tv'] will be given priority since it's declared before 'labelAny' // since, activeLabels -> ['mobile', 'tablet', 'desktop'], doesn't include 'HD-Tv', 'isLabelActivated' function should return "false" - const activeAdUnit = isLabelActivated(adUnits, activeLabels, adUnitCode); + const activeAdUnit = isLabelActivated(adUnits, activeLabels, adUnitCode, adUnitInstance); expect(activeAdUnit).to.equal(false); // bidder level check @@ -793,7 +799,7 @@ describe('sizeMappingV2', function () { // activeBidder should be "true" // 'labelAny' -> ['mobile', 'tablet'] will be given priority since it's declared before 'labelAll' // since, activeLabels -> ['mobile', 'tablet', 'desktop'] and matches atleast one element in labelAny array, so, it'll return true - const activeBidder = isLabelActivated(adUnits.bids[0], activeLabels, adUnitCode); + const activeBidder = isLabelActivated(adUnits.bids[0], activeLabels, adUnitCode, adUnitInstance); expect(activeBidder).to.equal(true); }); @@ -802,16 +808,16 @@ describe('sizeMappingV2', function () { adUnit.labelAll = []; // adUnit level check - isLabelActivated(adUnit, activeLabels, adUnitCode); + isLabelActivated(adUnit, activeLabels, adUnitCode, adUnitInstance); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0 => Ad unit has declared property 'labelAll' with an empty array. Ad Unit is still enabled!`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0(1) => Ad unit has declared property 'labelAll' with an empty array.`); // bidder level check - isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode); + isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode, adUnitInstance); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0 => Ad unit has declared property 'labelAll' with an empty array. Ad Unit is still enabled!`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0(1) => Ad unit has declared property 'labelAll' with an empty array.`); }); it('should throw a warning log message if "labelAny" operator is declared as an empty array', function () { @@ -819,26 +825,26 @@ describe('sizeMappingV2', function () { adUnit.labelAny = []; // adUnit level check - isLabelActivated(adUnit, activeLabels, adUnitCode); + isLabelActivated(adUnit, activeLabels, adUnitCode, adUnitInstance); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0 => Ad unit has declared property 'labelAny' with an empty array. Ad Unit is still enabled!`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0(1) => Ad unit has declared property 'labelAny' with an empty array.`); // bidder level check - isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode); + isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode, adUnitInstance); sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0 => Ad unit has declared property 'labelAny' with an empty array. Ad Unit is still enabled!`); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-0(1) => Ad unit has declared property 'labelAny' with an empty array.`); }); it('should return "true" if label operators are not present on the Ad Unit or Bidder', function () { const [adUnit] = utils.deepClone(AD_UNITS); // adUnit level check - const activeAdUnit = isLabelActivated(adUnit, activeLabels, adUnitCode); + const activeAdUnit = isLabelActivated(adUnit, activeLabels, adUnitCode, adUnitInstance); expect(activeAdUnit).to.equal(true); // bidder level check - const activeBidder = isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode); + const activeBidder = isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode, adUnitInstance); expect(activeBidder).to.equal(true); }); @@ -851,13 +857,13 @@ describe('sizeMappingV2', function () { // const labelAll = ['mobile', 'tablet', 'desktop', 'HD-Tv']; // const activeLabels = ['mobile', 'tablet', 'desktop']; - const activeAdUnit = isLabelActivated(adUnit, activeLabels, adUnitCode); + const activeAdUnit = isLabelActivated(adUnit, activeLabels, adUnitCode, adUnitInstance); expect(activeAdUnit).to.equal(false) // bidder level checks adUnit.bids[0].labelAll = labelAll; - const activeBidder = isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode); + const activeBidder = isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode, adUnitInstance); expect(activeBidder).to.equal(false); }); @@ -870,15 +876,47 @@ describe('sizeMappingV2', function () { // const labelAny = ['mobile', 'tablet']; // const activeLabels = ['mobile', 'tablet', 'desktop']; - const activeAdUnit = isLabelActivated(adUnit, activeLabels, adUnitCode); + const activeAdUnit = isLabelActivated(adUnit, activeLabels, adUnitCode, adUnitInstance); expect(activeAdUnit).to.equal(true) // bidder level checks adUnit.bids[0].labelAny = labelAny; - const activeBidder = isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode); + const activeBidder = isLabelActivated(adUnit.bids[0], activeLabels, adUnitCode, adUnitInstance); expect(activeBidder).to.equal(true); }); + + it('should throw a warning message if labelAny/labelAll operator found on adunit/bidder when "label" is not passed to pbjs.requestBids', function() { + const adUnit = { + code: 'ad-unit-1', + mediaTypes: { + banner: { + sizeConfig: [{ minViewPort: [0, 0], sizes: [[300, 300], [400, 400]] }] + } + }, + labelAny: ['mobile'], + bids: [{ + bidder: 'appnexus', + params: 27, + labelAll: ['tablet', 'desktop'] + }] + } + const labels = undefined; + + // adUnit level check + isLabelActivated(adUnit, labels, adUnit.code, adUnitInstance); + + sinon.assert.callCount(utils.logWarn, 1); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: ad-unit-1(1) => Found 'labelAny' on ad unit, but 'labels' is not set. Did you pass 'labels' to pbjs.requestBids() ?`); + utils.logWarn.restore(); + + sinon.spy(utils, 'logWarn'); + + // bidder level check + isLabelActivated(adUnit.bids[0], labels, adUnit.code, adUnitInstance); + sinon.assert.callCount(utils.logWarn, 1); + sinon.assert.calledWith(utils.logWarn, `Size Mapping V2:: Ad Unit: ad-unit-1(1), Bidder: appnexus => Found 'labelAll' on bidder, but 'labels' is not set. Did you pass 'labels' to pbjs.requestBids() ?`); + }); }); describe('isSizeConfigActivated(mediaType, sizeConfig)', function () { @@ -998,7 +1036,7 @@ describe('sizeMappingV2', function () { }); }); - describe('getAdUnitDetail(auctionId, adUnit)', function () { + describe('getAdUnitDetail(auctionId, adUnit, labels)', function () { const adUnitDetailFixture_1 = { adUnitCode: 'div-gpt-ad-1460505748561-0', mediaTypes: { @@ -1052,7 +1090,10 @@ describe('sizeMappingV2', function () { }, sizeBucketToSizeMap: {}, activeViewport: {}, - transformedMediaTypes: {} + transformedMediaTypes: {}, + cacheHits: 0, + instance: 1, + isLabelActivated: true, }; const adUnitDetailFixture_2 = { adUnitCode: 'div-gpt-ad-1460505748561-1', @@ -1067,6 +1108,9 @@ describe('sizeMappingV2', function () { }, sizeBucketToSizeMap: {}, activeViewport: {}, + cacheHits: 0, + instance: 1, + isLabelActivated: true, transformedMediaTypes: { banner: {}, video: {} } } // adunit with same code at adUnitDetailFixture_1 but differnet mediaTypes object @@ -1082,8 +1126,12 @@ describe('sizeMappingV2', function () { }, sizeBucketToSizeMap: {}, activeViewport: {}, - transformedMediaTypes: {} + transformedMediaTypes: {}, + cacheHits: 0, + instance: 1, + isLabelActivated: true, } + const labels = ['mobile']; beforeEach(function () { sinon .stub(sizeMappingInternalStore, 'getAuctionDetail') @@ -1121,14 +1169,15 @@ describe('sizeMappingV2', function () { it('should return adUnit detail object from "sizeMappingInternalStore" if adUnit is already present in the store', function () { const [adUnit] = utils.deepClone(AD_UNITS); - const adUnitDetail = getAdUnitDetail('a1b2c3', adUnit); + const adUnitDetail = getAdUnitDetail('a1b2c3', adUnit, labels); sinon.assert.callCount(sizeMappingInternalStore.getAuctionDetail, 1); sinon.assert.callCount(utils.deepEqual, 1); sinon.assert.callCount(internal.getFilteredMediaTypes, 0); + expect(adUnitDetail.cacheHits).to.equal(1); expect(adUnitDetail).to.deep.equal(adUnitDetailFixture_1); }); - it('should NOT return adunit detail object from "sizeMappingInternalStore" if adUnit with the SAME CODE BUT DIFFERENT MEDIATYPES OBJECT is present in the store', function() { + it('should NOT return adunit detail object from "sizeMappingInternalStore" if adUnit with the SAME CODE BUT DIFFERENT MEDIATYPES OBJECT is present in the store', function () { const [adUnit] = utils.deepClone(AD_UNITS); adUnit.mediaTypes = { banner: { @@ -1138,7 +1187,7 @@ describe('sizeMappingV2', function () { ] } }; - const adUnitDetail = getAdUnitDetail('a1b2c3', adUnit); + const adUnitDetail = getAdUnitDetail('a1b2c3', adUnit, labels); sinon.assert.callCount(sizeMappingInternalStore.getAuctionDetail, 1); sinon.assert.callCount(utils.deepEqual, 1); expect(adUnitDetail).to.not.deep.equal(adUnitDetailFixture_1); @@ -1147,7 +1196,7 @@ describe('sizeMappingV2', function () { it('should store value in "sizeMappingInterStore" object if adUnit is NOT preset in this object', function () { const [, adUnit] = utils.deepClone(AD_UNITS); - const adUnitDetail = getAdUnitDetail('a1b2c3', adUnit); + const adUnitDetail = getAdUnitDetail('a1b2c3', adUnit, labels); sinon.assert.callCount(sizeMappingInternalStore.setAuctionDetail, 1); sinon.assert.callCount(internal.getFilteredMediaTypes, 1); expect(adUnitDetail).to.deep.equal(adUnitDetailFixture_2); @@ -1155,41 +1204,45 @@ describe('sizeMappingV2', function () { it('should log info message to show the details for activeSizeBucket', function () { const [, adUnit] = utils.deepClone(AD_UNITS); - getAdUnitDetail('a1b2c3', adUnit); + getAdUnitDetail('a1b2c3', adUnit, labels); sinon.assert.callCount(utils.logInfo, 1); - sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-1 => Active size buckets after filtration: `, adUnitDetailFixture_2.sizeBucketToSizeMap); + sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-1(1) => Active size buckets after filtration: `, adUnitDetailFixture_2.sizeBucketToSizeMap); }); - it('should log info message if any of the mediaTypes defined in adUnit.mediaTypes got filtered out', function () { - const [, adUnit] = utils.deepClone(AD_UNITS); - - internal.getFilteredMediaTypes.restore(); - - const adUnitDetailFixture = { - adUnitCode: 'div-gpt-ad-1460505748561-1', + it('should increment "instance" count if presence of "Identical ad units" is detected', function() { + const adUnit = { + code: 'div-gpt-ad-1460505748561-0', mediaTypes: { banner: { - sizes: [[300, 250], [300, 600]] - }, - video: { - context: 'instream', - playerSize: [300, 460] + sizeConfig: [{ minViewPort: [0, 0], sizes: [[300, 300]] }] } }, - sizeBucketToSizeMap: {}, - activeViewport: {}, - transformedMediaTypes: { banner: {} } - } + bids: [{ + bidder: 'appnexus', + params: 12 + }] + }; - sinon - .stub(internal, 'getFilteredMediaTypes') - .withArgs(adUnitDetailFixture.mediaTypes) - .returns(adUnitDetailFixture); + internal.getFilteredMediaTypes.restore(); - getAdUnitDetail('a1b2c3', adUnit); + sinon.stub(internal, 'getFilteredMediaTypes') + .withArgs(adUnit.mediaTypes) + .returns({ mediaTypes: {}, sizeBucketToSizeMap: {}, activeViewPort: [], transformedMediaTypes: {} }); - sinon.assert.callCount(utils.logInfo, 2); - sinon.assert.calledWith(utils.logInfo.getCall(1), `Size Mapping V2:: Ad Unit: div-gpt-ad-1460505748561-1 => Media types that got filtered out: video`); + const adUnitDetail = getAdUnitDetail('a1b2c3', adUnit, labels); + sinon.assert.callCount(sizeMappingInternalStore.setAuctionDetail, 1); + sinon.assert.callCount(internal.getFilteredMediaTypes, 1); + expect(adUnitDetail.instance).to.equal(2); + }); + + it('should not execute "getFilteredMediaTypes" function if label is not activated on the ad unit', function() { + const [adUnit] = utils.deepClone(AD_UNITS); + adUnit.labelAny = ['tablet']; + getAdUnitDetail('a1b2c3', adUnit, labels); + + // assertions + sinon.assert.callCount(internal.getFilteredMediaTypes, 0); + sinon.assert.callCount(utils.logInfo, 0); }); }); @@ -1370,12 +1423,15 @@ describe('sizeMappingV2', function () { ], sizes: [[300, 200], [400, 600]] } - } + }, + isLabelActivated: true, + instance: 1, + cacheHits: 0 }; beforeEach(function () { sinon .stub(internal, 'getAdUnitDetail') - .withArgs('6d51e2d7-1447-4242-b6af-aaa5525a2c6e', basic_AdUnit[0]) + .withArgs('6d51e2d7-1447-4242-b6af-aaa5525a2c6e', basic_AdUnit[0], []) .returns(adUnitDetailFixture); sinon.spy(internal, 'getRelevantMediaTypesForBidder'); @@ -1456,7 +1512,10 @@ describe('sizeMappingV2', function () { } }, activeViewport: [560, 260], - transformedMediaTypes: {} + transformedMediaTypes: {}, + isLabelActivated: true, + instance: 1, + cacheHits: 0 }; sinon @@ -1474,7 +1533,7 @@ describe('sizeMappingV2', function () { }); expect(bidRequests[0]).to.be.undefined; sinon.assert.callCount(utils.logInfo, 1); - sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1 => Ad unit disabled since there are no active media types after sizeConfig filtration.`); + sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1(1) => Ad unit disabled since there are no active media types after sizeConfig filtration.`); }); it('should throw an error if bidder level sizeConfig is not configured properly', function () { @@ -1502,7 +1561,7 @@ describe('sizeMappingV2', function () { expect(bidRequests[0]).to.not.be.undefined; sinon.assert.callCount(utils.logError, 1); - sinon.assert.calledWith(utils.logError, `Size Mapping V2:: Ad Unit: adUnit1, Bidder: rubicon => 'sizeConfig' is not configured properly. This bidder won't be eligible for sizeConfig checks and will remail active.`); + sinon.assert.calledWith(utils.logError, `Size Mapping V2:: Ad Unit: adUnit1(1), Bidder: rubicon => 'sizeConfig' is not configured properly. This bidder won't be eligible for sizeConfig checks and will remail active.`); }); it('should ensure bidder relevantMediaTypes is a subset of active media types at the ad unit level', function () { @@ -1585,12 +1644,15 @@ describe('sizeMappingV2', function () { activeViewport: [560, 260], transformedMediaTypes: { native: {} - } + }, + isLabelActivated: true, + instance: 1, + cacheHits: 0 }; sinon .stub(internal, 'getAdUnitDetail') - .withArgs('6d51e2d7-1447-4242-b6af-aaa5525a2c6e', adUnit[0]) + .withArgs('6d51e2d7-1447-4242-b6af-aaa5525a2c6e', adUnit[0], []) .returns(adUnitDetailFixture); const bidRequests = getBids({ @@ -1603,7 +1665,7 @@ describe('sizeMappingV2', function () { }); expect(bidRequests[0]).to.be.undefined; sinon.assert.callCount(utils.logInfo, 1); - sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1, Bidder: rubicon => 'relevantMediaTypes' does not match with any of the active mediaTypes at the Ad Unit level. This bidder is disabled.`); + sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1(1), Bidder: rubicon => 'relevantMediaTypes' does not match with any of the active mediaTypes at the Ad Unit level. This bidder is disabled.`); }); it('should throw a warning if mediaTypes object is not correctly formatted', function () { @@ -1626,10 +1688,13 @@ describe('sizeMappingV2', function () { }); it('should log a message if ad unit is disabled due to a failing label check', function () { + internal.getAdUnitDetail.restore(); + const adUnitDetail = Object.assign({}, adUnitDetailFixture); + adUnitDetail.isLabelActivated = false; sinon - .stub(internal, 'isLabelActivated') - .onFirstCall() - .returns(false); + .stub(internal, 'getAdUnitDetail') + .withArgs('6d51e2d7-1447-4242-b6af-aaa5525a2c6e', basic_AdUnit[0], []) + .returns(adUnitDetail); getBids({ bidderCode: 'appnexus', @@ -1641,15 +1706,11 @@ describe('sizeMappingV2', function () { }); sinon.assert.callCount(utils.logInfo, 1); - sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1 => Ad unit is disabled due to failing label check.`); - - internal.isLabelActivated.restore(); + sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1(1) => Ad unit is disabled due to failing label check.`); }); it('should log a message if bidder is disabled due to a failing label check', function () { - const stub = sinon.stub(internal, 'isLabelActivated') - stub.onFirstCall().returns(true); - stub.onSecondCall().returns(false); + const stub = sinon.stub(internal, 'isLabelActivated').returns(false); getBids({ bidderCode: 'appnexus', @@ -1661,7 +1722,7 @@ describe('sizeMappingV2', function () { }); sinon.assert.callCount(utils.logInfo, 1); - sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1, Bidder: appnexus => Label check for this bidder has failed. This bidder is disabled.`); + sinon.assert.calledWith(utils.logInfo, `Size Mapping V2:: Ad Unit: adUnit1(1), Bidder: appnexus => Label check for this bidder has failed. This bidder is disabled.`); internal.isLabelActivated.restore(); }) From 2a0cd2f7242b0b7d46aabb2a0e5cae27b7f4ba70 Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 31 May 2020 22:51:49 +0200 Subject: [PATCH 372/496] add onBidWon function, add bidder adapter version to bid requests (#5263) --- modules/ablidaBidAdapter.js | 9 ++++++++- test/spec/modules/ablidaBidAdapter_spec.js | 23 +++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/modules/ablidaBidAdapter.js b/modules/ablidaBidAdapter.js index ad507c18b24..9bd22ef1f0d 100644 --- a/modules/ablidaBidAdapter.js +++ b/modules/ablidaBidAdapter.js @@ -1,6 +1,7 @@ import * as utils from '../src/utils.js'; import {config} from '../src/config.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {ajax} from '../src/ajax.js'; const BIDDER_CODE = 'ablida'; const ENDPOINT_URL = 'https://bidder.ablida.net/prebid'; @@ -42,7 +43,8 @@ export const spec = { categories: bidRequest.params.categories, referer: bidderRequest.refererInfo.referer, jaySupported: jaySupported, - device: device + device: device, + adapterVersion: 2 }; return { method: 'POST', @@ -69,6 +71,11 @@ export const spec = { }); return bidResponses; }, + onBidWon: function (bid) { + if (!bid['nurl']) { return false; } + ajax(bid['nurl'], null); + return true; + } }; function getDevice() { diff --git a/test/spec/modules/ablidaBidAdapter_spec.js b/test/spec/modules/ablidaBidAdapter_spec.js index ca4fd4ab0be..0238c14fe5c 100644 --- a/test/spec/modules/ablidaBidAdapter_spec.js +++ b/test/spec/modules/ablidaBidAdapter_spec.js @@ -67,7 +67,8 @@ describe('ablidaBidAdapter', function () { bidId: '2b8c4de0116e54', jaySupported: true, device: 'desktop', - referer: 'www.example.com' + referer: 'www.example.com', + adapterVersion: 2 } }; let serverResponse = { @@ -80,7 +81,8 @@ describe('ablidaBidAdapter', function () { currency: 'EUR', netRevenue: true, ttl: 3000, - ad: '' + ad: '', + nurl: 'https://example.com/some-tracker' }] }; it('should get the correct bid response', function () { @@ -93,10 +95,25 @@ describe('ablidaBidAdapter', function () { currency: 'EUR', netRevenue: true, ttl: 3000, - ad: '' + ad: '', + nurl: 'https://example.com/some-tracker' }]; let result = spec.interpretResponse(serverResponse, bidRequest[0]); expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); }); }); + + describe('onBidWon', function() { + it('Should not ajax call if bid does not contain nurl', function() { + const result = spec.onBidWon({}); + expect(result).to.equal(false) + }) + + it('Should ajax call if bid nurl', function() { + const result = spec.onBidWon({ + nurl: 'https://example.com/some-tracker' + }); + expect(result).to.equal(true) + }) + }) }); From fcf1fadd356cdbd1bb365c84690817ceedc6046c Mon Sep 17 00:00:00 2001 From: Gena Date: Mon, 1 Jun 2020 15:02:27 +0300 Subject: [PATCH 373/496] Adtarget bid adapter (#5296) * Adtarget frist release * Fix * Fix lint * Coppa support * Added unit tests * revert package * Added unit tests --- modules/adtargetBidAdapter.js | 190 +++++++++++ modules/adtargetBidAdapter.md | 47 +++ test/spec/modules/adtargetBidAdapter_spec.js | 338 +++++++++++++++++++ 3 files changed, 575 insertions(+) create mode 100644 modules/adtargetBidAdapter.js create mode 100644 modules/adtargetBidAdapter.md create mode 100644 test/spec/modules/adtargetBidAdapter_spec.js diff --git a/modules/adtargetBidAdapter.js b/modules/adtargetBidAdapter.js new file mode 100644 index 00000000000..b22addec54f --- /dev/null +++ b/modules/adtargetBidAdapter.js @@ -0,0 +1,190 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import find from 'core-js-pure/features/array/find.js'; + +const ENDPOINT = 'https://ghb.console.adtarget.com.tr/v2/auction/'; +const BIDDER_CODE = 'adtarget'; +const DISPLAY = 'display'; +const syncsCache = {}; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [VIDEO, BANNER], + isBidRequestValid: function (bid) { + return !!utils.deepAccess(bid, 'params.aid'); + }, + getUserSyncs: function (syncOptions, serverResponses) { + const syncs = []; + + function addSyncs(bid) { + const uris = bid.cookieURLs; + const types = bid.cookieURLSTypes || []; + + if (Array.isArray(uris)) { + uris.forEach((uri, i) => { + const type = types[i] || 'image'; + + if ((!syncOptions.pixelEnabled && type === 'image') || + (!syncOptions.iframeEnabled && type === 'iframe') || + syncsCache[uri]) { + return; + } + + syncsCache[uri] = true; + syncs.push({ + type: type, + url: uri + }) + }) + } + } + + if (syncOptions.pixelEnabled || syncOptions.iframeEnabled) { + utils.isArray(serverResponses) && serverResponses.forEach((response) => { + if (response.body) { + if (utils.isArray(response.body)) { + response.body.forEach(b => { + addSyncs(b); + }) + } else { + addSyncs(response.body) + } + } + }) + } + return syncs; + }, + + buildRequests: function (bidRequests, adapterRequest) { + const adapterSettings = config.getConfig(adapterRequest.bidderCode) + const chunkSize = utils.deepAccess(adapterSettings, 'chunkSize', 10); + const { tag, bids } = bidToTag(bidRequests, adapterRequest); + const bidChunks = utils.chunk(bids, chunkSize); + return utils._map(bidChunks, (bids) => { + return { + data: Object.assign({}, tag, { BidRequests: bids }), + adapterRequest, + method: 'POST', + url: ENDPOINT + }; + }) + }, + interpretResponse: function (serverResponse, { adapterRequest }) { + serverResponse = serverResponse.body; + let bids = []; + + if (!utils.isArray(serverResponse)) { + return parseResponse(serverResponse, adapterRequest); + } + + serverResponse.forEach(serverBidResponse => { + bids = utils.flatten(bids, parseResponse(serverBidResponse, adapterRequest)); + }); + + return bids; + } +}; + +function parseResponse(serverResponse, adapterRequest) { + const isInvalidValidResp = !serverResponse || !utils.isArray(serverResponse.bids); + const bids = []; + + if (isInvalidValidResp) { + const extMessage = serverResponse && serverResponse.ext && serverResponse.ext.message ? `: ${serverResponse.ext.message}` : ''; + const errorMessage = `in response for ${adapterRequest.bidderCode} adapter ${extMessage}`; + + utils.logError(errorMessage); + + return bids; + } + + serverResponse.bids.forEach(serverBid => { + const request = find(adapterRequest.bids, (bidRequest) => { + return bidRequest.bidId === serverBid.requestId; + }); + + if (serverBid.cpm !== 0 && request !== undefined) { + const bid = createBid(serverBid, request); + + bids.push(bid); + } + }); + + return bids; +} + +function bidToTag(bidRequests, adapterRequest) { + const tag = { + Domain: utils.deepAccess(adapterRequest, 'refererInfo.referer') + }; + if (config.getConfig('coppa') === true) { + tag.Coppa = 1; + } + if (utils.deepAccess(adapterRequest, 'gdprConsent.gdprApplies')) { + tag.GDPR = 1; + tag.GDPRConsent = utils.deepAccess(adapterRequest, 'gdprConsent.consentString'); + } + if (utils.deepAccess(adapterRequest, 'uspConsent')) { + tag.USP = utils.deepAccess(adapterRequest, 'uspConsent'); + } + if (utils.deepAccess(bidRequests[0], 'schain')) { + tag.Schain = utils.deepAccess(bidRequests[0], 'schain'); + } + if (utils.deepAccess(bidRequests[0], 'userId')) { + tag.UserIds = utils.deepAccess(bidRequests[0], 'userId'); + } + + const bids = [] + + for (let i = 0, length = bidRequests.length; i < length; i++) { + const bid = prepareBidRequests(bidRequests[i]); + bids.push(bid); + } + + return { tag, bids }; +} + +function prepareBidRequests(bidReq) { + const mediaType = utils.deepAccess(bidReq, 'mediaTypes.video') ? VIDEO : DISPLAY; + const sizes = mediaType === VIDEO ? utils.deepAccess(bidReq, 'mediaTypes.video.playerSize') : utils.deepAccess(bidReq, 'mediaTypes.banner.sizes'); + const bidReqParams = { + 'CallbackId': bidReq.bidId, + 'Aid': bidReq.params.aid, + 'AdType': mediaType, + 'Sizes': utils.parseSizesInput(sizes).join(',') + }; + return bidReqParams; +} + +function getMediaType(bidderRequest) { + return utils.deepAccess(bidderRequest, 'mediaTypes.video') ? VIDEO : BANNER; +} + +function createBid(bidResponse, bidRequest) { + const mediaType = getMediaType(bidRequest) + const bid = { + requestId: bidResponse.requestId, + creativeId: bidResponse.cmpId, + height: bidResponse.height, + currency: bidResponse.cur, + width: bidResponse.width, + cpm: bidResponse.cpm, + netRevenue: true, + mediaType, + ttl: 300 + }; + + if (mediaType === BANNER) { + return Object.assign(bid, { + ad: bidResponse.ad + }); + } + Object.assign(bid, { + vastUrl: bidResponse.vastUrl + }); + return bid; +} + +registerBidder(spec); diff --git a/modules/adtargetBidAdapter.md b/modules/adtargetBidAdapter.md new file mode 100644 index 00000000000..a72b91a2f6a --- /dev/null +++ b/modules/adtargetBidAdapter.md @@ -0,0 +1,47 @@ +# Overview + +**Module Name**: Adtarget Bidder Adapter +**Module Type**: Bidder Adapter +**Maintainer**: kamil@adtarget.com.tr + +# Description +Provides a solution for accessing Video demand and display demand from Adtarget + +# Test Parameters +``` + var adUnits = [ + + // Video adUnit + { + code: 'videoPlayer', + mediaTypes: { + video: { + playerSize:[640,480] + context: 'instream' + } + }, + bids: [{ + bidder: 'adtarget', + params: { + aid: 331133 + } + }] + }, + + // Banner adUnit + { + code: 'bannerAd', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bids: [{ + bidder: 'adtarget', + params: { + aid: 350975 + } + }] + } + ]; +``` diff --git a/test/spec/modules/adtargetBidAdapter_spec.js b/test/spec/modules/adtargetBidAdapter_spec.js new file mode 100644 index 00000000000..5247dfb72e8 --- /dev/null +++ b/test/spec/modules/adtargetBidAdapter_spec.js @@ -0,0 +1,338 @@ +import { expect } from 'chai'; +import { spec } from 'modules/adtargetBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { config } from 'src/config.js'; + +const DISPLAY_REQUEST = { + 'bidder': 'adtarget', + 'params': { + 'aid': 12345 + }, + 'schain': { ver: 1 }, + 'userId': { criteo: 2 }, + 'mediaTypes': { 'banner': { 'sizes': [300, 250] } }, + 'bidderRequestId': '7101db09af0db2', + 'auctionId': '2e41f65424c87c', + 'adUnitCode': 'adunit-code', + 'bidId': '84ab500420319d', +}; + +const VIDEO_REQUEST = { + 'bidder': 'adtarget', + 'mediaTypes': { + 'video': { + 'playerSize': [[480, 360], [640, 480]] + } + }, + 'params': { + 'aid': 12345 + }, + 'bidderRequestId': '7101db09af0db2', + 'auctionId': '2e41f65424c87c', + 'adUnitCode': 'adunit-code', + 'bidId': '84ab500420319d' +}; + +const SERVER_VIDEO_RESPONSE = { + 'source': { 'aid': 12345, 'pubId': 54321 }, + 'bids': [{ + 'vastUrl': 'https://rtb.adtarget.com/vast/?adid=44F2AEB9BFC881B3', + 'requestId': '2e41f65424c87c', + 'url': '44F2AEB9BFC881B3', + 'creative_id': 342516, + 'durationSeconds': 30, + 'cmpId': 342516, + 'height': 480, + 'cur': 'USD', + 'width': 640, + 'cpm': 0.9 + }] +}; +const SERVER_DISPLAY_RESPONSE = { + 'source': { 'aid': 12345, 'pubId': 54321 }, + 'bids': [{ + 'ad': '', + 'requestId': '2e41f65424c87c', + 'creative_id': 342516, + 'cmpId': 342516, + 'height': 250, + 'cur': 'USD', + 'width': 300, + 'cpm': 0.9 + }], + 'cookieURLs': ['link1', 'link2'] +}; +const SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS = { + 'source': { 'aid': 12345, 'pubId': 54321 }, + 'bids': [{ + 'ad': '', + 'requestId': '2e41f65424c87c', + 'creative_id': 342516, + 'cmpId': 342516, + 'height': 250, + 'cur': 'USD', + 'width': 300, + 'cpm': 0.9 + }], + 'cookieURLs': ['link3', 'link4'], + 'cookieURLSTypes': ['image', 'iframe'] +}; +const videoBidderRequest = { + bidderCode: 'bidderCode', + bids: [{ mediaTypes: { video: {} }, bidId: '2e41f65424c87c' }] +}; + +const displayBidderRequest = { + bidderCode: 'bidderCode', + bids: [{ bidId: '2e41f65424c87c' }] +}; + +const displayBidderRequestWithConsents = { + bidderCode: 'bidderCode', + bids: [{ bidId: '2e41f65424c87c' }], + gdprConsent: { + gdprApplies: true, + consentString: 'test' + }, + uspConsent: 'iHaveIt' +}; + +const videoEqResponse = [{ + vastUrl: 'https://rtb.adtarget.com/vast/?adid=44F2AEB9BFC881B3', + requestId: '2e41f65424c87c', + creativeId: 342516, + mediaType: 'video', + netRevenue: true, + currency: 'USD', + height: 480, + width: 640, + ttl: 300, + cpm: 0.9 +}]; + +const displayEqResponse = [{ + requestId: '2e41f65424c87c', + creativeId: 342516, + mediaType: 'banner', + netRevenue: true, + currency: 'USD', + ad: '', + height: 250, + width: 300, + ttl: 300, + cpm: 0.9 +}]; + +describe.only('adtargetBidAdapter', () => { + const adapter = newBidder(spec); + describe('inherited functions', () => { + it('exists and is a function', () => { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('user syncs', () => { + describe('as image', () => { + it('should be returned if pixel enabled', () => { + const syncs = spec.getUserSyncs({ pixelEnabled: true }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); + + expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[0]]); + expect(syncs.map(s => s.type)).to.deep.equal(['image']); + }) + }) + + describe('as iframe', () => { + it('should be returned if iframe enabled', () => { + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); + + expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[1]]); + expect(syncs.map(s => s.type)).to.deep.equal(['iframe']); + }) + }) + + describe('user sync', () => { + it('should not be returned if passed syncs where already used', () => { + const syncs = spec.getUserSyncs({ + iframeEnabled: true, + pixelEnabled: true + }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); + + expect(syncs).to.deep.equal([]); + }) + + it('should not be returned if pixel not set', () => { + const syncs = spec.getUserSyncs({}, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); + + expect(syncs).to.be.empty; + }); + }); + describe('user syncs with both types', () => { + it('should be returned if pixel and iframe enabled', () => { + const mockedServerResponse = Object.assign({}, SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS, { 'cookieURLs': ['link5', 'link6'] }); + const syncs = spec.getUserSyncs({ + iframeEnabled: true, + pixelEnabled: true + }, [{ body: mockedServerResponse }]); + + expect(syncs.map(s => s.url)).to.deep.equal(mockedServerResponse.cookieURLs); + expect(syncs.map(s => s.type)).to.deep.equal(mockedServerResponse.cookieURLSTypes); + }); + }); + }); + + describe('isBidRequestValid', () => { + it('should return true when required params found', () => { + expect(spec.isBidRequestValid(VIDEO_REQUEST)).to.equal(true); + }); + + it('should return false when required params are not passed', () => { + let bid = Object.assign({}, VIDEO_REQUEST); + delete bid.params; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', () => { + let videoBidRequests = [VIDEO_REQUEST]; + let displayBidRequests = [DISPLAY_REQUEST]; + let videoAndDisplayBidRequests = [DISPLAY_REQUEST, VIDEO_REQUEST]; + const displayRequest = spec.buildRequests(displayBidRequests, {}); + const videoRequest = spec.buildRequests(videoBidRequests, {}); + const videoAndDisplayRequests = spec.buildRequests(videoAndDisplayBidRequests, {}); + + it('building requests as arrays', () => { + expect(videoRequest).to.be.a('array'); + expect(displayRequest).to.be.a('array'); + expect(videoAndDisplayRequests).to.be.a('array'); + }) + + it('sending as POST', () => { + const postActionMethod = 'POST' + const comparator = br => br.method === postActionMethod; + expect(videoRequest.every(comparator)).to.be.true; + expect(displayRequest.every(comparator)).to.be.true; + expect(videoAndDisplayRequests.every(comparator)).to.be.true; + }); + + it('sends correct video bid parameters', () => { + const data = videoRequest[0].data; + + const eq = { + CallbackId: '84ab500420319d', + AdType: 'video', + Aid: 12345, + Sizes: '480x360,640x480' + }; + expect(data.BidRequests[0]).to.deep.equal(eq); + }); + + it('sends correct display bid parameters', () => { + const data = displayRequest[0].data; + + const eq = { + CallbackId: '84ab500420319d', + AdType: 'display', + Aid: 12345, + Sizes: '300x250' + }; + + expect(data.BidRequests[0]).to.deep.equal(eq); + }); + + it('sends correct video and display bid parameters', () => { + const bidRequests = videoAndDisplayRequests[0].data; + const expectedBidReqs = [{ + CallbackId: '84ab500420319d', + AdType: 'display', + Aid: 12345, + Sizes: '300x250' + }, { + CallbackId: '84ab500420319d', + AdType: 'video', + Aid: 12345, + Sizes: '480x360,640x480' + }] + + expect(bidRequests.BidRequests).to.deep.equal(expectedBidReqs); + }); + + describe('publisher environment', () => { + const sandbox = sinon.sandbox.create(); + sandbox.stub(config, 'getConfig').callsFake((key) => { + const config = { + 'coppa': true + }; + return config[key]; + }); + const bidRequestWithPubSettingsData = spec.buildRequests([DISPLAY_REQUEST], displayBidderRequestWithConsents)[0].data; + sandbox.restore(); + it('sets GDPR', () => { + expect(bidRequestWithPubSettingsData.GDPR).to.be.equal(1); + expect(bidRequestWithPubSettingsData.GDPRConsent).to.be.equal(displayBidderRequestWithConsents.gdprConsent.consentString); + }); + it('sets USP', () => { + expect(bidRequestWithPubSettingsData.USP).to.be.equal(displayBidderRequestWithConsents.uspConsent); + }) + it('sets Coppa', () => { + expect(bidRequestWithPubSettingsData.Coppa).to.be.equal(1); + }) + it('sets Schain', () => { + expect(bidRequestWithPubSettingsData.Schain).to.be.deep.equal(DISPLAY_REQUEST.schain); + }) + it('sets UserId\'s', () => { + expect(bidRequestWithPubSettingsData.UserIds).to.be.deep.equal(DISPLAY_REQUEST.userId); + }) + }) + }); + + describe('interpretResponse', () => { + let serverResponse; + let adapterRequest; + let eqResponse; + + afterEach(() => { + serverResponse = null; + adapterRequest = null; + eqResponse = null; + }); + + it('should get correct video bid response', () => { + serverResponse = SERVER_VIDEO_RESPONSE; + adapterRequest = videoBidderRequest; + eqResponse = videoEqResponse; + + bidServerResponseCheck(); + }); + + it('should get correct display bid response', () => { + serverResponse = SERVER_DISPLAY_RESPONSE; + adapterRequest = displayBidderRequest; + eqResponse = displayEqResponse; + + bidServerResponseCheck(); + }); + + function bidServerResponseCheck() { + const result = spec.interpretResponse({ body: serverResponse }, { adapterRequest }); + + expect(result).to.deep.equal(eqResponse); + } + + function nobidServerResponseCheck() { + const noBidServerResponse = { bids: [] }; + const noBidResult = spec.interpretResponse({ body: noBidServerResponse }, { adapterRequest }); + + expect(noBidResult.length).to.equal(0); + } + + it('handles video nobid responses', () => { + adapterRequest = videoBidderRequest; + nobidServerResponseCheck(); + }); + + it('handles display nobid responses', () => { + adapterRequest = displayBidderRequest; + nobidServerResponseCheck(); + }); + }); +}); From 83f19f4033213cdf7ab8230ca76cf9abfecea8c9 Mon Sep 17 00:00:00 2001 From: susyt Date: Mon, 1 Jun 2020 07:58:28 -0700 Subject: [PATCH 374/496] removes referencing of digitrust library (#5316) --- modules/gumgumBidAdapter.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index ae8c15c8e84..273ecd44022 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -12,7 +12,6 @@ const storage = getStorageManager(); const BIDDER_CODE = 'gumgum' const ALIAS_BIDDER_CODE = ['gg'] const BID_ENDPOINT = `https://g2.gumgum.com/hbid/imp` -const DT_CREDENTIALS = { member: 'YcXr87z2lpbB' } const SUPPORTED_MEDIA_TYPES = [BANNER, VIDEO] const TIME_TO_LIVE = 60 @@ -91,10 +90,6 @@ function _getTradeDeskIDParam(userId) { function _getDigiTrustQueryParams(userId) { let digiTrustId = userId.digitrustid && userId.digitrustid.data; - if (!digiTrustId) { - const digiTrustUser = (window.DigiTrust && window.DigiTrust.getUser) ? window.DigiTrust.getUser(DT_CREDENTIALS) : {}; - digiTrustId = (digiTrustUser && digiTrustUser.success && digiTrustUser.identity) || ''; - } // Verify there is an ID and this user has not opted out if (!digiTrustId || (digiTrustId.privacy && digiTrustId.privacy.optout)) { return {}; From cd4019404a30aa086db877d5d0bb0f8481df57fe Mon Sep 17 00:00:00 2001 From: ucfunnel <39581136+ucfunnel@users.noreply.github.com> Date: Tue, 2 Jun 2020 19:27:08 +0800 Subject: [PATCH 375/496] ucfunnel adapter update request parameter (#5278) * Add a new ucfunnel Adapter and test page * Add a new ucfunnel Adapter and test page * 1. Use prebid lib in the repo to keep updated 2. Replace var with let 3. Put JSON.parse(JSON.stringify()) into try catch block * utils.getTopWindowLocation is a function * Change to modules from adapters * Migrate to module design * [Dev Fix] Remove width and height which can be got from ad unit id * Update ucfunnelBidAdapter to fit into new spec * Correct the endpoint. Fix the error of query string * Add test case for ucfunnelBidAdapter * Fix lint error * Update version number * Combine all checks on bid request * Add GDPR support for ucfunnel adapter * Add in-stream video and native support for ucfunnel adapter * Remove demo page. Add more test cases. * Change request method from POST to GET * Remove unnecessary comment * Support vastXml and vastUrl for video request * update TTL to 30 mins * Avoid using arrow function which is not discuraged in mocha * ucfunnel tdid support * ucfunnel fix error message in debug mode * ucfunnel adapter add bidfloor parameter * ucfunnel adapter support CCPA * ucfunnel adapter native support clicktrackers * ucfunnel adapter change cookie sync setting * ucfunnel adapter update request parameter Co-authored-by: root Co-authored-by: Ryan Chou Co-authored-by: jack.hsieh --- modules/ucfunnelBidAdapter.js | 36 ++++++++++++++++---- test/spec/modules/ucfunnelBidAdapter_spec.js | 18 ++++++++++ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index 505f3f89832..f9982edef36 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -1,6 +1,9 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js'; - +import { getStorageManager } from '../src/storageManager.js'; +import * as utils from '../src/utils.js'; +const storage = getStorageManager(); +const COOKIE_NAME = 'ucf_uid'; const VER = 'ADGENT_PREBID-2018011501'; const BIDDER_CODE = 'ucfunnel'; @@ -183,9 +186,6 @@ function getSupplyChain(schain) { function getRequestData(bid, bidderRequest) { const size = parseSizes(bid); - const loc = window.location; - const host = loc.host; - const page = loc.href; const language = navigator.language; const dnt = (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0; const userIdTdid = (bid.userId && bid.userId.tdid) ? bid.userId.tdid : ''; @@ -197,14 +197,38 @@ function getRequestData(bid, bidderRequest) { bl: language, je: 1, dnt: dnt, - host: host, - u: page, adid: bid.params.adid, tdid: userIdTdid, schain: supplyChain, fp: bid.params.bidfloor }; + try { + bidData.host = window.top.location.hostname; + bidData.u = window.top.location.href; + bidData.xr = 0; + } catch (e) { + bidData.host = window.location.hostname; + bidData.u = document.referrer || window.location.href; + bidData.xr = 1; + } + + if (window.location.ancestorOrigins && window.location.ancestorOrigins.length > 0) { + bidData.ao = window.location.ancestorOrigins[window.location.ancestorOrigins.length - 1]; + } + + if (storage.cookiesAreEnabled()) { + let ucfUid = ''; + if (storage.getCookie(COOKIE_NAME) != undefined) { + ucfUid = storage.getCookie(COOKIE_NAME); + bidData.ucfUid = ucfUid; + } else { + ucfUid = utils.generateUUID(); + bidData.ucfUid = ucfUid; + storage.setCookie(COOKIE_NAME, ucfUid); + } + } + if (size != undefined && size.length == 2) { bidData.w = size[0]; bidData.h = size[1]; diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index 70b273cfb8c..b5f29287f81 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -250,4 +250,22 @@ describe('ucfunnel Adapter', function () { }); }); }); + + describe('cookie sync', function () { + describe('cookie sync iframe', function () { + const result = spec.getUserSyncs({'iframeEnabled': true}); + + it('should return cookie sync iframe info', function () { + expect(result[0].type).to.equal('iframe'); + expect(result[0].url).to.equal('https://cdn.aralego.net/ucfad/cookie/sync.html'); + }); + }); + describe('cookie sync image', function () { + const result = spec.getUserSyncs({'pixelEnabled': true}); + it('should return cookie sync image info', function () { + expect(result[0].type).to.equal('image'); + expect(result[0].url).to.equal('https://sync.aralego.com/idSync'); + }); + }); + }); }); From adff6e444d85abf25cfb5ede6c9d30fdd383df57 Mon Sep 17 00:00:00 2001 From: adxpremium <55161519+adxpremium@users.noreply.github.com> Date: Tue, 2 Jun 2020 14:09:52 +0200 Subject: [PATCH 376/496] AdxPremium Analytics - bug fixes, handling timeout, etc. (#5182) * AdxPremium Analytics - bug fixes, handling timeout, etc. * AdxPremium Analytics - bug fixes, handling timeout, etc. * AdxPremium Analytics adapter update * AdxPremium Analytics update * unit testing added * adxpremiumAnalyticsAdapter_spec.js --- modules/adxpremiumAnalyticsAdapter.js | 134 +++++- modules/adxpremiumAnalyticsAdapter.md | 3 +- .../adxpremiumAnalyticsAdapter_spec.js | 415 ++++++++++++++++++ 3 files changed, 539 insertions(+), 13 deletions(-) create mode 100644 test/spec/modules/adxpremiumAnalyticsAdapter_spec.js diff --git a/modules/adxpremiumAnalyticsAdapter.js b/modules/adxpremiumAnalyticsAdapter.js index 47b401e2bb4..0aa0ca32374 100644 --- a/modules/adxpremiumAnalyticsAdapter.js +++ b/modules/adxpremiumAnalyticsAdapter.js @@ -5,7 +5,9 @@ import CONSTANTS from '../src/constants.json'; import * as utils from '../src/utils.js'; const analyticsType = 'endpoint'; -const url = 'https://adxpremium.services/graphql'; +const defaultUrl = 'https://adxpremium.services/graphql'; + +let reqCountry = window.reqCountry || null; // Events needed const { @@ -19,6 +21,11 @@ const { } } = CONSTANTS; +let timeoutBased = false; +let requestSent = false; +let requestDelivered = false; +let elementIds = []; + // Memory objects let completeObject = { publisher_id: null, @@ -26,11 +33,14 @@ let completeObject = { referer: null, screen_resolution: window.screen.width + 'x' + window.screen.height, device_type: null, - geo: null, + geo: reqCountry, events: [] }; -let adxpremiumAnalyticsAdapter = Object.assign(adapter({ url, analyticsType }), { +// Upgraded object +let upgradedObject = null; + +let adxpremiumAnalyticsAdapter = Object.assign(adapter({ defaultUrl, analyticsType }), { track({ eventType, args }) { switch (eventType) { case AUCTION_INIT: @@ -49,7 +59,7 @@ let adxpremiumAnalyticsAdapter = Object.assign(adapter({ url, analyticsType }), bidTimeout(args); break; case AUCTION_END: - setTimeout(function () { sendEvent(completeObject) }, 3100); + auctionEnd(args); break; default: break; @@ -62,17 +72,32 @@ let googletag = window.googletag || {}; googletag.cmd = googletag.cmd || []; googletag.cmd.push(function() { googletag.pubads().addEventListener('slotRenderEnded', args => { - utils.logInfo(Date.now() + ' GOOGLE SLOT: ' + JSON.stringify(args)); + clearSlot(args.slot.getSlotElementId()); }); }); // Event handlers let bidResponsesMapper = {}; +let bidRequestsMapper = {}; +let bidMapper = {}; function auctionInit(args) { + // Clear events + completeObject.events = []; + // Allow new requests + requestSent = false; + requestDelivered = false; + // Reset mappers + bidResponsesMapper = {}; + bidRequestsMapper = {}; + bidMapper = {}; + completeObject.auction_id = args.auctionId; completeObject.publisher_id = adxpremiumAnalyticsAdapter.initOptions.pubId; - try { completeObject.referer = args.bidderRequests[0].refererInfo.referer.split('?')[0]; } catch (e) { utils.logWarn('Could not parse referer, error details:', e.message); } + try { completeObject.referer = encodeURI(args.bidderRequests[0].refererInfo.referer.split('?')[0]); } catch (e) { utils.logError('AdxPremium Analytics - ' + e.message); } + if (args.adUnitCodes && args.adUnitCodes.length > 0) { + elementIds = args.adUnitCodes; + } completeObject.device_type = deviceType(); } function bidRequested(args) { @@ -85,9 +110,10 @@ function bidRequested(args) { args.bids.forEach(bid => { tmpObject.bid_gpt_codes[bid.adUnitCode] = bid.sizes; + bidMapper[bid.bidId] = bid.bidderRequestId; }); - completeObject.events.push(tmpObject); + bidRequestsMapper[args.bidderRequestId] = completeObject.events.push(tmpObject) - 1; } function bidResponse(args) { @@ -109,10 +135,69 @@ function bidResponse(args) { function bidWon(args) { let eventIndex = bidResponsesMapper[args.requestId]; - completeObject.events[eventIndex].is_winning = true; + if (eventIndex !== undefined) { + if (requestDelivered) { + if (completeObject.events[eventIndex]) { + // do the upgrade + utils.logInfo('AdxPremium Analytics - Upgrading request'); + completeObject.events[eventIndex].is_winning = true; + completeObject.events[eventIndex].is_upgrade = true; + upgradedObject = utils.deepClone(completeObject); + upgradedObject.events = [completeObject.events[eventIndex]]; + sendEvent(upgradedObject); // send upgrade + } else { + utils.logInfo('AdxPremium Analytics - CANNOT FIND INDEX FOR REQUEST ' + args.requestId); + } + } else { + completeObject.events[eventIndex].is_winning = true; + } + } else { + utils.logInfo('AdxPremium Analytics - Response not found, creating new one.'); + let tmpObject = { + type: 'RESPONSE', + bidder_code: args.bidderCode, + event_timestamp: args.responseTimestamp, + size: args.size, + gpt_code: args.adUnitCode, + currency: args.currency, + creative_id: args.creativeId, + time_to_respond: args.timeToRespond, + cpm: args.cpm, + is_winning: true, + is_lost: true + }; + let lostObject = utils.deepClone(completeObject); + lostObject.events = [tmpObject]; + sendEvent(lostObject); // send lost object + } } -function bidTimeout(args) { /* TODO: implement timeout */ } +function bidTimeout(args) { + let timeoutObject = utils.deepClone(completeObject); + timeoutObject.events = []; + let usedRequestIds = []; + + args.forEach(bid => { + let pulledRequestId = bidMapper[bid.bidId]; + let eventIndex = bidRequestsMapper[pulledRequestId]; + if (eventIndex !== undefined && completeObject.events[eventIndex] && usedRequestIds.indexOf(pulledRequestId) == -1) { + // mark as timeouted + let tempEventIndex = timeoutObject.events.push(completeObject.events[eventIndex]) - 1; + timeoutObject.events[tempEventIndex]['type'] = 'TIMEOUT'; + usedRequestIds.push(pulledRequestId); // mark as used + } + }); + + if (timeoutObject.events.length > 0) { + sendEvent(timeoutObject); // send timeouted + utils.logInfo('AdxPremium Analytics - Sending timeouted requests'); + } +} + +function auctionEnd(args) { + utils.logInfo('AdxPremium Analytics - Auction Ended at ' + Date.now()); + if (timeoutBased) { setTimeout(function () { requestSent = true; sendEvent(completeObject); }, 3500); } else { sendEventFallback(); } +} // Methods function deviceType() { @@ -125,16 +210,41 @@ function deviceType() { return 'desktop'; } +function clearSlot(elementId) { + if (elementIds.includes(elementId)) { elementIds.splice(elementIds.indexOf(elementId), 1); utils.logInfo('AdxPremium Analytics - Done with: ' + elementId); } + if (elementIds.length == 0 && !requestSent && !timeoutBased) { + requestSent = true; + sendEvent(completeObject); + utils.logInfo('AdxPremium Analytics - Everything ready'); + } +} + +export function testSend() { + sendEvent(completeObject); + utils.logInfo('AdxPremium Analytics - Sending without any conditions, used for testing'); +} + +function sendEventFallback() { + setTimeout(function () { + if (!requestSent) { requestSent = true; sendEvent(completeObject); utils.logInfo('AdxPremium Analytics - Sending event using fallback method.'); } + }, 2000); +} + function sendEvent(completeObject) { + requestDelivered = true; try { let responseEvents = btoa(JSON.stringify(completeObject)); let mutation = `mutation {createEvent(input: {event: {eventData: "${responseEvents}"}}) {event {createTime } } }`; let dataToSend = JSON.stringify({ query: mutation }); - ajax(url, function () { utils.logInfo(Date.now() + ' Sending event to adxpremium server.') }, dataToSend, { + let ajaxEndpoint = defaultUrl; + if (adxpremiumAnalyticsAdapter.initOptions.sid) { + ajaxEndpoint = 'https://' + adxpremiumAnalyticsAdapter.initOptions.sid + '.adxpremium.services/graphql' + } + ajax(ajaxEndpoint, function () { utils.logInfo('AdxPremium Analytics - Sending complete events at ' + Date.now()) }, dataToSend, { contentType: 'application/json', method: 'POST' }); - } catch (err) { utils.logError('Could not send event, error details:', err) } + } catch (err) { utils.logError('AdxPremium Analytics - Sending event error: ' + err); } } // save the base class function @@ -145,7 +255,7 @@ adxpremiumAnalyticsAdapter.enableAnalytics = function (config) { adxpremiumAnalyticsAdapter.initOptions = config.options; if (!config.options.pubId) { - utils.logError('Publisher ID (pubId) option is not defined. Analytics won\'t work'); + utils.logError('AdxPremium Analytics - Publisher ID (pubId) option is not defined. Analytics won\'t work'); return; } diff --git a/modules/adxpremiumAnalyticsAdapter.md b/modules/adxpremiumAnalyticsAdapter.md index b2a5efd653f..ab4ae53fe17 100644 --- a/modules/adxpremiumAnalyticsAdapter.md +++ b/modules/adxpremiumAnalyticsAdapter.md @@ -32,10 +32,11 @@ pbjs.que.push(function () { provider: 'adxpremium', options: { pubID: 12345678 + sid: "s2" } }); }]); }); ``` -*Note*: To use AdxPremium Prebid Analytics Adapter, you have to be AdxPremium publisher and get the publisher ID as well as include the adapter in your **Prebid Core** script. +*Note*: To use AdxPremium Prebid Analytics Adapter, you have to be AdxPremium publisher and get the publisher ID & sid (Server ID) as well as include the adapter in your **Prebid Core** script. diff --git a/test/spec/modules/adxpremiumAnalyticsAdapter_spec.js b/test/spec/modules/adxpremiumAnalyticsAdapter_spec.js new file mode 100644 index 00000000000..e4a8fa9dccd --- /dev/null +++ b/test/spec/modules/adxpremiumAnalyticsAdapter_spec.js @@ -0,0 +1,415 @@ +import adxpremiumAnalyticsAdapter from 'modules/adxpremiumAnalyticsAdapter.js'; +import { testSend } from 'modules/adxpremiumAnalyticsAdapter.js'; +import { expect } from 'chai'; +import adapterManager from 'src/adapterManager.js'; +import { server } from 'test/mocks/xhr.js'; + +let events = require('src/events'); +let constants = require('src/constants.json'); + +describe('AdxPremium analytics adapter', function () { + beforeEach(function () { + sinon.stub(events, 'getEvents').returns([]); + }); + + afterEach(function () { + events.getEvents.restore(); + }); + + describe('track', function () { + let initOptions = { + pubId: 123, + sid: 's2' + }; + + let auctionInit = { + 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', + 'timestamp': 1589707613899, + 'auctionStatus': 'inProgress', + 'adUnits': [ + { + 'code': 'div-gpt-ad-1533155193780-2', + 'mediaTypes': { + 'banner': { + 'sizes': [ + [ + 300, + 250 + ] + ] + } + }, + 'bids': [ + { + 'bidder': 'luponmedia', + 'params': { + 'siteId': 303522, + 'keyId': '4o2c4' + }, + 'crumbs': { + 'pubcid': 'aebbdfa9-3e0f-49b6-ad87-437aaa88db2d' + } + } + ], + 'sizes': [ + [ + 300, + 250 + ] + ], + 'transactionId': 'f68c54c2-0814-4ae5-95f5-09f6dd9dc1ef' + } + ], + 'adUnitCodes': [ + 'div-gpt-ad-1533155193780-2' + ], + 'labels': [ + 'BA' + ], + 'bidderRequests': [ + { + 'bidderCode': 'luponmedia', + 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', + 'bidderRequestId': '18c49b05a23645', + 'bids': [ + { + 'bidder': 'luponmedia', + 'params': { + 'siteId': 303522, + 'keyId': '4o2c4' + }, + 'crumbs': { + 'pubcid': 'aebbdfa9-3e0f-49b6-ad87-437aaa88db2d' + }, + 'mediaTypes': { + 'banner': { + 'sizes': [ + [ + 300, + 250 + ] + ] + } + }, + 'adUnitCode': 'div-gpt-ad-1533155193780-2', + 'transactionId': 'f68c54c2-0814-4ae5-95f5-09f6dd9dc1ef', + 'sizes': [ + [ + 300, + 250 + ] + ], + 'bidId': '284f8e1469246a', + 'bidderRequestId': '18c49b05a23645', + 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0, + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'novi.ba', + 'sid': '199424', + 'hp': 1 + } + ] + } + } + ], + 'auctionStart': 1589707613899, + 'timeout': 2000, + 'refererInfo': { + 'referer': 'https://test.com/article/176067', + 'reachedTop': true, + 'numIframes': 0, + 'stack': [ + 'https://test.com/article/176067' + ] + }, + 'gdprConsent': {} + } + ], + 'noBids': [], + 'bidsReceived': [], + 'winningBids': [], + 'timeout': 2000, + 'config': { + 'pubId': 4444, + 'sid': 's2' + } + }; + + // requests & responses + let bidRequest = { + 'bidderCode': 'luponmedia', + 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', + 'bidderRequestId': '18c49b05a23645', + 'bids': [ + { + 'bidder': 'luponmedia', + 'params': { + 'siteId': 303522, + 'keyId': '4o2c4' + }, + 'crumbs': { + 'pubcid': 'aebbdfa9-3e0f-49b6-ad87-437aaa88db2d' + }, + 'mediaTypes': { + 'banner': { + 'sizes': [ + [ + 300, + 250 + ] + ] + } + }, + 'adUnitCode': 'div-gpt-ad-1533155193780-2', + 'transactionId': 'f68c54c2-0814-4ae5-95f5-09f6dd9dc1ef', + 'sizes': [ + [ + 300, + 250 + ] + ], + 'bidId': '284f8e1469246a', + 'bidderRequestId': '18c49b05a23645', + 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0, + }, + { + 'bidder': 'luponmedia', + 'params': { + 'siteId': 303522, + 'keyId': '4o2c5' + }, + 'crumbs': { + 'pubcid': 'aebbdfa9-3e0f-49b6-ad87-437aaa88db2d' + }, + 'mediaTypes': { + 'banner': { + 'sizes': [ + [ + 300, + 250 + ] + ] + } + }, + 'adUnitCode': 'div-gpt-ad-1533155193780-3', + 'transactionId': 'f68c54c2-0814-4ae5-95f5-09f6dd9dc1ef', + 'sizes': [ + [ + 300, + 250 + ] + ], + 'bidId': '284f8e1469246b', + 'bidderRequestId': '18c49b05a23645', + 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0, + } + ], + 'auctionStart': 1589707613899, + 'timeout': 2000, + 'refererInfo': { + 'referer': 'https://test.com/article/176067', + 'reachedTop': true, + 'numIframes': 0, + 'stack': [ + 'https://test.com/article/176067' + ] + }, + 'start': 1589707613908 + }; + + let bidResponse = { + 'bidderCode': 'luponmedia', + 'width': 300, + 'height': 250, + 'statusMessage': 'Bid available', + 'adId': '3b40e0da8968f5', + 'requestId': '284f8e1469246a', + 'mediaType': 'banner', + 'source': 'client', + 'cpm': 0.43, + 'creativeId': '443801010', + 'currency': 'USD', + 'netRevenue': false, + 'ttl': 300, + 'referrer': '', + 'ad': " ", + 'originalCpm': '0.43', + 'originalCurrency': 'USD', + 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', + 'responseTimestamp': 1589707615188, + 'requestTimestamp': 1589707613908, + 'bidder': 'luponmedia', + 'adUnitCode': 'div-gpt-ad-1533155193780-2', + 'timeToRespond': 1280, + 'pbLg': '0.00', + 'pbMg': '0.40', + 'pbHg': '0.43', + 'pbAg': '0.40', + 'pbDg': '0.43', + 'pbCg': '0.43', + 'size': '300x250', + 'adserverTargeting': { + 'hb_bidder': 'luponmedia', + 'hb_adid': '3b40e0da8968f5', + 'hb_pb': '0.43', + 'hb_size': '300x250', + 'hb_source': 'client', + 'hb_format': 'banner' + } + }; + + // what we expect after general auction + + let expectedAfterBidData = JSON.parse(atob('eyJwdWJsaXNoZXJfaWQiOjEyMywiYXVjdGlvbl9pZCI6ImM0ZjBjY2UwLTI2NGMtNDgzYS1iMmY0LThhYzIyNDhhODk2YiIsInJlZmVyZXIiOiJodHRwczovL3Rlc3QuY29tL2FydGljbGUvMTc2MDY3Iiwic2NyZWVuX3Jlc29sdXRpb24iOiIxNDQweDkwMCIsImRldmljZV90eXBlIjoiZGVza3RvcCIsImdlbyI6bnVsbCwiZXZlbnRzIjpbeyJ0eXBlIjoiVElNRU9VVCIsImJpZGRlcl9jb2RlIjoibHVwb25tZWRpYSIsImV2ZW50X3RpbWVzdGFtcCI6MTU4OTcwNzYxMzkwOCwiYmlkX2dwdF9jb2RlcyI6eyJkaXYtZ3B0LWFkLTE1MzMxNTUxOTM3ODAtMiI6W1szMDAsMjUwXV0sImRpdi1ncHQtYWQtMTUzMzE1NTE5Mzc4MC0zIjpbWzMwMCwyNTBdXX19XX0=')); + expectedAfterBidData['screen_resolution'] = window.screen.width + 'x' + window.screen.height; + expectedAfterBidData = btoa(JSON.stringify(expectedAfterBidData)); + + let expectedAfterBid = { + 'query': 'mutation {createEvent(input: {event: {eventData: "' + expectedAfterBidData + '"}}) {event {createTime } } }' + }; + + // what we expect after timeout + + let expectedAfterTimeoutData = JSON.parse(atob('eyJwdWJsaXNoZXJfaWQiOjEyMywiYXVjdGlvbl9pZCI6ImM0ZjBjY2UwLTI2NGMtNDgzYS1iMmY0LThhYzIyNDhhODk2YiIsInJlZmVyZXIiOiJodHRwczovL3Rlc3QuY29tL2FydGljbGUvMTc2MDY3Iiwic2NyZWVuX3Jlc29sdXRpb24iOiIxNDQweDkwMCIsImRldmljZV90eXBlIjoiZGVza3RvcCIsImdlbyI6bnVsbCwiZXZlbnRzIjpbeyJ0eXBlIjoiVElNRU9VVCIsImJpZGRlcl9jb2RlIjoibHVwb25tZWRpYSIsImV2ZW50X3RpbWVzdGFtcCI6MTU4OTcwNzYxMzkwOCwiYmlkX2dwdF9jb2RlcyI6eyJkaXYtZ3B0LWFkLTE1MzMxNTUxOTM3ODAtMiI6W1szMDAsMjUwXV0sImRpdi1ncHQtYWQtMTUzMzE1NTE5Mzc4MC0zIjpbWzMwMCwyNTBdXX19XX0=')); + expectedAfterTimeoutData['screen_resolution'] = window.screen.width + 'x' + window.screen.height; + expectedAfterTimeoutData = btoa(JSON.stringify(expectedAfterTimeoutData)); + + let expectedAfterTimeout = { + 'query': 'mutation {createEvent(input: {event: {eventData: "' + expectedAfterTimeoutData + '"}}) {event {createTime } } }' + }; + + // lets simulate that some bidders timeout + let bidTimeoutArgsV1 = [ + { + 'bidId': '284f8e1469246b', + 'bidder': 'luponmedia', + 'adUnitCode': 'div-gpt-ad-1533155193780-3', + 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b' + } + ]; + + // now simulate some WIN and RENDERING + let wonRequest = { + 'bidderCode': 'luponmedia', + 'width': 300, + 'height': 250, + 'statusMessage': 'Bid available', + 'adId': '3b40e0da8968f5', + 'requestId': '284f8e1469246a', + 'mediaType': 'banner', + 'source': 'client', + 'cpm': 0.43, + 'creativeId': '443801010', + 'currency': 'USD', + 'netRevenue': false, + 'ttl': 300, + 'referrer': '', + 'ad': " ", + 'originalCpm': '0.43', + 'originalCurrency': 'USD', + 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', + 'responseTimestamp': 1589707615188, + 'requestTimestamp': 1589707613908, + 'bidder': 'luponmedia', + 'adUnitCode': 'div-gpt-ad-1533155193780-2', + 'timeToRespond': 1280, + 'pbLg': '0.00', + 'pbMg': '0.40', + 'pbHg': '0.43', + 'pbAg': '0.40', + 'pbDg': '0.43', + 'pbCg': '0.43', + 'size': '300x250', + 'adserverTargeting': { + 'hb_bidder': 'luponmedia', + 'hb_adid': '3b40e0da8968f5', + 'hb_pb': '0.43', + 'hb_size': '300x250', + 'hb_source': 'client', + 'hb_format': 'banner' + }, + 'status': 'rendered', + 'params': [ + { + 'siteId': 303522, + 'keyId': '4o2c4' + } + ] + }; + + let wonExpectData = JSON.parse(atob('eyJwdWJsaXNoZXJfaWQiOjEyMywiYXVjdGlvbl9pZCI6ImM0ZjBjY2UwLTI2NGMtNDgzYS1iMmY0LThhYzIyNDhhODk2YiIsInJlZmVyZXIiOiJodHRwczovL3Rlc3QuY29tL2FydGljbGUvMTc2MDY3Iiwic2NyZWVuX3Jlc29sdXRpb24iOiIxNDQweDkwMCIsImRldmljZV90eXBlIjoiZGVza3RvcCIsImdlbyI6bnVsbCwiZXZlbnRzIjpbeyJ0eXBlIjoiVElNRU9VVCIsImJpZGRlcl9jb2RlIjoibHVwb25tZWRpYSIsImV2ZW50X3RpbWVzdGFtcCI6MTU4OTcwNzYxMzkwOCwiYmlkX2dwdF9jb2RlcyI6eyJkaXYtZ3B0LWFkLTE1MzMxNTUxOTM3ODAtMiI6W1szMDAsMjUwXV0sImRpdi1ncHQtYWQtMTUzMzE1NTE5Mzc4MC0zIjpbWzMwMCwyNTBdXX19LHsidHlwZSI6IlJFU1BPTlNFIiwiYmlkZGVyX2NvZGUiOiJsdXBvbm1lZGlhIiwiZXZlbnRfdGltZXN0YW1wIjoxNTg5NzA3NjE1MTg4LCJzaXplIjoiMzAweDI1MCIsImdwdF9jb2RlIjoiZGl2LWdwdC1hZC0xNTMzMTU1MTkzNzgwLTIiLCJjdXJyZW5jeSI6IlVTRCIsImNyZWF0aXZlX2lkIjoiNDQzODAxMDEwIiwidGltZV90b19yZXNwb25kIjoxMjgwLCJjcG0iOjAuNDMsImlzX3dpbm5pbmciOmZhbHNlfV19')); + wonExpectData['screen_resolution'] = window.screen.width + 'x' + window.screen.height; + wonExpectData = btoa(JSON.stringify(wonExpectData)); + + let wonExpect = { + 'query': 'mutation {createEvent(input: {event: {eventData: "' + wonExpectData + '"}}) {event {createTime } } }' + }; + + adapterManager.registerAnalyticsAdapter({ + code: 'adxpremium', + adapter: adxpremiumAnalyticsAdapter + }); + + beforeEach(function () { + adapterManager.enableAnalytics({ + provider: 'adxpremium', + options: initOptions + }); + }); + + afterEach(function () { + adxpremiumAnalyticsAdapter.disableAnalytics(); + }); + + it('builds and sends auction data', function () { + // Step 1: Send auction init event + events.emit(constants.EVENTS.AUCTION_INIT, auctionInit); + + // Step 2: Send bid requested event + events.emit(constants.EVENTS.BID_REQUESTED, bidRequest); + + // Step 3: Send bid response event + events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); + + // Step 4: Send bid time out event + events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeoutArgsV1); + + // Step 5: Send auction end event + events.emit(constants.EVENTS.AUCTION_END, {}); + + testSend(); + + expect(server.requests.length).to.equal(2); + + let realAfterBid = JSON.parse(server.requests[0].requestBody); + + expect(realAfterBid).to.deep.equal(expectedAfterBid); + + // expect after timeout + expect(realAfterBid).to.deep.equal(expectedAfterTimeout); + + // Step 6: Send auction bid won event + events.emit(constants.EVENTS.BID_WON, wonRequest); + + expect(server.requests.length).to.equal(3); + let winEventData = JSON.parse(server.requests[1].requestBody); + + expect(winEventData).to.deep.equal(wonExpect); + }); + }); +}); From 5bc1ac45aa4d9f614d8c804bc546a797d19e6414 Mon Sep 17 00:00:00 2001 From: onlsol <48312668+onlsol@users.noreply.github.com> Date: Wed, 3 Jun 2020 09:18:02 +0200 Subject: [PATCH 377/496] Update Dspx adapter (#5277) * Add gdpr_consent support for Dspx Adapter * Add video support for dspx adapter * Update Video Test Parameters for Dspx Adapter * fix referrer in DSPX adapter * Fix Description in DSPX adapter Co-authored-by: Alexander --- modules/dspxBidAdapter.js | 86 +++++++++--- modules/dspxBidAdapter.md | 65 ++++----- test/spec/modules/dspxBidAdapter_spec.js | 163 ++++++++++++++++++++--- 3 files changed, 244 insertions(+), 70 deletions(-) diff --git a/modules/dspxBidAdapter.js b/modules/dspxBidAdapter.js index 16764e76ede..d05549601e1 100644 --- a/modules/dspxBidAdapter.js +++ b/modules/dspxBidAdapter.js @@ -1,45 +1,82 @@ import * as utils from '../src/utils.js'; import {config} from '../src/config.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'dspx'; const ENDPOINT_URL = 'https://buyer.dspx.tv/request/'; const ENDPOINT_URL_DEV = 'https://dcbuyer.dspx.tv/request/'; +const DEFAULT_VAST_FORMAT = 'vast2'; export const spec = { code: BIDDER_CODE, aliases: ['dspx'], + supportedMediaTypes: [BANNER, VIDEO], isBidRequestValid: function(bid) { return !!(bid.params.placement); }, buildRequests: function(validBidRequests, bidderRequest) { return validBidRequests.map(bidRequest => { const params = bidRequest.params; + + const videoData = utils.deepAccess(bidRequest, 'mediaTypes.video') || {}; + const sizes = utils.parseSizesInput(videoData.playerSize || bidRequest.sizes)[0]; + const [width, height] = sizes.split('x'); + const placementId = params.placement; const rnd = Math.floor(Math.random() * 99999999999); - const referrer = encodeURIComponent(bidderRequest.refererInfo.referer); + const referrer = bidderRequest.refererInfo.referer; const bidId = bidRequest.bidId; const isDev = params.devMode || false; - let bannerSizes = utils.parseSizesInput(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes); - let [width, height] = bannerSizes[0].split('x'); - let endpoint = isDev ? ENDPOINT_URL_DEV : ENDPOINT_URL; + let payload = {}; + + if (isVideoRequest(bidRequest)) { + let vastFormat = params.vastFormat || DEFAULT_VAST_FORMAT; + payload = { + _f: vastFormat, + alternative: 'prebid_js', + inventory_item_id: placementId, + srw: width, + srh: height, + idt: 100, + rnd: rnd, + ref: referrer, + bid_id: bidId, + }; + } else { + payload = { + _f: 'html', + alternative: 'prebid_js', + inventory_item_id: placementId, + srw: width, + srh: height, + idt: 100, + rnd: rnd, + ref: referrer, + bid_id: bidId, + }; + } - const payload = { - _f: 'html', - alternative: 'prebid_js', - inventory_item_id: placementId, - srw: width, - srh: height, - idt: 100, - rnd: rnd, - ref: referrer, - bid_id: bidId, - }; if (params.pfilter !== undefined) { payload.pfilter = params.pfilter; } + + if (bidderRequest && bidderRequest.gdprConsent) { + if (payload.pfilter !== undefined) { + if (!payload.pfilter.gdpr_consent) { + payload.pfilter.gdpr_consent = bidderRequest.gdprConsent.consentString; + payload.pfilter.gdpr = bidderRequest.gdprConsent.gdprApplies; + } + } else { + payload.pfilter = { + 'gdpr_consent': bidderRequest.gdprConsent.consentString, + 'gdpr': bidderRequest.gdprConsent.gdprApplies + }; + } + } + if (params.bcat !== undefined) { payload.bcat = params.bcat; } @@ -75,9 +112,14 @@ export const spec = { currency: currency, netRevenue: netRevenue, type: response.type, - ttl: config.getConfig('_bidderTimeout'), - ad: response.adTag + ttl: config.getConfig('_bidderTimeout') }; + if (response.vastXml) { + bidResponse.vastXml = response.vastXml; + bidResponse.mediaType = 'video'; + } else { + bidResponse.ad = response.adTag; + } bidResponses.push(bidResponse); } return bidResponses; @@ -99,4 +141,14 @@ function objectToQueryString(obj, prefix) { return str.join('&'); } +/** + * Check if it's a video bid request + * + * @param {BidRequest} bid - Bid request generated from ad slots + * @returns {boolean} True if it's a video bid + */ +function isVideoRequest(bid) { + return bid.mediaType === 'video' || !!utils.deepAccess(bid, 'mediaTypes.video'); +} + registerBidder(spec); diff --git a/modules/dspxBidAdapter.md b/modules/dspxBidAdapter.md index 9945dc5e6dd..8733aff698c 100644 --- a/modules/dspxBidAdapter.md +++ b/modules/dspxBidAdapter.md @@ -1,14 +1,14 @@ # Overview ``` -Module Name: Dspx Bidder Adapter +Module Name: DSPx Bidder Adapter Module Type: Bidder Adapter Maintainer: prebid@dspx.tv ``` # Description -Dspx adapter for Prebid.js 3.0 +DSPx adapter for Prebid. # Test Parameters ``` @@ -20,55 +20,46 @@ Dspx adapter for Prebid.js 3.0 sizes: [ [300, 250], [300, 600], - ], // a display size + ] } }, bids: [ { bidder: "dspx", params: { - placement: '101', - devMode: true, // if true: library uses dev server for tests - pfilter: { - floorprice: 1000000, // EUR * 1,000,000 - private_auction: 1, // Is private auction? 0 - no, 1 - yes - deals: [ - "666-9315-d58a7f9a-bdb9-4450-a3a2-046ba8ab2489;3;25000000;dspx-tv",// DEAL_ID;at;bidfloor;wseat1,wseat2;wadomain1,wadomain2" - "666-9315-d58a7f9a-bdb9-4450-a6a2-046ba8ab2489;3;25000000;dspx-tv",// DEAL_ID;at;bidfloor;wseat1,wseat2;wadomain1,wadomain2" - ], - geo: { // set client geo info manually (empty for auto detect) - lat: 52.52437, // Latitude from -90.0 to +90.0, where negative is south. - lon: 13.41053, // Longitude from -180.0 to +180.0, where negative is west - type: 1, // Source of location data: 1 - GPS/Location Services, 2 - IP Address, 3 - User provided (e.g. registration form) - country: 'DE', // Region of a country using FIPS 10-4 notation - region: 'DE-BE', // Region code using ISO-3166-2; 2-letter state code if USA. - regionfips104: 'GM', // Region of a country using FIPS 10-4 notation - city: 'BER', // City using United Nations Code for Trade and Transport Locations - zip: '10115' // Zip or postal code. - } + placement: '101', // [required] info available from your contact with DSPx team + /* + bcat: "IAB2,IAB4", // [optional] list of blocked advertiser categories (IAB), comma separated + */ + /* + pfilter: { // [optional] + // [optional] only required if a deal is negotiated + deals: [ // [optional] + "123-4567-d58a7f9a-..."// DEAL_ID from DSPx contact + ], + private_auction: 1 // [optional] 0 - no, 1 - yes + // usually managed on DSPx side + floorprice: 1000000 // input min_cpm_micros, CPM in EUR * 1000000 }, - bcat: "IAB2,IAB4", // List of Blocked Categories (IAB) - comma separated - dvt: "desktop|smartphone|tv|tablet" // DeVice Type (autodetect if not exists) + */ } } ] - },{ - code: 'test-div', + }, + { + code: 'video1', mediaTypes: { - banner: { - sizes: [[320, 50]], // a mobile size + video: { + playerSize: [640, 480], + context: 'instream' } }, - bids: [ - { - bidder: "dspx", - params: { - placement: 101 - } + bids: [{ + bidder: 'dspx', + params: { + placement: '106' } - ] + }] } ]; ``` - -Required param field is only `placement`. \ No newline at end of file diff --git a/test/spec/modules/dspxBidAdapter_spec.js b/test/spec/modules/dspxBidAdapter_spec.js index 2513a6174cd..cf36c3f62c4 100644 --- a/test/spec/modules/dspxBidAdapter_spec.js +++ b/test/spec/modules/dspxBidAdapter_spec.js @@ -59,8 +59,8 @@ describe('dspxAdapter', function () { 'sizes': [ [300, 250] ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', + 'bidId': '30b31c1838de1e1', + 'bidderRequestId': '22edbae2733bf61', 'auctionId': '1d1a030790a475' }, { @@ -72,32 +72,117 @@ describe('dspxAdapter', function () { 'sizes': [ [300, 250] ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' + 'bidId': '30b31c1838de1e2', + 'bidderRequestId': '22edbae2733bf62', + 'auctionId': '1d1a030790a476' + }, { + 'bidder': 'dspx', + 'params': { + 'placement': '6682', + 'pfilter': { + 'floorprice': 1000000, + 'private_auction': 0, + 'geo': { + 'country': 'DE' + } + }, + 'bcat': 'IAB2,IAB4', + 'dvt': 'desktop' + }, + 'sizes': [ + [300, 250] + ], + 'bidId': '30b31c1838de1e3', + 'bidderRequestId': '22edbae2733bf69', + 'auctionId': '1d1a030790a477' + }, + { + 'bidder': 'dspx', + 'params': { + 'placement': '101', + 'devMode': true + }, + 'sizes': [ + [300, 250] + ], + 'bidId': '30b31c1838de1e4', + 'bidderRequestId': '22edbae2733bf67', + 'auctionId': '1d1a030790a478' + }, + { + 'bidder': 'dspx', + 'params': { + 'placement': '101', + 'devMode': true + }, + 'mediaTypes': { + 'video': { + 'playerSize': [640, 480], + 'context': 'instream' + } + }, + 'bidId': '30b31c1838de1e41', + 'bidderRequestId': '22edbae2733bf67', + 'auctionId': '1d1a030790a478' } ]; - let bidderRequest = { + // With gdprConsent + var bidderRequest = { refererInfo: { referer: 'some_referrer.net' + }, + gdprConsent: { + consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', + vendorData: {someData: 'value'}, + gdprApplies: true } - } + }; - const request = spec.buildRequests(bidRequests, bidderRequest); + var request1 = spec.buildRequests([bidRequests[0]], bidderRequest)[0]; it('sends bid request to our endpoint via GET', function () { - expect(request[0].method).to.equal('GET'); - expect(request[0].url).to.equal(ENDPOINT_URL); - let data = request[0].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=6682&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bprivate_auction%5D=0&pfilter%5Bgeo%5D%5Bcountry%5D=DE&bcat=IAB2%2CIAB4&dvt=desktop'); + expect(request1.method).to.equal('GET'); + expect(request1.url).to.equal(ENDPOINT_URL); + let data = request1.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); + expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=6682&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e1&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bprivate_auction%5D=0&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop'); }); + var request2 = spec.buildRequests([bidRequests[1]], bidderRequest)[0]; it('sends bid request to our DEV endpoint via GET', function () { - expect(request[1].method).to.equal('GET'); - expect(request[1].url).to.equal(ENDPOINT_URL_DEV); - let data = request[1].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=101&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e&prebidDevMode=1'); + expect(request2.method).to.equal('GET'); + expect(request2.url).to.equal(ENDPOINT_URL_DEV); + let data = request2.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); + expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=101&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e2&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&prebidDevMode=1'); + }); + + // Without gdprConsent + var bidderRequestWithoutGdpr = { + refererInfo: { + referer: 'some_referrer.net' + } + }; + var request3 = spec.buildRequests([bidRequests[2]], bidderRequestWithoutGdpr)[0]; + it('sends bid request without gdprConsent to our endpoint via GET', function () { + expect(request3.method).to.equal('GET'); + expect(request3.url).to.equal(ENDPOINT_URL); + let data = request3.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); + expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=6682&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e3&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bprivate_auction%5D=0&pfilter%5Bgeo%5D%5Bcountry%5D=DE&bcat=IAB2%2CIAB4&dvt=desktop'); + }); + + var request4 = spec.buildRequests([bidRequests[3]], bidderRequestWithoutGdpr)[0]; + it('sends bid request without gdprConsent to our DEV endpoint via GET', function () { + expect(request4.method).to.equal('GET'); + expect(request4.url).to.equal(ENDPOINT_URL_DEV); + let data = request4.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); + expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=101&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e4&prebidDevMode=1'); + }); + + var request5 = spec.buildRequests([bidRequests[4]], bidderRequestWithoutGdpr)[0]; + it('sends bid video request to our rads endpoint via GET', function () { + expect(request5.method).to.equal('GET'); + let data = request5.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); + expect(data).to.equal('_f=vast2&alternative=prebid_js&inventory_item_id=101&srw=640&srh=480&idt=100&bid_id=30b31c1838de1e41&prebidDevMode=1'); }); }); @@ -117,6 +202,21 @@ describe('dspxAdapter', function () { 'zone': '6682' } }; + let serverVideoResponse = { + 'body': { + 'cpm': 5000000, + 'crid': 100500, + 'width': '300', + 'height': '250', + 'vastXml': '{"reason":7001,"status":"accepted"}', + 'requestId': '220ed41385952a', + 'type': 'vast2', + 'currency': 'EUR', + 'ttl': 60, + 'netRevenue': true, + 'zone': '6682' + } + }; let expectedResponse = [{ requestId: '23beaa6af6cdde', @@ -130,6 +230,19 @@ describe('dspxAdapter', function () { ttl: 300, type: 'sspHTML', ad: '' + }, { + requestId: '23beaa6af6cdde', + cpm: 0.5, + width: 0, + height: 0, + creativeId: 100500, + dealId: '', + currency: 'EUR', + netRevenue: true, + ttl: 300, + type: 'vast2', + vastXml: '{"reason":7001,"status":"accepted"}', + mediaType: 'video' }]; it('should get the correct bid response by display ad', function () { @@ -144,6 +257,24 @@ describe('dspxAdapter', function () { expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); + it('should get the correct dspx video bid response by display ad', function () { + let bidRequest = [{ + 'method': 'GET', + 'url': ENDPOINT_URL, + 'mediaTypes': { + 'video': { + 'playerSize': [640, 480], + 'context': 'instream' + } + }, + 'data': { + 'bid_id': '30b31c1838de1e' + } + }]; + let result = spec.interpretResponse(serverVideoResponse, bidRequest[0]); + expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[1])); + }); + it('handles empty bid response', function () { let response = { body: {} From c79700508051b02964d07cae6ea626e3f212f58c Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Wed, 3 Jun 2020 17:42:12 +0530 Subject: [PATCH 378/496] remove only keyword (#5324) --- test/spec/modules/adtargetBidAdapter_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/modules/adtargetBidAdapter_spec.js b/test/spec/modules/adtargetBidAdapter_spec.js index 5247dfb72e8..5a867e7dd52 100644 --- a/test/spec/modules/adtargetBidAdapter_spec.js +++ b/test/spec/modules/adtargetBidAdapter_spec.js @@ -123,7 +123,7 @@ const displayEqResponse = [{ cpm: 0.9 }]; -describe.only('adtargetBidAdapter', () => { +describe('adtargetBidAdapter', () => { const adapter = newBidder(spec); describe('inherited functions', () => { it('exists and is a function', () => { From e4e6e4a3f838633192b9ea2174d1f51659654a59 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Wed, 3 Jun 2020 05:42:26 -0700 Subject: [PATCH 379/496] PubMatic analytics documentation (#5322) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * simple example * added limitations * added contact details * example text --- modules/pubmaticAnalyticsAdapter.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 modules/pubmaticAnalyticsAdapter.md diff --git a/modules/pubmaticAnalyticsAdapter.md b/modules/pubmaticAnalyticsAdapter.md new file mode 100644 index 00000000000..9685f758ea2 --- /dev/null +++ b/modules/pubmaticAnalyticsAdapter.md @@ -0,0 +1,24 @@ +# PubMatic Analytics Adapter + +``` +Module Name: PubMatic Analytics Adapter +Module Type: Analytics Adapter +Maintainer: header-bidding@pubmatic.com +``` + +## How to configure? +``` +pbjs.enableAnalytics({ + provider: 'pubmatic', + options: { + "publisherId": 12345 // please contact PubMatic to get a publisherId for yourself + } +}); +``` + +## Limitations: +- Supports only Banner and Video media-type +- Does not supports Native media type +- Does not supports instream-video creative-render tracker +- BidCpmAdjustment: Bid CPM only after BidCpmAdjustment is logged +- If a currency module is NOT included and a bidder responds in a non-USD currency then PubMatic analytics bidder will not be able to log the bid CPM \ No newline at end of file From 1c744a4be11dce76cb704b9c65f52b2f2de014c1 Mon Sep 17 00:00:00 2001 From: harpere Date: Wed, 3 Jun 2020 08:55:02 -0400 Subject: [PATCH 380/496] Secure creative update (#5285) * replaced manually set secureCreative adServerDomain with automatic postMessage event.source.orgin * using event.origin rather than event.source.origin in secureCreative postMessage() * updated x-domain iframe render example Co-authored-by: Eric Harper --- integrationExamples/gpt/x-domain/creative.html | 4 +--- src/secureCreatives.js | 8 ++++---- test/spec/unit/pbjs_api_spec.js | 8 ++++---- test/spec/unit/secureCreatives_spec.js | 12 ++++++------ 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/integrationExamples/gpt/x-domain/creative.html b/integrationExamples/gpt/x-domain/creative.html index a6981706227..fce46bb380f 100644 --- a/integrationExamples/gpt/x-domain/creative.html +++ b/integrationExamples/gpt/x-domain/creative.html @@ -6,7 +6,6 @@ var urlParser = document.createElement('a'); urlParser.href = '%%PATTERN:url%%'; var publisherDomain = urlParser.protocol + '//' + urlParser.hostname; -var adServerDomain = windowLocation.protocol + '//tpc.googlesyndication.com'; function renderAd(ev) { var key = ev.message ? 'message' : 'data'; @@ -58,8 +57,7 @@ function requestAdFromPrebid() { var message = JSON.stringify({ message: 'Prebid Request', - adId: '%%PATTERN:hb_adid%%', - adServerDomain: adServerDomain + adId: '%%PATTERN:hb_adid%%' }); window.parent.postMessage(message, publisherDomain); } diff --git a/src/secureCreatives.js b/src/secureCreatives.js index 060a30b0a98..34de2be275c 100644 --- a/src/secureCreatives.js +++ b/src/secureCreatives.js @@ -33,7 +33,7 @@ function receiveMessage(ev) { }); if (adObject && data.message === 'Prebid Request') { - _sendAdToCreative(adObject, data.adServerDomain, ev.source); + _sendAdToCreative(adObject, ev); // save winning bids auctionManager.addWinningBid(adObject); @@ -62,21 +62,21 @@ function receiveMessage(ev) { } } -export function _sendAdToCreative(adObject, remoteDomain, source) { +export function _sendAdToCreative(adObject, ev) { const { adId, ad, adUrl, width, height, renderer, cpm } = adObject; // rendering for outstream safeframe if (isRendererRequired(renderer)) { executeRenderer(renderer, adObject); } else if (adId) { resizeRemoteCreative(adObject); - source.postMessage(JSON.stringify({ + ev.source.postMessage(JSON.stringify({ message: 'Prebid Response', ad: replaceAuctionPrice(ad, cpm), adUrl: replaceAuctionPrice(adUrl, cpm), adId, width, height - }), remoteDomain); + }), ev.origin); } } diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index 7b4061850cb..8a142d7a6aa 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -959,12 +959,12 @@ describe('Unit: Prebid Module', function () { adUnitCode: config.adUnitCodes[0], }; - const remoteDomain = '*'; - const source = { - postMessage: sinon.stub() + const event = { + source: { postMessage: sinon.stub() }, + origin: 'origin.sf.com' }; - _sendAdToCreative(mockAdObject, remoteDomain, source); + _sendAdToCreative(mockAdObject, event); expect(slots[0].spyGetSlotElementId.called).to.equal(false); expect(slots[1].spyGetSlotElementId.called).to.equal(true); diff --git a/test/spec/unit/secureCreatives_spec.js b/test/spec/unit/secureCreatives_spec.js index 97dfa119193..566154f0003 100644 --- a/test/spec/unit/secureCreatives_spec.js +++ b/test/spec/unit/secureCreatives_spec.js @@ -30,14 +30,14 @@ describe('secureCreatives', () => { cpm: '1.00', adUnitCode: 'some_dom_id' }; - const remoteDomain = '*'; - const source = { - postMessage: sinon.stub() + const event = { + source: { postMessage: sinon.stub() }, + origin: 'origin.sf.com' }; - _sendAdToCreative(mockAdObject, remoteDomain, source); - expect(JSON.parse(source.postMessage.args[0][0]).ad).to.equal(''); - expect(JSON.parse(source.postMessage.args[0][0]).adUrl).to.equal('http://creative.prebid.org/1.00'); + _sendAdToCreative(mockAdObject, event); + expect(JSON.parse(event.source.postMessage.args[0][0]).ad).to.equal(''); + expect(JSON.parse(event.source.postMessage.args[0][0]).adUrl).to.equal('http://creative.prebid.org/1.00'); window.googletag = oldVal; window.apntag = oldapntag; }); From 7362b693db3e7cd17c5147f928fbe5a80cec6533 Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Wed, 3 Jun 2020 14:36:30 -0400 Subject: [PATCH 381/496] update webdriverio and node 12 support (#5236) * update webdriverio and node 12 support * clean-up some commented code * updates to supported node version and other minor updates and wording * fix lint error * add description files for fixtures --- .circleci/config.yml | 2 +- .nvmrc | 2 +- README.md | 2 +- gulpfile.js | 47 +- .../longform/basic_w_bidderSettings.html | 7 +- .../basic_w_custom_adserver_translation.html | 7 +- .../longform/basic_w_priceGran.html | 7 +- .../basic_w_requireExactDuration.html | 7 +- .../basic_wo_brandCategoryExclusion.html | 7 +- .../basic_wo_requireExactDuration.html | 7 +- .../longform/longformTestUtils.js | 1256 + karma.conf.maker.js | 2 +- package-lock.json | 22442 ++++++++++------ package.json | 17 +- test/fake-server/README.md | 28 + test/fake-server/fake-responder.js | 75 + .../fixtures/basic-banner/description.md | 34 + .../fixtures/basic-banner/request.json | 61 + .../fixtures/basic-banner/response.json | 92 + .../fixtures/basic-instream/description.md | 28 + .../fixtures/basic-instream/request.json | 34 + .../fixtures/basic-instream/response.json | 42 + .../fixtures/basic-native/description.md | 62 + .../fixtures/basic-native/request.json | 81 + .../fixtures/basic-native/response.json | 116 + .../fixtures/basic-outstream/description.md | 44 + .../fixtures/basic-outstream/request.json | 50 + .../fixtures/basic-outstream/response.json | 105 + test/fake-server/fixtures/index.js | 41 + .../longform_biddersettings_1/description.md | 41 + .../longform_biddersettings_1/request.json | 387 + .../longform_biddersettings_1/response.json | 114 + .../longform_biddersettings_2/description.md | 28 + .../longform_biddersettings_2/request.json | 137 + .../longform_biddersettings_2/response.json | 188 + .../description.md | 43 + .../request.json | 402 + .../response.json | 294 + .../description.md | 43 + .../request.json | 142 + .../response.json | 188 + .../longform_priceGran_1/description.md | 62 + .../longform_priceGran_1/request.json | 387 + .../longform_priceGran_1/response.json | 366 + .../longform_priceGran_2/description.md | 62 + .../longform_priceGran_2/request.json | 137 + .../longform_priceGran_2/response.json | 188 + .../description.md | 40 + .../request.json | 401 + .../response.json | 330 + .../description.md | 40 + .../request.json | 141 + .../response.json | 188 + .../description.md | 40 + .../request.json | 386 + .../response.json | 654 + .../description.md | 40 + .../request.json | 136 + .../response.json | 224 + .../description.md | 40 + .../request.json | 387 + .../response.json | 366 + .../description.md | 40 + .../request.json | 137 + .../response.json | 224 + .../fixtures/modules/description.md | 68 + .../fake-server/fixtures/modules/request.json | 74 + .../fixtures/modules/response.json | 106 + .../multi-bidder-adasta/description.md | 43 + .../multi-bidder-adasta/request.json | 43 + .../multi-bidder-adasta/response.json | 59 + .../multi-bidder-appnexus/description.md | 43 + .../multi-bidder-appnexus/request.json | 36 + .../multi-bidder-appnexus/response.json | 49 + test/fake-server/index.js | 37 + test/helpers/testing-utils.js | 11 +- .../request-response-pairs/banner/index.js | 97 - .../request-response-pairs/currency/index.js | 177 - .../request-response-pairs/gdpr/index.js | 95 - .../request-response-pairs/instream/index.js | 95 - .../ad_server_translation_request_1.js | 577 - .../ad_server_translation_request_2.js | 289 - .../basic_w_requireExactDuration_request_1.js | 606 - .../basic_w_requireExactDuration_request_2.js | 288 - ...sic_wo_brandCategoryExclusion_request_1.js | 852 - ...sic_wo_brandCategoryExclusion_request_2.js | 312 - ...basic_wo_requireExactDuration_request_1.js | 620 - ...basic_wo_requireExactDuration_request_2.js | 312 - .../longform/bidder_settings_request_1.js | 418 - .../longform/bidder_settings_request_2.js | 284 - .../longform/price_gran_request_1.js | 620 - .../longform/price_gran_request_2.js | 283 - .../multiple-bidders/index-1.js | 111 - .../multiple-bidders/index-2.js | 177 - .../request-response-pairs/native/index.js | 193 - .../request-response-pairs/outstream/index.js | 164 - test/mock-server/index.js | 37 - .../request-middlewares/prebid-request.js | 75 - test/pages/banner.html | 42 +- test/pages/bidderSettings.html | 214 +- test/pages/consent_mgt_gdpr.html | 388 +- test/pages/currency.html | 2 +- test/pages/instream.html | 45 +- test/pages/multiple_bidders.html | 274 +- test/pages/native.html | 12 +- test/pages/outstream.html | 9 +- test/pages/priceGranularity.html | 228 +- test/pages/sizeConfig.html | 250 +- test/pages/userSync.html | 208 +- test/spec/e2e/banner/basic_banner_ad.spec.js | 51 +- .../instream/basic_instream_video_ad.spec.js | 40 +- .../longform/basic_w_bidderSettings.spec.js | 23 +- ...asic_w_custom_adserver_translation.spec.js | 23 +- .../e2e/longform/basic_w_priceGran.spec.js | 23 +- .../basic_w_requireExactDuration.spec.js | 23 +- .../basic_wo_brandCategoryExclusion.spec.js | 23 +- .../basic_wo_requireExactDuration.spec.js | 23 +- .../e2e/modules/e2e_bidderSettings.spec.js | 18 +- .../e2e/modules/e2e_consent_mgt_gdpr.spec.js | 18 +- test/spec/e2e/modules/e2e_currency.spec.js | 22 +- .../e2e/modules/e2e_priceGranularity.spec.js | 18 +- test/spec/e2e/modules/e2e_sizeConfig.spec.js | 18 +- test/spec/e2e/modules/e2e_userSync.spec.js | 18 +- .../multi-bidder/e2e_multiple_bidders.spec.js | 67 + .../multi-format/e2e_multiple_bidders.spec.js | 68 - test/spec/e2e/native/basic_native_ad.spec.js | 18 +- .../basic_outstream_video_ad.spec.js | 26 +- wdio.conf.js | 68 +- 128 files changed, 25062 insertions(+), 16177 deletions(-) create mode 100644 test/fake-server/README.md create mode 100644 test/fake-server/fake-responder.js create mode 100644 test/fake-server/fixtures/basic-banner/description.md create mode 100644 test/fake-server/fixtures/basic-banner/request.json create mode 100644 test/fake-server/fixtures/basic-banner/response.json create mode 100644 test/fake-server/fixtures/basic-instream/description.md create mode 100644 test/fake-server/fixtures/basic-instream/request.json create mode 100644 test/fake-server/fixtures/basic-instream/response.json create mode 100644 test/fake-server/fixtures/basic-native/description.md create mode 100644 test/fake-server/fixtures/basic-native/request.json create mode 100644 test/fake-server/fixtures/basic-native/response.json create mode 100644 test/fake-server/fixtures/basic-outstream/description.md create mode 100644 test/fake-server/fixtures/basic-outstream/request.json create mode 100644 test/fake-server/fixtures/basic-outstream/response.json create mode 100644 test/fake-server/fixtures/index.js create mode 100644 test/fake-server/fixtures/longform/longform_biddersettings_1/description.md create mode 100644 test/fake-server/fixtures/longform/longform_biddersettings_1/request.json create mode 100644 test/fake-server/fixtures/longform/longform_biddersettings_1/response.json create mode 100644 test/fake-server/fixtures/longform/longform_biddersettings_2/description.md create mode 100644 test/fake-server/fixtures/longform/longform_biddersettings_2/request.json create mode 100644 test/fake-server/fixtures/longform/longform_biddersettings_2/response.json create mode 100644 test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/description.md create mode 100644 test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/request.json create mode 100644 test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/response.json create mode 100644 test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/description.md create mode 100644 test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/request.json create mode 100644 test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/response.json create mode 100644 test/fake-server/fixtures/longform/longform_priceGran_1/description.md create mode 100644 test/fake-server/fixtures/longform/longform_priceGran_1/request.json create mode 100644 test/fake-server/fixtures/longform/longform_priceGran_1/response.json create mode 100644 test/fake-server/fixtures/longform/longform_priceGran_2/description.md create mode 100644 test/fake-server/fixtures/longform/longform_priceGran_2/request.json create mode 100644 test/fake-server/fixtures/longform/longform_priceGran_2/response.json create mode 100644 test/fake-server/fixtures/longform/longform_requireExactDuration_1/description.md create mode 100644 test/fake-server/fixtures/longform/longform_requireExactDuration_1/request.json create mode 100644 test/fake-server/fixtures/longform/longform_requireExactDuration_1/response.json create mode 100644 test/fake-server/fixtures/longform/longform_requireExactDuration_2/description.md create mode 100644 test/fake-server/fixtures/longform/longform_requireExactDuration_2/request.json create mode 100644 test/fake-server/fixtures/longform/longform_requireExactDuration_2/response.json create mode 100644 test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/description.md create mode 100644 test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/request.json create mode 100644 test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/response.json create mode 100644 test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/description.md create mode 100644 test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/request.json create mode 100644 test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/response.json create mode 100644 test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/description.md create mode 100644 test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/request.json create mode 100644 test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/response.json create mode 100644 test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/description.md create mode 100644 test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/request.json create mode 100644 test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/response.json create mode 100644 test/fake-server/fixtures/modules/description.md create mode 100644 test/fake-server/fixtures/modules/request.json create mode 100644 test/fake-server/fixtures/modules/response.json create mode 100644 test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/description.md create mode 100644 test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/request.json create mode 100644 test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/response.json create mode 100644 test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/description.md create mode 100644 test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/request.json create mode 100644 test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/response.json create mode 100644 test/fake-server/index.js delete mode 100644 test/mock-server/expectations/request-response-pairs/banner/index.js delete mode 100644 test/mock-server/expectations/request-response-pairs/currency/index.js delete mode 100644 test/mock-server/expectations/request-response-pairs/gdpr/index.js delete mode 100644 test/mock-server/expectations/request-response-pairs/instream/index.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_1.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_2.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_1.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_2.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_1.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_2.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_1.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_2.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_1.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_2.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/price_gran_request_1.js delete mode 100644 test/mock-server/expectations/request-response-pairs/longform/price_gran_request_2.js delete mode 100644 test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js delete mode 100644 test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js delete mode 100644 test/mock-server/expectations/request-response-pairs/native/index.js delete mode 100644 test/mock-server/expectations/request-response-pairs/outstream/index.js delete mode 100644 test/mock-server/index.js delete mode 100644 test/mock-server/request-middlewares/prebid-request.js create mode 100644 test/spec/e2e/multi-bidder/e2e_multiple_bidders.spec.js delete mode 100644 test/spec/e2e/multi-format/e2e_multiple_bidders.spec.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 58e379dced2..5ea5e87218c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,7 +7,7 @@ aliases: - &environment docker: # specify the version you desire here - - image: circleci/node:8.9.0 + - image: circleci/node:12.16.1 # Specify service dependencies here if necessary # CircleCI maintains a library of pre-built images diff --git a/.nvmrc b/.nvmrc index fa97ecedc28..66df3b7ab2d 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -8.9 +12.16.1 diff --git a/README.md b/README.md index 0e07521ac3b..0dd5b25a50f 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ prebid.requestBids({ $ cd Prebid.js $ npm install -*Note:* You need to have `NodeJS` 8.9.x or greater installed. +*Note:* You need to have `NodeJS` 12.16.1 or greater installed. *Note:* In the 1.24.0 release of Prebid.js we have transitioned to using gulp 4.0 from using gulp 3.9.1. To comply with gulp's recommended setup for 4.0, you'll need to have `gulp-cli` installed globally prior to running the general `npm install`. This shouldn't impact any other projects you may work on that use an earlier version of gulp in its setup. diff --git a/gulpfile.js b/gulpfile.js index 1b5cd85abd6..58e294bc559 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ 'use strict'; var _ = require('lodash'); @@ -32,8 +33,8 @@ var prebid = require('./package.json'); var dateString = 'Updated : ' + (new Date()).toISOString().substring(0, 10); var banner = '/* <%= prebid.name %> v<%= prebid.version %>\n' + dateString + ' */\n'; var port = 9999; -const mockServerPort = 4444; -const host = argv.host ? argv.host : 'localhost'; +const FAKE_SERVER_HOST = argv.host ? argv.host : 'localhost'; +const FAKE_SERVER_PORT = 4444; const { spawn } = require('child_process'); // these modules must be explicitly listed in --modules to be included in the build, won't be part of "all" modules @@ -238,25 +239,25 @@ function test(done) { ]; } - //run mock-server - const mockServer = spawn('node', ['./test/mock-server/index.js', '--port=' + mockServerPort]); - mockServer.stdout.on('data', (data) => { + // run fake-server + const fakeServer = spawn('node', ['./test/fake-server/index.js', `--port=${FAKE_SERVER_PORT}`]); + fakeServer.stdout.on('data', (data) => { console.log(`stdout: ${data}`); }); - mockServer.stderr.on('data', (data) => { + fakeServer.stderr.on('data', (data) => { console.log(`stderr: ${data}`); }); execa(wdioCmd, wdioOpts, { stdio: 'inherit' }) .then(stdout => { - // kill mock server - mockServer.kill('SIGINT'); + // kill fake server + fakeServer.kill('SIGINT'); done(); process.exit(0); }) .catch(err => { - // kill mock server - mockServer.kill('SIGINT'); + // kill fake server + fakeServer.kill('SIGINT'); done(new Error(`Tests failed with error: ${err}`)); process.exit(1); }); @@ -326,11 +327,27 @@ function setupE2e(done) { done(); } -gulp.task('updatepath', function () { +function injectFakeServerEndpoint() { return gulp.src(['build/dist/*.js']) - .pipe(replace('https://ib.adnxs.com/ut/v3/prebid', 'http://' + host + ':' + mockServerPort + '/')) + .pipe(replace('https://ib.adnxs.com/ut/v3/prebid', `http://${FAKE_SERVER_HOST}:${FAKE_SERVER_PORT}`)) .pipe(gulp.dest('build/dist')); -}); +} + +function injectFakeServerEndpointDev() { + return gulp.src(['build/dev/*.js']) + .pipe(replace('https://ib.adnxs.com/ut/v3/prebid', `http://${FAKE_SERVER_HOST}:${FAKE_SERVER_PORT}`)) + .pipe(gulp.dest('build/dev')); +} + +function startFakeServer() { + const fakeServer = spawn('node', ['./test/fake-server/index.js', `--port=${FAKE_SERVER_PORT}`]); + fakeServer.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + fakeServer.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + }); +} // support tasks gulp.task(lint); @@ -355,9 +372,11 @@ gulp.task('build', gulp.series(clean, 'build-bundle-prod')); gulp.task('build-postbid', gulp.series(escapePostbidConfig, buildPostbid)); gulp.task('serve', gulp.series(clean, lint, gulp.parallel('build-bundle-dev', watch, test))); +gulp.task('serve-fake', gulp.series(clean, gulp.parallel('build-bundle-dev', watch), injectFakeServerEndpointDev, test, startFakeServer)); + gulp.task('default', gulp.series(clean, makeWebpackPkg)); -gulp.task('e2e-test', gulp.series(clean, setupE2e, gulp.parallel('build-bundle-prod', watch), 'updatepath', test)); +gulp.task('e2e-test', gulp.series(clean, setupE2e, gulp.parallel('build-bundle-prod', watch), injectFakeServerEndpoint, test)); // other tasks gulp.task(bundleToStdout); gulp.task('bundle', gulpBundle.bind(null, false)); // used for just concatenating pre-built files with no build step diff --git a/integrationExamples/longform/basic_w_bidderSettings.html b/integrationExamples/longform/basic_w_bidderSettings.html index f9389686b1f..fb87ea5d990 100644 --- a/integrationExamples/longform/basic_w_bidderSettings.html +++ b/integrationExamples/longform/basic_w_bidderSettings.html @@ -5,6 +5,10 @@ Prebid Freewheel Integration Demo + + + - + + - + + - + + - + @@ -20,10 +24,9 @@ integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> - + - + + -
", + "width": 300, + "height": 250 + }, + "trackers": [ + { + "impression_urls": [ + "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fhello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QK7CKA7BAAAAwDWAAUBCJKPpe4FEKjwl-js2byJcRiq5MnUovf28WEqNgkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJADERG6gwsqKiBjjtSEDtSEgCUNOBly5YnPFbYABotc95eJK4BYABAYoBA1VTRJIBAQbwUpgBrAKgAfoBqAEBsAEAuAEBwAEEyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTczNDcyMTQ2KTt1ZigncicsIDk2ODQ2MDM1Nh4A8PWSAqUCIXp6ZmhVQWl1c0s0S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlJSUNhQUJ3Q0hncWdBRWtpQUVxa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUVwaTRpREFBRGdQOEVCS1l1SWd3QUE0RF9KQVozRkl5WjA1Tm9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pOZUFEcUJXSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkEg0QkFDSUJmOGuaAokBIUl3OTBCOikBJG5QRmJJQVFvQUQROFhEZ1B6b0pVMGxPTXpvME56TTFRS2dWUxFoDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJTDTrYdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9oZWxsb193b3JsZAVO8EA_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAOsAsgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw248F6YBACiBAsxMC43NS43NC42OagEkECyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQB8ATTgZcuiAUBmAUAoAX______wEDFAHABQDJBWmIFPA_0gUJCQkMcAAA2AUB4AUB8AUB-gUECAAQAJAGAJgGALgGAMEGCSM08D_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgHyBgIIAIAHAYgHAKAHAQ..&s=951a029669a69e3f0c527c937c2d852be92802e1" + ], + "video_events": {} + } + ] + } + } + ] + }, + { + "tag_id": 13144370, + "auction_id": "8147841645883553832", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fhello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKzCKAzBAAAAwDWAAUBCJKPpe4FEKjwl-js2byJcRiq5MnUovf28WEqNgkAAAkCABEJBywAABkAAACA61HgPyEREgApEQkAMREb8GkwsqKiBjjtSEDtSEgAUABYnPFbYABotc95eACAAQGKAQCSAQNVU0SYAawCoAH6AagBAbABALgBAcABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3MzQ3MjE0Nik7AR0scicsIDk2ODQ2MDM1Nh4A8PWSAqUCIXp6ZmhVQWl1c0s0S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlJSUNhQUJ3Q0hncWdBRWtpQUVxa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUVwaTRpREFBRGdQOEVCS1l1SWd3QUE0RF9KQVozRkl5WjA1Tm9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pOZUFEcUJXSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkEg0QkFDSUJmOGuaAokBIUl3OTBCOikBJG5QRmJJQVFvQUQROFhEZ1B6b0pVMGxPTXpvME56TTFRS2dWUxFoDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJTDTrYdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9oZWxsb193b3JsZAVO8EA_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAOsAsgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw248F6YBACiBAsxMC43NS43NC42OagEkECyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8ATTgZcuiAUBmAUAoAX______wEDFAHABQDJBWmAFPA_0gUJCQkMcAAA2AUB4AUB8AUB-gUECAAQAJAGAJgGALgGAMEGCSM08L_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgHyBgIIAIAHAYgHAKAHAQ..&s=68cfb6ed042ea47f5d3fc2c32cc068500e542066", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "banner", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 968460356666, + "media_type_id": 1, + "media_subtype_id": 1, + "cpm": 0.5, + "cpm_publisher_currency": 0.5, + "is_bin_price_applied": false, + "publisher_currency_code": "$", + "brand_category_id": 0, + "client_initiated_ad_counting": true, + "rtb": { + "banner": { + "content": "
", + "width": 300, + "height": 250 + }, + "trackers": [ + { + "impression_urls": [ + "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fhello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QK7CKA7BAAAAwDWAAUBCJKPpe4FEKjwl-js2byJcRiq5MnUovf28WEqNgkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJADERG6gwsqKiBjjtSEDtSEgCUNOBly5YnPFbYABotc95eJK4BYABAYoBA1VTRJIBAQbwUpgBrAKgAfoBqAEBsAEAuAEBwAEEyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTczNDcyMTQ2KTt1ZigncicsIDk2ODQ2MDM1Nh4A8PWSAqUCIXp6ZmhVQWl1c0s0S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlJSUNhQUJ3Q0hncWdBRWtpQUVxa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUVwaTRpREFBRGdQOEVCS1l1SWd3QUE0RF9KQVozRkl5WjA1Tm9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pOZUFEcUJXSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkEg0QkFDSUJmOGuaAokBIUl3OTBCOikBJG5QRmJJQVFvQUQROFhEZ1B6b0pVMGxPTXpvME56TTFRS2dWUxFoDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJTDTrYdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9oZWxsb193b3JsZAVO8EA_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAOsAsgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw248F6YBACiBAsxMC43NS43NC42OagEkECyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQB8ATTgZcuiAUBmAUAoAX______wEDFAHABQDJBWmIFPA_0gUJCQkMcAAA2AUB4AUB8AUB-gUECAAQAJAGAJgGALgGAMEGCSM08D_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgHyBgIIAIAHAYgHAKAHAQ..&s=951a029669a69e3f0c527c937c2d852be92802e1" + ], + "video_events": {} + } + ] + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-instream/description.md b/test/fake-server/fixtures/basic-instream/description.md new file mode 100644 index 00000000000..5d185f23ad3 --- /dev/null +++ b/test/fake-server/fixtures/basic-instream/description.md @@ -0,0 +1,28 @@ +Test Page - 'test/pages/instream.html' +Test Spec File - 'test/spec/e2e/instream/basic_instream_ad.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'video1', + mediaTypes: { + video: { + context: 'instream', + playerSize: [640, 480] + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: '13232361', + video: { + skipppable: false, + playback_methods: ['auto_play_sound_off'] + } + } + } + ] +}]; +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-instream/request.json b/test/fake-server/fixtures/basic-instream/request.json new file mode 100644 index 00000000000..db07ad3e98a --- /dev/null +++ b/test/fake-server/fixtures/basic-instream/request.json @@ -0,0 +1,34 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 13232361, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "require_asset_url": true, + "video": {}, + "hb_source": 1 + } + ], + "user": {} + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-instream/response.json b/test/fake-server/fixtures/basic-instream/response.json new file mode 100644 index 00000000000..5f51034f0be --- /dev/null +++ b/test/fake-server/fixtures/basic-instream/response.json @@ -0,0 +1,42 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [{ + "tag_id": 13232361, + "auction_id": "1398509384102899505", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Finstream.html&e=wqT_3QKxCKAxBAAAAwDWAAUBCKXQzPAFELHeg_SAnKC0ExjCs_b6q5D9_0oqNgkAAAkCABEJBywAABkAAADgehQUQCEREgApEQkAMREb8Hkw6dGnBjjtSEDtSEgAUABYnPFbYABozbp1eACAAQGKAQCSAQNVU0SYAQGgAQGoAQGwAQC4AQPAAQDIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzgzMTM3NjUpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPD1kgK1AiF5andtb2dpMi1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNmRHbkJsZ0FZTUlHYUFCd0tIZ0dnQUU4aUFFR2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFVUU1FQjg2MXFwQUFBRkVESkFmZjUwcVFyNGVvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHR2aThDcm9EQ1ZOSlRqTTZORGN6T09BRC1SaUlCQUNRQkFDWUJBSEJCBUUJAQh5UVEJCQEBFE5nRUFQRRGNAZAsNEJBQ0lCWUlscVFVAREBFDx3UHcuLpoCiQEhTGc5WkRRNjkBJG5QRmJJQVFvQUQVSFRVUURvSlUwbE9Nem8wTnpNNFFQa1lTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBSZUFBLsICP2h0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctdmlkZW8td2l0aC1hLWRmcC12aWRlby10YWcuaHRtbNgCAOACrZhI6gIzaHQFSkh0ZXN0LmxvY2FsaG9zdDo5OTk5BRQ4L3BhZ2VzL2luc3RyZWFtBT7IgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvCanwXpgEAKIECzEwLjc1Ljc0LjY5qAS0LLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM42gQCCADgBADwBMuBwC6IBQGYBQCgBf______AQMUAcAFAMkFaX8U8D_SBQkJCQx4AADYBQHgBQHwBcOVC_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=6805157848bdfdf973d0dbafff4bb9b4c4ce7e60", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [{ + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQklKBNeAAAAABEx74AO4IBoExklKBNeAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQ6dGnBljDlQtiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=07e6e5f2f03cc92e899c3ddbf4e2988e966caaa2&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 97517771, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 10.000000, + "cpm_publisher_currency": 10.000000, + "publisher_currency_code": "$", + "brand_category_id": 36, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": ["auto_play_sound_on"], + "frameworks": ["vpaid_1_0", "vpaid_2_0"], + "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Finstream.html&e=wqT_3QKNCaCNBAAAAwDWAAUBCKXQzPAFELHeg_SAnKC0ExjCs_b6q5D9_0oqNgkAAAECCBRAEQEHNAAAFEAZAAAA4HoUFEAhERIAKREJADERG6gw6dGnBjjtSEDtSEgCUMuBwC5YnPFbYABozbp1eJG4BYABAYoBA1VTRJIBAQbwUpgBAaABAagBAbABALgBA8ABBMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3ODMxMzc2NSk7dWYoJ3InLCA5NzUxNzc3MSwgLh4A8PWSArUCIXlqd21vZ2kyLUx3S0VNdUJ3QzRZQUNDYzhWc3dBRGdBUUFSSTdVaFE2ZEduQmxnQVlNSUdhQUJ3S0hnR2dBRThpQUVHa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUh6cldxa0FBQVVRTUVCODYxcXBBQUFGRURKQWZmNTBxUXI0ZW9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEdHZpOENyb0RDVk5KVGpNNk5EY3pPT0FELVJpSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkCw0QkFDSUJZSWxxUVUBEQEUPHdQdy4umgKJASFMZzlaRFE2OQEkblBGYklBUW9BRBVIVFVRRG9KVTBsT016bzBOek00UVBrWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8FJlQUEuwgI_aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy12aWRlby13aXRoLWEtZGZwLXZpZGVvLXRhZy5odG1s2AIA4AKtmEjqAjNodAVKSHRlc3QubG9jYWxob3N0Ojk5OTkFFDgvcGFnZXMvaW5zdHJlYW0FPmjyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-4ElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw398F6YBACiBAsxMC43NS43NC42OagEtCyyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczONoEAggB4AQA8ATLgcAuiAUBmAUAoAX______wEDFAHABQDJBWnbFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=68b9d39d60a72307a201e479000a8c7be5508188" + } + } + }] + }] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-native/description.md b/test/fake-server/fixtures/basic-native/description.md new file mode 100644 index 00000000000..950cc5da7d7 --- /dev/null +++ b/test/fake-server/fixtures/basic-native/description.md @@ -0,0 +1,62 @@ +Test Page - 'test/pages/native.html' +Test Spec File - 'test/spec/e2e/native/basic_native_ad.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: '/19968336/prebid_native_example_1', + sizes: [360, 360], + mediaTypes: { + native: { + title: { + required: true + }, + image: { + required: true + }, + sponsoredBy: { + required: true + } + } + }, + bids: [{ + bidder: 'appnexus', + params: { + placementId: 13232354, + allowSmallerSizes: true + } + }] +}, { + code: '/19968336/prebid_native_example_2', + sizes: [ + [1, 1] + ], + mediaTypes: { + native: { + title: { + required: true + }, + body: { + required: true + }, + image: { + required: true + }, + sponsoredBy: { + required: true + }, + icon: { + required: false + }, + } + }, + bids: [{ + bidder: 'appnexus', + params: { + placementId: 13232354, + allowSmallerSizes: true + } + }] +}]; +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-native/request.json b/test/fake-server/fixtures/basic-native/request.json new file mode 100644 index 00000000000..08e75d5bd69 --- /dev/null +++ b/test/fake-server/fixtures/basic-native/request.json @@ -0,0 +1,81 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 1, + "height": 1 + } + ], + "ad_types": [ + "native" + ], + "id": 13232354, + "allow_smaller_sizes": true, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "native": { + "layouts": [ + { + "title": { + "required": true + }, + "main_image": { + "required": true + }, + "sponsored_by": { + "required": true + } + } + ] + }, + "hb_source": 1 + }, + { + "sizes": [ + { + "width": 1, + "height": 1 + } + ], + "ad_types": [ + "native" + ], + "id": 13232354, + "allow_smaller_sizes": true, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "native": { + "layouts": [ + { + "title": { + "required": true + }, + "description": { + "required": true + }, + "main_image": { + "required": true + }, + "sponsored_by": { + "required": true + }, + "icon": { + "required": false + } + } + ] + }, + "hb_source": 1 + } + ], + "user": {} + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-native/response.json b/test/fake-server/fixtures/basic-native/response.json new file mode 100644 index 00000000000..fb85110663d --- /dev/null +++ b/test/fake-server/fixtures/basic-native/response.json @@ -0,0 +1,116 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "tag_id": 13232354, + "auction_id": "2566965852006062421", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLhB6DhAwAAAwDWAAUBCNDZme8FENWyhPv4uuzPIxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc1MzgyMjI0KTsBHThyJywgOTc0OTQ0MDMsIDEdHvDQkgKpAiFCenhPTlFqOC1Md0tFSVBMdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JRTDdBTHVfbzFqX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVBQZ0VBSWdGaGlVLpoCiQEhYWdfb0o6LQEkblBGYklBUW9BRBVYDGtRRG8yhQAQUU9ZV1MRWAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCMWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTwvC9wYWdlcy9uYXRpdmUuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATruAKyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQy2gQCCADgBAHwBIPLvi6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQkMeAAA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYJJTTwv8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=54514bb848c51d509dfe3e21af09b77edfe9738e", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "native", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 97494403, + "media_type_id": 12, + "media_subtype_id": 65, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 53, + "client_initiated_ad_counting": true, + "viewability": { + "config": "" + }, + "rtb": { + "native": { + "title": "This is a Prebid Native Creative", + "sponsored": "Prebid.org", + "main_img": { + "url": "http://vcdn.adnxs.com/p/creative-image/94/22/cd/0f/9422cd0f-f400-45d3-80f5-2b92629d9257.jpg", + "width": 3000, + "height": 2250, + "prevent_crop": false + }, + "link": { + "url": "http://prebid.org/dev-docs/show-native-ads.html", + "click_trackers": [ + "http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQFUZYY_XsZ8jKnKSKrrb42HQbOZdAAAAAOLoyQBtJAAAbSQAAAIAAACDpc8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoA8BZszgAAAAA./bcr=AAAAAAAA8D8=/cnd=%21ag_oJQj8-LwKEIPLvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzQyQOYWSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3NDI=/bn=89169/" + ] + }, + "impression_trackers": [ + "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLpB6DpAwAAAwDWAAUBCNDZme8FENWyhPv4uuzPIxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlCDy74uWJzxW2AAaM26dXjRuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzUzODIyMjQpO3VmKCdyJywgOTc0OTQ0MDMsIC4eAPDQkgKpAiFCenhPTlFqOC1Md0tFSVBMdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JRTDdBTHVfbzFqX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVBQZ0VBSWdGaGlVLpoCiQEhYWdfb0o6LQEkblBGYklBUW9BRBVYDGtRRG8yhQAQUU9ZV1MRWAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCMWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTwlS9wYWdlcy9uYXRpdmUuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATruAKyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQy2gQCCAHgBAHwBEH6IIgFAZgFAKAF_xEBGAHABQDJBQAFARTwP9IFCQkFC3wAAADYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgEhQAAA8D_IBgDQBvUv2gYWChAAOgEAUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=6b203c7aee654cffa9c0b3771f6945f6d1e8d06c" + ], + "id": 97494403 + } + } + } + ] + }, + { + "tag_id": 13232354, + "auction_id": "6083251961435599864", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLhB6DhAwAAAwDWAAUBCNDZme8FEPjnxITbrYO2VBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc1MzgyMjI0KTsBHSxyJywgOTc0OTQyMDQ2HgDw0JICqQIhYlR3OWZBajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWUlJQ2FBQndBSGdBZ0FHbUFZZ0JfRi1RQVFDWUFRQ2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCeVdmYjBYeWIxVF9aQVFBQUFBQUFBUEFfNEFFQTlRRUFBQUFBbUFJQW9BSUF0UUlBQUFBQXZRSUFBQUFBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQVA4AcSIdWdNSlUwbE9Nem8wTnpReTRBUG1Gb2dFQUpBRUFKZ0VBY0UJXQUBCERKQgUICQEYMkFRQThRUQkNAQFUUGdFQUlnRmhpVS6aAokBIW9ROTNPUTYtASRuUEZiSUFRb0FEFVgMa1FEbzKFABBRT1lXUxFYDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gIxaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPC8L3BhZ2VzL25hdGl2ZS5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBOu4ArIEDggAEAEYACAAKAAwADgCuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDLaBAIIAOAEAfAEvMm-LogFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJCQx4AADYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgklNPC_yAYA0Ab1L9oGFgoQCRQZAVAQABgA4AYM8gYCCACABwGIBwCgB0E.&s=99a73b39ab82dd9384eee306ff03276ab688cfe5", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "native", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 97494204, + "media_type_id": 12, + "media_subtype_id": 65, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 53, + "client_initiated_ad_counting": true, + "viewability": { + "config": "" + }, + "rtb": { + "native": { + "title": "This is a Prebid Native Creative", + "desc": "This is a Prebid Native Creative. There are many like it, but this one is mine.", + "sponsored": "Prebid.org", + "icon": { + "url": "http://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png", + "width": 127, + "height": 83, + "prevent_crop": false + }, + "main_img": { + "url": "http://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg", + "width": 989, + "height": 742, + "prevent_crop": false + }, + "link": { + "url": "http://prebid.org/dev-docs/show-native-ads.html", + "click_trackers": [ + "http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQPgzkbBtDWxUKnKSKrrb42HQbOZdAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAJhcX3AAAAAA./bcr=AAAAAAAA8D8=/cnd=%21oQ93OQj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzQyQOYWSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3NDI=/bn=89169/" + ] + }, + "impression_trackers": [ + "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLpB6DpAwAAAwDWAAUBCNDZme8FEPjnxITbrYO2VBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXjRuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzUzODIyMjQpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPDQkgKpAiFiVHc5ZkFqOC1Md0tFTHpKdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0J5V2ZiMFh5YjFUX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVRQZ0VBSWdGaGlVLpoCiQEhb1E5M09RNi0BJG5QRmJJQVFvQUQVWAxrUURvMoUAEFFPWVdTEVgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDKBlQUEu2AIA4AKtmEjqAjFodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OQUU8LwvcGFnZXMvbmF0aXZlLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagE67gCsgQOCAAQARgAIAAoADAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDc0MtoEAggB4AQB8AS8yb4uiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkJDHgAANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSU48D_IBgDQBvUv2gYWChAAOgEAUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=5c316c116b6e2bdb19f3950c4c769821e735688e" + ], + "id": 97494204 + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-outstream/description.md b/test/fake-server/fixtures/basic-outstream/description.md new file mode 100644 index 00000000000..c5855d6af15 --- /dev/null +++ b/test/fake-server/fixtures/basic-outstream/description.md @@ -0,0 +1,44 @@ +Test Page - 'test/pages/outstream.html' +Test Spec File - 'test/spec/e2e/outstream/basic_outstream_ad.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'video_ad_unit_1', + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 480] + } + }, + bids: [{ + bidder: 'appnexus', + params: { + placementId: 13232385, + video: { + skippable: true, + playback_method: ['auto_play_sound_off'] + } + } + }] +}, { + code: 'video_ad_unit_2', + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 480] + } + }, + bids: [{ + bidder: 'appnexus', + params: { + placementId: 13232385, + video: { + skippable: true, + playback_method: ['auto_play_sound_off'] + } + } + }] +}]; +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-outstream/request.json b/test/fake-server/fixtures/basic-outstream/request.json new file mode 100644 index 00000000000..611a518fc2d --- /dev/null +++ b/test/fake-server/fixtures/basic-outstream/request.json @@ -0,0 +1,50 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [{ + "sizes": [{ + "width": 640, + "height": 480 + }], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": ["video"], + "id": 13232385, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "video": { + "skippable": true, + "playback_method": ["auto_play_sound_off"] + }, + "hb_source": 1 + }, { + "sizes": [{ + "width": 640, + "height": 480 + }], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": ["video"], + "id": 13232385, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "video": { + "skippable": true, + "playback_method": ["auto_play_sound_off"] + }, + "hb_source": 1 + }], + "user": {} + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-outstream/response.json b/test/fake-server/fixtures/basic-outstream/response.json new file mode 100644 index 00000000000..13b4e527b1f --- /dev/null +++ b/test/fake-server/fixtures/basic-outstream/response.json @@ -0,0 +1,105 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "tag_id": 13232385, + "auction_id": "527250675737245396", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Foutstream.html&e=wqT_3QKwCKAwBAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIHSpwY47UhA7UhIAFAAWJzxW2AAaOWljwF4AIABAYoBAJIBA1VTRJgBAaABAagBAbABALgBA8ABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3NTU1Mzg5NikFHTRyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_yIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzLwmj8F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAOAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWlyFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwv8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9953ce4d94992db04897ab580bf81b3e274b2601", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQloC-ldAAAAABHUNucysitRBxloC-ldAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQgdKnBljDlQtiAi0taAFwAXgAgAECiAEEkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=979aee1106a0bea5609a3c23fdc46153ad6d9eec&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 97517771, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 36, + "renderer_url": "http://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js", + "renderer_id": 2, + "renderer_config": "{\"skippable\":{\"videoThreshold\":null,\"skipLocation\":\"top-right\"}}", + "client_initiated_ad_counting": true, + "viewability": { + "config": "tv=vh2-121&d=1x1&s=3479483&st=0&vctx=4&ts=1575553896&vc=iab;vid_ccr=1&vjs=http%3A%2F%2Fcdn.adnxs.com%2Fv%2Fvideo%2F182%2Ftrk.js&cb=http%3A%2F%2Fsin3-ib.adnxs.com%2Fvevent%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QK4CKA4BAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_yIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzLwmj8F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAeAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWl6FPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwP8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA%26s%3D5adef946cd5f0d8db86d67860914e02ef6f91d6b&cet=0&cecb=&rdcb=http%3A%2F%2Fsin3-ib.adnxs.com%2Frd_log%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QKMCaCMBAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_aPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7gSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDffwXpgEAKIECzEwLjc1Ljc0LjY5qASYzwKyBBIIBBAEGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDgzNNoEAggB4AQA8ATLgcAuiAUBmAUAoAX_____BQMUAcAFAMkFac4U8D_SBQkJCQx4AADYBQHgBQHwBcOVC_oFBAgAEACQBgGYBgC4BgDBBgklNPA_yAYA0Ab1L9oGFgoQCRQZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.%26s%3Df2a73057b50fb0c9e98a6093141472a4ed2e401e&bridge=1.11.0&rblog=auc=527250675737245396;bm=9325;sm=9325;cr=97517771;pl=13232385&vid_context=anoutstream;anbannerstream;anoverlayplayer" + }, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_off" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "content": "adnxs00:00:30.000" + } + } + } + ] + }, + { + "tag_id": 13232385, + "auction_id": "3449642271543746980", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Foutstream.html&e=wqT_3QKwCKAwBAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIHSpwY47UhA7UhIAFAAWJzxW2AAaOWljwF4AIABAYoBAJIBA1VTRJgBAaABAagBAbABALgBA8ABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3NTU1Mzg5NikFHTRyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP8iAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My8Jo_BemAQAogQLMTAuNzUuNzQuNjmoBJjPArIEEggEEAQYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODM02gQCCADgBADwBMuBwC6IBQGYBQCgBf____8FAxQBwAUAyQVpchTwP9IFCQkJDHgAANgFAeAFAfAFw5UL-gUECAAQAJAGAZgGALgGAMEGCSU08L_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=e43b45a2391036da6d93eda546d8808de0169bb1", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQloC-ldAAAAABGkYYl1XpffLxloC-ldAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQgdKnBljDlQtiAi0taAFwAXgAgAECiAEEkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=414834fdc6e268f284292aedf8b01ee525c3e999&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 97517771, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 36, + "renderer_url": "http://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js", + "renderer_id": 2, + "renderer_config": "{\"skippable\":{\"videoThreshold\":null,\"skipLocation\":\"top-right\"}}", + "client_initiated_ad_counting": true, + "viewability": { + "config": "tv=vh2-121&d=1x1&s=3479483&st=0&vctx=4&ts=1575553896&vc=iab;vid_ccr=1&vjs=http%3A%2F%2Fcdn.adnxs.com%2Fv%2Fvideo%2F182%2Ftrk.js&cb=http%3A%2F%2Fsin3-ib.adnxs.com%2Fvevent%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QK4CKA4BAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP8iAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My8Jo_BemAQAogQLMTAuNzUuNzQuNjmoBJjPArIEEggEEAQYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODM02gQCCAHgBADwBMuBwC6IBQGYBQCgBf____8FAxQBwAUAyQVpehTwP9IFCQkJDHgAANgFAeAFAfAFw5UL-gUECAAQAJAGAZgGALgGAMEGCSU08D_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..%26s%3Dc2a8dac8959d9366981afc868ec5b54853090944&cet=0&cecb=&rdcb=http%3A%2F%2Fsin3-ib.adnxs.com%2Frd_log%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QKMCaCMBAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP2jyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-4ElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw338F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAeAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWnOFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwP8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA%26s%3D4e9e218d8f075cb19c4a4e8da2a7e716fa15d3c5&bridge=1.11.0&rblog=auc=3449642271543746980;bm=9325;sm=9325;cr=97517771;pl=13232385&vid_context=anoutstream;anbannerstream;anoverlayplayer" + }, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_off" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "content": "adnxs00:00:30.000" + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/index.js b/test/fake-server/fixtures/index.js new file mode 100644 index 00000000000..bd58bda5ad5 --- /dev/null +++ b/test/fake-server/fixtures/index.js @@ -0,0 +1,41 @@ +/* eslint-disable no-console */ + +const path = require('path'); +const fs = require('fs'); + +const REQ_RES_PAIRS = {}; + +/** + * @param {String} dirname - Path of the fixture directory + * @returns {object} reqResPair - An object containing 'request' - 'response' segregated by ad unit media type. + */ +function getReqResPairs (dirname) { + try { + const filenames = fs.readdirSync(dirname, { withFileTypes: true }); + filenames.forEach(filename => { + if (filename.isDirectory()) { + getReqResPairs(`${dirname}/${filename.name}`); + } else { + if (filename.name === 'request.json' || filename.name === 'response.json') { + const parentDir = path.basename(dirname); + if (!REQ_RES_PAIRS[parentDir]) { + REQ_RES_PAIRS[parentDir] = { + request: {}, + response: {} + } + } + if (filename.name === 'request.json') { + REQ_RES_PAIRS[parentDir]['request'] = JSON.parse(fs.readFileSync(`${dirname}/${filename.name}`, { encoding: 'utf-8' })); + } else { + REQ_RES_PAIRS[parentDir]['response'] = JSON.parse(fs.readFileSync(`${dirname}/${filename.name}`, { encoding: 'utf-8' })); + } + } + } + }); + return REQ_RES_PAIRS; + } catch (e) { + console.error(`Error:: ${e.message}`); + } +} + +module.exports = getReqResPairs; diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_1/description.md b/test/fake-server/fixtures/longform/longform_biddersettings_1/description.md new file mode 100644 index 00000000000..207e851af74 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_biddersettings_1/description.md @@ -0,0 +1,41 @@ +Test Page - 'integrationExamples/longform/basic_w_bidderSettings.html' +Test Spec File - 'test/spec/e2e/longform/basic_w_bidderSettings.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: false + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` + +SetConfig to use with AdUnit: +``` +pbjs.setConfig({ + debug: true, + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + }, + adpod: { + brandCategoryExclusion: true + } +}); +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_1/request.json b/test/fake-server/fixtures/longform/longform_biddersettings_1/request.json new file mode 100644 index 00000000000..aba76398093 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_biddersettings_1/request.json @@ -0,0 +1,387 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + } + ], + "user": {}, + "brand_category_uniqueness": true + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_1/response.json b/test/fake-server/fixtures/longform/longform_biddersettings_1/response.json new file mode 100644 index 00000000000..e3ea15d7c6e --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_biddersettings_1/response.json @@ -0,0 +1,114 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "2678252910506723691", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "3548675574061430850", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "8693167356543642173", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "7686428711280367086", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "3784359541475413084", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "7233136875958651734", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "159775901183771330", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "6558726890185052779", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "6624810255570939818", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "528384387675374412", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "2535665225687089273", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "2166694611986638079", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "9137369006412413609", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "3524702228053475248", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2d4806af582cf6", + "tag_id": 15394006, + "auction_id": "57990683038266307", + "nobid": true, + "ad_profile_id": 1182765 + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_2/description.md b/test/fake-server/fixtures/longform/longform_biddersettings_2/description.md new file mode 100644 index 00000000000..cafbb17f61b --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_biddersettings_2/description.md @@ -0,0 +1,28 @@ +Test Page - 'integrationExamples/longform/basic_w_bidderSettings.html' +Test Spec File - 'test/spec/e2e/longform/basic_w_bidderSettings.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: false + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_2/request.json b/test/fake-server/fixtures/longform/longform_biddersettings_2/request.json new file mode 100644 index 00000000000..f2f20700ffe --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_biddersettings_2/request.json @@ -0,0 +1,137 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + } + ], + "user": {}, + "brand_category_uniqueness": true + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_2/response.json b/test/fake-server/fixtures/longform/longform_biddersettings_2/response.json new file mode 100644 index 00000000000..e2332806dbb --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_biddersettings_2/response.json @@ -0,0 +1,188 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "245a09bd675168", + "tag_id": 15394006, + "auction_id": "3810681093956255668", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKVCKAVBAAAAwDWAAUBCKD4kfAFELT_vOy9yJDxNBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUxEMWZkUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZVS10N09mcU9BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFLdy1SRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=66ba37441db5e28c87ee52e729333fd9324333f9", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQkgfAReAAAAABG0P4_dQ0LiNBkgfAReAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=6931bf3569012d0e1f02cb5a2e88dfcafe00dba9&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLxCOhxBAAAAwDWAAUBCKD4kfAFELT_vOy9yJDxNBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFMRDFmZFFpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWVUtdDdPZnFPQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhS3ctUkZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ea46ec90cf31744c7be2af5d5f239ab4eed29098" + } + } + } + ] + }, + { + "uuid": "245a09bd675168", + "tag_id": 15394006, + "auction_id": "7325897349627488405", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKUCKAUBAAAAwDWAAUBCKD4kfAFEJXRloy0mrTVZRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXJUeTNJd2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVSzAtQ2hwcWRrXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFBQTlLQlE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=271fd8a0ccdfc36e320f707164588ed1b33e9861", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQkgfAReAAAAABGVqIVB09CqZRkgfAReAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=115ac2b842cf3efeb5acaeda94ddf05632c345ca&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418671, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 30, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLwCOhwBAAAAwDWAAUBCKD4kfAFEJXRloy0mrTVZRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFyVHkzSXdpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVUswLUNocHFka18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhQUE5S0JRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=f73e060b15a6bbcca65f918a296f155b78c74eca" + } + } + } + ] + }, + { + "uuid": "245a09bd675168", + "tag_id": 15394006, + "auction_id": "968802322305726102", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKVCKAVBAAAAwDWAAUBCKD4kfAFEJbt7LTEkvi4DRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIUtUejN5d2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFTT3dTTWVaYnVJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASF0ZzY4Nmc2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULfAAAANgFAeAFAfAF8owB-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e35825a106304da78477df1575f981395be21d5f", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQkgfAReAAAAABGWNptGlOBxDRkgfAReAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=677bedd5b2d21fdc3f940cbae279261c8f84c2e7&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149414188, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 13.00001, + "cpm_publisher_currency": 13.00001, + "publisher_currency_code": "$", + "brand_category_id": 32, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 29000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLxCOhxBAAAAwDWAAUBCKD4kfAFEJbt7LTEkvi4DRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFLVHozeXdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBU093U01lWmJ1SV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhdGc2ODZnNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0707b1385afa81517cd338f1516aeccc46fe33e1" + } + } + } + ] + }, + { + "uuid": "245a09bd675168", + "tag_id": 15394006, + "auction_id": "1273216786519070425", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "245a09bd675168", + "tag_id": 15394006, + "auction_id": "1769115862397582681", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKUCKAUBAAAAwDWAAUBCKD4kfAFENn63YWPsMrGGBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIXp6djFzd2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZbW5MamdJaXVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFGdzkxRFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULeAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=fb3a15e7ff747fccd750671b763e312d97083c72", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQkgfAReAAAAABFZfbfwgCmNGBkgfAReAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=7f4b8dd7c7dd9faecebac2e9ec6d7ef8da08da16&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418948, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 1, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLwCOhwBAAAAwDWAAUBCKD4kfAFENn63YWPsMrGGBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiF6enYxc3dpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWW1uTGpnSWl1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhRnc5MURRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwsEFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBWm2FPA_0gUJCQkMdAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=3a27c12c33ebaaae43dbce1cafb0bae43b753fa0" + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/description.md b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/description.md new file mode 100644 index 00000000000..45ae30a7a41 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/description.md @@ -0,0 +1,43 @@ +Test Page - 'integrationExamples/longform/basic_w_custom_adserver_translation.html' +Test Spec File - 'test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: true + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` + +SetConfig to use with AdUnit: +``` +pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + }, + adpod: { + brandCategoryExclusion: true + }, + brandCategoryTranslation: { + translationFile: 'custom_adserver_translation.json' + } +}); +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/request.json b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/request.json new file mode 100644 index 00000000000..e7497ac78f3 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/request.json @@ -0,0 +1,402 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + } + ], + "user": {}, + "brand_category_uniqueness": true + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/response.json b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/response.json new file mode 100644 index 00000000000..b4d8483a539 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/response.json @@ -0,0 +1,294 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "7360998998672342781", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEP39-97ssuGTZhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIVNqMmZTQWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQmtTcHl1c2Q4XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzhKRnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=c92cbcde5c8bf8e053f86493dd4c4698da0392de", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABH9_t7LloUnZhne-wVeAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=8e35c1264cd1b4f1d89f929c3a4a334cf6a68eca&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEP39-97ssuGTZhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFTajJmU0FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkJrU3B5dXNkOF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc4SkZ3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBNLsn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=ca640dffaea7bfcf2b0f2e11d8877821189b74bb" + } + } + } + ] + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "1919339751435064934", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEOasy7zbqrfRGhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIU1EMUZJQWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRclZ0ZGpIUGVBXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASE1QTdmLVE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=c3130de64bc0b8df258e603dfb96f78550ab0c3c", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABFm1pK3Vd2iGhne-wVeAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=2c3cee10303d9b93531bed443c0781d905270598&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418123, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 12, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEOasy7zbqrfRGhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFNRDFGSUFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUXJWdGRqSFBlQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhNUE3Zi1RNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBIvhn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=996a3937245f03e5eefb0cb69917d2d8d7f60424" + } + } + } + ] + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "3257875652791896280", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "5756905673624319729", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "4205438746002589111", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "204849530930208960", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "3482944224379652843", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "2123689132466331410", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "6150444453316813936", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "2810956382376737966", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "7164199537578897638", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCN73l_AFEObhocvZsJa2Yxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXNENXVfQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYSEZfdmZOei1NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFDd19DQnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZs2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgUhLADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=2b9ed1e2e7f27fea52cbdc64cb700195bbd14d75", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQne-wVeAAAAABHmcGiZhVlsYxne-wVeAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=8ba7f141449cb45f8b6e12361a62d8d68aa9c812&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418671, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 30, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCN73l_AFEObhocvZsJa2Yxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFzRDV1X0FpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWEhGX3ZmTnotTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhQ3dfQ0J3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=527640949733fba32740156d743d421eb1fe2863" + } + } + } + ] + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "8404712946290777461", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEPW6p5bQvOLRdBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIWp6MkdiZ2lta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQ0RhTlBDYk9NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFOUS0yRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56TXpRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE18LYuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASSxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABldnDYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgUiLADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ed84428f432d6e743bcad6f7862aed957bece82b", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABF13ckC5YmjdBne-wVeAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=7024b063fcacac27e184ed097ad5878c4dd4dc1d&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417951, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 33, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEPW6p5bQvOLRdBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFqejJHYmdpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkNEYU5QQ2JPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhTlEtMkY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNXwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wn0lGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpwxTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=aefe9625d8e866e048a156abdf26d7c626e6a398" + } + } + } + ] + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "4063389973481762703", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEI_fjorv9IOyOBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIV96eHRIQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFSVExWM2x4c2VJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFEZy1VQ1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAExd2fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=2fb33b5204f9b75c58d89487725a9d55139f9ff4", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABGPr0Pxpg9kOBne-wVeAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=f9ec8d0b81c1cf4eefc58a7990f4a0a78440725f&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417669, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 4, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-CKB-BAAAAwDWAAUBCN73l_AFEI_fjorv9IOyOBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjSuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc0NTA0NjIpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIV96eHRIQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFSVExWM2x4c2VJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFEZy1VQ1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNXwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wn0lGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAExd2fR4gFAZgFAKAF______8BBRQBwAUAyQVpwxTwP9IFCQkJDHgAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=6b79542e3cee0319d8cb83d1daf127c3aeea9b28" + } + } + } + ] + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "5097385192927446024", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "201bba5bb8827", + "tag_id": 15394006, + "auction_id": "2612757136292876686", + "nobid": true, + "ad_profile_id": 1182765 + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/description.md b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/description.md new file mode 100644 index 00000000000..45ae30a7a41 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/description.md @@ -0,0 +1,43 @@ +Test Page - 'integrationExamples/longform/basic_w_custom_adserver_translation.html' +Test Spec File - 'test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: true + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` + +SetConfig to use with AdUnit: +``` +pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + }, + adpod: { + brandCategoryExclusion: true + }, + brandCategoryTranslation: { + translationFile: 'custom_adserver_translation.json' + } +}); +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/request.json b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/request.json new file mode 100644 index 00000000000..f4cea46918f --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/request.json @@ -0,0 +1,142 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + } + ], + "user": {}, + "brand_category_uniqueness": true + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/response.json b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/response.json new file mode 100644 index 00000000000..6a81de25ebe --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/response.json @@ -0,0 +1,188 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "285a2f41615348", + "tag_id": 15394006, + "auction_id": "2837696487158070058", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCNSDmPAFEKr2uMu5veGwJxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIV9EemhKUWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTbnRDdFVIdU9BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFOdzh1Rnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDtLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAAAU3DQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=3414eb9e83df14945d2dbfb00e17fb3f2bad2e33", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnUAQZeAAAAABEqO26Z64VhJxnUAQZeAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=e5a720a9884e1df845be9c33658ab69f4c56981e&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417951, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 33, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCNSDmPAFEKr2uMu5veGwJxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFfRHpoSlFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU250Q3RVSHVPQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhTnc4dUZ3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBN_fn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=99418325b8f5ec79e22c1a9aedd73f03de616c2d" + } + } + } + ] + }, + { + "uuid": "285a2f41615348", + "tag_id": 15394006, + "auction_id": "8688113570839045503", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCNSDmPAFEP_K8rCtqJjJeBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIUN6d3Rud2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWUzRZeVVvR09JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFKQTlsRUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDXLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGBSEsAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=2e7c9d18300402e2e183667711728f7743b70a2b", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnUAQZeAAAAABF_pRzWQmGSeBnUAQZeAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=febf12010c66ac7247f571f03c33175ca9036b32&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418948, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 1, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCNSDmPAFEP_K8rCtqJjJeBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFDend0bndpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVlM0WXlVb0dPSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhSkE5bEVBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBMTnn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=92aa9e9c89384c435ab9c7fa62b963d8fc087ef7" + } + } + } + ] + }, + { + "uuid": "285a2f41615348", + "tag_id": 15394006, + "auction_id": "4162295099171231907", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCNSDmPAFEKOxzaPwqtzhORiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIWREMGtXZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhSFRjUzNjWS1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFEUTg2Q0E2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDXLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=95047e919846faea401c778106fb33dae0c95b02", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnUAQZeAAAAABGjWHMEV3HDORnUAQZeAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=50350aadc603f4bb6c59888515d60e9182da0eb8&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418671, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 30, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCNSDmPAFEKOxzaPwqtzhORiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFkRDBrV2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYUhUY1MzY1ktVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhRFE4NkNBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=82c42e6aa09e7c842254552ae524791fa3693bbb" + } + } + } + ] + }, + { + "uuid": "285a2f41615348", + "tag_id": 15394006, + "auction_id": "1076114531988487576", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCNSDmPAFEJj7vIbyjsj3Dhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIVRqMWVUZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZOUNHX2M3MHRvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0BBRHdQdy4umgKJASFFQThNQzo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TTFRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE18O0uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASrxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQA8ATF3Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAAAABTcNAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=c49afba7ca4b5193f7da37b17e1fbfbee2328f61", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnUAQZeAAAAABGYPc8gdyDvDhnUAQZeAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=47618eb9096567900e84fd1c6aff09d753b2fe91&event_type=1", + "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417669, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 4, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-CKB-BAAAAwDWAAUBCNSDmPAFEJj7vIbyjsj3Dhiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc0NTE5ODgpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIVRqMWVUZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZOUNHX2M3MHRvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0BBRHdQdy4umgKJASFFQThNQzo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TTFRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE1fC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCfSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASrxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQA8ATF3Z9HiAUBmAUAoAX______wEFFAHABQDJBWnDFPA_0gUJCQkMeAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=72d1ec3db5baaa29c1b0e5f07c012db606675fe5" + } + } + } + ] + }, + { + "uuid": "285a2f41615348", + "tag_id": 15394006, + "auction_id": "7495588537924508785", + "nobid": true, + "ad_profile_id": 1182765 + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_1/description.md b/test/fake-server/fixtures/longform/longform_priceGran_1/description.md new file mode 100644 index 00000000000..8bc4d242f46 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_priceGran_1/description.md @@ -0,0 +1,62 @@ +Test Page - 'integrationExamples/longform/basic_w_priceGran.html' +Test Spec File - 'test/spec/e2e/longform/basic_w_priceGran.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: false + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` + +SetConfig to use with AdUnit: +``` +const customConfigObject = { + 'buckets': [{ + 'precision': 2, // default is 2 if omitted - means 2.1234 rounded to 2 decimal places = 2.12 + 'min': 0, + 'max': 5, + 'increment': 0.01 // from $0 to $5, 1-cent increments + }, + { + 'precision': 2, + 'min': 5, + 'max': 8, + 'increment': 0.05 // from $5 to $8, round down to the previous 5-cent increment + }, + { + 'precision': 2, + 'min': 8, + 'max': 40, + 'increment': 0.5 // from $8 to $40, round down to the previous 50-cent increment + }] +}; + +pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + }, + adpod: { + brandCategoryExclusion: true + }, + priceGranularity: customConfigObject +}); +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_1/request.json b/test/fake-server/fixtures/longform/longform_priceGran_1/request.json new file mode 100644 index 00000000000..aba76398093 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_priceGran_1/request.json @@ -0,0 +1,387 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + } + ], + "user": {}, + "brand_category_uniqueness": true + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_1/response.json b/test/fake-server/fixtures/longform/longform_priceGran_1/response.json new file mode 100644 index 00000000000..4665aa4ef9c --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_priceGran_1/response.json @@ -0,0 +1,366 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "1249897353793397796", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEKTIuZTW4KGsERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCITFqdjBlZ2lta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFXU1JOVU1OTk9jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFTUTgtR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e9887c670ae9fcb7eb2a0253037c64c3587f4bcb", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEkZI5iBYdYERnJwgleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=68a5c49da3a6ecf3dfc0835cb3da72b3b2c7b080&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417951, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 33, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEKTIuZTW4KGsERiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiExanYwZWdpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBV1NSTlVNTk5PY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhU1E4LUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9514ae5f8aae1ee9dddd24dce3e812ae76e0e783" + } + } + } + ] + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "4278372095219023172", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMT65MOLmPWvOxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIUxEeUhqUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQWJScDluWS1FXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASEtQTVuX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=987d4bb0c7611d41b5974ec412469da2241084cd", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABFEPXm4wNRfOxnJwgleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=75aaa9ec84807690ceff60e39fbba6625240f9f3&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418123, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 12, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEMT65MOLmPWvOxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFMRHlIalFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkFiUnA5blktRV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhLUE1bl9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9872a378866ce61fc366ca8c34bdd9302fa41a9b" + } + } + } + ] + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "8860024420878272196", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFEMSN8Z3LqMj6ehiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIU9EMjhLZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkZExBS3hfN09nXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFIdzlLREE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=1289862cbe265fd9af13d2aab9635e3232421ec1", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnKwgleAAAAABHERryzRCH1ehnJwgleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=0b094204d5c18803149e081bd2bc0077d25ebb14&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418671, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 30, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFEMSN8Z3LqMj6ehiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFPRDI4S2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZGRMQUt4XzdPZ18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhSHc5S0RBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=f35771975371bb250fd6701914534b4f595fcf68" + } + } + } + ] + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "5236733650551797458", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFENLt5YOosKfWSBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIThUMjJsZ2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkczByb2Ytbk9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzkxRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=e997907677e4e2f9b641d51b522a901b85944899", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnKwgleAAAAABHSdnmAgp2sSBnJwgleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=d70eef0df40cece50465a13d05a2dc11b65eadeb&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418948, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 1, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFENLt5YOosKfWSBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE4VDIybGdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZHMwcm9mLW5PVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc5MUZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_DtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAGn1FQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e8b6716ad3d2fcbdb79976f72d60f8e90ce8f5a6" + } + } + } + ] + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "4987762881548953446", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "201567478388503336", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEKjm-NzbkYfmAhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXV6NlFDd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkejE5MUdLNk8wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFTZy1SRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=4a887316a3197dfae07c1443a4debc62a2f17fef", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEoM567jRzMAhnJwgleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=eef6278d136f8df4879846840f97933e9d67388a&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEKjm-NzbkYfmAhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiF1ejZRQ3dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZHoxOTFHSzZPMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhU2ctUkc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8JplQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkNVU1RPTREdCEFTVAEL8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAEYYIgiAUBmAUAoAX_EQEUAcAFAMkFabMU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e68b089e4fc94aa7566784ccbff299e50c8bc090" + } + } + } + ] + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "3876520534914199302", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "4833995299234629234", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "8352235304492782614", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEJaok6aeuMb0cxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIUpUMS1FZ2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFmQ1lIN1I1bmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASExUTY4OFE2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=7081f4ad4ae9837aaff4b4f59abc4ce7f8b02cb6", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEW1MTkwRnpcxnJwgleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=71f281c81d1ae269bde275b84aa955c833ab1dea&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149414188, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 13.00001, + "cpm_publisher_currency": 13.00001, + "publisher_currency_code": "$", + "brand_category_id": 32, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 29000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEJaok6aeuMb0cxiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFKVDEtRWdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBZkNZSDdSNW5lc18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhMVE2ODhRNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=05fc37623521011853ff69d194aa6d692b6c0504" + } + } + } + ] + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "2318891724556922037", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "5654583906891472332", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMy7oJeqw8e8Thiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIXZ6Ml9mZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFhYzY5MFRlZi1rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFJZzhjRDo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATF3Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=f929565158c7caa5b85e88fa456cdd04d0e4b6d8", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABHMHeiiGh55ThnJwgleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=a93773067b8588465b9c007e19970bd9e08c1b6c&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417669, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 4, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCKBuBAAAAwDWAAUBCMmFp_AFEMy7oJeqw8e8Thiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjDuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTc5OTMpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIXZ6Ml9mZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFhYzY5MFRlZi1rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFJZzhjRDo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwmmVBQS7YAgDgAq2YSOoCTmh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19wcmljZUdyYW4uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTV9NT0RFTF9MRUFGX05BTUUSAPICHgoaQ1VTVE9NER0IQVNUAQvwkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhgiCIBQGYBQCgBf8RARQBwAUAyQVpsxTwP9IFCQkJDHgAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=a3a24cbf148bb959f539e883af3d118f64e81bc9" + } + } + } + ] + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "2268711976967571175", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "8379392370800588084", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "6225030428438795793", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "1592368529919250324", + "nobid": true, + "ad_profile_id": 1182765 + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_2/description.md b/test/fake-server/fixtures/longform/longform_priceGran_2/description.md new file mode 100644 index 00000000000..8bc4d242f46 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_priceGran_2/description.md @@ -0,0 +1,62 @@ +Test Page - 'integrationExamples/longform/basic_w_priceGran.html' +Test Spec File - 'test/spec/e2e/longform/basic_w_priceGran.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: false + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` + +SetConfig to use with AdUnit: +``` +const customConfigObject = { + 'buckets': [{ + 'precision': 2, // default is 2 if omitted - means 2.1234 rounded to 2 decimal places = 2.12 + 'min': 0, + 'max': 5, + 'increment': 0.01 // from $0 to $5, 1-cent increments + }, + { + 'precision': 2, + 'min': 5, + 'max': 8, + 'increment': 0.05 // from $5 to $8, round down to the previous 5-cent increment + }, + { + 'precision': 2, + 'min': 8, + 'max': 40, + 'increment': 0.5 // from $8 to $40, round down to the previous 50-cent increment + }] +}; + +pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + }, + adpod: { + brandCategoryExclusion: true + }, + priceGranularity: customConfigObject +}); +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_2/request.json b/test/fake-server/fixtures/longform/longform_priceGran_2/request.json new file mode 100644 index 00000000000..f2f20700ffe --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_priceGran_2/request.json @@ -0,0 +1,137 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + } + ], + "user": {}, + "brand_category_uniqueness": true + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_2/response.json b/test/fake-server/fixtures/longform/longform_priceGran_2/response.json new file mode 100644 index 00000000000..ee7494ea665 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_priceGran_2/response.json @@ -0,0 +1,188 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "6123799897847039642", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFEJqN_JX98Yb-VBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIUN6dzV3Z2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYQm5aNWdRbi1NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFJQS1IREE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=a7e4ff14c60153db90971365f90e514f45875324", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnJwgleAAAAABGaBr_Sjxv8VBnJwgleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=842283d9de78fba7e92fac09f95bb63902a0b54a&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418671, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 30, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFEJqN_JX98Yb-VBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFDenc1d2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWEJuWjVnUW4tTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhSUEtSERBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0fb74d544be103e1440c3ee8f7abc14d2c322d15" + } + } + } + ] + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "889501690217653627", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEPvKoYSxoomsDBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIWt6eTlHUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRSzgzNzR1VnVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=78ac70aeeae1da43c90efd248fb30a4ee630ffd5", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABF7ZYgQEyVYDBnJwgleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=f21e2a522ddcaf0a67bc7d52f70288fdf7e6f3dd&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEPvKoYSxoomsDBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFrenk5R1FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUUs4Mzc0dVZ1VV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=69611db1024ddb77e0754087ddbeae68a00633a1" + } + } + } + ] + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "2793012314322059080", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMj-1IPuvLHhJhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIXhqb2ZBZ2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFRQWhlSGt0VHVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASExZzc1OFE2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=243f58d85b09468de2fe485662c950a86b5d90fb", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABFIP3Xg5sXCJhnJwgleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=99dd40ab6ae736c6aa7c96b5319e1723ea581e0d&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149414188, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 13.00001, + "cpm_publisher_currency": 13.00001, + "publisher_currency_code": "$", + "brand_category_id": 32, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 29000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEMj-1IPuvLHhJhiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiF4am9mQWdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBUUFoZUhrdFR1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhMWc3NThRNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=d9a3c817696f263b6e6d81f7251827fa54a47c37" + } + } + } + ] + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "45194178065897765", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2def02900a6cda", + "tag_id": 15394006, + "auction_id": "3805126675549039795", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFELPZ2uvQ0aHnNBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIWNUM1hkZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjbUQzMExTME9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASEtUTZrXzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=bbeaa584bea9afedf6dcab51b1616988441dfa22", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABGzrHYNjYbONBnJwgleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=b7e937b5acc3d8b910f6b08c3a40e04aa10818cd&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418123, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 12, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFELPZ2uvQ0aHnNBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFjVDNYZGdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY21EMzBMUzBPVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhLVE2a186PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8JplQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkNVU1RPTREdCEFTVAEL8N5JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgAAYeYo8D_QBvUv2gYWChABDy4BAFAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=279827127eba3204bc3a152b8abaf701260eb494" + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_1/description.md b/test/fake-server/fixtures/longform/longform_requireExactDuration_1/description.md new file mode 100644 index 00000000000..8fe815912e8 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_requireExactDuration_1/description.md @@ -0,0 +1,40 @@ +Test Page - 'integrationExamples/longform/basic_w_requireExactDuration.html' +Test Spec File - 'test/spec/e2e/longform/basic_w_requireExactDuration.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: true + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` + +SetConfig to use with AdUnit: +``` +pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + }, + adpod: { + brandCategoryExclusion: true + } +}); +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_1/request.json b/test/fake-server/fixtures/longform/longform_requireExactDuration_1/request.json new file mode 100644 index 00000000000..1e036c367c6 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_requireExactDuration_1/request.json @@ -0,0 +1,401 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 15, + "maxduration": 15 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + } + ], + "user": {} + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_1/response.json b/test/fake-server/fixtures/longform/longform_requireExactDuration_1/response.json new file mode 100644 index 00000000000..b91a5a3d523 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_requireExactDuration_1/response.json @@ -0,0 +1,330 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "4424969993715088689", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFELH6mcm82Km0PRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIWhUNEwzZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjek5XT196NC1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFTZy1SR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBNLsn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=3d8c006f4f85ecffd49c500554c3852b9079ff2b", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABExfSbJw6ZoPRlNxwleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=e2c6cedf67a96613ea8851673ebcfdd25a19435c&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFELH6mcm82Km0PRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFoVDRMM2dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY3pOV09fejQtVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhU2ctUkd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHgAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=de23f822f483b6e85615d4297d872262310c240d" + } + } + } + ] + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "2013100091803497646", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "2659371493620557151", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEN_KtpiJif_zJBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIWR6eUJxQWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWSHZpWGF0Q09zXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASEtQTVuX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBIvhn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=eafba287adec58427d1679f43a84ebb19223c4e7", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABFfpQ2TSPznJBlNxwleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=b335b2c79378c1699d54cf9ffe097958bd989a0b&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418123, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 12, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEN_KtpiJif_zJBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFkenlCcUFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVkh2aVhhdENPc18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhLUE1bl9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHgAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=66b9e769da1e1d68b202605fc178fc172046e9c5" + } + } + } + ] + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "5424637592449788792", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "3470330348822422583", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "4415549097692431196", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "1628359298176905427", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "1949183409076770477", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "4707958683377993236", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "2499032734231846767", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "1295788165766409083", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEPvWpeWKj-T9ERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCITR6eVM5d2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFlS0tONGIwQS00XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzkxRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBMTnn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=3cb170cdf53cd6a6bfec0676659daeb6170895e3", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABF7a6mseJD7ERlNxwleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=45f5cce314725120ec769afaacbb7aa92d32e674&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418948, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 1, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEPvWpeWKj-T9ERiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE0enlTOXdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZUtLTjRiMEEtNF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc5MUZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7w7UlGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwP9AG9S_aBhYKEACJABUBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=5c9f03b9c5c6cc2bf070d8cdc6c9af4b06595879" + } + } + } + ] + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "702761892273189154", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEKLi_7T7xq3gCRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4NDg2Nh8A8P2SArkCITdUeVNDd2lva184UEVQYmpuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFHSTh5N21BQUFzUU1FQmlQTXU1Z0FBTEVESkFYQTM4QzJIcnVFXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHFKUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFaQThESlE2PQEkblBGYklBUW9BRBVIVHNRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBPbjn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBf0F-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=f459a78a1b20c9643b90d7491f22593d79cff253", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABEi8Z-2N7bACRlNxwleAAAAACD2459HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1j9BWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgB9uOfR7ABAQ..&s=83289d261bced5258930a1ce2464260a96565241&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418486, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 14.00001, + "cpm_publisher_currency": 14.00001, + "publisher_currency_code": "$", + "brand_category_id": 30, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEKLi_7T7xq3gCRiq5MnUovf28WEqNgmOWItPAQAsQBGOWItPAQAsQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ9uOfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODQ4NiwgMTUZH_D9kgK5AiE3VHlTQ3dpb2tfOFBFUGJqbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRR0k4eTdtQUFBc1FNRUJpUE11NWdBQUxFREpBWEEzOEMySHJ1RV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RxSlBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhWkE4REpRNj0BJG5QRmJJQVFvQUQVSFRzUURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7w7UlGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8AT2459HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF_QX6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwP9AG9S_aBhYKEACJABUBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=16a432c0a05db78fa40fefc7967796ff2a2e8444" + } + } + } + ] + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "8192047453391406704", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEPCMp9SW-P_XcRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXhUdGdYZ2lHa184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFSR0FWSjZORXVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFKUThlRDo9ASRuUEZiSUFRb0FEFUhUcVFEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=8bf90e0756a9265ab6ac029e883e14803447a7fb", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABFwxolqwf-vcRlNxwleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=cf9ea0df7655a5c6150a527399cb2852c61ec14a&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417951, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 13.00001, + "cpm_publisher_currency": 13.00001, + "publisher_currency_code": "$", + "brand_category_id": 33, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEPCMp9SW-P_XcRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF4VHRnWGdpR2tfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBUkdBVko2TkV1TV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhSlE4ZUQ6PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGNIIgFAZgFAKAF_xEBFAHABQDJBWm-FPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=cefb5f476892ed335cd8b0fc20fabf7650b1d2e3" + } + } + } + ] + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "9041697983972949142", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEJb5yqiVjaS9fRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIURUMkpEd2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFYeHdUOEhkUmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFJZzhjRGc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBMXdn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBcLyF_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=308ea3c3363b379ef62dbb6c7a91d1d91d9ee47a", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABGWvBJVaZB6fRlNxwleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=70a33aa1a57d812d9da5c321e898197836ed16f8&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417669, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 4, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5CKB5BAAAAwDWAAUBCM2Op_AFEJb5yqiVjaS9fRiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXiVuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTkxNDkpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIURUMkpEd2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFYeHdUOEhkUmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFJZzhjRGc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYAAGHxKPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ee15793b41a9d22ffad9bd46878a47821d6044fa" + } + } + } + ] + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "356000177781223639", + "nobid": true, + "ad_profile_id": 1182765 + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_2/description.md b/test/fake-server/fixtures/longform/longform_requireExactDuration_2/description.md new file mode 100644 index 00000000000..8fe815912e8 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_requireExactDuration_2/description.md @@ -0,0 +1,40 @@ +Test Page - 'integrationExamples/longform/basic_w_requireExactDuration.html' +Test Spec File - 'test/spec/e2e/longform/basic_w_requireExactDuration.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: true + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` + +SetConfig to use with AdUnit: +``` +pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + }, + adpod: { + brandCategoryExclusion: true + } +}); +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_2/request.json b/test/fake-server/fixtures/longform/longform_requireExactDuration_2/request.json new file mode 100644 index 00000000000..83877ff9ac0 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_requireExactDuration_2/request.json @@ -0,0 +1,141 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "minduration": 30, + "maxduration": 30 + } + } + ], + "user": {} + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_2/response.json b/test/fake-server/fixtures/longform/longform_requireExactDuration_2/response.json new file mode 100644 index 00000000000..e776170328e --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_requireExactDuration_2/response.json @@ -0,0 +1,188 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "198494455120718841", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEPnX6_r7tMzgAhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXpUMDRwQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhejg2NVNoMGVJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKQTkzRFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCADgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=645b6e0a37eb3a315bc3208365bd4fc03e1ecd18", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABH561q_pzHBAhlNxwleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=35a21bf0bef1ca2c138e37a2e025ad523b5a1db2&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418671, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 30, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEPnX6_r7tMzgAhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiF6VDA0cEFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYXo4NjVTaDBlSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNEQUR3UHcuLpoCiQEhSkE5M0RRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0N9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHQAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYJJCjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=cf3130989b2b4fe5271240d65055b85d1192b78a" + } + } + } + ] + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "998265386177420565", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEJW6sbXGoqPtDRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIVdqM1Jid2lHa184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFmcXpCNjduMU9rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0BBRHdQdy4umgKJASFLZzlMRDo9ASRuUEZiSUFRb0FEFUhUcVFEb0pVMGxPTXpvME56UTNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDfaBAIIAOAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=33f01ddfb15bc84d7bf134a168aeb9d9de76fa57", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABEVXaxmFI3aDRlNxwleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=023640de7c18a0d0e80b2456144b89a351455cda&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417951, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 13.00001, + "cpm_publisher_currency": 13.00001, + "publisher_currency_code": "$", + "brand_category_id": 33, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEJW6sbXGoqPtDRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFXajNSYndpR2tfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBZnF6QjY3bjFPa18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNAQUR3UHcuLpoCiQEhS2c5TEQ6PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBGGNIIgFAZgFAKAF_xEBFAHABQDJBWm-FPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=515ab42a7fdcad8fcf34e4fb98b1e076a75006a9" + } + } + } + ] + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "8884527464400177295", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEI-RmcaB1Yumexiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCITVqcmtHUWlta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYb0paejlaR09NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0BBRHdQdy4umgKJASFPdy1pRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UTNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDfaBAIIAOAEAPAExOefR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHQAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYJJCjwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=dc7d874e52ac39980ec1070a7769632be56a2f00", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABGPSMYYqC5MexlNxwleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=9fd739e9f0a6054296f9bb5168c49a89a425795c&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418948, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 1, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEI-RmcaB1Yumexiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE1anJrR1FpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWG9KWno5WkdPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNAQUR3UHcuLpoCiQEhT3ctaUY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkAFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=1f8ea8f07f781fe149beb0d65dd25ad725a12f3b" + } + } + } + ] + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "1279521442385130931", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFELPr8f6Pv_HgERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIW9EeDJEQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFkb01fcFZkVGVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKdzlKRHc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCADgBADwBMXdn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBcLyF_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=4b14660ae659b3d301ec6c40f0f096bb88db145b", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABGzddz_-MXBERlNxwleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=5f277bcab624f05c9d3a3a9c111961f3f33ccca2&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417669, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 4, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5CKB5BAAAAwDWAAUBCM2Op_AFELPr8f6Pv_HgERiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjFuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTkxNDkpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIW9EeDJEQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFkb01fcFZkVGVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKdzlKRHc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYAAGHxKPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=7bb7b75e4769a1260eaed2c79752ee542b4d28ce" + } + } + } + ] + }, + { + "uuid": "25593f19ac7ed2", + "tag_id": 15394006, + "auction_id": "7664937561033023835", + "nobid": true, + "ad_profile_id": 1182765 + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/description.md b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/description.md new file mode 100644 index 00000000000..159ebbcc30b --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/description.md @@ -0,0 +1,40 @@ +Test Page - 'integrationExamples/longform/basic_wo_brandCategoryExclusion.html' +Test Spec File - 'test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: false + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` + +SetConfig to use with AdUnit: +``` +pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + }, + adpod: { + brandCategoryExclusion: false + } +}); +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/request.json b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/request.json new file mode 100644 index 00000000000..2d1fa3f16bf --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/request.json @@ -0,0 +1,386 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + } + ], + "user": {} + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/response.json b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/response.json new file mode 100644 index 00000000000..bfef650e07a --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/response.json @@ -0,0 +1,654 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "6316075342634007031", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPfztqL2oc3TVxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIV96eWNLZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZYkYwSW1fZGU0XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASE5dzR0Xzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=bb81a081c756fd493253bf765c06ff46888f009a", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABH3uU1kDzWnVxk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=a3da30186f69a5ce2edcfc14fa3a31b92ee70060&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418123, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 12, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPfztqL2oc3TVxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFfenljS2dpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWWJGMEltX2RlNF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhOXc0dF86PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=62b9db151b3739399e0970c74fafc4bb61486510" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "8259815099516488747", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEKuY2qihwrDQchiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIW1UeUFCd2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYNml4eGFGdE8wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=8a55db8e788616ef057647b49c0560296fdacb65", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABErjBYVEsKgchk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=75d46be63f76fd4062f354a56c692855da366148&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418948, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 1, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEKuY2qihwrDQchiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFtVHlBQndpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWDZpeHhhRnRPMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=59e0ab1f626c2e4dc5c4f6e6837b77559cf502b4" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "7960926407704980889", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEJnboLK5jLm9bhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIUZEeFl4QWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhSUpVQVhXMC1JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTQThFR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=8d00bc7576c3cc19fe8b3fb4aa42966583741dfa", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGZLUiWY-R6bhk3yQleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=c813392cbb81d43466d5d949b9bebc2305e6fe7d&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417951, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 33, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEJnboLK5jLm9bhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFGRHhZeEFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYUlKVUFYVzAtSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU0E4RUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=284760a6e2d4f226b639d29237e9c1aa25ca49a9" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "7561862402601574638", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEO7By9umucj4aBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCITREcWpId2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTSVA1dzg5RGVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=917e8af2ed1c82091f487b6abd78de47b99e9e46", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABHu4HJryiHxaBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=ff73768bfb14e9ae603064fc91e95b60c8d872e2&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEO7By9umucj4aBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiE0RHFqSHdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU0lQNXc4OURlUV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=84c66b632a2930d28092e00985ee154ba2e97288" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "6577796711489765634", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEIKC0sii6MGkWxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIVBUem53UWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFlaE5hMWl1Y3V3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASE5dzR0X2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ea4a54786a8f3cf5177b3372ce97682da060c358", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABECgRQpQgdJWxk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=778fbf3014328ec0b01d6ebd7b306be32cf79950&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418123, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 12, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEIKC0sii6MGkWxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFQVHpud1FpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZWhOYTFpdWN1d18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhOXc0dF9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=28a3b583912b95528519f63a75c0fe2d06064e7b" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "2418275491761094586", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELr_z7v0l9zHIRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUF6MUJSZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVNUE2dXpUVy1ZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTUTlYR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=c563626304ebb31fd6f1644cc2d4098133dec096", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABG6_3NHv3CPIRk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=88c9fbb2b9dc273865a5f9238543a29224908b26&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELr_z7v0l9zHIRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFBejFCUmdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVTVBNnV6VFctWV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU1E5WEd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e76aeb8daad477f4428631fc89d277d4a4646ded" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "5990197965284733361", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELHjwfj9qd2QUxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIURUeDF3d2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFmWXBYSEoxUGVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e443347514ff5f6a52a2811f591f9a346061a756", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGxcRDfT3UhUxk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=50348eb78116f7d35ca5ac6f6fa4c5548a6ceffc&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELHjwfj9qd2QUxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFEVHgxd3dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZllwWEhKMVBlTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a24f331ff55f96c5afe5134762f8d8e230b6287c" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "4399290132982250349", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEO32psKU4tqGPRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCITN6dDlwd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRWlZqbkpncmV3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0d9b0a06992ff427d281fae8d8b18d4e6838b944", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABFtu0lIEWsNPRk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=52a446d84f5e9a2baa068760c4406f4a567a911a&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEO32psKU4tqGPRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiEzenQ5cHdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUVpWam5KZ3Jld18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e6ae592b5fc3de0053b5acd46294b83549aa00c8" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "8677372908685012092", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPzYku74lY62eBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIVVEeGp5d2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVN29abmh2c09RXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASE5dzR0X2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=522b764f2276ce75053a55a0198b79fb8d1d39d5", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABF8rMSNrzhseBk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=02b75d0ecc71c7897b9590be5e50b094158c8097&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418123, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 12, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPzYku74lY62eBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFVRHhqeXdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVTdvWm5odnNPUV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhOXc0dF9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0ae5558a7b0cc87eaa0c6811522629963b41bac5" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "617065604518434488", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELitu4PevJDICBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUFqMVNSZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaUzdZYTg5Ny13XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTUTlYR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9HYBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAAAAAAAAAAAAAAAAAAAAEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f59bdb7b0f7020f75c6019f23686915b72d61779", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABG41m7g5UGQCBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=912a721db8e85d4d64a8869d7cf9b56cd0c24907&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELitu4PevJDICBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFBajFTUmdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWlM3WWE4OTctd18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU1E5WEd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBGAHABQDJBQAFARTwP9IFCQkFC3wAAADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgEhMAAA8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=9b4372ae0674305d9cd7152959910d1fa7d4daec" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "8957511111704921777", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELGNpebanN6nfBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXVqdHppQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFUM1dNOVpkQU9JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFIZzhRRDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBK_ln0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAaakNAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a8817d9dc3326ba1b59fe308f126ddaca5710a9c", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABGxRsms5XhPfBk3yQleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=a0ac94e902cbc609881fa9f39537bbc67ba046e7&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418671, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 30, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELGNpebanN6nfBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiF1anR6aUFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVDNXTTlaZEFPSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhSGc4UUQ6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=75b3ad3e867323196da165cd655b3ae51c8b44d0" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "2680240375770812721", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELGi6rO9jYiZJRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIWd6eTMtZ2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYcFdVTk9rai1jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f8458c6a48fed591c269169a9744aba11cb90285", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABExkXrWayAyJRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=e2dbd082b353a37db9f632efc2532913a0c48166&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418948, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 1, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELGi6rO9jYiZJRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFnenkzLWdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWHBXVU5Pa2otY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=5475ac640321ae51a06b5c05ac62519e97e90114" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "8439286287321689724", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEPzciY2kxZePdRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIU1UeWZ6d2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWalR1QThjek9FXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=73e760427d2aec3d47824994cf35c35f1eeddcf8", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABF8bqJBKl4edRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=dac1e836a6f2c4dc036c50d0b3128dfefb34915d&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418948, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 1, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEPzciY2kxZePdRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFNVHlmendpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVmpUdUE4Y3pPRV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=6c1fb35564d2ffd08fb4c5b290aadd6e1e3d83ec" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "5519278898732145414", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEIa29Pmn3ZrMTBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCITFEc0hwUWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkQUZ3YVliRWVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTQThFR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=d01f411e7cc9126e912daca85136b2ca6f99a347", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABEGGz1_6mqYTBk3yQleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=81115280cee86ae0bc259627410fa5dbbc178646&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417951, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 33, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEIa29Pmn3ZrMTBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiExRHNIcFFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZEFGd2FZYkVlTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU0E4RUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=90f21feeb2c798cd77b3cadbc961240238825f0d" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "6754624236211478320", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELC-hPXI3s_eXRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIVJqc0hVUWlta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaRjJPd05MVnVvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=34811f7e5c917550619274f5b75a0cd214119812", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABEwH6GO9D69XRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=d811faa48963b18d33c0a1f9d1e64ff97640a415&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418948, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 1, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELC-hPXI3s_eXRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFSanNIVVFpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkYyT3dOTFZ1b18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=c0a0a2d65dd091bd2ed81f95da1a9f7ff16ad70e" + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/description.md b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/description.md new file mode 100644 index 00000000000..159ebbcc30b --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/description.md @@ -0,0 +1,40 @@ +Test Page - 'integrationExamples/longform/basic_wo_brandCategoryExclusion.html' +Test Spec File - 'test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: false + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` + +SetConfig to use with AdUnit: +``` +pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + }, + adpod: { + brandCategoryExclusion: false + } +}); +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/request.json b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/request.json new file mode 100644 index 00000000000..5a5ddce7d54 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/request.json @@ -0,0 +1,136 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + } + ], + "user": {} + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/response.json b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/response.json new file mode 100644 index 00000000000..9273f8e0c7b --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/response.json @@ -0,0 +1,224 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "4631210661889362034", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPKQq-_0sdeiQBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXF6eU1HUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVQk5fYTFxbHU0XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0dae5294ed5bb48b7d3a156e5e587a26da27c7e1", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABFyyOpNj11FQBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=9085e4dbb4849b0e6d3714d84a2754bbab578e16&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPKQq-_0sdeiQBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFxenlNR1FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVUJOX2ExcWx1NF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=aa5533d04e16ee398f8028ab3af03a48d7d8cc17" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "714778825826946473", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEKmbi7Ph8dn1CRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIU56dmJOZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRbjlXUzRmY09jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASEtUTZrXzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCADgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=8917b1722eed5b6d85c6d5a01eea7862089bee32", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGpzWIWjmfrCRk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=9ec7e7de16b948b60d74b47f1917faf5d3b6dbf0&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418123, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 12, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEKmbi7Ph8dn1CRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFOenZiTmdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUW45V1M0ZmNPY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhLVE2a186PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8N5JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgAAYfQo8D_QBvUv2gYWChABDy4BAFAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=8198652a5ee16abf4595ab1bfc6b051f81f0579d" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "231404788116786844", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEJydmpjcrYebAxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUVqMFlVZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhLXFPTExmZ2VrXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=775dfc49086467337dee9a5e8d78b361931c6aaa", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGcjgbDbR02Axk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=914256a92514df787ccb1eae7dea7578d23c8fba&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEJydmpjcrYebAxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFFajBZVWdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYS1xT0xMZmdla18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f624619431372f9a248d0fa0dd8d09c4977bb544" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "7557072342526904599", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEJeS-7GaqIfwaBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIUFqdmVKQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFSY2lLblVqeU9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASFJQS1IRDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0dQFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCADgBADwBK_ln0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAAAAAAAAAAAAAAAAAABAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=552663ed1246fd2a3cc5824164f57d32f18078ee", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABEXyT6mQR3gaBk3yQleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=e1c80e622aa60bf7683413f4371b0055d0d16f47&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418671, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 30, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEJeS-7GaqIfwaBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFBanZlSkFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUmNpS25VanlPVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhSUEtSEQ6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEYAcAFAMkFAAUBFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=ccf266d1b02551a2ad0af0871d4af43e4aee4bba" + } + } + } + ] + }, + { + "uuid": "2c52d7d1f2f703", + "tag_id": 15394006, + "auction_id": "5093465143102876632", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFENjX7JP78efXRhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIUJUeXRwUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYamVBMVdNcXUwXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASEtUTZrX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=6651c1436b699842aabb3ae53d96d07caf5b4938", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABHYK3uyj5-vRhk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=f62098bf5037b22ca4e5583289a1527fdfa87e43&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418123, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 12, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFENjX7JP78efXRhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFCVHl0cFFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWGplQTFXTXF1MF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhLVE2a19nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAGH0KPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=4b43aaab766ee7d2e4c900ec32cb3c8b7ccef1d0" + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/description.md b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/description.md new file mode 100644 index 00000000000..c1781561af5 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/description.md @@ -0,0 +1,40 @@ +Test Page - 'integrationExamples/longform/basic_wo_requireExactDuration.html' +Test Spec File - 'test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: false + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` + +SetConfig to use with AdUnit: +``` +pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + }, + adpod: { + brandCategoryExclusion: true + } +}); +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/request.json b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/request.json new file mode 100644 index 00000000000..aba76398093 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/request.json @@ -0,0 +1,387 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + } + ], + "user": {}, + "brand_category_uniqueness": true + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/response.json b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/response.json new file mode 100644 index 00000000000..c35a47781f7 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/response.json @@ -0,0 +1,366 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "8905202273088829598", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEJ7x1-ORyejKexiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIWlEeE84Z2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhV09TRWpDY09NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0BBRHdQdy4umgKJASFQZzlaRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56YzNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAZWQU8D_SBQkJBQt4AAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgEgMAAA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=21195aa3e27f8eb88ba43d5da32e6b78c2aa03f8", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABGe-HUcSaKVexm1ywleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=3c05b8509dd5c7c4459886f4c69fdd9cd07caa66&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418948, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 1, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEJ7x1-ORyejKexiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFpRHhPOGdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYVdPU0VqQ2NPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNAQUR3UHcuLpoCiQEhUGc5WkY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXObNgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYFISwA8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=203ae79160a460b18f20165e5de53bb1f45e4933" + } + } + } + ] + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "2428831247136753876", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFENSR0sfppLzaIRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXRUeV9FQWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTek5nNXJvQi0wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFVUThpSFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=af2d5096aa4f934e84b59ad16cd18dfe5b9bbc77", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHUiPSYJvG0IRm1ywleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=440a389c7f556dac70c650bb1e593a10cbcdf2af&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417951, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 33, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFENSR0sfppLzaIRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF0VHlfRUFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU3pOZzVyb0ItMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhVVE4aUhRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9b00ed17c420f328d63b72519d2d578c5921d0d7" + } + } + } + ] + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "1625697369389546128", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEJD1gLbO5OjHFhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIXVqeHMtUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhcDVwSkxuSXVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFBQTlhQUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0e70f535a95c82238d685147f41e0bd2f86631c0", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGQOsDmJKOPFhm1ywleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=144214d77cc4ced0893c9fe64132ad01c429c43c&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418123, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 12, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEJD1gLbO5OjHFhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiF1anhzLVFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYXA1cEpMbkl1VV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhQUE5YUFBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f6bc475b66c167036dcb9f10c7c5f176124829a6" + } + } + } + ] + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "5434800203981031918", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEO6TivzZv5K2Sxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIW5Ud3I5QWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFXVVcwV1Y1LU9JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFKdzh1RGc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=c3ba85f0eb0293896e02066385f82b4450af2cfb", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABHuiYKf_UlsSxm1ywleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=9eb2d880fa9b524a6a0807eef0c65b7b1393f48a&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418671, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 30, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEO6TivzZv5K2Sxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFuVHdyOUFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBV1VXMFdWNS1PSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhSnc4dURnNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASv5Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=17038c2671b58d2fd6ea98dd3f3e1166ee664dd0" + } + } + } + ] + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "8071104954749355970", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEMKP7OWZ5pSBcBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXBUeEJEQWlsa184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFRbWtta1pXNGVZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFSZ19sR1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=005579c0ff91586a887354409f637a63a1d69031", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHCB7ucMVMCcBm1ywleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=edbfae73be0f41d672298d5c3ec9dd28a5307233&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6CKB6BAAAAwDWAAUBCLWXp_AFEMKP7OWZ5pSBcBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDS7J9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc3MDAyNzcpO3VmKCdyJywgMTQ5NDE5NjAyLCAxNRkf8P2SArkCIXBUeEJEQWlsa184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFRbWtta1pXNGVZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFSZ19sR1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0ac18b64a6c0d58a114085d8b565b4c98de56448" + } + } + } + ] + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "6893555531330982923", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEIuopuO2h7XVXxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIVFqd1R0Z2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFZS1J6NEZQV2V3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASEzUTZnOHc2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF8owB-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f9ddb1066825dfc556d108168ffc0d16cf567ae8", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABELlGlsO9SqXxm1ywleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=db3a0d52f97edd94aa7e4213c437d8e4a5bd16ce&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149414188, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 13.00001, + "cpm_publisher_currency": 13.00001, + "publisher_currency_code": "$", + "brand_category_id": 32, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 29000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEIuopuO2h7XVXxiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFRandUdGdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBWUtSejRGUFdld18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhM1E2Zzh3Nj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASswp9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=917c8192c7dc7e382c0bb7296ab0df261e69f572" + } + } + } + ] + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "5615186251901272031", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "6647218197537074925", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "4707051182303115567", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "4831890668873532085", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "7151522995196673389", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "4077353832159380438", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFENaHwKvS9urKOBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIWJqeHo1UWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZd1VQNVZMNi1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFLZzhBRUE2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAExd2fR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e96d121a0a7d49e05c1d2b4fab2da60d0b544287", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHWA3AltauVOBm1ywleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=8d90e3ce42fe47da19cb85f8fb2d78822c590464&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417669, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 4, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6CKB6BAAAAwDWAAUBCLWXp_AFENaHwKvS9urKOBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc3MDAyNzcpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIWJqeHo1UWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZd1VQNVZMNi1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFLZzhBRUE2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=db30796cc71c3bee3aa8fc2890c75ad7186f9d73" + } + } + } + ] + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "2099457773367093540", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "7214207858308840891", + "nobid": true, + "ad_profile_id": 1182765 + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "4564285281969145467", + "nobid": true, + "ad_profile_id": 1182765 + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/description.md b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/description.md new file mode 100644 index 00000000000..c1781561af5 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/description.md @@ -0,0 +1,40 @@ +Test Page - 'integrationExamples/longform/basic_wo_requireExactDuration.html' +Test Spec File - 'test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'sample-code', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: false + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 15394006 + } + } + ] +}]; +``` + +SetConfig to use with AdUnit: +``` +pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + }, + adpod: { + brandCategoryExclusion: true + } +}); +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/request.json b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/request.json new file mode 100644 index 00000000000..f2f20700ffe --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/request.json @@ -0,0 +1,137 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + }, + { + "sizes": [ + { + "width": 640, + "height": 480 + } + ], + "primary_size": { + "width": 640, + "height": 480 + }, + "ad_types": [ + "video" + ], + "id": 15394006, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 7, + "require_asset_url": true, + "video": { + "maxduration": 30 + } + } + ], + "user": {}, + "brand_category_uniqueness": true + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/response.json b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/response.json new file mode 100644 index 00000000000..5f2118095d4 --- /dev/null +++ b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/response.json @@ -0,0 +1,224 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "2704229116537156015", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEK_j3NPcwdbDJRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXpUczJvQWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFURVBwVy1oVE9ZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0BBRHdQdy4umgKJASFVQV9qSDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UTVRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAZWQU8D_SBQkJBQt8AAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYBITAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=64565aadf65d370e9730e9ce82c93c9bd2fcfc14", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGvMXfKDVqHJRm1ywleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=3b1f10f67b3253e38770fff694edbe6052795602&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149417951, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 33, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEK_j3NPcwdbDJRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF6VHMyb0FpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVEVQcFctaFRPWV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNAQUR3UHcuLpoCiQEhVUFfakg6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ52gQCCAHgBADwBN_fn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=5316c3262f36e4d89735b1ba252c64651a84f479" + } + } + } + ] + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "7987581685263122854", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEKaDmaSQ5-Xsbhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIU16MXpZd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYLVkxZU5tY3VRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFVUTgySFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=17f2a3f5e78c188cc6ca23e677ced305198a8a05", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGmQYYEOZfZbhm1ywleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=28e8f96efdfb9bc1e33e4d087ff5ed992e4692b1&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149419602, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 24, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEKaDmaSQ5-Xsbhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFNejF6WXdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWC1ZMWVObWN1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhVVE4MkhRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=89d4586d9597cd2f9a4a918d1e6985aee45ade01" + } + } + } + ] + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "653115326806257319", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEKfdmd3enZWICRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCITlEd0hNZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjTnlESmJxeS13XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFKZ192RFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=1928a9daadbd431792adace7620880dda961eefb", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABGnbqbr7VQQCRm1ywleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=7617d08e0c16fe1dea8ec80cd6bf73ec0a736b41&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418671, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 30, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEKfdmd3enZWICRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiE5RHdITWdpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY055REpicXktd18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhSmdfdkRRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ASv5Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0d1d3f42fa225995a2f57ab84877dce3d24e9901" + } + } + } + ] + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "866435845408148233", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEImW35H52YyDDBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIXJEenNfZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjMmZTZ1BpMi1BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFfdzRiQUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=83f65f38b4fd56344b3aceb70df7bac1b9b5f229", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABEJyzeSzzIGDBm1ywleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=9130c13cca7a1d3eb05c2b96585ccfdc2faa6844&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418123, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 12, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 15000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEImW35H52YyDDBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFyRHpzX2dpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYzJmU2dQaTItQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhX3c0YkFBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=1f88d8b0a467d528291f90a54fd810b8fdac4488" + } + } + } + ] + }, + { + "uuid": "2022b6b1fcf477", + "tag_id": 15394006, + "auction_id": "1540903203561034860", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEOyokYzL6ZixFRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIXdUekVId2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaeE00NUxjRXVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFQUThhRmc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a4de0e4084ce04a5cb2d347c07fde867aa9ff5c1", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "video", + "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABFsVISxTGNiFRm1ywleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=cf600d825cec85f83c06119e5e383f8548b469a2&event_type=1", + "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 149418948, + "media_type_id": 4, + "media_subtype_id": 64, + "cpm": 15.00001, + "cpm_publisher_currency": 15.00001, + "publisher_currency_code": "$", + "brand_category_id": 1, + "client_initiated_ad_counting": true, + "rtb": { + "video": { + "player_width": 640, + "player_height": 480, + "duration_ms": 30000, + "playback_methods": [ + "auto_play_sound_on" + ], + "frameworks": [ + "vpaid_1_0", + "vpaid_2_0" + ], + "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEOyokYzL6ZixFRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiF3VHpFSHdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWnhNNDVMY0V1TV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhUFE4YUZnNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=17c466ea45d5d4beff02aa2b0eb87bc6c4d5aff3" + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/modules/description.md b/test/fake-server/fixtures/modules/description.md new file mode 100644 index 00000000000..db13453b8aa --- /dev/null +++ b/test/fake-server/fixtures/modules/description.md @@ -0,0 +1,68 @@ +Test Pages: + - 'test/pages/bidderSettings.html' + - 'test/pages/consent_mgt_gdpr.html' + - 'test/pages/currency.html' + - 'test/pages/priceGranularity.html' + - 'test/pages/sizeConfig.html' + - 'test/pages/userSync.html' +Test Spec Files: + - 'test/spec/e2e/modules/e2e_bidderSettings.spec.js' + - 'test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js' + - 'test/spec/e2e/modules/e2e_currency.spec.js' + - 'test/spec/e2e/modules/e2e_priceGranularity.spec.js' + - 'test/spec/e2e/modules/e2e_sizeConfig.spec.js' + - 'test/spec/e2e/modules/e2e_userSync.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'div-gpt-ad-1460505748561-0', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + } + }, + // Replace this object to test a new Adapter! + bids: [{ + bidder: 'appnexus', + params: { + placementId: 13144370 + } + }] + +}, { + code: '/19968336/prebid_native_example_2', + sizes: [ + [1, 1] + ], + mediaTypes: { + native: { + title: { + required: true + }, + body: { + required: true + }, + image: { + required: true + }, + sponsoredBy: { + required: true + }, + icon: { + required: false + }, + } + }, + bids: [{ + bidder: 'appnexus', + params: { + placementId: 13232354, + allowSmallerSizes: true + } + }] +}]; +``` + +Refer to individual test pages to see the proper setConfigs for each test. diff --git a/test/fake-server/fixtures/modules/request.json b/test/fake-server/fixtures/modules/request.json new file mode 100644 index 00000000000..35dd6e2d499 --- /dev/null +++ b/test/fake-server/fixtures/modules/request.json @@ -0,0 +1,74 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 300, + "height": 250 + }, + { + "width": 300, + "height": 600 + } + ], + "primary_size": { + "width": 300, + "height": 250 + }, + "ad_types": [ + "banner" + ], + "id": 13144370, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 1 + }, + { + "sizes": [ + { + "width": 1, + "height": 1 + } + ], + "ad_types": [ + "native" + ], + "id": 13232354, + "allow_smaller_sizes": true, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "native": { + "layouts": [ + { + "title": { + "required": true + }, + "description": { + "required": true + }, + "main_image": { + "required": true + }, + "sponsored_by": { + "required": true + }, + "icon": { + "required": false + } + } + ] + }, + "hb_source": 1 + } + ], + "user": {} + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/modules/response.json b/test/fake-server/fixtures/modules/response.json new file mode 100644 index 00000000000..9b708fa1534 --- /dev/null +++ b/test/fake-server/fixtures/modules/response.json @@ -0,0 +1,106 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "tag_id": 13144370, + "auction_id": "4842409943576641356", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QK7CKA7BAAAAwDWAAUBCNvV-_AFEMz-0f3_xeyZQxjCs_b6q5D9_0oqNgkAAAkCABEJBywAABkAAACA61HgPyEREgApEQkAMREb8GkwsqKiBjjtSEDtSEgAUABYnPFbYABotc95eACAAQGKAQCSAQNVU0SYAawCoAHYBKgBAbABALgBAcABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3OTA4NDUwNyk7AR0scicsIDk4NDkzNTgxNh4A8NCSArUCIVpqeldtZ2l1c0s0S0VJM0oteTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlNSUdhQUJ3RG5qd0U0QUJUSWdCOEJPUUFRQ1lBUUNnQVFHb0FRT3dBUUM1QVNtTGlJTUFBT0Ffd1FFcGk0aURBQURnUDhrQmxiMDhGYV9INERfWkFRQUFBQUFBQVBBXzRBRUE5UUVBQUFBQW1BSUFvQUlBdFFJQUFBQUF2UUlBQUFBQTRBSUE2QUlBLUFJQWdBTUJtQU1CcUFPdQHEiHVnTUpVMGxPTXpvME56TTE0QU80R1lnRUFKQUVBSmdFQWNFCV0FAQhESkIFCAkBGDJBUUE4UVEJDQEBLFBnRUFJZ0ZfeVNwQhEXNFBBX5oCiQEhblE4cUxBNjkBJG5QRmJJQVFvQUQRZBBEZ1B6bzKRABBRTGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJLDTpIdGVzdC5sb2NhbGhvc3Q6OTk5OQUUWC9wYWdlcy9tb2R1bGVzL2N1cnJlbmN5BUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbDwXpgEAKIECzEwLjc1Ljc0LjY5qATikAGyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8ASNyfsuiAUBmAUAoAX_____BQMYAcAFAMkFAAUBFPA_0gUJCQULfAAAANgFAeAFAfAFmfQh-gUECAAQAJAGAJgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=16a5ea7c8d5eb050a368495961803753dd6086c2", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "banner", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 98493581, + "media_type_id": 1, + "media_subtype_id": 1, + "cpm": 0.5, + "cpm_publisher_currency": 0.5, + "publisher_currency_code": "$", + "brand_category_id": 53, + "client_initiated_ad_counting": true, + "rtb": { + "banner": { + "content": "
", + "width": 300, + "height": 600 + }, + "trackers": [ + { + "impression_urls": [ + "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLDCKBDBAAAAwDWAAUBCNvV-_AFEMz-0f3_xeyZQxjCs_b6q5D9_0oqNgkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJADERG6gwsqKiBjjtSEDtSEgCUI3J-y5YnPFbYABotc95eJ64BYABAYoBA1VTRJIBAQbwUpgBrAKgAdgEqAEBsAEAuAEBwAEEyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5MDg0NTA3KTt1ZigncicsIDk4NDkzNTgxNh4A8NCSArUCIVpqeldtZ2l1c0s0S0VJM0oteTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlNSUdhQUJ3RG5qd0U0QUJUSWdCOEJPUUFRQ1lBUUNnQVFHb0FRT3dBUUM1QVNtTGlJTUFBT0Ffd1FFcGk0aURBQURnUDhrQmxiMDhGYV9INERfWkFRQUFBQUFBQVBBXzRBRUE5UUVBQUFBQW1BSUFvQUlBdFFJQUFBQUF2UUlBQUFBQTRBSUE2QUlBLUFJQWdBTUJtQU1CcUFPdQHEiHVnTUpVMGxPTXpvME56TTE0QU80R1lnRUFKQUVBSmdFQWNFCV0FAQhESkIFCAkBGDJBUUE4UVEJDQEBLFBnRUFJZ0ZfeVNwQhEXNFBBX5oCiQEhblE4cUxBNjkBJG5QRmJJQVFvQUQRZBBEZ1B6bzKRABBRTGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJLDTpIdGVzdC5sb2NhbGhvc3Q6OTk5OQUUWC9wYWdlcy9tb2R1bGVzL2N1cnJlbmN5BUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbDwXpgEAKIECzEwLjc1Ljc0LjY5qATikAGyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQB8ASNyfsuiAUBmAUAoAX_____BQMYAcAFAMkFAAUBFPA_0gUJCQULfAAAANgFAeAFAfAFmfQh-gUECAAQAJAGAJgGALgGAMEGASEwAADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=9c378bb4ca21a7509f69955fb4e6fe72035190c6" + ], + "video_events": {} + } + ] + } + } + ] + }, + { + "tag_id": 13232354, + "auction_id": "8100967561168057198", + "nobid": false, + "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKECKAEBAAAAwDWAAUBCNvV-_AFEO7mieO34pq2cBjCs_b6q5D9_0oqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5MDg0NTA3KTsBHSxyJywgOTc0OTQyMDQ2HgDwmpICtQIhMVR6c3lRajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWU1JR2FBQndBSGdBZ0FGTWlBSHdFNUFCQUpnQkFLQUJBYWdCQTdBQkFMa0I4NjFxcEFBQUpFREJBZk90YXFRQUFDUkF5UUc5QzZTMEtFampQOWtCQUFBQUFBQUE4RF9nQVFEMUFRAQ8sQ1lBZ0NnQWdDMUFnBRAAOQkI8EBEZ0FnRG9BZ0Q0QWdDQUF3R1lBd0dvQV96NHZBcTZBd2xUU1U0ek9qUTNNelhnQTdnWmlBUUFrQVFBbUFRQndRUQFNCQEITWtFCQkBARhEWUJBRHhCAQsNASwtQVFBaUFYX0pLa0YNEzxBOEQ4LpoCiQEhZUE4dE1BNjkBJG5QRmJJQVFvQUQVWFhrUURvSlUwbE9Nem8wTnpNMVFMZ1pTUQ1PDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gJLaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPDXL3BhZ2VzL21vZHVsZXMvY3VycmVuY3kuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagE4pABsgQOCAAQARgAIAAoADAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8AS8yb4uiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaVZ0ANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=428486554947609aac96ed5569d9bb2dd2be5502", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "native", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 97494204, + "media_type_id": 12, + "media_subtype_id": 65, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 53, + "client_initiated_ad_counting": true, + "viewability": { + "config": "" + }, + "rtb": { + "native": { + "title": "This is a Prebid Native Creative", + "desc": "This is a Prebid Native Creative. There are many like it, but this one is mine.", + "sponsored": "Prebid.org", + "icon": { + "url": "http://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png", + "width": 127, + "height": 83, + "prevent_crop": false + }, + "main_img": { + "url": "http://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg", + "width": 989, + "height": 742, + "prevent_crop": false + }, + "link": { + "url": "http://prebid.org/dev-docs/show-native-ads.html", + "click_trackers": [ + "http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQG5zYnwTa2xwwpldv4L0_0rb6h5eAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAYBc26wAAAAA./bcr=AAAAAAAA8D8=/cnd=%21eA8tMAj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzM1QLgZSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3MzU=/bn=89118/" + ] + }, + "impression_trackers": [ + "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKMCKAMBAAAAwDWAAUBCNvV-_AFEO7mieO34pq2cBjCs_b6q5D9_0oqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXieuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzkwODQ1MDcpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPCakgK1AiExVHpzeVFqOC1Md0tFTHpKdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZTUlHYUFCd0FIZ0FnQUZNaUFId0U1QUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRRzlDNlMwS0VqalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BX3o0dkFxNkF3bFRTVTR6T2pRM016WGdBN2daaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhfSktrRg0TPEE4RDgumgKJASFlQTh0TUE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBOek0xUUxnWlNRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDKBlQUEu2AIA4AKtmEjqAktodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OQUU8NcvcGFnZXMvbW9kdWxlcy9jdXJyZW5jeS5odG1sP3BianNfZGVidWc9dHJ1ZYADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATikAGyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBAHwBLzJvi6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQBpXnQA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYJJCjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=d6c58ebc137658c5dd258579c2575ad499e7a7b4" + ], + "id": 97494204 + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/description.md b/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/description.md new file mode 100644 index 00000000000..c5b114e8bb3 --- /dev/null +++ b/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/description.md @@ -0,0 +1,43 @@ +Test Page - 'test/pages/multiple_bidders.html' +Test Spec File - 'test/spec/e2e/multi-bidder/e2e_multiple_bidders.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'div-banner-native-1', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]] + } + }, + bids: [{ + bidder: 'appnexus', + params: { + placementId: 13232392, + } + }] +}, +{ + code: 'div-banner-native-2', + mediaTypes: { + native: { + title: { + required: true + }, + image: { + required: true + }, + sponsoredBy: { + required: true + } + } + }, + bids: [{ + bidder: 'adasta', + params: { + placementId: 13232392, + } + }] +}]; +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/request.json b/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/request.json new file mode 100644 index 00000000000..c4c862adc20 --- /dev/null +++ b/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/request.json @@ -0,0 +1,43 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 1, + "height": 1 + } + ], + "ad_types": [ + "native" + ], + "id": 13232392, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "native": { + "layouts": [ + { + "title": { + "required": true + }, + "main_image": { + "required": true + }, + "sponsored_by": { + "required": true + } + } + ] + }, + "hb_source": 1 + } + ], + "user": {} + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/response.json b/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/response.json new file mode 100644 index 00000000000..56894e97e05 --- /dev/null +++ b/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/response.json @@ -0,0 +1,59 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "tag_id": 13232392, + "auction_id": "6287559286677633407", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKICKAIBAAAAwDWAAUBCM3FpfEFEP_yg9W7u_mgVxi7_-bKzp3kuD8qNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIjSpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5NzcwNTczKTsBHSxyJywgOTc1MjA0MzQ2HgDw0JICtQIhQWp4NUh3aUgtYndLRUxLV3dDNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUWlOS25CbGdBWUtzR2FBQndBbmlLQVlBQkhvZ0JpZ0dRQVFDWUFRQ2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCb2FZc1BwVDM0VF9aQVFBQUFBQUFBUEFfNEFFQTlRRUFBQUFBbUFJQW9BSUF0UUlBQUFBQXZRSUFBQUFBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQU9IAcSIdWdNSlUwbE9Nem8wT0RRMDRBUDRHWWdFQUpBRUFKZ0VBY0UJXQUBCERKQgUICQEYMkFRQThRUQkNAQEsUGdFQUlnRjdDV3BCERc0UEFfmgKJASFDZy1TX2c2OQEkblBGYklBUW9BRBVkDGtRRG8ykQAQUVBnWlMdTQBVEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCS2h0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTw3i9wYWdlcy9tdWx0aXBsZV9iaWRkZXJzLmh0bWw_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQOMTAzLjc5LjEwMC4xODCoBOZCsgQQCAQQARgAIAAoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODQ02gQCCADgBAHwBLKWwC6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAABDnDYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgEhMAAA8L_QBvUv2gYWChAJERkBUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=8b14b952b73092945ef66436be991786b53f7a68", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "native", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 97520434, + "media_type_id": 12, + "media_subtype_id": 65, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 53, + "client_initiated_ad_counting": true, + "viewability": { + "config": "" + }, + "rtb": { + "native": { + "title": "This is a Prebid Native Creative", + "sponsored": "Prebid.org", + "main_img": { + "url": "https://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg", + "width": 989, + "height": 742, + "prevent_crop": false + }, + "link": { + "url": "http://prebid.org/dev-docs/show-multi-format-ads.html", + "click_trackers": [ + "https://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQH_5oLrb5UFXu79Z6eyQcT_NYileAAAAAAjpyQBtJAAAbSQAAAIAAAAyC9AFnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAnRbC8wAAAAA./bcr=AAAAAAAA8D8=/cnd=%21Cg-S_giH-bwKELKWwC4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0ODQ0QPgZSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ4NDQ=/bn=89112/" + ] + }, + "impression_trackers": [ + "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKQCKAQBAAAAwDWAAUBCM3FpfEFEP_yg9W7u_mgVxi7_-bKzp3kuD8qNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIjSpwY47UhA7UhIAlCylsAuWJzxW2AAaM26dXiYuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1Nzk3NzA1NzMpO3VmKCdyJywgOTc1MjA0MzQsIC4eAPDQkgK1AiFBang1SHdpSC1id0tFTEtXd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRaU5LbkJsZ0FZS3NHYUFCd0FuaUtBWUFCSG9nQmlnR1FBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JvYVlzUHBUMzRUX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBT0gBxIh1Z01KVTBsT016bzBPRFEwNEFQNEdZZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BASxQZ0VBSWdGN0NXcEIRFzRQQV-aAokBIUNnLVNfZzY5ASRuUEZiSUFRb0FEFWQMa1FEbzKRABBRUGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gJLaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPDeL3BhZ2VzL211bHRpcGxlX2JpZGRlcnMuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA4xMDMuNzkuMTAwLjE4MKgE5kKyBBAIBBABGAAgACgBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4NDTaBAIIAeAEAfAEspbALogFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAEOcNgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGASEwAADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=2061bd85ce022a41bc16ebb20c193aabbbc07809" + ], + "id": 97520434 + } + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/description.md b/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/description.md new file mode 100644 index 00000000000..c5b114e8bb3 --- /dev/null +++ b/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/description.md @@ -0,0 +1,43 @@ +Test Page - 'test/pages/multiple_bidders.html' +Test Spec File - 'test/spec/e2e/multi-bidder/e2e_multiple_bidders.spec.js' + +Ad Unit that generates given 'Request' - 'Response' pairs. + +```(javascript) +[{ + code: 'div-banner-native-1', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]] + } + }, + bids: [{ + bidder: 'appnexus', + params: { + placementId: 13232392, + } + }] +}, +{ + code: 'div-banner-native-2', + mediaTypes: { + native: { + title: { + required: true + }, + image: { + required: true + }, + sponsoredBy: { + required: true + } + } + }, + bids: [{ + bidder: 'adasta', + params: { + placementId: 13232392, + } + }] +}]; +``` \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/request.json b/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/request.json new file mode 100644 index 00000000000..8399bed631c --- /dev/null +++ b/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/request.json @@ -0,0 +1,36 @@ +{ + "httpRequest": { + "method": "POST", + "path": "/", + "body": { + "tags": [ + { + "sizes": [ + { + "width": 300, + "height": 250 + }, + { + "width": 300, + "height": 600 + } + ], + "primary_size": { + "width": 300, + "height": 250 + }, + "ad_types": [ + "banner" + ], + "id": 13232392, + "allow_smaller_sizes": false, + "use_pmt_rule": false, + "prebid": true, + "disable_psa": true, + "hb_source": 1 + } + ], + "user": {} + } + } +} \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/response.json b/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/response.json new file mode 100644 index 00000000000..54ad643b82d --- /dev/null +++ b/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/response.json @@ -0,0 +1,49 @@ +{ + "httpResponse": { + "body": { + "version": "3.0.0", + "tags": [ + { + "tag_id": 13232392, + "auction_id": "6917498423334366136", + "nobid": false, + "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLBCKBBBAAAAwDWAAUBCNGcpvEFELjXrYmmhfn_Xxi7_-bKzp3kuD8qNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQn0gQEkQDCI0qcGOO1IQO1ISABQAFic8VtgAGjNunV4AIABAYoBAJIBA1VTRJgBrAKgAfoBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5NzgxNzEzKTt1ZigncicsIDk2ODQ2MDM1LCAxNTc5NzgxNzEzKTuSArUCITZEb2NyZ2lILWJ3S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFpTktuQmxnQVlLc0dhQUJ3R25oaWdBR1lBWWdCWXBBQkFKZ0JBS0FCQWFnQkE3QUJBTGtCODYxcXBBQUFKRURCQWZPdGFxUUFBQ1JBeVFHQ1VBT2x6Q0xkUDlrQkFBQUFBQUFBOERfZ0FRRDFBUUFBQUFDWUFnQ2dBZ0MxQWdBQUFBQzlBZ0FBQUFEZ0FnRG9BZ0Q0QWdDQUF3R1lBd0dvQTRmNXZBcTZBd2xUU1U0ek9qUTNNem5nQV9nWmlBUUFrQVFBbUFRQndRUQFNCQEITWtFCQkBARhEWUJBRHhCAQsNASwtQVFBaUFXREpha0YNE0BBOEQ4LpoCiQEhOEE1YjlRaTI5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME56TTVRUGdaU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EZlQUEuwgI1aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1tdWx0aS1mb3JtYXQtYWRzLmh0bWzYAgDgAq2YSOoCSw1ASHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvBUYocGxlX2JpZGRlcnMFRvBAP3BianNfZGVidWc9dHJ1ZYADAIgDAZADAJgDF6ADAaoDAMADrALIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMNtvBhmAQAogQOMTAzLjc5LjEwMC4xODCoBJ9EsgQSCAQQARisAiD6ASgBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MznaBAIIAOAEAfAE04GXLogFAZgFAKAF______8BAxQBwAUAyQVpiBTwP9IFCQkJDHAAANgFAeAFAfAFAfoFBAgAEACQBgCYBgC4BgDBBgkjKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYB8gYCCACABwGIBwCgBwE.&s=8d42ac30ca2d2a8a63215f5aba2a43bd23af0023", + "timeout_ms": 0, + "ad_profile_id": 1182765, + "rtb_video_fallback": false, + "ads": [ + { + "content_source": "rtb", + "ad_type": "banner", + "buyer_member_id": 9325, + "advertiser_id": 2529885, + "creative_id": 96846035, + "media_type_id": 1, + "media_subtype_id": 1, + "cpm": 10, + "cpm_publisher_currency": 10, + "publisher_currency_code": "$", + "brand_category_id": 0, + "client_initiated_ad_counting": true, + "rtb": { + "banner": { + "content": "
", + "width": 300, + "height": 250 + }, + "trackers": [ + { + "impression_urls": [ + "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLJCKBJBAAAAwDWAAUBCNGcpvEFELjXrYmmhfn_Xxi7_-bKzp3kuD8qNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIjSpwY47UhA7UhIAlDTgZcuWJzxW2AAaM26dXicuAWAAQGKAQNVU0SSAQEG8FKYAawCoAH6AagBAbABALgBAcABBMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3OTc4MTcxMyk7dWYoJ3InLCA5Njg0NjAzNTYeAPCakgK1AiE2RG9jcmdpSC1id0tFTk9CbHk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRaU5LbkJsZ0FZS3NHYUFCd0duaGlnQUdZQVlnQllwQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRR0NVQU9sekNMZFA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BNGY1dkFxNkF3bFRTVTR6T2pRM016bmdBX2daaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVdESmFrRg0TPEE4RDgumgKJASE4QTViOVE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBOek01UVBnWlNRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBGZUFBLsICNWh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctbXVsdGktZm9ybWF0LWFkcy5odG1s2AIA4AKtmEjqAksNQEh0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLwVGKHBsZV9iaWRkZXJzBUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbbwYZgEAKIEDjEwMy43OS4xMDAuMTgwqASfRLIEEggEEAEYrAIg-gEoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM52gQCCAHgBAHwBNOBly6IBQGYBQCgBf______AQMUAcAFAMkFaZAU8D_SBQkJCQxwAADYBQHgBQHwBQH6BQQIABAAkAYAmAYAuAYAwQYJIyjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=6c6fb8a005b60bc5535b528c16ed74cd66c08dd0" + ], + "video_events": {} + } + ] + } + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/test/fake-server/index.js b/test/fake-server/index.js new file mode 100644 index 00000000000..752648c6746 --- /dev/null +++ b/test/fake-server/index.js @@ -0,0 +1,37 @@ +/* eslint-disable no-console */ + +const express = require('express'); +const morgan = require('morgan'); +const bodyParser = require('body-parser'); +const argv = require('yargs').argv; +const fakeResponder = require('./fake-responder.js'); + +const PORT = argv.port || '3000'; + +// Initialize express app +const app = express(); + +// Middlewares +app.use(bodyParser.urlencoded({ extended: false })); +app.use(bodyParser.json()); +app.use(bodyParser.text({ type: 'text/plain' })); +app.use(morgan('dev')); // used to log incoming requests + +// Allow Cross Origin request from 'test.localhost:9999' +app.use(function(req, res, next) { + res.header('Access-Control-Allow-Origin', req.headers.origin); + res.header('Access-Control-Allow-Credentials', true); + next(); +}); + +app.post('/', fakeResponder, (req, res) => { + res.send(); +}); + +app.use((req, res) => { + res.status(404).send('Not Found'); +}); + +app.listen(PORT, () => { + console.log(`fake-server listening on http://localhost:${PORT}`); +}); diff --git a/test/helpers/testing-utils.js b/test/helpers/testing-utils.js index 21d5992873e..76e2b652a79 100644 --- a/test/helpers/testing-utils.js +++ b/test/helpers/testing-utils.js @@ -1,4 +1,13 @@ +/* eslint-disable no-console */ module.exports = { host: (process.env.TEST_SERVER_HOST) ? process.env.TEST_SERVER_HOST : 'localhost', - protocol: (process.env.TEST_SERVER_PROTOCOL) ? 'https' : 'http' + protocol: (process.env.TEST_SERVER_PROTOCOL) ? 'https' : 'http', + waitForElement: function(elementRef, time = 2000) { + let element = $(elementRef); + element.waitForExist({timeout: time}); + }, + switchFrame: function(frameRef, frameName) { + let iframe = $(frameRef); + browser.switchToFrame(iframe); + } } diff --git a/test/mock-server/expectations/request-response-pairs/banner/index.js b/test/mock-server/expectations/request-response-pairs/banner/index.js deleted file mode 100644 index b34af63cc45..00000000000 --- a/test/mock-server/expectations/request-response-pairs/banner/index.js +++ /dev/null @@ -1,97 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - * The expecation created here is replicating trafficSourceCode example in Prebid. - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 300, - 'height': 250 - }, { - 'width': 300, - 'height': 600 - }], - 'primary_size': { - 'width': 300, - 'height': 250 - }, - 'ad_types': ['banner'], - 'id': 13144370, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'hb_source': 1 - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '2c8c83a1deaf1a', - 'tag_id': 13144370, - 'auction_id': '8147841645883553832', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fhello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKzCKAzBAAAAwDWAAUBCJKPpe4FEKjwl-js2byJcRiq5MnUovf28WEqNgkAAAkCABEJBywAABkAAACA61HgPyEREgApEQkAMREb8GkwsqKiBjjtSEDtSEgAUABYnPFbYABotc95eACAAQGKAQCSAQNVU0SYAawCoAH6AagBAbABALgBAcABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3MzQ3MjE0Nik7AR0scicsIDk2ODQ2MDM1Nh4A8PWSAqUCIXp6ZmhVQWl1c0s0S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlJSUNhQUJ3Q0hncWdBRWtpQUVxa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUVwaTRpREFBRGdQOEVCS1l1SWd3QUE0RF9KQVozRkl5WjA1Tm9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pOZUFEcUJXSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkEg0QkFDSUJmOGuaAokBIUl3OTBCOikBJG5QRmJJQVFvQUQROFhEZ1B6b0pVMGxPTXpvME56TTFRS2dWUxFoDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJTDTrYdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9oZWxsb193b3JsZAVO8EA_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAOsAsgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw248F6YBACiBAsxMC43NS43NC42OagEkECyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8ATTgZcuiAUBmAUAoAX______wEDFAHABQDJBWmAFPA_0gUJCQkMcAAA2AUB4AUB8AUB-gUECAAQAJAGAJgGALgGAMEGCSM08L_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgHyBgIIAIAHAYgHAKAHAQ..&s=68cfb6ed042ea47f5d3fc2c32cc068500e542066', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'banner', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 96846035, - 'media_type_id': 1, - 'media_subtype_id': 1, - 'cpm': 0.500000, - 'cpm_publisher_currency': 0.500000, - 'is_bin_price_applied': false, - 'publisher_currency_code': '$', - 'brand_category_id': 0, - 'client_initiated_ad_counting': true, - 'rtb': { - 'banner': { - 'content': "
", - 'width': 300, - 'height': 250 - }, - 'trackers': [{ - 'impression_urls': ['http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fhello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QK7CKA7BAAAAwDWAAUBCJKPpe4FEKjwl-js2byJcRiq5MnUovf28WEqNgkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJADERG6gwsqKiBjjtSEDtSEgCUNOBly5YnPFbYABotc95eJK4BYABAYoBA1VTRJIBAQbwUpgBrAKgAfoBqAEBsAEAuAEBwAEEyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTczNDcyMTQ2KTt1ZigncicsIDk2ODQ2MDM1Nh4A8PWSAqUCIXp6ZmhVQWl1c0s0S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlJSUNhQUJ3Q0hncWdBRWtpQUVxa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUVwaTRpREFBRGdQOEVCS1l1SWd3QUE0RF9KQVozRkl5WjA1Tm9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pOZUFEcUJXSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkEg0QkFDSUJmOGuaAokBIUl3OTBCOikBJG5QRmJJQVFvQUQROFhEZ1B6b0pVMGxPTXpvME56TTFRS2dWUxFoDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJTDTrYdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9oZWxsb193b3JsZAVO8EA_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAOsAsgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw248F6YBACiBAsxMC43NS43NC42OagEkECyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQB8ATTgZcuiAUBmAUAoAX______wEDFAHABQDJBWmIFPA_0gUJCQkMcAAA2AUB4AUB8AUB-gUECAAQAJAGAJgGALgGAMEGCSM08D_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgHyBgIIAIAHAYgHAKAHAQ..&s=951a029669a69e3f0c527c937c2d852be92802e1'], - 'video_events': {} - }] - } - }] - }] - }, - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/currency/index.js b/test/mock-server/expectations/request-response-pairs/currency/index.js deleted file mode 100644 index d9bdc5af737..00000000000 --- a/test/mock-server/expectations/request-response-pairs/currency/index.js +++ /dev/null @@ -1,177 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 300, - 'height': 250 - }, { - 'width': 300, - 'height': 600 - }], - 'primary_size': { - 'width': 300, - 'height': 250 - }, - 'ad_types': ['banner'], - 'id': 13144370, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'hb_source': 1 - }, { - 'sizes': [{ - 'width': 1, - 'height': 1 - }], - 'ad_types': ['native'], - 'id': 13232354, - 'allow_smaller_sizes': true, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'native': { - 'layouts': [{ - 'title': { - 'required': true - }, - 'description': { - 'required': true - }, - 'main_image': { - 'required': true - }, - 'sponsored_by': { - 'required': true - }, - 'icon': { - 'required': false - } - }] - }, - 'hb_source': 1 - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '232f6ceccb3749', - 'tag_id': 13144370, - 'auction_id': '4842409943576641356', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QK7CKA7BAAAAwDWAAUBCNvV-_AFEMz-0f3_xeyZQxjCs_b6q5D9_0oqNgkAAAkCABEJBywAABkAAACA61HgPyEREgApEQkAMREb8GkwsqKiBjjtSEDtSEgAUABYnPFbYABotc95eACAAQGKAQCSAQNVU0SYAawCoAHYBKgBAbABALgBAcABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3OTA4NDUwNyk7AR0scicsIDk4NDkzNTgxNh4A8NCSArUCIVpqeldtZ2l1c0s0S0VJM0oteTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlNSUdhQUJ3RG5qd0U0QUJUSWdCOEJPUUFRQ1lBUUNnQVFHb0FRT3dBUUM1QVNtTGlJTUFBT0Ffd1FFcGk0aURBQURnUDhrQmxiMDhGYV9INERfWkFRQUFBQUFBQVBBXzRBRUE5UUVBQUFBQW1BSUFvQUlBdFFJQUFBQUF2UUlBQUFBQTRBSUE2QUlBLUFJQWdBTUJtQU1CcUFPdQHEiHVnTUpVMGxPTXpvME56TTE0QU80R1lnRUFKQUVBSmdFQWNFCV0FAQhESkIFCAkBGDJBUUE4UVEJDQEBLFBnRUFJZ0ZfeVNwQhEXNFBBX5oCiQEhblE4cUxBNjkBJG5QRmJJQVFvQUQRZBBEZ1B6bzKRABBRTGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJLDTpIdGVzdC5sb2NhbGhvc3Q6OTk5OQUUWC9wYWdlcy9tb2R1bGVzL2N1cnJlbmN5BUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbDwXpgEAKIECzEwLjc1Ljc0LjY5qATikAGyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8ASNyfsuiAUBmAUAoAX_____BQMYAcAFAMkFAAUBFPA_0gUJCQULfAAAANgFAeAFAfAFmfQh-gUECAAQAJAGAJgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=16a5ea7c8d5eb050a368495961803753dd6086c2', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'banner', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 98493581, - 'media_type_id': 1, - 'media_subtype_id': 1, - 'cpm': 0.500000, - 'cpm_publisher_currency': 0.500000, - 'publisher_currency_code': '$', - 'brand_category_id': 53, - 'client_initiated_ad_counting': true, - 'rtb': { - 'banner': { - 'content': "
", - 'width': 300, - 'height': 600 - }, - 'trackers': [{ - 'impression_urls': ['http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLDCKBDBAAAAwDWAAUBCNvV-_AFEMz-0f3_xeyZQxjCs_b6q5D9_0oqNgkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJADERG6gwsqKiBjjtSEDtSEgCUI3J-y5YnPFbYABotc95eJ64BYABAYoBA1VTRJIBAQbwUpgBrAKgAdgEqAEBsAEAuAEBwAEEyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5MDg0NTA3KTt1ZigncicsIDk4NDkzNTgxNh4A8NCSArUCIVpqeldtZ2l1c0s0S0VJM0oteTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlNSUdhQUJ3RG5qd0U0QUJUSWdCOEJPUUFRQ1lBUUNnQVFHb0FRT3dBUUM1QVNtTGlJTUFBT0Ffd1FFcGk0aURBQURnUDhrQmxiMDhGYV9INERfWkFRQUFBQUFBQVBBXzRBRUE5UUVBQUFBQW1BSUFvQUlBdFFJQUFBQUF2UUlBQUFBQTRBSUE2QUlBLUFJQWdBTUJtQU1CcUFPdQHEiHVnTUpVMGxPTXpvME56TTE0QU80R1lnRUFKQUVBSmdFQWNFCV0FAQhESkIFCAkBGDJBUUE4UVEJDQEBLFBnRUFJZ0ZfeVNwQhEXNFBBX5oCiQEhblE4cUxBNjkBJG5QRmJJQVFvQUQRZBBEZ1B6bzKRABBRTGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJLDTpIdGVzdC5sb2NhbGhvc3Q6OTk5OQUUWC9wYWdlcy9tb2R1bGVzL2N1cnJlbmN5BUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbDwXpgEAKIECzEwLjc1Ljc0LjY5qATikAGyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQB8ASNyfsuiAUBmAUAoAX_____BQMYAcAFAMkFAAUBFPA_0gUJCQULfAAAANgFAeAFAfAFmfQh-gUECAAQAJAGAJgGALgGAMEGASEwAADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=9c378bb4ca21a7509f69955fb4e6fe72035190c6'], - 'video_events': {} - }] - } - }] - }, { - 'uuid': '3867e6fdb23eb6', - 'tag_id': 13232354, - 'auction_id': '8100967561168057198', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKECKAEBAAAAwDWAAUBCNvV-_AFEO7mieO34pq2cBjCs_b6q5D9_0oqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5MDg0NTA3KTsBHSxyJywgOTc0OTQyMDQ2HgDwmpICtQIhMVR6c3lRajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWU1JR2FBQndBSGdBZ0FGTWlBSHdFNUFCQUpnQkFLQUJBYWdCQTdBQkFMa0I4NjFxcEFBQUpFREJBZk90YXFRQUFDUkF5UUc5QzZTMEtFampQOWtCQUFBQUFBQUE4RF9nQVFEMUFRAQ8sQ1lBZ0NnQWdDMUFnBRAAOQkI8EBEZ0FnRG9BZ0Q0QWdDQUF3R1lBd0dvQV96NHZBcTZBd2xUU1U0ek9qUTNNelhnQTdnWmlBUUFrQVFBbUFRQndRUQFNCQEITWtFCQkBARhEWUJBRHhCAQsNASwtQVFBaUFYX0pLa0YNEzxBOEQ4LpoCiQEhZUE4dE1BNjkBJG5QRmJJQVFvQUQVWFhrUURvSlUwbE9Nem8wTnpNMVFMZ1pTUQ1PDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gJLaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPDXL3BhZ2VzL21vZHVsZXMvY3VycmVuY3kuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagE4pABsgQOCAAQARgAIAAoADAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8AS8yb4uiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaVZ0ANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=428486554947609aac96ed5569d9bb2dd2be5502', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'native', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 97494204, - 'media_type_id': 12, - 'media_subtype_id': 65, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 53, - 'client_initiated_ad_counting': true, - 'viewability': { - 'config': '' - }, - 'rtb': { - 'native': { - 'title': 'This is a Prebid Native Creative', - 'desc': 'This is a Prebid Native Creative. There are many like it, but this one is mine.', - 'sponsored': 'Prebid.org', - 'icon': { - 'url': 'http://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png', - 'width': 127, - 'height': 83, - 'prevent_crop': false - }, - 'main_img': { - 'url': 'http://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg', - 'width': 989, - 'height': 742, - 'prevent_crop': false - }, - 'link': { - 'url': 'http://prebid.org/dev-docs/show-native-ads.html', - 'click_trackers': ['http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQG5zYnwTa2xwwpldv4L0_0rb6h5eAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAYBc26wAAAAA./bcr=AAAAAAAA8D8=/cnd=%21eA8tMAj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzM1QLgZSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3MzU=/bn=89118/'] - }, - 'impression_trackers': ['http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKMCKAMBAAAAwDWAAUBCNvV-_AFEO7mieO34pq2cBjCs_b6q5D9_0oqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXieuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzkwODQ1MDcpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPCakgK1AiExVHpzeVFqOC1Md0tFTHpKdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZTUlHYUFCd0FIZ0FnQUZNaUFId0U1QUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRRzlDNlMwS0VqalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BX3o0dkFxNkF3bFRTVTR6T2pRM016WGdBN2daaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhfSktrRg0TPEE4RDgumgKJASFlQTh0TUE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBOek0xUUxnWlNRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDKBlQUEu2AIA4AKtmEjqAktodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OQUU8NcvcGFnZXMvbW9kdWxlcy9jdXJyZW5jeS5odG1sP3BianNfZGVidWc9dHJ1ZYADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATikAGyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBAHwBLzJvi6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQBpXnQA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYJJCjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=d6c58ebc137658c5dd258579c2575ad499e7a7b4'], - 'id': 97494204 - } - } - }] - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/gdpr/index.js b/test/mock-server/expectations/request-response-pairs/gdpr/index.js deleted file mode 100644 index aa815820873..00000000000 --- a/test/mock-server/expectations/request-response-pairs/gdpr/index.js +++ /dev/null @@ -1,95 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 300, - 'height': 250 - }, { - 'width': 300, - 'height': 600 - }], - 'primary_size': { - 'width': 300, - 'height': 250 - }, - 'ad_types': ['banner'], - 'id': 13144370, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'hb_source': 1 - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '27c4cea6dfcad4', - 'tag_id': 13144370, - 'auction_id': '6784868202366971885', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fgdpr_hello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QL0CWz0BAAAAwDWAAUBCKKt0fAFEO3ftM_qtayUXhj_EQEQASo2CQANAQARDQgoABkAAACA61HgPyEREgApEQkAMREb8GkwsqKiBjjtSEDtSEgAUABYnPFbYABotc95eACAAQGKAQCSAQNVU0SYAawCoAH6AagBAbABALgBAcABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3ODM5MTIwMik7AR0scicsIDk2ODQ2MDM1Nh4A9A4BkgLJAiF0ajlmS2dpdXNLNEtFTk9CbHk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRc3FLaUJsZ0FZUF9fX184UGFBQndBWGdCZ0FFQmlBRUJrQUVCbUFFQm9BRUJxQUVEc0FFQXVRRXBpNGlEQUFEZ1A4RUJLWXVJZ3dBQTREX0pBZWxBS28zZEV1OF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBTUFDQWNnQ0FkQUNBZGdDQWVBQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pPZUFEX0JpSUJBQ1FCQUNZQkFIQkJBQUFBQQmDCHlRUQkJAQEYTmdFQVBFRQELCQEwRDRCQUNJQllNbHFRVQkTREFEd1B3Li6aAokBIWZnOFhHUTZNASRuUEZiSUFRb0FEEUhYRGdQem9KVTBsT016bzBOek01UVB3WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EBlQUEuwgIvaHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3MvZ2V0dGluZy1zdGFydGVkLmh0bWzYAgDgAq2YSOoCWA068IF0ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvZ3B0L2dkcHJfaGVsbG9fd29ybGQuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwGIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDb3wW5gEAKIECzEwLjc1Ljc0LjY5qAS_NrIEEggEEAQYrAIg-gEoASgCMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM52gQCCADgBAHwBNOBly6IBQGYBQCgBf__bcwUAcAFAMkFaakU8D_SBQkJCQyIAADYBQHgBQHwBQH6BQQIABAAkAYAmAYAsgaWAUJPc3kwUXkBBixYaUFBQUJBRU5DMi0hswh0RjdhJQxfX185AQXwcV9fOXV6X092X3ZfZl9fMzNlOF9fOXZfbF83Xy1fX191Xy0zM2Q0dV8xdmY5OXlmbTEtN2V0cjN0cF84N3VlczJfWHVyX183OV9fM3ozXzlweFA3OGs4OXI3MzM3RXdfdi1fdi1iN0pDT05fQbgGAcEGAAW-KPC_0Ab1L9oGFgoQBRAdAVAQABgA4AYB8gYCCACABwGIBwCgBwE.&s=896d8d25ed5c73ed4b49adebaa58ba23ed6afa43', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'banner', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 96846035, - 'media_type_id': 1, - 'media_subtype_id': 1, - 'cpm': 0.500000, - 'cpm_publisher_currency': 0.500000, - 'publisher_currency_code': '$', - 'brand_category_id': 0, - 'client_initiated_ad_counting': true, - 'rtb': { - 'banner': { - 'content': "
", - 'width': 300, - 'height': 250 - }, - 'trackers': [{ - 'impression_urls': ['http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fgdpr_hello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QL8CWz8BAAAAwDWAAUBCKKt0fAFEO3ftM_qtayUXhj_EQEQASo2CQAFAQjgPxEFCDAA4D8ZAAAAgOtR4D8hERIAKREJADERG6gwsqKiBjjtSEDtSEgCUNOBly5YnPFbYABotc95eMu4BYABAYoBA1VTRJIBAQbwUpgBrAKgAfoBqAEBsAEAuAEBwAEEyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc4MzkxMjAyKTt1ZigncicsIDk2ODQ2MDM1Nh4A9A4BkgLJAiF0ajlmS2dpdXNLNEtFTk9CbHk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRc3FLaUJsZ0FZUF9fX184UGFBQndBWGdCZ0FFQmlBRUJrQUVCbUFFQm9BRUJxQUVEc0FFQXVRRXBpNGlEQUFEZ1A4RUJLWXVJZ3dBQTREX0pBZWxBS28zZEV1OF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBTUFDQWNnQ0FkQUNBZGdDQWVBQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pPZUFEX0JpSUJBQ1FCQUNZQkFIQkJBQUFBQQmDCHlRUQkJAQEYTmdFQVBFRQELCQEwRDRCQUNJQllNbHFRVQkTREFEd1B3Li6aAokBIWZnOFhHUTZNASRuUEZiSUFRb0FEEUhYRGdQem9KVTBsT016bzBOek01UVB3WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EBlQUEuwgIvaHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3MvZ2V0dGluZy1zdGFydGVkLmh0bWzYAgDgAq2YSOoCWA068IF0ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvZ3B0L2dkcHJfaGVsbG9fd29ybGQuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwGIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDb3wW5gEAKIECzEwLjc1Ljc0LjY5qAS_NrIEEggEEAQYrAIg-gEoASgCMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM52gQCCAHgBAHwBNOBly6IBQGYBQCgBf__bdQUAcAFAMkFabEU8D_SBQkJCQyIAADYBQHgBQHwBQH6BQQIABAAkAYAmAYAsgaWAUJPc3kwUXkBBixYaUFBQUJBRU5DMi0hswh0RjdhJQxfX185AQXwcV9fOXV6X092X3ZfZl9fMzNlOF9fOXZfbF83Xy1fX191Xy0zM2Q0dV8xdmY5OXlmbTEtN2V0cjN0cF84N3VlczJfWHVyX183OV9fM3ozXzlweFA3OGs4OXI3MzM3RXdfdi1fdi1iN0pDT05fQbgGAcEGAAW-KPA_0Ab1L9oGFgoQBRAdAVAQABgA4AYB8gYCCACABwGIBwCgBwE.&s=1ad011df80b035fdd957f6ae84e46bdeebae9f83'], - 'video_events': {} - }] - } - }] - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/instream/index.js b/test/mock-server/expectations/request-response-pairs/instream/index.js deleted file mode 100644 index 2c6ca03875b..00000000000 --- a/test/mock-server/expectations/request-response-pairs/instream/index.js +++ /dev/null @@ -1,95 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 13232361, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': {}, - 'hb_source': 1 - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '206465a8c326a5', - 'tag_id': 13232361, - 'auction_id': '1398509384102899505', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Finstream.html&e=wqT_3QKxCKAxBAAAAwDWAAUBCKXQzPAFELHeg_SAnKC0ExjCs_b6q5D9_0oqNgkAAAkCABEJBywAABkAAADgehQUQCEREgApEQkAMREb8Hkw6dGnBjjtSEDtSEgAUABYnPFbYABozbp1eACAAQGKAQCSAQNVU0SYAQGgAQGoAQGwAQC4AQPAAQDIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzgzMTM3NjUpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPD1kgK1AiF5andtb2dpMi1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNmRHbkJsZ0FZTUlHYUFCd0tIZ0dnQUU4aUFFR2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFVUU1FQjg2MXFwQUFBRkVESkFmZjUwcVFyNGVvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHR2aThDcm9EQ1ZOSlRqTTZORGN6T09BRC1SaUlCQUNRQkFDWUJBSEJCBUUJAQh5UVEJCQEBFE5nRUFQRRGNAZAsNEJBQ0lCWUlscVFVAREBFDx3UHcuLpoCiQEhTGc5WkRRNjkBJG5QRmJJQVFvQUQVSFRVUURvSlUwbE9Nem8wTnpNNFFQa1lTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBSZUFBLsICP2h0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctdmlkZW8td2l0aC1hLWRmcC12aWRlby10YWcuaHRtbNgCAOACrZhI6gIzaHQFSkh0ZXN0LmxvY2FsaG9zdDo5OTk5BRQ4L3BhZ2VzL2luc3RyZWFtBT7IgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvCanwXpgEAKIECzEwLjc1Ljc0LjY5qAS0LLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM42gQCCADgBADwBMuBwC6IBQGYBQCgBf______AQMUAcAFAMkFaX8U8D_SBQkJCQx4AADYBQHgBQHwBcOVC_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=6805157848bdfdf973d0dbafff4bb9b4c4ce7e60', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQklKBNeAAAAABEx74AO4IBoExklKBNeAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQ6dGnBljDlQtiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=07e6e5f2f03cc92e899c3ddbf4e2988e966caaa2&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 97517771, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 5.000000, - 'cpm_publisher_currency': 5.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 36, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Finstream.html&e=wqT_3QKNCaCNBAAAAwDWAAUBCKXQzPAFELHeg_SAnKC0ExjCs_b6q5D9_0oqNgkAAAECCBRAEQEHNAAAFEAZAAAA4HoUFEAhERIAKREJADERG6gw6dGnBjjtSEDtSEgCUMuBwC5YnPFbYABozbp1eJG4BYABAYoBA1VTRJIBAQbwUpgBAaABAagBAbABALgBA8ABBMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3ODMxMzc2NSk7dWYoJ3InLCA5NzUxNzc3MSwgLh4A8PWSArUCIXlqd21vZ2kyLUx3S0VNdUJ3QzRZQUNDYzhWc3dBRGdBUUFSSTdVaFE2ZEduQmxnQVlNSUdhQUJ3S0hnR2dBRThpQUVHa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUh6cldxa0FBQVVRTUVCODYxcXBBQUFGRURKQWZmNTBxUXI0ZW9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEdHZpOENyb0RDVk5KVGpNNk5EY3pPT0FELVJpSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkCw0QkFDSUJZSWxxUVUBEQEUPHdQdy4umgKJASFMZzlaRFE2OQEkblBGYklBUW9BRBVIVFVRRG9KVTBsT016bzBOek00UVBrWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8FJlQUEuwgI_aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy12aWRlby13aXRoLWEtZGZwLXZpZGVvLXRhZy5odG1s2AIA4AKtmEjqAjNodAVKSHRlc3QubG9jYWxob3N0Ojk5OTkFFDgvcGFnZXMvaW5zdHJlYW0FPmjyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-4ElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw398F6YBACiBAsxMC43NS43NC42OagEtCyyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczONoEAggB4AQA8ATLgcAuiAUBmAUAoAX______wEDFAHABQDJBWnbFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=68b9d39d60a72307a201e479000a8c7be5508188' - } - } - }] - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_1.js deleted file mode 100644 index d92e64c6075..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_1.js +++ /dev/null @@ -1,577 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '7360998998672342781', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEP39-97ssuGTZhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIVNqMmZTQWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQmtTcHl1c2Q4XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzhKRnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=c92cbcde5c8bf8e053f86493dd4c4698da0392de', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABH9_t7LloUnZhne-wVeAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=8e35c1264cd1b4f1d89f929c3a4a334cf6a68eca&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEP39-97ssuGTZhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFTajJmU0FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkJrU3B5dXNkOF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc4SkZ3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBNLsn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=ca640dffaea7bfcf2b0f2e11d8877821189b74bb' - } - } - }] - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '1919339751435064934', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEOasy7zbqrfRGhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIU1EMUZJQWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRclZ0ZGpIUGVBXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASE1QTdmLVE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=c3130de64bc0b8df258e603dfb96f78550ab0c3c', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABFm1pK3Vd2iGhne-wVeAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=2c3cee10303d9b93531bed443c0781d905270598&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418123, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 12, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEOasy7zbqrfRGhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFNRDFGSUFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUXJWdGRqSFBlQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhNUE3Zi1RNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBIvhn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=996a3937245f03e5eefb0cb69917d2d8d7f60424' - } - } - }] - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '3257875652791896280', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '5756905673624319729', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '4205438746002589111', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '204849530930208960', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '3482944224379652843', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '2123689132466331410', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '6150444453316813936', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '2810956382376737966', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '7164199537578897638', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCN73l_AFEObhocvZsJa2Yxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXNENXVfQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYSEZfdmZOei1NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFDd19DQnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZs2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgUhLADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=2b9ed1e2e7f27fea52cbdc64cb700195bbd14d75', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQne-wVeAAAAABHmcGiZhVlsYxne-wVeAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=8ba7f141449cb45f8b6e12361a62d8d68aa9c812&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418671, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 30, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCN73l_AFEObhocvZsJa2Yxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFzRDV1X0FpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWEhGX3ZmTnotTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhQ3dfQ0J3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=527640949733fba32740156d743d421eb1fe2863' - } - } - }] - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '8404712946290777461', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEPW6p5bQvOLRdBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIWp6MkdiZ2lta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQ0RhTlBDYk9NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFOUS0yRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56TXpRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE18LYuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASSxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABldnDYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgUiLADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ed84428f432d6e743bcad6f7862aed957bece82b', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABF13ckC5YmjdBne-wVeAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=7024b063fcacac27e184ed097ad5878c4dd4dc1d&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417951, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 33, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEPW6p5bQvOLRdBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFqejJHYmdpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkNEYU5QQ2JPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhTlEtMkY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNXwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wn0lGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpwxTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=aefe9625d8e866e048a156abdf26d7c626e6a398' - } - } - }] - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '4063389973481762703', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEI_fjorv9IOyOBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIV96eHRIQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFSVExWM2x4c2VJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFEZy1VQ1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAExd2fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=2fb33b5204f9b75c58d89487725a9d55139f9ff4', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABGPr0Pxpg9kOBne-wVeAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=f9ec8d0b81c1cf4eefc58a7990f4a0a78440725f&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417669, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 4, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-CKB-BAAAAwDWAAUBCN73l_AFEI_fjorv9IOyOBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjSuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc0NTA0NjIpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIV96eHRIQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFSVExWM2x4c2VJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFEZy1VQ1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNXwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wn0lGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAExd2fR4gFAZgFAKAF______8BBRQBwAUAyQVpwxTwP9IFCQkJDHgAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=6b79542e3cee0319d8cb83d1daf127c3aeea9b28' - } - } - }] - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '5097385192927446024', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '201bba5bb8827', - 'tag_id': 15394006, - 'auction_id': '2612757136292876686', - 'nobid': true, - 'ad_profile_id': 1182765 - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_2.js deleted file mode 100644 index ea77d211826..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/ad_server_translation_request_2.js +++ /dev/null @@ -1,289 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '285a2f41615348', - 'tag_id': 15394006, - 'auction_id': '2837696487158070058', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCNSDmPAFEKr2uMu5veGwJxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIV9EemhKUWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTbnRDdFVIdU9BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFOdzh1Rnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDtLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAAAU3DQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=3414eb9e83df14945d2dbfb00e17fb3f2bad2e33', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnUAQZeAAAAABEqO26Z64VhJxnUAQZeAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=e5a720a9884e1df845be9c33658ab69f4c56981e&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417951, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 33, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCNSDmPAFEKr2uMu5veGwJxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFfRHpoSlFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU250Q3RVSHVPQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhTnc4dUZ3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBN_fn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=99418325b8f5ec79e22c1a9aedd73f03de616c2d' - } - } - }] - }, { - 'uuid': '285a2f41615348', - 'tag_id': 15394006, - 'auction_id': '8688113570839045503', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCNSDmPAFEP_K8rCtqJjJeBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIUN6d3Rud2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWUzRZeVVvR09JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFKQTlsRUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDXLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGBSEsAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=2e7c9d18300402e2e183667711728f7743b70a2b', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnUAQZeAAAAABF_pRzWQmGSeBnUAQZeAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=febf12010c66ac7247f571f03c33175ca9036b32&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418948, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 1, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCNSDmPAFEP_K8rCtqJjJeBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFDend0bndpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVlM0WXlVb0dPSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhSkE5bEVBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBMTnn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=92aa9e9c89384c435ab9c7fa62b963d8fc087ef7' - } - } - }] - }, { - 'uuid': '285a2f41615348', - 'tag_id': 15394006, - 'auction_id': '4162295099171231907', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCNSDmPAFEKOxzaPwqtzhORiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIWREMGtXZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhSFRjUzNjWS1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFEUTg2Q0E2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDXLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=95047e919846faea401c778106fb33dae0c95b02', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnUAQZeAAAAABGjWHMEV3HDORnUAQZeAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=50350aadc603f4bb6c59888515d60e9182da0eb8&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418671, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 30, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCNSDmPAFEKOxzaPwqtzhORiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFkRDBrV2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYUhUY1MzY1ktVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhRFE4NkNBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=82c42e6aa09e7c842254552ae524791fa3693bbb' - } - } - }] - }, { - 'uuid': '285a2f41615348', - 'tag_id': 15394006, - 'auction_id': '1076114531988487576', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCNSDmPAFEJj7vIbyjsj3Dhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIVRqMWVUZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZOUNHX2M3MHRvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0BBRHdQdy4umgKJASFFQThNQzo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TTFRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE18O0uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASrxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQA8ATF3Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAAAABTcNAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=c49afba7ca4b5193f7da37b17e1fbfbee2328f61', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnUAQZeAAAAABGYPc8gdyDvDhnUAQZeAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=47618eb9096567900e84fd1c6aff09d753b2fe91&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417669, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 4, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-CKB-BAAAAwDWAAUBCNSDmPAFEJj7vIbyjsj3Dhiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc0NTE5ODgpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIVRqMWVUZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZOUNHX2M3MHRvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0BBRHdQdy4umgKJASFFQThNQzo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TTFRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE1fC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCfSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASrxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQA8ATF3Z9HiAUBmAUAoAX______wEFFAHABQDJBWnDFPA_0gUJCQkMeAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=72d1ec3db5baaa29c1b0e5f07c012db606675fe5' - } - } - }] - }, { - 'uuid': '285a2f41615348', - 'tag_id': 15394006, - 'auction_id': '7495588537924508785', - 'nobid': true, - 'ad_profile_id': 1182765 - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_1.js deleted file mode 100644 index 0c58bd6fb3e..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_1.js +++ /dev/null @@ -1,606 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 15, - 'maxduration': 15 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '4424969993715088689', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFELH6mcm82Km0PRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIWhUNEwzZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjek5XT196NC1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFTZy1SR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBNLsn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=3d8c006f4f85ecffd49c500554c3852b9079ff2b', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABExfSbJw6ZoPRlNxwleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=e2c6cedf67a96613ea8851673ebcfdd25a19435c&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFELH6mcm82Km0PRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFoVDRMM2dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY3pOV09fejQtVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhU2ctUkd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHgAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=de23f822f483b6e85615d4297d872262310c240d' - } - } - }] - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '2013100091803497646', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '2659371493620557151', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEN_KtpiJif_zJBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIWR6eUJxQWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWSHZpWGF0Q09zXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASEtQTVuX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBIvhn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=eafba287adec58427d1679f43a84ebb19223c4e7', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABFfpQ2TSPznJBlNxwleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=b335b2c79378c1699d54cf9ffe097958bd989a0b&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418123, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 12, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEN_KtpiJif_zJBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFkenlCcUFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVkh2aVhhdENPc18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhLUE1bl9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHgAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=66b9e769da1e1d68b202605fc178fc172046e9c5' - } - } - }] - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '5424637592449788792', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '3470330348822422583', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '4415549097692431196', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '1628359298176905427', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '1949183409076770477', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '4707958683377993236', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '2499032734231846767', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '1295788165766409083', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEPvWpeWKj-T9ERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCITR6eVM5d2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFlS0tONGIwQS00XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzkxRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBMTnn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=3cb170cdf53cd6a6bfec0676659daeb6170895e3', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABF7a6mseJD7ERlNxwleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=45f5cce314725120ec769afaacbb7aa92d32e674&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418948, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 1, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEPvWpeWKj-T9ERiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE0enlTOXdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZUtLTjRiMEEtNF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc5MUZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7w7UlGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwP9AG9S_aBhYKEACJABUBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=5c9f03b9c5c6cc2bf070d8cdc6c9af4b06595879' - } - } - }] - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '702761892273189154', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEKLi_7T7xq3gCRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4NDg2Nh8A8P2SArkCITdUeVNDd2lva184UEVQYmpuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFHSTh5N21BQUFzUU1FQmlQTXU1Z0FBTEVESkFYQTM4QzJIcnVFXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHFKUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFaQThESlE2PQEkblBGYklBUW9BRBVIVHNRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBPbjn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBf0F-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=f459a78a1b20c9643b90d7491f22593d79cff253', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABEi8Z-2N7bACRlNxwleAAAAACD2459HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1j9BWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgB9uOfR7ABAQ..&s=83289d261bced5258930a1ce2464260a96565241&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418486, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 14.000010, - 'cpm_publisher_currency': 14.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 30, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEKLi_7T7xq3gCRiq5MnUovf28WEqNgmOWItPAQAsQBGOWItPAQAsQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ9uOfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODQ4NiwgMTUZH_D9kgK5AiE3VHlTQ3dpb2tfOFBFUGJqbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRR0k4eTdtQUFBc1FNRUJpUE11NWdBQUxFREpBWEEzOEMySHJ1RV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RxSlBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhWkE4REpRNj0BJG5QRmJJQVFvQUQVSFRzUURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7w7UlGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8AT2459HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF_QX6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwP9AG9S_aBhYKEACJABUBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=16a432c0a05db78fa40fefc7967796ff2a2e8444' - } - } - }] - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '8192047453391406704', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEPCMp9SW-P_XcRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXhUdGdYZ2lHa184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFSR0FWSjZORXVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFKUThlRDo9ASRuUEZiSUFRb0FEFUhUcVFEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=8bf90e0756a9265ab6ac029e883e14803447a7fb', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABFwxolqwf-vcRlNxwleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=cf9ea0df7655a5c6150a527399cb2852c61ec14a&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417951, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 13.000010, - 'cpm_publisher_currency': 13.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 33, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEPCMp9SW-P_XcRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF4VHRnWGdpR2tfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBUkdBVko2TkV1TV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhSlE4ZUQ6PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGNIIgFAZgFAKAF_xEBFAHABQDJBWm-FPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=cefb5f476892ed335cd8b0fc20fabf7650b1d2e3' - } - } - }] - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '9041697983972949142', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEJb5yqiVjaS9fRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIURUMkpEd2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFYeHdUOEhkUmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFJZzhjRGc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBMXdn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBcLyF_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=308ea3c3363b379ef62dbb6c7a91d1d91d9ee47a', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABGWvBJVaZB6fRlNxwleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=70a33aa1a57d812d9da5c321e898197836ed16f8&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417669, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 4, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5CKB5BAAAAwDWAAUBCM2Op_AFEJb5yqiVjaS9fRiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXiVuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTkxNDkpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIURUMkpEd2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFYeHdUOEhkUmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFJZzhjRGc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYAAGHxKPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ee15793b41a9d22ffad9bd46878a47821d6044fa' - } - } - }] - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '356000177781223639', - 'nobid': true, - 'ad_profile_id': 1182765 - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_2.js deleted file mode 100644 index 38331688a9b..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/basic_w_requireExactDuration_request_2.js +++ /dev/null @@ -1,288 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'minduration': 30, - 'maxduration': 30 - } - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '198494455120718841', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEPnX6_r7tMzgAhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXpUMDRwQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhejg2NVNoMGVJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKQTkzRFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCADgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=645b6e0a37eb3a315bc3208365bd4fc03e1ecd18', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABH561q_pzHBAhlNxwleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=35a21bf0bef1ca2c138e37a2e025ad523b5a1db2&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418671, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 30, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEPnX6_r7tMzgAhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiF6VDA0cEFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYXo4NjVTaDBlSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNEQUR3UHcuLpoCiQEhSkE5M0RRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0N9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHQAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYJJCjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=cf3130989b2b4fe5271240d65055b85d1192b78a' - } - } - }] - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '998265386177420565', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEJW6sbXGoqPtDRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIVdqM1Jid2lHa184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFmcXpCNjduMU9rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0BBRHdQdy4umgKJASFLZzlMRDo9ASRuUEZiSUFRb0FEFUhUcVFEb0pVMGxPTXpvME56UTNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDfaBAIIAOAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=33f01ddfb15bc84d7bf134a168aeb9d9de76fa57', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABEVXaxmFI3aDRlNxwleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=023640de7c18a0d0e80b2456144b89a351455cda&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417951, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 13.000010, - 'cpm_publisher_currency': 13.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 33, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEJW6sbXGoqPtDRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFXajNSYndpR2tfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBZnF6QjY3bjFPa18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNAQUR3UHcuLpoCiQEhS2c5TEQ6PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBGGNIIgFAZgFAKAF_xEBFAHABQDJBWm-FPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=515ab42a7fdcad8fcf34e4fb98b1e076a75006a9' - } - } - }] - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '8884527464400177295', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEI-RmcaB1Yumexiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCITVqcmtHUWlta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYb0paejlaR09NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0BBRHdQdy4umgKJASFPdy1pRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UTNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDfaBAIIAOAEAPAExOefR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHQAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYJJCjwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=dc7d874e52ac39980ec1070a7769632be56a2f00', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABGPSMYYqC5MexlNxwleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=9fd739e9f0a6054296f9bb5168c49a89a425795c&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418948, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 1, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEI-RmcaB1Yumexiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE1anJrR1FpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWG9KWno5WkdPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNAQUR3UHcuLpoCiQEhT3ctaUY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkAFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=1f8ea8f07f781fe149beb0d65dd25ad725a12f3b' - } - } - }] - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '1279521442385130931', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFELPr8f6Pv_HgERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIW9EeDJEQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFkb01fcFZkVGVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKdzlKRHc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCADgBADwBMXdn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBcLyF_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=4b14660ae659b3d301ec6c40f0f096bb88db145b', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABGzddz_-MXBERlNxwleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=5f277bcab624f05c9d3a3a9c111961f3f33ccca2&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417669, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 4, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5CKB5BAAAAwDWAAUBCM2Op_AFELPr8f6Pv_HgERiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjFuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTkxNDkpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIW9EeDJEQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFkb01fcFZkVGVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKdzlKRHc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYAAGHxKPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=7bb7b75e4769a1260eaed2c79752ee542b4d28ce' - } - } - }] - }, { - 'uuid': '25593f19ac7ed2', - 'tag_id': 15394006, - 'auction_id': '7664937561033023835', - 'nobid': true, - 'ad_profile_id': 1182765 - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_1.js deleted file mode 100644 index ee1a19d21b2..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_1.js +++ /dev/null @@ -1,852 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '6316075342634007031', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPfztqL2oc3TVxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIV96eWNLZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZYkYwSW1fZGU0XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASE5dzR0Xzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=bb81a081c756fd493253bf765c06ff46888f009a', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABH3uU1kDzWnVxk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=a3da30186f69a5ce2edcfc14fa3a31b92ee70060&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418123, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 12, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPfztqL2oc3TVxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFfenljS2dpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWWJGMEltX2RlNF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhOXc0dF86PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=62b9db151b3739399e0970c74fafc4bb61486510' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '8259815099516488747', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEKuY2qihwrDQchiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIW1UeUFCd2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYNml4eGFGdE8wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=8a55db8e788616ef057647b49c0560296fdacb65', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABErjBYVEsKgchk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=75d46be63f76fd4062f354a56c692855da366148&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418948, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 1, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEKuY2qihwrDQchiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFtVHlBQndpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWDZpeHhhRnRPMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=59e0ab1f626c2e4dc5c4f6e6837b77559cf502b4' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '7960926407704980889', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEJnboLK5jLm9bhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIUZEeFl4QWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhSUpVQVhXMC1JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTQThFR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=8d00bc7576c3cc19fe8b3fb4aa42966583741dfa', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGZLUiWY-R6bhk3yQleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=c813392cbb81d43466d5d949b9bebc2305e6fe7d&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417951, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 33, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEJnboLK5jLm9bhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFGRHhZeEFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYUlKVUFYVzAtSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU0E4RUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=284760a6e2d4f226b639d29237e9c1aa25ca49a9' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '7561862402601574638', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEO7By9umucj4aBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCITREcWpId2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTSVA1dzg5RGVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=917e8af2ed1c82091f487b6abd78de47b99e9e46', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABHu4HJryiHxaBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=ff73768bfb14e9ae603064fc91e95b60c8d872e2&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEO7By9umucj4aBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiE0RHFqSHdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU0lQNXc4OURlUV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=84c66b632a2930d28092e00985ee154ba2e97288' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '6577796711489765634', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEIKC0sii6MGkWxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIVBUem53UWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFlaE5hMWl1Y3V3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASE5dzR0X2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ea4a54786a8f3cf5177b3372ce97682da060c358', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABECgRQpQgdJWxk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=778fbf3014328ec0b01d6ebd7b306be32cf79950&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418123, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 12, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEIKC0sii6MGkWxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFQVHpud1FpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZWhOYTFpdWN1d18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhOXc0dF9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=28a3b583912b95528519f63a75c0fe2d06064e7b' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '2418275491761094586', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELr_z7v0l9zHIRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUF6MUJSZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVNUE2dXpUVy1ZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTUTlYR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=c563626304ebb31fd6f1644cc2d4098133dec096', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABG6_3NHv3CPIRk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=88c9fbb2b9dc273865a5f9238543a29224908b26&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELr_z7v0l9zHIRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFBejFCUmdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVTVBNnV6VFctWV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU1E5WEd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e76aeb8daad477f4428631fc89d277d4a4646ded' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '5990197965284733361', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELHjwfj9qd2QUxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIURUeDF3d2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFmWXBYSEoxUGVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e443347514ff5f6a52a2811f591f9a346061a756', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGxcRDfT3UhUxk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=50348eb78116f7d35ca5ac6f6fa4c5548a6ceffc&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELHjwfj9qd2QUxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFEVHgxd3dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZllwWEhKMVBlTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a24f331ff55f96c5afe5134762f8d8e230b6287c' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '4399290132982250349', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEO32psKU4tqGPRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCITN6dDlwd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRWlZqbkpncmV3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0d9b0a06992ff427d281fae8d8b18d4e6838b944', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABFtu0lIEWsNPRk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=52a446d84f5e9a2baa068760c4406f4a567a911a&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEO32psKU4tqGPRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiEzenQ5cHdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUVpWam5KZ3Jld18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e6ae592b5fc3de0053b5acd46294b83549aa00c8' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '8677372908685012092', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPzYku74lY62eBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIVVEeGp5d2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVN29abmh2c09RXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASE5dzR0X2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=522b764f2276ce75053a55a0198b79fb8d1d39d5', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABF8rMSNrzhseBk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=02b75d0ecc71c7897b9590be5e50b094158c8097&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418123, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 12, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPzYku74lY62eBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFVRHhqeXdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVTdvWm5odnNPUV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhOXc0dF9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0ae5558a7b0cc87eaa0c6811522629963b41bac5' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '617065604518434488', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELitu4PevJDICBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUFqMVNSZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaUzdZYTg5Ny13XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTUTlYR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9HYBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAAAAAAAAAAAAAAAAAAAAEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f59bdb7b0f7020f75c6019f23686915b72d61779', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABG41m7g5UGQCBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=912a721db8e85d4d64a8869d7cf9b56cd0c24907&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELitu4PevJDICBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFBajFTUmdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWlM3WWE4OTctd18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU1E5WEd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBGAHABQDJBQAFARTwP9IFCQkFC3wAAADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgEhMAAA8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=9b4372ae0674305d9cd7152959910d1fa7d4daec' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '8957511111704921777', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELGNpebanN6nfBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXVqdHppQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFUM1dNOVpkQU9JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFIZzhRRDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBK_ln0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAaakNAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a8817d9dc3326ba1b59fe308f126ddaca5710a9c', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABGxRsms5XhPfBk3yQleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=a0ac94e902cbc609881fa9f39537bbc67ba046e7&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418671, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 30, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELGNpebanN6nfBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiF1anR6aUFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVDNXTTlaZEFPSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhSGc4UUQ6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=75b3ad3e867323196da165cd655b3ae51c8b44d0' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '2680240375770812721', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELGi6rO9jYiZJRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIWd6eTMtZ2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYcFdVTk9rai1jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f8458c6a48fed591c269169a9744aba11cb90285', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABExkXrWayAyJRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=e2dbd082b353a37db9f632efc2532913a0c48166&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418948, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 1, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELGi6rO9jYiZJRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFnenkzLWdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWHBXVU5Pa2otY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=5475ac640321ae51a06b5c05ac62519e97e90114' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '8439286287321689724', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEPzciY2kxZePdRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIU1UeWZ6d2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWalR1QThjek9FXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=73e760427d2aec3d47824994cf35c35f1eeddcf8', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABF8bqJBKl4edRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=dac1e836a6f2c4dc036c50d0b3128dfefb34915d&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418948, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 1, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEPzciY2kxZePdRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFNVHlmendpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVmpUdUE4Y3pPRV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=6c1fb35564d2ffd08fb4c5b290aadd6e1e3d83ec' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '5519278898732145414', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEIa29Pmn3ZrMTBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCITFEc0hwUWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkQUZ3YVliRWVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTQThFR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=d01f411e7cc9126e912daca85136b2ca6f99a347', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABEGGz1_6mqYTBk3yQleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=81115280cee86ae0bc259627410fa5dbbc178646&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417951, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 33, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEIa29Pmn3ZrMTBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiExRHNIcFFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZEFGd2FZYkVlTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU0E4RUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=90f21feeb2c798cd77b3cadbc961240238825f0d' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '6754624236211478320', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELC-hPXI3s_eXRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIVJqc0hVUWlta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaRjJPd05MVnVvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=34811f7e5c917550619274f5b75a0cd214119812', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABEwH6GO9D69XRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=d811faa48963b18d33c0a1f9d1e64ff97640a415&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418948, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 1, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELC-hPXI3s_eXRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFSanNIVVFpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkYyT3dOTFZ1b18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=c0a0a2d65dd091bd2ed81f95da1a9f7ff16ad70e' - } - } - }] - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_2.js deleted file mode 100644 index ce8bad3e9d7..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_brandCategoryExclusion_request_2.js +++ /dev/null @@ -1,312 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '4631210661889362034', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPKQq-_0sdeiQBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXF6eU1HUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVQk5fYTFxbHU0XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0dae5294ed5bb48b7d3a156e5e587a26da27c7e1', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABFyyOpNj11FQBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=9085e4dbb4849b0e6d3714d84a2754bbab578e16&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPKQq-_0sdeiQBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFxenlNR1FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVUJOX2ExcWx1NF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=aa5533d04e16ee398f8028ab3af03a48d7d8cc17' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '714778825826946473', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEKmbi7Ph8dn1CRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIU56dmJOZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRbjlXUzRmY09jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASEtUTZrXzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCADgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=8917b1722eed5b6d85c6d5a01eea7862089bee32', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGpzWIWjmfrCRk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=9ec7e7de16b948b60d74b47f1917faf5d3b6dbf0&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418123, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 12, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEKmbi7Ph8dn1CRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFOenZiTmdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUW45V1M0ZmNPY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhLVE2a186PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8N5JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgAAYfQo8D_QBvUv2gYWChABDy4BAFAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=8198652a5ee16abf4595ab1bfc6b051f81f0579d' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '231404788116786844', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEJydmpjcrYebAxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUVqMFlVZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhLXFPTExmZ2VrXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=775dfc49086467337dee9a5e8d78b361931c6aaa', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGcjgbDbR02Axk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=914256a92514df787ccb1eae7dea7578d23c8fba&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEJydmpjcrYebAxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFFajBZVWdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYS1xT0xMZmdla18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f624619431372f9a248d0fa0dd8d09c4977bb544' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '7557072342526904599', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEJeS-7GaqIfwaBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIUFqdmVKQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFSY2lLblVqeU9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASFJQS1IRDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0dQFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCADgBADwBK_ln0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAAAAAAAAAAAAAAAAAABAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=552663ed1246fd2a3cc5824164f57d32f18078ee', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABEXyT6mQR3gaBk3yQleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=e1c80e622aa60bf7683413f4371b0055d0d16f47&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418671, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 30, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEJeS-7GaqIfwaBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFBanZlSkFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUmNpS25VanlPVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhSUEtSEQ6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEYAcAFAMkFAAUBFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=ccf266d1b02551a2ad0af0871d4af43e4aee4bba' - } - } - }] - }, { - 'uuid': '2c52d7d1f2f703', - 'tag_id': 15394006, - 'auction_id': '5093465143102876632', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFENjX7JP78efXRhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIUJUeXRwUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYamVBMVdNcXUwXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASEtUTZrX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=6651c1436b699842aabb3ae53d96d07caf5b4938', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABHYK3uyj5-vRhk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=f62098bf5037b22ca4e5583289a1527fdfa87e43&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418123, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 12, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFENjX7JP78efXRhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFCVHl0cFFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWGplQTFXTXF1MF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhLVE2a19nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAGH0KPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=4b43aaab766ee7d2e4c900ec32cb3c8b7ccef1d0' - } - } - }] - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_1.js deleted file mode 100644 index fc2ad82fe5f..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_1.js +++ /dev/null @@ -1,620 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '8905202273088829598', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEJ7x1-ORyejKexiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIWlEeE84Z2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhV09TRWpDY09NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0BBRHdQdy4umgKJASFQZzlaRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56YzNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAZWQU8D_SBQkJBQt4AAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgEgMAAA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=21195aa3e27f8eb88ba43d5da32e6b78c2aa03f8', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABGe-HUcSaKVexm1ywleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=3c05b8509dd5c7c4459886f4c69fdd9cd07caa66&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418948, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 1, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEJ7x1-ORyejKexiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFpRHhPOGdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYVdPU0VqQ2NPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNAQUR3UHcuLpoCiQEhUGc5WkY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXObNgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYFISwA8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=203ae79160a460b18f20165e5de53bb1f45e4933' - } - } - }] - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '2428831247136753876', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFENSR0sfppLzaIRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXRUeV9FQWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTek5nNXJvQi0wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFVUThpSFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=af2d5096aa4f934e84b59ad16cd18dfe5b9bbc77', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHUiPSYJvG0IRm1ywleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=440a389c7f556dac70c650bb1e593a10cbcdf2af&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417951, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 33, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFENSR0sfppLzaIRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF0VHlfRUFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU3pOZzVyb0ItMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhVVE4aUhRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9b00ed17c420f328d63b72519d2d578c5921d0d7' - } - } - }] - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '1625697369389546128', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEJD1gLbO5OjHFhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIXVqeHMtUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhcDVwSkxuSXVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFBQTlhQUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0e70f535a95c82238d685147f41e0bd2f86631c0', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGQOsDmJKOPFhm1ywleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=144214d77cc4ced0893c9fe64132ad01c429c43c&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418123, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 12, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEJD1gLbO5OjHFhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiF1anhzLVFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYXA1cEpMbkl1VV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhQUE5YUFBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f6bc475b66c167036dcb9f10c7c5f176124829a6' - } - } - }] - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '5434800203981031918', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEO6TivzZv5K2Sxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIW5Ud3I5QWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFXVVcwV1Y1LU9JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFKdzh1RGc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=c3ba85f0eb0293896e02066385f82b4450af2cfb', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABHuiYKf_UlsSxm1ywleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=9eb2d880fa9b524a6a0807eef0c65b7b1393f48a&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418671, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 30, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEO6TivzZv5K2Sxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFuVHdyOUFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBV1VXMFdWNS1PSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhSnc4dURnNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASv5Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=17038c2671b58d2fd6ea98dd3f3e1166ee664dd0' - } - } - }] - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '8071104954749355970', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEMKP7OWZ5pSBcBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXBUeEJEQWlsa184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFRbWtta1pXNGVZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFSZ19sR1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=005579c0ff91586a887354409f637a63a1d69031', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHCB7ucMVMCcBm1ywleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=edbfae73be0f41d672298d5c3ec9dd28a5307233&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6CKB6BAAAAwDWAAUBCLWXp_AFEMKP7OWZ5pSBcBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDS7J9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc3MDAyNzcpO3VmKCdyJywgMTQ5NDE5NjAyLCAxNRkf8P2SArkCIXBUeEJEQWlsa184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFRbWtta1pXNGVZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFSZ19sR1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0ac18b64a6c0d58a114085d8b565b4c98de56448' - } - } - }] - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '6893555531330982923', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEIuopuO2h7XVXxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIVFqd1R0Z2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFZS1J6NEZQV2V3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASEzUTZnOHc2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF8owB-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f9ddb1066825dfc556d108168ffc0d16cf567ae8', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABELlGlsO9SqXxm1ywleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=db3a0d52f97edd94aa7e4213c437d8e4a5bd16ce&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149414188, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 13.000010, - 'cpm_publisher_currency': 13.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 32, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 29000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEIuopuO2h7XVXxiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFRandUdGdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBWUtSejRGUFdld18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhM1E2Zzh3Nj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASswp9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=917c8192c7dc7e382c0bb7296ab0df261e69f572' - } - } - }] - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '5615186251901272031', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '6647218197537074925', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '4707051182303115567', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '4831890668873532085', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '7151522995196673389', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '4077353832159380438', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFENaHwKvS9urKOBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIWJqeHo1UWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZd1VQNVZMNi1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFLZzhBRUE2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAExd2fR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e96d121a0a7d49e05c1d2b4fab2da60d0b544287', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHWA3AltauVOBm1ywleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=8d90e3ce42fe47da19cb85f8fb2d78822c590464&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417669, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 4, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6CKB6BAAAAwDWAAUBCLWXp_AFENaHwKvS9urKOBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc3MDAyNzcpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIWJqeHo1UWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZd1VQNVZMNi1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFLZzhBRUE2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=db30796cc71c3bee3aa8fc2890c75ad7186f9d73' - } - } - }] - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '2099457773367093540', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '7214207858308840891', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '4564285281969145467', - 'nobid': true, - 'ad_profile_id': 1182765 - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_2.js deleted file mode 100644 index 751abfa14e4..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/basic_wo_requireExactDuration_request_2.js +++ /dev/null @@ -1,312 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '2704229116537156015', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEK_j3NPcwdbDJRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXpUczJvQWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFURVBwVy1oVE9ZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0BBRHdQdy4umgKJASFVQV9qSDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UTVRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAZWQU8D_SBQkJBQt8AAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYBITAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=64565aadf65d370e9730e9ce82c93c9bd2fcfc14', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGvMXfKDVqHJRm1ywleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=3b1f10f67b3253e38770fff694edbe6052795602&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417951, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 33, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEK_j3NPcwdbDJRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF6VHMyb0FpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVEVQcFctaFRPWV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNAQUR3UHcuLpoCiQEhVUFfakg6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ52gQCCAHgBADwBN_fn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=5316c3262f36e4d89735b1ba252c64651a84f479' - } - } - }] - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '7987581685263122854', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEKaDmaSQ5-Xsbhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIU16MXpZd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYLVkxZU5tY3VRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFVUTgySFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=17f2a3f5e78c188cc6ca23e677ced305198a8a05', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGmQYYEOZfZbhm1ywleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=28e8f96efdfb9bc1e33e4d087ff5ed992e4692b1&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEKaDmaSQ5-Xsbhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFNejF6WXdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWC1ZMWVObWN1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhVVE4MkhRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=89d4586d9597cd2f9a4a918d1e6985aee45ade01' - } - } - }] - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '653115326806257319', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEKfdmd3enZWICRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCITlEd0hNZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjTnlESmJxeS13XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFKZ192RFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=1928a9daadbd431792adace7620880dda961eefb', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABGnbqbr7VQQCRm1ywleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=7617d08e0c16fe1dea8ec80cd6bf73ec0a736b41&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418671, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 30, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEKfdmd3enZWICRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiE5RHdITWdpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY055REpicXktd18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhSmdfdkRRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ASv5Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0d1d3f42fa225995a2f57ab84877dce3d24e9901' - } - } - }] - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '866435845408148233', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEImW35H52YyDDBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIXJEenNfZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjMmZTZ1BpMi1BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFfdzRiQUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=83f65f38b4fd56344b3aceb70df7bac1b9b5f229', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABEJyzeSzzIGDBm1ywleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=9130c13cca7a1d3eb05c2b96585ccfdc2faa6844&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418123, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 12, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEImW35H52YyDDBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFyRHpzX2dpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYzJmU2dQaTItQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhX3c0YkFBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=1f88d8b0a467d528291f90a54fd810b8fdac4488' - } - } - }] - }, { - 'uuid': '2022b6b1fcf477', - 'tag_id': 15394006, - 'auction_id': '1540903203561034860', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEOyokYzL6ZixFRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIXdUekVId2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaeE00NUxjRXVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFQUThhRmc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a4de0e4084ce04a5cb2d347c07fde867aa9ff5c1', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABFsVISxTGNiFRm1ywleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=cf600d825cec85f83c06119e5e383f8548b469a2&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418948, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 1, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEOyokYzL6ZixFRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiF3VHpFSHdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWnhNNDVMY0V1TV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhUFE4YUZnNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=17c466ea45d5d4beff02aa2b0eb87bc6c4d5aff3' - } - } - }] - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_1.js deleted file mode 100644 index 4f11a203724..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_1.js +++ /dev/null @@ -1,418 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }], - 'user': {}, - 'brand_category_uniqueness': true - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '2678252910506723691', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '3548675574061430850', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '8693167356543642173', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '7686428711280367086', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '3784359541475413084', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '7233136875958651734', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '159775901183771330', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '6558726890185052779', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '6624810255570939818', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '528384387675374412', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '2535665225687089273', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '2166694611986638079', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '9137369006412413609', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '3524702228053475248', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2d4806af582cf6', - 'tag_id': 15394006, - 'auction_id': '57990683038266307', - 'nobid': true, - 'ad_profile_id': 1182765 - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_2.js deleted file mode 100644 index b69612d86b9..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/bidder_settings_request_2.js +++ /dev/null @@ -1,284 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }], - 'user': {}, - 'brand_category_uniqueness': true - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '245a09bd675168', - 'tag_id': 15394006, - 'auction_id': '3810681093956255668', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKVCKAVBAAAAwDWAAUBCKD4kfAFELT_vOy9yJDxNBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUxEMWZkUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZVS10N09mcU9BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFLdy1SRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=66ba37441db5e28c87ee52e729333fd9324333f9', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQkgfAReAAAAABG0P4_dQ0LiNBkgfAReAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=6931bf3569012d0e1f02cb5a2e88dfcafe00dba9&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLxCOhxBAAAAwDWAAUBCKD4kfAFELT_vOy9yJDxNBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFMRDFmZFFpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWVUtdDdPZnFPQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhS3ctUkZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ea46ec90cf31744c7be2af5d5f239ab4eed29098' - } - } - }] - }, { - 'uuid': '245a09bd675168', - 'tag_id': 15394006, - 'auction_id': '7325897349627488405', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKUCKAUBAAAAwDWAAUBCKD4kfAFEJXRloy0mrTVZRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXJUeTNJd2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVSzAtQ2hwcWRrXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFBQTlLQlE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=271fd8a0ccdfc36e320f707164588ed1b33e9861', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQkgfAReAAAAABGVqIVB09CqZRkgfAReAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=115ac2b842cf3efeb5acaeda94ddf05632c345ca&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418671, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 30, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLwCOhwBAAAAwDWAAUBCKD4kfAFEJXRloy0mrTVZRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFyVHkzSXdpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVUswLUNocHFka18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhQUE5S0JRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=f73e060b15a6bbcca65f918a296f155b78c74eca' - } - } - }] - }, { - 'uuid': '245a09bd675168', - 'tag_id': 15394006, - 'auction_id': '968802322305726102', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKVCKAVBAAAAwDWAAUBCKD4kfAFEJbt7LTEkvi4DRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIUtUejN5d2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFTT3dTTWVaYnVJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASF0ZzY4Nmc2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULfAAAANgFAeAFAfAF8owB-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e35825a106304da78477df1575f981395be21d5f', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQkgfAReAAAAABGWNptGlOBxDRkgfAReAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=677bedd5b2d21fdc3f940cbae279261c8f84c2e7&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149414188, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 13.000010, - 'cpm_publisher_currency': 13.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 32, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 29000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLxCOhxBAAAAwDWAAUBCKD4kfAFEJbt7LTEkvi4DRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFLVHozeXdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBU093U01lWmJ1SV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhdGc2ODZnNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0707b1385afa81517cd338f1516aeccc46fe33e1' - } - } - }] - }, { - 'uuid': '245a09bd675168', - 'tag_id': 15394006, - 'auction_id': '1273216786519070425', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '245a09bd675168', - 'tag_id': 15394006, - 'auction_id': '1769115862397582681', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKUCKAUBAAAAwDWAAUBCKD4kfAFENn63YWPsMrGGBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIXp6djFzd2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZbW5MamdJaXVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFGdzkxRFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULeAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=fb3a15e7ff747fccd750671b763e312d97083c72', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQkgfAReAAAAABFZfbfwgCmNGBkgfAReAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=7f4b8dd7c7dd9faecebac2e9ec6d7ef8da08da16&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418948, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 1, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLwCOhwBAAAAwDWAAUBCKD4kfAFENn63YWPsMrGGBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiF6enYxc3dpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWW1uTGpnSWl1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhRnc5MURRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwsEFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBWm2FPA_0gUJCQkMdAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=3a27c12c33ebaaae43dbce1cafb0bae43b753fa0' - } - } - }] - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_1.js b/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_1.js deleted file mode 100644 index ffb03cc0563..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_1.js +++ /dev/null @@ -1,620 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '1249897353793397796', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEKTIuZTW4KGsERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCITFqdjBlZ2lta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFXU1JOVU1OTk9jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFTUTgtR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e9887c670ae9fcb7eb2a0253037c64c3587f4bcb', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEkZI5iBYdYERnJwgleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=68a5c49da3a6ecf3dfc0835cb3da72b3b2c7b080&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417951, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 33, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEKTIuZTW4KGsERiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiExanYwZWdpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBV1NSTlVNTk5PY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhU1E4LUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9514ae5f8aae1ee9dddd24dce3e812ae76e0e783' - } - } - }] - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '4278372095219023172', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMT65MOLmPWvOxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIUxEeUhqUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQWJScDluWS1FXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASEtQTVuX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=987d4bb0c7611d41b5974ec412469da2241084cd', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABFEPXm4wNRfOxnJwgleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=75aaa9ec84807690ceff60e39fbba6625240f9f3&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418123, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 12, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEMT65MOLmPWvOxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFMRHlIalFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkFiUnA5blktRV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhLUE1bl9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9872a378866ce61fc366ca8c34bdd9302fa41a9b' - } - } - }] - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '8860024420878272196', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFEMSN8Z3LqMj6ehiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIU9EMjhLZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkZExBS3hfN09nXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFIdzlLREE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=1289862cbe265fd9af13d2aab9635e3232421ec1', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnKwgleAAAAABHERryzRCH1ehnJwgleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=0b094204d5c18803149e081bd2bc0077d25ebb14&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418671, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 30, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFEMSN8Z3LqMj6ehiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFPRDI4S2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZGRMQUt4XzdPZ18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhSHc5S0RBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=f35771975371bb250fd6701914534b4f595fcf68' - } - } - }] - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '5236733650551797458', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFENLt5YOosKfWSBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIThUMjJsZ2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkczByb2Ytbk9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzkxRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=e997907677e4e2f9b641d51b522a901b85944899', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnKwgleAAAAABHSdnmAgp2sSBnJwgleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=d70eef0df40cece50465a13d05a2dc11b65eadeb&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418948, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 1, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFENLt5YOosKfWSBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE4VDIybGdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZHMwcm9mLW5PVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc5MUZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_DtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAGn1FQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e8b6716ad3d2fcbdb79976f72d60f8e90ce8f5a6' - } - } - }] - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '4987762881548953446', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '201567478388503336', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEKjm-NzbkYfmAhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXV6NlFDd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkejE5MUdLNk8wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFTZy1SRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=4a887316a3197dfae07c1443a4debc62a2f17fef', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEoM567jRzMAhnJwgleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=eef6278d136f8df4879846840f97933e9d67388a&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEKjm-NzbkYfmAhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiF1ejZRQ3dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZHoxOTFHSzZPMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhU2ctUkc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8JplQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkNVU1RPTREdCEFTVAEL8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAEYYIgiAUBmAUAoAX_EQEUAcAFAMkFabMU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e68b089e4fc94aa7566784ccbff299e50c8bc090' - } - } - }] - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '3876520534914199302', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '4833995299234629234', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '8352235304492782614', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEJaok6aeuMb0cxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIUpUMS1FZ2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFmQ1lIN1I1bmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASExUTY4OFE2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=7081f4ad4ae9837aaff4b4f59abc4ce7f8b02cb6', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEW1MTkwRnpcxnJwgleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=71f281c81d1ae269bde275b84aa955c833ab1dea&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149414188, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 13.000010, - 'cpm_publisher_currency': 13.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 32, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 29000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEJaok6aeuMb0cxiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFKVDEtRWdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBZkNZSDdSNW5lc18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhMVE2ODhRNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=05fc37623521011853ff69d194aa6d692b6c0504' - } - } - }] - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '2318891724556922037', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '5654583906891472332', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMy7oJeqw8e8Thiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIXZ6Ml9mZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFhYzY5MFRlZi1rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFJZzhjRDo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATF3Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=f929565158c7caa5b85e88fa456cdd04d0e4b6d8', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABHMHeiiGh55ThnJwgleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=a93773067b8588465b9c007e19970bd9e08c1b6c&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149417669, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 4, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCKBuBAAAAwDWAAUBCMmFp_AFEMy7oJeqw8e8Thiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjDuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTc5OTMpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIXZ6Ml9mZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFhYzY5MFRlZi1rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFJZzhjRDo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwmmVBQS7YAgDgAq2YSOoCTmh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19wcmljZUdyYW4uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTV9NT0RFTF9MRUFGX05BTUUSAPICHgoaQ1VTVE9NER0IQVNUAQvwkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhgiCIBQGYBQCgBf8RARQBwAUAyQVpsxTwP9IFCQkJDHgAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=a3a24cbf148bb959f539e883af3d118f64e81bc9' - } - } - }] - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '2268711976967571175', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '8379392370800588084', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '6225030428438795793', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '1592368529919250324', - 'nobid': true, - 'ad_profile_id': 1182765 - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_2.js b/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_2.js deleted file mode 100644 index 5a716c6e8e9..00000000000 --- a/test/mock-server/expectations/request-response-pairs/longform/price_gran_request_2.js +++ /dev/null @@ -1,283 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 15394006, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'require_asset_url': true, - 'video': { - 'maxduration': 30 - } - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '6123799897847039642', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFEJqN_JX98Yb-VBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIUN6dzV3Z2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYQm5aNWdRbi1NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFJQS1IREE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=a7e4ff14c60153db90971365f90e514f45875324', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnJwgleAAAAABGaBr_Sjxv8VBnJwgleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=842283d9de78fba7e92fac09f95bb63902a0b54a&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418671, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 30, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFEJqN_JX98Yb-VBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFDenc1d2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWEJuWjVnUW4tTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhSUEtSERBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0fb74d544be103e1440c3ee8f7abc14d2c322d15' - } - } - }] - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '889501690217653627', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEPvKoYSxoomsDBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIWt6eTlHUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRSzgzNzR1VnVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=78ac70aeeae1da43c90efd248fb30a4ee630ffd5', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABF7ZYgQEyVYDBnJwgleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=f21e2a522ddcaf0a67bc7d52f70288fdf7e6f3dd&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149419602, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 24, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEPvKoYSxoomsDBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFrenk5R1FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUUs4Mzc0dVZ1VV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=69611db1024ddb77e0754087ddbeae68a00633a1' - } - } - }] - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '2793012314322059080', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMj-1IPuvLHhJhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIXhqb2ZBZ2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFRQWhlSGt0VHVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASExZzc1OFE2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=243f58d85b09468de2fe485662c950a86b5d90fb', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABFIP3Xg5sXCJhnJwgleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=99dd40ab6ae736c6aa7c96b5319e1723ea581e0d&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149414188, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 13.000010, - 'cpm_publisher_currency': 13.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 32, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 29000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEMj-1IPuvLHhJhiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiF4am9mQWdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBUUFoZUhrdFR1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhMWc3NThRNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=d9a3c817696f263b6e6d81f7251827fa54a47c37' - } - } - }] - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '45194178065897765', - 'nobid': true, - 'ad_profile_id': 1182765 - }, { - 'uuid': '2def02900a6cda', - 'tag_id': 15394006, - 'auction_id': '3805126675549039795', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFELPZ2uvQ0aHnNBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIWNUM1hkZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjbUQzMExTME9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASEtUTZrXzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=bbeaa584bea9afedf6dcab51b1616988441dfa22', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABGzrHYNjYbONBnJwgleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=b7e937b5acc3d8b910f6b08c3a40e04aa10818cd&event_type=1', - 'usersync_url': 'https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 149418123, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 15.000010, - 'cpm_publisher_currency': 15.000010, - 'publisher_currency_code': '$', - 'brand_category_id': 12, - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 15000, - 'playback_methods': ['auto_play_sound_on'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'asset_url': 'https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFELPZ2uvQ0aHnNBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFjVDNYZGdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY21EMzBMUzBPVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhLVE2a186PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8JplQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkNVU1RPTREdCEFTVAEL8N5JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgAAYeYo8D_QBvUv2gYWChABDy4BAFAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=279827127eba3204bc3a152b8abaf701260eb494' - } - } - }] - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js b/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js deleted file mode 100644 index deca38b6022..00000000000 --- a/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-1.js +++ /dev/null @@ -1,111 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 1, - 'height': 1 - }], - 'ad_types': ['native'], - 'id': 13232392, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'native': { - 'layouts': [{ - 'title': { - 'required': true - }, - 'main_image': { - 'required': true - }, - 'sponsored_by': { - 'required': true - } - }] - }, - 'hb_source': 1 - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '256e5e4b136d05', - 'tag_id': 13232392, - 'auction_id': '6287559286677633407', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKICKAIBAAAAwDWAAUBCM3FpfEFEP_yg9W7u_mgVxi7_-bKzp3kuD8qNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIjSpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5NzcwNTczKTsBHSxyJywgOTc1MjA0MzQ2HgDw0JICtQIhQWp4NUh3aUgtYndLRUxLV3dDNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUWlOS25CbGdBWUtzR2FBQndBbmlLQVlBQkhvZ0JpZ0dRQVFDWUFRQ2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCb2FZc1BwVDM0VF9aQVFBQUFBQUFBUEFfNEFFQTlRRUFBQUFBbUFJQW9BSUF0UUlBQUFBQXZRSUFBQUFBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQU9IAcSIdWdNSlUwbE9Nem8wT0RRMDRBUDRHWWdFQUpBRUFKZ0VBY0UJXQUBCERKQgUICQEYMkFRQThRUQkNAQEsUGdFQUlnRjdDV3BCERc0UEFfmgKJASFDZy1TX2c2OQEkblBGYklBUW9BRBVkDGtRRG8ykQAQUVBnWlMdTQBVEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCS2h0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTw3i9wYWdlcy9tdWx0aXBsZV9iaWRkZXJzLmh0bWw_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQOMTAzLjc5LjEwMC4xODCoBOZCsgQQCAQQARgAIAAoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODQ02gQCCADgBAHwBLKWwC6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAABDnDYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgEhMAAA8L_QBvUv2gYWChAJERkBUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=8b14b952b73092945ef66436be991786b53f7a68', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'native', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 97520434, - 'media_type_id': 12, - 'media_subtype_id': 65, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 53, - 'client_initiated_ad_counting': true, - 'viewability': { - 'config': '' - }, - 'rtb': { - 'native': { - 'title': 'This is a Prebid Native Creative', - 'sponsored': 'Prebid.org', - 'main_img': { - 'url': 'https://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg', - 'width': 989, - 'height': 742, - 'prevent_crop': false - }, - 'link': { - 'url': 'http://prebid.org/dev-docs/show-multi-format-ads.html', - 'click_trackers': ['https://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQH_5oLrb5UFXu79Z6eyQcT_NYileAAAAAAjpyQBtJAAAbSQAAAIAAAAyC9AFnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAnRbC8wAAAAA./bcr=AAAAAAAA8D8=/cnd=%21Cg-S_giH-bwKELKWwC4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0ODQ0QPgZSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ4NDQ=/bn=89112/'] - }, - 'impression_trackers': ['https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKQCKAQBAAAAwDWAAUBCM3FpfEFEP_yg9W7u_mgVxi7_-bKzp3kuD8qNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIjSpwY47UhA7UhIAlCylsAuWJzxW2AAaM26dXiYuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1Nzk3NzA1NzMpO3VmKCdyJywgOTc1MjA0MzQsIC4eAPDQkgK1AiFBang1SHdpSC1id0tFTEtXd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRaU5LbkJsZ0FZS3NHYUFCd0FuaUtBWUFCSG9nQmlnR1FBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JvYVlzUHBUMzRUX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBT0gBxIh1Z01KVTBsT016bzBPRFEwNEFQNEdZZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BASxQZ0VBSWdGN0NXcEIRFzRQQV-aAokBIUNnLVNfZzY5ASRuUEZiSUFRb0FEFWQMa1FEbzKRABBRUGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gJLaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPDeL3BhZ2VzL211bHRpcGxlX2JpZGRlcnMuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA4xMDMuNzkuMTAwLjE4MKgE5kKyBBAIBBABGAAgACgBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4NDTaBAIIAeAEAfAEspbALogFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAEOcNgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGASEwAADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=2061bd85ce022a41bc16ebb20c193aabbbc07809'], - 'id': 97520434 - } - } - }] - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js b/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js deleted file mode 100644 index ae09e4ec4a7..00000000000 --- a/test/mock-server/expectations/request-response-pairs/multiple-bidders/index-2.js +++ /dev/null @@ -1,177 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 300, - 'height': 250 - }, { - 'width': 300, - 'height': 600 - }], - 'primary_size': { - 'width': 300, - 'height': 250 - }, - 'ad_types': ['banner'], - 'id': 13232392, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'hb_source': 1 - }, { - 'sizes': [{ - 'width': 1, - 'height': 1 - }], - 'ad_types': ['native'], - 'id': 13232354, - 'allow_smaller_sizes': true, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'native': { - 'layouts': [{ - 'title': { - 'required': true - }, - 'description': { - 'required': true - }, - 'main_image': { - 'required': true - }, - 'sponsored_by': { - 'required': true - }, - 'icon': { - 'required': false - } - }] - }, - 'hb_source': 1 - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '28ae233df319a1', - 'tag_id': 13232392, - 'auction_id': '6917498423334366136', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLBCKBBBAAAAwDWAAUBCNGcpvEFELjXrYmmhfn_Xxi7_-bKzp3kuD8qNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQn0gQEkQDCI0qcGOO1IQO1ISABQAFic8VtgAGjNunV4AIABAYoBAJIBA1VTRJgBrAKgAfoBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5NzgxNzEzKTt1ZigncicsIDk2ODQ2MDM1LCAxNTc5NzgxNzEzKTuSArUCITZEb2NyZ2lILWJ3S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFpTktuQmxnQVlLc0dhQUJ3R25oaWdBR1lBWWdCWXBBQkFKZ0JBS0FCQWFnQkE3QUJBTGtCODYxcXBBQUFKRURCQWZPdGFxUUFBQ1JBeVFHQ1VBT2x6Q0xkUDlrQkFBQUFBQUFBOERfZ0FRRDFBUUFBQUFDWUFnQ2dBZ0MxQWdBQUFBQzlBZ0FBQUFEZ0FnRG9BZ0Q0QWdDQUF3R1lBd0dvQTRmNXZBcTZBd2xUU1U0ek9qUTNNem5nQV9nWmlBUUFrQVFBbUFRQndRUQFNCQEITWtFCQkBARhEWUJBRHhCAQsNASwtQVFBaUFXREpha0YNE0BBOEQ4LpoCiQEhOEE1YjlRaTI5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME56TTVRUGdaU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EZlQUEuwgI1aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1tdWx0aS1mb3JtYXQtYWRzLmh0bWzYAgDgAq2YSOoCSw1ASHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvBUYocGxlX2JpZGRlcnMFRvBAP3BianNfZGVidWc9dHJ1ZYADAIgDAZADAJgDF6ADAaoDAMADrALIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMNtvBhmAQAogQOMTAzLjc5LjEwMC4xODCoBJ9EsgQSCAQQARisAiD6ASgBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MznaBAIIAOAEAfAE04GXLogFAZgFAKAF______8BAxQBwAUAyQVpiBTwP9IFCQkJDHAAANgFAeAFAfAFAfoFBAgAEACQBgCYBgC4BgDBBgkjKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYB8gYCCACABwGIBwCgBwE.&s=8d42ac30ca2d2a8a63215f5aba2a43bd23af0023', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'banner', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 96846035, - 'media_type_id': 1, - 'media_subtype_id': 1, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 0, - 'client_initiated_ad_counting': true, - 'rtb': { - 'banner': { - 'content': "
", - 'width': 300, - 'height': 250 - }, - 'trackers': [{ - 'impression_urls': ['https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLJCKBJBAAAAwDWAAUBCNGcpvEFELjXrYmmhfn_Xxi7_-bKzp3kuD8qNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIjSpwY47UhA7UhIAlDTgZcuWJzxW2AAaM26dXicuAWAAQGKAQNVU0SSAQEG8FKYAawCoAH6AagBAbABALgBAcABBMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3OTc4MTcxMyk7dWYoJ3InLCA5Njg0NjAzNTYeAPCakgK1AiE2RG9jcmdpSC1id0tFTk9CbHk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRaU5LbkJsZ0FZS3NHYUFCd0duaGlnQUdZQVlnQllwQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRR0NVQU9sekNMZFA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BNGY1dkFxNkF3bFRTVTR6T2pRM016bmdBX2daaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVdESmFrRg0TPEE4RDgumgKJASE4QTViOVE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBOek01UVBnWlNRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBGZUFBLsICNWh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctbXVsdGktZm9ybWF0LWFkcy5odG1s2AIA4AKtmEjqAksNQEh0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLwVGKHBsZV9iaWRkZXJzBUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbbwYZgEAKIEDjEwMy43OS4xMDAuMTgwqASfRLIEEggEEAEYrAIg-gEoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM52gQCCAHgBAHwBNOBly6IBQGYBQCgBf______AQMUAcAFAMkFaZAU8D_SBQkJCQxwAADYBQHgBQHwBQH6BQQIABAAkAYAmAYAuAYAwQYJIyjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=6c6fb8a005b60bc5535b528c16ed74cd66c08dd0'], - 'video_events': {} - }] - } - }] - }, { - 'uuid': '375d249fda4d84', - 'tag_id': 13232354, - 'auction_id': '2793298983265666969', - 'nobid': false, - 'no_ad_url': 'https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKGCKAGBAAAAwDWAAUBCNGcpvEFEJmPioiD1PLhJhi7_-bKzp3kuD8qNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5NzgxNzEzKTsBHSxyJywgOTc0OTQyMDQ2HgDw0JICtQIhZ2oxVmFnajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWUtzR2FBQndCbmlhQklBQm1BR0lBV0tRQVFDWUFRQ2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCQXNyenVXOVg0RF9aQVFBQUFBQUFBUEFfNEFFQTlRRUFBQUFBbUFJQW9BSUF0UUlBQUFBQXZRSUFBQUFBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQVA4AcSIdWdNSlUwbE9Nem8wTnpNNTRBUDRHWWdFQUpBRUFKZ0VBY0UJXQUBCERKQgUICQEYMkFRQThRUQkNAQEsUGdFQUlnRmd5V3BCERc0UEFfmgKJASF2QS1kUHc2OQEkblBGYklBUW9BRBVkDGtRRG8ykQAQUVBnWlMdTQBVEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCS2h0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRT0DgEvcGFnZXMvbXVsdGlwbGVfYmlkZGVycy5odG1sP3BianNfZGVidWc9dHJ1ZYADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDjEwMy43OS4xMDAuMTgwqASfRLIEDggAEAEYACAAKAAwADgCuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MznaBAIIAOAEAfAEvMm-LogFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYM8gYCCACABwGIBwCgB0E.&s=acd26154fe24e1ce797e3016322901140c18ce65', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'native', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 97494204, - 'media_type_id': 12, - 'media_subtype_id': 65, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 53, - 'client_initiated_ad_counting': true, - 'viewability': { - 'config': '' - }, - 'rtb': { - 'native': { - 'title': 'This is a Prebid Native Creative', - 'desc': 'This is a Prebid Native Creative. There are many like it, but this one is mine.', - 'sponsored': 'Prebid.org', - 'icon': { - 'url': 'https://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png', - 'width': 127, - 'height': 83, - 'prevent_crop': false - }, - 'main_img': { - 'url': 'https://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg', - 'width': 989, - 'height': 742, - 'prevent_crop': false - }, - 'link': { - 'url': 'http://prebid.org/dev-docs/show-native-ads.html', - 'click_trackers': ['https://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQJmHAjGgysMmu79Z6eyQcT9RjileAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAxBbHxgAAAAA./bcr=AAAAAAAA8D8=/cnd=%21vA-dPwj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzM5QPgZSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3Mzk=/bn=89116/'] - }, - 'impression_trackers': ['https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKOCKAOBAAAAwDWAAUBCNGcpvEFEJmPioiD1PLhJhi7_-bKzp3kuD8qNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXicuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1Nzk3ODE3MTMpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPDQkgK1AiFnajFWYWdqOC1Md0tFTHpKdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZS3NHYUFCd0JuaWFCSUFCbUFHSUFXS1FBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JBc3J6dVc5WDREX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOek01NEFQNEdZZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BASxQZ0VBSWdGZ3lXcEIRFzRQQV-aAokBIXZBLWRQdzY5ASRuUEZiSUFRb0FEFWQMa1FEbzKRABBRUGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gJLaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPQOAS9wYWdlcy9tdWx0aXBsZV9iaWRkZXJzLmh0bWw_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQOMTAzLjc5LjEwMC4xODCoBJ9EsgQOCAAQARgAIAAoADAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczOdoEAggB4AQB8AS8yb4uiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8D_QBvUv2gYWChAJERkBUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=2d3f9336af4da684d7733e29f53bbb80bf69a18c'], - 'id': 97494204 - } - } - }] - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/native/index.js b/test/mock-server/expectations/request-response-pairs/native/index.js deleted file mode 100644 index 201e9834b68..00000000000 --- a/test/mock-server/expectations/request-response-pairs/native/index.js +++ /dev/null @@ -1,193 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 1, - 'height': 1 - }], - 'ad_types': ['native'], - 'id': 13232354, - 'allow_smaller_sizes': true, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'native': { - 'layouts': [{ - 'title': { - 'required': true - }, - 'main_image': { - 'required': true - }, - 'sponsored_by': { - 'required': true - } - }] - }, - 'hb_source': 1 - }, { - 'sizes': [{ - 'width': 1, - 'height': 1 - }], - 'ad_types': ['native'], - 'id': 13232354, - 'allow_smaller_sizes': true, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'native': { - 'layouts': [{ - 'title': { - 'required': true - }, - 'description': { - 'required': true - }, - 'main_image': { - 'required': true - }, - 'sponsored_by': { - 'required': true - }, - 'icon': { - 'required': false - } - }] - }, - 'hb_source': 1 - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '2b7ae9fa0e76be', - 'tag_id': 13232354, - 'auction_id': '2566965852006062421', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLhB6DhAwAAAwDWAAUBCNDZme8FENWyhPv4uuzPIxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc1MzgyMjI0KTsBHThyJywgOTc0OTQ0MDMsIDEdHvDQkgKpAiFCenhPTlFqOC1Md0tFSVBMdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JRTDdBTHVfbzFqX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVBQZ0VBSWdGaGlVLpoCiQEhYWdfb0o6LQEkblBGYklBUW9BRBVYDGtRRG8yhQAQUU9ZV1MRWAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCMWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTwvC9wYWdlcy9uYXRpdmUuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATruAKyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQy2gQCCADgBAHwBIPLvi6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQkMeAAA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYJJTTwv8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=54514bb848c51d509dfe3e21af09b77edfe9738e', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'native', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 97494403, - 'media_type_id': 12, - 'media_subtype_id': 65, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 53, - 'client_initiated_ad_counting': true, - 'viewability': { - 'config': '' - }, - 'rtb': { - 'native': { - 'title': 'This is a Prebid Native Creative', - 'sponsored': 'Prebid.org', - 'main_img': { - 'url': 'http://vcdn.adnxs.com/p/creative-image/94/22/cd/0f/9422cd0f-f400-45d3-80f5-2b92629d9257.jpg', - 'width': 3000, - 'height': 2250, - 'prevent_crop': false - }, - 'link': { - 'url': 'http://prebid.org/dev-docs/show-native-ads.html', - 'click_trackers': ['http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQFUZYY_XsZ8jKnKSKrrb42HQbOZdAAAAAOLoyQBtJAAAbSQAAAIAAACDpc8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoA8BZszgAAAAA./bcr=AAAAAAAA8D8=/cnd=%21ag_oJQj8-LwKEIPLvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzQyQOYWSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3NDI=/bn=89169/'] - }, - 'impression_trackers': ['http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLpB6DpAwAAAwDWAAUBCNDZme8FENWyhPv4uuzPIxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlCDy74uWJzxW2AAaM26dXjRuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzUzODIyMjQpO3VmKCdyJywgOTc0OTQ0MDMsIC4eAPDQkgKpAiFCenhPTlFqOC1Md0tFSVBMdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JRTDdBTHVfbzFqX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVBQZ0VBSWdGaGlVLpoCiQEhYWdfb0o6LQEkblBGYklBUW9BRBVYDGtRRG8yhQAQUU9ZV1MRWAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCMWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTwlS9wYWdlcy9uYXRpdmUuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATruAKyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQy2gQCCAHgBAHwBEH6IIgFAZgFAKAF_xEBGAHABQDJBQAFARTwP9IFCQkFC3wAAADYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgEhQAAA8D_IBgDQBvUv2gYWChAAOgEAUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=6b203c7aee654cffa9c0b3771f6945f6d1e8d06c'], - 'id': 97494403 - } - } - }] - }, { - 'uuid': '35598a5ad26f59', - 'tag_id': 13232354, - 'auction_id': '6083251961435599864', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLhB6DhAwAAAwDWAAUBCNDZme8FEPjnxITbrYO2VBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc1MzgyMjI0KTsBHSxyJywgOTc0OTQyMDQ2HgDw0JICqQIhYlR3OWZBajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWUlJQ2FBQndBSGdBZ0FHbUFZZ0JfRi1RQVFDWUFRQ2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCeVdmYjBYeWIxVF9aQVFBQUFBQUFBUEFfNEFFQTlRRUFBQUFBbUFJQW9BSUF0UUlBQUFBQXZRSUFBQUFBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQVA4AcSIdWdNSlUwbE9Nem8wTnpReTRBUG1Gb2dFQUpBRUFKZ0VBY0UJXQUBCERKQgUICQEYMkFRQThRUQkNAQFUUGdFQUlnRmhpVS6aAokBIW9ROTNPUTYtASRuUEZiSUFRb0FEFVgMa1FEbzKFABBRT1lXUxFYDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gIxaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPC8L3BhZ2VzL25hdGl2ZS5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBOu4ArIEDggAEAEYACAAKAAwADgCuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDLaBAIIAOAEAfAEvMm-LogFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJCQx4AADYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgklNPC_yAYA0Ab1L9oGFgoQCRQZAVAQABgA4AYM8gYCCACABwGIBwCgB0E.&s=99a73b39ab82dd9384eee306ff03276ab688cfe5', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'native', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 97494204, - 'media_type_id': 12, - 'media_subtype_id': 65, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 53, - 'client_initiated_ad_counting': true, - 'viewability': { - 'config': '' - }, - 'rtb': { - 'native': { - 'title': 'This is a Prebid Native Creative', - 'desc': 'This is a Prebid Native Creative. There are many like it, but this one is mine.', - 'sponsored': 'Prebid.org', - 'icon': { - 'url': 'http://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png', - 'width': 127, - 'height': 83, - 'prevent_crop': false - }, - 'main_img': { - 'url': 'http://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg', - 'width': 989, - 'height': 742, - 'prevent_crop': false - }, - 'link': { - 'url': 'http://prebid.org/dev-docs/show-native-ads.html', - 'click_trackers': ['http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQPgzkbBtDWxUKnKSKrrb42HQbOZdAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAJhcX3AAAAAA./bcr=AAAAAAAA8D8=/cnd=%21oQ93OQj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzQyQOYWSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3NDI=/bn=89169/'] - }, - 'impression_trackers': ['http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLpB6DpAwAAAwDWAAUBCNDZme8FEPjnxITbrYO2VBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXjRuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzUzODIyMjQpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPDQkgKpAiFiVHc5ZkFqOC1Md0tFTHpKdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0J5V2ZiMFh5YjFUX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVRQZ0VBSWdGaGlVLpoCiQEhb1E5M09RNi0BJG5QRmJJQVFvQUQVWAxrUURvMoUAEFFPWVdTEVgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDKBlQUEu2AIA4AKtmEjqAjFodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OQUU8LwvcGFnZXMvbmF0aXZlLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagE67gCsgQOCAAQARgAIAAoADAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDc0MtoEAggB4AQB8AS8yb4uiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkJDHgAANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSU48D_IBgDQBvUv2gYWChAAOgEAUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=5c316c116b6e2bdb19f3950c4c769821e735688e'], - 'id': 97494204 - } - } - }] - }] - } - } - } -} diff --git a/test/mock-server/expectations/request-response-pairs/outstream/index.js b/test/mock-server/expectations/request-response-pairs/outstream/index.js deleted file mode 100644 index ad2502aff2d..00000000000 --- a/test/mock-server/expectations/request-response-pairs/outstream/index.js +++ /dev/null @@ -1,164 +0,0 @@ -var app = require('../../../index'); - -/** - * This file will have the fixtures for request and response. Each one has to export two functions getRequest and getResponse. - * expectation directory will hold all the request reponse pairs of different types. middlewares added to the server will parse - * these files and return the response when expecation is met - * - */ - -/** - * This function will return the request object with all the entities method, path, body, header etc. - * - * @return {object} Request object - */ -exports.getRequest = function() { - return { - 'httpRequest': { - 'method': 'POST', - 'path': '/', - 'body': { - 'tags': [{ - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 13232385, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'video': { - 'skippable': true, - 'playback_method': ['auto_play_sound_off'] - }, - 'hb_source': 1 - }, { - 'sizes': [{ - 'width': 640, - 'height': 480 - }], - 'primary_size': { - 'width': 640, - 'height': 480 - }, - 'ad_types': ['video'], - 'id': 13232385, - 'allow_smaller_sizes': false, - 'use_pmt_rule': false, - 'prebid': true, - 'disable_psa': true, - 'video': { - 'skippable': true, - 'playback_method': ['auto_play_sound_off'] - }, - 'hb_source': 1 - }], - 'user': {} - } - } - } -} - -/** - * This function will return the response object with all the entities method, path, body, header etc. - * - * @return {object} Response object - */ -exports.getResponse = function() { - return { - 'httpResponse': { - 'body': { - 'version': '3.0.0', - 'tags': [{ - 'uuid': '223e8549781f2e', - 'tag_id': 13232385, - 'auction_id': '527250675737245396', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Foutstream.html&e=wqT_3QKwCKAwBAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIHSpwY47UhA7UhIAFAAWJzxW2AAaOWljwF4AIABAYoBAJIBA1VTRJgBAaABAagBAbABALgBA8ABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3NTU1Mzg5NikFHTRyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_yIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzLwmj8F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAOAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWlyFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwv8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9953ce4d94992db04897ab580bf81b3e274b2601', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQloC-ldAAAAABHUNucysitRBxloC-ldAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQgdKnBljDlQtiAi0taAFwAXgAgAECiAEEkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=979aee1106a0bea5609a3c23fdc46153ad6d9eec&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 97517771, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 36, - 'renderer_url': 'http://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - 'renderer_id': 2, - 'renderer_config': '{"skippable":{"videoThreshold":null,"skipLocation":"top-right"}}', - 'client_initiated_ad_counting': true, - 'viewability': { - 'config': 'tv=vh2-121&d=1x1&s=3479483&st=0&vctx=4&ts=1575553896&vc=iab;vid_ccr=1&vjs=http%3A%2F%2Fcdn.adnxs.com%2Fv%2Fvideo%2F182%2Ftrk.js&cb=http%3A%2F%2Fsin3-ib.adnxs.com%2Fvevent%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QK4CKA4BAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_yIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzLwmj8F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAeAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWl6FPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwP8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA%26s%3D5adef946cd5f0d8db86d67860914e02ef6f91d6b&cet=0&cecb=&rdcb=http%3A%2F%2Fsin3-ib.adnxs.com%2Frd_log%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QKMCaCMBAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_aPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7gSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDffwXpgEAKIECzEwLjc1Ljc0LjY5qASYzwKyBBIIBBAEGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDgzNNoEAggB4AQA8ATLgcAuiAUBmAUAoAX_____BQMUAcAFAMkFac4U8D_SBQkJCQx4AADYBQHgBQHwBcOVC_oFBAgAEACQBgGYBgC4BgDBBgklNPA_yAYA0Ab1L9oGFgoQCRQZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.%26s%3Df2a73057b50fb0c9e98a6093141472a4ed2e401e&bridge=1.11.0&rblog=auc=527250675737245396;bm=9325;sm=9325;cr=97517771;pl=13232385&vid_context=anoutstream;anbannerstream;anoverlayplayer' - }, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_off'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'content': 'adnxs00:00:30.000' - } - } - }] - }, { - 'uuid': '3acfd472dd4bdf', - 'tag_id': 13232385, - 'auction_id': '3449642271543746980', - 'nobid': false, - 'no_ad_url': 'http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Foutstream.html&e=wqT_3QKwCKAwBAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIHSpwY47UhA7UhIAFAAWJzxW2AAaOWljwF4AIABAYoBAJIBA1VTRJgBAaABAagBAbABALgBA8ABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3NTU1Mzg5NikFHTRyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP8iAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My8Jo_BemAQAogQLMTAuNzUuNzQuNjmoBJjPArIEEggEEAQYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODM02gQCCADgBADwBMuBwC6IBQGYBQCgBf____8FAxQBwAUAyQVpchTwP9IFCQkJDHgAANgFAeAFAfAFw5UL-gUECAAQAJAGAZgGALgGAMEGCSU08L_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=e43b45a2391036da6d93eda546d8808de0169bb1', - 'timeout_ms': 0, - 'ad_profile_id': 1182765, - 'rtb_video_fallback': false, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'notify_url': 'http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQloC-ldAAAAABGkYYl1XpffLxloC-ldAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQgdKnBljDlQtiAi0taAFwAXgAgAECiAEEkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=414834fdc6e268f284292aedf8b01ee525c3e999&event_type=1', - 'usersync_url': 'http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html', - 'buyer_member_id': 9325, - 'advertiser_id': 2529885, - 'creative_id': 97517771, - 'media_type_id': 4, - 'media_subtype_id': 64, - 'cpm': 10.000000, - 'cpm_publisher_currency': 10.000000, - 'publisher_currency_code': '$', - 'brand_category_id': 36, - 'renderer_url': 'http://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - 'renderer_id': 2, - 'renderer_config': '{"skippable":{"videoThreshold":null,"skipLocation":"top-right"}}', - 'client_initiated_ad_counting': true, - 'viewability': { - 'config': 'tv=vh2-121&d=1x1&s=3479483&st=0&vctx=4&ts=1575553896&vc=iab;vid_ccr=1&vjs=http%3A%2F%2Fcdn.adnxs.com%2Fv%2Fvideo%2F182%2Ftrk.js&cb=http%3A%2F%2Fsin3-ib.adnxs.com%2Fvevent%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QK4CKA4BAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP8iAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My8Jo_BemAQAogQLMTAuNzUuNzQuNjmoBJjPArIEEggEEAQYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODM02gQCCAHgBADwBMuBwC6IBQGYBQCgBf____8FAxQBwAUAyQVpehTwP9IFCQkJDHgAANgFAeAFAfAFw5UL-gUECAAQAJAGAZgGALgGAMEGCSU08D_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..%26s%3Dc2a8dac8959d9366981afc868ec5b54853090944&cet=0&cecb=&rdcb=http%3A%2F%2Fsin3-ib.adnxs.com%2Frd_log%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QKMCaCMBAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP2jyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-4ElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw338F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAeAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWnOFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwP8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA%26s%3D4e9e218d8f075cb19c4a4e8da2a7e716fa15d3c5&bridge=1.11.0&rblog=auc=3449642271543746980;bm=9325;sm=9325;cr=97517771;pl=13232385&vid_context=anoutstream;anbannerstream;anoverlayplayer' - }, - 'rtb': { - 'video': { - 'player_width': 640, - 'player_height': 480, - 'duration_ms': 30000, - 'playback_methods': ['auto_play_sound_off'], - 'frameworks': ['vpaid_1_0', 'vpaid_2_0'], - 'content': 'adnxs00:00:30.000' - } - } - }] - }] - } - } - } -} diff --git a/test/mock-server/index.js b/test/mock-server/index.js deleted file mode 100644 index 9a97ca5e0a0..00000000000 --- a/test/mock-server/index.js +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-disable no-console */ -const express = require('express'); -const argv = require('yargs').argv; -const app = module.exports = express(); -const port = (argv.port) ? argv.port : 3000; -const bodyParser = require('body-parser'); -const renderCreative = require('./request-middlewares/prebid-request.js'); - -app.use(express.static(__dirname + '/content')); -app.use(bodyParser.text({type: 'text/plain'})); - -app.locals = { - 'port': port, - 'host': 'localhost' -}; - -// get type will be used to test prebid jsonp requests -app.get('/', renderCreative, (request, response) => { - response.send(); -}); - -// prebid make POST type request to ut endpoint so here we will match ut endpoint request. -app.post('/', renderCreative, (request, response) => { - response.send(); -}); - -app.listen(port, (err) => { - if (err) { - return console.log('something bad happened', err); - } - - console.log(`server is listening on ${port}`); -}); - -process.on('SIGTERM', function() { console.log('halt mock-server'); process.exit(0) }); - -process.on('SIGINT', function() { console.log('shutdown mock-server'); process.exit(0) }); diff --git a/test/mock-server/request-middlewares/prebid-request.js b/test/mock-server/request-middlewares/prebid-request.js deleted file mode 100644 index b14c3119247..00000000000 --- a/test/mock-server/request-middlewares/prebid-request.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * This middleware will be used to find matching request hitting the ut endpoint by prebid. - * As of now it only uses the request payload to compare with httpRequest.body defined in expectations dir. - * Matching headers or cookies can also be the use case. - */ - -const glob = require('glob'); -const path = require('path'); -const deepEqual = require('deep-equal'); - -module.exports = function (req, res, next) { - let reqBody; - try { - if (req.method === 'GET') { - reqBody = JSON.parse(req.query.q); - } else { - reqBody = JSON.parse(req.body); - } - } catch (e) { - // error - } - - // prebid uses uuid to match request response pairs. - // On each request new uuid is generated, so here i am grabbing the uuid from incoming request and adding it to matched response. - let uuidObj = {}; - if (reqBody && reqBody.uuid) { - uuidObj.response = reqBody.uuid; - delete reqBody.uuid; - } - - if (reqBody && reqBody.tags) { - uuidObj.tags = reqBody.tags.map((tag) => { - let uuid = tag.uuid; - delete tag.uuid; - return uuid; - }); - } - - // values within these request props are dynamically generated and aren't - // vital to check in these tests, so they are deleted rather than updating - // the request-response pairs continuously - ['sdk', 'referrer_detection', 'brand_category_uniqueness', 'gdpr_consent'].forEach(prop => { - if (reqBody && reqBody[prop]) { - delete reqBody[prop]; - } - }); - - // Parse all the expectation to find response for this request - glob.sync('./test/mock-server/expectations/**/*.js').some((file) => { - file = require(path.resolve(file)); - let expectedReqBody = JSON.parse(JSON.stringify(file.getRequest().httpRequest.body)); - // respond to all requests - // TODO send a 404 if resource not found - res.set({ - 'Access-Control-Allow-Credentials': 'true', - 'Access-Control-Allow-Origin': req.headers.origin - }); - - // As of now only body is compared. We can also add other request properties like headers, cookies if required - if (deepEqual(reqBody, expectedReqBody)) { - let response = file.getResponse().httpResponse.body; - if (Object.keys(uuidObj).length > 0) { - response.tags.forEach((tag, index) => { - tag.uuid = uuidObj.tags[index]; - }); - } - res.type('json'); - response = JSON.stringify(response); - res.write(response); - return true; - } - }); - - next(); -}; diff --git a/test/pages/banner.html b/test/pages/banner.html index e1859abdd85..75993cefb39 100644 --- a/test/pages/banner.html +++ b/test/pages/banner.html @@ -31,22 +31,20 @@ } }] } - //, { - // code: 'div-gpt-ad-1460505748561-1', - // mediaTypes: { - // banner: { - // sizes: [[300, 250], [300, 600]], - // } - // }, - // bids: [{ - // bidder: "appnexus", - // params: { - // accountId: 14062, - // siteId: 70608, - // zoneId: 498816 - // } - // }] - // } + ,{ + code: 'div-gpt-ad-1460505748561-1', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + } + }, + bids: [{ + bidder: "appnexus", + params: { + placementId: 13144370 + } + }] + } ]; @@ -54,18 +52,18 @@ var googletag = googletag || {}; googletag.cmd = googletag.cmd || []; - googletag.cmd.push(() => { + googletag.cmd.push(function() { googletag.pubads().disableInitialLoad(); }); - pbjs.que.push(() => { + pbjs.que.push(function () { pbjs.addAdUnits(adUnits); pbjs.requestBids({ bidsBackHandler: sendAdServerRequest }); }); function sendAdServerRequest() { - googletag.cmd.push(() => { - pbjs.que.push(() => { + googletag.cmd.push(function () { + pbjs.que.push(function () { pbjs.setTargetingForGPTAsync('div-gpt-ad-1460505748561-0'); googletag.pubads().refresh(); }); @@ -74,7 +72,7 @@
diff --git a/test/pages/bidderSettings.html b/test/pages/bidderSettings.html index a4a718d6497..015ad3ca45f 100644 --- a/test/pages/bidderSettings.html +++ b/test/pages/bidderSettings.html @@ -1,125 +1,127 @@ + - - - + + + - + function sendAdserverRequest() { + if (pbjs.adserverRequestSent) return; + pbjs.adserverRequestSent = true; + googletag.cmd.push(function () { + pbjs.que.push(function () { + pbjs.setTargetingForGPTAsync(); + googletag.pubads().refresh(); + }); + }); + } - - googletag.pubads().enableSingleRequest(); - googletag.enableServices(); - }); - + -

Prebid.js Test

-
Div-1
-
+

Prebid.js Test

+
Div-1
+
-
+
- + + \ No newline at end of file diff --git a/test/pages/consent_mgt_gdpr.html b/test/pages/consent_mgt_gdpr.html index a7da17ca2f7..02b367b3c7c 100644 --- a/test/pages/consent_mgt_gdpr.html +++ b/test/pages/consent_mgt_gdpr.html @@ -1,206 +1,208 @@ - - - - - + + - - + + + + - - - - + }); + } + + + + + +

Prebid.js Test

Div-1
- +
- - + + + \ No newline at end of file diff --git a/test/pages/currency.html b/test/pages/currency.html index 5214982f67c..7f196e60d5e 100644 --- a/test/pages/currency.html +++ b/test/pages/currency.html @@ -80,7 +80,7 @@ "currency": { "adServerCurrency": "GBP", "granularityMultiplier": 1, - "defaultRates": { "USD": { "GBP": 0.75 }} + "defaultRates": { "USD": { "GBP": 0.80 }} } }); pbjs.addAdUnits(adUnits); diff --git a/test/pages/instream.html b/test/pages/instream.html index be7aceb40db..c1e2358b754 100644 --- a/test/pages/instream.html +++ b/test/pages/instream.html @@ -49,6 +49,14 @@ }; pbjs.que.push(function(){ + pbjs.onEvent('auctionEnd', function() { + let pEl = document.createElement('p'); + pEl.innerText = 'PREBID HAS FINISHED'; + pEl.id = 'statusText'; + let parDiv = document.getElementById('event-window'); + parDiv.appendChild(pEl); + }); + pbjs.addAdUnits(videoAdUnit); pbjs.setConfig({ debug: true, @@ -57,7 +65,6 @@ } }); pbjs.requestBids({ - timeout : 700, bidsBackHandler : function(bids) { var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ adUnit: videoAdUnit, @@ -70,36 +77,13 @@ } }); }); - - pbjs.bidderSettings = - { - standard: { - adserverTargeting: [ - { - key: "hb_bidder", - val: function (bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: "hb_adid", - val: function (bidResponse) { - return bidResponse.adId; - } - }, { - key: "hb_pb", - val: function (bidResponse) { - return "10.00"; - } - }, { - key: "hb_size", - val: function (bidResponse) { - return bidResponse.size; - - } - } - ] + pbjs.bidderSettings = { + appnexus: { + bidCpmAdjustment: function() { + return 10.00; } - }; + } + }; @@ -107,6 +91,7 @@

Prebid Video -- video.js

+
diff --git a/test/pages/outstream.html b/test/pages/outstream.html index 2a0543095cd..262c15ed02a 100644 --- a/test/pages/outstream.html +++ b/test/pages/outstream.html @@ -62,7 +62,14 @@ pbjs.que.push(function () { pbjs.setConfig({ debug: true }); - pbjs.addAdUnits(outstreamVideoAdUnit); + pbjs.addAdUnits(outstreamVideoAdUnit); + pbjs.bidderSettings = { + appnexus: { + bidCpmAdjustment: function () { + return 10; + } + } + }; pbjs.requestBids({ bidsBackHandler: initAdServer }); }); diff --git a/test/pages/priceGranularity.html b/test/pages/priceGranularity.html index 588b11044fb..7eae83f673a 100644 --- a/test/pages/priceGranularity.html +++ b/test/pages/priceGranularity.html @@ -1,131 +1,133 @@ + - - - + + + - + - + googletag.pubads().enableSingleRequest(); + googletag.enableServices(); + }); + -

Prebid.js Test

-
Div-1
-
+

Prebid.js Test

+
Div-1
+
-
+
- + + \ No newline at end of file diff --git a/test/pages/sizeConfig.html b/test/pages/sizeConfig.html index b62b4a741ab..a4aef89e44a 100644 --- a/test/pages/sizeConfig.html +++ b/test/pages/sizeConfig.html @@ -1,142 +1,144 @@ + - - - + + + - + - + googletag.pubads().enableSingleRequest(); + googletag.enableServices(); + }); + -

Prebid.js Test

-
Div-1
-
+

Prebid.js Test

+
Div-1
+
-
+
- + + \ No newline at end of file diff --git a/test/pages/userSync.html b/test/pages/userSync.html index 43aeafd46e9..3d848906ae3 100644 --- a/test/pages/userSync.html +++ b/test/pages/userSync.html @@ -1,121 +1,123 @@ + - - - + + + - + function sendAdserverRequest() { + if (pbjs.adserverRequestSent) return; + pbjs.adserverRequestSent = true; + googletag.cmd.push(function () { + pbjs.que.push(function () { + pbjs.setTargetingForGPTAsync(); + googletag.pubads().refresh(); + }); + }); + } - - googletag.pubads().enableSingleRequest(); - googletag.enableServices(); - }); - + -

Prebid.js Test

-
Div-1
-
+

Prebid.js Test

+
Div-1
+
-
+
- + + \ No newline at end of file diff --git a/test/spec/e2e/banner/basic_banner_ad.spec.js b/test/spec/e2e/banner/basic_banner_ad.spec.js index fa2d5af142f..7088bd3eade 100644 --- a/test/spec/e2e/banner/basic_banner_ad.spec.js +++ b/test/spec/e2e/banner/basic_banner_ad.spec.js @@ -1,27 +1,28 @@ const expect = require('chai').expect; -const { host, protocol } = require('../../../helpers/testing-utils'); +const { host, protocol, waitForElement, switchFrame } = require('../../../helpers/testing-utils'); const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/banner.html?pbjs_debug=true`; -const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; +const CREATIVE_IFRAME_ID = 'google_ads_iframe_/19968336/header-bid-tag-0_0'; +const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="' + CREATIVE_IFRAME_ID + '"]'; const EXPECTED_TARGETING_KEYS = { 'hb_format': 'banner', 'hb_source': 'client', - 'hb_pb': '0.60', - 'hb_bidder': 'rubicon', - 'hb_format_rubicon': 'banner', - 'hb_source_rubicon': 'client', - 'hb_pb_rubicon': '0.60', - 'hb_bidder_rubicon': 'rubicon' + 'hb_pb': '0.50', + 'hb_bidder': 'appnexus', + 'hb_format_appnexus': 'banner', + 'hb_source_appnexus': 'client', + 'hb_pb_appnexus': '0.50', + 'hb_bidder_appnexus': 'appnexus' }; describe('Prebid.js Banner Ad Unit Test', function () { + this.retries(3); before(function loadTestPage() { - browser.url(TEST_PAGE_URL).pause(3000); + browser.url(TEST_PAGE_URL); + browser.pause(3000); try { - browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; - browser.frame(creativeIframe); + waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 3000); } catch (e) { // If creative Iframe didn't load, repeat the steps again! // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js @@ -29,21 +30,21 @@ describe('Prebid.js Banner Ad Unit Test', function () { } }); - // TODO: Add below test again. Removed the test since we are testing only for appnexus endpoint now and appnexus adapter does not set AdserverTargetting. + it('should load the targeting keys with correct values', function () { + const result = browser.execute(function () { + return window.pbjs.getAdserverTargeting('div-gpt-ad-1460505748561-1'); + }); + const targetingKeys = result['div-gpt-ad-1460505748561-1']; - // it('should load the targeting keys with correct values', function () { - // const result = browser.execute(function () { - // return window.top.pbjs.getAdserverTargeting('div-gpt-ad-1460505748561-1'); - // }); - // const targetingKeys = result.value['div-gpt-ad-1460505748561-1']; - - // expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - // expect(targetingKeys.hb_adid).to.be.a('string'); - // expect(targetingKeys.hb_adid_rubicon).to.be.a('string'); - // expect(targetingKeys.hb_size).to.satisfy((size) => size === '300x250' || '300x600'); - // }); + expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); + expect(targetingKeys.hb_adid).to.be.a('string'); + expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); + expect(targetingKeys.hb_size).to.satisfy((size) => size === '300x250' || '300x600'); + }); it('should render the Banner Ad on the page', function () { - expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + switchFrame(CREATIVE_IFRAME_CSS_SELECTOR, CREATIVE_IFRAME_ID); + const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); + expect(ele.isExisting()).to.be.true; }); }); diff --git a/test/spec/e2e/instream/basic_instream_video_ad.spec.js b/test/spec/e2e/instream/basic_instream_video_ad.spec.js index 034363685d2..b712f90bf63 100644 --- a/test/spec/e2e/instream/basic_instream_video_ad.spec.js +++ b/test/spec/e2e/instream/basic_instream_video_ad.spec.js @@ -1,12 +1,10 @@ const expect = require('chai').expect; -const { host, protocol } = require('../../../helpers/testing-utils'); +const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/instream.html?pbjs_debug=true`; -const CREATIVE_IFRAME_CSS_SELECTOR = 'div[class="VPAID-container"] > div > iframe'; +const ALERT_BOX_CSS_SELECTOR = 'div[id="event-window"] > p[id="statusText"]'; const EXPECTED_TARGETING_KEYS = { - hb_cache_id: '', - hb_uuid: '', hb_format: 'video', hb_source: 'client', hb_size: '640x480', @@ -20,13 +18,12 @@ const EXPECTED_TARGETING_KEYS = { }; describe('Prebid.js Instream Video Ad Test', function () { + this.retries(3); before(function loadTestPage() { - browser - .url(TEST_PAGE_URL) + browser.url(TEST_PAGE_URL); + browser.pause(5000); try { - browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 5000); - // const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; - // browser.frame(creativeIframe); + waitForElement(ALERT_BOX_CSS_SELECTOR, 3000); } catch (e) { // If creative Iframe didn't load, repeat the steps again! // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js @@ -34,19 +31,18 @@ describe('Prebid.js Instream Video Ad Test', function () { } }); - // it('should load the targeting keys with correct values', function () { - // const result = browser.execute(function () { - // console.log('pbjs::', window.top.pbjs); - // return window.top.pbjs.getAdserverTargeting('video1'); - // }); - // console.log('result:::', result); - // const targetingKeys = result.value['vid1']; - // expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - // expect(targetingKeys.hb_adid).to.be.a('string'); - // expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - // }); + it('should load the targeting keys with correct values', function () { + const result = browser.execute(function () { + return window.top.pbjs.getAdserverTargeting('video1'); + }); - it('should render the instream ad on the page', function() { - expect(browser.isVisible(CREATIVE_IFRAME_CSS_SELECTOR)); + const targetingKeys = result['video1']; + expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); + expect(targetingKeys.hb_adid).to.be.a('string'); + expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); + expect(targetingKeys.hb_uuid).to.be.a('string'); + expect(targetingKeys.hb_cache_id).to.be.a('string'); + expect(targetingKeys.hb_uuid_appnexus).to.be.a('string'); + expect(targetingKeys.hb_cache_id_appnexus).to.be.a('string'); }); }); diff --git a/test/spec/e2e/longform/basic_w_bidderSettings.spec.js b/test/spec/e2e/longform/basic_w_bidderSettings.spec.js index 684f5acab17..d3443558316 100644 --- a/test/spec/e2e/longform/basic_w_bidderSettings.spec.js +++ b/test/spec/e2e/longform/basic_w_bidderSettings.spec.js @@ -1,9 +1,6 @@ const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; -const testServer = require('../../../helpers/testing-utils'); - -const host = testServer.host; -const protocol = testServer.protocol; +const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); const validDurations = ['15s', '30s']; const validCats = ['Food', 'Retail Stores/Chains', 'Pet Food/Supplies', 'Travel/Hotels/Airlines', 'Automotive', 'Health Care Services']; @@ -14,20 +11,20 @@ const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; describe('longform ads not using requireExactDuration field', function() { this.retries(3); it('process the bids successfully', function() { - browser - .url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_bidderSettings.html?pbjs_debug=true') - .pause(10000); + browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_bidderSettings.html?pbjs_debug=true'); + browser.pause(7000); const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - browser.waitForExist(loadPrebidBtnXpath); - $(loadPrebidBtnXpath).click(); - browser.pause(3000); + waitForElement(loadPrebidBtnXpath, 3000); + const prebidBtn = $(loadPrebidBtnXpath); + prebidBtn.click(); + browser.pause(5000); const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; const listOfCategoriesXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[3]'; const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - browser.waitForExist(listOfCpmsXpath); + waitForElement(listOfCpmsXpath, 3000); let listOfCpms = $$(listOfCpmsXpath); let listOfCats = $$(listOfCategoriesXpath); @@ -47,8 +44,8 @@ describe('longform ads not using requireExactDuration field', function() { it('formats the targeting keys properly', function () { const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - browser.waitForExist(listOfKeyElementsXpath); - browser.waitForExist(listOfKeyValuesXpath); + waitForElement(listOfKeyElementsXpath); + waitForElement(listOfKeyValuesXpath); let listOfKeyElements = $$(listOfKeyElementsXpath); let listOfKeyValues = $$(listOfKeyValuesXpath); diff --git a/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js b/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js index 175e5d041d9..9abe7295027 100644 --- a/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js +++ b/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js @@ -1,9 +1,6 @@ const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; -const testServer = require('../../../helpers/testing-utils'); - -const host = testServer.host; -const protocol = testServer.protocol; +const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); const validDurations = ['15s', '30s']; const validCats = ['Food', 'Retail Stores/Chains', 'Pet Food/Supplies', 'Travel/Hotels/Airlines', 'Automotive', 'Health Care Services']; @@ -14,20 +11,20 @@ const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; describe('longform ads using custom adserver translation file', function() { this.retries(3); it('process the bids successfully', function() { - browser - .url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_custom_adserver_translation.html?pbjs_debug=true') - .pause(10000); + browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_custom_adserver_translation.html?pbjs_debug=true'); + browser.pause(7000); const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - browser.waitForExist(loadPrebidBtnXpath); - $(loadPrebidBtnXpath).click(); - browser.pause(3000); + waitForElement(loadPrebidBtnXpath, 3000); + const prebidBtn = $(loadPrebidBtnXpath); + prebidBtn.click(); + browser.pause(5000); const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; const listOfCategoriesXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[3]'; const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - browser.waitForExist(listOfCpmsXpath); + waitForElement(listOfCpmsXpath); let listOfCpms = $$(listOfCpmsXpath); let listOfCats = $$(listOfCategoriesXpath); @@ -47,8 +44,8 @@ describe('longform ads using custom adserver translation file', function() { it('formats the targeting keys properly', function () { const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - browser.waitForExist(listOfKeyElementsXpath); - browser.waitForExist(listOfKeyValuesXpath); + waitForElement(listOfKeyElementsXpath); + waitForElement(listOfKeyValuesXpath); let listOfKeyElements = $$(listOfKeyElementsXpath); let listOfKeyValues = $$(listOfKeyValuesXpath); diff --git a/test/spec/e2e/longform/basic_w_priceGran.spec.js b/test/spec/e2e/longform/basic_w_priceGran.spec.js index 294557193b4..5658595eef7 100644 --- a/test/spec/e2e/longform/basic_w_priceGran.spec.js +++ b/test/spec/e2e/longform/basic_w_priceGran.spec.js @@ -1,9 +1,6 @@ const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; -const testServer = require('../../../helpers/testing-utils'); - -const host = testServer.host; -const protocol = testServer.protocol; +const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); const validDurations = ['15s', '30s']; const validCats = ['Food', 'Retail Stores/Chains', 'Pet Food/Supplies', 'Travel/Hotels/Airlines', 'Automotive', 'Health Care Services']; @@ -14,20 +11,20 @@ const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; describe('longform ads not using requireExactDuration field', function() { this.retries(3); it('process the bids successfully', function() { - browser - .url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_priceGran.html?pbjs_debug=true') - .pause(10000); + browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_priceGran.html?pbjs_debug=true'); + browser.pause(7000); const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - browser.waitForExist(loadPrebidBtnXpath); - $(loadPrebidBtnXpath).click(); - browser.pause(3000); + waitForElement(loadPrebidBtnXpath); + const prebidBtn = $(loadPrebidBtnXpath); + prebidBtn.click(); + browser.pause(5000); const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; const listOfCategoriesXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[3]'; const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - browser.waitForExist(listOfCpmsXpath); + waitForElement(listOfCpmsXpath); let listOfCpms = $$(listOfCpmsXpath); let listOfCats = $$(listOfCategoriesXpath); @@ -47,8 +44,8 @@ describe('longform ads not using requireExactDuration field', function() { it('formats the targeting keys properly', function () { const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - browser.waitForExist(listOfKeyElementsXpath); - browser.waitForExist(listOfKeyValuesXpath); + waitForElement(listOfKeyElementsXpath); + waitForElement(listOfKeyValuesXpath); let listOfKeyElements = $$(listOfKeyElementsXpath); let listOfKeyValues = $$(listOfKeyValuesXpath); diff --git a/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js b/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js index d92e5361ae3..886daa3e320 100644 --- a/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js +++ b/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js @@ -1,9 +1,6 @@ const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; -const testServer = require('../../../helpers/testing-utils'); - -const host = testServer.host; -const protocol = testServer.protocol; +const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); const validDurations = ['15s', '30s']; const validCats = ['Food', 'Retail Stores/Chains', 'Pet Food/Supplies', 'Travel/Hotels/Airlines', 'Automotive', 'Health Care Services']; @@ -14,20 +11,20 @@ const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; describe('longform ads using requireExactDuration field', function() { this.retries(3); it('process the bids successfully', function() { - browser - .url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_requireExactDuration.html?pbjs_debug=true') - .pause(10000); + browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_requireExactDuration.html?pbjs_debug=true'); + browser.pause(7000); const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - browser.waitForExist(loadPrebidBtnXpath); - $(loadPrebidBtnXpath).click(); - browser.pause(3000); + waitForElement(loadPrebidBtnXpath); + const prebidBtn = $(loadPrebidBtnXpath); + prebidBtn.click(); + browser.pause(5000); const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; const listOfCategoriesXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[3]'; const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - browser.waitForExist(listOfCpmsXpath); + waitForElement(listOfCpmsXpath); let listOfCpms = $$(listOfCpmsXpath); let listOfCats = $$(listOfCategoriesXpath); @@ -47,8 +44,8 @@ describe('longform ads using requireExactDuration field', function() { it('formats the targeting keys properly', function () { const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - browser.waitForExist(listOfKeyElementsXpath); - browser.waitForExist(listOfKeyValuesXpath); + waitForElement(listOfKeyElementsXpath); + waitForElement(listOfKeyValuesXpath); let listOfKeyElements = $$(listOfKeyElementsXpath); let listOfKeyValues = $$(listOfKeyValuesXpath); diff --git a/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js b/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js index de3e334e755..e19f90b8c39 100644 --- a/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js +++ b/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js @@ -1,9 +1,6 @@ const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; -const testServer = require('../../../helpers/testing-utils'); - -const host = testServer.host; -const protocol = testServer.protocol; +const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); const validDurations = ['15s', '30s']; const validCpms = ['15.00', '14.00', '13.00', '10.00']; @@ -13,19 +10,19 @@ const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; describe('longform ads without using brandCategoryExclusion', function() { this.retries(3); it('process the bids successfully', function() { - browser - .url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_wo_brandCategoryExclusion.html?pbjs_debug=true') - .pause(10000); + browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_wo_brandCategoryExclusion.html?pbjs_debug=true'); + browser.pause(7000); const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - browser.waitForExist(loadPrebidBtnXpath); - $(loadPrebidBtnXpath).click(); - browser.pause(3000); + waitForElement(loadPrebidBtnXpath); + const prebidBtn = $(loadPrebidBtnXpath); + prebidBtn.click(); + browser.pause(5000); const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - browser.waitForExist(listOfCpmsXpath); + waitForElement(listOfCpmsXpath); let listOfCpms = $$(listOfCpmsXpath); let listOfDuras = $$(listOfDurationsXpath); @@ -42,8 +39,8 @@ describe('longform ads without using brandCategoryExclusion', function() { it('formats the targeting keys properly', function () { const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - browser.waitForExist(listOfKeyElementsXpath); - browser.waitForExist(listOfKeyValuesXpath); + waitForElement(listOfKeyElementsXpath); + waitForElement(listOfKeyValuesXpath); let listOfKeyElements = $$(listOfKeyElementsXpath); let listOfKeyValues = $$(listOfKeyValuesXpath); diff --git a/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js b/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js index 849eb5ade4d..cb1bcda93ff 100644 --- a/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js +++ b/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js @@ -1,9 +1,6 @@ const includes = require('core-js-pure/features/array/includes.js'); const expect = require('chai').expect; -const testServer = require('../../../helpers/testing-utils'); - -const host = testServer.host; -const protocol = testServer.protocol; +const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); const validDurations = ['15s', '30s']; const validCats = ['Food', 'Retail Stores/Chains', 'Pet Food/Supplies', 'Travel/Hotels/Airlines', 'Automotive', 'Health Care Services']; @@ -14,20 +11,20 @@ const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; describe('longform ads not using requireExactDuration field', function() { this.retries(3); it('process the bids successfully', function() { - browser - .url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_wo_requireExactDuration.html?pbjs_debug=true') - .pause(10000); + browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_wo_requireExactDuration.html?pbjs_debug=true'); + browser.pause(7000); const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - browser.waitForExist(loadPrebidBtnXpath); - $(loadPrebidBtnXpath).click(); - browser.pause(3000); + waitForElement(loadPrebidBtnXpath); + const prebidBtn = $(loadPrebidBtnXpath); + prebidBtn.click(); + browser.pause(5000); const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; const listOfCategoriesXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[3]'; const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - browser.waitForExist(listOfCpmsXpath); + waitForElement(listOfCpmsXpath); let listOfCpms = $$(listOfCpmsXpath); let listOfCats = $$(listOfCategoriesXpath); @@ -47,8 +44,8 @@ describe('longform ads not using requireExactDuration field', function() { it('formats the targeting keys properly', function () { const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - browser.waitForExist(listOfKeyElementsXpath); - browser.waitForExist(listOfKeyValuesXpath); + waitForElement(listOfKeyElementsXpath); + waitForElement(listOfKeyValuesXpath); let listOfKeyElements = $$(listOfKeyElementsXpath); let listOfKeyValues = $$(listOfKeyValuesXpath); diff --git a/test/spec/e2e/modules/e2e_bidderSettings.spec.js b/test/spec/e2e/modules/e2e_bidderSettings.spec.js index d9f1d18725d..2c0ba484654 100644 --- a/test/spec/e2e/modules/e2e_bidderSettings.spec.js +++ b/test/spec/e2e/modules/e2e_bidderSettings.spec.js @@ -1,5 +1,5 @@ const expect = require('chai').expect; -const { host, protocol } = require('../../../helpers/testing-utils'); +const { host, protocol, waitForElement, switchFrame } = require('../../../helpers/testing-utils'); const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/bidderSettings.html?pbjs_debug=true`; const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; @@ -24,12 +24,12 @@ const EXPECTED_TARGETING_KEYS = { } describe('Prebid.js Bidder Settings Ad Unit Test', function () { + this.retries(3); before(function loadTestPage() { - browser.url(TEST_PAGE_URL).pause(3000); + browser.url(TEST_PAGE_URL); + browser.pause(3000); try { - browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; - browser.frame(creativeIframe); + waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); } catch (e) { // If creative Iframe didn't load, repeat the steps again! // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js @@ -39,10 +39,10 @@ describe('Prebid.js Bidder Settings Ad Unit Test', function () { it('should load the targeting keys with correct values', function () { const result = browser.execute(function () { - return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); }); - const targetingKeys = result.value['/19968336/prebid_native_example_2']; + const targetingKeys = result['/19968336/prebid_native_example_2']; expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); expect(targetingKeys.hb_adid).to.be.a('string'); expect(targetingKeys.hb_native_body).to.be.a('string'); @@ -54,6 +54,8 @@ describe('Prebid.js Bidder Settings Ad Unit Test', function () { }); it('should render the Banner Ad on the page', function () { - expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); + const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); + expect(ele.isExisting()).to.be.true; }); }); diff --git a/test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js b/test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js index 1c11a5432ff..4e0e7da49ea 100644 --- a/test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js +++ b/test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js @@ -1,5 +1,5 @@ const expect = require('chai').expect; -const { host, protocol } = require('../../../helpers/testing-utils'); +const { host, protocol, switchFrame, waitForElement } = require('../../../helpers/testing-utils'); const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/consent_mgt_gdpr.html?pbjs_debug=true`; const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; @@ -24,12 +24,12 @@ const EXPECTED_TARGETING_KEYS = { }; describe('Prebid.js GDPR Ad Unit Test', function () { + this.retries(3); before(function loadTestPage() { - browser.url(TEST_PAGE_URL).pause(3000); + browser.url(TEST_PAGE_URL); + browser.pause(3000); try { - browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; - browser.frame(creativeIframe); + waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); } catch (e) { // If creative Iframe didn't load, repeat the steps again! // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js @@ -39,10 +39,10 @@ describe('Prebid.js GDPR Ad Unit Test', function () { it('should load the targeting keys with correct values', function () { const result = browser.execute(function () { - return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); }); - const targetingKeys = result.value['/19968336/prebid_native_example_2']; + const targetingKeys = result['/19968336/prebid_native_example_2']; expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); expect(targetingKeys.hb_adid).to.be.a('string'); expect(targetingKeys.hb_native_body).to.be.a('string'); @@ -54,6 +54,8 @@ describe('Prebid.js GDPR Ad Unit Test', function () { }); it('should render the Banner Ad on the page', function () { - expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); + const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); + expect(ele.isExisting()).to.be.true; }); }); diff --git a/test/spec/e2e/modules/e2e_currency.spec.js b/test/spec/e2e/modules/e2e_currency.spec.js index 8692b4991bd..8d8da5c5d45 100644 --- a/test/spec/e2e/modules/e2e_currency.spec.js +++ b/test/spec/e2e/modules/e2e_currency.spec.js @@ -1,5 +1,5 @@ const expect = require('chai').expect; -const { host, protocol } = require('../../../helpers/testing-utils'); +const { host, protocol, waitForElement, switchFrame } = require('../../../helpers/testing-utils'); const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/currency.html?pbjs_debug=true`; const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; @@ -7,7 +7,6 @@ const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/hea const EXPECTED_TARGETING_KEYS = { hb_source: 'client', hb_source_appnexus: 'client', - hb_pb_appnexus: '7.50', hb_native_title_appn: 'This is a Prebid Native Creative', hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', hb_format: 'native', @@ -16,7 +15,6 @@ const EXPECTED_TARGETING_KEYS = { hb_bidder_appnexus: 'appnexus', hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', hb_native_title: 'This is a Prebid Native Creative', - hb_pb: '7.50', hb_native_brand_appn: 'Prebid.org', hb_bidder: 'appnexus', hb_format_appnexus: 'native', @@ -24,12 +22,12 @@ const EXPECTED_TARGETING_KEYS = { } describe('Prebid.js Currency Ad Unit Test', function () { + this.retries(3); before(function loadTestPage() { - browser.url(TEST_PAGE_URL).pause(3000); + browser.url(TEST_PAGE_URL); + browser.pause(5000); try { - browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; - browser.frame(creativeIframe); + waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); } catch (e) { // If creative Iframe didn't load, repeat the steps again! // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js @@ -39,12 +37,14 @@ describe('Prebid.js Currency Ad Unit Test', function () { it('should load the targeting keys with correct values', function () { const result = browser.execute(function () { - return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); }); - const targetingKeys = result.value['/19968336/prebid_native_example_2']; + const targetingKeys = result['/19968336/prebid_native_example_2']; expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); expect(targetingKeys.hb_adid).to.be.a('string'); + expect(targetingKeys.hb_pb).to.be.a('string'); + expect(targetingKeys.hb_pb_appnexus).to.be.a('string'); expect(targetingKeys.hb_native_body).to.be.a('string'); expect(targetingKeys.hb_native_body_appne).to.be.a('string'); expect(targetingKeys.hb_native_icon).to.be.a('string'); @@ -54,6 +54,8 @@ describe('Prebid.js Currency Ad Unit Test', function () { }); it('should render the Banner Ad on the page', function () { - expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); + const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); + expect(ele.isExisting()).to.be.true; }); }); diff --git a/test/spec/e2e/modules/e2e_priceGranularity.spec.js b/test/spec/e2e/modules/e2e_priceGranularity.spec.js index 1042ab491fb..157961d69ea 100644 --- a/test/spec/e2e/modules/e2e_priceGranularity.spec.js +++ b/test/spec/e2e/modules/e2e_priceGranularity.spec.js @@ -1,5 +1,5 @@ const expect = require('chai').expect; -const { host, protocol } = require('../../../helpers/testing-utils'); +const { host, protocol, switchFrame, waitForElement } = require('../../../helpers/testing-utils'); const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/priceGranularity.html?pbjs_debug=true`; const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; @@ -24,12 +24,12 @@ const EXPECTED_TARGETING_KEYS = { } describe('Prebid.js Price Granularity Ad Unit Test', function () { + this.retries(3); before(function loadTestPage() { - browser.url(TEST_PAGE_URL).pause(3000); + browser.url(TEST_PAGE_URL); + browser.pause(3000); try { - browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; - browser.frame(creativeIframe); + waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); } catch (e) { // If creative Iframe didn't load, repeat the steps again! // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js @@ -39,10 +39,10 @@ describe('Prebid.js Price Granularity Ad Unit Test', function () { it('should load the targeting keys with correct values', function () { const result = browser.execute(function () { - return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); }); - const targetingKeys = result.value['/19968336/prebid_native_example_2']; + const targetingKeys = result['/19968336/prebid_native_example_2']; expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); expect(targetingKeys.hb_adid).to.be.a('string'); expect(targetingKeys.hb_native_body).to.be.a('string'); @@ -54,6 +54,8 @@ describe('Prebid.js Price Granularity Ad Unit Test', function () { }); it('should render the Banner Ad on the page', function () { - expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); + const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); + expect(ele.isExisting()).to.be.true; }); }); diff --git a/test/spec/e2e/modules/e2e_sizeConfig.spec.js b/test/spec/e2e/modules/e2e_sizeConfig.spec.js index 1eb3fad8dea..a37e6d49122 100644 --- a/test/spec/e2e/modules/e2e_sizeConfig.spec.js +++ b/test/spec/e2e/modules/e2e_sizeConfig.spec.js @@ -1,5 +1,5 @@ const expect = require('chai').expect; -const { host, protocol } = require('../../../helpers/testing-utils'); +const { host, protocol, switchFrame, waitForElement } = require('../../../helpers/testing-utils'); const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/sizeConfig.html?pbjs_debug=true`; const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; @@ -24,12 +24,12 @@ const EXPECTED_TARGETING_KEYS = { } describe('Prebid.js Size Config Ad Unit Test', function () { + this.retries(3); before(function loadTestPage() { - browser.url(TEST_PAGE_URL).pause(3000); + browser.url(TEST_PAGE_URL); + browser.pause(3000); try { - browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; - browser.frame(creativeIframe); + waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); } catch (e) { // If creative Iframe didn't load, repeat the steps again! // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js @@ -39,10 +39,10 @@ describe('Prebid.js Size Config Ad Unit Test', function () { it('should load the targeting keys with correct values', function () { const result = browser.execute(function () { - return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); }); - const targetingKeys = result.value['/19968336/prebid_native_example_2']; + const targetingKeys = result['/19968336/prebid_native_example_2']; expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); expect(targetingKeys.hb_adid).to.be.a('string'); expect(targetingKeys.hb_native_body).to.be.a('string'); @@ -54,6 +54,8 @@ describe('Prebid.js Size Config Ad Unit Test', function () { }); it('should render the Banner Ad on the page', function () { - expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); + const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); + expect(ele.isExisting()).to.be.true; }); }); diff --git a/test/spec/e2e/modules/e2e_userSync.spec.js b/test/spec/e2e/modules/e2e_userSync.spec.js index 3957f3cdfef..d945bfd3278 100644 --- a/test/spec/e2e/modules/e2e_userSync.spec.js +++ b/test/spec/e2e/modules/e2e_userSync.spec.js @@ -1,5 +1,5 @@ const expect = require('chai').expect; -const { host, protocol } = require('../../../helpers/testing-utils'); +const { host, protocol, switchFrame, waitForElement } = require('../../../helpers/testing-utils'); const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/userSync.html?pbjs_debug=true`; const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; @@ -24,12 +24,12 @@ const EXPECTED_TARGETING_KEYS = { } describe('Prebid.js User Sync Ad Unit Test', function () { + this.retries(3); before(function loadTestPage() { - browser.url(TEST_PAGE_URL).pause(3000); + browser.url(TEST_PAGE_URL); + browser.pause(3000); try { - browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; - browser.frame(creativeIframe); + waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); } catch (e) { // If creative Iframe didn't load, repeat the steps again! // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js @@ -39,10 +39,10 @@ describe('Prebid.js User Sync Ad Unit Test', function () { it('should load the targeting keys with correct values', function () { const result = browser.execute(function () { - return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); }); - const targetingKeys = result.value['/19968336/prebid_native_example_2']; + const targetingKeys = result['/19968336/prebid_native_example_2']; expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); expect(targetingKeys.hb_adid).to.be.a('string'); expect(targetingKeys.hb_native_body).to.be.a('string'); @@ -54,6 +54,8 @@ describe('Prebid.js User Sync Ad Unit Test', function () { }); it('should render the Banner Ad on the page', function () { - expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; + switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); + const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); + expect(ele.isExisting()).to.be.true; }); }); diff --git a/test/spec/e2e/multi-bidder/e2e_multiple_bidders.spec.js b/test/spec/e2e/multi-bidder/e2e_multiple_bidders.spec.js new file mode 100644 index 00000000000..a67e2bd6db5 --- /dev/null +++ b/test/spec/e2e/multi-bidder/e2e_multiple_bidders.spec.js @@ -0,0 +1,67 @@ +const expect = require('chai').expect; +const { host, protocol, waitForElement, switchFrame } = require('../../../helpers/testing-utils'); + +const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/multiple_bidders.html?pbjs_debug=true`; +const CREATIVE_BANNER_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/prebid_multiformat_test_0"]'; + +const EXPECTED_TARGETING_KEYS = { + hb_source: 'client', + hb_source_adasta: 'client', + hb_pb_adasta: '10.00', + hb_native_title_adas: 'This is a Prebid Native Creative', + hb_native_linkurl: 'http://prebid.org/dev-docs/show-multi-format-ads.html', + hb_format: 'native', + hb_native_brand: 'Prebid.org', + hb_size: '0x0', + hb_bidder_adasta: 'adasta', + hb_native_linkurl_ad: 'http://prebid.org/dev-docs/show-multi-format-ads.html', + hb_native_title: 'This is a Prebid Native Creative', + hb_pb: '10.00', + hb_native_brand_adas: 'Prebid.org', + hb_bidder: 'adasta', + hb_format_adasta: 'native', + hb_size_adasta: '0x0' +}; + +describe('Prebid.js Multiple Bidder Ad Unit Test', function () { + this.retries(3); + before(function loadTestPage() { + browser.url(TEST_PAGE_URL); + browser.pause(5000); + try { + waitForElement(CREATIVE_BANNER_CSS_SELECTOR, 3000); + } catch (e) { + // If creative Iframe didn't load, repeat the steps again! + // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js + loadTestPage(); + } + }); + + it('should load the targeting keys with correct values', function () { + const result = browser.execute(function () { + return window.pbjs.getAdserverTargeting('div-banner-native-2'); + }); + + const targetingKeys = result['div-banner-native-2']; + expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); + expect(targetingKeys.hb_adid).to.be.a('string'); + expect(targetingKeys.hb_native_image).to.be.a('string'); + expect(targetingKeys.hb_native_image_adas).to.be.a('string'); + expect(targetingKeys.hb_adid_adasta).to.be.a('string'); + }); + + it('should render the Banner Ad on the page', function () { + switchFrame(CREATIVE_BANNER_CSS_SELECTOR); + let ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); + expect(ele.isExisting()).to.be.true; + }); + + // it('should render the native ad on the page', function () { + // browser.switchToParentFrame(); + // waitForElement(CREATIVE_NATIVE_CSS_SELECTOR, 3000); + // switchFrame(CREATIVE_NATIVE_CSS_SELECTOR); + + // let ele = $('body > div[class="GoogleActiveViewElement"] > div[class="card"]'); + // expect(ele.isExisting()).to.be.true; + // }); +}); diff --git a/test/spec/e2e/multi-format/e2e_multiple_bidders.spec.js b/test/spec/e2e/multi-format/e2e_multiple_bidders.spec.js deleted file mode 100644 index 4ce750bdd96..00000000000 --- a/test/spec/e2e/multi-format/e2e_multiple_bidders.spec.js +++ /dev/null @@ -1,68 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/multiple_bidders.html?pbjs_debug=true`; -const CREATIVE_BANNER_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/prebid_multiformat_test_0"]'; -const CREATIVE_NATIVE_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/prebid_multiformat_test_1"]'; - -const EXPECTED_TARGETING_KEYS = { - hb_source: 'client', - hb_source_appnexus: 'client', - hb_pb_appnexus: '10.00', - hb_native_title_appn: 'This is a Prebid Native Creative', - hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_format: 'native', - hb_native_brand: 'Prebid.org', - hb_size: '0x0', - hb_bidder_appnexus: 'appnexus', - hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_native_title: 'This is a Prebid Native Creative', - hb_pb: '10.00', - hb_native_brand_appn: 'Prebid.org', - hb_bidder: 'appnexus', - hb_format_appnexus: 'native', - hb_size_appnexus: '0x0' -}; - -describe('Prebid.js Multiple Bidder Ad Unit Test', function () { - before(function loadTestPage() { - browser.url(TEST_PAGE_URL).pause(3000); - try { - browser.waitForExist(CREATIVE_BANNER_CSS_SELECTOR, 3000); - const creativeIframe = $(CREATIVE_BANNER_CSS_SELECTOR).value; - browser.frame(creativeIframe); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); - }); - - const targetingKeys = result.value['/19968336/prebid_native_example_2']; - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_native_body).to.be.a('string'); - expect(targetingKeys.hb_native_body_appne).to.be.a('string'); - expect(targetingKeys.hb_native_icon).to.be.a('string'); - expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); - expect(targetingKeys.hb_native_image).to.be.a('string'); - expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - }); - - it('should render the Banner Ad on the page', function () { - expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > a > img')).to.be.true; - }); - - it('should render the native ad on the page', function () { - browser.frameParent(); - browser.waitForExist(CREATIVE_NATIVE_CSS_SELECTOR, 3000); - const creativeIframe = $(CREATIVE_NATIVE_CSS_SELECTOR).value; - browser.frame(creativeIframe); - expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > div[class="card"]')).to.be.true; - }); -}); diff --git a/test/spec/e2e/native/basic_native_ad.spec.js b/test/spec/e2e/native/basic_native_ad.spec.js index 8eb9a5940a0..418bcf271a3 100644 --- a/test/spec/e2e/native/basic_native_ad.spec.js +++ b/test/spec/e2e/native/basic_native_ad.spec.js @@ -1,5 +1,5 @@ const expect = require('chai').expect; -const { host, protocol } = require('../../../helpers/testing-utils'); +const { host, protocol, switchFrame, waitForElement } = require('../../../helpers/testing-utils'); const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/native.html`; const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/prebid_native_example_1_0"]'; @@ -24,10 +24,12 @@ const EXPECTED_TARGETING_KEYS = { } describe('Prebid.js Native Ad Unit Test', function () { + this.retries(3); before(function loadTestPage() { - browser.url(TEST_PAGE_URL).pause(3000); + browser.url(TEST_PAGE_URL); + browser.pause(3000); try { - browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 2000); + waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); } catch (e) { // If creative Iframe didn't load, repeat the steps again! // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js @@ -37,10 +39,10 @@ describe('Prebid.js Native Ad Unit Test', function () { it('should load the targeting keys with correct values', function () { const result = browser.execute(function () { - return window.top.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); + return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); }); - const targetingKeys = result.value['/19968336/prebid_native_example_2']; + const targetingKeys = result['/19968336/prebid_native_example_2']; expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); expect(targetingKeys.hb_adid).to.be.a('string'); expect(targetingKeys.hb_native_body).to.be.a('string'); @@ -52,8 +54,8 @@ describe('Prebid.js Native Ad Unit Test', function () { }); it('should render the native ad on the page', function () { - const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; - browser.frame(creativeIframe); - expect(browser.isVisible('body > div[class="GoogleActiveViewElement"] > div[class="card"]')).to.be.true; + switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); + const ele = $('body > div[class="GoogleActiveViewElement"] > div[class="card"]'); + expect(ele.isExisting()).to.be.true; }); }); diff --git a/test/spec/e2e/outstream/basic_outstream_video_ad.spec.js b/test/spec/e2e/outstream/basic_outstream_video_ad.spec.js index 15b0bb29309..0240b094f5e 100644 --- a/test/spec/e2e/outstream/basic_outstream_video_ad.spec.js +++ b/test/spec/e2e/outstream/basic_outstream_video_ad.spec.js @@ -1,5 +1,5 @@ const expect = require('chai').expect; -const { host, protocol } = require('../../../helpers/testing-utils'); +const { host, protocol, waitForElement, switchFrame } = require('../../../helpers/testing-utils'); const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/outstream.html`; const CREATIVE_IFRAME_CSS_SELECTOR = 'div[id="video_ad_unit_1"] > div:nth-child(2) > iframe:nth-child(1)'; @@ -20,13 +20,15 @@ const EXPECTED_TARGETING_KEYS = { }; describe('Prebid.js Outstream Video Ad Test', function () { + this.retries(3); before(function loadTestPage() { - browser - .url(TEST_PAGE_URL) - .scroll(0, 300) - .pause(3000); + browser.url(TEST_PAGE_URL); + browser.execute(function () { + return window.scrollBy(0, 300); + }); + browser.pause(3000); try { - browser.waitForExist(CREATIVE_IFRAME_CSS_SELECTOR, 5000); + waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 5000); } catch (e) { // If creative Iframe didn't load, repeat the steps again! // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js @@ -39,15 +41,19 @@ describe('Prebid.js Outstream Video Ad Test', function () { return window.pbjs.getAdserverTargeting('video_ad_unit_2'); }); - const targetingKeys = result.value['video_ad_unit_2']; + const targetingKeys = result['video_ad_unit_2']; expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); expect(targetingKeys.hb_adid).to.be.a('string'); expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); }); it('should render the native ad on the page', function() { - const creativeIframe = $(CREATIVE_IFRAME_CSS_SELECTOR).value; - browser.frame(creativeIframe); - expect(browser.isVisible('body > div[class="video-js"] > video')); + // skipping test in Edge due to wdio bug: https://github.com/webdriverio/webdriverio/issues/3880 + // the iframe for the video does not have a name property and id is generated automatically... + if (browser.capabilities.browserName !== 'edge') { + switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); + const ele = $('body > div[id*="an_video_ad_player"] > video'); + expect(ele.isExisting()).to.be.true; + } }); }); diff --git a/wdio.conf.js b/wdio.conf.js index dd94e82cf90..4d93f3d88d3 100644 --- a/wdio.conf.js +++ b/wdio.conf.js @@ -9,22 +9,24 @@ function getCapabilities() { return platformMap[os]; } - // only Edge 16, Chrome 74 & Firefox 66 run as part of functional tests + // only IE 11, Chrome 80 & Firefox 73 run as part of functional tests // rest of the browsers are discarded. - delete browsers['bs_ie_11_windows_10']; - delete browsers['bs_edge_17_windows_10']; - delete browsers['bs_chrome_75_windows_10']; - delete browsers['bs_firefox_67_windows_10']; - delete browsers['bs_safari_11_mac_high_sierra']; + delete browsers['bs_chrome_79_windows_10']; + delete browsers['bs_firefox_72_windows_10']; + delete browsers['bs_safari_11_mac_catalina']; delete browsers['bs_safari_12_mac_mojave']; + // disable all edge browsers due to wdio bug for switchToFrame: https://github.com/webdriverio/webdriverio/issues/3880 + delete browsers['bs_edge_18_windows_10']; + delete browsers['bs_edge_17_windows_10']; let capabilities = [] Object.keys(browsers).forEach(key => { let browser = browsers[key]; capabilities.push({ browserName: browser.browser, - platform: getPlatform(browser.os), - version: browser.browser_version, + os: getPlatform(browser.os), + os_version: browser.os_version, + browser_version: browser.browser_version, acceptSslCerts: true, 'browserstack.networkLogs': true, 'browserstack.console': 'verbose', @@ -35,27 +37,29 @@ function getCapabilities() { } exports.config = { - specs: [ - './test/spec/e2e/**/*.spec.js' - ], - services: ['browserstack'], - user: process.env.BROWSERSTACK_USERNAME, - key: process.env.BROWSERSTACK_ACCESS_KEY, - browserstackLocal: true, - // Do not increase this, since we have only 5 parallel tests in browserstack account - maxInstances: 5, - capabilities: getCapabilities(), - logLevel: 'silent', // Level of logging verbosity: silent | verbose | command | data | result | error - coloredLogs: true, - waitforTimeout: 60000, // Default timeout for all waitFor* commands. - connectionRetryTimeout: 60000, // Default timeout in milliseconds for request if Selenium Grid doesn't send response - connectionRetryCount: 3, // Default request retries count - framework: 'mocha', - mochaOpts: { - ui: 'bdd', - timeout: 60000, - compilers: ['js:babel-register'], - }, - // if you see error, update this to spec reporter and logLevel above to get detailed report. - reporters: ['concise'] -}; + specs: [ + './test/spec/e2e/**/*.spec.js' + ], + services: [ + ['browserstack', { + browserstackLocal: true + }] + ], + user: process.env.BROWSERSTACK_USERNAME, + key: process.env.BROWSERSTACK_ACCESS_KEY, + maxInstances: 5, // Do not increase this, since we have only 5 parallel tests in browserstack account + capabilities: getCapabilities(), + logLevel: 'silent', // put option here: info | trace | debug | warn| error | silent + bail: 0, + waitforTimeout: 60000, // Default timeout for all waitFor* commands. + connectionRetryTimeout: 60000, // Default timeout in milliseconds for request if Selenium Grid doesn't send response + connectionRetryCount: 3, // Default request retries count + framework: 'mocha', + mochaOpts: { + ui: 'bdd', + timeout: 60000, + compilers: ['js:babel-register'], + }, + // if you see error, update this to spec reporter and logLevel above to get detailed report. + reporters: ['concise'] +} From 80f19ceec86fe81866a98a9e14d99ebcb83f5e9b Mon Sep 17 00:00:00 2001 From: Jason Snellbaker Date: Wed, 3 Jun 2020 15:36:27 -0400 Subject: [PATCH 382/496] Prebid 3.22.0 release --- package-lock.json | 1390 ++++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 746 insertions(+), 646 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe04647fa30..5fae703fd91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,43 +1,43 @@ { "name": "prebid.js", - "version": "3.20.0-pre", + "version": "3.22.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", "dev": true, "requires": { - "@babel/highlight": "^7.8.3" + "@babel/highlight": "^7.10.1" } }, "@babel/compat-data": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.6.tgz", - "integrity": "sha512-5QPTrNen2bm7RBc7dsOmcA5hbrS4O2Vhmk5XOL4zWW/zD/hV0iinpefDlkm+tBBy8kDtFaaeEvmAqt+nURAV2g==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.1.tgz", + "integrity": "sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw==", "dev": true, "requires": { - "browserslist": "^4.11.1", + "browserslist": "^4.12.0", "invariant": "^2.2.4", "semver": "^5.5.0" } }, "@babel/core": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", - "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.9.6", - "@babel/parser": "^7.9.6", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz", + "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.2", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helpers": "^7.10.1", + "@babel/parser": "^7.10.2", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.2", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -66,347 +66,381 @@ } }, "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", "dev": true, "requires": { - "@babel/types": "^7.9.6", + "@babel/types": "^7.10.2", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, "@babel/helper-annotate-as-pure": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", - "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", + "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", - "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz", + "integrity": "sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-explode-assignable-expression": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/helper-compilation-targets": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.9.6.tgz", - "integrity": "sha512-x2Nvu0igO0ejXzx09B/1fGBxY9NXQlBW2kZsSxCJft+KHN8t9XWzIvFxtPHnBOAXpVsdxZKZFbRUC8TsNKajMw==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz", + "integrity": "sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==", "dev": true, "requires": { - "@babel/compat-data": "^7.9.6", - "browserslist": "^4.11.1", + "@babel/compat-data": "^7.10.1", + "browserslist": "^4.12.0", "invariant": "^2.2.4", "levenary": "^1.1.1", "semver": "^5.5.0" } }, + "@babel/helper-create-class-features-plugin": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz", + "integrity": "sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1" + } + }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", - "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz", + "integrity": "sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-regex": "^7.8.3", + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-regex": "^7.10.1", "regexpu-core": "^4.7.0" } }, "@babel/helper-define-map": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", - "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz", + "integrity": "sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/types": "^7.8.3", + "@babel/helper-function-name": "^7.10.1", + "@babel/types": "^7.10.1", "lodash": "^4.17.13" } }, "@babel/helper-explode-assignable-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", - "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz", + "integrity": "sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg==", "dev": true, "requires": { - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", + "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", + "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@babel/helper-hoist-variables": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", - "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz", + "integrity": "sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", - "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", + "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@babel/helper-module-imports": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", - "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", + "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@babel/helper-module-transforms": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", - "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", + "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-simple-access": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/template": "^7.8.6", - "@babel/types": "^7.9.0", + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1", "lodash": "^4.17.13" } }, "@babel/helper-optimise-call-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", - "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", + "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", + "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", "dev": true }, "@babel/helper-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", - "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.1.tgz", + "integrity": "sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g==", "dev": true, "requires": { "lodash": "^4.17.13" } }, "@babel/helper-remap-async-to-generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", - "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz", + "integrity": "sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-wrap-function": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-wrap-function": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/helper-replace-supers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", - "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", + "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/helper-simple-access": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", - "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", + "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", + "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", "dev": true }, "@babel/helper-wrap-function": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", - "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz", + "integrity": "sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-function-name": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/helpers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", - "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", + "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/highlight": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", - "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.10.1", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", - "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz", + "integrity": "sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-remap-async-to-generator": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-remap-async-to-generator": "^7.10.1", "@babel/plugin-syntax-async-generators": "^7.8.0" } }, + "@babel/plugin-proposal-class-properties": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz", + "integrity": "sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", - "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz", + "integrity": "sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.1", "@babel/plugin-syntax-dynamic-import": "^7.8.0" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", - "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz", + "integrity": "sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.1", "@babel/plugin-syntax-json-strings": "^7.8.0" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz", + "integrity": "sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.1", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", - "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz", + "integrity": "sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-numeric-separator": "^7.10.1" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz", - "integrity": "sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz", + "integrity": "sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.1", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.9.5" + "@babel/plugin-transform-parameters": "^7.10.1" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz", + "integrity": "sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.1", "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", - "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz", + "integrity": "sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.1", "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, + "@babel/plugin-proposal-private-methods": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz", + "integrity": "sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz", - "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz", + "integrity": "sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.8", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-syntax-async-generators": { @@ -418,6 +452,15 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-class-properties": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz", + "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, "@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", @@ -446,12 +489,12 @@ } }, "@babel/plugin-syntax-numeric-separator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", - "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz", + "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-syntax-object-rest-spread": { @@ -482,196 +525,196 @@ } }, "@babel/plugin-syntax-top-level-await": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", - "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz", + "integrity": "sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", - "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz", + "integrity": "sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", - "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz", + "integrity": "sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-remap-async-to-generator": "^7.8.3" + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-remap-async-to-generator": "^7.10.1" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", - "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz", + "integrity": "sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", - "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz", + "integrity": "sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-plugin-utils": "^7.10.1", "lodash": "^4.17.13" } }, "@babel/plugin-transform-classes": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz", - "integrity": "sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-define-map": "^7.8.3", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-split-export-declaration": "^7.8.3", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz", + "integrity": "sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-define-map": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", - "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz", + "integrity": "sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-destructuring": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz", - "integrity": "sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz", + "integrity": "sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", - "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz", + "integrity": "sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", - "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz", + "integrity": "sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", - "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz", + "integrity": "sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-for-of": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz", - "integrity": "sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz", + "integrity": "sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", - "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz", + "integrity": "sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", - "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz", + "integrity": "sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", - "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz", + "integrity": "sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.6.tgz", - "integrity": "sha512-zoT0kgC3EixAyIAU+9vfaUVKTv9IxBDSabgHoUCBP6FqEJ+iNiN7ip7NBKcYqbfUDfuC2mFCbM7vbu4qJgOnDw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz", + "integrity": "sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.6.tgz", - "integrity": "sha512-7H25fSlLcn+iYimmsNe3uK1at79IE6SKW9q0/QeEHTMC9MdOZ+4bA+T1VFB5fgOqBWoqlifXRzYD0JPdmIrgSQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz", + "integrity": "sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.6.tgz", - "integrity": "sha512-NW5XQuW3N2tTHim8e1b7qGy7s0kZ2OH3m5octc49K1SdAKGxYxeIx7hiIz05kS1R2R+hOWcsr1eYwcGhrdHsrg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz", + "integrity": "sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.8.3", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-hoist-variables": "^7.10.1", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz", - "integrity": "sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz", + "integrity": "sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-named-capturing-groups-regex": { @@ -684,180 +727,193 @@ } }, "@babel/plugin-transform-new-target": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", - "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz", + "integrity": "sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-object-super": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", - "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz", + "integrity": "sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1" } }, "@babel/plugin-transform-parameters": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz", - "integrity": "sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz", + "integrity": "sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-property-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", - "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz", + "integrity": "sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-regenerator": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", - "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz", + "integrity": "sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw==", "dev": true, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", - "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz", + "integrity": "sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", - "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz", + "integrity": "sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", - "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz", + "integrity": "sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", - "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz", + "integrity": "sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-regex": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-regex": "^7.10.1" } }, "@babel/plugin-transform-template-literals": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", - "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz", + "integrity": "sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", - "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz", + "integrity": "sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz", + "integrity": "sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", - "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz", + "integrity": "sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" } }, "@babel/preset-env": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.6.tgz", - "integrity": "sha512-0gQJ9RTzO0heXOhzftog+a/WyOuqMrAIugVYxMYf83gh1CQaQDjMtsOpqOwXyDL/5JcWsrCm8l4ju8QC97O7EQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.9.6", - "@babel/helper-compilation-targets": "^7.9.6", - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-proposal-async-generator-functions": "^7.8.3", - "@babel/plugin-proposal-dynamic-import": "^7.8.3", - "@babel/plugin-proposal-json-strings": "^7.8.3", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-proposal-numeric-separator": "^7.8.3", - "@babel/plugin-proposal-object-rest-spread": "^7.9.6", - "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", - "@babel/plugin-proposal-optional-chaining": "^7.9.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.2.tgz", + "integrity": "sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.10.1", + "@babel/helper-compilation-targets": "^7.10.2", + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-proposal-async-generator-functions": "^7.10.1", + "@babel/plugin-proposal-class-properties": "^7.10.1", + "@babel/plugin-proposal-dynamic-import": "^7.10.1", + "@babel/plugin-proposal-json-strings": "^7.10.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1", + "@babel/plugin-proposal-numeric-separator": "^7.10.1", + "@babel/plugin-proposal-object-rest-spread": "^7.10.1", + "@babel/plugin-proposal-optional-catch-binding": "^7.10.1", + "@babel/plugin-proposal-optional-chaining": "^7.10.1", + "@babel/plugin-proposal-private-methods": "^7.10.1", + "@babel/plugin-proposal-unicode-property-regex": "^7.10.1", "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-class-properties": "^7.10.1", "@babel/plugin-syntax-dynamic-import": "^7.8.0", "@babel/plugin-syntax-json-strings": "^7.8.0", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", - "@babel/plugin-syntax-numeric-separator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.1", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.8.3", - "@babel/plugin-transform-arrow-functions": "^7.8.3", - "@babel/plugin-transform-async-to-generator": "^7.8.3", - "@babel/plugin-transform-block-scoped-functions": "^7.8.3", - "@babel/plugin-transform-block-scoping": "^7.8.3", - "@babel/plugin-transform-classes": "^7.9.5", - "@babel/plugin-transform-computed-properties": "^7.8.3", - "@babel/plugin-transform-destructuring": "^7.9.5", - "@babel/plugin-transform-dotall-regex": "^7.8.3", - "@babel/plugin-transform-duplicate-keys": "^7.8.3", - "@babel/plugin-transform-exponentiation-operator": "^7.8.3", - "@babel/plugin-transform-for-of": "^7.9.0", - "@babel/plugin-transform-function-name": "^7.8.3", - "@babel/plugin-transform-literals": "^7.8.3", - "@babel/plugin-transform-member-expression-literals": "^7.8.3", - "@babel/plugin-transform-modules-amd": "^7.9.6", - "@babel/plugin-transform-modules-commonjs": "^7.9.6", - "@babel/plugin-transform-modules-systemjs": "^7.9.6", - "@babel/plugin-transform-modules-umd": "^7.9.0", + "@babel/plugin-syntax-top-level-await": "^7.10.1", + "@babel/plugin-transform-arrow-functions": "^7.10.1", + "@babel/plugin-transform-async-to-generator": "^7.10.1", + "@babel/plugin-transform-block-scoped-functions": "^7.10.1", + "@babel/plugin-transform-block-scoping": "^7.10.1", + "@babel/plugin-transform-classes": "^7.10.1", + "@babel/plugin-transform-computed-properties": "^7.10.1", + "@babel/plugin-transform-destructuring": "^7.10.1", + "@babel/plugin-transform-dotall-regex": "^7.10.1", + "@babel/plugin-transform-duplicate-keys": "^7.10.1", + "@babel/plugin-transform-exponentiation-operator": "^7.10.1", + "@babel/plugin-transform-for-of": "^7.10.1", + "@babel/plugin-transform-function-name": "^7.10.1", + "@babel/plugin-transform-literals": "^7.10.1", + "@babel/plugin-transform-member-expression-literals": "^7.10.1", + "@babel/plugin-transform-modules-amd": "^7.10.1", + "@babel/plugin-transform-modules-commonjs": "^7.10.1", + "@babel/plugin-transform-modules-systemjs": "^7.10.1", + "@babel/plugin-transform-modules-umd": "^7.10.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", - "@babel/plugin-transform-new-target": "^7.8.3", - "@babel/plugin-transform-object-super": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.9.5", - "@babel/plugin-transform-property-literals": "^7.8.3", - "@babel/plugin-transform-regenerator": "^7.8.7", - "@babel/plugin-transform-reserved-words": "^7.8.3", - "@babel/plugin-transform-shorthand-properties": "^7.8.3", - "@babel/plugin-transform-spread": "^7.8.3", - "@babel/plugin-transform-sticky-regex": "^7.8.3", - "@babel/plugin-transform-template-literals": "^7.8.3", - "@babel/plugin-transform-typeof-symbol": "^7.8.4", - "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.10.1", + "@babel/plugin-transform-object-super": "^7.10.1", + "@babel/plugin-transform-parameters": "^7.10.1", + "@babel/plugin-transform-property-literals": "^7.10.1", + "@babel/plugin-transform-regenerator": "^7.10.1", + "@babel/plugin-transform-reserved-words": "^7.10.1", + "@babel/plugin-transform-shorthand-properties": "^7.10.1", + "@babel/plugin-transform-spread": "^7.10.1", + "@babel/plugin-transform-sticky-regex": "^7.10.1", + "@babel/plugin-transform-template-literals": "^7.10.1", + "@babel/plugin-transform-typeof-symbol": "^7.10.1", + "@babel/plugin-transform-unicode-escapes": "^7.10.1", + "@babel/plugin-transform-unicode-regex": "^7.10.1", "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.9.6", - "browserslist": "^4.11.1", + "@babel/types": "^7.10.2", + "browserslist": "^4.12.0", "core-js-compat": "^3.6.2", "invariant": "^2.2.2", "levenary": "^1.1.1", @@ -878,9 +934,9 @@ } }, "@babel/runtime": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", - "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz", + "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -895,28 +951,28 @@ } }, "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", + "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" @@ -940,12 +996,12 @@ } }, "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.5", + "@babel/helper-validator-identifier": "^7.10.1", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -1866,9 +1922,9 @@ "dev": true }, "@sinonjs/commons": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", - "integrity": "sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", + "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -1910,9 +1966,9 @@ } }, "@types/babel__core": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", - "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==", + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz", + "integrity": "sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -1942,9 +1998,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz", - "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==", + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz", + "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -1975,9 +2031,9 @@ "dev": true }, "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz", + "integrity": "sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w==", "dev": true }, "@types/istanbul-lib-report": { @@ -1990,15 +2046,21 @@ } }, "@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, + "@types/json-schema": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", + "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "dev": true + }, "@types/keyv": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", @@ -2009,9 +2071,9 @@ } }, "@types/node": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.1.tgz", - "integrity": "sha512-FAYBGwC+W6F9+huFIDtn43cpy7+SzG+atzRiTfdp3inUKL2hXnd4rG8hylJLIh4+hqrQy1P17kvJByE/z825hA==", + "version": "14.0.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.9.tgz", + "integrity": "sha512-0sCTiXKXELOBxvZLN4krQ0FPOAA7ij+6WwvD0k/PHd9/KAkr4dXel5J9fh6F4x1FwAQILqAWkmpeuS6mjf1iKA==", "dev": true }, "@types/responselike": { @@ -2055,9 +2117,9 @@ } }, "@wdio/browserstack-service": { - "version": "6.1.10", - "resolved": "https://registry.npmjs.org/@wdio/browserstack-service/-/browserstack-service-6.1.10.tgz", - "integrity": "sha512-RhPT4sSZIWv+xUMOxpq7HCBmdbDdXQJpo1vrqjDKmdjhyWnZDbhZfETaHL4cUepYudwV9B06pxYrF6cmL17rdg==", + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/@wdio/browserstack-service/-/browserstack-service-6.1.15.tgz", + "integrity": "sha512-q8qLa44wGSB3tIuZ0yquvAZqr2W7vEwupWiOd1ct0CSYgd4yX/nLd8oypqJCc8jU1ZwNAhu+V3/6hszvwx+HbA==", "dev": true, "requires": { "@wdio/logger": "6.0.16", @@ -2066,12 +2128,12 @@ } }, "@wdio/cli": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-6.1.11.tgz", - "integrity": "sha512-xH/val+A2rimVgWnT7P7V7/DH7+r1bQ88a3LjM1UJIEnjVBhglx+fysjFCnRV205IhkW5lej0XLUlIJmMFdhiA==", + "version": "6.1.16", + "resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-6.1.16.tgz", + "integrity": "sha512-q7JaEiLU2mdOibeKAQFqdWTS2evdkwgWSft1rmWDN7idiV39uncTTUcwlXBKE2a9yDk/8qn6EEXdBLthOCfyOA==", "dev": true, "requires": { - "@wdio/config": "6.1.2", + "@wdio/config": "6.1.14", "@wdio/logger": "6.0.16", "@wdio/utils": "6.1.8", "async-exit-hook": "^2.0.1", @@ -2085,7 +2147,7 @@ "lodash.pickby": "^4.6.0", "lodash.union": "^4.6.0", "log-update": "^4.0.0", - "webdriverio": "6.1.11", + "webdriverio": "6.1.16", "yargs": "^15.0.1", "yarn-install": "^1.0.0" }, @@ -2211,12 +2273,12 @@ } }, "@wdio/concise-reporter": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@wdio/concise-reporter/-/concise-reporter-6.1.9.tgz", - "integrity": "sha512-fIWaMfVr8D5N2Wk9qqv73PWHinGHmhgsTpKlqnlfJ2kOTu3aTRMQoRqY4MUm44KQTflofRV7u9FXhV5vYyxGJw==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@wdio/concise-reporter/-/concise-reporter-6.1.14.tgz", + "integrity": "sha512-QKGiIPE2sYJpQcQ5zogUogu+Yldkx/FUM4LC01lc3v0Nww7n0p0fJA3U4cKFAqyW0gXCwW7m6/9c5fDgaSv8+g==", "dev": true, "requires": { - "@wdio/reporter": "6.1.9", + "@wdio/reporter": "6.1.14", "chalk": "^4.0.0", "pretty-ms": "^7.0.0" }, @@ -2274,9 +2336,9 @@ } }, "@wdio/config": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-6.1.2.tgz", - "integrity": "sha512-mMatdM9RLNZI0dzHWGPl/8lU8+GX5q0K2Esd+VyDOLQNg/9pykidEQURwvoQb6YvvV5wiX4IXqLSIYh1ELjyOA==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-6.1.14.tgz", + "integrity": "sha512-MXHMHwtkAblfnIxONs9aW//T9Fq5XIw3oH+tztcBRvNTTAIXmwHd+4sOjAwjpCdBSGs0C4kM/aTpGfwDZVURvQ==", "dev": true, "requires": { "@wdio/logger": "6.0.16", @@ -2285,14 +2347,14 @@ } }, "@wdio/local-runner": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-6.1.11.tgz", - "integrity": "sha512-cM8suZ5m35nIf02KmZqC5zi7bhb/k9jmbZJ0RaRLSSCrQK0CaWiSiUSJxx8FSymueStsob7dKQg3jzdUcOzQeQ==", + "version": "6.1.16", + "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-6.1.16.tgz", + "integrity": "sha512-3+pT2fcMXFAnELA6jYjVm6Nt8Il7tGL66A90UbRiT0sL2faTcD3uGAPbmzxMclsmWLh7C04ucCnFwQoTMW1emg==", "dev": true, "requires": { "@wdio/logger": "6.0.16", "@wdio/repl": "6.1.8", - "@wdio/runner": "6.1.11", + "@wdio/runner": "6.1.16", "async-exit-hook": "^2.0.1", "stream-buffers": "^3.0.2" } @@ -2362,9 +2424,9 @@ } }, "@wdio/mocha-framework": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-6.1.8.tgz", - "integrity": "sha512-qxetJAYIK8aoL6qHGfVM2OrR0XNnFcI0iy6qUwDhcbKpGsk/fyR+l+8xT75LonW93hLSXDI83PBGkfyQVnMgbQ==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-6.1.14.tgz", + "integrity": "sha512-2AmUH/v3kZoIDAMdW73AhI4tDJU3ie/2dO/DtpXJ3XFnuJ1CtklZGyCTtYHGMZ8DBj18/8Lrs/O0CjS5bAu2tw==", "dev": true, "requires": { "@wdio/logger": "6.0.16", @@ -2461,9 +2523,9 @@ } }, "mocha": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", - "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", "dev": true, "requires": { "ansi-colors": "3.2.3", @@ -2602,9 +2664,9 @@ } }, "@wdio/protocols": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-6.1.11.tgz", - "integrity": "sha512-opauqB8kxsUOHrNxHv24D+DjULOvxQUfwSIGL4pv6u/b/Jzni4Nmjy4wcIb8TFXvWWvp7JfFQM1DntM0gQ0d3g==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-6.1.14.tgz", + "integrity": "sha512-UtRLQ55i23cLQRGtFiEJty1F6AbAfiSpfIxDAiXKHbw6Rp1StwxlqHFrhNe5F48Zu4hnie46t9N/tr/cZOe0kA==", "dev": true }, "@wdio/repl": { @@ -2617,36 +2679,36 @@ } }, "@wdio/reporter": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-6.1.9.tgz", - "integrity": "sha512-3eQ8VcloL27Ev27EQIGS/BlmRrAeSu/e7ZHbQ3SN6E8eDpbJ7UZauO5mh+XqAq7a2LF8Sd5PMLnJ3RKlGtw+kA==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-6.1.14.tgz", + "integrity": "sha512-Pt6P0JU0COHTpggsOoJKUJyAyQsi7xlHebBNU/DWdHHpmzYd4e9vDutjyTqXu/1zn+t+Zq+uL1IC0E4Xjv6f7w==", "dev": true, "requires": { "fs-extra": "^9.0.0" } }, "@wdio/runner": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-6.1.11.tgz", - "integrity": "sha512-Hw+sL63ALE7/CsxVEt3uwUtERcDZn2gbUhwuHUdNoePtj2kD1UQwpof8LATrymT3oVaiMYB3j3hcB8hvoTGQRA==", + "version": "6.1.16", + "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-6.1.16.tgz", + "integrity": "sha512-pGRT51BGnxp4zFD1pSp6qZD/4dnbSnDyV4g/MbbFiA4PFKF41mFhaxRwIGMHcp4EYlv9gaT31UA52JaFIYyuNA==", "dev": true, "requires": { - "@wdio/config": "6.1.2", + "@wdio/config": "6.1.14", "@wdio/logger": "6.0.16", "@wdio/utils": "6.1.8", "deepmerge": "^4.0.0", "gaze": "^1.1.2", - "webdriver": "6.1.11", - "webdriverio": "6.1.11" + "webdriver": "6.1.14", + "webdriverio": "6.1.16" } }, "@wdio/spec-reporter": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-6.1.9.tgz", - "integrity": "sha512-f71FkV5AYhGnZ3aP+FGGGNogyo5QCn4VVz0tfqr7jG7Fk2SsdjoYhKDlLD+fG+R7PwFIwpcVea8zM6NZSIm75g==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-6.1.14.tgz", + "integrity": "sha512-QaSBgnzllzLp9LR7/5DTkmrI8BqcznUma8ZxwUNmhvskv/oKzrmNyeCsGoiExFmCk81A9FgZiZPXey7CuaTkdw==", "dev": true, "requires": { - "@wdio/reporter": "6.1.9", + "@wdio/reporter": "6.1.14", "chalk": "^4.0.0", "easy-table": "^1.1.1", "pretty-ms": "^7.0.0" @@ -2705,9 +2767,9 @@ } }, "@wdio/sync": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/@wdio/sync/-/sync-6.1.8.tgz", - "integrity": "sha512-oghYrfMcLrVc0zxWUw9TQmUmdPQ8HmE2VMK6tifpOaF+Zo0jfsj2huajos1GPgdYqJV+LoZ3nXtdSYllG6n4gg==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/@wdio/sync/-/sync-6.1.14.tgz", + "integrity": "sha512-94K0kQdrOU0aMlJ2Xsd4tWr4tPpmCFp612Ml5+ecQh4C4XD07ocfsvGs+mwI7cfF1sO6g/Hoc+XTY2D+/8En3w==", "dev": true, "requires": { "@wdio/logger": "6.0.16", @@ -3241,9 +3303,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } @@ -3369,9 +3431,9 @@ "dev": true }, "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", "dev": true }, "babel-code-frame": { @@ -4851,9 +4913,9 @@ "dev": true }, "binaryextensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.2.0.tgz", - "integrity": "sha512-bHhs98rj/7i/RZpCSJ3uk55pLXOItjIrh2sRQZSM6OoktScX+LxJzvlU+FELp9j3TdcddTmmYArLSGptCTwjuw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.3.0.tgz", + "integrity": "sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg==", "dev": true }, "bindings": { @@ -4898,9 +4960,9 @@ "dev": true }, "bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", + "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==", "dev": true }, "body": { @@ -5063,17 +5125,17 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } }, "browserify-sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz", - "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", + "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", "dev": true, "requires": { "bn.js": "^5.1.1", @@ -5083,7 +5145,8 @@ "elliptic": "^6.5.2", "inherits": "^2.0.4", "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0" + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" }, "dependencies": { "inherits": { @@ -5091,6 +5154,12 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true } } }, @@ -5387,9 +5456,9 @@ } }, "cacheable-lookup": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-4.3.0.tgz", - "integrity": "sha512-PTUoCeIjj2awloqyVRUL33SjquU1Qv5xuDalYY8WAzd9NnUMUivZnGsOzVsMfg2YuMsWXaXkd/hjnsVoWc/3YA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz", + "integrity": "sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w==", "dev": true }, "cacheable-request": { @@ -5461,9 +5530,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001058", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001058.tgz", - "integrity": "sha512-UiRZmBYd1HdVVdFKy7PuLVx9e2NS7SMyx7QpWvFjiklYrLJKpLd19cRnRNqlw4zYa7vVejS3c8JUVobX241zHQ==", + "version": "1.0.30001077", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001077.tgz", + "integrity": "sha512-AEzsGvjBJL0lby/87W96PyEvwN0GsYvk5LHsglLg9tW37K4BqvAvoSCdWIE13OZQ8afupqZ73+oL/1LkedN8hA==", "dev": true }, "capture-exit": { @@ -6111,9 +6180,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } @@ -6348,18 +6417,18 @@ "dev": true }, "decompress-response": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", - "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, "requires": { - "mimic-response": "^2.0.0" + "mimic-response": "^3.1.0" }, "dependencies": { "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "dev": true } } @@ -6574,14 +6643,14 @@ } }, "devtools": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-6.1.11.tgz", - "integrity": "sha512-jqCkkIcFTUq7xAPRwUApq8IMUn6v5XWoroaIec27ALXehFdGpEmO4p6Uehbn2580HOa2JYB+FdR9yzTw+MAuQA==", + "version": "6.1.16", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-6.1.16.tgz", + "integrity": "sha512-Px/K/xYY+fTW8D5yt7p6ZZJfkfHHulKVr2Y+BJSCQyKNSY/hiZFT6KAjoUFrAastLCqqs1gW2Dy/OGb0qWm+Hg==", "dev": true, "requires": { - "@wdio/config": "6.1.2", + "@wdio/config": "6.1.14", "@wdio/logger": "6.0.16", - "@wdio/protocols": "6.1.11", + "@wdio/protocols": "6.1.14", "@wdio/utils": "6.1.8", "chrome-launcher": "^0.13.1", "puppeteer-core": "^3.0.0", @@ -6619,9 +6688,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } @@ -7387,18 +7456,18 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "ejs": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.2.tgz", - "integrity": "sha512-zFuywxrAWtX5Mk2KAuoJNkXXbfezpNA0v7i+YC971QORguPekpjpAgeOv99YWSdKXwj7JxI2QAWDeDkE8fWtXw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz", + "integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==", "dev": true, "requires": { "jake": "^10.6.1" } }, "electron-to-chromium": { - "version": "1.3.437", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.437.tgz", - "integrity": "sha512-PBQn2q68ErqMyBUABh9Gh8R6DunGky8aB5y3N5lPM7OVpldwyUbAK5AX9WcwE/5F6ceqvQ+iQLYkJYRysAs6Bg==", + "version": "1.3.458", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.458.tgz", + "integrity": "sha512-OjRkb0igW0oKE2QbzS7vBYrm7xjW/KRTtIj0OGGx57jr/YhBiKb7oZvdbaojqjfCb/7LbnwsbMbdsYjthdJbAw==", "dev": true }, "elliptic": { @@ -7417,9 +7486,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } @@ -9249,9 +9318,9 @@ } }, "fun-hooks": { - "version": "0.9.8", - "resolved": "https://registry.npmjs.org/fun-hooks/-/fun-hooks-0.9.8.tgz", - "integrity": "sha512-FZUHodONJBOCCETXnHTSvqnz+pLZiN2ZqbOZsjXIqJRI8AbvTqOJzDTEeMfPzFf8rPuSZnD5EPcbl7yZsEQ/NA==", + "version": "0.9.9", + "resolved": "https://registry.npmjs.org/fun-hooks/-/fun-hooks-0.9.9.tgz", + "integrity": "sha512-821UhoYfO9Sg01wAl/QsDRB088BW0aeOqzC1PXLxSlB+kaUVbK+Vp6wMDHU5huZZopYxmMmv5jDkEYqDpK3hqg==", "requires": { "typescript-tuple": "^2.2.1" } @@ -9782,18 +9851,18 @@ } }, "got": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.1.3.tgz", - "integrity": "sha512-JnGxEHZiy0ZArb/zhfu1Gxoksy9PjhQ4GAk6N4UArV/m1JdE7cGNVXbUDnrQk+nU7UPMDX+BHQAP0daMjsnTtQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/got/-/got-11.2.0.tgz", + "integrity": "sha512-68pBow9XXXSdVRV5wSx0kWMCZsag4xE3Ru0URVe0PWsSYmU4SJrUmEO6EVYFlFHc9rq/6Yqn6o1GxIb9torQxg==", "dev": true, "requires": { "@sindresorhus/is": "^2.1.1", "@szmarczak/http-timer": "^4.0.5", "@types/cacheable-request": "^6.0.1", "@types/responselike": "^1.0.0", - "cacheable-lookup": "^4.3.0", + "cacheable-lookup": "^5.0.3", "cacheable-request": "^7.0.1", - "decompress-response": "^5.0.0", + "decompress-response": "^6.0.0", "get-stream": "^5.1.0", "http2-wrapper": "^1.0.0-beta.4.5", "lowercase-keys": "^2.0.0", @@ -9876,9 +9945,9 @@ "dev": true }, "gulp-cli": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz", - "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.1.tgz", + "integrity": "sha512-yEMxrXqY8mJFlaauFQxNrCpzWJThu0sH1sqlToaTOT063Hub9s/Nt2C+GSLe6feQ/IMWrHvGOOsyES7CQc9O+A==", "dev": true, "requires": { "ansi-colors": "^1.0.1", @@ -9968,9 +10037,9 @@ "dev": true }, "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.1.tgz", + "integrity": "sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g==", "dev": true, "requires": { "camelcase": "^3.0.0", @@ -9985,16 +10054,17 @@ "string-width": "^1.0.2", "which-module": "^1.0.0", "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" + "yargs-parser": "5.0.0-security.0" } }, "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "version": "5.0.0-security.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0-security.0.tgz", + "integrity": "sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ==", "dev": true, "requires": { - "camelcase": "^3.0.0" + "camelcase": "^3.0.0", + "object.assign": "^4.1.0" } } } @@ -11093,15 +11163,15 @@ } }, "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz", + "integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ==", "dev": true }, "http-proxy": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", - "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "requires": { "eventemitter3": "^4.0.0", @@ -11306,9 +11376,9 @@ } }, "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, "into-stream": { @@ -11426,9 +11496,9 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" }, "is-ci": { "version": "2.0.0", @@ -12139,9 +12209,9 @@ } }, "jake": { - "version": "10.6.1", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.6.1.tgz", - "integrity": "sha512-pHUK3+V0BjOb1XSi95rbBksrMdIqLVC9bJqDnshVyleYsET3H0XAq+3VB2E3notcYvv4wRdRHn13p7vobG+wfQ==", + "version": "10.8.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.1.tgz", + "integrity": "sha512-eSp5h9S7UFzKdQERTyF+KuPLjDZa1Tbw8gCVUn98n4PbIkLEDGe4zl7vF4Qge9kQj06HcymnksPk8jznPZeKsA==", "dev": true, "requires": { "async": "0.9.x", @@ -14669,9 +14739,9 @@ }, "dependencies": { "mime": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", - "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", "dev": true }, "rimraf": { @@ -16160,9 +16230,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } @@ -16736,9 +16806,9 @@ } }, "node-releases": { - "version": "1.1.55", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.55.tgz", - "integrity": "sha512-H3R3YR/8TjT5WPin/wOoHOUPHgvj8leuU/Keta/rwelEQN9pA/S2Dx8/se4pZ2LBxSd0nAGzsNzhqwa77v7F1w==", + "version": "1.1.58", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz", + "integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==", "dev": true }, "nopt": { @@ -17775,9 +17845,9 @@ } }, "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-wHMFZ6HTLGlB9f/WsQBs5OwMQJoLXYuJUzbA+j+hRBf7+Y8KcXpatzIviIcTy1OAyhWQp08nyiPO8Dnv0z4Sww==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -18126,9 +18196,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "dev": true } } @@ -18173,9 +18243,9 @@ "dev": true }, "puppeteer-core": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-3.0.4.tgz", - "integrity": "sha512-DhsR97T84FguRBuWJbNXMIOzrO64a80CMFOoLyiQWX7MGu+ZlhcqAagZyvRDRYfSoyqYUiIqH0vgtfQkfRgQFg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-3.3.0.tgz", + "integrity": "sha512-hynQ3r0J/lkGrKeBCqu160jrj0WhthYLIzDQPkBxLzxPokjw4elk1sn6mXAian/kfD2NRzpdh9FSykxZyL56uA==", "dev": true, "requires": { "debug": "^4.1.0", @@ -18200,9 +18270,9 @@ } }, "mime": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", - "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", "dev": true }, "ms": { @@ -18268,9 +18338,9 @@ "dev": true }, "quick-lru": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.0.tgz", - "integrity": "sha512-WjAKQ9ORzvqjLijJXiXWqc3Gcs1ivoxCj6KJmEjoWBE6OtHwuaDLSAUqGHALUiid7A1KqGqsSHZs8prxF5xxAQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true }, "randomatic": { @@ -18513,9 +18583,9 @@ } }, "regjsgen": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", - "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", "dev": true }, "regjsparser": { @@ -18953,9 +19023,9 @@ "dev": true }, "rgb2hex": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.10.tgz", - "integrity": "sha512-vKz+kzolWbL3rke/xeTE2+6vHmZnNxGyDnaVW4OckntAIcc7DcZzWkQSfxMDwqHS8vhgySnIFyBUH7lIk6PxvQ==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.0.tgz", + "integrity": "sha512-cHdNTwmTMPu/TpP1bJfdApd6MbD+Kzi4GNnM6h35mdFChhQPSi9cAI8J7DMn5kQDKX8NuBaQXAyo360Oa7tOEA==", "dev": true }, "right-align": { @@ -19207,12 +19277,13 @@ "dev": true }, "schema-utils": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.6.tgz", - "integrity": "sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", "dev": true, "requires": { - "ajv": "^6.12.0", + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", "ajv-keywords": "^3.4.1" }, "dependencies": { @@ -19273,18 +19344,18 @@ } }, "serialize-error": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-6.0.0.tgz", - "integrity": "sha512-3vmBkMZLQO+BR4RPHcyRGdE09XCF6cvxzk2N2qn8Er3F91cy8Qt7VvEbZBOpaL53qsBbe2cFOefU6tRY6WDelA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", "dev": true, "requires": { - "type-fest": "^0.12.0" + "type-fest": "^0.13.1" }, "dependencies": { "type-fest": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.12.0.tgz", - "integrity": "sha512-53RyidyjvkGpnWPMF9bQgFtWp+Sl8O2Rp13VavmJgfAP9WWG6q6TkrKU8iyJdnwnfgHI6k2hTlgqH4aSdjoTbg==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true } } @@ -19773,9 +19844,9 @@ "dev": true }, "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -20981,9 +21052,9 @@ "dev": true }, "uglify-js": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.3.tgz", - "integrity": "sha512-r5ImcL6QyzQGVimQoov3aL2ZScywrOgBXGndbWrdehKoSvGe/RmiE5Jpw/v+GvxODt6l2tpBXwA7n+qZVlHBMA==", + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.4.tgz", + "integrity": "sha512-8RZBJq5smLOa7KslsNsVcSH+KOXf1uDU8yqLeNuVKwmT0T3FA0ZoXlinQfRad7SDcbZZRZE4ov+2v71EnxNyCA==", "dev": true, "requires": { "commander": "~2.20.3" @@ -21061,9 +21132,9 @@ "dev": true }, "unbzip2-stream": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.2.tgz", - "integrity": "sha512-pZMVAofMrrHX6Ik39hCk470kulCbmZ2SWfQLPmTWqfJV/oUm0gn1CblvHdUu4+54Je6Jq34x8kY6XjTy6dMkOg==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, "requires": { "buffer": "^5.2.1", @@ -21451,15 +21522,15 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz", + "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==", "dev": true }, "v8flags": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", - "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", "dev": true, "requires": { "homedir-polyfill": "^1.0.1" @@ -21748,14 +21819,25 @@ } }, "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz", + "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==", "dev": true, "requires": { - "chokidar": "^2.1.8", + "chokidar": "^3.4.0", "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" }, "dependencies": { "anymatch": { @@ -21763,6 +21845,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, + "optional": true, "requires": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" @@ -21773,6 +21856,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, + "optional": true, "requires": { "remove-trailing-separator": "^1.0.1" } @@ -21783,13 +21867,15 @@ "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true + "dev": true, + "optional": true }, "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, + "optional": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -21808,6 +21894,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -21819,6 +21906,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, + "optional": true, "requires": { "anymatch": "^2.0.0", "async-each": "^1.0.1", @@ -21839,6 +21927,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, + "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -21851,6 +21940,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -21873,6 +21963,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, + "optional": true, "requires": { "is-glob": "^3.1.0", "path-dirname": "^1.0.0" @@ -21883,6 +21974,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, + "optional": true, "requires": { "is-extglob": "^2.1.0" } @@ -21894,6 +21986,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, + "optional": true, "requires": { "binary-extensions": "^1.0.0" } @@ -21902,13 +21995,15 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "dev": true, + "optional": true }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -21918,6 +22013,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -21929,6 +22025,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, + "optional": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -21950,6 +22047,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -21965,6 +22063,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, + "optional": true, "requires": { "graceful-fs": "^4.1.11", "micromatch": "^3.1.10", @@ -21976,6 +22075,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, + "optional": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -21994,41 +22094,41 @@ } }, "webdriver": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-6.1.11.tgz", - "integrity": "sha512-CWCsTSz4J5uSQD8PHtDyHCdzqWr/8GD9feesJSiftHvauegikTFCC8nUtI68EfYlNO5gYpnI0eF90prKTz8SnA==", + "version": "6.1.14", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-6.1.14.tgz", + "integrity": "sha512-6fXoGDnxWfJn9zqfYbc6+VEV5N1obd3K7iuRmJ7w/hH9d9XDxcrcx147T5egiy1qziko61hqYE/x9VtSQbjPcA==", "dev": true, "requires": { - "@wdio/config": "6.1.2", + "@wdio/config": "6.1.14", "@wdio/logger": "6.0.16", - "@wdio/protocols": "6.1.11", + "@wdio/protocols": "6.1.14", "@wdio/utils": "6.1.8", "got": "^11.0.2", "lodash.merge": "^4.6.1" } }, "webdriverio": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-6.1.11.tgz", - "integrity": "sha512-b6nP19da0HlqqD3ApYZc3yCraMwUjWLX+ghaT0kCIA8lBbVCEhXhJNAgPrEZJUfYJPKmYe7f0Gibn821fCMCQQ==", + "version": "6.1.16", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-6.1.16.tgz", + "integrity": "sha512-vk6/XeErNnMooebCtxwIR//LqrastXO9gXL+eVUGNRAuG5omp8XCdT+MK2fmlw53xhcPULQ/y3h8ysYlPnPeyA==", "dev": true, "requires": { - "@wdio/config": "6.1.2", + "@wdio/config": "6.1.14", "@wdio/logger": "6.0.16", "@wdio/repl": "6.1.8", "@wdio/utils": "6.1.8", "archiver": "^4.0.1", "css-value": "^0.0.1", - "devtools": "6.1.11", + "devtools": "6.1.16", "grapheme-splitter": "^1.0.2", "lodash.clonedeep": "^4.5.0", "lodash.isobject": "^3.0.2", "lodash.isplainobject": "^4.0.6", "lodash.zip": "^4.2.0", "resq": "^1.6.0", - "rgb2hex": "^0.1.0", - "serialize-error": "^6.0.0", - "webdriver": "6.1.11" + "rgb2hex": "^0.2.0", + "serialize-error": "^7.0.0", + "webdriver": "6.1.14" } }, "webidl-conversions": { @@ -22318,9 +22418,9 @@ } }, "webpack-bundle-analyzer": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.7.0.tgz", - "integrity": "sha512-mETdjZ30a3Yf+NTB/wqTgACK7rAYQl5uxKK0WVTNmF0sM3Uv8s3R58YZMW7Rhu0Lk2Rmuhdj5dcH5Q76zCDVdA==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.8.0.tgz", + "integrity": "sha512-PODQhAYVEourCcOuU+NiYI7WdR8QyELZGgPvB1y2tjbUpbmcQOt5Q7jEK+ttd5se0KSBKD9SXHCEozS++Wllmw==", "dev": true, "requires": { "acorn": "^7.1.1", @@ -22410,9 +22510,9 @@ }, "dependencies": { "mime": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz", - "integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==", + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", "dev": true } } @@ -23331,20 +23431,20 @@ } }, "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", + "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true }, "whatwg-encoding": { diff --git a/package.json b/package.json index 5fcf5003b14..5e188aab48b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.22.0-pre", + "version": "3.22.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From b7ee9c55760dbb3285507d5cd43a6ac44031ae63 Mon Sep 17 00:00:00 2001 From: Jason Snellbaker Date: Wed, 3 Jun 2020 15:49:09 -0400 Subject: [PATCH 383/496] increment pre version --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5fae703fd91..583d25d3459 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.22.0", + "version": "3.23.0-pre", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5e188aab48b..10f9354b0e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.22.0", + "version": "3.23.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 70cc46958cdc9990ef24216b7af0cf2d3b8d3104 Mon Sep 17 00:00:00 2001 From: thuyhq <61451682+thuyhq@users.noreply.github.com> Date: Thu, 4 Jun 2020 03:15:51 +0700 Subject: [PATCH 384/496] Update Usersync Url For Quantumdex bid adapter (#5327) We have upgraded the new user cookie storage system. Where everything is gathered in one place --- modules/quantumdexBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/quantumdexBidAdapter.js b/modules/quantumdexBidAdapter.js index c2a130f789d..1ac4353c43f 100644 --- a/modules/quantumdexBidAdapter.js +++ b/modules/quantumdexBidAdapter.js @@ -2,7 +2,7 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'quantumdex'; const ENDPOINT = 'https://useast.quantumdex.io/auction/adapter'; -const USER_SYNC_URL = 'https://useast.quantumdex.io/usersync/adapter'; +const USER_SYNC_URL = 'https://sync.quantumdex.io/usersync/adapter'; var bySlotTargetKey = {}; var bySlotSizesCount = {} From 77705e81a94ab4235a421a3c19277d8f503956bc Mon Sep 17 00:00:00 2001 From: Toshiki Yamamoto <6803209+Tosh39@users.noreply.github.com> Date: Thu, 4 Jun 2020 22:37:48 +0900 Subject: [PATCH 385/496] fix wipesAdapter CPM culclation (#5330) --- modules/wipesBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/wipesBidAdapter.js b/modules/wipesBidAdapter.js index 5a2c860130f..f381bcb68a0 100644 --- a/modules/wipesBidAdapter.js +++ b/modules/wipesBidAdapter.js @@ -38,7 +38,7 @@ function buildRequests(validBidRequests, bidderRequest) { function interpretResponse(serverResponse, bidRequest) { const bidResponses = []; const response = serverResponse.body; - const cpm = response.cpm * 1000 || 0; + const cpm = response.cpm || 0; if (cpm !== 0) { const netRevenue = (response.netRevenue === undefined) ? true : response.netRevenue; const bidResponse = { From 8d00d1e27e262cc78f0f1265212b9692ed7790fc Mon Sep 17 00:00:00 2001 From: susyt Date: Thu, 4 Jun 2020 18:58:48 -0700 Subject: [PATCH 386/496] GumGum: handling misconfigured requests (#5212) * uses encodeURIComponent inline * adds test for jcsi param * adds request delay depending on previous response * adds inVideo param --- modules/gumgumBidAdapter.js | 22 ++++++++++++++++++++++ test/spec/modules/gumgumBidAdapter_spec.js | 20 ++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index 273ecd44022..85eb3ccb60d 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -14,7 +14,9 @@ const ALIAS_BIDDER_CODE = ['gg'] const BID_ENDPOINT = `https://g2.gumgum.com/hbid/imp` const SUPPORTED_MEDIA_TYPES = [BANNER, VIDEO] const TIME_TO_LIVE = 60 +const DELAY_REQUEST_TIME = 1800000; // setting to 30 mins +let invalidRequestIds = {}; let browserParams = {}; let pageViewId = null @@ -132,9 +134,16 @@ function isBidRequestValid (bid) { params, adUnitCode } = bid; + const id = params.inScreen || params.inScreenPubID || params.inSlot || params.ICV || params.video || params.inVideo; + + if (invalidRequestIds[id]) { + utils.logWarn(`[GumGum] Please check the implementation for ${id} for the placement ${adUnitCode}`); + return false; + } switch (true) { case !!(params.inScreen): break; + case !!(params.inScreenPubID): break; case !!(params.inSlot): break; case !!(params.ICV): break; case !!(params.video): break; @@ -281,6 +290,19 @@ function buildRequests (validBidRequests, bidderRequest) { function interpretResponse (serverResponse, bidRequest) { const bidResponses = [] const serverResponseBody = serverResponse.body + + if (!serverResponseBody || serverResponseBody.err) { + const data = bidRequest.data || {} + const id = data.t || data.si || data.ni || data.pubId; + const delayTime = serverResponseBody ? serverResponseBody.err.drt : DELAY_REQUEST_TIME; + invalidRequestIds[id] = { productId: data.pi, timestamp: new Date().getTime() }; + + setTimeout(() => { + !!invalidRequestIds[id] && delete invalidRequestIds[id]; + }, delayTime); + utils.logWarn(`[GumGum] Please check the implementation for ${id}`); + } + const defaultResponse = { ad: { price: 0, diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index c2fb7f26559..9612276c14c 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -63,6 +63,20 @@ describe('gumgumAdapter', function () { }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); + + it('should return false if invalid request id is found', function () { + const bidRequest = { + id: 12345, + sizes: [[300, 250], [1, 1]], + url: ENDPOINT, + method: 'GET', + pi: 3, + data: { t: '10433394' } + }; + let body; + spec.interpretResponse({ body }, bidRequest); // empty response + expect(spec.isBidRequestValid(bid)).to.be.equal(false); + }); }); describe('buildRequests', function () { @@ -341,6 +355,12 @@ describe('gumgumAdapter', function () { expect(result.length).to.equal(0); }); + it('handles empty response', function () { + let body; + let result = spec.interpretResponse({ body }, bidRequest); + expect(result.length).to.equal(0); + }); + it('returns 1x1 when eligible product and size available', function () { let inscreenBidRequest = { id: 12346, From 02d5b67d85f290178f71978b1ef1f97397008c4a Mon Sep 17 00:00:00 2001 From: susyt Date: Thu, 4 Jun 2020 19:04:43 -0700 Subject: [PATCH 387/496] GumGum: update jcsi object values (#5258) * updates jcsi object * adds test for jcsi * fix lint * updates due to prebid rollback --- modules/gumgumBidAdapter.js | 10 ++++++++-- test/spec/modules/gumgumBidAdapter_spec.js | 22 ++++++++++++++++------ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index 85eb3ccb60d..3d0c27ad121 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -12,6 +12,7 @@ const storage = getStorageManager(); const BIDDER_CODE = 'gumgum' const ALIAS_BIDDER_CODE = ['gg'] const BID_ENDPOINT = `https://g2.gumgum.com/hbid/imp` +const JCSI = { t: 0, rq: 8, pbv: '$prebid.version$' } const SUPPORTED_MEDIA_TYPES = [BANNER, VIDEO] const TIME_TO_LIVE = 60 const DELAY_REQUEST_TIME = 1800000; // setting to 30 mins @@ -62,7 +63,7 @@ function _getBrowserParams(topWindowUrl) { pu: topUrl, ce: storage.cookiesAreEnabled(), dpr: topWindow.devicePixelRatio || 1, - jcsi: encodeURIComponent(JSON.stringify({ t: 0, rq: 8 })), + jcsi: JSON.stringify(JCSI), ogu: getOgURL() } @@ -323,7 +324,8 @@ function interpretResponse (serverResponse, bidRequest) { cw: wrapper, pag: { pvid - } + }, + jcsi } = Object.assign(defaultResponse, serverResponseBody) let data = bidRequest.data || {} let product = data.pi @@ -337,6 +339,10 @@ function interpretResponse (serverResponse, bidRequest) { height = '1' } + if (jcsi) { + serverResponseBody.jcsi = JCSI + } + // update Page View ID from server response pageViewId = pvid diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index 9612276c14c..e4e8cb18ac8 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -3,6 +3,7 @@ import { newBidder } from 'src/adapters/bidderFactory.js'; import { spec } from 'modules/gumgumBidAdapter.js'; const ENDPOINT = 'https://g2.gumgum.com/hbid/imp'; +const JCSI = { t: 0, rq: 8, pbv: '$prebid.version$' } describe('gumgumAdapter', function () { const adapter = newBidder(spec); @@ -274,12 +275,13 @@ describe('gumgumAdapter', function () { expect(bidRequest.data).to.not.include.any.keys('ns'); } }); - it('has jcsi param correctly encoded', function () { - const jcsi = JSON.stringify({ t: 0, rq: 8 }); - const encodedJCSI = encodeURIComponent(jcsi); + it('adds jcsi param with correct keys', function () { + const expectedKeys = Object.keys(JCSI).sort(); + const jcsi = JSON.stringify(JCSI); const bidRequest = spec.buildRequests(bidRequests)[0]; - expect(bidRequest.data.jcsi).to.not.contain(/\{.*\}/); - expect(bidRequest.data.jcsi).to.eq(encodedJCSI); + const actualKeys = Object.keys(JSON.parse(bidRequest.data.jcsi)).sort(); + expect(actualKeys).to.eq(actualKeys); + expect(bidRequest.data.jcsi).to.eq(jcsi); }); }) @@ -304,6 +306,7 @@ describe('gumgumAdapter', function () { 'css': 'html { overflow-y: auto }', 'js': 'console.log("environment", env);' }, + 'jcsi': { t: 0, rq: 8 }, 'thms': 10000 } let bidRequest = { @@ -396,7 +399,14 @@ describe('gumgumAdapter', function () { let result = spec.interpretResponse({ body: inscreenServerResponse }, inscreenBidRequest); expect(result[0].width).to.equal('1'); expect(result[0].height).to.equal('1'); - }) + }); + + it('updates jcsi object when the server response jcsi prop is found', function () { + const response = Object.assign({cw: 'AD_JSON'}, serverResponse); + const bidResponse = spec.interpretResponse({ body: response }, bidRequest)[0].ad; + const decodedResponse = JSON.parse(atob(bidResponse)); + expect(decodedResponse.jcsi).to.eql(JCSI); + }); }) describe('getUserSyncs', function () { const syncOptions = { From 994dd292f80217598c757810b729ea3d83be1b8a Mon Sep 17 00:00:00 2001 From: Tim Holmes-Mitra Date: Sat, 6 Jun 2020 02:14:16 +0100 Subject: [PATCH 388/496] * Add Glimpes Protocol Bidding Adaptor (#5293) * Initial submission of adaptor * Currently only supports Banner * 100% code coverage from tests * Author Tim Holmes-Mitra --- modules/glimpseBidAdapter.js | 58 +++++++ modules/glimpseBidAdapter.md | 101 +++++++++++ test/spec/modules/glimpseBidAdapter_spec.js | 179 ++++++++++++++++++++ 3 files changed, 338 insertions(+) create mode 100644 modules/glimpseBidAdapter.js create mode 100644 modules/glimpseBidAdapter.md create mode 100644 test/spec/modules/glimpseBidAdapter_spec.js diff --git a/modules/glimpseBidAdapter.js b/modules/glimpseBidAdapter.js new file mode 100644 index 00000000000..969c04bb451 --- /dev/null +++ b/modules/glimpseBidAdapter.js @@ -0,0 +1,58 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; + +const BIDDER_CODE = 'glimpse'; + +export const spec = { + code: BIDDER_CODE, + url: 'https://api.glimpseprotocol.io/cloud/v1/vault/prebid', + supportedMediaTypes: [BANNER], + + isBidRequestValid: (bid) => { + try { + const { placementId } = bid.params; + return typeof placementId === 'string' && placementId.length > 0; + } catch (error) { + return false; + } + }, + + buildRequests: (validBidRequests, bidderRequest) => { + const { url, code: bidderCode } = spec; + + const bids = validBidRequests.map((request) => { + delete request.mediaTypes; + return request; + }); + + const sdk = { + source: 'pbjs', + version: '$prebid.version$', + }; + + const payload = { + ...bidderRequest, + bidderCode, + bids, + sdk, + }; + + return { + method: 'POST', + url, + data: JSON.stringify(payload), + }; + }, + + interpretResponse: (serverResponse, _) => { + const bids = []; + try { + const { body } = serverResponse; + bids.push(...body); + } catch (error) {} + + return bids; + }, +}; + +registerBidder(spec); diff --git a/modules/glimpseBidAdapter.md b/modules/glimpseBidAdapter.md new file mode 100644 index 00000000000..024cc9ebfa7 --- /dev/null +++ b/modules/glimpseBidAdapter.md @@ -0,0 +1,101 @@ +# Overview + +``` +Module Name: Glimpse Protocol Bid Adapter +Module Type: Bidder Adapter +Maintainer: hello@glimpseprotocol.io +``` + +# Description + +This module connects publishers to Glimpse Protocol's demand sources via Prebid.js. Our innovative marketplace protects +consumer privacy while allowing precise targeting. It is compliant with GDPR, DPA and CCPA. + +This adapter supports Banner. + +# Test Parameters + +```javascript +var adUnits = [ + { + code: 'banner-div-a', + mediaTypes: { + banner: { + sizes: [[300, 250]], + }, + }, + bids: [ + { + bidder: 'glimpse', + params: { + placementId: 'glimpse-demo-300x250', + }, + }, + ], + }, + { + code: 'banner-div-b', + mediaTypes: { + banner: { + sizes: [[320, 50]], + }, + }, + bids: [ + { + bidder: 'glimpse', + params: { + placementId: 'glimpse-demo-320x50', + }, + }, + ], + }, + { + code: 'banner-div-c', + mediaTypes: { + banner: { + sizes: [[970, 250]], + }, + }, + bids: [ + { + bidder: 'glimpse', + params: { + placementId: 'glimpse-demo-970x250', + }, + }, + ], + }, + { + code: 'banner-div-d', + mediaTypes: { + banner: { + sizes: [[728, 90]], + }, + }, + bids: [ + { + bidder: 'glimpse', + params: { + placementId: 'glimpse-demo-728x90', + }, + }, + ], + }, + { + code: 'banner-div-e', + mediaTypes: { + banner: { + sizes: [[300, 600]], + }, + }, + bids: [ + { + bidder: 'glimpse', + params: { + placementId: 'glimpse-demo-300x600', + }, + }, + ], + }, +]; +``` diff --git a/test/spec/modules/glimpseBidAdapter_spec.js b/test/spec/modules/glimpseBidAdapter_spec.js new file mode 100644 index 00000000000..cc11efcb2af --- /dev/null +++ b/test/spec/modules/glimpseBidAdapter_spec.js @@ -0,0 +1,179 @@ +import { expect } from 'chai'; +import { spec } from 'modules/glimpseBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; + +/** + * Test Helpers + */ + +const API = 'https://api.glimpseprotocol.io/cloud/v1/vault/prebid'; + +const templateBidRequest = { + bidder: 'glimpse', + params: { + placementId: 'glimpse-demo-300x250', + }, + adUnitCode: 'banner-div-a', + sizes: [[300, 250]], + bidId: '26a80b71cfd671', + bidderRequestId: '133baeded6ac94', + auctionId: '96692a73-307b-44b8-8e4f-ddfb40341570', +}; + +const templateBidderRequest = { + bidderCode: 'glimpse', + auctionId: '96692a73-307b-44b8-8e4f-ddfb40341570', + bidderRequestId: '133baeded6ac94', + timeout: 3000, + gdprConsent: { + apiVersion: 2, + consentString: + 'COzP517OzP517AcABBENAlCsAP_AAAAAAAwIF8NX-T5eL2vju2Zdt7JEaYwfZxyigOgThgQIsW8NwIeFbBoGP2EgHBG4JCQAGBAkkgCBAQMsHGBcCQAAgIgRiRKMYE2MjzNKBJJAigkbc0FACDVunsHS2ZCY70-8O__bPAviADAvUC-AAAAA.YAAAAAAAAAAA', + gdprApplies: true, + vendorData: {}, + }, + refererInfo: { + referer: 'https://demo.glimpseprotocol.io/prebid/desktop', + reachedTop: true, + numIframes: 0, + stack: ['https://demo.glimpseprotocol.io/prebid/desktop'], + }, +}; + +const templateBidResponse = { + ad: '
HelloWorld
', + adUnitCode: 'banner-div-a', + bidder: 'glimpse', + cpm: 1.04, + creativeId: 'glimpse-demo-300x250', + currency: 'GBP', + height: 250, + mediaType: 'banner', + netRevenue: true, + pbAg: '1.04', + pbDg: '1.04', + pbHg: '1.04', + pbLg: '1.00', + pbMg: '1.05', + requestId: '133baeded6ac94', + ttl: 60, + width: 300, +}; + +const copyBidResponse = () => ({ ...templateBidResponse }); +const copyBidderRequest = () => ({ ...templateBidderRequest, bids: copyBidRequests() }); +const copyBidRequest = () => ({ ...templateBidRequest }); + +const copyBidRequests = () => [copyBidRequest()]; +const copyBidResponses = () => ({ + body: [copyBidResponse()], +}); + +/** + * Tests + */ + +describe('GlimpseProtocolAdapter', function () { + const adapter = newBidder(spec); + + describe('inherited functions', function () { + it('exists and is a function', function () { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + expect(adapter.getSpec).to.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', function () { + it('should return true when params.placementId is valid', function () { + expect(spec.isBidRequestValid(templateBidRequest)).to.equal(true); + }); + + it('should return false when params.placementId is invalid', function () { + let bid = copyBidRequest(); + delete bid.params; + bid.params = { + placementId: 0, + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when params is not passed', function () { + let bid = copyBidRequest(); + delete bid.params; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when params.placementId is not passed', function () { + let bid = copyBidRequest(); + delete bid.params.placementId; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + const bidRequest = copyBidRequest(); + const bidRequests = [bidRequest]; + + it('should add version and source information', function () { + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + + expect(payload.sdk).to.exist; + expect(payload.sdk).to.deep.equal({ + source: 'pbjs', + version: '$prebid.version$', + }); + }); + + it('should send request to API via POST', function () { + const request = spec.buildRequests(bidRequests); + expect(request.url).to.equal(API); + expect(request.method).to.equal('POST'); + }); + + it('should add GDPR consent', function () { + const bidderRequest = copyBidderRequest(); + const request = spec.buildRequests(bidRequests, bidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.gdprConsent).to.exist; + const { gdprConsent } = payload; + expect(gdprConsent.gdprApplies).to.be.true; + expect(gdprConsent.consentString).to.equal(bidderRequest.gdprConsent.consentString); + }); + + it('should add referer info', function () { + const bidderRequest = copyBidderRequest(); + const request = spec.buildRequests(bidRequests, bidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.refererInfo.referer).to.equal(templateBidderRequest.refererInfo.referer); + }); + }); + + describe('interpretResponse', function () { + it('should handle valid bid responses', function () { + const response = copyBidResponses(); + + const bids = spec.interpretResponse(response); + expect(bids).to.have.length(1); + expect(bids[0].adUnitCode).to.equal(templateBidRequest.adUnitCode); + }); + + it('should handle no bid responses', function () { + const response = copyBidResponses(); + response.body = []; + + const bids = spec.interpretResponse(response); + expect(bids).to.have.length(0); + }); + + it('should return no bid on an invalid response', function () { + const response = copyBidResponses(); + delete response.body; + + const bids = spec.interpretResponse(response); + expect(bids).to.have.length(0); + }); + }); +}); From bdaa4112d1447358a8362aea466efa9b4651de12 Mon Sep 17 00:00:00 2001 From: John Salis Date: Sun, 7 Jun 2020 18:24:59 -0400 Subject: [PATCH 389/496] fix secure protocol check for beachfront video (#5318) Co-authored-by: John Salis --- modules/beachfrontBidAdapter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/beachfrontBidAdapter.js b/modules/beachfrontBidAdapter.js index b5ac0321cae..815b0471436 100644 --- a/modules/beachfrontBidAdapter.js +++ b/modules/beachfrontBidAdapter.js @@ -6,7 +6,7 @@ import { VIDEO, BANNER } from '../src/mediaTypes.js'; import find from 'core-js-pure/features/array/find.js'; import includes from 'core-js-pure/features/array/includes.js'; -const ADAPTER_VERSION = '1.9'; +const ADAPTER_VERSION = '1.10'; const ADAPTER_NAME = 'BFIO_PREBID'; const OUTSTREAM = 'outstream'; @@ -285,7 +285,7 @@ function createVideoRequestData(bid, bidderRequest) { mimes: DEFAULT_MIMES }, video), bidfloor: bidfloor, - secure: topLocation.protocol === 'https:' ? 1 : 0, + secure: topLocation.protocol.indexOf('https') === 0 ? 1 : 0, displaymanager: ADAPTER_NAME, displaymanagerver: ADAPTER_VERSION }], From 461fea9f3d1271259e675b40f15f4408f63ef0c4 Mon Sep 17 00:00:00 2001 From: matthieularere-msq <63732822+matthieularere-msq@users.noreply.github.com> Date: Mon, 8 Jun 2020 11:29:14 +0200 Subject: [PATCH 390/496] new bidder adapter: mediasquareBidAdapter (#5317) * add adapter mediasquare * Update mediasquareBidAdapter.md * Update mediasquareBidAdapter.js * test-coverage * Update mediasquareBidAdapter.js * Update mediasquareBidAdapter_spec.js * Update mediasquareBidAdapter_spec.js * Update mediasquareBidAdapter_spec.js * Object.values unsupported by IE11 --- modules/mediasquareBidAdapter.js | 155 ++++++++++++++++++ modules/mediasquareBidAdapter.md | 35 ++++ .../modules/mediasquareBidAdapter_spec.js | 123 ++++++++++++++ 3 files changed, 313 insertions(+) create mode 100644 modules/mediasquareBidAdapter.js create mode 100644 modules/mediasquareBidAdapter.md create mode 100644 test/spec/modules/mediasquareBidAdapter_spec.js diff --git a/modules/mediasquareBidAdapter.js b/modules/mediasquareBidAdapter.js new file mode 100644 index 00000000000..91adfacb64d --- /dev/null +++ b/modules/mediasquareBidAdapter.js @@ -0,0 +1,155 @@ +import {ajax} from '../src/ajax.js'; +import {config} from '../src/config.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; +import {BANNER} from '../src/mediaTypes.js'; + +const BIDDER_CODE = 'mediasquare'; +const BIDDER_URL_PROD = 'https://pbs-front.mediasquare.fr/' +const BIDDER_URL_TEST = 'https://bidder-test.mediasquare.fr/' +const BIDDER_ENDPOINT_AUCTION = 'msq_prebid'; +const BIDDER_ENDPOINT_SYNC = 'cookie_sync'; +const BIDDER_ENDPOINT_WINNING = 'winning'; + +export const spec = { + code: BIDDER_CODE, + aliases: ['msq'], // short code + supportedMediaTypes: [BANNER], + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function(bid) { + return !!(bid.params.owner || bid.params.code); + }, + /** + * Make a server request from the list of BidRequests. + * + * @param {validBidRequests[]} - an array of bids + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function(validBidRequests, bidderRequest) { + let codes = []; + let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD; + const test = config.getConfig('debug') ? 1 : 0; + let adunitValue = null; + Object.keys(validBidRequests).forEach(key => { + adunitValue = validBidRequests[key]; + codes.push({ + owner: adunitValue.params.owner, + code: adunitValue.params.code, + adunit: adunitValue.adUnitCode, + bidId: adunitValue.bidId, + auctionId: adunitValue.auctionId, + transactionId: adunitValue.transactionId, + mediatypes: adunitValue.mediaTypes + }); + }); + const payload = { + codes: codes, + referer: encodeURIComponent(bidderRequest.refererInfo.referer) + // schain: validBidRequests.schain, + }; + if (bidderRequest && bidderRequest.gdprConsent) { + payload.gdpr = { + consent_string: bidderRequest.gdprConsent.consentString, + consent_required: bidderRequest.gdprConsent.gdprApplies + }; + }; + if (test) { payload.debug = true; } + const payloadString = JSON.stringify(payload); + return { + method: 'POST', + url: endpoint + BIDDER_ENDPOINT_AUCTION, + data: payloadString, + }; + }, + /** + * Unpack the response from the server into a list of bids. + * + * @param {ServerResponse} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function(serverResponse, bidRequest) { + const serverBody = serverResponse.body; + // const headerValue = serverResponse.headers.get('some-response-header'); + const bidResponses = []; + let bidResponse = null; + let value = null; + if (serverBody.hasOwnProperty('responses')) { + Object.keys(serverBody['responses']).forEach(key => { + value = serverBody['responses'][key]; + bidResponse = { + requestId: value['bid_id'], + cpm: value['cpm'], + width: value['width'], + height: value['height'], + creativeId: value['creative_id'], + currency: value['currency'], + netRevenue: value['net_revenue'], + ttl: value['ttl'], + ad: value['ad'], + mediasquare: { + 'bidder': value['bidder'], + 'code': value['code'] + } + }; + if (value.hasOwnProperty('deal_id')) { bidResponse['dealId'] = value['deal_id']; } + bidResponses.push(bidResponse); + }); + } + return bidResponses; + }, + + /** + * Register the user sync pixels which should be dropped after the auction. + * + * @param {SyncOptions} syncOptions Which user syncs are allowed? + * @param {ServerResponse[]} serverResponses List of server's responses. + * @return {UserSync[]} The user syncs which should be dropped. + */ + getUserSyncs: function(syncOptions, serverResponses, gdprConsent) { + let params = ''; + let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD; + if (gdprConsent && typeof gdprConsent.consentString === 'string') { + if (typeof gdprConsent.gdprApplies === 'boolean') { params += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; } else { params += `&gdpr_consent=${gdprConsent.consentString}`; } + } + if (syncOptions.iframeEnabled) { + return { + type: 'iframe', + url: endpoint + BIDDER_ENDPOINT_SYNC + '?type=iframe' + params + }; + } + if (syncOptions.pixelEnabled) { + return { + type: 'image', + url: endpoint + BIDDER_ENDPOINT_SYNC + '?type=pixel' + params + }; + } + return false; + }, + + /** + * Register bidder specific code, which will execute if a bid from this bidder won the auction + * @param {Bid} The bid that won the auction + */ + onBidWon: function(bid) { + // fires a pixel to confirm a winning bid + let params = []; + let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD; + let paramsToSearchFor = ['cpm', 'size', 'mediaType', 'currency', 'creativeId', 'adUnitCode', 'timeToRespond'] + if (bid.hasOwnProperty('mediasquare')) { + if (bid['mediasquare'].hasOwnProperty('bidder')) { params.push('bidder=' + bid['mediasquare']['bidder']); } + if (bid['mediasquare'].hasOwnProperty('code')) { params.push('code=' + bid['mediasquare']['code']); } + }; + for (let i = 0; i < paramsToSearchFor.length; i++) { + if (bid.hasOwnProperty(paramsToSearchFor[i])) { params.push(paramsToSearchFor[i] + '=' + bid[paramsToSearchFor[i]]); } + } + if (params.length > 0) { params = '?' + params.join('&'); } + ajax(endpoint + BIDDER_ENDPOINT_WINNING + params, null); + return true; + } + +} +registerBidder(spec); diff --git a/modules/mediasquareBidAdapter.md b/modules/mediasquareBidAdapter.md new file mode 100644 index 00000000000..f9f8d4be908 --- /dev/null +++ b/modules/mediasquareBidAdapter.md @@ -0,0 +1,35 @@ +# Overview + +``` +Module Name: MediaSquare Bid Adapter +Module Type: Bidder Adapter +Maintainer: tech@mediasquare.fr +``` + +# Description + +Connects to Mediasquare network for bids. + +Mediasquare bid adapter supports Banner only for the time being. + +# Test Parameters +``` +var adUnits = [ + // Banner adUnit + { + code: 'banner-div', + mediaTypes: { + banner: { + sizes: [[300, 250], [300,600]] + } + }, + bids: [{ + bidder: 'mediasquare', + params: { + owner: "test", + code: "publishername_atf_desktop_rg_pave" + } + }] + }, +]; +``` diff --git a/test/spec/modules/mediasquareBidAdapter_spec.js b/test/spec/modules/mediasquareBidAdapter_spec.js new file mode 100644 index 00000000000..56c1fd105fe --- /dev/null +++ b/test/spec/modules/mediasquareBidAdapter_spec.js @@ -0,0 +1,123 @@ +import {expect} from 'chai'; +import {spec} from 'modules/mediasquareBidAdapter.js'; +import {newBidder} from 'src/adapters/bidderFactory.js'; +import {config} from 'src/config.js'; +import * as utils from 'src/utils.js'; +import { requestBidsHook } from 'modules/consentManagement.js'; + +describe('MediaSquare bid adapter tests', function () { + var DEFAULT_PARAMS = [{ + adUnitCode: 'banner-div', + bidId: 'aaaa1234', + auctionId: 'bbbb1234', + transactionId: 'cccc1234', + mediaTypes: { + banner: { + sizes: [ + [300, 250] + ] + } + }, + bidder: 'mediasquare', + params: { + owner: 'test', + code: 'publishername_atf_desktop_rg_pave' + }, + }]; + + var BID_RESPONSE = {'body': { + 'responses': [{ + 'transaction_id': 'cccc1234', + 'cpm': 22.256608, + 'width': 300, + 'height': 250, + 'creative_id': '158534630', + 'currency': 'USD', + 'net_revenue': true, + 'ttl': 300, + 'ad': '< --- creative code --- >', + 'bidder': 'msqClassic', + 'code': 'test/publishername_atf_desktop_rg_pave', + 'bid_id': 'aaaa1234', + }] + }}; + + const DEFAULT_OPTIONS = { + gdprConsent: { + gdprApplies: true, + consentString: 'BOzZdA0OzZdA0AGABBENDJ-AAAAvh7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__79__3z3_9pxP78k89r7337Mw_v-_v-b7JCPN_Y3v-8Kg', + vendorData: {} + }, + refererInfo: { + referer: 'https://www.prebid.org', + canonicalUrl: 'https://www.prebid.org/the/link/to/the/page' + } + }; + it('Verify build request', function () { + const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); + expect(request).to.have.property('url').and.to.equal('https://pbs-front.mediasquare.fr/msq_prebid'); + expect(request).to.have.property('method').and.to.equal('POST'); + const requestContent = JSON.parse(request.data); + expect(requestContent.codes[0]).to.have.property('owner').and.to.equal('test'); + expect(requestContent.codes[0]).to.have.property('code').and.to.equal('publishername_atf_desktop_rg_pave'); + expect(requestContent.codes[0]).to.have.property('adunit').and.to.equal('banner-div'); + expect(requestContent.codes[0]).to.have.property('bidId').and.to.equal('aaaa1234'); + expect(requestContent.codes[0]).to.have.property('auctionId').and.to.equal('bbbb1234'); + expect(requestContent.codes[0]).to.have.property('transactionId').and.to.equal('cccc1234'); + expect(requestContent.codes[0]).to.have.property('mediatypes').exist; + }); + + it('Verify parse response', function () { + const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); + const response = spec.interpretResponse(BID_RESPONSE, request); + expect(response).to.have.lengthOf(1); + const bid = response[0]; + expect(bid.cpm).to.equal(22.256608); + expect(bid.ad).to.equal('< --- creative code --- >'); + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); + expect(bid.creativeId).to.equal('158534630'); + expect(bid.currency).to.equal('USD'); + expect(bid.netRevenue).to.equal(true); + expect(bid.ttl).to.equal(300); + expect(bid.requestId).to.equal('aaaa1234'); + expect(bid.mediasquare).to.exist; + expect(bid.mediasquare.bidder).to.equal('msqClassic'); + expect(bid.mediasquare.code).to.equal([DEFAULT_PARAMS[0].params.owner, DEFAULT_PARAMS[0].params.code].join('/')); + }); + + it('Verifies bidder code', function () { + expect(spec.code).to.equal('mediasquare'); + }); + + it('Verifies bidder aliases', function () { + expect(spec.aliases).to.have.lengthOf(1); + expect(spec.aliases[0]).to.equal('msq'); + }); + it('Verifies if bid request valid', function () { + expect(spec.isBidRequestValid(DEFAULT_PARAMS[0])).to.equal(true); + }); + it('Verifies bid won', function () { + const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); + const response = spec.interpretResponse(BID_RESPONSE, request); + const won = spec.onBidWon(response[0]); + expect(won).to.equal(true); + }); + it('Verifies user sync', function () { + var syncs = spec.getUserSyncs({ + iframeEnabled: true, + pixelEnabled: false, + }, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent); + expect(syncs).to.have.property('type').and.to.equal('iframe'); + syncs = spec.getUserSyncs({ + iframeEnabled: false, + pixelEnabled: true, + }, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent); + expect(syncs).to.have.property('type').and.to.equal('image'); + syncs = spec.getUserSyncs({ + iframeEnabled: false, + pixelEnabled: false, + }, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent); + expect(syncs).to.equal(false); + }); +}); From acdece88ea1c2aaae6e4f04464db9b334c4b9600 Mon Sep 17 00:00:00 2001 From: Konduit <55142865+konduit-dev@users.noreply.github.com> Date: Tue, 9 Jun 2020 00:10:08 +0300 Subject: [PATCH 391/496] Konduit Accelerate module with 'send all bids' support (#5247) * Adding Konduit module * Removed superfluous arguments passed to obtainVastUrl function * Removed superfluous arguments passed to obtainVastUrl function. * Build trigger (empty commit) * Module documentation updated according to the comments * Logic in obtainVastUrl function updated according to the review comment. * Removed hook, enabled eslint * Merged recent prebid changes * New method is introduced to process a bid and return dynamic CPM data * New Konduit Analytics adapter responsible for client auction stats collection * Updated konduit analytics adapter .md file * Fixed linter issue with more than 1 blank line used * Use '$prebid.version$' instead of the $$PREBID_GLOBAL$$.version * Updated unit tests * Enable "Send all bids" support * Updated konduitWrapper.md file * Updated links in konduitWrapper.md * Updated spec file (unit tests) * Added Konduit Prebid module version Co-authored-by: Max Shevchenko Co-authored-by: Alexander Kislitsyn --- modules/konduitAnalyticsAdapter.js | 2 + modules/konduitWrapper.js | 157 ++++++++++++++++------- modules/konduitWrapper.md | 20 ++- test/spec/modules/konduitWrapper_spec.js | 124 +++++++++++++++++- 4 files changed, 248 insertions(+), 55 deletions(-) diff --git a/modules/konduitAnalyticsAdapter.js b/modules/konduitAnalyticsAdapter.js index 00df790b18a..f6b77f23d87 100644 --- a/modules/konduitAnalyticsAdapter.js +++ b/modules/konduitAnalyticsAdapter.js @@ -7,6 +7,7 @@ import { config } from '../src/config.js'; import CONSTANTS from '../src/constants.json'; const TRACKER_HOST = 'tracker.konduit.me'; +const KONDUIT_PREBID_MODULE_VERSION = '1.0.0'; const analyticsType = 'endpoint'; @@ -168,6 +169,7 @@ function composeRequestPayload () { return { konduitId, prebidVersion: '$prebid.version$', + konduitPrebidModuleVersion: KONDUIT_PREBID_MODULE_VERSION, environment: { screen: { width, height }, language: navigator.language, diff --git a/modules/konduitWrapper.js b/modules/konduitWrapper.js index e015fb93616..3ce9bc7a501 100644 --- a/modules/konduitWrapper.js +++ b/modules/konduitWrapper.js @@ -5,16 +5,20 @@ import { config } from '../src/config.js'; import { ajaxBuilder } from '../src/ajax.js'; import { getPriceBucketString } from '../src/cpmBucketManager.js'; import { getPriceByGranularity } from '../src/auction.js'; +import { auctionManager } from '../src/auctionManager.js'; const SERVER_PROTOCOL = 'https'; const SERVER_HOST = 'p.konduit.me'; +const KONDUIT_PREBID_MODULE_VERSION = '1.0.0'; const MODULE_NAME = 'Konduit'; const KONDUIT_ID_CONFIG = 'konduit.konduitId'; +const SEND_ALL_BIDS_CONFIG = 'enableSendAllBids'; export const errorMessages = { NO_KONDUIT_ID: 'A konduitId param is required to be in configs', + NO_BIDS: 'No bids received in the auction', NO_BID: 'A bid was not found', CACHE_FAILURE: 'A bid was not cached', }; @@ -78,14 +82,81 @@ function sendRequest ({ host = SERVER_HOST, protocol = SERVER_PROTOCOL, method = ); } +function composeBidsProcessorRequestPayload(bid) { + return { + auctionId: bid.auctionId, + vastUrl: bid.vastUrl, + bidderCode: bid.bidderCode, + creativeId: bid.creativeId, + adUnitCode: bid.adUnitCode, + cpm: bid.cpm, + currency: bid.currency, + }; +} + +function setDefaultKCpmToBid(bid, winnerBid, priceGranularity) { + bid.kCpm = bid.cpm; + + if (!bid.adserverTargeting) { + bid.adserverTargeting = {}; + } + + const kCpm = getPriceByGranularity(priceGranularity)(bid); + + if (config.getConfig(SEND_ALL_BIDS_CONFIG)) { + bid.adserverTargeting[`k_cpm_${bid.bidderCode}`] = kCpm; + } + + if ((winnerBid.bidderCode === bid.bidderCode) && (winnerBid.creativeId === bid.creativeId)) { + bid.adserverTargeting.k_cpm = kCpm; + } +} + +function addKCpmToBid(kCpm, bid, winnerBid, priceGranularity) { + if (utils.isNumber(kCpm)) { + bid.kCpm = kCpm; + const priceStringsObj = getPriceBucketString( + kCpm, + config.getConfig('customPriceBucket'), + config.getConfig('currency.granularityMultiplier') + ); + + const calculatedKCpm = priceStringsObj.custom || priceStringsObj[priceGranularity] || priceStringsObj.med; + + if (config.getConfig(SEND_ALL_BIDS_CONFIG)) { + bid.adserverTargeting[`k_cpm_${bid.bidderCode}`] = calculatedKCpm; + } + + if ((winnerBid.bidderCode === bid.bidderCode) && (winnerBid.creativeId === bid.creativeId)) { + bid.adserverTargeting.k_cpm = calculatedKCpm; + } + } +} + +function addKonduitCacheKeyToBid(cacheKey, bid, winnerBid) { + if (utils.isStr(cacheKey)) { + bid.konduitCacheKey = cacheKey; + + if (config.getConfig(SEND_ALL_BIDS_CONFIG)) { + bid.adserverTargeting[`k_cache_key_${bid.bidderCode}`] = cacheKey; + } + + if ((winnerBid.bidderCode === bid.bidderCode) && (winnerBid.creativeId === bid.creativeId)) { + bid.adserverTargeting.k_cache_key = cacheKey; + bid.adserverTargeting.konduit_cache_key = cacheKey; + } + } +} + /** - * This function accepts an object with bid and tries to cache it while generating konduit_cache_key for it. + * This function accepts an object with bid and tries to cache it while generating k_cache_key for it. * In addition, it returns a list with updated bid objects where k_cpm key is added * @param {Object} options - * @param {Object} [options.bid] - winner bid from publisher - * @param {string} [options.adUnitCode] - to look for winner bid - * @param {string} [options.timeout] - timeout for bidsProcessor request - * @param {function} [options.callback] - callback will be called in the end of the request + * @param {Object} [options.bid] - a winner bid provided by a client + * @param {Object} [options.bids] - bids array provided by a client for "Send All Bids" scenario + * @param {string} [options.adUnitCode] - ad unit code that is used to get winning bids + * @param {string} [options.timeout] - timeout for Konduit bids processor HTTP request + * @param {function} [options.callback] - callback function to be executed on HTTP request end; the function is invoked with two parameters - error and bids */ export function processBids(options = {}) { const konduitId = config.getConfig(KONDUIT_ID_CONFIG); @@ -95,19 +166,28 @@ export function processBids(options = {}) { logError(errorMessages.NO_KONDUIT_ID); if (options.callback) { - options.callback(new Error(errorMessages.NO_KONDUIT_ID)); + options.callback(new Error(errorMessages.NO_KONDUIT_ID), []); } return null; } - const bid = options.bid || targeting.getWinningBids(options.adUnitCode)[0]; + const publisherBids = options.bids || auctionManager.getBidsReceived(); - if (!bid) { - logError(errorMessages.NO_BID); + const winnerBid = options.bid || targeting.getWinningBids(options.adUnitCode, publisherBids)[0]; + const bids = []; + + if (config.getConfig(SEND_ALL_BIDS_CONFIG)) { + bids.push(...publisherBids); + } else if (winnerBid) { + bids.push(winnerBid); + } + + if (!bids.length) { + logError(errorMessages.NO_BIDS); if (options.callback) { - options.callback(new Error(errorMessages.NO_BID)); + options.callback(new Error(errorMessages.NO_BIDS), []); } return null; @@ -115,23 +195,12 @@ export function processBids(options = {}) { const priceGranularity = config.getConfig('priceGranularity'); - bid.kCpm = bid.cpm; - - if (!bid.adserverTargeting) { - bid.adserverTargeting = {}; - } - - bid.adserverTargeting.k_cpm = getPriceByGranularity(priceGranularity)(bid); + const bidsToProcess = []; - const bidsToProcess = [{ - auctionId: bid.auctionId, - vastUrl: bid.vastUrl, - bidderCode: bid.bidderCode, - creativeId: bid.creativeId, - adUnitCode: bid.adUnitCode, - cpm: bid.cpm, - currency: bid.currency, - }]; + bids.forEach((bid) => { + setDefaultKCpmToBid(bid, winnerBid, priceGranularity); + bidsToProcess.push(composeBidsProcessorRequestPayload(bid)); + }); sendRequest({ method: 'POST', @@ -139,7 +208,10 @@ export function processBids(options = {}) { timeout: options.timeout || 1000, payload: { clientId: konduitId, + konduitPrebidModuleVersion: KONDUIT_PREBID_MODULE_VERSION, + enableSendAllBids: config.getConfig(SEND_ALL_BIDS_CONFIG), bids: bidsToProcess, + bidResponsesCount: auctionManager.getBidsReceived().length, }, callbacks: { success: (data) => { @@ -147,41 +219,32 @@ export function processBids(options = {}) { logInfo('Bids processed successfully ', data); try { const { kCpmData, cacheData } = JSON.parse(data); - const processedBidKey = `${bid.bidderCode}:${bid.creativeId}`; - if (!utils.isEmpty(cacheData)) { - bid.adserverTargeting.konduit_id = konduitId; - } else { - error = new Error(errorMessages.CACHE_FAILURE); + if (utils.isEmpty(cacheData)) { + throw new Error(errorMessages.CACHE_FAILURE); } - if (utils.isNumber(kCpmData[processedBidKey])) { - bid.kCpm = kCpmData[processedBidKey]; - const priceStringsObj = getPriceBucketString( - bid.kCpm, - config.getConfig('customPriceBucket'), - config.getConfig('currency.granularityMultiplier') - ); - bid.adserverTargeting.k_cpm = priceStringsObj.custom || priceStringsObj[priceGranularity] || priceStringsObj.med; - } + winnerBid.adserverTargeting.konduit_id = konduitId; + winnerBid.adserverTargeting.k_id = konduitId; - if (utils.isStr(cacheData[processedBidKey])) { - bid.konduitCacheKey = cacheData[processedBidKey]; - bid.adserverTargeting.konduit_cache_key = cacheData[processedBidKey]; - } + bids.forEach((bid) => { + const processedBidKey = `${bid.bidderCode}:${bid.creativeId}`; + addKCpmToBid(kCpmData[processedBidKey], bid, winnerBid, priceGranularity); + addKonduitCacheKeyToBid(cacheData[processedBidKey], bid, winnerBid); + }) } catch (err) { error = err; logError('Error parsing JSON response for bidsProcessor data: ', err) } if (options.callback) { - options.callback(error, [bid]); + options.callback(error, bids); } }, error: (error) => { - logError('Bid was not processed successfully ', error); + logError('Bids were not processed successfully ', error); if (options.callback) { - options.callback(utils.isStr(error) ? new Error(error) : error, [bid]); + options.callback(utils.isStr(error) ? new Error(error) : error, bids); } } } diff --git a/modules/konduitWrapper.md b/modules/konduitWrapper.md index 3097801ffab..a5718d9848e 100644 --- a/modules/konduitWrapper.md +++ b/modules/konduitWrapper.md @@ -34,8 +34,9 @@ pbjs.setConfig({ }); ``` -Please contact support@konduit.me for assistance. +Konduit module respects the Prebid `enableSendAllBids` flag and supports both ‘Send All Bids’ and ‘Use only a winner bid’ scenarios. +Please contact support@konduit.me for assistance. ## GAM related configuration @@ -43,10 +44,22 @@ It is important to configure your GAM line items. Please contact support@konduit.me for assistance. In most cases it would require only Creative VAST URL update with the following URL: + +Konduit platform supports ‘Send all bids’ scenario and depending on whether this feature is used or not GAM configuration could be slightly different. + +- Send all bids is off (a single winner bid is used) +GAM line item creative URL should be updated as: +``` +https://p.konduit.me/api/vastProxy?konduit_hb=1&konduit_hb_awarded=1&konduit_cache_key=%%PATTERN:k_cache_key%%&konduit_id=%%PATTERN:k_id%% +``` + +- Send all bids is on +GAM line item creative URL should be updated as: ``` -https://p.konduit.me/api/vastProxy?konduit_hb=1&konduit_hb_awarded=1&konduit_cache_key=%%PATTERN:konduit_cache_key%%&konduit_id=%%PATTERN:konduit_id%% +https://p.konduit.me/api/vastProxy?konduit_hb=1&konduit_hb_awarded=1&konduit_cache_key=%%PATTERN:k_cache_key_BIDDERCODE%%&konduit_id=%%PATTERN:k_id%% ``` +k_cache_key_BIDDERCODE is a bidder specific macro and ‘BIDDERCODE’ should be replaced with a bidder code. For instance, k_cache_key_appnexus. # Usage @@ -54,6 +67,7 @@ Konduit module contains a single function that accepts an `options` parameter. The `options` parameter can include: * `bid` - prebid object with VAST url that should be cached (if not passed first winning bid from `auctionManager.getWinningBids()` will be used) +* `bids` - array of prebid objects with VAST url that should be cached (if not passed and `enableSendAllBids: true` bids from `auctionManager.getBidsReceived()` will be used) * `adUnitCode` - adUnitCode where a winner bid can be found * `timeout` - max time to wait for Konduit response with cache key and kCpm data * `callback` - callback function is called once Konduit cache data for the bid. Arguments of this function are - `error` and `bids` (error should be `null` if Konduit request is successful) @@ -65,7 +79,7 @@ The function adds two parameters into the passed bid - kCpm and konduitCacheKey. pbjs.requestBids({ bidsBackHandler: function (bids) { pbjs.adServers.konduit.processBids({ - callback: function (error, bids) { + callback: function (error, processedBids) { var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ ... }); diff --git a/test/spec/modules/konduitWrapper_spec.js b/test/spec/modules/konduitWrapper_spec.js index 9fa2a66f50c..c88287c7066 100644 --- a/test/spec/modules/konduitWrapper_spec.js +++ b/test/spec/modules/konduitWrapper_spec.js @@ -10,7 +10,11 @@ describe('The Konduit vast wrapper module', function () { config.setConfig({ konduit: { konduitId } }); }); - describe('processBids function', () => { + describe('processBids function (send one bid)', () => { + beforeEach(function() { + config.setConfig({ enableSendAllBids: false }); + }); + it(`should make a correct processBids request and add kCpm and konduitCacheKey to the passed bids and to the adserverTargeting object`, function () { const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); @@ -35,7 +39,7 @@ describe('The Konduit vast wrapper module', function () { expect(bid.adserverTargeting).to.be.an('object'); expect(bid.adserverTargeting.k_cpm).to.equal(bid.pbCg || bid.pbAg); - expect(bid.adserverTargeting.konduit_cache_key).to.equal('test_cache_key'); + expect(bid.adserverTargeting.k_cache_key).to.equal('test_cache_key'); expect(bid.adserverTargeting.konduit_id).to.equal(konduitId); }); @@ -60,7 +64,7 @@ describe('The Konduit vast wrapper module', function () { expect(bid.kCpm).to.equal(bid.cpm); expect(bid.adserverTargeting.k_cpm).to.equal(bid.pbCg || bid.pbAg); - expect(bid.adserverTargeting.konduit_cache_key).to.be.undefined; + expect(bid.adserverTargeting.k_cache_key).to.be.undefined; expect(bid.adserverTargeting.konduit_id).to.be.undefined; expect(callback.firstCall.args[0]).to.be.an('error'); @@ -111,12 +115,122 @@ describe('The Konduit vast wrapper module', function () { const callback = sinon.spy(); processBids({ bid: null, + bids: [], + callback + }); + + expect(callback.calledOnce).to.be.true; + expect(callback.firstCall.args[0]).to.be.an('error'); + expect(callback.firstCall.args[0].message).to.equal(errorMessages.NO_BIDS); + }); + }); + describe('processBids function (send all bids)', () => { + beforeEach(function() { + config.setConfig({ enableSendAllBids: true }); + }); + + it(`should make a correct processBids request and add kCpm and konduitCacheKey + to the passed bids and to the adserverTargeting object`, function () { + const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + + server.respondWith(JSON.stringify({ + kCpmData: { [`${bid.bidderCode}:${bid.creativeId}`]: bid.cpm }, + cacheData: { [`${bid.bidderCode}:${bid.creativeId}`]: 'test_cache_key' }, + })); + + processBids({ adUnitCode: 'video1', bids: [bid] }); + server.respond(); + + expect(server.requests.length).to.equal(1); + + const requestBody = JSON.parse(server.requests[0].requestBody); + + expect(requestBody.clientId).to.equal(konduitId); + + expect(bid.konduitCacheKey).to.equal('test_cache_key'); + expect(bid.kCpm).to.equal(bid.cpm); + + expect(bid.adserverTargeting).to.be.an('object'); + + expect(bid.adserverTargeting.k_cpm).to.equal(bid.pbCg || bid.pbAg); + expect(bid.adserverTargeting[`k_cpm_${bid.bidderCode}`]).to.equal(bid.pbCg || bid.pbAg); + expect(bid.adserverTargeting.k_cache_key).to.equal('test_cache_key'); + expect(bid.adserverTargeting[`k_cache_key_${bid.bidderCode}`]).to.equal('test_cache_key'); + expect(bid.adserverTargeting.konduit_id).to.equal(konduitId); + }); + + it(`should call callback with error object in arguments if cacheData is empty in the response`, function () { + const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + + server.respondWith(JSON.stringify({ + kCpmData: { [`${bid.bidderCode}:${bid.creativeId}`]: bid.cpm }, + cacheData: {}, + })); + const callback = sinon.spy(); + processBids({ adUnitCode: 'video1', bids: [bid], callback }); + server.respond(); + + expect(server.requests.length).to.equal(1); + + const requestBody = JSON.parse(server.requests[0].requestBody); + + expect(requestBody.clientId).to.equal(konduitId); + + expect(bid.konduitCacheKey).to.be.undefined; + expect(bid.kCpm).to.equal(bid.cpm); + + expect(bid.adserverTargeting.k_cpm).to.equal(bid.pbCg || bid.pbAg); + expect(bid.adserverTargeting[`k_cpm_${bid.bidderCode}`]).to.equal(bid.pbCg || bid.pbAg); + expect(bid.adserverTargeting.k_cache_key).to.be.undefined; + expect(bid.adserverTargeting[`k_cache_key_${bid.bidderCode}`]).to.be.undefined; + expect(bid.adserverTargeting.konduit_id).to.be.undefined; + + expect(callback.firstCall.args[0]).to.be.an('error'); + }); + + it('should call callback if processBids request is sent successfully', function () { + const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + server.respondWith(JSON.stringify({ key: 'test' })); + const callback = sinon.spy(); + processBids({ adUnitCode: 'video1', bid: [bid], callback }); + server.respond(); + + expect(callback.calledOnce).to.be.true; + }); + + it('should call callback with error object in arguments if processBids request is failed', function () { + const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + const callback = sinon.spy(); + processBids({ adUnitCode: 'video1', bid: [bid], callback }); + server.respond(); + + expect(callback.calledOnce).to.be.true; + expect(callback.firstCall.args[0]).to.be.an('error'); + }); + + it('should call callback with error object in arguments if no konduitId in configs', function () { + config.setConfig({ konduit: { konduitId: null } }); + + const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); + const callback = sinon.spy(); + processBids({ adUnitCode: 'video1', bid: [bid], callback }); + + expect(callback.calledOnce).to.be.true; + expect(callback.firstCall.args[0]).to.be.an('error'); + expect(callback.firstCall.args[0].message).to.equal(errorMessages.NO_KONDUIT_ID); + }); + + it('should call callback with error object in arguments if no bids found', function () { + const callback = sinon.spy(); + processBids({ + bid: null, + bids: [], callback }); expect(callback.calledOnce).to.be.true; expect(callback.firstCall.args[0]).to.be.an('error'); - expect(callback.firstCall.args[0].message).to.equal(errorMessages.NO_BID); + expect(callback.firstCall.args[0].message).to.equal(errorMessages.NO_BIDS); }); }); }); @@ -152,7 +266,7 @@ function createBid(cpm, adUnitCode, durationBucket, priceIndustryDuration, uuid, 'bidder': 'appnexus', 'timeToRespond': 61, 'pbLg': '5.00', - 'pbMg': '5.00', + 'pbMg': `${cpm}.00`, 'pbHg': '5.00', 'pbAg': `${cpm}.00`, 'pbDg': '5.00', From cabbf4e512cc003ee3cf7c9a60845c65b48a5f80 Mon Sep 17 00:00:00 2001 From: Ian Flournoy Date: Mon, 8 Jun 2020 17:14:57 -0400 Subject: [PATCH 392/496] parrableIdSystem: Read legacy ID and optout cookies and migrate to new cookie storage implementation (#5219) * Add unit coverage for parrableIdSystem getId callback * PBID-14: Pass uspString to Parrable as us_privacy query parameter * PBID-14: Simplify parrableIdSystem us_privacy test * PBID-14: Only send us_privacy to Parrable when a value exists * PBID-11: Read new Parrable compound cookie _parrable_id Migrating from legacy _parrable_eid cookie. The new cookie contains ibaOptout and ccpaOptout status fields * Remove path check from parrableIdSystem url test * PBID-11: Integrate Parrable compound cookie, consolidating old cookies * PBID-11: Update parrableIdSystem requestBids hook test to support compound cookie value * PBID-11: Small refactor to parrableIdSystem spec to support compound cookie * PBID-11: Handle legacy ibaOptout as truthy value when migrating to compound cookie * PBID-11: Add parrableIdSystem spec tests covering migration of legacy cookies * PBID-11: Remove storage documentation from test pages and userId module docs * PBID-11: Remove SUBMODULES_THAT_ALWAYS_REFRESH_ID feature from userId system * PBID-11: Use better serialize implementation for Parrable compound cookie * PBID-11: Update parrableIdSystem interface documentation * Add missing extension to mock xhr import * PBID-11: Try to access eid property only when parrableId object exists * PBID-11: Construct parrableId from legacy cookies in same manner as compound cookie * Use hardcoded expiration date for legacy cookies * parrableIdSystem: Relocate new unit test from upstream * PBID-39: Fallback to cookie values when backend response is missing components Also handle another missed callback scenario if the response object parses to nothing --- .../gpt/audigentSegments_example.html | 5 - integrationExamples/gpt/userId_example.html | 5 - modules/parrableIdSystem.js | 138 +++++++++++- modules/userId/index.js | 4 - modules/userId/userId.md | 5 - src/constants.json | 3 - test/spec/modules/parrableIdSystem_spec.js | 212 ++++++++++++------ test/spec/modules/userId_spec.js | 76 ------- 8 files changed, 267 insertions(+), 181 deletions(-) diff --git a/integrationExamples/gpt/audigentSegments_example.html b/integrationExamples/gpt/audigentSegments_example.html index 9b72da76d23..7739b558327 100644 --- a/integrationExamples/gpt/audigentSegments_example.html +++ b/integrationExamples/gpt/audigentSegments_example.html @@ -162,11 +162,6 @@ params: { // change to Parrable Partner Client ID(s) you received from the Parrable Partners you are using partner: '30182847-e426-4ff9-b2b5-9ca1324ea09b' - }, - storage: { - type: "cookie", - name: "_parrable_eid", // create a cookie with this name - expires: 365 // cookie can last for a year } }, { name: "pubCommonId", diff --git a/integrationExamples/gpt/userId_example.html b/integrationExamples/gpt/userId_example.html index 6d2c2ce677a..3bb8ce2df66 100644 --- a/integrationExamples/gpt/userId_example.html +++ b/integrationExamples/gpt/userId_example.html @@ -157,11 +157,6 @@ params: { // change to Parrable Partner Client ID(s) you received from the Parrable Partners you are using partner: '30182847-e426-4ff9-b2b5-9ca1324ea09b' - }, - storage: { - type: "cookie", - name: "_parrable_eid", // create a cookie with this name - expires: 365 // cookie can last for a year } }, { name: "pubCommonId", diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js index 8c487c783ae..ec033e62983 100644 --- a/modules/parrableIdSystem.js +++ b/modules/parrableIdSystem.js @@ -10,8 +10,50 @@ import { ajax } from '../src/ajax.js'; import { submodule } from '../src/hook.js'; import { getRefererInfo } from '../src/refererDetection.js'; import { uspDataHandler } from '../src/adapterManager.js'; +import { getStorageManager } from '../src/storageManager.js'; const PARRABLE_URL = 'https://h.parrable.com/prebid'; +const PARRABLE_COOKIE_NAME = '_parrable_id'; +const LEGACY_ID_COOKIE_NAME = '_parrable_eid'; +const LEGACY_OPTOUT_COOKIE_NAME = '_parrable_optout'; +const ONE_YEAR_MS = 364 * 24 * 60 * 60 * 1000; +const EXPIRE_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:00 GMT'; + +const storage = getStorageManager(); + +function getExpirationDate() { + const oneYearFromNow = new Date(utils.timestamp() + ONE_YEAR_MS); + return oneYearFromNow.toGMTString(); +} + +function deserializeParrableId(parrableIdStr) { + const parrableId = {}; + const values = parrableIdStr.split(','); + + values.forEach(function(value) { + const pair = value.split(':'); + // unpack a value of 1 as true + parrableId[pair[0]] = +pair[1] === 1 ? true : pair[1]; + }); + + return parrableId; +} + +function serializeParrableId(parrableId) { + let components = []; + + if (parrableId.eid) { + components.push('eid:' + parrableId.eid); + } + if (parrableId.ibaOptout) { + components.push('ibaOptout:1'); + } + if (parrableId.ccpaOptout) { + components.push('ccpaOptout:1'); + } + + return components.join(','); +} function isValidConfig(configParams) { if (!configParams) { @@ -22,17 +64,70 @@ function isValidConfig(configParams) { utils.logError('User ID - parrableId submodule requires partner list'); return false; } + if (configParams.storage) { + utils.logWarn('User ID - parrableId submodule does not require a storage config'); + } return true; } -function fetchId(configParams, currentStoredId) { +function readCookie() { + const parrableIdStr = storage.getCookie(PARRABLE_COOKIE_NAME); + if (parrableIdStr) { + return deserializeParrableId(decodeURIComponent(parrableIdStr)); + } + return null; +} + +function writeCookie(parrableId) { + if (parrableId) { + const parrableIdStr = encodeURIComponent(serializeParrableId(parrableId)); + storage.setCookie(PARRABLE_COOKIE_NAME, parrableIdStr, getExpirationDate(), 'lax'); + } +} + +function readLegacyCookies() { + const eid = storage.getCookie(LEGACY_ID_COOKIE_NAME); + const ibaOptout = (storage.getCookie(LEGACY_OPTOUT_COOKIE_NAME) === 'true'); + if (eid || ibaOptout) { + const parrableId = {}; + if (eid) { + parrableId.eid = eid; + } + if (ibaOptout) { + parrableId.ibaOptout = ibaOptout; + } + return parrableId; + } + return null; +} + +function migrateLegacyCookies(parrableId) { + if (parrableId) { + writeCookie(parrableId); + if (parrableId.eid) { + storage.setCookie(LEGACY_ID_COOKIE_NAME, '', EXPIRE_COOKIE_DATE); + } + if (parrableId.ibaOptout) { + storage.setCookie(LEGACY_OPTOUT_COOKIE_NAME, '', EXPIRE_COOKIE_DATE); + } + } +} + +function fetchId(configParams) { if (!isValidConfig(configParams)) return; + let parrableId = readCookie(); + if (!parrableId) { + parrableId = readLegacyCookies(); + migrateLegacyCookies(parrableId); + } + + const eid = (parrableId) ? parrableId.eid : null; const refererInfo = getRefererInfo(); const uspString = uspDataHandler.getConsentData(); const data = { - eid: currentStoredId || null, + eid, trackers: configParams.partner.split(','), url: refererInfo.referer }; @@ -54,16 +149,31 @@ function fetchId(configParams, currentStoredId) { const callback = function (cb) { const callbacks = { success: response => { - let eid; + let newParrableId = parrableId ? utils.deepClone(parrableId) : {}; if (response) { try { let responseObj = JSON.parse(response); - eid = responseObj ? responseObj.eid : undefined; + if (responseObj) { + if (responseObj.ccpaOptout !== true) { + newParrableId.eid = responseObj.eid; + } else { + newParrableId.eid = null; + newParrableId.ccpaOptout = true; + } + if (responseObj.ibaOptout === true) { + newParrableId.ibaOptout = true; + } + } } catch (error) { utils.logError(error); + cb(); } + writeCookie(newParrableId); + cb(newParrableId); + } else { + utils.logError('parrableId: ID fetch returned an empty result'); + cb(); } - cb(eid); }, error: error => { utils.logError(`parrableId: ID fetch encountered an error`, error); @@ -73,7 +183,10 @@ function fetchId(configParams, currentStoredId) { ajax(PARRABLE_URL, callbacks, searchParams, options); }; - return { callback }; + return { + callback, + id: parrableId + }; }; /** @type {Submodule} */ @@ -86,11 +199,14 @@ export const parrableIdSubmodule = { /** * decode the stored id value for passing to bid requests * @function - * @param {Object|string} value + * @param {ParrableId} parrableId * @return {(Object|undefined} */ - decode(value) { - return (value && typeof value === 'string') ? { 'parrableid': value } : undefined; + decode(parrableId) { + if (parrableId && utils.isPlainObject(parrableId)) { + return { 'parrableid': parrableId.eid }; + } + return undefined; }, /** @@ -98,10 +214,10 @@ export const parrableIdSubmodule = { * @function * @param {SubmoduleParams} [configParams] * @param {ConsentData} [consentData] - * @returns {function(callback:function)} + * @returns {function(callback:function), id:ParrableId} */ getId(configParams, gdprConsentData, currentStoredId) { - return fetchId(configParams, currentStoredId); + return fetchId(configParams); } }; diff --git a/modules/userId/index.js b/modules/userId/index.js index 7f7fec291ed..a47565a53de 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -426,10 +426,6 @@ function initSubmodules(submodules, consentData) { refreshNeeded = storedDate && (Date.now() - storedDate.getTime() > submodule.config.storage.refreshInSeconds * 1000); } - if (CONSTANTS.SUBMODULES_THAT_ALWAYS_REFRESH_ID[submodule.config.name] === true) { - refreshNeeded = true; - } - if (!storedId || refreshNeeded) { // No previously saved id. Request one from submodule. response = submodule.submodule.getId(submodule.config.params, consentData, storedId); diff --git a/modules/userId/userId.md b/modules/userId/userId.md index e6da02a6811..5ce31a4e3a9 100644 --- a/modules/userId/userId.md +++ b/modules/userId/userId.md @@ -38,11 +38,6 @@ pbjs.setConfig({ params: { // Replace partner with comma-separated (if more than one) Parrable Partner Client ID(s) for Parrable-aware bid adapters in use partner: "30182847-e426-4ff9-b2b5-9ca1324ea09b" - }, - storage: { - type: 'cookie', - name: '_parrable_eid', - expires: 365 } }, { name: 'identityLink', diff --git a/src/constants.json b/src/constants.json index 7ffef9db1aa..5965d77a6c4 100644 --- a/src/constants.json +++ b/src/constants.json @@ -97,8 +97,5 @@ "BID_TARGETING_SET": "targetingSet", "RENDERED": "rendered", "BID_REJECTED": "bidRejected" - }, - "SUBMODULES_THAT_ALWAYS_REFRESH_ID": { - "parrableId": true } } diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js index 0183a6f79d4..fdfd3042561 100644 --- a/test/spec/modules/parrableIdSystem_spec.js +++ b/test/spec/modules/parrableIdSystem_spec.js @@ -11,76 +11,96 @@ import { server } from 'test/mocks/xhr.js'; const storage = newStorageManager(); const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; -const P_COOKIE_NAME = '_parrable_eid'; +const P_COOKIE_NAME = '_parrable_id'; const P_COOKIE_EID = '01.1563917337.test-eid'; const P_XHR_EID = '01.1588030911.test-new-eid' const P_CONFIG_MOCK = { name: 'parrableId', params: { partner: 'parrable_test_partner_123,parrable_test_partner_456' - }, - storage: { - name: '_parrable_eid', - type: 'cookie', - expires: 364 } }; -describe('Parrable ID System', function() { - function getConfigMock() { - return { - userSync: { - syncDelay: 0, - userIds: [P_CONFIG_MOCK] - } +function getConfigMock() { + return { + userSync: { + syncDelay: 0, + userIds: [P_CONFIG_MOCK] } } - - function getAdUnitMock(code = 'adUnit-code') { - return { - code, - mediaTypes: {banner: {}, native: {}}, - sizes: [ - [300, 200], - [300, 600] - ], - bids: [{ - bidder: 'sampleBidder', - params: { placementId: 'banner-only-bidder' } - }] - }; +} + +function getAdUnitMock(code = 'adUnit-code') { + return { + code, + mediaTypes: {banner: {}, native: {}}, + sizes: [ + [300, 200], + [300, 600] + ], + bids: [{ + bidder: 'sampleBidder', + params: { placementId: 'banner-only-bidder' } + }] + }; +} + +function serializeParrableId(parrableId) { + let str = ''; + if (parrableId.eid) { + str += 'eid:' + parrableId.eid; + } + if (parrableId.ibaOptout) { + str += ',ibaOptout:1'; } + if (parrableId.ccpaOptout) { + str += ',ccpaOptout:1'; + } + return str; +} + +function writeParrableCookie(parrableId) { + let cookieValue = encodeURIComponent(serializeParrableId(parrableId)); + storage.setCookie( + P_COOKIE_NAME, + cookieValue, + (new Date(Date.now() + 5000).toUTCString()), + 'lax' + ); +} + +function removeParrableCookie() { + storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); +} - describe('parrableIdSystem.getId()', function() { +describe('Parrable ID System', function() { + describe('parrableIdSystem.getId() callback', function() { + let logErrorStub; let callbackSpy = sinon.spy(); beforeEach(function() { + logErrorStub = sinon.stub(utils, 'logError'); callbackSpy.resetHistory(); + writeParrableCookie({ eid: P_COOKIE_EID }); }); - it('returns a callback used to refresh the ID', function() { - let getIdResponse = parrableIdSubmodule.getId( - P_CONFIG_MOCK.params, - null, - P_COOKIE_EID - ); - expect(getIdResponse.callback).to.be.a('function'); - }); + afterEach(function() { + removeParrableCookie(); + logErrorStub.restore(); + }) - it('callback creates xhr to Parrable that synchronizes the ID', function() { - let getIdCallback = parrableIdSubmodule.getId( - P_CONFIG_MOCK.params, - null, - P_COOKIE_EID - ).callback; + it('creates xhr to Parrable that synchronizes the ID', function() { + let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK.params); - getIdCallback(callbackSpy); + getIdResult.callback(callbackSpy); let request = server.requests[0]; let queryParams = utils.parseQS(request.url.split('?')[1]); let data = JSON.parse(atob(queryParams.data)); + expect(getIdResult.callback).to.be.a('function'); expect(request.url).to.contain('h.parrable.com'); + expect(queryParams).to.not.have.property('us_privacy'); expect(data).to.deep.equal({ eid: P_COOKIE_EID, @@ -93,45 +113,108 @@ describe('Parrable ID System', function() { JSON.stringify({ eid: P_XHR_EID }) ); - expect(callbackSpy.calledWith(P_XHR_EID)).to.be.true; + expect(callbackSpy.lastCall.lastArg).to.deep.equal({ + eid: P_XHR_EID + }); + + expect(storage.getCookie(P_COOKIE_NAME)).to.equal( + encodeURIComponent('eid:' + P_XHR_EID) + ); }); - it('passes the uspString to Parrable', function() { + it('xhr passes the uspString to Parrable', function() { let uspString = '1YNN'; uspDataHandler.setConsentData(uspString); parrableIdSubmodule.getId( P_CONFIG_MOCK.params, null, - P_COOKIE_EID + null ).callback(callbackSpy); + uspDataHandler.setConsentData(null); expect(server.requests[0].url).to.contain('us_privacy=' + uspString); }); + + it('should log an error and continue to callback if ajax request errors', function () { + let callBackSpy = sinon.spy(); + let submoduleCallback = parrableIdSubmodule.getId({partner: 'prebid'}).callback; + submoduleCallback(callBackSpy); + let request = server.requests[0]; + expect(request.url).to.contain('h.parrable.com'); + request.respond( + 503, + null, + 'Unavailable' + ); + expect(logErrorStub.calledOnce).to.be.true; + expect(callBackSpy.calledOnce).to.be.true; + }); + }); + + describe('parrableIdSystem.getId() id', function() { + it('provides the stored Parrable values if a cookie exists', function() { + writeParrableCookie({ eid: P_COOKIE_EID }); + let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK.params); + removeParrableCookie(); + + expect(getIdResult.id).to.deep.equal({ + eid: P_COOKIE_EID + }); + }); + + it('provides the stored legacy Parrable ID values if cookies exist', function() { + let oldEid = '01.111.old-eid'; + let oldEidCookieName = '_parrable_eid'; + let oldOptoutCookieName = '_parrable_optout'; + + storage.setCookie(oldEidCookieName, oldEid); + storage.setCookie(oldOptoutCookieName, 'true'); + + let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK.params); + expect(getIdResult.id).to.deep.equal({ + eid: oldEid, + ibaOptout: true + }); + + // The ID system is expected to migrate old cookies to the new format + expect(storage.getCookie(P_COOKIE_NAME)).to.equal( + encodeURIComponent('eid:' + oldEid + ',ibaOptout:1') + ); + expect(storage.getCookie(oldEidCookieName)).to.equal(null); + expect(storage.getCookie(oldOptoutCookieName)).to.equal(null); + }); }); - describe('Parrable ID in Bid Request', function() { + describe('parrableIdSystem.decode()', function() { + it('provides the Parrable ID (EID) from a stored object', function() { + let eid = '01.123.4567890'; + let parrableId = { + eid, + ccpaOptout: true + }; + + expect(parrableIdSubmodule.decode(parrableId)).to.deep.equal({ + parrableid: eid + }); + }); + }); + + describe('userId requestBids hook', function() { let adUnits; - let logErrorStub; beforeEach(function() { adUnits = [getAdUnitMock()]; - // simulate existing browser local storage values - storage.setCookie( - P_COOKIE_NAME, - P_COOKIE_EID, - (new Date(Date.now() + 5000).toUTCString()) - ); + writeParrableCookie({ eid: P_COOKIE_EID }); setSubmoduleRegistry([parrableIdSubmodule]); init(config); config.setConfig(getConfigMock()); - logErrorStub = sinon.stub(utils, 'logError'); }); afterEach(function() { + removeParrableCookie(); storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); - logErrorStub.restore(); }); - it('provides the parrableid in the bid request', function(done) { + it('when a stored Parrable ID exists it is added to bids', function(done) { requestBidsHook(function() { adUnits.forEach(unit => { unit.bids.forEach(bid => { @@ -142,20 +225,5 @@ describe('Parrable ID System', function() { done(); }, { adUnits }); }); - - it('should log an error and continue to callback if ajax request errors', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = parrableIdSubmodule.getId({partner: 'prebid'}).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('h.parrable.com'); - request.respond( - 503, - null, - 'Unavailable' - ); - expect(logErrorStub.calledOnce).to.be.true; - expect(callBackSpy.calledOnce).to.be.true; - }); }); }); diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index 02f65a6e53d..e909c53b60f 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -1231,81 +1231,5 @@ describe('User ID', function() { events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); expect(server.requests[0].url).to.equal('https://match.adsrvr.org/track/rid?ttd_pid=rubicon&fmt=json'); }); - - it('callback for submodules that always need to refresh stored id', function(done) { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; - const parrableStoredId = '01.1111111111.test-eid'; - const parrableRefreshedId = '02.2222222222.test-eid'; - coreStorage.setCookie('_parrable_eid', parrableStoredId, (new Date(Date.now() + 5000).toUTCString())); - - const parrableIdSubmoduleMock = { - name: 'parrableId', - decode: function(value) { - return { 'parrableid': value }; - }, - getId: function() { - return { - callback: function(cb) { - cb(parrableRefreshedId); - } - }; - } - }; - - const parrableConfigMock = { - userSync: { - syncDelay: 0, - userIds: [{ - name: 'parrableId', - storage: { - type: 'cookie', - name: '_parrable_eid' - } - }] - } - }; - - setSubmoduleRegistry([parrableIdSubmoduleMock]); - attachIdSystem(parrableIdSubmoduleMock); - init(config); - config.setConfig(parrableConfigMock); - - // make first bid request, should use stored id value - requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - innerAdUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.parrableid'); - expect(bid.userId.parrableid).to.equal(parrableStoredId); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'parrable.com', - uids: [{id: parrableStoredId, atype: 1}] - }); - }); - }); - - // attach a handler for auction end event to run the second bid request - events.on(CONSTANTS.EVENTS.AUCTION_END, function handler(submodule) { - if (submodule === 'parrableIdSubmoduleMock') { - // make the second bid request, id should have been refreshed - requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - innerAdUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.parrableid'); - expect(bid.userId.parrableid).to.equal(parrableRefreshedId); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'parrable.com', - uids: [{id: parrableRefreshedId, atype: 1}] - }); - }); - }); - events.off(CONSTANTS.EVENTS.AUCTION_END, handler); - done(); - } - }); - - // emit an auction end event to run the submodule callback - events.emit(CONSTANTS.EVENTS.AUCTION_END, 'parrableIdSubmoduleMock'); - }); }); }); From 612d1ad8f64148b9247cc0b50d626d87b85680e5 Mon Sep 17 00:00:00 2001 From: Kylian Deau Date: Mon, 8 Jun 2020 23:16:48 +0200 Subject: [PATCH 393/496] Teads adapter: Support deal targeting (#5270) --- modules/teadsBidAdapter.js | 3 + test/spec/modules/teadsBidAdapter_spec.js | 74 +++++++++++++++-------- 2 files changed, 52 insertions(+), 25 deletions(-) diff --git a/modules/teadsBidAdapter.js b/modules/teadsBidAdapter.js index 38c261745c7..370797e7d80 100644 --- a/modules/teadsBidAdapter.js +++ b/modules/teadsBidAdapter.js @@ -99,6 +99,9 @@ export const spec = { creativeId: bid.creativeId, placementId: bid.placementId }; + if (bid.dealId) { + bidResponse.dealId = bid.dealId + } bidResponses.push(bidResponse); }); } diff --git a/test/spec/modules/teadsBidAdapter_spec.js b/test/spec/modules/teadsBidAdapter_spec.js index e21dce9135a..6854c9ae94f 100644 --- a/test/spec/modules/teadsBidAdapter_spec.js +++ b/test/spec/modules/teadsBidAdapter_spec.js @@ -403,39 +403,63 @@ describe('teadsBidAdapter', () => { }); describe('interpretResponse', function() { - let bids = { - 'body': { - 'responses': [{ - 'ad': AD_SCRIPT, + it('should get correct bid responses', function() { + let bids = { + 'body': { + 'responses': [{ + 'ad': AD_SCRIPT, + 'cpm': 0.5, + 'currency': 'USD', + 'height': 250, + 'bidId': '3ede2a3fa0db94', + 'ttl': 360, + 'width': 300, + 'creativeId': 'er2ee', + 'placementId': 34 + }, { + 'ad': AD_SCRIPT, + 'cpm': 0.5, + 'currency': 'USD', + 'height': 200, + 'bidId': '4fef3b4gb1ec15', + 'ttl': 360, + 'width': 350, + 'creativeId': 'fs3ff', + 'placementId': 34, + 'dealId': 'ABC_123' + }] + } + }; + let expectedResponse = [ + { 'cpm': 0.5, - 'currency': 'USD', + 'width': 300, 'height': 250, + 'currency': 'USD', 'netRevenue': true, - 'bidId': '3ede2a3fa0db94', 'ttl': 360, - 'width': 300, + 'ad': AD_SCRIPT, + 'requestId': '3ede2a3fa0db94', 'creativeId': 'er2ee', 'placementId': 34 - }] - } - }; - - it('should get correct bid response', function() { - let expectedResponse = { - 'cpm': 0.5, - 'width': 300, - 'height': 250, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 360, - 'ad': AD_SCRIPT, - 'requestId': '3ede2a3fa0db94', - 'creativeId': 'er2ee', - 'placementId': 34 - }; + }, { + 'cpm': 0.5, + 'width': 350, + 'height': 200, + 'currency': 'USD', + 'netRevenue': true, + 'ttl': 360, + 'ad': AD_SCRIPT, + 'requestId': '4fef3b4gb1ec15', + 'creativeId': 'fs3ff', + 'placementId': 34, + 'dealId': 'ABC_123' + } + ] + ; let result = spec.interpretResponse(bids); - expect(result[0]).to.deep.equal(expectedResponse); + expect(result).to.eql(expectedResponse); }); it('handles nobid responses', function() { From 34f7249c7c78da4c2763e0997a2dd63934f05193 Mon Sep 17 00:00:00 2001 From: susyt Date: Mon, 8 Jun 2020 21:34:35 -0700 Subject: [PATCH 394/496] GumGum: adds new param (#5297) * adds in new videoPubID param * adds test --- modules/gumgumBidAdapter.js | 7 ++++++- test/spec/modules/gumgumBidAdapter_spec.js | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index 3d0c27ad121..2bccc30bb64 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -149,7 +149,7 @@ function isBidRequestValid (bid) { case !!(params.ICV): break; case !!(params.video): break; case !!(params.inVideo): break; - + case !!(params.videoPubID): break; default: utils.logWarn(`[GumGum] No product selected for the placement ${adUnitCode}, please check your implementation.`); return false; @@ -244,6 +244,11 @@ function buildRequests (validBidRequests, bidderRequest) { data.ni = parseInt(params.ICV, 10); data.pi = 5; } + if (params.videoPubID) { + data = Object.assign(data, _getVidParams(mediaTypes.video)); + data.pubId = params.videoPubID; + data.pi = 7; + } if (params.video) { data = Object.assign(data, _getVidParams(mediaTypes.video)); data.t = params.video; diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index e4e8cb18ac8..7022f8f96dd 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -144,6 +144,27 @@ describe('gumgumAdapter', function () { expect(bidRequest.data.pubId).to.equal(request.params.inScreenPubID); expect(bidRequest.data).to.not.include.any.keys('t'); }); + it('should send pubId if videoPubID param is specified', function () { + const mediaTypes = { + video: { + playerSize: [640, 480], + context: 'instream', + minduration: 1, + maxduration: 2, + linearity: 1, + startdelay: 1, + placement: 123456, + protocols: [1, 2] + } + }; + const request = Object.assign({}, bidRequests[0]); + request.mediaTypes = mediaTypes + request.params = { 'videoPubID': 123 }; + const bidRequest = spec.buildRequests([request])[0]; + expect(bidRequest.data).to.include.any.keys('pubId'); + expect(bidRequest.data.pubId).to.equal(request.params.videoPubID); + expect(bidRequest.data).to.not.include.any.keys('t'); + }); it('should set a ni parameter in bid request if ICV request param is found', function () { const request = Object.assign({}, bidRequests[0]); delete request.params; From 87c000d9531d5d8c52fc09a3502fd9d40faf082e Mon Sep 17 00:00:00 2001 From: Simon Critchley Date: Tue, 9 Jun 2020 14:05:29 +0100 Subject: [PATCH 395/496] Avocet bid adapter (#5262) * adds avocet bid adapter * modules/avocetBidAdapter.js: fixes lint issues * adds id5 support and test/code improvements --- modules/avocetBidAdapter.js | 141 ++++++++++++++++++ modules/avocetBidAdapter.md | 40 +++++ test/spec/modules/avocetBidAdapter_spec.js | 165 +++++++++++++++++++++ 3 files changed, 346 insertions(+) create mode 100644 modules/avocetBidAdapter.js create mode 100644 modules/avocetBidAdapter.md create mode 100644 test/spec/modules/avocetBidAdapter_spec.js diff --git a/modules/avocetBidAdapter.js b/modules/avocetBidAdapter.js new file mode 100644 index 00000000000..1163ac830ba --- /dev/null +++ b/modules/avocetBidAdapter.js @@ -0,0 +1,141 @@ +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; + +const BIDDER_CODE = 'avct'; +const DEFAULT_BASE_URL = 'https://ads.avct.cloud'; +const DEFAULT_PREBID_PATH = '/prebid'; + +function getPrebidURL() { + let host = config.getConfig('avct.baseUrl'); + if (host && typeof host === 'string') { + return `${host}${getPrebidPath()}`; + } + return `${DEFAULT_BASE_URL}${getPrebidPath()}`; +} + +function getPrebidPath() { + let prebidPath = config.getConfig('avct.prebidPath'); + if (prebidPath && typeof prebidPath === 'string') { + return prebidPath; + } + return DEFAULT_PREBID_PATH; +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid with params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bid) { + return ( + !!bid.params && + !!bid.params.placement && + typeof bid.params.placement === 'string' && + bid.params.placement.length === 24 + ); + }, + /** + * Make a server request from the list of BidRequests. + * + * @param {validBidRequests[]} - an array of bids + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function (bidRequests, bidderRequest) { + // Get currency from config + const currency = config.getConfig('currency.adServerCurrency'); + + // Publisher domain from config + const publisherDomain = config.getConfig('publisherDomain'); + + // First-party data from config + const fpd = config.getConfig('fpd'); + + // GDPR status and TCF consent string + let tcfConsentString; + let gdprApplies = false; + if (bidderRequest.gdprConsent) { + tcfConsentString = bidderRequest.gdprConsent.consentString; + gdprApplies = !!bidderRequest.gdprConsent.gdprApplies; + } + + // US privacy string + let usPrivacyString; + if (bidderRequest.uspConsent) { + usPrivacyString = bidderRequest.uspConsent; + } + + // Supply chain + let schain; + if (bidderRequest.schain) { + schain = bidderRequest.schain; + } + + // ID5 identifier + let id5id; + if (bidRequests[0].userId && bidRequests[0].userId.id5id) { + id5id = bidRequests[0].userId.id5id; + } + + // Build the avocet ext object + const ext = { + currency, + tcfConsentString, + gdprApplies, + usPrivacyString, + schain, + publisherDomain, + fpd, + id5id, + }; + + // Extract properties from bidderRequest + const { + auctionId, + auctionStart, + bidderCode, + bidderRequestId, + refererInfo, + timeout, + } = bidderRequest; + + // Construct payload + const payload = JSON.stringify({ + auctionId, + auctionStart, + bidderCode, + bidderRequestId, + refererInfo, + timeout, + bids: bidRequests, + ext, + }); + + return { + method: 'POST', + url: getPrebidURL(), + data: payload, + }; + }, + interpretResponse: function (serverResponse, bidRequest) { + if ( + !serverResponse || + !serverResponse.body || + typeof serverResponse.body !== 'object' + ) { + return []; + } + if (Array.isArray(serverResponse.body)) { + return serverResponse.body; + } + if (Array.isArray(serverResponse.body.responses)) { + return serverResponse.body.responses; + } + return []; + }, +}; +registerBidder(spec); diff --git a/modules/avocetBidAdapter.md b/modules/avocetBidAdapter.md new file mode 100644 index 00000000000..95cb29303f2 --- /dev/null +++ b/modules/avocetBidAdapter.md @@ -0,0 +1,40 @@ +# Overview + +``` +Module Name: Avocet Bidder Adapter +Module Type: Bidder Adapter +Maintainer: developers@avocet.io +``` + +# Description + +Module that connects to the Avocet advertising platform. + +# Parameters + +| Name | Scope | Description | Example | +| :------------ | :------- | :---------------------------------- | :------------------------- | +| `placement` | required | A Placement ID from Avocet. | "5ebd27607781b9af3ccc3332" | + + +# Test Parameters +``` + var adUnits = [ + { + code: 'test-div', + mediaTypes: { + banner: { + sizes: [[300, 250]], // a display size + } + }, + bids: [ + { + bidder: "avct", + params: { + placement: "5ebd27607781b9af3ccc3332" + } + } + ] + } + ]; +``` \ No newline at end of file diff --git a/test/spec/modules/avocetBidAdapter_spec.js b/test/spec/modules/avocetBidAdapter_spec.js new file mode 100644 index 00000000000..4cfd8ab89d4 --- /dev/null +++ b/test/spec/modules/avocetBidAdapter_spec.js @@ -0,0 +1,165 @@ +import { expect } from 'chai'; +import { spec } from 'modules/avocetBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; +import { config } from 'src/config'; + +describe('Avocet adapter', function () { + beforeEach(function () { + config.setConfig({ + currency: { + adServerCurrency: 'USD', + }, + publisherDomain: 'test.com', + fpd: { + some: 'data', + }, + }); + }); + + afterEach(function () { + config.resetConfig(); + }); + + describe('inherited functions', function () { + it('exists and is a function', function () { + const adapter = newBidder(spec); + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', function () { + it('should return false for bid request missing params', () => { + const invalidBidRequest = { + bid: {}, + }; + expect(spec.isBidRequestValid(invalidBidRequest)).to.equal(false); + }); + it('should return false for an invalid type placement param', () => { + const invalidBidRequest = { + params: { + placement: 123, + }, + }; + expect(spec.isBidRequestValid(invalidBidRequest)).to.equal(false); + }); + it('should return false for an invalid length placement param', () => { + const invalidBidRequest = { + params: { + placement: '123', + }, + }; + expect(spec.isBidRequestValid(invalidBidRequest)).to.equal(false); + }); + it('should return true for a valid length placement param', () => { + const validBidRequest = { + params: { + placement: '012345678901234567890123', + }, + }; + expect(spec.isBidRequestValid(validBidRequest)).to.equal(true); + }); + }); + describe('buildRequests', function () { + it('constructs a valid POST request', function () { + const request = spec.buildRequests( + [ + { + bidder: 'avct', + params: { + placement: '012345678901234567890123', + }, + userId: { + id5id: 'test' + } + }, + { + bidder: 'avct', + params: { + placement: '012345678901234567890123', + }, + }, + ], + exampleBidderRequest + ); + expect(request.method).to.equal('POST'); + expect(request.url).to.equal('https://ads.avct.cloud/prebid'); + + const requestData = JSON.parse(request.data); + expect(requestData.ext).to.be.an('object'); + expect(requestData.ext.currency).to.equal('USD'); + expect(requestData.ext.publisherDomain).to.equal('test.com'); + expect(requestData.ext.fpd).to.deep.equal({ some: 'data' }); + expect(requestData.ext.schain).to.deep.equal({ + validation: 'strict', + config: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + hp: 1, + }, + ], + }, + }); + expect(requestData.ext.id5id).to.equal('test'); + expect(requestData.bids).to.be.an('array'); + expect(requestData.bids.length).to.equal(2); + }); + }); + describe('interpretResponse', function () { + it('no response', function () { + const response = spec.interpretResponse(); + expect(response).to.be.an('array'); + expect(response.length).to.equal(0); + }); + it('no body', function () { + const response = spec.interpretResponse({}); + expect(response).to.be.an('array'); + expect(response.length).to.equal(0); + }); + it('null body', function () { + const response = spec.interpretResponse({ body: null }); + expect(response).to.be.an('array'); + expect(response.length).to.equal(0); + }); + it('empty body', function () { + const response = spec.interpretResponse({ body: {} }); + expect(response).to.be.an('array'); + expect(response.length).to.equal(0); + }); + it('null body.responses', function () { + const response = spec.interpretResponse({ body: { responses: null } }); + expect(response).to.be.an('array'); + expect(response.length).to.equal(0); + }); + it('array body', function () { + const response = spec.interpretResponse({ body: [{}] }); + expect(response).to.be.an('array'); + expect(response.length).to.equal(1); + }); + it('array body.responses', function () { + const response = spec.interpretResponse({ body: { responses: [{}] } }); + expect(response).to.be.an('array'); + expect(response.length).to.equal(1); + }); + }); +}); + +const exampleBidderRequest = { + schain: { + validation: 'strict', + config: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + hp: 1, + }, + ], + }, + }, +}; From 1264683d925bf49e4dba7d608494fc3dfb3f9783 Mon Sep 17 00:00:00 2001 From: "Isaac A. Dettman" Date: Tue, 9 Jun 2020 10:47:02 -0700 Subject: [PATCH 396/496] Event updates (#5288) * event updates * removed char * add comment regarding removal of hb_wiurl and hb_bidid * optimized tests * fix for str validation * add test helper method to reset wurl map * update resetWurlMap * update test description * optimized calls to setConfig in tests * add timestamp to videoCache cached bid * revert unintended change to adapterManager.js * update imports ordering for cleaner diff * update string validation to use isStr * fix rename event to plural form * update event to events in tests --- modules/prebidServerBidAdapter/index.js | 105 ++++++- modules/rubiconAnalyticsAdapter.js | 2 +- modules/rubiconBidAdapter.js | 3 + src/auction.js | 2 +- src/videoCache.js | 12 +- .../modules/prebidServerBidAdapter_spec.js | 265 ++++++++++++++---- test/spec/modules/rubiconBidAdapter_spec.js | 1 + test/spec/videoCache_spec.js | 99 +++++++ 8 files changed, 415 insertions(+), 74 deletions(-) diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js index 9476b7a76a3..5794dc86f3a 100644 --- a/modules/prebidServerBidAdapter/index.js +++ b/modules/prebidServerBidAdapter/index.js @@ -366,10 +366,55 @@ let nativeEventTrackerMethodMap = { */ let bidIdMap = {}; let nativeAssetCache = {}; // store processed native params to preserve + +/** + * map wurl to auction id and adId for use in the BID_WON event + */ +let wurlMap = {}; + +/** + * @param {string} auctionId + * @param {string} adId generated value set to bidObject.adId by bidderFactory Bid() + * @param {string} wurl events.winurl passed from prebidServer as wurl + */ +function addWurl(auctionId, adId, wurl) { + if ([auctionId, adId].every(utils.isStr)) { + wurlMap[`${auctionId}${adId}`] = wurl; + } +} + +/** + * @param {string} auctionId + * @param {string} adId generated value set to bidObject.adId by bidderFactory Bid() + */ +function removeWurl(auctionId, adId) { + if ([auctionId, adId].every(utils.isStr)) { + wurlMap[`${auctionId}${adId}`] = undefined; + } +} +/** + * @param {string} auctionId + * @param {string} adId generated value set to bidObject.adId by bidderFactory Bid() + * @return {(string|undefined)} events.winurl which was passed as wurl + */ +function getWurl(auctionId, adId) { + if ([auctionId, adId].every(utils.isStr)) { + return wurlMap[`${auctionId}${adId}`]; + } +} + +/** + * remove all cached wurls + */ +export function resetWurlMap() { + wurlMap = {}; +} + const OPEN_RTB_PROTOCOL = { buildRequest(s2sBidRequest, bidRequests, adUnits) { let imps = []; let aliases = {}; + const firstBidRequest = bidRequests[0]; // transform ad unit into array of OpenRTB impression objects adUnits.forEach(adUnit => { @@ -522,7 +567,7 @@ const OPEN_RTB_PROTOCOL = { Object.assign(imp, mediaTypes); // if storedAuctionResponse has been set, pass SRID - const storedAuctionResponseBid = find(bidRequests[0].bids, bid => (bid.adUnitCode === adUnit.code && bid.storedAuctionResponse)); + const storedAuctionResponseBid = find(firstBidRequest.bids, bid => (bid.adUnitCode === adUnit.code && bid.storedAuctionResponse)); if (storedAuctionResponseBid) { utils.deepSetValue(imp, 'ext.prebid.storedauctionresponse.id', storedAuctionResponseBid.storedAuctionResponse.toString()); } @@ -544,6 +589,8 @@ const OPEN_RTB_PROTOCOL = { test: getConfig('debug') ? 1 : 0, ext: { prebid: { + // set ext.prebid.auctiontimestamp with the auction timestamp. Data type is long integer. + auctiontimestamp: firstBidRequest.auctionStart, targeting: { // includewinners is always true for openrtb includewinners: true, @@ -571,9 +618,9 @@ const OPEN_RTB_PROTOCOL = { request.cur = [adServerCur[0]]; } - _appendSiteAppDevice(request, bidRequests[0].refererInfo.referer); + _appendSiteAppDevice(request, firstBidRequest.refererInfo.referer); - const digiTrust = _getDigiTrustQueryParams(bidRequests && bidRequests[0]); + const digiTrust = _getDigiTrustQueryParams(firstBidRequest); if (digiTrust) { utils.deepSetValue(request, 'user.ext.digitrust', digiTrust); } @@ -596,19 +643,19 @@ const OPEN_RTB_PROTOCOL = { } if (bidRequests) { - if (bidRequests[0].gdprConsent) { + if (firstBidRequest.gdprConsent) { // note - gdprApplies & consentString may be undefined in certain use-cases for consentManagement module let gdprApplies; - if (typeof bidRequests[0].gdprConsent.gdprApplies === 'boolean') { - gdprApplies = bidRequests[0].gdprConsent.gdprApplies ? 1 : 0; + if (typeof firstBidRequest.gdprConsent.gdprApplies === 'boolean') { + gdprApplies = firstBidRequest.gdprConsent.gdprApplies ? 1 : 0; } utils.deepSetValue(request, 'regs.ext.gdpr', gdprApplies); - utils.deepSetValue(request, 'user.ext.consent', bidRequests[0].gdprConsent.consentString); + utils.deepSetValue(request, 'user.ext.consent', firstBidRequest.gdprConsent.consentString); } // US Privacy (CCPA) support - if (bidRequests[0].uspConsent) { - utils.deepSetValue(request, 'regs.ext.us_privacy', bidRequests[0].uspConsent); + if (firstBidRequest.uspConsent) { + utils.deepSetValue(request, 'regs.ext.us_privacy', firstBidRequest.uspConsent); } } @@ -658,10 +705,28 @@ const OPEN_RTB_PROTOCOL = { bidRequest.serverResponseTimeMs = serverResponseTimeMs; } - const extPrebidTargeting = utils.deepAccess(bid, 'ext.prebid.targeting'); + // Look for seatbid[].bid[].ext.prebid.bidid and place it in the bidResponse object for use in analytics adapters as 'pbsBidId' + const bidId = utils.deepAccess(bid, 'ext.prebid.bidid'); + if (utils.isStr(bidId)) { + bidObject.pbsBidId = bidId; + } + + // store wurl by auctionId and adId so it can be accessed from the BID_WON event handler + if (utils.isStr(utils.deepAccess(bid, 'ext.prebid.events.win'))) { + addWurl(bidRequest.auctionId, bidObject.adId, utils.deepAccess(bid, 'ext.prebid.events.win')); + } + + let extPrebidTargeting = utils.deepAccess(bid, 'ext.prebid.targeting'); // If ext.prebid.targeting exists, add it as a property value named 'adserverTargeting' - if (extPrebidTargeting && typeof extPrebidTargeting === 'object') { + // The removal of hb_winurl and hb_bidid targeting values is temporary + // once we get through the transition, this block will be removed. + if (utils.isPlainObject(extPrebidTargeting)) { + // If wurl exists, remove hb_winurl and hb_bidid targeting attributes + if (utils.isStr(utils.deepAccess(bid, 'ext.prebid.events.win'))) { + extPrebidTargeting = utils.getDefinedParams(extPrebidTargeting, Object.keys(extPrebidTargeting) + .filter(i => (i.indexOf('hb_winurl') === -1 && i.indexOf('hb_bidid') === -1))); + } bidObject.adserverTargeting = extPrebidTargeting; } @@ -773,6 +838,21 @@ const OPEN_RTB_PROTOCOL = { } }; +/** + * BID_WON event to request the wurl + * @param {Bid} bid the winning bid object + */ +function bidWonHandler(bid) { + const wurl = getWurl(bid.auctionId, bid.adId); + if (utils.isStr(wurl)) { + utils.logMessage(`Invoking image pixel for wurl on BID_WIN: "${wurl}"`); + utils.triggerPixel(wurl); + + // remove from wurl cache, since the wurl url was called + removeWurl(bid.auctionId, bid.adId); + } +} + /** * Bidder adapter for Prebid Server */ @@ -856,6 +936,9 @@ export function PrebidServer() { doClientSideSyncs(requestedBidders); } + // Listen for bid won to call wurl + events.on(EVENTS.BID_WON, bidWonHandler); + return Object.assign(this, { callBids: baseAdapter.callBids, setBidderCode: baseAdapter.setBidderCode, diff --git a/modules/rubiconAnalyticsAdapter.js b/modules/rubiconAnalyticsAdapter.js index 8f30a38723b..00ad14dd316 100644 --- a/modules/rubiconAnalyticsAdapter.js +++ b/modules/rubiconAnalyticsAdapter.js @@ -87,7 +87,7 @@ function sendMessage(auctionId, bidWonId) { function formatBid(bid) { return utils.pick(bid, [ 'bidder', - 'bidId', bidId => utils.deepAccess(bid, 'bidResponse.seatBidId') || bidId, + 'bidId', bidId => utils.deepAccess(bid, 'bidResponse.pbsBidId') || utils.deepAccess(bid, 'bidResponse.seatBidId') || bidId, 'status', 'error', 'source', (source, bid) => { diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index 3c17f609a37..f09bc51e2c5 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -339,6 +339,9 @@ export const spec = { utils.deepSetValue(data.imp[0], 'ext.prebid.storedauctionresponse.id', bidRequest.storedAuctionResponse.toString()); } + // set ext.prebid.auctiontimestamp using auction time + utils.deepSetValue(data.imp[0], 'ext.prebid.auctiontimestamp', bidderRequest.auctionStart); + return { method: 'POST', url: VIDEO_ENDPOINT, diff --git a/src/auction.js b/src/auction.js index 6166e59bbf0..b82b4752479 100644 --- a/src/auction.js +++ b/src/auction.js @@ -483,7 +483,7 @@ export const callPrebidCache = hook('async', function(auctionInstance, bidRespon afterBidAdded(); } } - }); + }, bidderRequest); }, 'callPrebidCache'); // Postprocess the bids so that all the universal properties exist, no matter which bidder they came from. diff --git a/src/videoCache.js b/src/videoCache.js index 46bf74ee553..9f1fd7e4117 100644 --- a/src/videoCache.js +++ b/src/videoCache.js @@ -10,7 +10,8 @@ */ import { ajax } from './ajax.js'; -import { config } from '../src/config.js'; +import { config } from './config.js'; +import * as utils from './utils.js'; /** * @typedef {object} CacheableUrlBid @@ -70,6 +71,10 @@ function toStorageRequest(bid) { if (config.getConfig('cache.vasttrack')) { payload.bidder = bid.bidder; payload.bidid = bid.requestId; + // function has a thisArg set to bidderRequest for accessing the auctionStart + if (utils.isPlainObject(this) && this.hasOwnProperty('auctionStart')) { + payload.timestamp = this.auctionStart; + } } if (typeof bid.customCacheKey === 'string' && bid.customCacheKey !== '') { @@ -126,11 +131,12 @@ function shimStorageCallback(done) { * * @param {CacheableBid[]} bids A list of bid objects which should be cached. * @param {videoCacheStoreCallback} [done] An optional callback which should be executed after + * @param {BidderRequest} [bidderRequest] * the data has been stored in the cache. */ -export function store(bids, done) { +export function store(bids, done, bidderRequest) { const requestData = { - puts: bids.map(toStorageRequest) + puts: bids.map(toStorageRequest, bidderRequest) }; ajax(config.getConfig('cache.url'), shimStorageCallback(done), JSON.stringify(requestData), { diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index 4744bef0ee3..f66c87582f5 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { PrebidServer as Adapter, resetSyncedStatus } from 'modules/prebidServerBidAdapter/index.js'; +import { PrebidServer as Adapter, resetSyncedStatus, resetWurlMap } from 'modules/prebidServerBidAdapter/index.js'; import adapterManager from 'src/adapterManager.js'; import * as utils from 'src/utils.js'; import { ajax } from 'src/ajax.js'; @@ -261,7 +261,12 @@ const RESPONSE_OPENRTB = { 'w': 300, 'h': 250, 'ext': { - 'prebid': { 'type': 'banner' }, + 'prebid': { + 'type': 'banner', + 'event': { + 'win': 'http://wurl.org?id=333' + } + }, 'bidder': { 'appnexus': { 'brand_id': 1, @@ -304,6 +309,7 @@ const RESPONSE_OPENRTB_VIDEO = { ext: { prebid: { type: 'video', + bidid: '654321' }, bidder: { appnexus: { @@ -432,6 +438,7 @@ describe('S2S Adapter', function () { done = sinon.spy(); beforeEach(function () { + config.resetConfig(); adapter = new Adapter(); BID_REQUESTS = [ { @@ -481,16 +488,15 @@ describe('S2S Adapter', function () { done.resetHistory(); }); + after(function () { + config.resetConfig(); + }); + describe('request function', function () { beforeEach(function () { - config.resetConfig(); resetSyncedStatus(); }); - afterEach(function () { - config.resetConfig(); - }); - it('should not add outstrean without renderer', function () { let ortb2Config = utils.deepClone(CONFIG); ortb2Config.endpoint = 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'; @@ -509,7 +515,6 @@ describe('S2S Adapter', function () { describe('gdpr tests', function () { afterEach(function () { - config.resetConfig(); $$PREBID_GLOBAL$$.requestBids.removeAll(); }); @@ -608,7 +613,6 @@ describe('S2S Adapter', function () { describe('us_privacy (ccpa) consent data', function () { afterEach(function () { - config.resetConfig(); $$PREBID_GLOBAL$$.requestBids.removeAll(); }); @@ -653,7 +657,6 @@ describe('S2S Adapter', function () { describe('gdpr and us_privacy (ccpa) consent data', function () { afterEach(function () { - config.resetConfig(); $$PREBID_GLOBAL$$.requestBids.removeAll(); }); @@ -955,6 +958,7 @@ describe('S2S Adapter', function () { aliases: { brealtime: 'appnexus' }, + auctiontimestamp: 1510852447530, targeting: { includebidderkeys: false, includewinners: true @@ -989,6 +993,7 @@ describe('S2S Adapter', function () { aliases: { [alias]: 'appnexus' }, + auctiontimestamp: 1510852447530, targeting: { includebidderkeys: false, includewinners: true @@ -1240,6 +1245,7 @@ describe('S2S Adapter', function () { expect(requestBid).to.haveOwnProperty('ext'); expect(requestBid.ext).to.haveOwnProperty('prebid'); expect(requestBid.ext.prebid).to.deep.equal({ + auctiontimestamp: 1510852447530, foo: 'bar', targeting: { includewinners: true, @@ -1271,6 +1277,7 @@ describe('S2S Adapter', function () { expect(requestBid).to.haveOwnProperty('ext'); expect(requestBid.ext).to.haveOwnProperty('prebid'); expect(requestBid.ext.prebid).to.deep.equal({ + auctiontimestamp: 1510852447530, targeting: { includewinners: false, includebidderkeys: true @@ -1304,6 +1311,7 @@ describe('S2S Adapter', function () { expect(requestBid).to.haveOwnProperty('ext'); expect(requestBid.ext).to.haveOwnProperty('prebid'); expect(requestBid.ext.prebid).to.deep.equal({ + auctiontimestamp: 1510852447530, cache: { vastxml: 'vastxml-set-though-extPrebid.cache.vastXml' }, @@ -1459,67 +1467,52 @@ describe('S2S Adapter', function () { }); describe('response handler', function () { - let server; - let logWarnSpy; - beforeEach(function () { - server = sinon.fakeServer.create(); sinon.stub(utils, 'triggerPixel'); sinon.stub(utils, 'insertUserSyncIframe'); sinon.stub(utils, 'logError'); sinon.stub(events, 'emit'); - logWarnSpy = sinon.spy(utils, 'logWarn'); }); afterEach(function () { - server.restore(); utils.triggerPixel.restore(); utils.insertUserSyncIframe.restore(); utils.logError.restore(); events.emit.restore(); - logWarnSpy.restore(); }); // TODO: test dependent on pbjs_api_spec. Needs to be isolated it('does not call addBidResponse and calls done when ad unit not set', function () { - server.respondWith(JSON.stringify(RESPONSE_NO_BID_NO_UNIT)); - config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_NO_BID_NO_UNIT)); sinon.assert.notCalled(addBidResponse); sinon.assert.calledOnce(done); }); it('does not call addBidResponse and calls done when server requests cookie sync', function () { - server.respondWith(JSON.stringify(RESPONSE_NO_COOKIE)); - config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_NO_COOKIE)); sinon.assert.notCalled(addBidResponse); sinon.assert.calledOnce(done); }); it('does not call addBidResponse and calls done when ad unit is set', function () { - server.respondWith(JSON.stringify(RESPONSE_NO_BID_UNIT_SET)); - config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_NO_BID_UNIT_SET)); sinon.assert.notCalled(addBidResponse); sinon.assert.calledOnce(done); }); it('registers successful bids and calls done when there are less bids than requests', function () { - server.respondWith(JSON.stringify(RESPONSE_OPENRTB)); - config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); sinon.assert.calledOnce(addBidResponse); sinon.assert.calledOnce(done); @@ -1533,11 +1526,9 @@ describe('S2S Adapter', function () { }); it('should have dealId in bidObject', function () { - server.respondWith(JSON.stringify(RESPONSE_OPENRTB)); - config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); const response = addBidResponse.firstCall.args[1]; expect(response).to.have.property('dealId', 'test-dealid'); }); @@ -1553,9 +1544,8 @@ describe('S2S Adapter', function () { cacheResponse.seatbid.forEach(item => { item.bid[0].ext.prebid.targeting = targetingTestData }); - server.respondWith(JSON.stringify(cacheResponse)); adapter.callBids(VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); sinon.assert.calledOnce(addBidResponse); const response = addBidResponse.firstCall.args[1]; @@ -1567,9 +1557,8 @@ describe('S2S Adapter', function () { }); it('should set the bidResponse currency to whats in the PBS response', function() { - server.respondWith(JSON.stringify(RESPONSE_OPENRTB)); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); sinon.assert.calledOnce(addBidResponse); const pbjsResponse = addBidResponse.firstCall.args[1]; expect(pbjsResponse).to.have.property('currency', 'EUR'); @@ -1578,9 +1567,8 @@ describe('S2S Adapter', function () { it('should set the default bidResponse currency when not specified in OpenRTB', function() { let modifiedResponse = utils.deepClone(RESPONSE_OPENRTB); modifiedResponse.cur = ''; - server.respondWith(JSON.stringify(modifiedResponse)); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(modifiedResponse)); sinon.assert.calledOnce(addBidResponse); const pbjsResponse = addBidResponse.firstCall.args[1]; expect(pbjsResponse).to.have.property('currency', 'USD'); @@ -1597,11 +1585,9 @@ describe('S2S Adapter', function () { item.bid[0].ext.prebid.targeting = targetingTestData }); - server.respondWith(JSON.stringify(cacheResponse)); - config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); sinon.assert.calledOnce(addBidResponse); const response = addBidResponse.firstCall.args[1]; expect(response).to.have.property('adserverTargeting').that.deep.equals({ 'foo': 'bar' }); @@ -1613,11 +1599,9 @@ describe('S2S Adapter', function () { }; sinon.stub(adapterManager, 'getBidAdapter').callsFake(() => rubiconAdapter); - server.respondWith(JSON.stringify(RESPONSE_NO_PBS_COOKIE)); - config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_NO_PBS_COOKIE)); sinon.assert.calledOnce(rubiconAdapter.registerSyncs); @@ -1635,9 +1619,8 @@ describe('S2S Adapter', function () { }); config.setConfig({ s2sConfig }); - server.respondWith(JSON.stringify(RESPONSE_OPENRTB)); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); sinon.assert.calledOnce(rubiconAdapter.registerSyncs); @@ -1650,9 +1633,8 @@ describe('S2S Adapter', function () { }); config.setConfig({ s2sConfig }); - server.respondWith(JSON.stringify(RESPONSE_OPENRTB)); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); sinon.assert.calledOnce(events.emit); const event = events.emit.firstCall.args; @@ -1675,9 +1657,8 @@ describe('S2S Adapter', function () { }); config.setConfig({ s2sConfig }); - server.respondWith(JSON.stringify(RESPONSE_OPENRTB_VIDEO)); adapter.callBids(VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB_VIDEO)); sinon.assert.calledOnce(addBidResponse); const response = addBidResponse.firstCall.args[1]; @@ -1703,9 +1684,9 @@ describe('S2S Adapter', function () { } } }); - server.respondWith(JSON.stringify(cacheResponse)); + adapter.callBids(VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); sinon.assert.calledOnce(addBidResponse); const response = addBidResponse.firstCall.args[1]; @@ -1729,9 +1710,8 @@ describe('S2S Adapter', function () { cacheResponse.seatbid.forEach(item => { item.bid[0].ext.prebid.targeting = targetingTestData }); - server.respondWith(JSON.stringify(cacheResponse)); adapter.callBids(VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); sinon.assert.calledOnce(addBidResponse); const response = addBidResponse.firstCall.args[1]; @@ -1756,9 +1736,8 @@ describe('S2S Adapter', function () { hb_cache_path: '/cache' } }); - server.respondWith(JSON.stringify(cacheResponse)); adapter.callBids(VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); sinon.assert.calledOnce(addBidResponse); const response = addBidResponse.firstCall.args[1]; @@ -1768,6 +1747,77 @@ describe('S2S Adapter', function () { expect(response).to.have.property('vastUrl', 'https://prebid-cache.net/cache?uuid=a5ad3993'); }); + it('handles response cache from ext.prebid.targeting with wurl', function () { + const s2sConfig = Object.assign({}, CONFIG, { + endpoint: 'https://prebidserverurl/openrtb2/auction?querystring=param' + }); + config.setConfig({ s2sConfig }); + const cacheResponse = utils.deepClone(RESPONSE_OPENRTB_VIDEO); + cacheResponse.seatbid.forEach(item => { + item.bid[0].ext.prebid.events = { + win: 'https://wurl.com?a=1&b=2' + }; + item.bid[0].ext.prebid.targeting = { + hb_uuid: 'a5ad3993', + hb_cache_host: 'prebid-cache.net', + hb_cache_path: '/cache' + } + }); + adapter.callBids(VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax); + server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); + + sinon.assert.calledOnce(addBidResponse); + const response = addBidResponse.firstCall.args[1]; + expect(response).to.have.property('pbsBidId', '654321'); + }); + + it('handles response cache from ext.prebid.targeting with wurl and removes invalid targeting', function () { + const s2sConfig = Object.assign({}, CONFIG, { + endpoint: 'https://prebidserverurl/openrtb2/auction?querystring=param' + }); + config.setConfig({ s2sConfig }); + const cacheResponse = utils.deepClone(RESPONSE_OPENRTB_VIDEO); + cacheResponse.seatbid.forEach(item => { + item.bid[0].ext.prebid.events = { + win: 'https://wurl.com?a=1&b=2' + }; + item.bid[0].ext.prebid.targeting = { + hb_uuid: 'a5ad3993', + hb_cache_host: 'prebid-cache.net', + hb_cache_path: '/cache', + hb_winurl: 'https://hbwinurl.com?a=1&b=2', + hb_bidid: '1234567890', + } + }); + adapter.callBids(VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax); + server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); + + sinon.assert.calledOnce(addBidResponse); + const response = addBidResponse.firstCall.args[1]; + + expect(response.adserverTargeting).to.deep.equal({ + hb_uuid: 'a5ad3993', + hb_cache_host: 'prebid-cache.net', + hb_cache_path: '/cache' + }); + }); + + it('add request property pbsBidId with ext.prebid.bidid value', function () { + const s2sConfig = Object.assign({}, CONFIG, { + endpoint: 'https://prebidserverurl/openrtb2/auction?querystring=param' + }); + config.setConfig({ s2sConfig }); + const cacheResponse = utils.deepClone(RESPONSE_OPENRTB_VIDEO); + + adapter.callBids(VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax); + server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); + + sinon.assert.calledOnce(addBidResponse); + const response = addBidResponse.firstCall.args[1]; + + expect(response).to.have.property('pbsBidId', '654321'); + }); + it('handles OpenRTB native responses', function () { sinon.stub(utils, 'getBidRequest').returns({ adUnitCode: 'div-gpt-ad-1460505748561-0', @@ -1779,9 +1829,8 @@ describe('S2S Adapter', function () { }); config.setConfig({ s2sConfig }); - server.respondWith(JSON.stringify(RESPONSE_OPENRTB_NATIVE)); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.respond(); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB_NATIVE)); sinon.assert.calledOnce(addBidResponse); const response = addBidResponse.firstCall.args[1]; @@ -1796,6 +1845,98 @@ describe('S2S Adapter', function () { }); }); + describe('bid won events', function () { + let uniqueIdCount = 0; + let triggerPixelStub; + const staticUniqueIds = ['1000', '1001', '1002', '1003']; + + before(function () { + triggerPixelStub = sinon.stub(utils, 'triggerPixel'); + }); + + beforeEach(function () { + resetWurlMap(); + sinon.stub(utils, 'insertUserSyncIframe'); + sinon.stub(utils, 'logError'); + sinon.stub(utils, 'getUniqueIdentifierStr').callsFake(() => { + uniqueIdCount++; + return staticUniqueIds[uniqueIdCount - 1]; + }); + triggerPixelStub.resetHistory(); + + config.setConfig({ + s2sConfig: Object.assign({}, CONFIG, { + endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' + }) + }); + }); + + afterEach(function () { + utils.triggerPixel.resetHistory(); + utils.insertUserSyncIframe.restore(); + utils.logError.restore(); + utils.getUniqueIdentifierStr.restore(); + uniqueIdCount = 0; + }); + + after(function () { + triggerPixelStub.restore(); + }); + + it('should call triggerPixel if wurl is defined', function () { + const clonedResponse = utils.deepClone(RESPONSE_OPENRTB); + clonedResponse.seatbid[0].bid[0].ext.prebid.events = { + win: 'https://wurl.org' + }; + + adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); + server.requests[0].respond(200, {}, JSON.stringify(clonedResponse)); + + events.emit(CONSTANTS.EVENTS.BID_WON, { + auctionId: '173afb6d132ba3', + adId: '1000' + }); + + sinon.assert.calledOnce(addBidResponse); + expect(utils.triggerPixel.called).to.be.true; + expect(utils.triggerPixel.getCall(0).args[0]).to.include('https://wurl.org'); + }); + + it('should not call triggerPixel if the wurl cache does not contain the winning bid', function () { + const clonedResponse = utils.deepClone(RESPONSE_OPENRTB); + clonedResponse.seatbid[0].bid[0].ext.prebid.events = { + win: 'https://wurl.org' + }; + + adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); + server.requests[0].respond(200, {}, JSON.stringify(clonedResponse)); + + events.emit(CONSTANTS.EVENTS.BID_WON, { + auctionId: '173afb6d132ba3', + adId: 'missingAdId' + }); + + sinon.assert.calledOnce(addBidResponse) + expect(utils.triggerPixel.called).to.be.false; + }); + + it('should not call triggerPixel if wurl is undefined', function () { + const clonedResponse = utils.deepClone(RESPONSE_OPENRTB); + clonedResponse.seatbid[0].bid[0].ext.prebid.events = {}; + + adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); + server.requests[0].respond(200, {}, JSON.stringify(clonedResponse)); + + events.emit(CONSTANTS.EVENTS.BID_WON, { + auctionId: '173afb6d132ba3', + adId: '1060' + }); + + sinon.assert.calledOnce(addBidResponse) + expect(utils.triggerPixel.called).to.be.false; + }); + }) + describe('s2sConfig', function () { let logErrorSpy; @@ -1901,6 +2042,14 @@ describe('S2S Adapter', function () { }); it('should return proper defaults', function () { + const options = { + accountId: 'abc', + bidders: ['rubicon'], + defaultVendor: 'rubicon', + timeout: 750 + }; + + config.setConfig({ s2sConfig: options }); expect(config.getConfig('s2sConfig')).to.deep.equal({ 'accountId': 'abc', 'adapter': 'prebidServer', diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 99928b41d7b..11ed17df5f8 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -1461,6 +1461,7 @@ describe('the rubicon adapter', function () { expect(post.site.content.language).to.equal('en'); expect(imp.ext.rubicon.video.skip).to.equal(1); expect(imp.ext.rubicon.video.skipafter).to.equal(15); + expect(imp.ext.prebid.auctiontimestamp).to.equal(1472239426000); expect(post.user.ext.consent).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); expect(post.user.ext.eids[0].source).to.equal('liveintent.com'); expect(post.user.ext.eids[0].uids[0].id).to.equal('0000-1111-2222-3333'); diff --git a/test/spec/videoCache_spec.js b/test/spec/videoCache_spec.js index 7d706947416..6bb214af8a0 100644 --- a/test/spec/videoCache_spec.js +++ b/test/spec/videoCache_spec.js @@ -5,6 +5,50 @@ import { server } from 'test/mocks/xhr.js'; const should = chai.should(); +function getMockBid(bidder, auctionId, bidderRequestId) { + return { + 'bidder': bidder, + 'params': { + 'placementId': '10433394', + 'member': 123, + 'keywords': { + 'foo': ['bar', 'baz'], + 'fizz': ['buzz'] + } + }, + 'bid_id': '12345abc', + 'adUnitCode': 'div-gpt-ad-1460505748561-0', + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250]] + } + }, + 'transactionId': '4ef956ad-fd83-406d-bd35-e4bb786ab86c', + 'sizes': [300, 250], + 'bidId': '123', + 'bidderRequestId': bidderRequestId, + 'auctionId': auctionId, + 'storedAuctionResponse': 11111 + }; +} + +function getMockBidRequest(bidder = 'appnexus', auctionId = '173afb6d132ba3', bidderRequestId = '3d1063078dfcc8') { + return { + 'bidderCode': bidder, + 'auctionId': auctionId, + 'bidderRequestId': bidderRequestId, + 'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5', + 'bids': [getMockBid(bidder, auctionId, bidderRequestId)], + 'auctionStart': 1510852447530, + 'timeout': 5000, + 'src': 's2s', + 'doneCbCallCount': 0, + 'refererInfo': { + 'referer': 'http://mytestpage.com' + } + } +} + describe('The video cache', function () { function assertError(callbackSpy) { callbackSpy.calledOnce.should.equal(true); @@ -192,6 +236,61 @@ describe('The video cache', function () { JSON.parse(request.requestBody).should.deep.equal(payload); }); + it('should include additional params in request payload should config.cache.vasttrack be true and bidderRequest argument was defined', () => { + config.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache', + vasttrack: true + } + }); + + const customKey1 = 'vasttrack_123'; + const customKey2 = 'vasttrack_abc'; + const vastXml1 = 'testvast1'; + const vastXml2 = 'testvast2'; + + const bids = [{ + vastXml: vastXml1, + ttl: 25, + customCacheKey: customKey1, + requestId: '12345abc', + bidder: 'appnexus' + }, { + vastXml: vastXml2, + ttl: 25, + customCacheKey: customKey2, + requestId: 'cba54321', + bidder: 'rubicon' + }]; + + store(bids, function () { }, getMockBidRequest()); + const request = server.requests[0]; + request.method.should.equal('POST'); + request.url.should.equal('https://prebid.adnxs.com/pbc/v1/cache'); + request.requestHeaders['Content-Type'].should.equal('text/plain;charset=utf-8'); + let payload = { + puts: [{ + type: 'xml', + value: vastXml1, + ttlseconds: 25, + key: customKey1, + bidid: '12345abc', + bidder: 'appnexus', + timestamp: 1510852447530 + }, { + type: 'xml', + value: vastXml2, + ttlseconds: 25, + key: customKey2, + bidid: 'cba54321', + bidder: 'rubicon', + timestamp: 1510852447530 + }] + }; + + JSON.parse(request.requestBody).should.deep.equal(payload); + }); + function assertRequestMade(bid, expectedValue) { store([bid], function () { }); From e91bcdd36008ba54433003c30bad1ef1d17b9776 Mon Sep 17 00:00:00 2001 From: Marcin Muras <47107445+mmuras@users.noreply.github.com> Date: Wed, 10 Jun 2020 08:56:06 +0200 Subject: [PATCH 397/496] AdOcean adapter - support for sizes defined in Prebid configuration. (#5337) * AdOcean adapter - support for multiple sizes * AdOcean adapter - tests - use normal functions instead of arrow ones for consistency * AdOcean adapter - support for multiple sizes - changed way of sending dimensions * AdOcean adapter - change separator between sizes group * AdOcean adapter - small fix in buildRequest --- modules/adoceanBidAdapter.js | 30 +++++++++++------ test/spec/modules/adoceanBidAdapter_spec.js | 36 ++++++++++++++++++--- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/modules/adoceanBidAdapter.js b/modules/adoceanBidAdapter.js index 2b14876fe6f..b75d1972f5a 100644 --- a/modules/adoceanBidAdapter.js +++ b/modules/adoceanBidAdapter.js @@ -3,23 +3,21 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'adocean'; -function buildEndpointUrl(emiter, payload) { - let payloadString = ''; - utils._each(payload, function(v, k) { - if (payloadString.length) { - payloadString += '&'; - } - payloadString += k + '=' + encodeURIComponent(v); +function buildEndpointUrl(emiter, payloadMap) { + const payload = []; + utils._each(payloadMap, function(v, k) { + payload.push(k + '=' + encodeURIComponent(v)); }); const randomizedPart = Math.random().toString().slice(2); - return 'https://' + emiter + '/_' + randomizedPart + '/ad.json?' + payloadString; + return 'https://' + emiter + '/_' + randomizedPart + '/ad.json?' + payload.join('&'); } function buildRequest(masterBidRequests, masterId, gdprConsent) { let emiter; const payload = { id: masterId, + aosspsizes: [] }; if (gdprConsent) { payload.gdpr_consent = gdprConsent.consentString || undefined; @@ -32,13 +30,20 @@ function buildRequest(masterBidRequests, masterId, gdprConsent) { if (!emiter) { emiter = bid.params.emiter; } + + const slaveSizes = utils.parseSizesInput(bid.mediaTypes.banner.sizes).join('_'); + const rawSlaveId = bid.params.slaveId.replace('adocean', ''); + payload.aosspsizes.push(rawSlaveId + '~' + slaveSizes); + bidIdMap[slaveId] = bid.bidId; }); + payload.aosspsizes = payload.aosspsizes.join('-'); + return { method: 'GET', url: buildEndpointUrl(emiter, payload), - data: {}, + data: '', bidIdMap: bidIdMap }; } @@ -86,7 +91,12 @@ export const spec = { code: BIDDER_CODE, isBidRequestValid: function(bid) { - return !!(bid.params.slaveId && bid.params.masterId && bid.params.emiter); + const requiredParams = ['slaveId', 'masterId', 'emiter']; + if (requiredParams.some(name => !utils.isStr(bid.params[name]) || !bid.params[name].length)) { + return false; + } + + return !!bid.mediaTypes.banner; }, buildRequests: function(validBidRequests, bidderRequest) { diff --git a/test/spec/modules/adoceanBidAdapter_spec.js b/test/spec/modules/adoceanBidAdapter_spec.js index 1c3383be5aa..2b4b7d711e1 100644 --- a/test/spec/modules/adoceanBidAdapter_spec.js +++ b/test/spec/modules/adoceanBidAdapter_spec.js @@ -1,6 +1,7 @@ import { expect } from 'chai'; import { spec } from 'modules/adoceanBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; +import { deepClone } from 'src/utils.js'; describe('AdoceanAdapter', function () { const adapter = newBidder(spec); @@ -20,7 +21,11 @@ describe('AdoceanAdapter', function () { 'emiter': 'myao.adocean.pl' }, 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250]] + } + }, 'bidId': '30b31c1838de1e', 'bidderRequestId': '22edbae2733bf6', 'auctionId': '1d1a030790a475', @@ -51,7 +56,11 @@ describe('AdoceanAdapter', function () { 'emiter': 'myao.adocean.pl' }, 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250], [300, 600]] + } + }, 'bidId': '30b31c1838de1e', 'bidderRequestId': '22edbae2733bf6', 'auctionId': '1d1a030790a475', @@ -64,7 +73,11 @@ describe('AdoceanAdapter', function () { 'emiter': 'myao.adocean.pl' }, 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 200], [600, 250]] + } + }, 'bidId': '30b31c1838de1f', 'bidderRequestId': '22edbae2733bf6', 'auctionId': '1d1a030790a475', @@ -78,12 +91,12 @@ describe('AdoceanAdapter', function () { } }; - it('should send two requests if slave is duplicated', () => { + it('should send two requests if slave is duplicated', function () { const nrOfRequests = spec.buildRequests(bidRequests, bidderRequest).length; expect(nrOfRequests).to.equal(2); }); - it('should add bidIdMap with correct slaveId => bidId mapping', () => { + it('should add bidIdMap with correct slaveId => bidId mapping', function () { const requests = spec.buildRequests(bidRequests, bidderRequest); for (let i = 0; i < bidRequests.length; i++) { expect(requests[i]).to.exist; @@ -108,6 +121,19 @@ describe('AdoceanAdapter', function () { expect(request.url).to.include('gdpr=1'); expect(request.url).to.include('gdpr_consent=' + bidderRequest.gdprConsent.consentString); }); + + it('should attach sizes information to url', function () { + let requests = spec.buildRequests(bidRequests, bidderRequest); + expect(requests[0].url).to.include('aosspsizes=myaozpniqismex~300x250_300x600'); + expect(requests[1].url).to.include('aosspsizes=myaozpniqismex~300x200_600x250'); + + const differentSlavesBids = deepClone(bidRequests); + differentSlavesBids[1].params.slaveId = 'adoceanmyaowafpdwlrks'; + requests = spec.buildRequests(differentSlavesBids, bidderRequest); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.include('aosspsizes=myaozpniqismex~300x250_300x600-myaowafpdwlrks~300x200_600x250'); + expect((requests[0].url.match(/aosspsizes=/g) || []).length).to.equal(1); + }); }) describe('interpretResponse', function () { From dcf88bdb49fa66c804dd2aa3f300bcbeaf502424 Mon Sep 17 00:00:00 2001 From: Udi Talias Date: Wed, 10 Jun 2020 10:13:27 +0300 Subject: [PATCH 398/496] Vidazoo: Feature support usp consent (#5111) * feat(module): multi size request * fix getUserSyncs added tests * update(module): package-lock.json from master * feat(module): add usp consent support * added uspConsent test Co-authored-by: roman --- modules/vidazooBidAdapter.js | 3 +++ test/spec/modules/vidazooBidAdapter_spec.js | 2 ++ 2 files changed, 5 insertions(+) diff --git a/modules/vidazooBidAdapter.js b/modules/vidazooBidAdapter.js index d974c0e1eb7..0880b115c70 100644 --- a/modules/vidazooBidAdapter.js +++ b/modules/vidazooBidAdapter.js @@ -39,6 +39,9 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest) { data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; } } + if (bidderRequest.uspConsent) { + data.usPrivacy = bidderRequest.uspConsent + } const dto = { method: 'POST', url: `${URL}/prebid/multi/${cId}`, diff --git a/test/spec/modules/vidazooBidAdapter_spec.js b/test/spec/modules/vidazooBidAdapter_spec.js index a52669b773b..0c9867cbe9c 100644 --- a/test/spec/modules/vidazooBidAdapter_spec.js +++ b/test/spec/modules/vidazooBidAdapter_spec.js @@ -25,6 +25,7 @@ const BIDDER_REQUEST = { 'consentString': 'consent_string', 'gdprApplies': true }, + 'uspConsent': 'consent_string', 'refererInfo': { 'referer': 'https://www.greatsite.com' } @@ -131,6 +132,7 @@ describe('VidazooBidAdapter', function () { data: { gdprConsent: 'consent_string', gdpr: 1, + usPrivacy: 'consent_string', sizes: ['300x250', '300x600'], url: 'https%3A%2F%2Fwww.greatsite.com', cb: 1000, From 431eeddc915d3413bc15402e6e3dfbf8ccc01738 Mon Sep 17 00:00:00 2001 From: John Salis Date: Wed, 10 Jun 2020 03:18:36 -0400 Subject: [PATCH 399/496] add optional video param for tagid (#5344) Co-authored-by: John Salis --- modules/beachfrontBidAdapter.js | 4 +++- test/spec/modules/beachfrontBidAdapter_spec.js | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/beachfrontBidAdapter.js b/modules/beachfrontBidAdapter.js index 815b0471436..12e78c684ad 100644 --- a/modules/beachfrontBidAdapter.js +++ b/modules/beachfrontBidAdapter.js @@ -6,7 +6,7 @@ import { VIDEO, BANNER } from '../src/mediaTypes.js'; import find from 'core-js-pure/features/array/find.js'; import includes from 'core-js-pure/features/array/includes.js'; -const ADAPTER_VERSION = '1.10'; +const ADAPTER_VERSION = '1.11'; const ADAPTER_NAME = 'BFIO_PREBID'; const OUTSTREAM = 'outstream'; @@ -272,6 +272,7 @@ function createVideoRequestData(bid, bidderRequest) { let video = getVideoTargetingParams(bid); let appId = getVideoBidParam(bid, 'appId'); let bidfloor = getVideoBidParam(bid, 'bidfloor'); + let tagid = getVideoBidParam(bid, 'tagid'); let topLocation = getTopWindowLocation(bidderRequest); let payload = { isPrebid: true, @@ -285,6 +286,7 @@ function createVideoRequestData(bid, bidderRequest) { mimes: DEFAULT_MIMES }, video), bidfloor: bidfloor, + tagid: tagid, secure: topLocation.protocol.indexOf('https') === 0 ? 1 : 0, displaymanager: ADAPTER_NAME, displaymanagerver: ADAPTER_VERSION diff --git a/test/spec/modules/beachfrontBidAdapter_spec.js b/test/spec/modules/beachfrontBidAdapter_spec.js index f7dcc1305e5..5711e111e30 100644 --- a/test/spec/modules/beachfrontBidAdapter_spec.js +++ b/test/spec/modules/beachfrontBidAdapter_spec.js @@ -146,6 +146,7 @@ describe('BeachfrontAdapter', function () { const width = 640; const height = 480; const bidRequest = bidRequests[0]; + bidRequest.params.tagid = '7cd7a7b4-ef3f-4aeb-9565-3627f255fa10'; bidRequest.mediaTypes = { video: { playerSize: [ width, height ] @@ -165,6 +166,7 @@ describe('BeachfrontAdapter', function () { expect(data.id).to.be.a('string'); expect(data.imp[0].video).to.deep.contain({ w: width, h: height, mimes: DEFAULT_MIMES }); expect(data.imp[0].bidfloor).to.equal(bidRequest.params.bidfloor); + expect(data.imp[0].tagid).to.equal(bidRequest.params.tagid); expect(data.site).to.deep.equal({ page: topLocation.href, domain: topLocation.hostname }); expect(data.device).to.deep.contain({ ua: navigator.userAgent, language: navigator.language, js: 1 }); expect(data.cur).to.deep.equal(['USD']); From 3669f7d7b12ee44e77cf243a0225f65f1bb8e341 Mon Sep 17 00:00:00 2001 From: h12media <65672347+h12media@users.noreply.github.com> Date: Wed, 10 Jun 2020 14:28:36 +0300 Subject: [PATCH 400/496] Add module H12 Media (#5328) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add module H12 Media * Add module H12 Media * Add module H12 Media — fix gdpr info * Add module H12 Media — fix find --- modules/h12mediaBidAdapter.js | 209 ++++++++++ modules/h12mediaBidAdapter.md | 48 +++ test/spec/modules/h12mediaBidAdapter_spec.js | 388 +++++++++++++++++++ 3 files changed, 645 insertions(+) create mode 100644 modules/h12mediaBidAdapter.js create mode 100644 modules/h12mediaBidAdapter.md create mode 100644 test/spec/modules/h12mediaBidAdapter_spec.js diff --git a/modules/h12mediaBidAdapter.js b/modules/h12mediaBidAdapter.js new file mode 100644 index 00000000000..0d2c22a3f68 --- /dev/null +++ b/modules/h12mediaBidAdapter.js @@ -0,0 +1,209 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import find from 'core-js-pure/features/array/find.js'; +const BIDDER_CODE = 'h12media'; +const DEFAULT_URL = 'https://bidder.h12-media.com/prebid/'; +const DEFAULT_CURRENCY = 'USD'; +const DEFAULT_TTL = 360; +const DEFAULT_NET_REVENUE = false; + +export const spec = { + code: BIDDER_CODE, + aliases: ['h12'], + + isBidRequestValid: function(bid) { + return !!(bid.params && bid.params.pubid); + }, + + buildRequests: function(validBidRequests, bidderRequest) { + const requestUrl = validBidRequests[0].params.endpointdom || DEFAULT_URL; + const isiframe = !((window.self === window.top) || window.frameElement); + const screenSize = getClientDimensions(); + const docSize = getDocumentDimensions(); + + const bidrequests = validBidRequests.map((bidRequest) => { + const bidderParams = bidRequest.params; + const adUnitElement = document.getElementById(bidRequest.adUnitCode); + const ishidden = !isVisible(adUnitElement); + const coords = { + x: adUnitElement && adUnitElement.getBoundingClientRect().x, + y: adUnitElement && adUnitElement.getBoundingClientRect().y, + }; + + return { + bidId: bidRequest.bidId, + transactionId: bidRequest.transactionId, + adunitId: bidRequest.adUnitCode, + pubid: bidderParams.pubid, + placementid: bidderParams.placementid || '', + size: bidderParams.size || '', + adunitSize: bidRequest.mediaTypes.banner.sizes || [], + coords, + ishidden, + }; + }); + + return { + method: 'POST', + url: requestUrl, + options: {withCredentials: false}, + data: { + gdpr: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? Boolean(bidderRequest.gdprConsent.gdprApplies & 1) : false, + gdpr_cs: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? bidderRequest.gdprConsent.consentString : '', + topLevelUrl: window.top.location.href, + refererUrl: bidderRequest.refererInfo ? bidderRequest.refererInfo.referer : '', + isiframe, + version: '$prebid.version$', + visitorInfo: { + localTime: getLocalDateFormatted(), + dayOfWeek: new Date().getDay(), + screenWidth: screenSize[0], + screenHeight: screenSize[1], + docWidth: docSize[0], + docHeight: docSize[1], + scrollbarx: window.scrollX, + scrollbary: window.scrollY, + }, + bidrequests, + }, + }; + }, + + interpretResponse: function(serverResponse, bidRequests) { + let bidResponses = []; + try { + const serverBody = serverResponse.body; + if (serverBody) { + if (serverBody.bids) { + serverBody.bids.forEach(bidBody => { + const bidRequest = find(bidRequests.data.bidrequests, bid => bid.bidId === bidBody.bidId); + const bidResponse = { + currency: serverBody.currency || DEFAULT_CURRENCY, + netRevenue: serverBody.netRevenue || DEFAULT_NET_REVENUE, + ttl: serverBody.ttl || DEFAULT_TTL, + requestId: bidBody.bidId, + cpm: bidBody.cpm, + width: bidBody.width, + height: bidBody.height, + creativeId: bidBody.creativeId, + ad: bidBody.ad, + meta: bidBody.meta, + mediaType: 'banner', + }; + if (bidRequest) { + bidResponse.pubid = bidRequest.pubid; + bidResponse.placementid = bidRequest.placementid; + bidResponse.size = bidRequest.size; + } + bidResponses.push(bidResponse); + }); + } + } + return bidResponses; + } catch (err) { + utils.logError(err); + } + }, + + getUserSyncs: function(syncOptions, serverResponses, gdprConsent) { + const serverBody = serverResponses[0].body; + const syncs = []; + gdprConsent = gdprConsent || { + gdprApplies: false, consentString: '', + }; + + if (serverBody) { + if (serverBody.bids) { + serverBody.bids.forEach(bidBody => { + const userSyncUrls = bidBody.usersync || []; + const userSyncUrlProcess = url => { + return url + .replace('{gdpr}', gdprConsent.gdprApplies) + .replace('{gdpr_cs}', gdprConsent.consentString); + } + + userSyncUrls.forEach(sync => { + if (syncOptions.iframeEnabled && sync.type === 'iframe' && sync.url) { + syncs.push({ + type: 'iframe', + url: userSyncUrlProcess(sync.url), + }); + } + if (syncOptions.pixelEnabled && sync.type === 'image' && sync.url) { + syncs.push({ + type: 'image', + url: userSyncUrlProcess(sync.url), + }); + } + }); + }); + } + } + + return syncs; + }, +} + +function getContext(elem) { + return elem && window.document.body.contains(elem) ? window : (window.top.document.body.contains(elem) ? top : undefined); +} + +function isDefined(val) { + return (val !== null) && (typeof val !== 'undefined'); +} + +function getIsHidden(elem) { + let lastElem = elem; + let elemHidden = false; + let m; + m = 0; + + do { + m = m + 1; + try { + if ( + getContext(elem).getComputedStyle(lastElem).getPropertyValue('display') === 'none' || + getContext(elem).getComputedStyle(lastElem).getPropertyValue('visibility') === 'hidden' + ) { + return true; + } else { + elemHidden = false; + lastElem = lastElem.parentElement; + } + } catch (o) { + return false; + } + } while ((m < 250) && (lastElem != null) && (elemHidden === false)) + return elemHidden; +} + +function isVisible(element) { + return element && isDefined(getContext(element)) && !getIsHidden(element); +} + +function getClientDimensions() { + try { + const t = window.top.innerWidth || window.top.document.documentElement.clientWidth || window.top.document.body.clientWidth; + const e = window.top.innerHeight || window.top.document.documentElement.clientHeight || window.top.document.body.clientHeight; + return [Math.round(t), Math.round(e)]; + } catch (i) { + return [0, 0]; + } +} + +function getDocumentDimensions() { + try { + const D = window.top.document; + return [D.body.offsetWidth, Math.max(D.body.scrollHeight, D.documentElement.scrollHeight, D.body.offsetHeight, D.documentElement.offsetHeight, D.body.clientHeight, D.documentElement.clientHeight)] + } catch (t) { + return [-1, -1] + } +} + +function getLocalDateFormatted() { + const two = num => ('0' + num).slice(-2); + const d = new Date(); + return `${d.getFullYear()}-${two(d.getMonth() + 1)}-${two(d.getDate())} ${two(d.getHours())}:${two(d.getMinutes())}:${two(d.getSeconds())}`; +} + +registerBidder(spec); diff --git a/modules/h12mediaBidAdapter.md b/modules/h12mediaBidAdapter.md new file mode 100644 index 00000000000..7430bf11b90 --- /dev/null +++ b/modules/h12mediaBidAdapter.md @@ -0,0 +1,48 @@ +# Overview + +Module Name: H12 Media Bidder Adapter +Module Type: Bidder Adapter +Maintainer: contact@h12-media.com + +# Description + +Module that connects to H12 Media demand source to fetch bids. + +# Test Parameters +``` + var adUnits = [ + { + code: 'div-1', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bids: [ + { + bidder: "h12media", + params: { + pubid: '123', + sizes: '300x250', + } + } + ] + },{ + code: 'div-2', + mediaTypes: { + banner: { + sizes: [[728, 90]] + } + }, + bids: [ + { + bidder: "h12media", + params: { + pubid: '123', + placementid: '321' + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/h12mediaBidAdapter_spec.js b/test/spec/modules/h12mediaBidAdapter_spec.js new file mode 100644 index 00000000000..08a83ce981f --- /dev/null +++ b/test/spec/modules/h12mediaBidAdapter_spec.js @@ -0,0 +1,388 @@ +import {expect} from 'chai'; +import {spec} from 'modules/h12mediaBidAdapter'; +import {newBidder} from 'src/adapters/bidderFactory'; + +describe('H12 Media Adapter', function () { + const DEFAULT_CURRENCY = 'USD'; + const DEFAULT_TTL = 360; + const DEFAULT_NET_REVENUE = false; + const adapter = newBidder('spec'); + + const validBid = { + adUnitCode: 'div-gpt-ad-1460505748561-0', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + } + }, + bidder: 'h12media', + bidId: '1c5e8a1a84522d', + bidderRequestId: '1d0c4017f02458', + auctionId: '9adc85ed-43ee-4a78-816b-52b7e578f313', + params: { + pubid: 123321, + }, + }; + + const validBid2 = { + adUnitCode: 'div-gpt-ad-1460505748561-1', + mediaTypes: { + banner: {} + }, + bidder: 'h12media', + bidId: '2c5e8a1a84522d', + bidderRequestId: '2d0c4017f02458', + auctionId: '9adc85ed-43ee-4a78-816b-52b7e578f314', + params: { + pubid: 123321, + size: '100x200' + }, + }; + + const invalidBid = { + adUnitCode: 'div-gpt-ad-1460505748561-2', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + } + }, + bidder: 'h12media', + bidId: '3c5e8a1a84522d', + bidderRequestId: '3d0c4017f02458', + auctionId: '9adc85ed-43ee-4a78-816b-52b7e578f315', + }; + + const bidderRequest = { + refererInfo: { + referer: 'https://localhost' + }, + gdprConsent: { + gdprApplies: 1, + consentString: 'concentDataString', + vendorData: { + vendorConsents: { + '90': 1 + }, + }, + }, + uspConsent: 'consentUspString' + }; + + const serverResponse = { + currency: 'EUR', + netRevenue: true, + ttl: 500, + bids: [{ + bidId: validBid.bidId, + cpm: 0.33, + width: 300, + height: 600, + creativeId: '335566', + ad: '
my ad
', + usersync: [ + {url: 'https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies={gdpr}&gdpr_consent_string={gdpr_cs}', type: 'image'}, + {url: 'https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies={gdpr}&gdpr_consent_string={gdpr_cs}', type: 'iframe'} + ], + meta: { + advertiserId: '54321', + advertiserName: 'My advertiser', + advertiserDomains: ['test.com'] + } + }] + }; + + const serverResponse2 = { + bids: [{ + bidId: validBid2.bidId, + cpm: 0.33, + width: 300, + height: 600, + creativeId: '335566', + ad: '
my ad 2
', + }] + }; + + function removeElement(id) { + if (document.getElementById(id)) { + document.body.removeChild(document.getElementById(id)); + } + } + + function createElement(id) { + const div = document.createElement('div'); + div.id = id; + div.style.width = '50px'; + div.style.height = '50px'; + if (frameElement) { + frameElement.style.width = '100px'; + frameElement.style.height = '100px'; + } + div.style.background = 'black'; + document.body.appendChild(div); + return div; + } + function createElementVisible(id) { + const element = createElement(id); + sandbox.stub(element, 'getBoundingClientRect').returns({ + x: 10, + y: 10, + }); + return element; + } + function createElementInvisible(id) { + const element = document.createElement('div'); + element.id = id; + document.body.appendChild(element); + element.style.display = 'none'; + return element; + } + + function createElementHidden(id) { + const element = createElement(id); + document.body.appendChild(element); + element.style.visibility = 'hidden'; + sandbox.stub(element, 'getBoundingClientRect').returns({ + x: 100, + y: 100, + }); + return element; + } + + let sandbox; + + beforeEach(function () { + sandbox = sinon.sandbox.create(); + }); + + afterEach(function () { + removeElement(validBid.adUnitCode); + removeElement(validBid2.adUnitCode); + removeElement(invalidBid.adUnitCode); + sandbox.restore(); + }); + + after(function() { + sandbox.reset(); + }) + + describe('inherited functions', function () { + it('exists and is a function', function () { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', function () { + it('should return true when bid is valid', function () { + expect(spec.isBidRequestValid(validBid)).to.equal(true); + }); + + it('should return false when bid does not have pubid parameter', function () { + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + it('should return adUnit size', function () { + createElementVisible(validBid.adUnitCode); + createElementVisible(validBid2.adUnitCode); + const requests = spec.buildRequests([validBid, validBid2], bidderRequest); + const requestsData = requests.data; + + expect(requestsData.bidrequests[0]).to.include({adunitSize: validBid.mediaTypes.banner.sizes}); + }); + + it('should return empty bid size', function () { + createElementVisible(validBid.adUnitCode); + createElementVisible(validBid2.adUnitCode); + const requests = spec.buildRequests([validBid, validBid2], bidderRequest); + const requestsData = requests.data; + + expect(requestsData.bidrequests[1]).to.deep.include({adunitSize: []}); + }); + + it('should return bid size from params', function () { + createElementVisible(validBid.adUnitCode); + createElementVisible(validBid2.adUnitCode); + const requests = spec.buildRequests([validBid, validBid2], bidderRequest); + const requestsData = requests.data; + + expect(requestsData.bidrequests[1]).to.include({size: validBid2.params.size}); + }); + + it('should return GDPR info', function () { + createElementVisible(validBid.adUnitCode); + createElementVisible(validBid2.adUnitCode); + const requests = spec.buildRequests([validBid, validBid2], bidderRequest); + const requestsData = requests.data; + + expect(requestsData).to.include({gdpr: true, gdpr_cs: bidderRequest.gdprConsent.consentString}); + }); + + it('should not have error on empty GDPR', function () { + createElementVisible(validBid.adUnitCode); + createElementVisible(validBid2.adUnitCode); + const bidderRequestWithoutGDRP = {...bidderRequest, gdprConsent: null}; + const requests = spec.buildRequests([validBid, validBid2], bidderRequestWithoutGDRP); + const requestsData = requests.data; + + expect(requestsData).to.include({gdpr: false}); + }); + + it('should create single POST', function () { + createElementVisible(validBid.adUnitCode); + createElementVisible(validBid2.adUnitCode); + const requests = spec.buildRequests([validBid, validBid2], bidderRequest); + + expect(requests.method).to.equal('POST'); + }); + }); + + describe('creative viewability', function () { + it('should return coords', function () { + createElementVisible(validBid.adUnitCode); + const requests = spec.buildRequests([validBid], bidderRequest); + const requestsData = requests.data; + + expect(requestsData.bidrequests[0]).to.deep.include({coords: {x: 10, y: 10}}); + }); + + it('should define not iframe', function () { + createElementVisible(validBid.adUnitCode); + createElementVisible(validBid2.adUnitCode); + const requests = spec.buildRequests([validBid, validBid2], bidderRequest); + const requestsData = requests.data; + + expect(requestsData).to.include({isiframe: false}); + }); + + it('should define visible element', function () { + createElementVisible(validBid.adUnitCode); + const requests = spec.buildRequests([validBid], bidderRequest); + const requestsData = requests.data; + + expect(requestsData.bidrequests[0]).to.include({ishidden: false}); + }); + + it('should define invisible element', function () { + createElementInvisible(validBid.adUnitCode); + const requests = spec.buildRequests([validBid], bidderRequest); + const requestsData = requests.data; + + expect(requestsData.bidrequests[0]).to.include({ishidden: true}); + }); + + it('should define hidden element', function () { + createElementHidden(validBid.adUnitCode); + const requests = spec.buildRequests([validBid], bidderRequest); + const requestsData = requests.data; + + expect(requestsData.bidrequests[0]).to.include({ishidden: true}); + }); + }); + + describe('interpretResponse', function () { + it('should return no bids if the response is not valid', function () { + const bidResponse = spec.interpretResponse({ body: null }, validBid); + + expect(bidResponse.length).to.equal(0); + }); + + it('should return no bids if the response is empty', function () { + const bidResponse = spec.interpretResponse({ body: [] }, { validBid }); + + expect(bidResponse.length).to.equal(0); + }); + + it('should return valid bid responses', function () { + createElementVisible(validBid.adUnitCode); + createElementVisible(validBid2.adUnitCode); + const request = spec.buildRequests([validBid, validBid2], bidderRequest); + const bidResponse = spec.interpretResponse({body: serverResponse}, request); + + expect(bidResponse[0]).to.deep.include({ + requestId: validBid.bidId, + ad: serverResponse.bids[0].ad, + mediaType: 'banner', + creativeId: serverResponse.bids[0].creativeId, + cpm: serverResponse.bids[0].cpm, + width: serverResponse.bids[0].width, + height: serverResponse.bids[0].height, + currency: 'EUR', + netRevenue: true, + ttl: 500, + meta: serverResponse.bids[0].meta, + pubid: validBid.params.pubid + }); + }); + + it('should return default bid params', function () { + createElementVisible(validBid.adUnitCode); + createElementVisible(validBid2.adUnitCode); + const request = spec.buildRequests([validBid, validBid2], bidderRequest); + const bidResponse = spec.interpretResponse({body: serverResponse2}, request); + + expect(bidResponse[0]).to.deep.include({ + requestId: validBid2.bidId, + ad: serverResponse2.bids[0].ad, + mediaType: 'banner', + creativeId: serverResponse2.bids[0].creativeId, + cpm: serverResponse2.bids[0].cpm, + width: serverResponse2.bids[0].width, + height: serverResponse2.bids[0].height, + meta: serverResponse2.bids[0].meta, + pubid: validBid2.params.pubid, + currency: DEFAULT_CURRENCY, + netRevenue: DEFAULT_NET_REVENUE, + ttl: DEFAULT_TTL, + }); + }); + }); + + describe('getUserSyncs', function () { + let syncOptions + beforeEach(function () { + syncOptions = { + enabledBidders: ['h12media'], + pixelEnabled: true, + iframeEnabled: true + } + }); + + it('should success with usersync pixel url', function () { + const result = { + type: 'image', + url: `https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies=${bidderRequest.gdprConsent.gdprApplies}&gdpr_consent_string=${bidderRequest.gdprConsent.consentString}`, + }; + const syncs = spec.getUserSyncs(syncOptions, [{body: serverResponse}], bidderRequest.gdprConsent); + + expect(syncs).to.deep.include(result); + }); + + it('should success with usersync iframe url', function () { + const result = { + type: 'iframe', + url: `https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies=${bidderRequest.gdprConsent.gdprApplies}&gdpr_consent_string=${bidderRequest.gdprConsent.consentString}`, + }; + const syncs = spec.getUserSyncs(syncOptions, [{body: serverResponse}], bidderRequest.gdprConsent); + + expect(syncs).to.deep.include(result); + }); + + it('should success without GDRP', function () { + const result = { + type: 'iframe', + url: `https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies=false&gdpr_consent_string=`, + }; + + expect(spec.getUserSyncs(syncOptions, [{body: serverResponse}], null)).to.deep.include(result); + }); + + it('should success without usersync url', function () { + expect(spec.getUserSyncs(syncOptions, [{body: serverResponse2}], bidderRequest.gdprConsent)).to.deep.equal([]); + }); + + it('should return empty usersync on empty response', function () { + expect(spec.getUserSyncs(syncOptions, [{body: {}}])).to.deep.equal([]); + }); + }); +}); From e5d7ecfc5b99a6518ba15b5d118c827c96d418a6 Mon Sep 17 00:00:00 2001 From: redaguermas Date: Wed, 10 Jun 2020 11:45:04 -0700 Subject: [PATCH 401/496] No bid version 1.2.6 (#5323) * Enable supplyChain support * Added support for COPPA * - Added support for Safeframe creative. - Added support for out-stream video. * Changed the protocol from JSON to string because Exceptions cause a slowdown on the browser. * Change in package.json * Fix error * Changed startsWidth() to indexOf() * Fix lint error. Not sure why my gulp lint does not detect this error. * Fix indexOf not available on IE 11 Co-authored-by: Reda Guermas --- modules/nobidBidAdapter.js | 33 ++++++++- package.json | 14 ++-- test/spec/modules/nobidBidAdapter_spec.js | 89 +++++++++++++++++++++++ 3 files changed, 127 insertions(+), 9 deletions(-) diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index dacb76a9a98..f1a9092e31d 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -6,7 +6,7 @@ import { getStorageManager } from '../src/storageManager.js'; const storage = getStorageManager(); const BIDDER_CODE = 'nobid'; -window.nobidVersion = '1.2.5'; +window.nobidVersion = '1.2.6'; window.nobid = window.nobid || {}; window.nobid.bidResponses = window.nobid.bidResponses || {}; window.nobid.timeoutTotal = 0; @@ -200,7 +200,7 @@ function nobidBuildRequests(bids, bidderRequest) { var adType = 'banner'; const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video'); const context = utils.deepAccess(bid, 'mediaTypes.video.context'); - if (bid.mediaType === VIDEO || (videoMediaType && context === 'instream')) { + if (bid.mediaType === VIDEO || (videoMediaType && (context === 'instream' || context === 'outstream'))) { adType = 'video'; } @@ -287,6 +287,35 @@ window.nobid.renderTag = function(doc, id, win) { } log('nobid.renderTag() tag NOT FOUND *ERROR*', id); } +window.addEventListener('message', function (event) { + let key = event.message ? 'message' : 'data'; + var msg = '' + event[key]; + if (msg.substring(0, 'nbTagRenderer.requestAdMarkup|'.length) === 'nbTagRenderer.requestAdMarkup|') { + log('Prebid received nbTagRenderer.requestAdMarkup event'); + var adId = msg.substring(msg.indexOf('|') + 1); + if (window.nobid && window.nobid.bidResponses) { + var bid = window.nobid.bidResponses['' + adId]; + if (bid && bid.adm2) { + var markup = null; + if (bid.is_combo && bid.adm_combo) { + for (var i in bid.adm_combo) { + var combo = bid.adm_combo[i]; + if (!combo.done) { + markup = combo.adm; + combo.done = true; + break; + } + } + } else { + markup = bid.adm2; + } + if (markup) { + event.source.postMessage('nbTagRenderer.renderAdInSafeFrame|' + markup, '*'); + } + } + } + } +}, false); export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO], diff --git a/package.json b/package.json index 10f9354b0e1..84cc5931495 100644 --- a/package.json +++ b/package.json @@ -38,11 +38,11 @@ "babel-loader": "^8.0.5", "body-parser": "^1.19.0", "chai": "^4.2.0", - "coveralls": "^3.0.2", + "coveralls": "^3.1.0", "documentation": "^5.2.2", - "es5-shim": "^4.5.2", + "es5-shim": "^4.5.14", "eslint-config-standard": "^10.2.1", - "eslint-plugin-import": "^2.20.1", + "eslint-plugin-import": "^2.20.2", "eslint-plugin-node": "^5.1.0", "eslint-plugin-prebid": "file:./plugins/eslint", "eslint-plugin-promise": "^3.5.0", @@ -95,23 +95,23 @@ "url-parse": "^1.0.5", "webdriverio": "^6.1.5", "webpack": "^3.0.0", - "webpack-bundle-analyzer": "^3.3.2", + "webpack-bundle-analyzer": "^3.8.0", "webpack-stream": "^3.2.0", "yargs": "^1.3.1" }, "dependencies": { "babel-plugin-transform-object-assign": "^6.22.0", "core-js": "^3.0.0", + "core-js-pure": "^3.6.5", "criteo-direct-rsa-validate": "^1.1.0", "crypto-js": "^3.3.0", "deep-equal": "^1.0.1", "dlv": "1.1.3", "dset": "2.0.1", "express": "^4.15.4", - "fun-hooks": "^0.9.8", + "fun-hooks": "^0.9.9", "jsencrypt": "^3.0.0-rc.1", "just-clone": "^1.0.2", - "live-connect-js": "1.1.1", - "core-js-pure": "^3.6.5" + "live-connect-js": "1.1.1" } } diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js index afbc46f862f..3b8fd32160b 100644 --- a/test/spec/modules/nobidBidAdapter_spec.js +++ b/test/spec/modules/nobidBidAdapter_spec.js @@ -139,6 +139,95 @@ describe('Nobid Adapter', function () { }); }); + describe('isVideoBidRequestValid', function () { + let bid = { + bidder: 'nobid', + params: { + siteId: 2, + video: { + skippable: true, + playback_methods: ['auto_play_sound_off'], + position: 'atf', + mimes: ['video/x-flv', 'video/mp4', 'video/x-ms-wmv', 'application/x-shockwave-flash', 'application/javascript'], + minduration: 1, + maxduration: 30, + frameworks: [1, 2, 3, 4, 5, 6] + } + }, + adUnitCode: 'adunit-code', + sizes: [[640, 480]], + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + mediaTypes: { + video: { + context: 'outstream' + } + } + }; + const SITE_ID = 2; + const REFERER = 'https://www.examplereferer.com'; + let bidRequests = [ + { + bidder: 'nobid', + params: { + siteId: SITE_ID, + video: { + skippable: true, + playback_methods: ['auto_play_sound_off'], + position: 'atf', + mimes: ['video/x-flv', 'video/mp4', 'video/x-ms-wmv', 'application/x-shockwave-flash', 'application/javascript'], + minduration: 1, + maxduration: 30, + frameworks: [1, 2, 3, 4, 5, 6] + } + }, + adUnitCode: 'adunit-code', + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'outstream' + } + } + } + ]; + + let bidderRequest = { + refererInfo: {referer: REFERER} + } + + it('should add source and version to the tag', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.sid).to.equal(SITE_ID); + expect(payload.l).to.exist.and.to.equal(encodeURIComponent(REFERER)); + expect(payload.a).to.exist; + expect(payload.t).to.exist; + expect(payload.tz).to.exist; + expect(payload.r).to.exist; + expect(payload.lang).to.exist; + expect(payload.ref).to.exist; + expect(payload.a[0].d).to.exist.and.to.equal('adunit-code'); + expect(payload.a[0].at).to.exist.and.to.equal('video'); + expect(payload.a[0].params.video).to.exist; + expect(payload.a[0].params.video.skippable).to.exist.and.to.equal(true); + expect(payload.a[0].params.video.playback_methods).to.exist.and.to.contain('auto_play_sound_off'); + expect(payload.a[0].params.video.position).to.exist.and.to.equal('atf'); + expect(payload.a[0].params.video.mimes).to.exist.and.to.contain('video/x-flv'); + expect(payload.a[0].params.video.minduration).to.exist.and.to.equal(1); + expect(payload.a[0].params.video.maxduration).to.exist.and.to.equal(30); + expect(payload.a[0].params.video.frameworks[0]).to.exist.and.to.equal(1); + expect(payload.a[0].params.video.frameworks[1]).to.exist.and.to.equal(2); + expect(payload.a[0].params.video.frameworks[2]).to.exist.and.to.equal(3); + expect(payload.a[0].params.video.frameworks[3]).to.exist.and.to.equal(4); + expect(payload.a[0].params.video.frameworks[4]).to.exist.and.to.equal(5); + expect(payload.a[0].params.video.frameworks[5]).to.exist.and.to.equal(6); + }); + }); + describe('buildRequests', function () { const SITE_ID = 2; const REFERER = 'https://www.examplereferer.com'; From 3e443e8d39255628314fc69e83ba06f9831534f7 Mon Sep 17 00:00:00 2001 From: Olivier Date: Thu, 11 Jun 2020 13:37:53 +0200 Subject: [PATCH 402/496] AdagioBidAdapter 2.2.2 (#5347) * Adagio: params auto-detection Improve user integration with auto-detection for adUnitElementId and environment params. * Adagio: update config example in .md file --- modules/adagioBidAdapter.js | 79 +++++++++++++++++----- modules/adagioBidAdapter.md | 24 ++++--- test/spec/modules/adagioBidAdapter_spec.js | 35 +++++++--- 3 files changed, 99 insertions(+), 39 deletions(-) diff --git a/modules/adagioBidAdapter.js b/modules/adagioBidAdapter.js index f144089b2a2..b2ef5dafb41 100644 --- a/modules/adagioBidAdapter.js +++ b/modules/adagioBidAdapter.js @@ -7,7 +7,7 @@ import sha256 from 'crypto-js/sha256.js'; import { getStorageManager } from '../src/storageManager.js'; const BIDDER_CODE = 'adagio'; -const VERSION = '2.2.1'; +const VERSION = '2.2.2'; const FEATURES_VERSION = '1'; const ENDPOINT = 'https://mp.4dex.io/prebid'; const SUPPORTED_MEDIA_TYPES = ['banner']; @@ -89,7 +89,7 @@ if (canAccessTopWindow()) { initAdagio(); } -const _features = { +export const _features = { getPrintNumber: function (adUnitCode) { const adagioAdUnit = _getOrAddAdagioAdUnit(adUnitCode); return adagioAdUnit.printNumber || 1; @@ -274,6 +274,34 @@ function _getElementFromTopWindow(element, currentWindow) { } } +export function _autoDetectAdUnitElementId(adUnitCode) { + const autoDetectedAdUnit = utils.getGptSlotInfoForAdUnitCode(adUnitCode) + let adUnitElementId = null; + + if (autoDetectedAdUnit && autoDetectedAdUnit.divId) { + adUnitElementId = autoDetectedAdUnit.divId; + } + + return adUnitElementId; +} + +function _autoDetectEnvironment() { + const device = _features.getDevice(); + let environment; + switch (device) { + case 2: + environment = 'desktop' + break; + case 4: + environment = 'mobile' + break; + case 5: + environment = 'tablet' + break; + }; + return environment +} + /** * Returns all features for a specific adUnit element * @@ -283,22 +311,26 @@ function _getElementFromTopWindow(element, currentWindow) { function _getFeatures(bidRequest) { if (!canAccessTopWindow()) return; const w = utils.getWindowTop(); - const adUnitElementId = bidRequest.params.adUnitElementId; const adUnitCode = bidRequest.adUnitCode; + const adUnitElementId = bidRequest.params.adUnitElementId || _autoDetectAdUnitElementId(adUnitCode); + let element; - let element = window.document.getElementById(adUnitElementId); - - if (bidRequest.params.postBid === true) { - element = _getElementFromTopWindow(element, window); - w.ADAGIO.pbjsAdUnits.map((adUnit) => { - if (adUnit.code === adUnitCode) { - const outerElementId = element.getAttribute('id'); - adUnit.outerAdUnitElementId = outerElementId; - bidRequest.params.outerAdUnitElementId = outerElementId; - } - }); + if (!adUnitElementId) { + utils.logWarn('Unable to detect adUnitElementId. Adagio measures won\'t start'); } else { - element = w.document.getElementById(adUnitElementId); + if (bidRequest.params.postBid === true) { + window.document.getElementById(adUnitElementId); + element = _getElementFromTopWindow(element, window); + w.ADAGIO.pbjsAdUnits.map((adUnit) => { + if (adUnit.code === adUnitCode) { + const outerElementId = element.getAttribute('id'); + adUnit.outerAdUnitElementId = outerElementId; + bidRequest.params.outerAdUnitElementId = outerElementId; + } + }); + } else { + element = w.document.getElementById(adUnitElementId); + } } const features = { @@ -316,6 +348,7 @@ function _getFeatures(bidRequest) { }; const adUnitFeature = {}; + adUnitFeature[adUnitElementId] = { features: features, version: FEATURES_VERSION @@ -362,17 +395,29 @@ export const spec = { isBidRequestValid: function (bid) { const { adUnitCode, auctionId, sizes, bidder, params, mediaTypes } = bid; - const { organizationId, site, placement, adUnitElementId } = bid.params; + const { organizationId, site, placement } = bid.params; + const adUnitElementId = bid.params.adUnitElementId || _autoDetectAdUnitElementId(adUnitCode); + const environment = bid.params.environment || _autoDetectEnvironment(); let isValid = false; + utils.logInfo('adUnitElementId', adUnitElementId) + try { if (canAccessTopWindow()) { const w = utils.getWindowTop(); w.ADAGIO = w.ADAGIO || {}; w.ADAGIO.adUnits = w.ADAGIO.adUnits || {}; w.ADAGIO.pbjsAdUnits = w.ADAGIO.pbjsAdUnits || []; - isValid = !!(organizationId && site && placement && adUnitElementId); + isValid = !!(organizationId && site && placement); + const tempAdUnits = w.ADAGIO.pbjsAdUnits.filter((adUnit) => adUnit.code !== adUnitCode); + + bid.params = { + ...bid.params, + adUnitElementId, + environment + } + tempAdUnits.push({ code: adUnitCode, sizes: (mediaTypes && mediaTypes.banner && Array.isArray(mediaTypes.banner.sizes)) ? mediaTypes.banner.sizes : sizes, diff --git a/modules/adagioBidAdapter.md b/modules/adagioBidAdapter.md index 5dc8aa3d80c..b34cc3fe37a 100644 --- a/modules/adagioBidAdapter.md +++ b/modules/adagioBidAdapter.md @@ -12,15 +12,19 @@ Connects to Adagio demand source to fetch bids. ```javascript var adUnits = [ - { - code: 'dfp_banniere_atf', - sizes: [[300, 250], [300, 600]], - bids: [ - { + { + code: 'dfp_banniere_atf', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + } + }, + bids: [{ bidder: 'adagio', // Required params: { organizationId: '0', // Required - Organization ID provided by Adagio. site: 'news-of-the-day', // Required - Site Name provided by Adagio. + placement: 'ban_atf', // Required. Refers to the placement of an adunit in a page. Must not contain any information about the type of device. Other example: `mpu_btf'. adUnitElementId: 'dfp_banniere_atf', // Required - AdUnit element id. Refers to the adunit id in a page. Usually equals to the adunit code above. // The following params are limited to 30 characters, @@ -29,16 +33,14 @@ Connects to Adagio demand source to fetch bids. // - dashes `-` // - underscores `_` // Also, each param can have at most 50 unique active values (case-insensitive). - environment: 'mobile', // Required. Environment where the page is displayed. - placement: 'ban_atf', // Required. Refers to the placement of an adunit in a page. Must not contain any information about the type of device. Other example: `mpu_btf'. - pagetype: 'article', // Required. The pagetype describes what kind of content will be present in the page. + pagetype: 'article', // Highly recommended. The pagetype describes what kind of content will be present in the page. + environment: 'mobile', // Recommended. Environment where the page is displayed. category: 'sport', // Recommended. Category of the content displayed in the page. subcategory: 'handball', // Optional. Subcategory of the content displayed in the page. postBid: false // Optional. Use it in case of Post-bid integration only. } - } - ] - } + }] + } ]; pbjs.addAdUnits(adUnits); diff --git a/test/spec/modules/adagioBidAdapter_spec.js b/test/spec/modules/adagioBidAdapter_spec.js index 8996b288576..97265121ce0 100644 --- a/test/spec/modules/adagioBidAdapter_spec.js +++ b/test/spec/modules/adagioBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { adagioScriptFromLocalStorageCb, spec } from 'modules/adagioBidAdapter.js'; +import { adagioScriptFromLocalStorageCb, _features, spec } from 'modules/adagioBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import * as utils from 'src/utils.js'; @@ -7,7 +7,7 @@ describe('adagioAdapter', () => { let utilsMock; const adapter = newBidder(spec); const ENDPOINT = 'https://mp.4dex.io/prebid'; - const VERSION = '2.2.1'; + const VERSION = '2.2.2'; beforeEach(function() { localStorage.removeItem('adagioScript'); @@ -51,7 +51,7 @@ describe('adagioAdapter', () => { sandbox.restore(); }); - let bid = { + const bid = { 'bidder': 'adagio', 'params': { organizationId: '0', @@ -67,7 +67,7 @@ describe('adagioAdapter', () => { 'auctionId': 'lel4fhp239i9km', }; - let bidWithMediaTypes = { + const bidWithMediaTypes = { 'bidder': 'adagio', 'params': { organizationId: '0', @@ -108,28 +108,41 @@ describe('adagioAdapter', () => { }); it('should return false when organization params is not passed', () => { - let bidTest = Object.assign({}, bid); + const bidTest = utils.deepClone(bid); delete bidTest.params.organizationId; expect(spec.isBidRequestValid(bidTest)).to.equal(false); }); it('should return false when site params is not passed', () => { - let bidTest = Object.assign({}, bid); + const bidTest = utils.deepClone(bid); delete bidTest.params.site; expect(spec.isBidRequestValid(bidTest)).to.equal(false); }); it('should return false when placement params is not passed', () => { - let bidTest = Object.assign({}, bid); + const bidTest = utils.deepClone(bid); delete bidTest.params.placement; expect(spec.isBidRequestValid(bidTest)).to.equal(false); }); - it('should return false when adUnit element id params is not passed', () => { - let bidTest = Object.assign({}, bid); + it('should add autodetected adUnitElementId and environment params', () => { + const bidTest = utils.deepClone(bid); delete bidTest.params.adUnitElementId; - expect(spec.isBidRequestValid(bidTest)).to.equal(false); - }); + delete bidTest.params.environment; + sandbox.stub(utils, 'getGptSlotInfoForAdUnitCode').returns({divId: 'banner-atf'}); + sandbox.stub(_features, 'getDevice').returns(4); + spec.isBidRequestValid(bidTest) + expect(bidTest.params.adUnitElementId).to.equal('banner-atf'); + expect(bidTest.params.environment).to.equal('mobile'); + }) + + it('should add autodetected tablet environment params', () => { + const bidTest = utils.deepClone(bid); + delete bidTest.params.environment; + sandbox.stub(_features, 'getDevice').returns(5); + spec.isBidRequestValid(bidTest) + expect(bidTest.params.environment).to.equal('tablet'); + }) it('should return false if not in the window.top', () => { sandbox.stub(utils, 'getWindowTop').throws(); From e17703a6f220628e66c43bf172967bb93422265e Mon Sep 17 00:00:00 2001 From: Jurij Sinickij Date: Thu, 11 Jun 2020 16:48:21 +0300 Subject: [PATCH 403/496] added CCPA support, gvlid to adform and adformOpenRTB adapters (#5214) --- modules/adformBidAdapter.js | 18 ++++++++---- modules/adformOpenRTBBidAdapter.js | 8 +++++- test/spec/modules/adformBidAdapter_spec.js | 28 +++++++++++-------- .../modules/adformOpenRTBBidAdapter_spec.js | 26 +++++++++++++++-- 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/modules/adformBidAdapter.js b/modules/adformBidAdapter.js index d2e8a570b8a..bf30a32b565 100644 --- a/modules/adformBidAdapter.js +++ b/modules/adformBidAdapter.js @@ -9,8 +9,10 @@ import * as utils from '../src/utils.js'; const OUTSTREAM_RENDERER_URL = 'https://s2.adform.net/banners/scripts/video/outstream/render.js'; const BIDDER_CODE = 'adform'; +const GVLID = 50; export const spec = { code: BIDDER_CODE, + gvlid: GVLID, supportedMediaTypes: [ BANNER, VIDEO ], isBidRequestValid: function (bid) { return !!(bid.params.mid); @@ -47,13 +49,19 @@ export const spec = { request.push('pt=' + netRevenue); request.push('stid=' + validBidRequests[0].auctionId); - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { + const gdprApplies = utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies'); + const consentString = utils.deepAccess(bidderRequest, 'gdprConsent.consentString'); + if (gdprApplies !== undefined) { gdprObject = { - gdpr: bidderRequest.gdprConsent.gdprApplies, - gdpr_consent: bidderRequest.gdprConsent.consentString + gdpr: gdprApplies, + gdpr_consent: consentString }; - request.push('gdpr=' + gdprObject.gdpr); - request.push('gdpr_consent=' + gdprObject.gdpr_consent); + request.push('gdpr=' + (gdprApplies & 1)); + request.push('gdpr_consent=' + consentString); + } + + if (bidderRequest && bidderRequest.uspConsent) { + request.push('us_privacy=' + bidderRequest.uspConsent); } for (i = 1, l = globalParams.length; i < l; i++) { diff --git a/modules/adformOpenRTBBidAdapter.js b/modules/adformOpenRTBBidAdapter.js index 9e3325fad0a..300cb211dcf 100644 --- a/modules/adformOpenRTBBidAdapter.js +++ b/modules/adformOpenRTBBidAdapter.js @@ -11,6 +11,7 @@ import * as utils from '../src/utils.js'; import { config } from '../src/config.js'; const BIDDER_CODE = 'adformOpenRTB'; +const GVLID = 50; const NATIVE_ASSET_IDS = { 0: 'title', 2: 'icon', 3: 'image', 5: 'sponsoredBy', 4: 'body', 1: 'cta' }; const NATIVE_PARAMS = { title: { @@ -46,6 +47,7 @@ const NATIVE_PARAMS = { export const spec = { code: BIDDER_CODE, + gvlid: GVLID, supportedMediaTypes: [ NATIVE ], isBidRequestValid: bid => !!bid.params.mid, buildRequests: (validBidRequests, bidderRequest) => { @@ -122,11 +124,15 @@ export const spec = { request.is_debug = !!test; request.test = 1; } - if (utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies')) { + if (utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') !== undefined) { request.user = { ext: { consent: bidderRequest.gdprConsent.consentString } }; request.regs = { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies & 1 } }; } + if (bidderRequest.uspConsent) { + utils.deepSetValue(request, 'regs.ext.us_privacy', bidderRequest.uspConsent); + } + return { method: 'POST', url: 'https://' + adxDomain + '/adx/openrtb', diff --git a/test/spec/modules/adformBidAdapter_spec.js b/test/spec/modules/adformBidAdapter_spec.js index 9233ca1dd7a..5bf0576362c 100644 --- a/test/spec/modules/adformBidAdapter_spec.js +++ b/test/spec/modules/adformBidAdapter_spec.js @@ -129,25 +129,24 @@ describe('Adform adapter', function () { assert.equal(parsedUrl.query.pt, 'gross'); }); - describe('gdpr', function () { + describe('user privacy', function () { it('should send GDPR Consent data to adform if gdprApplies', function () { - let resultBids = JSON.parse(JSON.stringify(bids[0])); let request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: true, consentString: 'concentDataString'}}); let parsedUrl = parseUrl(request.url).query; - assert.equal(parsedUrl.gdpr, 'true'); + assert.equal(parsedUrl.gdpr, '1'); assert.equal(parsedUrl.gdpr_consent, 'concentDataString'); }); - it('should not send GDPR Consent data to adform if gdprApplies is false or undefined', function () { - let resultBids = JSON.parse(JSON.stringify(bids[0])); + it('should not send GDPR Consent data to adform if gdprApplies is undefined', function () { let request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: false, consentString: 'concentDataString'}}); let parsedUrl = parseUrl(request.url).query; - assert.ok(!parsedUrl.gdpr); - assert.ok(!parsedUrl.gdpr_consent); + assert.equal(parsedUrl.gdpr, '0'); + assert.equal(parsedUrl.gdpr_consent, 'concentDataString'); request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: undefined, consentString: 'concentDataString'}}); + parsedUrl = parseUrl(request.url).query; assert.ok(!parsedUrl.gdpr); assert.ok(!parsedUrl.gdpr_consent); }); @@ -163,6 +162,13 @@ describe('Adform adapter', function () { request = spec.buildRequests([bids[0]]); assert.ok(!request.gdpr); }); + + it('should send CCPA Consent data to adform', function () { + const request = spec.buildRequests([bids[0]], {uspConsent: '1YA-'}); + const parsedUrl = parseUrl(request.url).query; + + assert.equal(parsedUrl.us_privacy, '1YA-'); + }); }); }); @@ -247,14 +253,14 @@ describe('Adform adapter', function () { for (let i = 0; i < result.length; i++) { assert.equal(result[i].gdpr, true); assert.equal(result[i].gdpr_consent, 'ERW342EIOWT34234KMGds'); - }; + } bidRequest.gdpr = undefined; result = spec.interpretResponse(serverResponse, bidRequest); for (let i = 0; i < result.length; i++) { assert.ok(!result[i].gdpr); assert.ok(!result[i].gdpr_consent); - }; + } }); it('should set a renderer only for an outstream context', function () { @@ -302,13 +308,13 @@ describe('Adform adapter', function () { serverResponse.body = [serverResponse.body[0]]; bidRequest.bids = [bidRequest.bids[0]]; - bidRequest.bids[0].sizes = [['300', '250'], ['250', '300'], ['300', '600'], ['600', '300']] + bidRequest.bids[0].sizes = [['300', '250'], ['250', '300'], ['300', '600'], ['600', '300']]; let result = spec.interpretResponse(serverResponse, bidRequest); assert.equal(result[0].width, 300); assert.equal(result[0].height, 600); }); - }) + }); }); beforeEach(function () { diff --git a/test/spec/modules/adformOpenRTBBidAdapter_spec.js b/test/spec/modules/adformOpenRTBBidAdapter_spec.js index 77dbc17cdb2..9f21a9af756 100644 --- a/test/spec/modules/adformOpenRTBBidAdapter_spec.js +++ b/test/spec/modules/adformOpenRTBBidAdapter_spec.js @@ -43,7 +43,7 @@ describe('AdformOpenRTB adapter', function () { assert.ok(request.data); }); - describe('gdpr', function () { + describe('user privacy', function () { it('should send GDPR Consent data to adform if gdprApplies', function () { let validBidRequests = [{ bidId: 'bidId', params: { siteId: 'siteId', test: 1 } }]; let bidderRequest = { gdprConsent: { gdprApplies: true, consentString: 'consentDataString' }, refererInfo: { referer: 'page' } }; @@ -60,9 +60,25 @@ describe('AdformOpenRTB adapter', function () { let request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data); assert.equal(typeof request.regs.ext.gdpr, 'number'); + assert.equal(request.regs.ext.gdpr, 1); }); - it('should not send GDPR Consent data to adform if gdprApplies is false or undefined', function () { + it('should send CCPA Consent data to adform', function () { + let validBidRequests = [{ bidId: 'bidId', params: { siteId: 'siteId', test: 1 } }]; + let bidderRequest = { uspConsent: '1YA-', refererInfo: { referer: 'page' } }; + let request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data); + + assert.equal(request.regs.ext.us_privacy, '1YA-'); + + bidderRequest = { uspConsent: '1YA-', gdprConsent: { gdprApplies: true, consentString: 'consentDataString' }, refererInfo: { referer: 'page' } }; + request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data); + + assert.equal(request.regs.ext.us_privacy, '1YA-'); + assert.equal(request.user.ext.consent, 'consentDataString'); + assert.equal(request.regs.ext.gdpr, 1); + }); + + it('should not send GDPR Consent data to adform if gdprApplies is undefined', function () { let validBidRequests = [{ bidId: 'bidId', params: { siteId: 'siteId' } @@ -70,6 +86,12 @@ describe('AdformOpenRTB adapter', function () { let bidderRequest = {gdprConsent: {gdprApplies: false, consentString: 'consentDataString'}, refererInfo: { referer: 'page' }}; let request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data); + assert.equal(request.user.ext.consent, 'consentDataString'); + assert.equal(request.regs.ext.gdpr, 0); + + bidderRequest = {gdprConsent: {consentString: 'consentDataString'}, refererInfo: { referer: 'page' }}; + request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data); + assert.equal(request.user, undefined); assert.equal(request.regs, undefined); }); From 00906b4a4f520cb7e88c0f952a447992dd094543 Mon Sep 17 00:00:00 2001 From: Ricardo Azpeitia Pimentel Date: Thu, 11 Jun 2020 08:54:19 -0500 Subject: [PATCH 404/496] Native support for NextRoll adapter (#5319) * Add native support * Add response testing * DRY test * Change required from bool to int * Set mediaType * Fixes objects * Fixes object access * Remove ad property, only set it for banner * Update tests * Moving hardcoding values to constants * Update docs with native information --- modules/nextrollBidAdapter.js | 159 +++++++++++++++++-- modules/nextrollBidAdapter.md | 29 +++- test/spec/modules/nextrollBidAdapter_spec.js | 117 ++++++++++++++ 3 files changed, 294 insertions(+), 11 deletions(-) diff --git a/modules/nextrollBidAdapter.js b/modules/nextrollBidAdapter.js index 0f273792154..56fca22d2c3 100644 --- a/modules/nextrollBidAdapter.js +++ b/modules/nextrollBidAdapter.js @@ -1,16 +1,16 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; import find from 'core-js-pure/features/array/find.js'; const BIDDER_CODE = 'nextroll'; const BIDDER_ENDPOINT = 'https://d.adroll.com/bid/prebid/'; -const ADAPTER_VERSION = 4; +const ADAPTER_VERSION = 5; export const spec = { code: BIDDER_CODE, - supportedMediaTypes: [BANNER], + supportedMediaTypes: [BANNER, NATIVE], /** * Determines whether or not the given bid request is valid. @@ -43,9 +43,8 @@ export const spec = { imp: { id: bidRequest.bidId, bidfloor: utils.getBidIdParameter('bidfloor', bidRequest.params), - banner: { - format: _getSizes(bidRequest) - }, + banner: _getBanner(bidRequest), + native: _getNative(utils.deepAccess(bidRequest, 'mediaTypes.native')), ext: { zone: { id: utils.getBidIdParameter('zoneId', bidRequest.params) @@ -82,6 +81,98 @@ export const spec = { } } +function _getBanner(bidRequest) { + let sizes = _getSizes(bidRequest) + if (sizes === undefined) return undefined + return {format: sizes} +} + +function _getNative(mediaTypeNative) { + if (mediaTypeNative === undefined) return undefined + let assets = _getNativeAssets(mediaTypeNative) + if (assets === undefined || assets.length == 0) return undefined + return { + request: { + native: { + assets: assets + } + } + } +} + +/* + id: Unique numeric id for the asset + kind: OpenRTB kind of asset. Supported: title, img and data. + key: Name of property that comes in the mediaType.native object. + type: OpenRTB type for that spefic kind of asset. + required: Overrides the asset required field configured, only overrides when is true. +*/ +const NATIVE_ASSET_MAP = [ + {id: 1, kind: 'title', key: 'title', required: true}, + {id: 2, kind: 'img', key: 'image', type: 3, required: true}, + {id: 3, kind: 'img', key: 'icon', type: 1}, + {id: 4, kind: 'img', key: 'logo', type: 2}, + {id: 5, kind: 'data', key: 'sponsoredBy', type: 1}, + {id: 6, kind: 'data', key: 'body', type: 2} +] + +const ASSET_KIND_MAP = { + title: _getTitleAsset, + img: _getImageAsset, + data: _getDataAsset, +} + +function _getAsset(mediaTypeNative, assetMap) { + let asset = mediaTypeNative[assetMap.key] + if (asset === undefined) return undefined + let assetFunc = ASSET_KIND_MAP[assetMap.kind] + return { + id: assetMap.id, + required: (assetMap.required || !!asset.required) ? 1 : 0, + [assetMap.kind]: assetFunc(asset, assetMap) + } +} + +function _getTitleAsset(title, _assetMap) { + return {len: title.len || 0} +} + +function _getMinAspectRatio(aspectRatio, property) { + if (!utils.isPlainObject(aspectRatio)) return 1 + + let ratio = aspectRatio['ratio_' + property] + let min = aspectRatio['min_' + property] + + if (utils.isNumber(ratio)) return ratio + if (utils.isNumber(min)) return min + + return 1 +} + +function _getImageAsset(image, assetMap) { + let sizes = image.sizes + let aspectRatio = image.aspect_ratios ? image.aspect_ratios[0] : undefined + + return { + type: assetMap.type, + w: (sizes ? sizes[0] : undefined), + h: (sizes ? sizes[1] : undefined), + wmin: _getMinAspectRatio(aspectRatio, 'width'), + hmin: _getMinAspectRatio(aspectRatio, 'height'), + } +} + +function _getDataAsset(data, assetMap) { + return { + type: assetMap.type, + len: data.len || 0 + } +} + +function _getNativeAssets(mediaTypeNative) { + return NATIVE_ASSET_MAP.map(assetMap => _getAsset(mediaTypeNative, assetMap)).filter(asset => asset !== undefined) +} + function _getUser(requests) { let id = utils.deepAccess(requests, '0.userId.nextroll'); if (id === undefined) { @@ -99,8 +190,7 @@ function _getUser(requests) { } function _buildResponse(bidResponse, bid) { - const adm = utils.replaceAuctionPrice(bid.adm, bid.price); - return { + let response = { requestId: bidResponse.id, cpm: bid.price, width: bid.w, @@ -109,8 +199,53 @@ function _buildResponse(bidResponse, bid) { dealId: bidResponse.dealId, currency: 'USD', netRevenue: true, - ttl: 300, - ad: adm + ttl: 300 + } + if (utils.isStr(bid.adm)) { + response.mediaType = BANNER + response.ad = utils.replaceAuctionPrice(bid.adm, bid.price) + } else { + response.mediaType = NATIVE + response.native = _getNativeResponse(bid.adm, bid.price) + } + return response +} + +const privacyLink = 'https://info.evidon.com/pub_info/573'; +const privacyIcon = 'https://c.betrad.com/pub/icon1.png'; + +function _getNativeResponse(adm, price) { + let baseResponse = { + clickTrackers: (adm.link && adm.link.clicktrackers) || [], + jstracker: adm.jstracker || [], + clickUrl: utils.replaceAuctionPrice(adm.link.url, price), + impressionTrackers: adm.imptrackers.map(impTracker => utils.replaceAuctionPrice(impTracker, price)), + privacyLink: privacyLink, + privacyIcon: privacyIcon + } + return adm.assets.reduce((accResponse, asset) => { + let assetMaps = NATIVE_ASSET_MAP.filter(assetMap => assetMap.id === asset.id && asset[assetMap.kind] !== undefined) + if (assetMaps.length === 0) return accResponse + let assetMap = assetMaps[0] + accResponse[assetMap.key] = _getAssetResponse(asset, assetMap) + return accResponse + }, baseResponse) +} + +function _getAssetResponse(asset, assetMap) { + switch (assetMap.kind) { + case 'title': + return asset.title.text + + case 'img': + return { + url: asset.img.url, + width: asset.img.w, + height: asset.img.h + } + + case 'data': + return asset.data.value } } @@ -131,6 +266,9 @@ function _getSeller(bidRequest) { } function _getSizes(bidRequest) { + if (!utils.isArray(bidRequest.sizes)) { + return undefined + } return bidRequest.sizes.filter(_isValidSize).map(size => { return { w: size[0], @@ -191,6 +329,7 @@ function _getOsVersion(userAgent) { } export function hasCCPAConsent(bidderRequest) { + if (bidderRequest === undefined) return true; if (typeof bidderRequest.uspConsent !== 'string') { return true; } diff --git a/modules/nextrollBidAdapter.md b/modules/nextrollBidAdapter.md index 2f57987f985..c706839c453 100644 --- a/modules/nextrollBidAdapter.md +++ b/modules/nextrollBidAdapter.md @@ -9,9 +9,11 @@ Maintainer: prebid@nextroll.com # Description Module that connects to NextRoll's bidders. -The NextRoll bid adapter supports Banner format only. +The NextRoll bid adapter supports banner and native format. # Test Parameters + +## Banner Example ``` javascript var adUnits = [ { @@ -47,4 +49,29 @@ var adUnits = [ }] } ] +``` + +## Native Example +```javascript +var adUnits = [ + { + code: 'div-1', + mediaTypes: { + native: { + title: { required: true, len: 80 }, + image: { required: true, sizes: [728, 90] }, + sponsoredBy: { required: false, len: 20 } + } + }, + bids: [{ + bidder: 'nextroll', + params: { + bidfloor: 1, + zoneId: "13144370", + publisherId: "publisherId", + sellerId: "sellerId", + } + }] + } +]; ``` \ No newline at end of file diff --git a/test/spec/modules/nextrollBidAdapter_spec.js b/test/spec/modules/nextrollBidAdapter_spec.js index 85cd45be1d0..e1d85244931 100644 --- a/test/spec/modules/nextrollBidAdapter_spec.js +++ b/test/spec/modules/nextrollBidAdapter_spec.js @@ -27,6 +27,44 @@ describe('nextrollBidAdapter', function() { let bidWithoutValidId = { id: '' }; let bidWithoutId = { params: { zoneId: 'zone1' } }; + describe('nativeBidRequest', () => { + it('validates native spec', () => { + let nativeAdUnit = [{ + bidder: 'nextroll', + adUnitCode: 'adunit-code', + bidId: 'bid_id', + mediaTypes: { + native: { + title: {required: true, len: 80}, + image: {required: true, sizes: [728, 90]}, + sponsoredBy: {required: false, len: 20}, + clickUrl: {required: true}, + body: {required: true, len: 25}, + icon: {required: true, sizes: [50, 50], aspect_ratios: [{ratio_height: 3, ratio_width: 4}]}, + someRandomAsset: {required: false, len: 100} // This should be ignored + } + }, + params: { + bidfloor: 1, + zoneId: 'zone1', + publisherId: 'publisher_id' + } + }]; + + let request = spec.buildRequests(nativeAdUnit) + let assets = request[0].data.imp.native.request.native.assets + + let excptedAssets = [ + {id: 1, required: 1, title: {len: 80}}, + {id: 2, required: 1, img: {w: 728, h: 90, wmin: 1, hmin: 1, type: 3}}, + {id: 3, required: 1, img: {w: 50, h: 50, wmin: 4, hmin: 3, type: 1}}, + {id: 5, required: 0, data: {len: 20, type: 1}}, + {id: 6, required: 1, data: {len: 25, type: 2}} + ] + expect(assets).to.be.deep.equal(excptedAssets) + }) + }) + describe('isBidRequestValid', function() { it('validates the bids correctly when the bid has an id', function() { expect(spec.isBidRequestValid(validBid)).to.be.true; @@ -142,6 +180,85 @@ describe('nextrollBidAdapter', function() { }); }); + describe('interpret native response', () => { + let clickUrl = 'https://clickurl.com/with/some/path' + let titleText = 'Some title' + let imgW = 300 + let imgH = 250 + let imgUrl = 'https://clickurl.com/img.png' + let brandText = 'Some Brand' + let impUrl = 'https://clickurl.com/imptracker' + + let responseBody = { + body: { + id: 'bidresponse_id', + seatbid: [{ + bid: [{ + price: 1.2, + crid: 'crid1', + adm: { + link: {url: clickUrl}, + assets: [ + {id: 1, title: {text: titleText}}, + {id: 2, img: {w: imgW, h: imgH, url: imgUrl}}, + {id: 5, data: {value: brandText}} + ], + imptrackers: [impUrl] + } + }] + }] + } + }; + + it('Should interpret response', () => { + let response = spec.interpretResponse(utils.deepClone(responseBody)) + let expectedResponse = { + clickUrl: clickUrl, + impressionTrackers: [impUrl], + privacyLink: 'https://info.evidon.com/pub_info/573', + privacyIcon: 'https://c.betrad.com/pub/icon1.png', + title: titleText, + image: {url: imgUrl, width: imgW, height: imgH}, + sponsoredBy: brandText, + clickTrackers: [], + jstracker: [] + } + + expect(response[0].native).to.be.deep.equal(expectedResponse) + }) + + it('Should interpret all assets', () => { + let allAssetsResponse = utils.deepClone(responseBody) + let iconUrl = imgUrl + '?icon=true', iconW = 10, iconH = 15 + let logoUrl = imgUrl + '?logo=true', logoW = 20, logoH = 25 + let bodyText = 'Some body text' + + allAssetsResponse.body.seatbid[0].bid[0].adm.assets.push(...[ + {id: 3, img: {w: iconW, h: iconH, url: iconUrl}}, + {id: 4, img: {w: logoW, h: logoH, url: logoUrl}}, + {id: 6, data: {value: bodyText}} + ]) + + let response = spec.interpretResponse(allAssetsResponse) + let expectedResponse = { + clickUrl: clickUrl, + impressionTrackers: [impUrl], + jstracker: [], + clickTrackers: [], + privacyLink: 'https://info.evidon.com/pub_info/573', + privacyIcon: 'https://c.betrad.com/pub/icon1.png', + title: titleText, + image: {url: imgUrl, width: imgW, height: imgH}, + icon: {url: iconUrl, width: iconW, height: iconH}, + logo: {url: logoUrl, width: logoW, height: logoH}, + body: bodyText, + sponsoredBy: brandText + } + + expect(response[0].native).to.be.deep.equal(expectedResponse) + }) + }) + describe('hasCCPAConsent', function() { function ccpaRequest(consentString) { return { From 57fab27ed00c2f96f44b23d56b410ec300669f5b Mon Sep 17 00:00:00 2001 From: skazedo Date: Thu, 11 Jun 2020 11:14:07 -0400 Subject: [PATCH 405/496] Adding back ZEDO adapter with changes to make it compatible to latest prebid (#5276) * initial commit * updated contact and tag details * changes ti support the renderers * changes to pass dimId * fixed names of internal mapping * added comment * added gdpr param to request and other fixes * modified api url * fix * fixed the secure api call * rolled back video event callback till we support it * updated doc with video details * added bid won and timeout pixel * added testcase for bid events * modified testcase * fixed the url logged * tag param values passed ot renderer * added a conditioal check * changes to support new param to adserver for purpose of tracking * passed param to renderer * missing variable defined * changes to pass schain * fix * added protocol to url * fixed test for protocol * changed urls to secure only * fixes to make it compatible to head * added support for ccpa * Fixed path of find module * Remove package.json * updated test example with new setup * Adding back the file * trying to resolve conflict Co-authored-by: Sanoska Gonsalves --- modules/zedoBidAdapter.js | 342 ++++++++++++++++++++++ modules/zedoBidAdapter.md | 33 ++- test/spec/modules/zedoBidAdapter_spec.js | 354 +++++++++++++++++++++++ 3 files changed, 713 insertions(+), 16 deletions(-) create mode 100644 modules/zedoBidAdapter.js create mode 100644 test/spec/modules/zedoBidAdapter_spec.js diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js new file mode 100644 index 00000000000..e75b9c82065 --- /dev/null +++ b/modules/zedoBidAdapter.js @@ -0,0 +1,342 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import find from 'core-js-pure/features/array/find'; +import { Renderer } from '../src/Renderer.js'; +import { getRefererInfo } from '../src/refererDetection.js'; + +const BIDDER_CODE = 'zedo'; +const SECURE_URL = 'https://saxp.zedo.com/asw/fmh.json'; +const DIM_TYPE = { + '7': 'display', + '9': 'display', + '14': 'display', + '70': 'SBR', + '83': 'CurtainRaiser', + '85': 'Inarticle', + '86': 'pswipeup', + '88': 'Inview', + '100': 'display', + '101': 'display', + '102': 'display', + '103': 'display' + // '85': 'pre-mid-post-roll', +}; +const SECURE_EVENT_PIXEL_URL = 'tt1.zedo.com/log/p.gif'; + +export const spec = { + code: BIDDER_CODE, + aliases: [], + supportedMediaTypes: [BANNER, VIDEO], + + /** + * Determines whether or not the given bid request is valid. + * + * @param {object} bid The bid to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bid) { + return !!(bid.params && bid.params.channelCode && bid.params.dimId); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function (bidRequests, bidderRequest) { + let data = { + placements: [] + }; + bidRequests.map(bidRequest => { + let channelCode = parseInt(bidRequest.params.channelCode); + let network = parseInt(channelCode / 1000000); + let channel = channelCode % 1000000; + let dim = getSizes(bidRequest.sizes); + let placement = { + id: bidRequest.bidId, + network: network, + channel: channel, + publisher: bidRequest.params.pubId ? bidRequest.params.pubId : 0, + width: dim[0], + height: dim[1], + dimension: bidRequest.params.dimId, + version: '$prebid.version$', + keyword: '', + transactionId: bidRequest.transactionId + } + if (bidderRequest && bidderRequest.gdprConsent) { + if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { + data.gdpr = Number(bidderRequest.gdprConsent.gdprApplies); + } + data.gdpr_consent = bidderRequest.gdprConsent.consentString; + } + // Add CCPA consent string + if (bidderRequest && bidderRequest.uspConsent) { + data.usp = bidderRequest.uspConsent; + } + + let dimType = DIM_TYPE[String(bidRequest.params.dimId)] + if (dimType) { + placement['renderers'] = [{ + 'name': dimType + }] + } else { // default to display + placement['renderers'] = [{ + 'name': 'display' + }] + } + data['placements'].push(placement); + }); + // adding schain object + if (bidRequests[0].schain) { + data['supplyChain'] = getSupplyChain(bidRequests[0].schain); + } + return { + method: 'GET', + url: SECURE_URL, + data: 'g=' + JSON.stringify(data) + } + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function (serverResponse, request) { + serverResponse = serverResponse.body; + const bids = []; + if (!serverResponse || serverResponse.error) { + let errorMessage = `in response for ${request.bidderCode} adapter`; + if (serverResponse && serverResponse.error) { errorMessage += `: ${serverResponse.error}`; } + utils.logError(errorMessage); + return bids; + } + + if (serverResponse.ad) { + serverResponse.ad.forEach(ad => { + const creativeBid = getCreative(ad); + if (creativeBid) { + if (parseInt(creativeBid.cpm) !== 0) { + const bid = newBid(ad, creativeBid, request); + bid.mediaType = parseMediaType(creativeBid); + bids.push(bid); + } + } + }); + } + return bids; + }, + + getUserSyncs: function (syncOptions, responses, gdprConsent) { + if (syncOptions.iframeEnabled) { + let url = 'https://tt3.zedo.com/rs/us/fcs.html'; + if (gdprConsent && typeof gdprConsent.consentString === 'string') { + // add 'gdpr' only if 'gdprApplies' is defined + if (typeof gdprConsent.gdprApplies === 'boolean') { + url += `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; + } else { + url += `?gdpr_consent=${gdprConsent.consentString}`; + } + } + return [{ + type: 'iframe', + url: url + }]; + } + }, + + onTimeout: function (timeoutData) { + try { + logEvent('117', timeoutData); + } catch (e) { + utils.logError(e); + } + }, + + onBidWon: function (bid) { + try { + logEvent('116', [bid]); + } catch (e) { + utils.logError(e); + } + } + +}; + +function getSupplyChain (supplyChain) { + return { + complete: supplyChain.complete, + nodes: supplyChain.nodes + } +}; + +function getCreative(ad) { + return ad && ad.creatives && ad.creatives.length && find(ad.creatives, creative => creative.adId); +}; +/** + * Unpack the Server's Bid into a Prebid-compatible one. + * @param serverBid + * @param rtbBid + * @param bidderRequest + * @return Bid + */ +function newBid(serverBid, creativeBid, bidderRequest) { + const bid = { + requestId: serverBid.slotId, + creativeId: creativeBid.adId, + network: serverBid.network, + adType: creativeBid.creativeDetails.type, + dealId: 99999999, + currency: 'USD', + netRevenue: true, + ttl: 300 + }; + + if (creativeBid.creativeDetails.type === 'VAST') { + Object.assign(bid, { + width: creativeBid.width, + height: creativeBid.height, + vastXml: creativeBid.creativeDetails.adContent, + cpm: parseInt(creativeBid.bidCpm) / 1000000, + ttl: 3600 + }); + const rendererOptions = utils.deepAccess( + bidderRequest, + 'renderer.options' + ); + let rendererUrl = 'https://ss3.zedo.com/gecko/beta/fmpbgt.min.js'; + Object.assign(bid, { + adResponse: serverBid, + renderer: getRenderer(bid.adUnitCode, serverBid.slotId, rendererUrl, rendererOptions) + }); + } else { + Object.assign(bid, { + width: creativeBid.width, + height: creativeBid.height, + cpm: parseInt(creativeBid.bidCpm) / 1000000, + ad: creativeBid.creativeDetails.adContent, + }); + } + + return bid; +} +/* Turn bid request sizes into compatible format */ +function getSizes(requestSizes) { + let width = 0; + let height = 0; + if (utils.isArray(requestSizes) && requestSizes.length === 2 && + !utils.isArray(requestSizes[0])) { + width = parseInt(requestSizes[0], 10); + height = parseInt(requestSizes[1], 10); + } else if (typeof requestSizes === 'object') { + for (let i = 0; i < requestSizes.length; i++) { + let size = requestSizes[i]; + width = parseInt(size[0], 10); + height = parseInt(size[1], 10); + break; + } + } + return [width, height]; +} + +function getRenderer(adUnitCode, rendererId, rendererUrl, rendererOptions = {}) { + const renderer = Renderer.install({ + id: rendererId, + url: rendererUrl, + config: rendererOptions, + loaded: false, + }); + + try { + renderer.setRender(videoRenderer); + } catch (err) { + utils.logWarn('Prebid Error calling setRender on renderer', err); + } + + renderer.setEventHandlers({ + impression: () => utils.logMessage('ZEDO video impression'), + loaded: () => utils.logMessage('ZEDO video loaded'), + ended: () => { + utils.logMessage('ZEDO renderer video ended'); + document.querySelector(`#${adUnitCode}`).style.display = 'none'; + } + }); + return renderer; +} + +function videoRenderer(bid) { + // push to render queue + const refererInfo = getRefererInfo(); + let referrer = ''; + if (refererInfo) { + referrer = refererInfo.referer; + } + bid.renderer.push(() => { + let channelCode = utils.deepAccess(bid, 'params.0.channelCode') || 0; + let dimId = utils.deepAccess(bid, 'params.0.dimId') || 0; + let publisher = utils.deepAccess(bid, 'params.0.pubId') || 0; + let options = utils.deepAccess(bid, 'params.0.options') || {}; + let channel = (channelCode > 0) ? (channelCode - (bid.network * 1000000)) : 0; + + var rndr = new window.ZdPBTag(bid.adUnitCode, bid.network, bid.width, bid.height, bid.adType, bid.vastXml, channel, dimId, + (encodeURI(referrer) || ''), options); + rndr.renderAd(publisher); + }); +} + +function parseMediaType(creativeBid) { + const adType = creativeBid.creativeDetails.type; + if (adType === 'VAST') { + return VIDEO; + } else { + return BANNER; + } +} + +function logEvent(eid, data) { + let getParams = { + protocol: 'https', + hostname: SECURE_EVENT_PIXEL_URL, + search: getLoggingData(eid, data) + }; + let eventUrl = utils.buildUrl(getParams).replace(/&/g, ';'); + utils.triggerPixel(eventUrl); +} + +function getLoggingData(eid, data) { + data = (utils.isArray(data) && data) || []; + + let params = {}; + let channel, network, dim, publisher, adunitCode, timeToRespond, cpm; + data.map((adunit) => { + adunitCode = adunit.adUnitCode; + channel = utils.deepAccess(adunit, 'params.0.channelCode') || 0; + network = channel > 0 ? parseInt(channel / 1000000) : 0; + dim = utils.deepAccess(adunit, 'params.0.dimId') * 256 || 0; + publisher = utils.deepAccess(adunit, 'params.0.pubId') || 0; + timeToRespond = adunit.timeout ? adunit.timeout : adunit.timeToRespond; + cpm = adunit.cpm; + }); + let referrer = ''; + const refererInfo = getRefererInfo(); + if (refererInfo) { + referrer = refererInfo.referer; + } + params.n = network; + params.c = channel; + params.s = publisher; + params.x = dim; + params.ai = encodeURI('Prebid^zedo^' + adunitCode + '^' + cpm + '^' + timeToRespond); + params.pu = encodeURI(referrer) || ''; + params.eid = eid; + params.e = 'e'; + params.z = Math.random(); + + return params; +} + +registerBidder(spec); diff --git a/modules/zedoBidAdapter.md b/modules/zedoBidAdapter.md index e0f9101deaa..2f31e8aed9b 100644 --- a/modules/zedoBidAdapter.md +++ b/modules/zedoBidAdapter.md @@ -18,22 +18,23 @@ ZEDO has its own renderer and will render the video unit if not defined in the c # display ``` - var adUnits = [ - { - code: 'banner-ad-div', - sizes: [[300, 250], [728, 90]], - bids: [ - { - bidder: 'zedo', - params: { - channelCode: 2264004118, // required - dimId: 9, // required - pubId: 1 // optional - } + var adUnits = [{ + code: 'div-gpt-ad-1460505748561-0', + mediaTypes: { + banner: { + sizes: [[300, 250], [300,600]], } - ] - } - ]; + }, + // Replace this object to test a new Adapter! + bids: [{ + bidder: 'zedo', + params: { + channelCode: 2264004735, //REQUIRED + dimId:9 //REQUIRED + } + }] + + }]; ``` # video ``` @@ -54,7 +55,7 @@ ZEDO has its own renderer and will render the video unit if not defined in the c bidder: 'zedo', params: { - channelCode: 2264004593, // required + channelCode: 2264004735, // required dimId: 85, // required pubId: 1 // optional } diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js new file mode 100644 index 00000000000..8e5a789656e --- /dev/null +++ b/test/spec/modules/zedoBidAdapter_spec.js @@ -0,0 +1,354 @@ +import { expect } from 'chai'; +import { spec } from 'modules/zedoBidAdapter'; + +describe('The ZEDO bidding adapter', function () { + describe('isBidRequestValid', function () { + it('should return false when given an invalid bid', function () { + const bid = { + bidder: 'zedo', + }; + const isValid = spec.isBidRequestValid(bid); + expect(isValid).to.equal(false); + }); + + it('should return true when given a channelcode bid', function () { + const bid = { + bidder: 'zedo', + params: { + channelCode: 20000000, + dimId: 9 + }, + }; + const isValid = spec.isBidRequestValid(bid); + expect(isValid).to.equal(true); + }); + }); + + describe('buildRequests', function () { + const bidderRequest = { + timeout: 3000, + }; + + it('should properly build a channelCode request for dim Id with type not defined', function () { + const bidRequests = [ + { + bidder: 'zedo', + adUnitCode: 'p12345', + transactionId: '12345667', + sizes: [[300, 200]], + params: { + channelCode: 20000000, + dimId: 10, + pubId: 1 + }, + }, + ]; + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.url).to.match(/^https:\/\/saxp.zedo.com\/asw\/fmh.json/); + expect(request.method).to.equal('GET'); + const zedoRequest = request.data; + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"publisher":1,"width":300,"height":200,"dimension":10,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}]}'); + }); + + it('should properly build a channelCode request for video with type defined', function () { + const bidRequests = [ + { + bidder: 'zedo', + adUnitCode: 'p12345', + transactionId: '12345667', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'instream', + }, + }, + params: { + channelCode: 20000000, + dimId: 85 + }, + }, + ]; + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.url).to.match(/^https:\/\/saxp.zedo.com\/asw\/fmh.json/); + expect(request.method).to.equal('GET'); + const zedoRequest = request.data; + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"publisher":0,"width":640,"height":480,"dimension":85,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"Inarticle"}]}]}'); + }); + + describe('buildGDPRRequests', function () { + let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; + const bidderRequest = { + timeout: 3000, + gdprConsent: { + 'consentString': consentString, + 'gdprApplies': true + } + }; + + it('should properly build request with gdpr consent', function () { + const bidRequests = [ + { + bidder: 'zedo', + adUnitCode: 'p12345', + transactionId: '12345667', + sizes: [[300, 200]], + params: { + channelCode: 20000000, + dimId: 10 + }, + }, + ]; + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.method).to.equal('GET'); + const zedoRequest = request.data; + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"publisher":0,"width":300,"height":200,"dimension":10,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}],"gdpr":1,"gdpr_consent":"BOJ8RZsOJ8RZsABAB8AAAAAZ+A=="}'); + }); + }); + }); + describe('interpretResponse', function () { + it('should return an empty array when there is bid response', function () { + const response = {}; + const request = { bidRequests: [] }; + const bids = spec.interpretResponse(response, request); + expect(bids).to.have.lengthOf(0); + }); + + it('should properly parse a bid response with no valid creative', function () { + const response = { + body: { + ad: [ + { + 'slotId': 'ad1d762', + 'network': '2000', + 'creatives': [ + { + 'adId': '12345', + 'height': '600', + 'width': '160', + 'isFoc': true, + 'creativeDetails': { + 'type': 'StdBanner', + 'adContent': { + 'focImage': { + 'url': 'https://c13.zedo.com/OzoDB/0/0/0/blank.gif', + 'target': '_blank', + } + } + }, + 'cpm': '0' + } + ] + } + ] + } + }; + const request = { + bidRequests: [{ + bidder: 'zedo', + adUnitCode: 'p12345', + bidId: 'test-bidId', + params: { + channelCode: 2000000, + dimId: 9 + } + }] + }; + const bids = spec.interpretResponse(response, request); + expect(bids).to.have.lengthOf(0); + }); + + it('should properly parse a bid response with valid display creative', function () { + const response = { + body: { + ad: [ + { + 'slotId': 'ad1d762', + 'network': '2000', + 'creatives': [ + { + 'adId': '12345', + 'height': '600', + 'width': '160', + 'isFoc': true, + 'creativeDetails': { + 'type': 'StdBanner', + 'adContent': '' + }, + 'bidCpm': '720000' + } + ] + } + ] + } + }; + const request = { + bidRequests: [{ + bidder: 'zedo', + adUnitCode: 'test-requestId', + bidId: 'test-bidId', + params: { + channelCode: 2000000, + dimId: 9 + }, + }] + }; + const bids = spec.interpretResponse(response, request); + expect(bids).to.have.lengthOf(1); + expect(bids[0].requestId).to.equal('ad1d762'); + expect(bids[0].cpm).to.equal(0.72); + expect(bids[0].width).to.equal('160'); + expect(bids[0].height).to.equal('600'); + }); + + it('should properly parse a bid response with valid video creative', function () { + const response = { + body: { + ad: [ + { + 'slotId': 'ad1d762', + 'network': '2000', + 'creatives': [ + { + 'adId': '12345', + 'height': '480', + 'width': '640', + 'isFoc': true, + 'creativeDetails': { + 'type': 'VAST', + 'adContent': '' + }, + 'bidCpm': '780000' + } + ] + } + ] + } + }; + const request = { + bidRequests: [{ + bidder: 'zedo', + adUnitCode: 'test-requestId', + bidId: 'test-bidId', + params: { + channelCode: 2000000, + dimId: 85 + }, + }] + }; + + const bids = spec.interpretResponse(response, request); + expect(bids).to.have.lengthOf(1); + expect(bids[0].requestId).to.equal('ad1d762'); + expect(bids[0].cpm).to.equal(0.78); + expect(bids[0].width).to.equal('640'); + expect(bids[0].height).to.equal('480'); + expect(bids[0].adType).to.equal('VAST'); + expect(bids[0].vastXml).to.not.equal(''); + expect(bids[0].ad).to.be.an('undefined'); + expect(bids[0].renderer).not.to.be.an('undefined'); + }); + }); + + describe('user sync', function () { + it('should register the iframe sync url', function () { + let syncs = spec.getUserSyncs({ + iframeEnabled: true + }); + expect(syncs).to.not.be.an('undefined'); + expect(syncs).to.have.lengthOf(1); + expect(syncs[0].type).to.equal('iframe'); + }); + + it('should pass gdpr params', function () { + let syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, { + gdprApplies: false, consentString: 'test' + }); + expect(syncs).to.not.be.an('undefined'); + expect(syncs).to.have.lengthOf(1); + expect(syncs[0].type).to.equal('iframe'); + expect(syncs[0].url).to.contains('gdpr=0'); + }); + }); + + describe('bid events', function () { + it('should trigger a win pixel', function () { + const bid = { + 'bidderCode': 'zedo', + 'width': '300', + 'height': '250', + 'statusMessage': 'Bid available', + 'adId': '148018fe5e', + 'cpm': 0.5, + 'ad': 'dummy data', + 'ad_id': '12345', + 'sizeId': '15', + 'adResponse': + { + 'creatives': [ + { + 'adId': '12345', + 'height': '480', + 'width': '640', + 'isFoc': true, + 'creativeDetails': { + 'type': 'VAST', + 'adContent': '' + }, + 'seeder': { + 'network': 1234, + 'servedChan': 1234567, + }, + 'cpm': '1200000', + 'servedChan': 1234, + }] + }, + 'params': [{ + 'channelCode': '123456', + 'dimId': '85' + }], + 'requestTimestamp': 1540401686, + 'responseTimestamp': 1540401687, + 'timeToRespond': 6253, + 'pbLg': '0.50', + 'pbMg': '0.50', + 'pbHg': '0.53', + 'adUnitCode': '/123456/header-bid-tag-0', + 'bidder': 'zedo', + 'size': '300x250', + 'adserverTargeting': { + 'hb_bidder': 'zedo', + 'hb_adid': '148018fe5e', + 'hb_pb': '10.00', + } + }; + spec.onBidWon(bid); + spec.onTimeout(bid); + }); + it('should trigger a timeout pixel', function () { + const bid = { + 'bidderCode': 'zedo', + 'width': '300', + 'height': '250', + 'statusMessage': 'Bid available', + 'adId': '148018fe5e', + 'cpm': 0.5, + 'ad': 'dummy data', + 'ad_id': '12345', + 'sizeId': '15', + 'params': [{ + 'channelCode': '123456', + 'dimId': '85' + }], + 'timeout': 1, + 'requestTimestamp': 1540401686, + 'responseTimestamp': 1540401687, + 'timeToRespond': 6253, + 'adUnitCode': '/123456/header-bid-tag-0', + 'bidder': 'zedo', + 'size': '300x250', + }; + spec.onBidWon(bid); + spec.onTimeout(bid); + }); + }); +}); From 4c86e0d994d8a781cd00575746b628cac002bc55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Udi=20Talias=20=E2=9A=9B=EF=B8=8F?= Date: Thu, 11 Jun 2020 18:59:30 +0300 Subject: [PATCH 406/496] Vidazoo Adapter: Feature/direct deal targeting (#5343) * feat(module): multi size request * fix getUserSyncs added tests * update(module): package-lock.json from master * feat(client): send deal id with each request Co-authored-by: roman --- modules/vidazooBidAdapter.js | 61 ++++++++++++++++++--- test/spec/modules/vidazooBidAdapter_spec.js | 13 +++-- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/modules/vidazooBidAdapter.js b/modules/vidazooBidAdapter.js index 0880b115c70..19c3f1db8e8 100644 --- a/modules/vidazooBidAdapter.js +++ b/modules/vidazooBidAdapter.js @@ -1,6 +1,6 @@ import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; export const URL = 'https://prebid.cootlogix.com'; const BIDDER_CODE = 'vidazoo'; @@ -21,8 +21,11 @@ function isBidRequestValid(bid) { } function buildRequest(bid, topWindowUrl, sizes, bidderRequest) { - const {params, bidId} = bid; - const {bidFloor, cId, pId, ext} = params; + const { params, bidId } = bid; + const { bidFloor, cId, pId, ext } = params; + const hashUrl = hashCode(topWindowUrl); + const dealId = getNextDealId(hashUrl); + let data = { url: encodeURIComponent(topWindowUrl), cb: Date.now(), @@ -30,6 +33,7 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest) { bidId: bidId, publisherId: pId, sizes: sizes, + dealId: dealId, }; if (bidderRequest.gdprConsent) { if (bidderRequest.gdprConsent.consentString) { @@ -70,14 +74,14 @@ function interpretResponse(serverResponse, request) { if (!serverResponse || !serverResponse.body) { return []; } - const {bidId} = request.data; - const {results} = serverResponse.body; + const { bidId } = request.data; + const { results } = serverResponse.body; let output = []; try { results.forEach(result => { - const {creativeId, ad, price, exp, width, height, currency} = result; + const { creativeId, ad, price, exp, width, height, currency } = result; if (!ad || !price) { return; } @@ -100,7 +104,7 @@ function interpretResponse(serverResponse, request) { } function getUserSyncs(syncOptions, responses) { - const {iframeEnabled, pixelEnabled} = syncOptions; + const { iframeEnabled, pixelEnabled } = syncOptions; if (iframeEnabled) { return [{ @@ -113,7 +117,7 @@ function getUserSyncs(syncOptions, responses) { const lookup = {}; const syncs = []; responses.forEach(response => { - const {body} = response; + const { body } = response; const results = body ? body.results || [] : []; results.forEach(result => { (result.cookies || []).forEach(cookie => { @@ -134,6 +138,45 @@ function getUserSyncs(syncOptions, responses) { return []; } +function hashCode(s, prefix = '_') { + const l = s.length; + let h = 0 + let i = 0; + if (l > 0) { + while (i < l) { h = (h << 5) - h + s.charCodeAt(i++) | 0; } + } + return prefix + h; +} + +function getNextDealId(key) { + try { + const currentValue = Number(getStorageItem(key) || 0); + const nextValue = currentValue + 1; + setStorageItem(key, nextValue); + return nextValue; + } catch (e) { + return 0; + } +} + +function getStorage() { + return window['sessionStorage']; +} + +function getStorageItem(key) { + try { + return getStorage().getItem(key); + } catch (e) { + return null; + } +} + +function setStorageItem(key, value) { + try { + getStorage().setItem(key, String(value)); + } catch (e) { } +} + export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER], diff --git a/test/spec/modules/vidazooBidAdapter_spec.js b/test/spec/modules/vidazooBidAdapter_spec.js index 0c9867cbe9c..9b7b6a73a21 100644 --- a/test/spec/modules/vidazooBidAdapter_spec.js +++ b/test/spec/modules/vidazooBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec as adapter, URL} from 'modules/vidazooBidAdapter.js'; +import { expect } from 'chai'; +import { spec as adapter, URL } from 'modules/vidazooBidAdapter.js'; import * as utils from 'src/utils.js'; const BID = { @@ -139,6 +139,7 @@ describe('VidazooBidAdapter', function () { bidFloor: 0.1, bidId: '2d52001cabd527', publisherId: '59ac17c192832d0011283fe3', + dealId: 1, 'ext.param1': 'loremipsum', 'ext.param2': 'dolorsitamet', } @@ -151,7 +152,7 @@ describe('VidazooBidAdapter', function () { }); describe('getUserSyncs', function () { it('should have valid user sync with iframeEnabled', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', @@ -160,7 +161,7 @@ describe('VidazooBidAdapter', function () { }); it('should have valid user sync with pixelEnabled', function () { - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ 'url': 'https://sync.com', @@ -176,12 +177,12 @@ describe('VidazooBidAdapter', function () { }); it('should return empty array when there is no ad', function () { - const responses = adapter.interpretResponse({price: 1, ad: ''}); + const responses = adapter.interpretResponse({ price: 1, ad: '' }); expect(responses).to.be.empty; }); it('should return empty array when there is no price', function () { - const responses = adapter.interpretResponse({price: null, ad: 'great ad'}); + const responses = adapter.interpretResponse({ price: null, ad: 'great ad' }); expect(responses).to.be.empty; }); From e7131ebf998582a68f8e410037b4fb3e46088fad Mon Sep 17 00:00:00 2001 From: Itay Nave <38345760+itaynave@users.noreply.github.com> Date: Thu, 11 Jun 2020 19:41:49 +0300 Subject: [PATCH 407/496] Add support for aliases (#5342) * Support new aniview bid adapter * Support new aniview bid adapter * Support new aniview bid adapter * Support new aniview bid adapter * Fix Consent parameters * Update aniviewBidAdapter.js V3 support * Update aniviewBidAdapter.js * Update aniviewBidAdapter.js Update refererInfo * Update aniviewBidAdapter.js Fix tabs and spaces * Update aniviewBidAdapter.js fixes * Update aniviewBidAdapter.js * Update aniviewBidAdapter.js Add ccpa support * Update aniviewBidAdapter.js Typo * Update aniviewBidAdapter.js * Update aniviewBidAdapter.js * Fix size and sample Fixed sizes from playerSize Updated md sample * Fix tabs * Fix sizes * Recheck * Add tgt parameter * Update sample * Add support for cookie sync + tests * Add support for cookie sync + tests * Add support for cookie sync + tests * Support aliases Support aliases * Update Update * Fix lint Fix lint * Update spec Update spec --- modules/aniviewBidAdapter.js | 5 +++-- test/spec/modules/aniviewBidAdapter_spec.js | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/aniviewBidAdapter.js b/modules/aniviewBidAdapter.js index 50c403350dd..f0fab83aeea 100644 --- a/modules/aniviewBidAdapter.js +++ b/modules/aniviewBidAdapter.js @@ -24,8 +24,9 @@ function avRenderer(bid) { } function newRenderer(bidRequest) { + let playerDomain = bidRequest && bidRequest.bidRequest && bidRequest.bidRequest.params && bidRequest.bidRequest.params.playerDomain ? bidRequest.bidRequest.params.playerDomain : 'player.aniview.com'; const renderer = Renderer.install({ - url: 'https://player.aniview.com/script/6.1/prebidRenderer.js', + url: 'https://' + playerDomain + '/script/6.1/prebidRenderer.js', config: {}, loaded: false, }); @@ -167,7 +168,6 @@ function interpretResponse(serverResponse, bidRequest) { let cpmData = getCpmData(xml); if (cpmData && cpmData.cpm > 0) { bidResponse.requestId = bidRequest.data.bidId; - bidResponse.bidderCode = BIDDER_CODE; bidResponse.ad = ''; bidResponse.cpm = cpmData.cpm; bidResponse.width = bidRequest.data.AV_WIDTH; @@ -252,6 +252,7 @@ function getUserSyncs(syncOptions, serverResponses) { export const spec = { code: BIDDER_CODE, + aliases: ['selectmediavideo'], supportedMediaTypes: [VIDEO], isBidRequestValid, buildRequests, diff --git a/test/spec/modules/aniviewBidAdapter_spec.js b/test/spec/modules/aniviewBidAdapter_spec.js index 0161652505c..cca175c3388 100644 --- a/test/spec/modules/aniviewBidAdapter_spec.js +++ b/test/spec/modules/aniviewBidAdapter_spec.js @@ -41,7 +41,6 @@ describe('ANIVIEW Bid Adapter Test', function () { }); describe('buildRequests', function () { - const ENDPOINT = 'https://v.lkqd.net/ad'; let bid2Requests = [ { 'bidder': 'aniview', @@ -156,7 +155,6 @@ describe('ANIVIEW Bid Adapter Test', function () { expect(bidResponses.length).to.equal(1); let bidResponse = bidResponses[0]; expect(bidResponse.requestId).to.equal(bidRequest.data.bidId); - expect(bidResponse.bidderCode).to.equal(BIDDER_CODE); expect(bidResponse.cpm).to.equal('2'); expect(bidResponse.ttl).to.equal(600); expect(bidResponse.currency).to.equal('USD'); From 577c9ae8b64f2d05b8aa2b7db402f9e8cfa88f40 Mon Sep 17 00:00:00 2001 From: Chris Cole Date: Thu, 11 Jun 2020 09:45:52 -0700 Subject: [PATCH 408/496] =?UTF-8?q?Fix=20to=20issue=20#5141=20exception=20?= =?UTF-8?q?thrown=20in=20pbjs.requestBids=20when=20DigiTrus=E2=80=A6=20(#5?= =?UTF-8?q?333)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix to issue #5141 exception thrown in pbjs.requestBids when DigiTrust does not init. Safe extract value of id or null. * Code syntax change to overcome linter issue. --- modules/userId/eids.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/userId/eids.js b/modules/userId/eids.js index 5ca9e40866b..c088e51c74b 100644 --- a/modules/userId/eids.js +++ b/modules/userId/eids.js @@ -64,8 +64,12 @@ const USER_IDS_CONFIG = { // DigiTrust 'digitrustid': { - getValue: function(data) { - return data.data.id; + getValue: function (data) { + var id = null; + if (data && data.data && data.data.id != null) { + id = data.data.id; + } + return id; }, source: 'digitru.st', atype: 1 From b3dedca97b381bd7c0f7dc432be3098997ef78f8 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Thu, 11 Jun 2020 09:59:23 -0700 Subject: [PATCH 409/496] PubMatic analytics adapter to support bidCpmAdustment values (#5354) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * set gross ecpm using originalCpm * using bidGrossCpmUSD to set eg * lint * fixed old cases * added some tests * removed comments * removed commented code , and unused import * en related changes in test cases * using pbjs.getHighestCpmBids, added test cases around it * passing highestCpmBids * fixed test cases * added notes * using getGlobal() instead of $$PREBID_GLOBAL$$ --- modules/pubmaticAnalyticsAdapter.js | 50 +++---- modules/pubmaticAnalyticsAdapter.md | 3 +- .../modules/pubmaticAnalyticsAdapter_spec.js | 133 +++++++++++++++++- 3 files changed, 156 insertions(+), 30 deletions(-) diff --git a/modules/pubmaticAnalyticsAdapter.js b/modules/pubmaticAnalyticsAdapter.js index 9d2f45159e9..a19c6f095ad 100755 --- a/modules/pubmaticAnalyticsAdapter.js +++ b/modules/pubmaticAnalyticsAdapter.js @@ -4,6 +4,7 @@ import CONSTANTS from '../src/constants.json'; import { ajax } from '../src/ajax.js'; import { config } from '../src/config.js'; import * as utils from '../src/utils.js'; +import { getGlobal } from '../src/prebidGlobal.js'; /// /////////// CONSTANTS ////////////// const ADAPTER_CODE = 'pubmatic'; @@ -124,7 +125,19 @@ function parseBidResponse(bid) { if (typeof bid.getCpmInNewCurrency === 'function') { return window.parseFloat(Number(bid.getCpmInNewCurrency(CURRENCY_USD)).toFixed(BID_PRECISION)); } - utils.logWarn(LOG_PRE_FIX + 'Could not determine the bidPriceUSD of the bid ', bid); + utils.logWarn(LOG_PRE_FIX + 'Could not determine the Net cpm in USD for the bid thus using bid.cpm', bid); + return bid.cpm + }, + 'bidGrossCpmUSD', () => { + if (typeof bid.originalCurrency === 'string' && bid.originalCurrency.toUpperCase() === CURRENCY_USD) { + return window.parseFloat(Number(bid.originalCpm).toFixed(BID_PRECISION)); + } + // use currency conversion function if present + if (typeof getGlobal().convertCurrency === 'function') { + return window.parseFloat(Number(getGlobal().convertCurrency(bid.originalCpm, bid.originalCurrency, CURRENCY_USD)).toFixed(BID_PRECISION)); + } + utils.logWarn(LOG_PRE_FIX + 'Could not determine the Gross cpm in USD for the bid, thus using bid.originalCpm', bid); + return bid.originalCpm }, 'dealId', 'currency', @@ -152,20 +165,8 @@ function getDomainFromUrl(url) { return a.hostname; } -function getHighestBidForAdUnit(adUnit) { - return Object.keys(adUnit.bids).reduce(function(currentHighestBid, bidId) { - // todo: later we will need to consider grossECPM and netECPM - let bid = adUnit.bids[bidId]; - if (bid.bidResponse && bid.bidResponse.bidPriceUSD > currentHighestBid.bidPriceUSD) { - currentHighestBid.bidPriceUSD = bid.bidResponse.bidPriceUSD; - currentHighestBid.bidId = bidId; - } - return currentHighestBid; - }, {bidId: '', bidPriceUSD: 0}); -} - -function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId) { - const highestsBid = getHighestBidForAdUnit(adUnit); +function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) { + highestBid = (highestBid && highestBid.length > 0) ? highestBid[0] : null; return Object.keys(adUnit.bids).reduce(function(partnerBids, bidId) { let bid = adUnit.bids[bidId]; partnerBids.push({ @@ -175,16 +176,15 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId) { 'kgpv': bid.params.kgpv ? bid.params.kgpv : adUnitId, 'kgpsv': bid.params.kgpv ? bid.params.kgpv : adUnitId, 'psz': bid.bidResponse ? (bid.bidResponse.dimensions.width + 'x' + bid.bidResponse.dimensions.height) : '0x0', - 'eg': bid.bidResponse ? bid.bidResponse.bidPriceUSD : 0, // todo: later we will need to consider grossECPM and netECPM, precision - 'en': bid.bidResponse ? bid.bidResponse.bidPriceUSD : 0, // todo: later we will need to consider grossECPM and netECPM, precision + 'eg': bid.bidResponse ? bid.bidResponse.bidGrossCpmUSD : 0, + 'en': bid.bidResponse ? bid.bidResponse.bidPriceUSD : 0, 'di': bid.bidResponse ? (bid.bidResponse.dealId || EMPTY_STRING) : EMPTY_STRING, 'dc': bid.bidResponse ? (bid.bidResponse.dealChannel || EMPTY_STRING) : EMPTY_STRING, 'l1': bid.bidResponse ? bid.clientLatencyTimeMs : 0, 'l2': 0, - // 'ss': (bid.source === 'server' ? 1 : 0), // todo: is there any special handling required as per OW? 'ss': (s2sBidders.indexOf(bid.bidder) > -1) ? 1 : 0, 't': (bid.status == ERROR && bid.error.code == TIMEOUT_ERROR) ? 1 : 0, - 'wb': highestsBid.bidId === bid.bidId ? 1 : 0, + 'wb': (highestBid && highestBid.requestId === bid.bidId ? 1 : 0), 'mi': bid.bidResponse ? (bid.bidResponse.mi || undefined) : undefined, 'af': bid.bidResponse ? (bid.bidResponse.mediaType || undefined) : undefined, 'ocpm': bid.bidResponse ? (bid.bidResponse.originalCpm || 0) : 0, @@ -194,7 +194,8 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId) { }, []) } -function executeBidsLoggerCall(auctionId) { +function executeBidsLoggerCall(e, highestCpmBids) { + let auctionId = e.auctionId; let referrer = config.getConfig('pageUrl') || cache.auctions[auctionId].referer || ''; let auctionCache = cache.auctions[auctionId]; let outputObj = { s: [] }; @@ -230,7 +231,7 @@ function executeBidsLoggerCall(auctionId) { let slotObject = { 'sn': adUnitId, 'sz': adUnit.dimensions.map(e => e[0] + 'x' + e[1]), - 'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId) + 'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId)) }; slotsArray.push(slotObject); return slotsArray; @@ -263,8 +264,8 @@ function executeBidWonLoggerCall(auctionId, adUnitId) { pixelURL += '&pdvid=' + enc(profileVersionId); pixelURL += '&slot=' + enc(adUnitId); pixelURL += '&pn=' + enc(winningBid.bidder); - pixelURL += '&en=' + enc(winningBid.bidResponse.bidPriceUSD); // todo: later we will need to consider grossECPM and netECPM - pixelURL += '&eg=' + enc(winningBid.bidResponse.bidPriceUSD); // todo: later we will need to consider grossECPM and netECPM + pixelURL += '&en=' + enc(winningBid.bidResponse.bidPriceUSD); + pixelURL += '&eg=' + enc(winningBid.bidResponse.bidGrossCpmUSD); pixelURL += '&kgpv=' + enc(winningBid.params.kgpv || adUnitId); ajax( pixelURL, @@ -345,8 +346,9 @@ function bidWonHandler(args) { function auctionEndHandler(args) { // if for the given auction bidderDonePendingCount == 0 then execute logger call sooners + let highestCpmBids = getGlobal().getHighestCpmBids() || []; setTimeout(() => { - executeBidsLoggerCall.call(this, args.auctionId); + executeBidsLoggerCall.call(this, args, highestCpmBids); }, (cache.auctions[args.auctionId].bidderDonePendingCount === 0 ? 500 : SEND_TIMEOUT)); } diff --git a/modules/pubmaticAnalyticsAdapter.md b/modules/pubmaticAnalyticsAdapter.md index 9685f758ea2..097f0b3d792 100644 --- a/modules/pubmaticAnalyticsAdapter.md +++ b/modules/pubmaticAnalyticsAdapter.md @@ -20,5 +20,4 @@ pbjs.enableAnalytics({ - Supports only Banner and Video media-type - Does not supports Native media type - Does not supports instream-video creative-render tracker -- BidCpmAdjustment: Bid CPM only after BidCpmAdjustment is logged -- If a currency module is NOT included and a bidder responds in a non-USD currency then PubMatic analytics bidder will not be able to log the bid CPM \ No newline at end of file +- If a currency module is NOT included and a bidder responds in a non-USD currency then PubMatic analytics bidder will log values in original bid currency otherwise always logged in USD \ No newline at end of file diff --git a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js index e9d23692d23..bb9aa20f1b4 100755 --- a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +++ b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js @@ -293,6 +293,10 @@ describe('pubmatic analytics adapter', function () { }); it('Logger: best case + win tracker', function() { + sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => { + return [MOCK.BID_RESPONSE[0], MOCK.BID_RESPONSE[1]] + }); + events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); @@ -387,6 +391,122 @@ describe('pubmatic analytics adapter', function () { expect(data.en).to.equal('1.23'); }); + it('bidCpmAdjustment: USD: Logger: best case + win tracker', function() { + const bidCopy = utils.deepClone(BID); + bidCopy.cpm = bidCopy.originalCpm * 2; // bidCpmAdjustment => bidCpm * 2 + + sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => { + return [bidCopy, MOCK.BID_RESPONSE[1]] + }); + + events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); + events.emit(BID_RESPONSE, bidCopy); + events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); + events.emit(BID_RESPONSE, bidCopy); + events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); + events.emit(AUCTION_END, MOCK.AUCTION_END); + events.emit(SET_TARGETING, MOCK.SET_TARGETING); + events.emit(BID_WON, MOCK.BID_WON[0]); + events.emit(BID_WON, MOCK.BID_WON[1]); + + clock.tick(2000 + 1000); + expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker + let request = requests[2]; // logger is executed late, trackers execute first + expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999&gdEn=1'); + let data = getLoggerJsonFromRequest(request.requestBody); + expect(data.pubid).to.equal('9999'); + expect(data.pid).to.equal('1111'); + expect(data.s).to.be.an('array'); + expect(data.s.length).to.equal(2); + // slot 1 + expect(data.s[0].sn).to.equal('/19968336/header-bid-tag-0'); + expect(data.s[0].sz).to.deep.equal(['640x480']); + expect(data.s[0].ps).to.be.an('array'); + expect(data.s[0].ps.length).to.equal(1); + expect(data.s[0].ps[0].pn).to.equal('pubmatic'); + expect(data.s[0].ps[0].bidid).to.equal('2ecff0db240757'); + expect(data.s[0].ps[0].kgpv).to.equal('/19968336/header-bid-tag-0'); + expect(data.s[0].ps[0].eg).to.equal(1.23); + expect(data.s[0].ps[0].en).to.equal(2.46); + expect(data.s[0].ps[0].wb).to.equal(1); + expect(data.s[0].ps[0].af).to.equal('video'); + expect(data.s[0].ps[0].ocpm).to.equal(1.23); + expect(data.s[0].ps[0].ocry).to.equal('USD'); + // tracker slot1 + let firstTracker = requests[0].url; + expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); + data = {}; + firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]); + expect(data.pubid).to.equal('9999'); + expect(data.tst).to.equal('1519767014'); + expect(data.iid).to.equal('25c6d7f5-699a-4bfc-87c9-996f915341fa'); + expect(data.eg).to.equal('1.23'); + expect(data.en).to.equal('2.46'); + }); + + it('bidCpmAdjustment: JPY: Logger: best case + win tracker', function() { + setConfig({ + adServerCurrency: 'JPY', + rates: { + USD: { + JPY: 100 + } + } + }); + const bidCopy = utils.deepClone(BID); + bidCopy.originalCpm = 100; + bidCopy.originalCurrency = 'JPY'; + bidCopy.currency = 'JPY'; + bidCopy.cpm = bidCopy.originalCpm * 2; // bidCpmAdjustment => bidCpm * 2 + + events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); + // events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); + events.emit(BID_RESPONSE, bidCopy); + events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); + events.emit(BID_RESPONSE, bidCopy); + events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); + events.emit(AUCTION_END, MOCK.AUCTION_END); + events.emit(SET_TARGETING, MOCK.SET_TARGETING); + events.emit(BID_WON, MOCK.BID_WON[0]); + events.emit(BID_WON, MOCK.BID_WON[1]); + + clock.tick(2000 + 1000); + expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker + let request = requests[2]; // logger is executed late, trackers execute first + expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999&gdEn=1'); + let data = getLoggerJsonFromRequest(request.requestBody); + expect(data.pubid).to.equal('9999'); + expect(data.pid).to.equal('1111'); + expect(data.s).to.be.an('array'); + expect(data.s.length).to.equal(2); + // slot 1 + expect(data.s[0].sn).to.equal('/19968336/header-bid-tag-0'); + expect(data.s[0].sz).to.deep.equal(['640x480']); + expect(data.s[0].ps).to.be.an('array'); + expect(data.s[0].ps.length).to.equal(1); + expect(data.s[0].ps[0].pn).to.equal('pubmatic'); + expect(data.s[0].ps[0].bidid).to.equal('2ecff0db240757'); + expect(data.s[0].ps[0].kgpv).to.equal('/19968336/header-bid-tag-0'); + expect(data.s[0].ps[0].eg).to.equal(1); + expect(data.s[0].ps[0].en).to.equal(200); + expect(data.s[0].ps[0].wb).to.equal(0); // bidPriceUSD is not getting set as currency module is not added, so unable to set wb to 1 + expect(data.s[0].ps[0].af).to.equal('video'); + expect(data.s[0].ps[0].ocpm).to.equal(100); + expect(data.s[0].ps[0].ocry).to.equal('JPY'); + // tracker slot1 + let firstTracker = requests[0].url; + expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); + data = {}; + firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]); + expect(data.pubid).to.equal('9999'); + expect(data.tst).to.equal('1519767014'); + expect(data.iid).to.equal('25c6d7f5-699a-4bfc-87c9-996f915341fa'); + expect(data.eg).to.equal('1'); + expect(data.en).to.equal('200'); // bidPriceUSD is not getting set as currency module is not added + }); + it('Logger: when bid is not submitted, default bid status 1 check: pubmatic set as s2s', function() { events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); @@ -463,6 +583,11 @@ describe('pubmatic analytics adapter', function () { it('Logger: post-timeout check with bid response', function() { // db = 1 and t = 1 means bidder did NOT respond with a bid but we got a timeout notification + + sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => { + return [MOCK.BID_RESPONSE[1]] + }); + events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); @@ -492,7 +617,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].ps[0].l2).to.equal(0); expect(data.s[1].ps[0].ss).to.equal(1); expect(data.s[1].ps[0].t).to.equal(1); - expect(data.s[1].ps[0].wb).to.equal(1); + expect(data.s[1].ps[0].wb).to.equal(1); // todo expect(data.s[1].ps[0].af).to.equal('banner'); expect(data.s[1].ps[0].ocpm).to.equal(1.52); expect(data.s[1].ps[0].ocry).to.equal('USD'); @@ -538,8 +663,8 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].ps[0].kgpv).to.equal('this-is-a-kgpv'); expect(data.s[1].ps[0].kgpsv).to.equal('this-is-a-kgpv'); expect(data.s[1].ps[0].psz).to.equal('728x90'); - expect(data.s[1].ps[0].eg).to.equal(undefined); // bidPriceUSD is not getting set as currency module is not added - expect(data.s[1].ps[0].en).to.equal(undefined); // bidPriceUSD is not getting set as currency module is not added + expect(data.s[1].ps[0].eg).to.equal(1); + expect(data.s[1].ps[0].en).to.equal(100); expect(data.s[1].ps[0].di).to.equal('the-deal-id'); expect(data.s[1].ps[0].dc).to.equal('PMP'); expect(data.s[1].ps[0].mi).to.equal('matched-impression'); @@ -552,5 +677,5 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].ps[0].ocpm).to.equal(100); expect(data.s[1].ps[0].ocry).to.equal('JPY'); }); - }) + }); }); From 487fc297f073e6289636810f5fcfa1aa1745efd0 Mon Sep 17 00:00:00 2001 From: Eric Harper Date: Thu, 11 Jun 2020 15:32:02 -0400 Subject: [PATCH 410/496] Prebid 3.23.0 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 84cc5931495..dc5924e97fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.23.0-pre", + "version": "3.23.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From fc8bee80a8c9f32bac1769aec6fa978921ae711a Mon Sep 17 00:00:00 2001 From: Eric Harper Date: Thu, 11 Jun 2020 16:13:52 -0400 Subject: [PATCH 411/496] increment prebid version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dc5924e97fb..c84e354bd1b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.23.0", + "version": "3.24.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From f326ad679603bfb09639b9ce8b35e965b1d4a25f Mon Sep 17 00:00:00 2001 From: lowendavid <66423906+lowendavid@users.noreply.github.com> Date: Fri, 12 Jun 2020 06:11:32 +0200 Subject: [PATCH 412/496] improveStartDelay after documentation update default value is now 1 and 0 does not exist. (#5361) --- modules/smartadserverBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/smartadserverBidAdapter.js b/modules/smartadserverBidAdapter.js index bff592383a4..15808a516c8 100644 --- a/modules/smartadserverBidAdapter.js +++ b/modules/smartadserverBidAdapter.js @@ -88,7 +88,7 @@ export const spec = { videoProtocol: bid.params.video.protocol, playerWidth: playerSize[0], playerHeight: playerSize[1], - adBreak: bid.params.video.startDelay || 0 + adBreak: bid.params.video.startDelay || 1 }; } else { return {}; From d884d4092cc256c40cdde59b89736580c1828e51 Mon Sep 17 00:00:00 2001 From: bretg Date: Fri, 12 Jun 2020 01:30:12 -0400 Subject: [PATCH 413/496] Updating docs header info fields (#5366) Related to https://github.com/prebid/prebid.github.io/pull/2056 --- PR_REVIEW.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/PR_REVIEW.md b/PR_REVIEW.md index 3af98f37be0..dac50593d6e 100644 --- a/PR_REVIEW.md +++ b/PR_REVIEW.md @@ -15,12 +15,15 @@ For modules and core platform updates, the initial reviewer should request an ad - If the change is a new feature / change to core prebid.js - review the change with a Tech Lead on the project and make sure they agree with the nature of change. - If the change results in needing updates to docs (such as public API change, module interface etc), add a label for "needs docs" and inform the submitter they must submit a docs PR to update the appropriate area of Prebid.org **before the PR can merge**. Help them with finding where the docs are located on prebid.org if needed. - Below are some examples of bidder specific updates that should require docs update (in their dev-docs/bidders/bidder.md file): - - Add support for GDPR consentManagement module > add `gdpr_supported: true` - - Add support for US Privacy consentManagement module > add `usp_supported: true` - - Add support for userId module > add `userId: pubCommon, digitrust, newProviderHere` - - Add support for video and/or native mediaTypes > add `media_types: video, native` - - Add support for COPPA > add `coppa_supported: true` - - Add support for SChain > add `schain_supported: true` + - If they support the GDPR consentManagement module and TCF1, add `gdpr_supported: true` + - If they support the GDPR consentManagement module and TCF2, add `tcf2_supported: true` + - If they support the US Privacy consentManagementUsp module, add `usp_supported: true` + - If they support one or more userId modules, add `userId: (list of supported vendors)` + - If they support video and/or native mediaTypes add `media_types: video, native`. Note that display is added by default. If you don't support display, add "no-display" as the first entry, e.g. `media_types: no-display, native` + - If they support COPPA, add `coppa_supported: true` + - If they support SChain, add `schain_supported: true` + - If their bidder doesn't work well with safeframed creatives, add `safeframes_ok: false`. This will alert publishers to not use safeframed creatives when creating the ad server entries for their bidder. + - If they're a member of Prebid.org, add `prebid_member: true` - If all above is good, add a `LGTM` comment and request 1 additional core member to review. - Once there is 2 `LGTM` on the PR, merge to master - Ask the submitter to add a PR for documentation if applicable. From f99eb51be6a317f8a9b2c2988a69b8bdbabc6d15 Mon Sep 17 00:00:00 2001 From: Nick Peceniak Date: Thu, 11 Jun 2020 23:30:56 -0600 Subject: [PATCH 414/496] Add placement_type and position parameters to spotxBidAdapter (#5364) * Add min_duration and max_duration parameter to spotxBidAdapter * Add placement_type and position parameters to spotxBidAdapter Co-authored-by: Nick Peceniak --- modules/spotxBidAdapter.js | 8 ++++++++ test/spec/modules/spotxBidAdapter_spec.js | 20 ++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/modules/spotxBidAdapter.js b/modules/spotxBidAdapter.js index 515360d482e..1733a176eba 100644 --- a/modules/spotxBidAdapter.js +++ b/modules/spotxBidAdapter.js @@ -168,6 +168,14 @@ export const spec = { spotxReq.video.maxduration = utils.getBidIdParameter('max_duration', bid.params); } + if (utils.getBidIdParameter('placement_type', bid.params) != '') { + spotxReq.video.ext.placement = utils.getBidIdParameter('placement_type', bid.params); + } + + if (utils.getBidIdParameter('position', bid.params) != '') { + spotxReq.video.ext.pos = utils.getBidIdParameter('position', bid.params); + } + if (bid.crumbs && bid.crumbs.pubcid) { pubcid = bid.crumbs.pubcid; } diff --git a/test/spec/modules/spotxBidAdapter_spec.js b/test/spec/modules/spotxBidAdapter_spec.js index 56936dcfc62..78d17f35c69 100644 --- a/test/spec/modules/spotxBidAdapter_spec.js +++ b/test/spec/modules/spotxBidAdapter_spec.js @@ -146,7 +146,9 @@ describe('the spotx adapter', function () { number_of_ads: 2, spotx_all_google_consent: 1, min_duration: 5, - max_duration: 10 + max_duration: 10, + placement_type: 1, + position: 1 }; bid.userId = { @@ -183,7 +185,9 @@ describe('the spotx adapter', function () { outstream_function: '987', custom: {bar: 'foo'}, sdk_name: 'Prebid 1+', - versionOrtb: '2.3' + versionOrtb: '2.3', + placement: 1, + pos: 1 }); expect(request.data.imp.video.startdelay).to.equal(1); @@ -315,6 +319,18 @@ describe('the spotx adapter', function () { expect(request.data.imp.video.minduration).to.equal(3); expect(request.data.imp.video.maxduration).to.equal(15); }); + + it('should pass placement_type and position params', function() { + var request; + + bid.params.placement_type = 2 + bid.params.position = 5 + + request = spec.buildRequests([bid], bidRequestObj)[0]; + + expect(request.data.imp.video.ext.placement).to.equal(2); + expect(request.data.imp.video.ext.pos).to.equal(5); + }); }); describe('interpretResponse', function() { From 18fc232123b5f7f6be82282b2065190abc08debc Mon Sep 17 00:00:00 2001 From: Denis Logachov Date: Fri, 12 Jun 2020 13:04:31 +0300 Subject: [PATCH 415/496] Configurable user-sync types support (#5359) --- modules/adkernelBidAdapter.js | 128 +++++++++++++++---- test/spec/modules/adkernelBidAdapter_spec.js | 95 +++++++++++++- 2 files changed, 190 insertions(+), 33 deletions(-) diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index cbd30edb432..d069af7d56e 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -1,8 +1,9 @@ import * as utils from '../src/utils.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import find from 'core-js-pure/features/array/find.js'; import includes from 'core-js-pure/features/array/includes.js'; +import {config} from '../src/config.js'; /* * In case you're AdKernel whitelable platform's client who needs branded adapter to @@ -11,10 +12,16 @@ import includes from 'core-js-pure/features/array/includes.js'; * Please contact prebid@adkernel.com and we'll add your adapter as an alias. */ -const VIDEO_TARGETING = ['mimes', 'minduration', 'maxduration', 'protocols', +const VIDEO_TARGETING = Object.freeze(['mimes', 'minduration', 'maxduration', 'protocols', 'startdelay', 'linearity', 'boxingallowed', 'playbackmethod', 'delivery', - 'pos', 'api', 'ext']; -const VERSION = '1.4'; + 'pos', 'api', 'ext']); +const VERSION = '1.5'; +const SYNC_IFRAME = 1; +const SYNC_IMAGE = 2; +const SYNC_TYPES = Object.freeze({ + 1: 'iframe', + 2: 'image' +}); const NATIVE_MODEL = [ {name: 'title', assetType: 'title'}, @@ -47,7 +54,13 @@ export const spec = { code: 'adkernel', aliases: ['headbidding', 'adsolut', 'oftmediahb', 'audiencemedia', 'waardex_ak', 'roqoon'], supportedMediaTypes: [BANNER, VIDEO, NATIVE], - isBidRequestValid: function(bidRequest) { + + /** + * Validates bid request for adunit + * @param bidRequest {BidRequest} + * @returns {boolean} + */ + isBidRequestValid: function (bidRequest) { return 'params' in bidRequest && typeof bidRequest.params.host !== 'undefined' && 'zoneId' in bidRequest.params && @@ -56,13 +69,19 @@ export const spec = { bidRequest.mediaTypes && (bidRequest.mediaTypes.banner || bidRequest.mediaTypes.video || (bidRequest.mediaTypes.native && validateNativeAdUnit(bidRequest.mediaTypes.native))); }, - buildRequests: function(bidRequests, bidderRequest) { + + /** + * Builds http request for each unique combination of adkernel host/zone + * @param bidRequests {BidRequest[]} + * @param bidderRequest {BidderRequest} + * @returns {ServerRequest[]} + */ + buildRequests: function (bidRequests, bidderRequest) { let impDispatch = dispatchImps(bidRequests, bidderRequest.refererInfo); - const {gdprConsent, auctionId, refererInfo, timeout, uspConsent} = bidderRequest; const requests = []; Object.keys(impDispatch).forEach(host => { Object.keys(impDispatch[host]).forEach(zoneId => { - const request = buildRtbRequest(impDispatch[host][zoneId], auctionId, gdprConsent, uspConsent, refererInfo, timeout); + const request = buildRtbRequest(impDispatch[host][zoneId], bidderRequest); requests.push({ method: 'POST', url: `https://${host}/hb?zone=${zoneId}&v=${VERSION}`, @@ -72,13 +91,20 @@ export const spec = { }); return requests; }, - interpretResponse: function(serverResponse, request) { + + /** + * Parse response from adkernel backend + * @param serverResponse {ServerResponse} + * @param serverRequest {ServerRequest} + * @returns {Bid[]} + */ + interpretResponse: function (serverResponse, serverRequest) { let response = serverResponse.body; if (!response.seatbid) { return []; } - let rtbRequest = JSON.parse(request.data); + let rtbRequest = JSON.parse(serverRequest.data); let rtbBids = response.seatbid .map(seatbid => seatbid.bid) .reduce((a, b) => a.concat(b), []); @@ -110,21 +136,30 @@ export const spec = { return prBid; }); }, - getUserSyncs: function(syncOptions, serverResponses) { - if (!syncOptions.iframeEnabled || !serverResponses || serverResponses.length === 0) { + + /** + * Extracts user-syncs information from server response + * @param syncOptions {SyncOptions} + * @param serverResponses {ServerResponse[]} + * @returns {UserSync[]} + */ + getUserSyncs: function (syncOptions, serverResponses) { + if (!serverResponses || serverResponses.length === 0 || (!syncOptions.iframeEnabled && !syncOptions.pixelEnabled)) { return []; } return serverResponses.filter(rsp => rsp.body && rsp.body.ext && rsp.body.ext.adk_usersync) .map(rsp => rsp.body.ext.adk_usersync) .reduce((a, b) => a.concat(b), []) - .map(syncUrl => ({type: 'iframe', url: syncUrl})); + .map(({url, type}) => ({type: SYNC_TYPES[type], url: url})); } }; registerBidder(spec); /** - * Dispatch impressions by ad network host and zone + * Dispatch impressions by ad network host and zone + * @param bidRequests {BidRequest[]} + * @param refererInfo {refererInfo} */ function dispatchImps(bidRequests, refererInfo) { let secure = (refererInfo && refererInfo.referer.indexOf('https:') === 0); @@ -140,7 +175,9 @@ function dispatchImps(bidRequests, refererInfo) { } /** - * Builds parameters object for single impression + * Builds rtb imp object for single adunit + * @param bidRequest {BidRequest} + * @param secure {boolean} */ function buildImp(bidRequest, secure) { const imp = { @@ -220,21 +257,51 @@ function buildImageAsset(desc, val) { return utils.cleanObj(img); } +/** + * Checks if configuration allows specified sync method + * @param syncRule {Object} + * @param bidderCode {string} + * @returns {boolean} + */ +function isSyncMethodAllowed(syncRule, bidderCode) { + if (!syncRule) { + return false; + } + let bidders = utils.isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode]; + let rule = syncRule.filter === 'include'; + return utils.contains(bidders, bidderCode) === rule; +} + +/** + * Get preferred user-sync method based on publisher configuration + * @param bidderCode {string} + * @returns {number|undefined} + */ +function getAllowedSyncMethod(bidderCode) { + if (!config.getConfig('userSync.syncEnabled')) { + return; + } + let filterConfig = config.getConfig('userSync.filterSettings'); + if (isSyncMethodAllowed(filterConfig.all, bidderCode) || isSyncMethodAllowed(filterConfig.iframe, bidderCode)) { + return SYNC_IFRAME; + } else if (isSyncMethodAllowed(filterConfig.image, bidderCode)) { + return SYNC_IMAGE; + } +} + /** * Builds complete rtb request - * @param imps collection of impressions - * @param auctionId - * @param gdprConsent {string=} - * @param uspConsent {string=} - * @param refInfo - * @param timeout - * @return Object complete rtb request + * @param imps {Object} Collection of rtb impressions + * @param bidderRequest {BidderRequest} + * @return {Object} Complete rtb request */ -function buildRtbRequest(imps, auctionId, gdprConsent, uspConsent, refInfo, timeout) { +function buildRtbRequest(imps, bidderRequest) { + let {bidderCode, gdprConsent, auctionId, refererInfo, timeout, uspConsent} = bidderRequest; + let req = { 'id': auctionId, 'imp': imps, - 'site': createSite(refInfo), + 'site': createSite(refererInfo), 'at': 1, 'device': { 'ip': 'caller', @@ -242,10 +309,7 @@ function buildRtbRequest(imps, auctionId, gdprConsent, uspConsent, refInfo, time 'js': 1, 'language': getLanguage() }, - 'tmax': parseInt(timeout), - 'ext': { - 'adk_usersync': 1 - } + 'tmax': parseInt(timeout) }; if (utils.getDNT()) { req.device.dnt = 1; @@ -261,9 +325,17 @@ function buildRtbRequest(imps, auctionId, gdprConsent, uspConsent, refInfo, time if (uspConsent) { utils.deepSetValue(req, 'regs.ext.us_privacy', uspConsent); } + let syncMethod = getAllowedSyncMethod(bidderCode); + if (syncMethod) { + utils.deepSetValue(req, 'ext.adk_usersync', syncMethod); + } return req; } +/** + * Get browser language + * @returns {String} + */ function getLanguage() { const language = navigator.language ? 'language' : 'userLanguage'; return navigator[language].split('-')[0]; diff --git a/test/spec/modules/adkernelBidAdapter_spec.js b/test/spec/modules/adkernelBidAdapter_spec.js index ef95febf13d..71637781f24 100644 --- a/test/spec/modules/adkernelBidAdapter_spec.js +++ b/test/spec/modules/adkernelBidAdapter_spec.js @@ -2,6 +2,7 @@ import {expect} from 'chai'; import {spec} from 'modules/adkernelBidAdapter.js'; import * as utils from 'src/utils.js'; import {NATIVE, BANNER, VIDEO} from 'src/mediaTypes'; +import {config} from 'src/config.js'; describe('Adkernel adapter', function () { const bid1_zone1 = { @@ -175,7 +176,7 @@ describe('Adkernel adapter', function () { }], cur: 'USD', ext: { - adk_usersync: ['https://adk.sync.com/sync'] + adk_usersync: [{type: 1, url: 'https://adk.sync.com/sync'}] } }, videoBidResponse = { id: '47ce4badcf7482', @@ -194,7 +195,7 @@ describe('Adkernel adapter', function () { }, usersyncOnlyResponse = { id: 'nobid1', ext: { - adk_usersync: ['https://adk.sync.com/sync'] + adk_usersync: [{type: 2, url: 'https://adk.sync.com/sync'}] } }, nativeResponse = { id: '56fbc713-b737-4651-9050-13376aed9818', @@ -229,7 +230,7 @@ describe('Adkernel adapter', function () { }; function buildBidderRequest(url = 'https://example.com/index.html', params = {}) { - return Object.assign({}, params, {refererInfo: {referer: url, reachedTop: true}, timeout: 3000}); + return Object.assign({}, params, {refererInfo: {referer: url, reachedTop: true}, timeout: 3000, bidderCode: 'adkernel'}); } const DEFAULT_BIDDER_REQUEST = buildBidderRequest(); @@ -403,6 +404,84 @@ describe('Adkernel adapter', function () { }); }); + describe('User sync request signals', function() { + it('should respect syncEnabled option', function() { + config.setConfig({ + userSync: { + syncEnabled: false, + filterSettings: { + all: { + bidders: '*', + filter: 'include' + } + } + } + }); + let [pbRequests, bidRequests] = buildRequest([bid1_zone1]); + expect(bidRequests).to.have.length(1); + expect(bidRequests[0]).to.not.have.property('ext'); + }); + + it('should respect all config node', function() { + config.setConfig({ + userSync: { + syncEnabled: true, + filterSettings: { + all: { + bidders: '*', + filter: 'include' + } + } + } + }); + let [pbRequests, bidRequests] = buildRequest([bid1_zone1]); + expect(bidRequests).to.have.length(1); + expect(bidRequests[0].ext).to.have.property('adk_usersync', 1); + }); + + it('should respect exclude filter', function() { + config.setConfig({ + userSync: { + syncEnabled: true, + filterSettings: { + image: { + bidders: '*', + filter: 'include' + }, + iframe: { + bidders: ['adkernel'], + filter: 'exclude' + } + } + } + }); + let [pbRequests, bidRequests] = buildRequest([bid1_zone1]); + expect(bidRequests).to.have.length(1); + expect(bidRequests[0].ext).to.have.property('adk_usersync', 2); + }); + + it('should respect total exclusion', function() { + config.setConfig({ + userSync: { + syncEnabled: true, + filterSettings: { + image: { + bidders: ['adkernel'], + filter: 'exclude' + }, + iframe: { + bidders: ['adkernel'], + filter: 'exclude' + } + } + } + }); + let [pbRequests, bidRequests] = buildRequest([bid1_zone1]); + expect(bidRequests).to.have.length(1); + expect(bidRequests[0]).to.not.have.property('ext'); + }); + }); + describe('responses processing', function () { it('should return fully-initialized banner bid-response', function () { let [pbRequests, _] = buildRequest([bid1_zone1]); @@ -444,12 +523,18 @@ describe('Adkernel adapter', function () { }); it('should perform usersync', function () { - let syncs = spec.getUserSyncs({iframeEnabled: false}, [{body: bidResponse1}]); + let syncs = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, []); expect(syncs).to.have.length(0); - syncs = spec.getUserSyncs({iframeEnabled: true}, [{body: bidResponse1}]); + syncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}, [{body: bidResponse1}]); + expect(syncs).to.have.length(0); + syncs = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [{body: bidResponse1}]); expect(syncs).to.have.length(1); expect(syncs[0]).to.have.property('type', 'iframe'); expect(syncs[0]).to.have.property('url', 'https://adk.sync.com/sync'); + syncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{body: usersyncOnlyResponse}]); + expect(syncs).to.have.length(1); + expect(syncs[0]).to.have.property('type', 'image'); + expect(syncs[0]).to.have.property('url', 'https://adk.sync.com/sync'); }); }); From e7a34e9f0ad9d9e73973d4dac370885dd8f1347e Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Fri, 12 Jun 2020 14:11:31 -0700 Subject: [PATCH 416/496] Delaying removal of floor data for 3 seconds (#5360) --- modules/priceFloors.js | 6 ++++-- test/spec/modules/priceFloors_spec.js | 31 +++++++++++++++++++++------ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/modules/priceFloors.js b/modules/priceFloors.js index dfc857bed6c..e84576d3474 100644 --- a/modules/priceFloors.js +++ b/modules/priceFloors.js @@ -532,8 +532,10 @@ export function handleSetFloorsConfig(config) { if (!addedFloorsHook) { // register hooks / listening events - // when auction finishes remove it's associated floor data - events.on(CONSTANTS.EVENTS.AUCTION_END, (args) => delete _floorDataForAuction[args.auctionId]); + // when auction finishes remove it's associated floor data after 3 seconds so we stil have it for latent responses + events.on(CONSTANTS.EVENTS.AUCTION_END, (args) => { + setTimeout(() => delete _floorDataForAuction[args.auctionId], 3000); + }); // we want our hooks to run after the currency hooks getGlobal().requestBids.before(requestBidsHook, 50); diff --git a/test/spec/modules/priceFloors_spec.js b/test/spec/modules/priceFloors_spec.js index 0d02b7f9772..2a816aef104 100644 --- a/test/spec/modules/priceFloors_spec.js +++ b/test/spec/modules/priceFloors_spec.js @@ -14,11 +14,13 @@ import { fieldMatchingFunctions, allowedFields } from 'modules/priceFloors.js'; +import events from 'src/events.js'; describe('the price floors module', function () { let logErrorSpy; let logWarnSpy; let sandbox; + let clock; const basicFloorData = { modelVersion: 'basic model', currency: 'USD', @@ -58,12 +60,14 @@ describe('the price floors module', function () { }; } beforeEach(function() { + clock = sinon.useFakeTimers(); sandbox = sinon.sandbox.create(); logErrorSpy = sinon.spy(utils, 'logError'); logWarnSpy = sinon.spy(utils, 'logWarn'); }); afterEach(function() { + clock.restore(); handleSetFloorsConfig({enabled: false}); sandbox.restore(); utils.logError.restore(); @@ -288,17 +292,10 @@ describe('the price floors module', function () { }); }; let fakeFloorProvider; - let clock; let actualAllowedFields = allowedFields; let actualFieldMatchingFunctions = fieldMatchingFunctions; const defaultAllowedFields = [...allowedFields]; const defaultMatchingFunctions = {...fieldMatchingFunctions}; - before(function () { - clock = sinon.useFakeTimers(); - }); - after(function () { - clock.restore(); - }); beforeEach(function() { fakeFloorProvider = sinon.fakeServer.create(); }); @@ -1056,4 +1053,24 @@ describe('the price floors module', function () { expect(returnedBidResponse.cpm).to.equal(7.5); }); }); + + describe('Post Auction Tests', function () { + let AUCTION_END_EVENT; + beforeEach(function () { + AUCTION_END_EVENT = { + auctionId: '123-45-6789' + }; + }); + it('should wait 3 seconds before deleting auction floor data', function () { + handleSetFloorsConfig({enabled: true}); + _floorDataForAuction[AUCTION_END_EVENT.auctionId] = utils.deepClone(basicFloorConfig); + events.emit(CONSTANTS.EVENTS.AUCTION_END, AUCTION_END_EVENT); + // should still be here + expect(_floorDataForAuction[AUCTION_END_EVENT.auctionId]).to.not.be.undefined; + // tick for 4 seconds + clock.tick(4000); + // should be undefined now + expect(_floorDataForAuction[AUCTION_END_EVENT.auctionId]).to.be.undefined; + }); + }); }); From 80832390c7d8546b89cc7fd07a9447c629e4bd90 Mon Sep 17 00:00:00 2001 From: "Isaac A. Dettman" Date: Fri, 12 Jun 2020 14:16:26 -0700 Subject: [PATCH 417/496] PBS Bid Adapter: allow setting site params (#4973) * add site config value to oRTB request * update to copy site.page and site.publisher.id if not defined in config site object --- modules/prebidServerBidAdapter/index.js | 12 +++- .../modules/prebidServerBidAdapter_spec.js | 55 ++++++++++++++++++- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js index 5794dc86f3a..96986ed185c 100644 --- a/modules/prebidServerBidAdapter/index.js +++ b/modules/prebidServerBidAdapter/index.js @@ -269,11 +269,17 @@ function _appendSiteAppDevice(request, pageUrl) { request.app.publisher = {id: _s2sConfig.accountId} } else { request.site = {}; - if (typeof config.getConfig('site') === 'object') { + if (utils.isPlainObject(config.getConfig('site'))) { request.site = config.getConfig('site'); } - utils.deepSetValue(request.site, 'publisher.id', _s2sConfig.accountId); - request.site.page = pageUrl; + // set publisher.id if not already defined + if (!utils.deepAccess(request.site, 'publisher.id')) { + utils.deepSetValue(request.site, 'publisher.id', _s2sConfig.accountId); + } + // set site.page if not already defined + if (!request.site.page) { + request.site.page = pageUrl; + } } if (typeof config.getConfig('device') === 'object') { request.device = config.getConfig('device'); diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index f66c87582f5..b4544a2ec48 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -925,7 +925,7 @@ describe('S2S Adapter', function () { expect(requestBid.site.content.language).to.exist.and.to.be.a('string'); expect(requestBid.site).to.deep.equal({ publisher: { - id: '1', + id: '1234', domain: 'test.com' }, content: { @@ -1095,6 +1095,59 @@ describe('S2S Adapter', function () { expect(requestBid.imp[0].ext.appnexus.key).to.be.equal('value') }); + describe('config site value is added to the oRTB request', function () { + const s2sConfig = Object.assign({}, CONFIG, { + endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', + adapterOptions: { + appnexus: { + key: 'value' + } + } + }); + const device = { + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36', + ip: '75.97.0.47' + }; + + it('and overrides publisher and page', function () { + config.setConfig({ + s2sConfig: s2sConfig, + site: { + domain: 'nytimes.com', + page: 'http://www.nytimes.com', + publisher: { id: '2' } + }, + device: device + }); + adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); + const requestBid = JSON.parse(server.requests[0].requestBody); + + expect(requestBid.site).to.exist.and.to.be.a('object'); + expect(requestBid.site.domain).to.equal('nytimes.com'); + expect(requestBid.site.page).to.equal('http://www.nytimes.com'); + expect(requestBid.site.publisher).to.exist.and.to.be.a('object'); + expect(requestBid.site.publisher.id).to.equal('2'); + }); + + it('and merges domain and page with the config site value', function () { + config.setConfig({ + s2sConfig: s2sConfig, + site: { + foo: 'bar' + }, + device: device + }); + adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); + + const requestBid = JSON.parse(server.requests[0].requestBody); + expect(requestBid.site).to.exist.and.to.be.a('object'); + expect(requestBid.site.foo).to.equal('bar'); + expect(requestBid.site.page).to.equal('http://mytestpage.com'); + expect(requestBid.site.publisher).to.exist.and.to.be.a('object'); + expect(requestBid.site.publisher.id).to.equal('1'); + }); + }); + it('when userId is defined on bids, it\'s properties should be copied to user.ext.tpid properties', function () { let ortb2Config = utils.deepClone(CONFIG); ortb2Config.endpoint = 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'; From 12c989ceb513d6eba05e70c3234f84720717680c Mon Sep 17 00:00:00 2001 From: Tim Sturtewagen Date: Mon, 15 Jun 2020 18:14:18 +0200 Subject: [PATCH 418/496] Support for ID5 (#5345) * Add support for bidderRequest.refererInfo in Adhese Adapter. * Add support for bidderRequest.refererInfo in Adhese Adapter. * Jira AD-2462 / add tlall is consent string is present * Added 'adhese' attribute to bid that contains meta data - Jira AD-2642 * added DALE to adhese determination * extra config option: no format, but use size array as format string * Added more values to originData * Revert "Added more values to originData" This reverts commit 57f003318cfb7dc2f9d1a97015a7639823b181a6. * Pulled Sander's changes & added more data to originData * Adhese bid adapter - final version * add origin and originInstance make ad.origin and ad.originInstance * add id5 id to request as x5 * Add support for bidderRequest.refererInfo in Adhese Adapter. * added DALE to adhese determination * updated tests to include new fields * Added test for ID5 id Co-authored-by: Mateusz Michalowski Co-authored-by: Mateusz Michalowski Co-authored-by: Tim Sturtewagen Co-authored-by: Kim Van Crombrugge Co-authored-by: Sander Co-authored-by: westerschmal <30859973+westerschmal@users.noreply.github.com> --- modules/adheseBidAdapter.js | 21 +++++++++++++++++---- test/spec/modules/adheseBidAdapter_spec.js | 20 ++++++++++++++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js index 96a2b52fb9c..3c129d1bee1 100644 --- a/modules/adheseBidAdapter.js +++ b/modules/adheseBidAdapter.js @@ -24,9 +24,10 @@ export const spec = { const targets = validBidRequests.map(bid => bid.params.data).reduce(mergeTargets, {}); const gdprParams = (gdprConsent && gdprConsent.consentString) ? [`xt${gdprConsent.consentString}`] : []; const refererParams = (refererInfo && refererInfo.referer) ? [`xf${base64urlEncode(refererInfo.referer)}`] : []; + const id5Params = (getId5Id(validBidRequests)) ? [`x5${getId5Id(validBidRequests)}`] : []; const targetsParams = Object.keys(targets).map(targetCode => targetCode + targets[targetCode].join(';')); const slotsParams = validBidRequests.map(bid => 'sl' + bidToSlotName(bid)); - const params = [...slotsParams, ...targetsParams, ...gdprParams, ...refererParams].map(s => `/${s}`).join(''); + const params = [...slotsParams, ...targetsParams, ...gdprParams, ...refererParams, ...id5Params].map(s => `/${s}`).join(''); const cacheBuster = '?t=' + new Date().getTime(); const uri = 'https://ads-' + account + '.adhese.com/json' + params + cacheBuster; @@ -85,7 +86,9 @@ function adResponse(bid, ad) { creativeId: adDetails.creativeId, dealId: adDetails.dealId, adhese: { - originData: adDetails.originData + originData: adDetails.originData, + origin: adDetails.origin, + originInstance: adDetails.originInstance } }); @@ -134,12 +137,18 @@ function getAccount(validBidRequests) { return validBidRequests[0].params.account; } +function getId5Id(validBidRequests) { + if (validBidRequests[0] && validBidRequests[0].userId && validBidRequests[0].userId.id5id) { + return validBidRequests[0].userId.id5id; + } +} + function getbaseAdResponse(response) { return Object.assign({ netRevenue: true, ttl: 360 }, response); } function isAdheseAd(ad) { - return !ad.origin || ad.origin === 'JERLICIA'; + return !ad.origin || ad.origin === 'JERLICIA' || ad.origin === 'DALE'; } function getMediaType(markup) { @@ -166,6 +175,8 @@ function getAdDetails(ad) { let creativeId = ''; let dealId = ''; let originData = {}; + let origin = ''; + let originInstance = ''; if (isAdheseAd(ad)) { creativeId = ad.id; @@ -188,8 +199,10 @@ function getAdDetails(ad) { } } } + if (ad.originInstance) originInstance = ad.originInstance; + if (ad.origin) origin = ad.origin; } - return { creativeId: creativeId, dealId: dealId, originData: originData }; + return { creativeId: creativeId, dealId: dealId, originData: originData, origin: origin, originInstance: originInstance }; } function base64urlEncode(s) { diff --git a/test/spec/modules/adheseBidAdapter_spec.js b/test/spec/modules/adheseBidAdapter_spec.js index 7392ecd8f4e..def504b0424 100644 --- a/test/spec/modules/adheseBidAdapter_spec.js +++ b/test/spec/modules/adheseBidAdapter_spec.js @@ -17,9 +17,10 @@ let minimalBid = function() { } }; -let bidWithParams = function(data) { +let bidWithParams = function(data, userId) { let bid = minimalBid(); bid.params.data = data; + bid.userId = userId; return bid; }; @@ -100,6 +101,12 @@ describe('AdheseAdapter', function () { expect(req.url).to.contain('/xfaHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc3ViamVjdHM_X2Q9MQ'); }); + it('should include id5 id as /x5 param', function () { + let req = spec.buildRequests([ bidWithParams({}, {'id5id': 'ID5-1234567890'}) ], bidderRequest); + + expect(req.url).to.contain('/x5ID5-1234567890'); + }); + it('should include bids', function () { let bid = minimalBid(); let req = spec.buildRequests([ bid ], bidderRequest); @@ -155,6 +162,8 @@ describe('AdheseAdapter', function () { netRevenue: NET_REVENUE, ttl: TTL, adhese: { + origin: 'APPNEXUS', + originInstance: '', originData: { adType: 'leaderboard', seatbid: [ @@ -199,7 +208,10 @@ describe('AdheseAdapter', function () { mediaType: 'video', netRevenue: NET_REVENUE, ttl: TTL, - adhese: { originData: {} } + adhese: { + origin: 'RUBICON', + originInstance: '', + originData: {} } }]; expect(spec.interpretResponse(sspVideoResponse, bidRequest)).to.deep.equal(expectedResponse); }); @@ -251,6 +263,8 @@ describe('AdheseAdapter', function () { requestId: BID_ID, ad: '', adhese: { + origin: '', + originInstance: '', originData: { adFormat: 'largeleaderboard', adId: '742898', @@ -310,6 +324,8 @@ describe('AdheseAdapter', function () { requestId: BID_ID, vastXml: '', adhese: { + origin: '', + originInstance: '', originData: { adFormat: '', adId: '742470', From 3de9e9cd0c8cfd969597679e4fa0b13f9033bd33 Mon Sep 17 00:00:00 2001 From: TheMediaGrid <44166371+TheMediaGrid@users.noreply.github.com> Date: Tue, 16 Jun 2020 00:58:14 +0300 Subject: [PATCH 419/496] Added keywords parameter to TheMediaGrid Bid Adapter (#5353) * Added TheMediaGridNM Bid Adapter * Updated required params for TheMediaGridNM Bid Adapter * Update TheMediGridNM Bid Adapter * Fix tests for TheMediaGridNM Bid Adapter * Fixes after review for TheMediaGridNM Bid Adapter * Add support of multi-format in TheMediaGrid Bid Adapter * Update sync url for grid and gridNM Bid Adapters * TheMediaGrid Bid Adapter: added keywords adUnit parameter * Update TheMediaGrid Bid Adapter to support keywords from config --- modules/gridBidAdapter.js | 33 ++++++++ modules/gridBidAdapter.md | 8 +- test/spec/modules/gridBidAdapter_spec.js | 95 ++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 2 deletions(-) diff --git a/modules/gridBidAdapter.js b/modules/gridBidAdapter.js index 3a78a5fcf20..d18effa349b 100644 --- a/modules/gridBidAdapter.js +++ b/modules/gridBidAdapter.js @@ -2,6 +2,7 @@ import * as utils from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import { Renderer } from '../src/Renderer.js'; import { VIDEO, BANNER } from '../src/mediaTypes.js'; +import {config} from '../src/config.js'; const BIDDER_CODE = 'grid'; const ENDPOINT_URL = 'https://grid.bidswitch.net/hb'; @@ -47,6 +48,7 @@ export const spec = { const slotsMapByUid = {}; const sizeMap = {}; const bids = validBidRequests || []; + let pageKeywords = null; let reqId; bids.forEach(bid => { @@ -55,6 +57,10 @@ export const spec = { auids.push(uid); const sizesId = utils.parseSizesInput(bid.sizes); + if (!pageKeywords && !utils.isEmpty(bid.params.keywords)) { + pageKeywords = utils.transformBidderParamKeywords(bid.params.keywords); + } + const addedSizes = {}; sizesId.forEach((sizeId) => { addedSizes[sizeId] = true; @@ -94,6 +100,19 @@ export const spec = { }); }); + const configKeywords = utils.transformBidderParamKeywords({ + 'user': utils.deepAccess(config.getConfig('fpd.user'), 'keywords') || null, + 'context': utils.deepAccess(config.getConfig('fpd.context'), 'keywords') || null + }); + + if (configKeywords.length) { + pageKeywords = (pageKeywords || []).concat(configKeywords); + } + + if (pageKeywords && pageKeywords.length > 0) { + pageKeywords.forEach(deleteValues); + } + const payload = { auids: auids.join(','), sizes: utils.getKeys(sizeMap).join(','), @@ -102,6 +121,10 @@ export const spec = { wrapperVersion: '$prebid.version$' }; + if (pageKeywords) { + payload.keywords = JSON.stringify(pageKeywords); + } + if (bidderRequest) { if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { payload.u = bidderRequest.refererInfo.referer; @@ -180,6 +203,16 @@ export const spec = { } }; +function isPopulatedArray(arr) { + return !!(utils.isArray(arr) && arr.length > 0); +} + +function deleteValues(keyPairObj) { + if (isPopulatedArray(keyPairObj.value) && keyPairObj.value[0] === '') { + delete keyPairObj.value; + } +} + function _getBidFromResponse(respItem) { if (!respItem) { utils.logError(LOG_ERROR_MESS.emptySeatbid); diff --git a/modules/gridBidAdapter.md b/modules/gridBidAdapter.md index 4720ee3d808..77b9bbf0f36 100644 --- a/modules/gridBidAdapter.md +++ b/modules/gridBidAdapter.md @@ -32,7 +32,11 @@ Grid bid adapter supports Banner and Video (instream and outstream). bidder: "grid", params: { uid: 2, - priceType: 'gross' + priceType: 'gross', + keywords: { + brandsafety: ['disaster'], + topic: ['stress', 'fear'] + } } } ] @@ -51,4 +55,4 @@ Grid bid adapter supports Banner and Video (instream and outstream). ] } ]; -``` \ No newline at end of file +``` diff --git a/test/spec/modules/gridBidAdapter_spec.js b/test/spec/modules/gridBidAdapter_spec.js index 4f53d9dcb25..c8d04113aeb 100644 --- a/test/spec/modules/gridBidAdapter_spec.js +++ b/test/spec/modules/gridBidAdapter_spec.js @@ -1,6 +1,7 @@ import { expect } from 'chai'; import { spec, resetUserSync, getSyncUrl } from 'modules/gridBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; +import { config } from 'src/config.js'; describe('TheMediaGrid Adapter', function () { const adapter = newBidder(spec); @@ -165,6 +166,100 @@ describe('TheMediaGrid Adapter', function () { const payload = parseRequest(request.data); expect(payload).to.have.property('us_privacy', '1YNN'); }); + + it('should convert keyword params to proper form and attaches to request', function () { + const bidRequestWithKeywords = [].concat(bidRequests); + bidRequestWithKeywords[1] = Object.assign({}, + bidRequests[1], + { + params: { + uid: '1', + keywords: { + single: 'val', + singleArr: ['val'], + singleArrNum: [3], + multiValMixed: ['value1', 2, 'value3'], + singleValNum: 123, + emptyStr: '', + emptyArr: [''], + badValue: {'foo': 'bar'} // should be dropped + } + } + } + ); + + const request = spec.buildRequests(bidRequestWithKeywords, bidderRequest); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload.keywords).to.be.an('string'); + payload.keywords = JSON.parse(payload.keywords); + + expect(payload.keywords).to.deep.equal([{ + 'key': 'single', + 'value': ['val'] + }, { + 'key': 'singleArr', + 'value': ['val'] + }, { + 'key': 'singleArrNum', + 'value': ['3'] + }, { + 'key': 'multiValMixed', + 'value': ['value1', '2', 'value3'] + }, { + 'key': 'singleValNum', + 'value': ['123'] + }, { + 'key': 'emptyStr' + }, { + 'key': 'emptyArr' + }]); + }); + + it('should mix keyword param with keywords from config', function () { + const getConfigStub = sinon.stub(config, 'getConfig').callsFake( + arg => arg === 'fpd.user' ? {'keywords': ['a', 'b']} : arg === 'fpd.context' ? {'keywords': ['any words']} : null); + + const bidRequestWithKeywords = [].concat(bidRequests); + bidRequestWithKeywords[1] = Object.assign({}, + bidRequests[1], + { + params: { + uid: '1', + keywords: { + single: 'val', + singleArr: ['val'], + multiValMixed: ['value1', 2, 'value3'] + } + } + } + ); + + const request = spec.buildRequests(bidRequestWithKeywords, bidderRequest); + expect(request.data).to.be.an('string'); + const payload = parseRequest(request.data); + expect(payload.keywords).to.be.an('string'); + payload.keywords = JSON.parse(payload.keywords); + + expect(payload.keywords).to.deep.equal([{ + 'key': 'single', + 'value': ['val'] + }, { + 'key': 'singleArr', + 'value': ['val'] + }, { + 'key': 'multiValMixed', + 'value': ['value1', '2', 'value3'] + }, { + 'key': 'user', + 'value': ['a', 'b'] + }, { + 'key': 'context', + 'value': ['any words'] + }]); + + getConfigStub.restore(); + }); }); describe('interpretResponse', function () { From f24890c33ac04c404bfa1c93531d65c09293387c Mon Sep 17 00:00:00 2001 From: thuyhq <61451682+thuyhq@users.noreply.github.com> Date: Tue, 16 Jun 2020 14:54:40 +0700 Subject: [PATCH 420/496] Apply some updates to Valueimpression bid adapter (#5356) - Update new adapter endpoint & usersync url - Use window.top instead window object - Use bidRequest.referrerInfo object to get page url, referrer - Tracking ad position by size called targetKey --- modules/valueimpressionBidAdapter.js | 113 ++++++++++++++---- modules/valueimpressionBidAdapter.md | 2 +- .../modules/valueimpressionBidAdapter_spec.js | 18 +-- 3 files changed, 101 insertions(+), 32 deletions(-) diff --git a/modules/valueimpressionBidAdapter.js b/modules/valueimpressionBidAdapter.js index 41bb6e6cacc..b3fe89ab28f 100644 --- a/modules/valueimpressionBidAdapter.js +++ b/modules/valueimpressionBidAdapter.js @@ -1,8 +1,10 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'valueimpression'; -const ENDPOINT = 'https://adapter.valueimpression.com/bid'; -const USER_SYNC_URL = 'https://adapter.valueimpression.com/usersync'; +const ENDPOINT = 'https://useast.quantumdex.io/auction/adapter'; +const USER_SYNC_URL = 'https://sync.quantumdex.io/usersync/adapter'; +var bySlotTargetKey = {}; +var bySlotSizesCount = {} export const spec = { code: BIDDER_CODE, @@ -33,19 +35,41 @@ export const spec = { }, buildRequests: function (validBidRequests, bidderRequest) { + var bids = JSON.parse(JSON.stringify(validBidRequests)) const payload = {}; + + bids.forEach(bidReq => { + var targetKey = 0; + if (bySlotTargetKey[bidReq.adUnitCode] != undefined) { + targetKey = bySlotTargetKey[bidReq.adUnitCode]; + } else { + var biggestSize = _getBiggestSize(bidReq.sizes); + if (biggestSize) { + if (bySlotSizesCount[biggestSize] != undefined) { + bySlotSizesCount[biggestSize]++ + targetKey = bySlotSizesCount[biggestSize]; + } else { + bySlotSizesCount[biggestSize] = 0; + targetKey = 0 + } + } + } + bySlotTargetKey[bidReq.adUnitCode] = targetKey; + bidReq.targetKey = targetKey; + }); + payload.device = {}; payload.device.ua = navigator.userAgent; - payload.device.height = window.innerHeight; - payload.device.width = window.innerWidth; + payload.device.height = window.top.innerHeight; + payload.device.width = window.top.innerWidth; payload.device.dnt = _getDoNotTrack(); payload.device.language = navigator.language; payload.site = {}; - payload.site.id = validBidRequests[0].params.siteId; - payload.site.page = window.location.href; - payload.site.referrer = document.referrer; - payload.site.hostname = window.location.hostname; + payload.site.id = bids[0].params.siteId; + payload.site.page = _extractTopWindowUrlFromBidderRequest(bidderRequest); + payload.site.referrer = _extractTopWindowReferrerFromBidderRequest(bidderRequest); + payload.site.hostname = window.top.location.hostname; // Apply GDPR parameters to request. payload.gdpr = {}; @@ -55,21 +79,23 @@ export const spec = { payload.gdpr.consentString = bidderRequest.gdprConsent.consentString; } } - if (validBidRequests[0].schain) { - payload.schain = JSON.stringify(validBidRequests[0].schain) + // Apply schain. + if (bids[0].schain) { + payload.schain = JSON.stringify(bids[0].schain) } + // Apply us_privacy. if (bidderRequest && bidderRequest.uspConsent) { payload.us_privacy = bidderRequest.uspConsent; } - payload.bids = validBidRequests; + payload.bids = bids; return { method: 'POST', url: ENDPOINT, data: payload, withCredentials: true, - bidderRequests: validBidRequests + bidderRequests: bids }; }, interpretResponse: function (serverResponse, bidRequest) { @@ -125,21 +151,26 @@ export const spec = { } } catch (e) { } return syncs; - }, - - onTimeout: function (timeoutData) { - }, - - onBidWon: function (bid) { - }, - - onSetTargeting: function (bid) { } }; +function _getBiggestSize(sizes) { + if (sizes.length <= 0) return false + var acreage = 0; + var index = 0; + for (var i = 0; i < sizes.length; i++) { + var currentAcreage = sizes[i][0] * sizes[i][1]; + if (currentAcreage >= acreage) { + acreage = currentAcreage; + index = i; + } + } + return sizes[index][0] + 'x' + sizes[index][1]; +} + function _getDoNotTrack() { - if (window.doNotTrack || navigator.doNotTrack || navigator.msDoNotTrack) { - if (window.doNotTrack == '1' || navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') { + if (window.top.doNotTrack || navigator.doNotTrack || navigator.msDoNotTrack) { + if (window.top.doNotTrack == '1' || navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') { return 1; } else { return 0; @@ -149,4 +180,40 @@ function _getDoNotTrack() { } } +/** + * Extracts the page url from given bid request or use the (top) window location as fallback + * + * @param {*} bidderRequest + * @returns {string} + */ +function _extractTopWindowUrlFromBidderRequest(bidderRequest) { + if (bidderRequest && utils.deepAccess(bidderRequest, 'refererInfo.canonicalUrl')) { + return bidderRequest.refererInfo.canonicalUrl; + } + + try { + return window.top.location.href; + } catch (e) { + return window.location.href; + } +} + +/** + * Extracts the referrer from given bid request or use the (top) document referrer as fallback + * + * @param {*} bidderRequest + * @returns {string} + */ +function _extractTopWindowReferrerFromBidderRequest(bidderRequest) { + if (bidderRequest && utils.deepAccess(bidderRequest, 'refererInfo.referer')) { + return bidderRequest.refererInfo.referer; + } + + try { + return window.top.document.referrer; + } catch (e) { + return window.document.referrer; + } +} + registerBidder(spec); diff --git a/modules/valueimpressionBidAdapter.md b/modules/valueimpressionBidAdapter.md index 11400f23834..23cf3c26cf8 100644 --- a/modules/valueimpressionBidAdapter.md +++ b/modules/valueimpressionBidAdapter.md @@ -3,7 +3,7 @@ ``` Module Name: Valueimpression Bidder Adapter Module Type: Bidder Adapter -Maintainer: thuyhq@83.com.vn +Maintainer: k.vision@valueimpression.com ``` # Description diff --git a/test/spec/modules/valueimpressionBidAdapter_spec.js b/test/spec/modules/valueimpressionBidAdapter_spec.js index 89a9657aff4..974d233af74 100644 --- a/test/spec/modules/valueimpressionBidAdapter_spec.js +++ b/test/spec/modules/valueimpressionBidAdapter_spec.js @@ -202,6 +202,7 @@ describe('ValueimpressionBidAdapter', function () { }, 'adUnitCode': 'adunit-code-1', 'sizes': [[300, 250], [300, 600]], + 'targetKey': 0, 'bidId': '30b31c1838de1f', }, { @@ -213,6 +214,7 @@ describe('ValueimpressionBidAdapter', function () { }, 'adUnitCode': 'adunit-code-2', 'sizes': [[120, 600], [300, 600], [160, 600]], + 'targetKey': 1, 'bidId': '30b31c1838de1e', }]; @@ -233,14 +235,14 @@ describe('ValueimpressionBidAdapter', function () { it('should return a properly formatted request', function () { const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.url).to.equal('https://adapter.valueimpression.com/bid') + expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/adapter') expect(bidRequests.method).to.equal('POST') expect(bidRequests.bidderRequests).to.eql(bidRequest); }) it('should return a properly formatted request with GDPR applies set to true', function () { const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.url).to.equal('https://adapter.valueimpression.com/bid') + expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/adapter') expect(bidRequests.method).to.equal('POST') expect(bidRequests.data.gdpr.gdprApplies).to.equal('true') expect(bidRequests.data.gdpr.consentString).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A==') @@ -249,7 +251,7 @@ describe('ValueimpressionBidAdapter', function () { it('should return a properly formatted request with GDPR applies set to false', function () { bidderRequests.gdprConsent.gdprApplies = false; const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.url).to.equal('https://adapter.valueimpression.com/bid') + expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/adapter') expect(bidRequests.method).to.equal('POST') expect(bidRequests.data.gdpr.gdprApplies).to.equal('false') expect(bidRequests.data.gdpr.consentString).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A==') @@ -269,7 +271,7 @@ describe('ValueimpressionBidAdapter', function () { } }; const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.url).to.equal('https://adapter.valueimpression.com/bid') + expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/adapter') expect(bidRequests.method).to.equal('POST') expect(bidRequests.data.gdpr.gdprApplies).to.equal('false') expect(bidRequests.data.gdpr).to.not.include.keys('consentString') @@ -289,7 +291,7 @@ describe('ValueimpressionBidAdapter', function () { } }; const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.url).to.equal('https://adapter.valueimpression.com/bid') + expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/adapter') expect(bidRequests.method).to.equal('POST') expect(bidRequests.data.gdpr.gdprApplies).to.equal('true') expect(bidRequests.data.gdpr).to.not.include.keys('consentString') @@ -307,7 +309,7 @@ describe('ValueimpressionBidAdapter', function () { describe('.interpretResponse', function () { const bidRequests = { 'method': 'POST', - 'url': 'https://adapter.valueimpression.com/bid', + 'url': 'https://useast.quantumdex.io/auction/adapter', 'withCredentials': true, 'data': { 'device': { @@ -319,9 +321,9 @@ describe('ValueimpressionBidAdapter', function () { }, 'site': { 'id': '343', - 'page': 'https://www.includehelp.com/?pbjs_debug=true', + 'page': 'https://www.example.com/tutorial', 'referrer': '', - 'hostname': 'www.includehelp.com' + 'hostname': 'www.example.com' } }, 'bidderRequests': [ From b1d594241f2838a22a32fbc9739eab3da4777a19 Mon Sep 17 00:00:00 2001 From: susyt Date: Tue, 16 Jun 2020 06:56:56 -0700 Subject: [PATCH 421/496] GumGum: removes deprecated banner sizes default (#5372) * uses encodeURIComponent inline * adds test for jcsi param * adds request delay depending on previous response * adds inVideo param * removes deprecated bidRequest.sizes --- modules/gumgumBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index 2bccc30bb64..54d845be7ad 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -278,7 +278,7 @@ function buildRequests (validBidRequests, bidderRequest) { tId: transactionId, pi: data.pi, selector: params.selector, - sizes: bannerSizes || bidRequest.sizes, + sizes: bannerSizes, url: BID_ENDPOINT, method: 'GET', data: Object.assign(data, _getBrowserParams(topWindowUrl), _getDigiTrustQueryParams(userId), _getTradeDeskIDParam(userId)) From 7bd17e4f49ef50c6e6308c4bd7a4b0de7bd9e449 Mon Sep 17 00:00:00 2001 From: SKOCHERI <37454420+SKOCHERI@users.noreply.github.com> Date: Tue, 16 Jun 2020 07:17:23 -0700 Subject: [PATCH 422/496] UserId SharedId submodule (#5315) * Adding sharedid submodule * Updating with Shared ID Module * SharedID test and sharedid eids * Shared ID md changes * Shared ID md changes * Shared ID changes * Apply suggestions from code review Co-Authored-By: Brad Rodriguez * Applying review suggestions * Apply suggestions from code review Co-Authored-By: Brad Rodriguez * Reformatting and reorganizing sharedId submodule * Reformatting and reorganizing sharedId submodule * Shared Id generation changes * Adding cookie Sync * Decode and sync cookie * Updating endpoint * Updaitng eids.md * Configured sync * Refactor and md update * Refactoring * Refactoring * Updating sync to seconds * Updating configuration * Reformatting * Reformatting * Reformatting * Fixing review comments * Changes to id value * Updating documentation * Documentation update * Resolving merge conflicts * updating userid_example.html * Fixing review comments on test to separate sharedid opt out tests * Moving sharedID generation within sharedId module * Moving sharedID generation within sharedId module Co-authored-by: skocheri Co-authored-by: Brad Rodriguez --- integrationExamples/gpt/userId_example.html | 12 +- modules/.submodules.json | 3 +- modules/sharedIdSystem.js | 333 ++++++++++++++++ modules/sharedIdSystem.md | 43 +++ modules/userId/eids.js | 13 + modules/userId/eids.md | 12 +- modules/userId/userId.md | 20 + test/spec/modules/eids_spec.js | 36 ++ test/spec/modules/userId_spec.js | 408 +++++++++++++++----- 9 files changed, 787 insertions(+), 93 deletions(-) create mode 100644 modules/sharedIdSystem.js create mode 100644 modules/sharedIdSystem.md diff --git a/integrationExamples/gpt/userId_example.html b/integrationExamples/gpt/userId_example.html index 3bb8ce2df66..7886e5b13ca 100644 --- a/integrationExamples/gpt/userId_example.html +++ b/integrationExamples/gpt/userId_example.html @@ -179,9 +179,19 @@ name: 'idl_env', expires: 30 } + }, { + name: "sharedId", + params: { + syncTime: 60 // in seconds, default is 24 hours + }, + storage: { + type: "cookie", + name: "sharedid", + expires: 28 + } }], syncDelay: 5000, - auctionDelay: 1000 + auctionDelay: 1000 } }); pbjs.addAdUnits(adUnits); diff --git a/modules/.submodules.json b/modules/.submodules.json index ce3eb8fa137..25ae3c3884b 100644 --- a/modules/.submodules.json +++ b/modules/.submodules.json @@ -9,7 +9,8 @@ "liveIntentIdSystem", "criteoIdSystem", "netIdSystem", - "identityLinkIdSystem" + "identityLinkIdSystem", + "sharedIdSystem" ], "adpod": [ "freeWheelAdserverVideo", diff --git a/modules/sharedIdSystem.js b/modules/sharedIdSystem.js new file mode 100644 index 00000000000..5c2a3df0595 --- /dev/null +++ b/modules/sharedIdSystem.js @@ -0,0 +1,333 @@ +/** + * This module adds Shared ID support to the User ID module + * The {@link module:modules/userId} module is required. + * @module modules/sharedIdSystem + * @requires module:modules/userId + */ + +import * as utils from '../src/utils.js' +import {ajax} from '../src/ajax.js'; +import {submodule} from '../src/hook.js'; + +const MODULE_NAME = 'sharedId'; +const ID_SVC = 'https://id.sharedid.org/id'; +const DEFAULT_24_HOURS = 86400; +const OPT_OUT_VALUE = '00000000000000000000000000'; +// These values should NEVER change. If +// they do, we're no longer making ulids! +const ENCODING = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; // Crockford's Base32 +const ENCODING_LEN = ENCODING.length; +const TIME_MAX = Math.pow(2, 48) - 1; +const TIME_LEN = 10; +const RANDOM_LEN = 16; +const id = factory(); +/** + * Constructs cookie value + * @param value + * @param needsSync + * @returns {string} + */ +function constructCookieValue(value, needsSync) { + const cookieValue = {}; + cookieValue.id = value; + cookieValue.ts = utils.timestamp(); + if (needsSync) { + cookieValue.ns = true; + } + utils.logInfo('SharedId: cookie Value: ' + JSON.stringify(cookieValue)); + return cookieValue; +} + +/** + * Checks if id needs to be synced + * @param configParams + * @param storedId + * @returns {boolean} + */ +function isIdSynced(configParams, storedId) { + const needSync = storedId.ns; + if (needSync) { + return true; + } + if (!configParams || typeof configParams.syncTime !== 'number') { + utils.logInfo('SharedId: Sync time is not configured or is not a number'); + } + let syncTime = (!configParams || typeof configParams.syncTime !== 'number') ? DEFAULT_24_HOURS : configParams.syncTime; + if (syncTime > DEFAULT_24_HOURS) { + syncTime = DEFAULT_24_HOURS; + } + const cookieTimestamp = storedId.ts; + if (cookieTimestamp) { + var secondBetweenTwoDate = timeDifferenceInSeconds(utils.timestamp(), cookieTimestamp); + return secondBetweenTwoDate >= syncTime; + } + return false; +} + +/** + * Gets time difference in secounds + * @param date1 + * @param date2 + * @returns {number} + */ +function timeDifferenceInSeconds(date1, date2) { + const diff = (date1 - date2) / 1000; + return Math.abs(Math.round(diff)); +} + +/** + * id generation call back + * @param result + * @param callback + * @returns {{success: success, error: error}} + */ +function idGenerationCallback(callback) { + return { + success: function (responseBody) { + let value = {}; + if (responseBody) { + try { + let responseObj = JSON.parse(responseBody); + utils.logInfo('SharedId: Generated SharedId: ' + responseObj.sharedId); + value = constructCookieValue(responseObj.sharedId, false); + } catch (error) { + utils.logError(error); + } + } + callback(value); + }, + error: function (statusText, responseBody) { + const value = constructCookieValue(id(), true); + utils.logInfo('SharedId: Ulid Generated SharedId: ' + value.id); + callback(value); + } + } +} + +/** + * existing id generation call back + * @param result + * @param callback + * @returns {{success: success, error: error}} + */ +function existingIdCallback(storedId, callback) { + return { + success: function (responseBody) { + utils.logInfo('SharedId: id to be synced: ' + storedId.id); + if (responseBody) { + try { + let responseObj = JSON.parse(responseBody); + storedId = constructCookieValue(responseObj.sharedId, false); + utils.logInfo('SharedId: Older SharedId: ' + storedId.id); + } catch (error) { + utils.logError(error); + } + } + callback(storedId); + }, + error: function () { + utils.logInfo('SharedId: Sync error for id : ' + storedId.id); + callback(storedId); + } + } +} + +/** + * Encode the id + * @param value + * @returns {string|*} + */ +function encodeId(value) { + const result = {}; + const sharedId = (value && typeof value['id'] === 'string') ? value['id'] : undefined; + if (sharedId == OPT_OUT_VALUE) { + return undefined; + } + if (sharedId) { + const bidIds = { + id: sharedId, + } + const ns = (value && typeof value['ns'] === 'boolean') ? value['ns'] : undefined; + if (ns == undefined) { + bidIds.third = sharedId; + } + result.sharedid = bidIds; + utils.logInfo('SharedId: Decoded value ' + JSON.stringify(result)); + return result; + } + return sharedId; +} + +/** + * the factory to generate unique identifier based on time and current pseudorandom number + * @param {string} the current pseudorandom number generator + * @returns {function(*=): *} + */ +function factory(currPrng) { + if (!currPrng) { + currPrng = detectPrng(); + } + return function ulid(seedTime) { + if (isNaN(seedTime)) { + seedTime = Date.now(); + } + return encodeTime(seedTime, TIME_LEN) + encodeRandom(RANDOM_LEN, currPrng); + }; +} + +/** + * creates and logs the error message + * @function + * @param {string} error message + * @returns {Error} + */ +function createError(message) { + utils.logError(message); + const err = new Error(message); + err.source = 'sharedId'; + return err; +} + +/** + * gets a a random charcter from generated pseudorandom number + * @param {string} the generated pseudorandom number + * @returns {string} + */ +function randomChar(prng) { + let rand = Math.floor(prng() * ENCODING_LEN); + if (rand === ENCODING_LEN) { + rand = ENCODING_LEN - 1; + } + return ENCODING.charAt(rand); +} + +/** + * encodes the time based on the length + * @param now + * @param len + * @returns {string} encoded time. + */ +function encodeTime (now, len) { + if (isNaN(now)) { + throw new Error(now + ' must be a number'); + } + + if (Number.isInteger(now) === false) { + throw createError('time must be an integer'); + } + + if (now > TIME_MAX) { + throw createError('cannot encode time greater than ' + TIME_MAX); + } + if (now < 0) { + throw createError('time must be positive'); + } + + if (Number.isInteger(len) === false) { + throw createError('length must be an integer'); + } + if (len < 0) { + throw createError('length must be positive'); + } + + let mod; + let str = ''; + for (; len > 0; len--) { + mod = now % ENCODING_LEN; + str = ENCODING.charAt(mod) + str; + now = (now - mod) / ENCODING_LEN; + } + return str; +} + +/** + * encodes random character + * @param len + * @param prng + * @returns {string} + */ +function encodeRandom (len, prng) { + let str = ''; + for (; len > 0; len--) { + str = randomChar(prng) + str; + } + return str; +} + +/** + * detects the pseudorandom number generator and generates the random number + * @function + * @param {string} error message + * @returns {string} a random number + */ +function detectPrng(root) { + if (!root) { + root = typeof window !== 'undefined' ? window : null; + } + const browserCrypto = root && (root.crypto || root.msCrypto); + if (browserCrypto) { + return () => { + const buffer = new Uint8Array(1); + browserCrypto.getRandomValues(buffer); + return buffer[0] / 0xff; + }; + } + return () => Math.random(); +} + +/** @type {Submodule} */ +export const sharedIdSubmodule = { + /** + * used to link submodule with config + * @type {string} + */ + name: MODULE_NAME, + + /** + * decode the stored id value for passing to bid requests + * @function + * @param {string} value + * @returns {{sharedid:{ id: string, third:string}} or undefined if value doesn't exists + */ + decode(value) { + return (value) ? encodeId(value) : undefined; + }, + + /** + * performs action to obtain id and return a value. + * @function + * @param {SubmoduleParams} [configParams] + * @returns {sharedId} + */ + getId(configParams) { + const resp = function (callback) { + utils.logInfo('SharedId: Sharedid doesnt exists, new cookie creation'); + ajax(ID_SVC, idGenerationCallback(callback), undefined, {method: 'GET', withCredentials: true}); + }; + return {callback: resp}; + }, + + /** + * performs actions even if the id exists and returns a value + * @param configParams + * @param storedId + * @returns {{callback: *}} + */ + extendId(configParams, storedId) { + utils.logInfo('SharedId: Existing shared id ' + storedId.id); + const resp = function (callback) { + const needSync = isIdSynced(configParams, storedId); + if (needSync) { + utils.logInfo('SharedId: Existing shared id ' + storedId + ' is not synced'); + const sharedIdPayload = {}; + sharedIdPayload.sharedId = storedId.id; + const payloadString = JSON.stringify(sharedIdPayload); + ajax(ID_SVC, existingIdCallback(storedId, callback), payloadString, {method: 'POST', withCredentials: true}); + } + }; + return {callback: resp}; + } +}; + +// Register submodule for userId +submodule('userId', sharedIdSubmodule); diff --git a/modules/sharedIdSystem.md b/modules/sharedIdSystem.md new file mode 100644 index 00000000000..acb076ed97f --- /dev/null +++ b/modules/sharedIdSystem.md @@ -0,0 +1,43 @@ +## Shared ID User ID Submodule + +Shared ID User ID Module generates a UUID that can be utilized to improve user matching.This module enables timely synchronization which handles sharedId.org optout. This module does not require any registration. + +### Building Prebid with Shared Id Support +Your Prebid build must include the modules for both **userId** and **sharedId** submodule. Follow the build instructions for Prebid as +explained in the top level README.md file of the Prebid source tree. + +ex: $ gulp build --modules=userId,sharedIdSystem + +### Prebid Params + +Individual params may be set for the Shared ID User ID Submodule. +``` +pbjs.setConfig({ + usersync: { + userIds: [{ + name: 'sharedId', + params: { + syncTime: 60 // in seconds, default is 24 hours + }, + storage: { + name: 'sharedid', + type: 'cookie', + expires: 28 + }, + }] + } +}); +``` + +### Parameter Descriptions for the `usersync` Configuration Section +The below parameters apply only to the Shared ID User ID Module integration. + +| Params under usersync.userIds[]| Scope | Type | Description | Example | +| --- | --- | --- | --- | --- | +| name | Required | String | ID value for the Shared ID module - `"sharedId"` | `"sharedId"` | +| params | Optional | Object | Details for sharedId syncing. | | +| params.syncTime | Optional | Object | Configuration to define the frequency(in seconds) of id synchronization. By default id is synchronized every 24 hours | 60 | +| storage | Required | Object | The publisher must specify the local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. | | +| storage.type | Required | String | This is where the results of the user ID will be stored. The recommended method is `localStorage` by specifying `html5`. | `"html5"` | +| storage.name | Required | String | The name of the cookie or html5 local storage where the user ID will be stored. | `"sharedid"` | +| storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `28` | diff --git a/modules/userId/eids.js b/modules/userId/eids.js index c088e51c74b..842737183a8 100644 --- a/modules/userId/eids.js +++ b/modules/userId/eids.js @@ -85,6 +85,19 @@ const USER_IDS_CONFIG = { 'netId': { source: 'netid.de', atype: 1 + }, + // sharedid + 'sharedid': { + source: 'sharedid.org', + atype: 1, + getValue: function(data) { + return data.id; + }, + getUidExt: function(data) { + return (data && data.third) ? { + third: data.third + } : undefined; + } } }; diff --git a/modules/userId/eids.md b/modules/userId/eids.md index baface1ab6f..60f450e9328 100644 --- a/modules/userId/eids.md +++ b/modules/userId/eids.md @@ -85,6 +85,16 @@ userIdAsEids = [ id: 'some-random-id-value', atype: 1 }] + }, + { + source: 'sharedid.org', + uids: [{ + id: 'some-random-id-value', + atype: 1, + ext: { + third: 'some-random-id-value' + } + }] } ] -``` \ No newline at end of file +``` diff --git a/modules/userId/userId.md b/modules/userId/userId.md index 5ce31a4e3a9..eb9e985a1d6 100644 --- a/modules/userId/userId.md +++ b/modules/userId/userId.md @@ -59,6 +59,16 @@ pbjs.setConfig({ name: '_li_pbid', expires: 60 } + }, { + name: 'sharedId', + params: { + syncTime: 60 // in seconds, default is 24 hours + }, + storage: { + type: 'cookie', + name: 'sharedid', + expires: 28 + } }], syncDelay: 5000, auctionDelay: 1000 @@ -108,6 +118,16 @@ pbjs.setConfig({ name: '_li_pbid', expires: 60 } + }, { + name: 'sharedId', + params: { + syncTime: 60 // in seconds, default is 24 hours + }, + storage: { + type: 'cookie', + name: 'sharedid', + expires: 28 + } }], syncDelay: 5000 } diff --git a/test/spec/modules/eids_spec.js b/test/spec/modules/eids_spec.js index ed32ecc51d2..160277204df 100644 --- a/test/spec/modules/eids_spec.js +++ b/test/spec/modules/eids_spec.js @@ -146,6 +146,42 @@ describe('eids array generation for known sub-modules', function() { uids: [{id: 'some-random-id-value', atype: 1}] }); }); + it('Sharedid', function() { + const userId = { + sharedid: { + id: 'test_sharedId', + third: 'test_sharedId' + } + }; + const newEids = createEidsArray(userId); + expect(newEids.length).to.equal(1); + expect(newEids[0]).to.deep.equal({ + source: 'sharedid.org', + uids: [{ + id: 'test_sharedId', + atype: 1, + ext: { + third: 'test_sharedId' + } + }] + }); + }); + it('Sharedid: Not Synched', function() { + const userId = { + sharedid: { + id: 'test_sharedId' + } + }; + const newEids = createEidsArray(userId); + expect(newEids.length).to.equal(1); + expect(newEids[0]).to.deep.equal({ + source: 'sharedid.org', + uids: [{ + id: 'test_sharedId', + atype: 1 + }] + }); + }); }); describe('Negative case', function() { diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index e909c53b60f..8ce81ea85b0 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -20,6 +20,7 @@ import {id5IdSubmodule} from 'modules/id5IdSystem.js'; import {identityLinkSubmodule} from 'modules/identityLinkIdSystem.js'; import {liveIntentIdSubmodule} from 'modules/liveIntentIdSystem.js'; import {netIdSubmodule} from 'modules/netIdSystem.js'; +import {sharedIdSubmodule} from 'modules/sharedIdSystem.js'; import {server} from 'test/mocks/xhr.js'; let assert = require('chai').assert; @@ -27,7 +28,7 @@ let expect = require('chai').expect; const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; describe('User ID', function() { - function getConfigMock(configArr1, configArr2, configArr3, configArr4, configArr5, configArr6) { + function getConfigMock(configArr1, configArr2, configArr3, configArr4, configArr5, configArr6, configArr7) { return { userSync: { syncDelay: 0, @@ -37,16 +38,20 @@ describe('User ID', function() { (configArr3 && configArr3.length >= 3) ? getStorageMock.apply(null, configArr3) : null, (configArr4 && configArr4.length >= 3) ? getStorageMock.apply(null, configArr4) : null, (configArr5 && configArr5.length >= 3) ? getStorageMock.apply(null, configArr5) : null, - (configArr6 && configArr6.length >= 3) ? getStorageMock.apply(null, configArr6) : null - ].filter(i => i)} + (configArr6 && configArr6.length >= 3) ? getStorageMock.apply(null, configArr6) : null, + (configArr7 && configArr7.length >= 3) ? getStorageMock.apply(null, configArr7) : null + ].filter(i => i) + } } } + function getStorageMock(name = 'pubCommonId', key = 'pubcid', type = 'cookie', expires = 30, refreshInSeconds) { - return { name: name, storage: { name: key, type: type, expires: expires, refreshInSeconds: refreshInSeconds } } + return {name: name, storage: {name: key, type: type, expires: expires, refreshInSeconds: refreshInSeconds}} } + function getConfigValueMock(name, value) { return { - userSync: { syncDelay: 0, userIds: [{ name: name, value: value }] } + userSync: {syncDelay: 0, userIds: [{name: name, value: value}]} } } @@ -62,7 +67,11 @@ describe('User ID', function() { function addConfig(cfg, name, value) { if (cfg && cfg.userSync && cfg.userSync.userIds) { cfg.userSync.userIds.forEach(element => { - if (element[name] !== undefined) { element[name] = Object.assign(element[name], value); } else { element[name] = value; } + if (element[name] !== undefined) { + element[name] = Object.assign(element[name], value); + } else { + element[name] = value; + } }); } @@ -82,7 +91,7 @@ describe('User ID', function() { sinon.spy(coreStorage, 'setCookie'); }); - afterEach(function () { + afterEach(function() { $$PREBID_GLOBAL$$.requestBids.removeAll(); config.resetConfig(); coreStorage.setCookie.restore(); @@ -93,7 +102,7 @@ describe('User ID', function() { coreStorage.setCookie('pubcid_alt', '', EXPIRED_COOKIE_DATE); }); - it('Check same cookie behavior', function () { + it('Check same cookie behavior', function() { let adUnits1 = [getAdUnitMock()]; let adUnits2 = [getAdUnitMock()]; let innerAdUnits1; @@ -106,7 +115,9 @@ describe('User ID', function() { init(config); config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); - requestBidsHook(config => { innerAdUnits1 = config.adUnits }, {adUnits: adUnits1}); + requestBidsHook(config => { + innerAdUnits1 = config.adUnits + }, {adUnits: adUnits1}); pubcid = coreStorage.getCookie('pubcid'); // cookies is created after requestbidHook innerAdUnits1.forEach(unit => { @@ -120,11 +131,13 @@ describe('User ID', function() { }); }); - requestBidsHook(config => { innerAdUnits2 = config.adUnits }, {adUnits: adUnits2}); + requestBidsHook(config => { + innerAdUnits2 = config.adUnits + }, {adUnits: adUnits2}); assert.deepEqual(innerAdUnits1, innerAdUnits2); }); - it('Check different cookies', function () { + it('Check different cookies', function() { let adUnits1 = [getAdUnitMock()]; let adUnits2 = [getAdUnitMock()]; let innerAdUnits1; @@ -135,7 +148,9 @@ describe('User ID', function() { setSubmoduleRegistry([pubCommonIdSubmodule]); init(config); config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); - requestBidsHook((config) => { innerAdUnits1 = config.adUnits }, {adUnits: adUnits1}); + requestBidsHook((config) => { + innerAdUnits1 = config.adUnits + }, {adUnits: adUnits1}); pubcid1 = coreStorage.getCookie('pubcid'); // get first cookie coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); // erase cookie @@ -153,7 +168,9 @@ describe('User ID', function() { setSubmoduleRegistry([pubCommonIdSubmodule]); init(config); config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); - requestBidsHook((config) => { innerAdUnits2 = config.adUnits }, {adUnits: adUnits2}); + requestBidsHook((config) => { + innerAdUnits2 = config.adUnits + }, {adUnits: adUnits2}); pubcid2 = coreStorage.getCookie('pubcid'); // get second cookie @@ -171,14 +188,16 @@ describe('User ID', function() { expect(pubcid1).to.not.equal(pubcid2); }); - it('Use existing cookie', function () { + it('Use existing cookie', function() { let adUnits = [getAdUnitMock()]; let innerAdUnits; setSubmoduleRegistry([pubCommonIdSubmodule]); init(config); config.setConfig(getConfigMock(['pubCommonId', 'pubcid_alt', 'cookie'])); - requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); + requestBidsHook((config) => { + innerAdUnits = config.adUnits + }, {adUnits}); innerAdUnits.forEach((unit) => { unit.bids.forEach((bid) => { expect(bid).to.have.deep.nested.property('userId.pubcid'); @@ -193,7 +212,7 @@ describe('User ID', function() { expect(coreStorage.setCookie.callCount).to.equal(0); }); - it('Extend cookie', function () { + it('Extend cookie', function() { let adUnits = [getAdUnitMock()]; let innerAdUnits; let customConfig = getConfigMock(['pubCommonId', 'pubcid_alt', 'cookie']); @@ -202,7 +221,9 @@ describe('User ID', function() { setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]); init(config); config.setConfig(customConfig); - requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); + requestBidsHook((config) => { + innerAdUnits = config.adUnits + }, {adUnits}); innerAdUnits.forEach((unit) => { unit.bids.forEach((bid) => { expect(bid).to.have.deep.nested.property('userId.pubcid'); @@ -217,7 +238,7 @@ describe('User ID', function() { expect(coreStorage.setCookie.callCount).to.equal(1); }); - it('Disable auto create', function () { + it('Disable auto create', function() { let adUnits = [getAdUnitMock()]; let innerAdUnits; let customConfig = getConfigMock(['pubCommonId', 'pubcid', 'cookie']); @@ -226,7 +247,9 @@ describe('User ID', function() { setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]); init(config); config.setConfig(customConfig); - requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); + requestBidsHook((config) => { + innerAdUnits = config.adUnits + }, {adUnits}); innerAdUnits.forEach((unit) => { unit.bids.forEach((bid) => { expect(bid).to.not.have.deep.nested.property('userId.pubcid'); @@ -267,16 +290,16 @@ describe('User ID', function() { }); }); - describe('Opt out', function () { - before(function () { + describe('Opt out', function() { + before(function() { coreStorage.setCookie('_pbjs_id_optout', '1', (new Date(Date.now() + 5000).toUTCString())); }); - beforeEach(function () { + beforeEach(function() { sinon.stub(utils, 'logInfo'); }); - afterEach(function () { + afterEach(function() { // removed cookie coreStorage.setCookie('_pbjs_id_optout', '', EXPIRED_COOKIE_DATE); $$PREBID_GLOBAL$$.requestBids.removeAll(); @@ -284,18 +307,18 @@ describe('User ID', function() { config.resetConfig(); }); - after(function () { + after(function() { coreStorage.setCookie('_pbjs_id_optout', '', EXPIRED_COOKIE_DATE); }); - it('fails initialization if opt out cookie exists', function () { + it('fails initialization if opt out cookie exists', function() { setSubmoduleRegistry([pubCommonIdSubmodule]); init(config); config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); expect(utils.logInfo.args[0][0]).to.exist.and.to.equal('User ID - opt-out cookie found, exit module'); }); - it('initializes if no opt out cookie exists', function () { + it('initializes if no opt out cookie exists', function() { setSubmoduleRegistry([pubCommonIdSubmodule]); init(config); config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); @@ -303,34 +326,34 @@ describe('User ID', function() { }); }); - describe('Handle variations of config values', function () { - beforeEach(function () { + describe('Handle variations of config values', function() { + beforeEach(function() { sinon.stub(utils, 'logInfo'); }); - afterEach(function () { + afterEach(function() { $$PREBID_GLOBAL$$.requestBids.removeAll(); utils.logInfo.restore(); config.resetConfig(); }); - it('handles config with no usersync object', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule]); + it('handles config with no usersync object', function() { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); init(config); config.setConfig({}); // usersync is undefined, and no logInfo message for 'User ID - usersync config updated' expect(typeof utils.logInfo.args[0]).to.equal('undefined'); }); - it('handles config with empty usersync object', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule]); + it('handles config with empty usersync object', function() { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); init(config); - config.setConfig({ userSync: {} }); + config.setConfig({userSync: {}}); expect(typeof utils.logInfo.args[0]).to.equal('undefined'); }); - it('handles config with usersync and userIds that are empty objs', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule]); + it('handles config with usersync and userIds that are empty objs', function() { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); init(config); config.setConfig({ userSync: { @@ -340,33 +363,33 @@ describe('User ID', function() { expect(typeof utils.logInfo.args[0]).to.equal('undefined'); }); - it('handles config with usersync and userIds with empty names or that dont match a submodule.name', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule]); + it('handles config with usersync and userIds with empty names or that dont match a submodule.name', function() { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); init(config); config.setConfig({ userSync: { userIds: [{ name: '', - value: { test: '1' } + value: {test: '1'} }, { name: 'foo', - value: { test: '1' } + value: {test: '1'} }] } }); expect(typeof utils.logInfo.args[0]).to.equal('undefined'); }); - it('config with 1 configurations should create 1 submodules', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule]); + it('config with 1 configurations should create 1 submodules', function() { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); init(config); config.setConfig(getConfigMock(['unifiedId', 'unifiedid', 'cookie'])); expect(utils.logInfo.args[0][0]).to.exist.and.to.equal('User ID - usersync config updated for 1 submodules'); }); - it('config with 7 configurations should result in 7 submodules add', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, liveIntentIdSubmodule, britepoolIdSubmodule, netIdSubmodule]); + it('config with 8 configurations should result in 8 submodules add', function() { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, liveIntentIdSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule]); init(config); config.setConfig({ userSync: { @@ -375,67 +398,70 @@ describe('User ID', function() { name: 'pubCommonId', value: {'pubcid': '11111'} }, { name: 'unifiedId', - storage: { name: 'unifiedid', type: 'cookie' } + storage: {name: 'unifiedid', type: 'cookie'} }, { name: 'id5Id', - storage: { name: 'id5id', type: 'cookie' } + storage: {name: 'id5id', type: 'cookie'} }, { name: 'identityLink', - storage: { name: 'idl_env', type: 'cookie' } + storage: {name: 'idl_env', type: 'cookie'} }, { name: 'liveIntentId', - storage: { name: '_li_pbid', type: 'cookie' } + storage: {name: '_li_pbid', type: 'cookie'} }, { name: 'britepoolId', - value: { 'primaryBPID': '279c0161-5152-487f-809e-05d7f7e653fd' } + value: {'primaryBPID': '279c0161-5152-487f-809e-05d7f7e653fd'} }, { name: 'netId', - storage: { name: 'netId', type: 'cookie' } + storage: {name: 'netId', type: 'cookie'} + }, { + name: 'sharedId', + storage: {name: 'sharedid', type: 'cookie'} }] } }); - expect(utils.logInfo.args[0][0]).to.exist.and.to.equal('User ID - usersync config updated for 7 submodules'); + expect(utils.logInfo.args[0][0]).to.exist.and.to.equal('User ID - usersync config updated for 8 submodules'); }); - it('config syncDelay updates module correctly', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule]); + it('config syncDelay updates module correctly', function() { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); init(config); config.setConfig({ userSync: { syncDelay: 99, userIds: [{ name: 'unifiedId', - storage: { name: 'unifiedid', type: 'cookie' } + storage: {name: 'unifiedid', type: 'cookie'} }] } }); expect(syncDelay).to.equal(99); }); - it('config auctionDelay updates module correctly', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule]); + it('config auctionDelay updates module correctly', function() { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); init(config); config.setConfig({ userSync: { auctionDelay: 100, userIds: [{ name: 'unifiedId', - storage: { name: 'unifiedid', type: 'cookie' } + storage: {name: 'unifiedid', type: 'cookie'} }] } }); expect(auctionDelay).to.equal(100); }); - it('config auctionDelay defaults to 0 if not a number', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule]); + it('config auctionDelay defaults to 0 if not a number', function() { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); init(config); config.setConfig({ userSync: { auctionDelay: '', userIds: [{ name: 'unifiedId', - storage: { name: 'unifiedid', type: 'cookie' } + storage: {name: 'unifiedid', type: 'cookie'} }] } }); @@ -483,7 +509,7 @@ describe('User ID', function() { attachIdSystem(mockIdSystem, true); }); - afterEach(function () { + afterEach(function() { $$PREBID_GLOBAL$$.requestBids.removeAll(); config.resetConfig(); sandbox.restore(); @@ -495,7 +521,7 @@ describe('User ID', function() { auctionDelay: 33, syncDelay: 77, userIds: [{ - name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } + name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} }] } }); @@ -528,7 +554,7 @@ describe('User ID', function() { auctionDelay: 33, syncDelay: 77, userIds: [{ - name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } + name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} }] } }); @@ -566,7 +592,7 @@ describe('User ID', function() { userSync: { syncDelay: 77, userIds: [{ - name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } + name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} }] } }); @@ -602,7 +628,7 @@ describe('User ID', function() { userSync: { syncDelay: 0, userIds: [{ - name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } + name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} }] } }); @@ -633,7 +659,7 @@ describe('User ID', function() { auctionDelay: 33, syncDelay: 77, userIds: [{ - name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } + name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} }] } }); @@ -712,7 +738,7 @@ describe('User ID', function() { expect(bid.userId.tdid).to.equal('testunifiedid_alt'); expect(bid.userIdAsEids[0]).to.deep.equal({ source: 'adserver.org', - uids: [{id: 'testunifiedid_alt', atype: 1, ext: { rtiPartner: 'TDID' }}] + uids: [{id: 'testunifiedid_alt', atype: 1, ext: {rtiPartner: 'TDID'}}] }); }); }); @@ -818,6 +844,133 @@ describe('User ID', function() { }, {adUnits}); }); + it('test hook from sharedId html5', function(done) { + // simulate existing browser local storage values + localStorage.setItem('sharedid', JSON.stringify({'id': 'test_sharedId', 'ts': 1590525289611})); + localStorage.setItem('sharedid_exp', ''); + + setSubmoduleRegistry([sharedIdSubmodule]); + init(config); + config.setConfig(getConfigMock(['sharedId', 'sharedid', 'html5'])); + requestBidsHook(function() { + adUnits.forEach(unit => { + unit.bids.forEach(bid => { + expect(bid).to.have.deep.nested.property('userId.sharedid'); + expect(bid.userId.sharedid).to.have.deep.nested.property('id'); + expect(bid.userId.sharedid).to.have.deep.nested.property('third'); + expect(bid.userId.sharedid).to.deep.equal({ + id: 'test_sharedId', + third: 'test_sharedId' + }); + expect(bid.userIdAsEids[0]).to.deep.equal({ + source: 'sharedid.org', + uids: [{ + id: 'test_sharedId', + atype: 1, + ext: { + third: 'test_sharedId' + } + }] + }); + }); + }); + localStorage.removeItem('sharedid'); + localStorage.removeItem('sharedid_exp'); + done(); + }, {adUnits}); + }); + + it('test hook from sharedId html5 (id not synced)', function(done) { + // simulate existing browser local storage values + localStorage.setItem('sharedid', JSON.stringify({'id': 'test_sharedId', 'ns': true, 'ts': 1590525289611})); + localStorage.setItem('sharedid_exp', ''); + + setSubmoduleRegistry([sharedIdSubmodule]); + init(config); + config.setConfig(getConfigMock(['sharedId', 'sharedid', 'html5'])); + requestBidsHook(function() { + adUnits.forEach(unit => { + unit.bids.forEach(bid => { + expect(bid).to.have.deep.nested.property('userId.sharedid'); + expect(bid.userId.sharedid).to.have.deep.nested.property('id'); + expect(bid.userId.sharedid).to.deep.equal({ + id: 'test_sharedId' + }); + expect(bid.userIdAsEids[0]).to.deep.equal({ + source: 'sharedid.org', + uids: [{ + id: 'test_sharedId', + atype: 1 + }] + }); + }); + }); + localStorage.removeItem('sharedid'); + localStorage.removeItem('sharedid_exp'); + done(); + }, {adUnits}); + }); + it('test hook from sharedId cookie', function(done) { + coreStorage.setCookie('sharedid', JSON.stringify({'id': 'test_sharedId', 'ts': 1590525289611}), (new Date(Date.now() + 100000).toUTCString())); + + setSubmoduleRegistry([sharedIdSubmodule]); + init(config); + config.setConfig(getConfigMock(['sharedId', 'sharedid', 'cookie'])); + + requestBidsHook(function() { + adUnits.forEach(unit => { + unit.bids.forEach(bid => { + expect(bid).to.have.deep.nested.property('userId.sharedid'); + expect(bid.userId.sharedid).to.have.deep.nested.property('id'); + expect(bid.userId.sharedid).to.have.deep.nested.property('third'); + expect(bid.userId.sharedid).to.deep.equal({ + id: 'test_sharedId', + third: 'test_sharedId' + }); + expect(bid.userIdAsEids[0]).to.deep.equal({ + source: 'sharedid.org', + uids: [{ + id: 'test_sharedId', + atype: 1, + ext: { + third: 'test_sharedId' + } + }] + }); + }); + }); + coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); + done(); + }, {adUnits}); + }); + it('test hook from sharedId cookie (id not synced) ', function(done) { + coreStorage.setCookie('sharedid', JSON.stringify({'id': 'test_sharedId', 'ns': true, 'ts': 1590525289611}), (new Date(Date.now() + 100000).toUTCString())); + + setSubmoduleRegistry([sharedIdSubmodule]); + init(config); + config.setConfig(getConfigMock(['sharedId', 'sharedid', 'cookie'])); + + requestBidsHook(function() { + adUnits.forEach(unit => { + unit.bids.forEach(bid => { + expect(bid).to.have.deep.nested.property('userId.sharedid'); + expect(bid.userId.sharedid).to.have.deep.nested.property('id'); + expect(bid.userId.sharedid).to.deep.equal({ + id: 'test_sharedId' + }); + expect(bid.userIdAsEids[0]).to.deep.equal({ + source: 'sharedid.org', + uids: [{ + id: 'test_sharedId', + atype: 1 + }] + }); + }); + }); + coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); + done(); + }, {adUnits}); + }); it('test hook from id5id cookies when refresh needed', function(done) { // simulate existing browser local storage values coreStorage.setCookie('id5id', JSON.stringify({'ID5ID': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); @@ -895,7 +1048,10 @@ describe('User ID', function() { }); it('test hook from liveIntentId cookie', function(done) { - coreStorage.setCookie('_li_pbid', JSON.stringify({'unifiedId': 'random-cookie-identifier', 'segments': ['123']}), (new Date(Date.now() + 100000).toUTCString())); + coreStorage.setCookie('_li_pbid', JSON.stringify({ + 'unifiedId': 'random-cookie-identifier', + 'segments': ['123'] + }), (new Date(Date.now() + 100000).toUTCString())); setSubmoduleRegistry([liveIntentIdSubmodule]); init(config); @@ -967,22 +1123,24 @@ describe('User ID', function() { }, {adUnits}); }); - it('test hook when pubCommonId, unifiedId, id5Id, identityLink, britepoolId and netId have data to pass', function(done) { + it('test hook when pubCommonId, unifiedId, id5Id, identityLink, britepoolId, netId and sharedId have data to pass', function(done) { coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('unifiedid', JSON.stringify({'TDID': 'testunifiedid'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('id5id', JSON.stringify({'ID5ID': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('idl_env', 'AiGNC8Z5ONyZKSpIPf', (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), (new Date(Date.now() + 5000).toUTCString())); + coreStorage.setCookie('sharedid', JSON.stringify({'id': 'test_sharedId', 'ts': 1590525289611}), (new Date(Date.now() + 5000).toUTCString())); - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule]); + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule]); init(config); config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'], ['unifiedId', 'unifiedid', 'cookie'], ['id5Id', 'id5id', 'cookie'], ['identityLink', 'idl_env', 'cookie'], ['britepoolId', 'britepoolid', 'cookie'], - ['netId', 'netId', 'cookie'])); + ['netId', 'netId', 'cookie'], + ['sharedId', 'sharedid', 'cookie'])); requestBidsHook(function() { adUnits.forEach(unit => { @@ -1005,7 +1163,12 @@ describe('User ID', function() { // also check that netId id data was copied to bid expect(bid).to.have.deep.nested.property('userId.netId'); expect(bid.userId.netId).to.equal('testnetId'); - expect(bid.userIdAsEids.length).to.equal(6); + expect(bid).to.have.deep.nested.property('userId.sharedid'); + expect(bid.userId.sharedid).to.deep.equal({ + id: 'test_sharedId', + third: 'test_sharedId' + }); + expect(bid.userIdAsEids.length).to.equal(7); }); }); coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); @@ -1014,17 +1177,37 @@ describe('User ID', function() { coreStorage.setCookie('idl_env', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('britepoolid', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('netId', '', EXPIRED_COOKIE_DATE); + coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); + done(); + }, {adUnits}); + }); + + it('test hook when sharedId (opted out) have data to pass', function(done) { + coreStorage.setCookie('sharedid', JSON.stringify({'id': '00000000000000000000000000', 'ts': 1590525289611}), (new Date(Date.now() + 5000).toUTCString())); + + setSubmoduleRegistry([sharedIdSubmodule]); + init(config); + config.setConfig(getConfigMock(['sharedId', 'sharedid', 'cookie'])); + + requestBidsHook(function() { + adUnits.forEach(unit => { + unit.bids.forEach(bid => { + expect(bid.userIdAsEids).to.be.undefined; + }); + }); + coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); done(); }, {adUnits}); }); - it('test hook when pubCommonId, unifiedId, id5Id, britepoolId and netId have their modules added before and after init', function(done) { + it('test hook when pubCommonId, unifiedId, id5Id, britepoolId, netId and sharedId have their modules added before and after init', function(done) { coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('unifiedid', JSON.stringify({'TDID': 'cookie-value-add-module-variations'}), new Date(Date.now() + 5000).toUTCString()); coreStorage.setCookie('id5id', JSON.stringify({'ID5ID': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('idl_env', 'AiGNC8Z5ONyZKSpIPf', new Date(Date.now() + 5000).toUTCString()); coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), (new Date(Date.now() + 5000).toUTCString())); + coreStorage.setCookie('sharedid', JSON.stringify({'id': 'test_sharedId', 'ts': 1590525289611}), (new Date(Date.now() + 5000).toUTCString())); setSubmoduleRegistry([]); @@ -1039,13 +1222,15 @@ describe('User ID', function() { attachIdSystem(identityLinkSubmodule); attachIdSystem(britepoolIdSubmodule); attachIdSystem(netIdSubmodule); + attachIdSystem(sharedIdSubmodule); config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'], ['unifiedId', 'unifiedid', 'cookie'], ['id5Id', 'id5id', 'cookie'], ['identityLink', 'idl_env', 'cookie'], ['britepoolId', 'britepoolid', 'cookie'], - ['netId', 'netId', 'cookie'])); + ['netId', 'netId', 'cookie'], + ['sharedId', 'sharedid', 'cookie'])); requestBidsHook(function() { adUnits.forEach(unit => { @@ -1068,7 +1253,12 @@ describe('User ID', function() { // also check that britepoolId id data was copied to bid expect(bid).to.have.deep.nested.property('userId.netId'); expect(bid.userId.netId).to.equal('testnetId'); - expect(bid.userIdAsEids.length).to.equal(6); + expect(bid).to.have.deep.nested.property('userId.sharedid'); + expect(bid.userId.sharedid).to.deep.equal({ + id: 'test_sharedId', + third: 'test_sharedId' + }); + expect(bid.userIdAsEids.length).to.equal(7); }); }); coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); @@ -1077,6 +1267,28 @@ describe('User ID', function() { coreStorage.setCookie('idl_env', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('britepoolid', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('netId', '', EXPIRED_COOKIE_DATE); + coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); + done(); + }, {adUnits}); + }); + + it('test hook when sharedId(opted out) have their modules added before and after init', function(done) { + coreStorage.setCookie('sharedid', JSON.stringify({'id': '00000000000000000000000000', 'ts': 1590525289611}), (new Date(Date.now() + 5000).toUTCString())); + + setSubmoduleRegistry([]); + init(config); + + attachIdSystem(sharedIdSubmodule); + + config.setConfig(getConfigMock(['sharedId', 'sharedid', 'cookie'])); + + requestBidsHook(function() { + adUnits.forEach(unit => { + unit.bids.forEach(bid => { + expect(bid.userIdAsEids).to.be.undefined; + }); + }); + coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); done(); }, {adUnits}); }); @@ -1088,28 +1300,31 @@ describe('User ID', function() { coreStorage.setCookie('idl_env', 'AiGNC8Z5ONyZKSpIPf', new Date(Date.now() + 5000).toUTCString()); coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), new Date(Date.now() + 5000).toUTCString()); + coreStorage.setCookie('sharedid', JSON.stringify({'id': 'test_sharedId', 'ts': 1590525289611}), new Date(Date.now() + 5000).toUTCString()); coreStorage.setCookie('MOCKID', JSON.stringify({'MOCKID': '123456778'}), new Date(Date.now() + 5000).toUTCString()); - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule]); + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule]); init(config); config.setConfig({ userSync: { syncDelay: 0, userIds: [{ - name: 'pubCommonId', storage: { name: 'pubcid', type: 'cookie' } + name: 'pubCommonId', storage: {name: 'pubcid', type: 'cookie'} + }, { + name: 'unifiedId', storage: {name: 'unifiedid', type: 'cookie'} }, { - name: 'unifiedId', storage: { name: 'unifiedid', type: 'cookie' } + name: 'id5Id', storage: {name: 'id5id', type: 'cookie'} }, { - name: 'id5Id', storage: { name: 'id5id', type: 'cookie' } + name: 'identityLink', storage: {name: 'idl_env', type: 'cookie'} }, { - name: 'identityLink', storage: { name: 'idl_env', type: 'cookie' } + name: 'britepoolId', storage: {name: 'britepoolid', type: 'cookie'} }, { - name: 'britepoolId', storage: { name: 'britepoolid', type: 'cookie' } + name: 'netId', storage: {name: 'netId', type: 'cookie'} }, { - name: 'netId', storage: { name: 'netId', type: 'cookie' } + name: 'sharedId', storage: {name: 'sharedid', type: 'cookie'} }, { - name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } + name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} }] } }); @@ -1149,10 +1364,16 @@ describe('User ID', function() { // check MockId data was copied to bid expect(bid).to.have.deep.nested.property('userId.netId'); expect(bid.userId.netId).to.equal('testnetId'); + // also check that sharedId id data was copied to bid + expect(bid).to.have.deep.nested.property('userId.sharedid'); + expect(bid.userId.sharedid).to.deep.equal({ + id: 'test_sharedId', + third: 'test_sharedId' + }); // check MockId data was copied to bid expect(bid).to.have.deep.nested.property('userId.mid'); expect(bid.userId.mid).to.equal('123456778'); - expect(bid.userIdAsEids.length).to.equal(6);// mid is unknown for eids.js + expect(bid.userIdAsEids.length).to.equal(7);// mid is unknown for eids.js }); }); coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); @@ -1161,6 +1382,7 @@ describe('User ID', function() { coreStorage.setCookie('idl_env', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('britepoolid', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('netId', '', EXPIRED_COOKIE_DATE); + coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('MOCKID', '', EXPIRED_COOKIE_DATE); done(); }, {adUnits}); @@ -1184,7 +1406,7 @@ describe('User ID', function() { coreStorage.setCookie('_parrable_eid', '', EXPIRED_COOKIE_DATE); }); - it('pubcid callback with url', function () { + it('pubcid callback with url', function() { let adUnits = [getAdUnitMock()]; let innerAdUnits; let customCfg = getConfigMock(['pubCommonId', 'pubcid_alt', 'cookie']); @@ -1193,14 +1415,16 @@ describe('User ID', function() { setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]); init(config); config.setConfig(customCfg); - requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); + requestBidsHook((config) => { + innerAdUnits = config.adUnits + }, {adUnits}); expect(utils.triggerPixel.called).to.be.false; events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); expect(utils.triggerPixel.getCall(0).args[0]).to.include('/any/pubcid/url'); }); - it('unifiedid callback with url', function () { + it('unifiedid callback with url', function() { let adUnits = [getAdUnitMock()]; let innerAdUnits; let customCfg = getConfigMock(['unifiedId', 'unifiedid', 'cookie']); @@ -1209,14 +1433,16 @@ describe('User ID', function() { setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]); init(config); config.setConfig(customCfg); - requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); + requestBidsHook((config) => { + innerAdUnits = config.adUnits + }, {adUnits}); expect(server.requests).to.be.empty; events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); expect(server.requests[0].url).to.equal('/any/unifiedid/url'); }); - it('unifiedid callback with partner', function () { + it('unifiedid callback with partner', function() { let adUnits = [getAdUnitMock()]; let innerAdUnits; let customCfg = getConfigMock(['unifiedId', 'unifiedid', 'cookie']); @@ -1225,7 +1451,9 @@ describe('User ID', function() { setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]); init(config); config.setConfig(customCfg); - requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); + requestBidsHook((config) => { + innerAdUnits = config.adUnits + }, {adUnits}); expect(server.requests).to.be.empty; events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); From 4ec459113ede3d7d8f4d64a569021763c28afa8d Mon Sep 17 00:00:00 2001 From: xwang202 <57196235+xwang202@users.noreply.github.com> Date: Wed, 17 Jun 2020 20:45:49 +0800 Subject: [PATCH 423/496] Freewheel - Converted the ComponentId property to be 'prebid' in request (#5320) * freewheel-ssp fix issue on playerSize of bidRequest * freewheel add dealId property in bidResponse * freewheel convert ComponentID to 'prebid' in request * freewheel add new parameter 'componentSubId' in request --- modules/freewheel-sspBidAdapter.js | 3 ++- .../modules/freewheel-sspBidAdapter_spec.js | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/modules/freewheel-sspBidAdapter.js b/modules/freewheel-sspBidAdapter.js index e1db7d5e1d3..5e3717ce1fe 100644 --- a/modules/freewheel-sspBidAdapter.js +++ b/modules/freewheel-sspBidAdapter.js @@ -261,7 +261,8 @@ export const spec = { reqType: 'AdsSetup', protocolVersion: '2.0', zoneId: zone, - componentId: getComponentId(currentBidRequest.params.format), + componentId: 'prebid', + componentSubId: getComponentId(currentBidRequest.params.format), timestamp: timeInMillis, pKey: keyCode }; diff --git a/test/spec/modules/freewheel-sspBidAdapter_spec.js b/test/spec/modules/freewheel-sspBidAdapter_spec.js index ffb9f1fe431..3047b635d13 100644 --- a/test/spec/modules/freewheel-sspBidAdapter_spec.js +++ b/test/spec/modules/freewheel-sspBidAdapter_spec.js @@ -107,7 +107,8 @@ describe('freewheelSSP BidAdapter Test', () => { expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('mustang'); + expect(payload.componentId).to.equal('prebid'); + expect(payload.componentSubId).to.equal('mustang'); expect(payload.playerSize).to.equal('300x600'); }); @@ -126,7 +127,8 @@ describe('freewheelSSP BidAdapter Test', () => { expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('mustang'); + expect(payload.componentId).to.equal('prebid'); + expect(payload.componentSubId).to.equal('mustang'); expect(payload.playerSize).to.equal('300x600'); expect(payload._fw_us_privacy).to.exist.and.to.be.a('string'); expect(payload._fw_us_privacy).to.equal(uspConsentString); @@ -145,7 +147,8 @@ describe('freewheelSSP BidAdapter Test', () => { expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('mustang'); + expect(payload.componentId).to.equal('prebid'); + expect(payload.componentSubId).to.equal('mustang'); expect(payload.playerSize).to.equal('300x600'); expect(payload._fw_gdpr_consent).to.exist.and.to.be.a('string'); expect(payload._fw_gdpr_consent).to.equal(gdprConsentString); @@ -178,7 +181,8 @@ describe('freewheelSSP BidAdapter Test', () => { expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('mustang'); + expect(payload.componentId).to.equal('prebid'); + expect(payload.componentSubId).to.equal('mustang'); expect(payload.playerSize).to.equal('300x600'); }); @@ -197,7 +201,8 @@ describe('freewheelSSP BidAdapter Test', () => { expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('mustang'); + expect(payload.componentId).to.equal('prebid'); + expect(payload.componentSubId).to.equal('mustang'); expect(payload.playerSize).to.equal('300x600'); expect(payload._fw_us_privacy).to.exist.and.to.be.a('string'); expect(payload._fw_us_privacy).to.equal(uspConsentString); @@ -216,7 +221,8 @@ describe('freewheelSSP BidAdapter Test', () => { expect(payload.reqType).to.equal('AdsSetup'); expect(payload.protocolVersion).to.equal('2.0'); expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('mustang'); + expect(payload.componentId).to.equal('prebid'); + expect(payload.componentSubId).to.equal('mustang'); expect(payload.playerSize).to.equal('300x600'); expect(payload._fw_gdpr_consent).to.exist.and.to.be.a('string'); expect(payload._fw_gdpr_consent).to.equal(gdprConsentString); From eb4bc8548166a0b1b337065960cec2be686a920c Mon Sep 17 00:00:00 2001 From: vladi-mmg Date: Wed, 17 Jun 2020 18:25:18 +0300 Subject: [PATCH 424/496] Marsmedia & videofy adapters - Add onTimeout & onSetTargeting (#5352) * Change publisherId to zoneId Add gdpr Add supply chain Add video media type * Remove comments * Fix unit test coverage * fix request id bug add vastXml to video response * Remove bid response default sizes * Change endpoint url * Add unit test for vastXml * Change end point * Remove trailing-space * Add onBidWon function * New adapter - videofy * Marsmedia & Videofy - Add onTimeout onSetTargeting * Create sendbeacon function --- modules/marsmediaBidAdapter.js | 18 +++++-- modules/videofyBidAdapter.js | 40 +++++++++++++- test/spec/modules/marsmediaBidAdapter_spec.js | 34 ++++++++++++ test/spec/modules/videofyBidAdapter_spec.js | 53 +++++++++++++++++++ 4 files changed, 141 insertions(+), 4 deletions(-) diff --git a/modules/marsmediaBidAdapter.js b/modules/marsmediaBidAdapter.js index 2a2017c4b5c..1ce2558b8de 100644 --- a/modules/marsmediaBidAdapter.js +++ b/modules/marsmediaBidAdapter.js @@ -222,18 +222,30 @@ function MarsmediaAdapter() { }; this.onBidWon = function (bid) { - const cpm = bid.pbMg; if (typeof bid.nurl !== 'undefined') { + const cpm = bid.pbMg; bid.nurl = bid.nurl.replace( /\$\{AUCTION_PRICE\}/, cpm ); utils.triggerPixel(bid.nurl, null); }; + sendbeacon(bid, 17) + }; + + this.onTimeout = function (bid) { + sendbeacon(bid, 19) + }; + + this.onSetTargeting = function (bid) { + sendbeacon(bid, 20) + }; + + function sendbeacon(bid, type) { const bidString = JSON.stringify(bid); const encodedBuf = window.btoa(bidString); - utils.triggerPixel('https://ping-hqx-1.go2speed.media/notification/rtb/beacon/?bt=17&hb_j=' + encodedBuf, null); - }; + utils.triggerPixel('https://ping-hqx-1.go2speed.media/notification/rtb/beacon/?bt=' + type + '&bid=3mhdom&hb_j=' + encodedBuf, null); + } this.interpretResponse = function (serverResponse) { let responses = serverResponse.body || []; diff --git a/modules/videofyBidAdapter.js b/modules/videofyBidAdapter.js index 07e95689ab4..11bc21303fd 100644 --- a/modules/videofyBidAdapter.js +++ b/modules/videofyBidAdapter.js @@ -1,6 +1,7 @@ import { VIDEO } from '../src/mediaTypes.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { Renderer } from '../src/Renderer.js'; +import * as utils from '../src/utils.js'; const BIDDER_CODE = 'videofy'; const TTL = 600; @@ -250,13 +251,50 @@ function getUserSyncs(syncOptions, serverResponses) { } } +function onBidWon(bid) { + sendbeacon(bid, 17); +} + +function onTimeout(bid) { + sendbeacon(bid, 19); +} + +function onSetTargeting(bid) { + sendbeacon(bid, 20); +} + +function sendbeacon(bid, type) { + const bidCopy = { + bidder: bid.bidder, + cpm: bid.cpm, + originalCpm: bid.originalCpm, + currency: bid.currency, + originalCurrency: bid.originalCurrency, + timeToRespond: bid.timeToRespond, + statusMessage: bid.statusMessage, + width: bid.width, + height: bid.height, + size: bid.size, + params: bid.params, + status: bid.status, + adserverTargeting: bid.adserverTargeting, + ttl: bid.ttl + }; + const bidString = JSON.stringify(bidCopy); + const encodedBuf = window.btoa(bidString); + utils.triggerPixel('https://beacon.videofy.io/notification/rtb/beacon/?bt=' + type + '&bid=hcwqso&hb_j=' + encodedBuf, null); +} + export const spec = { code: BIDDER_CODE, supportedMediaTypes: [VIDEO], isBidRequestValid, buildRequests, interpretResponse, - getUserSyncs + getUserSyncs, + onBidWon, + onTimeout, + onSetTargeting }; registerBidder(spec); diff --git a/test/spec/modules/marsmediaBidAdapter_spec.js b/test/spec/modules/marsmediaBidAdapter_spec.js index e02870d9890..b4c2fe68f34 100644 --- a/test/spec/modules/marsmediaBidAdapter_spec.js +++ b/test/spec/modules/marsmediaBidAdapter_spec.js @@ -624,4 +624,38 @@ describe('marsmedia adapter tests', function () { expect(utils.triggerPixel.called).to.equal(true); }); }); + + describe('on Timeout', function () { + beforeEach(function() { + sinon.stub(utils, 'triggerPixel'); + }); + afterEach(function() { + utils.triggerPixel.restore(); + }); + it('exists and is a function', () => { + expect(spec.onTimeout).to.exist.and.to.be.a('function'); + }); + it('should return nothing', function () { + var response = spec.onTimeout({}); + expect(response).to.be.an('undefined') + expect(utils.triggerPixel.called).to.equal(true); + }); + }); + + describe('on Set Targeting', function () { + beforeEach(function() { + sinon.stub(utils, 'triggerPixel'); + }); + afterEach(function() { + utils.triggerPixel.restore(); + }); + it('exists and is a function', () => { + expect(spec.onSetTargeting).to.exist.and.to.be.a('function'); + }); + it('should return nothing', function () { + var response = spec.onSetTargeting({}); + expect(response).to.be.an('undefined') + expect(utils.triggerPixel.called).to.equal(true); + }); + }); }); diff --git a/test/spec/modules/videofyBidAdapter_spec.js b/test/spec/modules/videofyBidAdapter_spec.js index e221ece45b8..270eefd1efc 100644 --- a/test/spec/modules/videofyBidAdapter_spec.js +++ b/test/spec/modules/videofyBidAdapter_spec.js @@ -1,5 +1,7 @@ import { spec } from 'modules/videofyBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; +import * as utils from '../../../src/utils.js'; + const { expect } = require('chai'); describe('Videofy Bid Adapter Test', function () { @@ -197,4 +199,55 @@ describe('Videofy Bid Adapter Test', function () { expect(pixel.type).to.equal('iframe'); }); }); + + describe('on bidWon', function () { + beforeEach(function() { + sinon.stub(utils, 'triggerPixel'); + }); + afterEach(function() { + utils.triggerPixel.restore(); + }); + it('exists and is a function', () => { + expect(spec.onBidWon).to.exist.and.to.be.a('function'); + }); + it('should return nothing', function () { + var response = spec.onBidWon({}); + expect(response).to.be.an('undefined') + expect(utils.triggerPixel.called).to.equal(true); + }); + }); + + describe('on Timeout', function () { + beforeEach(function() { + sinon.stub(utils, 'triggerPixel'); + }); + afterEach(function() { + utils.triggerPixel.restore(); + }); + it('exists and is a function', () => { + expect(spec.onTimeout).to.exist.and.to.be.a('function'); + }); + it('should return nothing', function () { + var response = spec.onTimeout({}); + expect(response).to.be.an('undefined') + expect(utils.triggerPixel.called).to.equal(true); + }); + }); + + describe('on Set Targeting', function () { + beforeEach(function() { + sinon.stub(utils, 'triggerPixel'); + }); + afterEach(function() { + utils.triggerPixel.restore(); + }); + it('exists and is a function', () => { + expect(spec.onSetTargeting).to.exist.and.to.be.a('function'); + }); + it('should return nothing', function () { + var response = spec.onSetTargeting({}); + expect(response).to.be.an('undefined') + expect(utils.triggerPixel.called).to.equal(true); + }); + }); }); From 5ac08c6e017c90432a29ae46b1289935c28ddad7 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Thu, 18 Jun 2020 11:05:36 -0700 Subject: [PATCH 425/496] PubMatic bid adapter to support price floors module (#5387) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * added support for floors module * using floorModule to set floor * removed commented console.log statements --- modules/pubmaticBidAdapter.js | 26 ++++++ test/spec/modules/pubmaticBidAdapter_spec.js | 84 ++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 4502dc66a65..8a05a1c90df 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -586,11 +586,37 @@ function _createImpressionObject(bid, conf) { impObj.banner = bannerObj; } + _addFloorFromFloorModule(impObj, bid); + return impObj.hasOwnProperty(BANNER) || impObj.hasOwnProperty(NATIVE) || impObj.hasOwnProperty(VIDEO) ? impObj : UNDEFINED; } +function _addFloorFromFloorModule(impObj, bid) { + let bidFloor = -1; + // get lowest floor from floorModule + if (typeof bid.getFloor === 'function' && !config.getConfig('pubmatic.disableFloors')) { + [BANNER, VIDEO, NATIVE].forEach(mediaType => { + if (impObj.hasOwnProperty(mediaType)) { + let floorInfo = bid.getFloor({ currency: impObj.bidfloorcur, mediaType: mediaType, size: '*' }); + if (typeof floorInfo === 'object' && floorInfo.currency === impObj.bidfloorcur && !isNaN(parseInt(floorInfo.floor))) { + let mediaTypeFloor = parseFloat(floorInfo.floor); + bidFloor = (bidFloor == -1 ? mediaTypeFloor : Math.min(mediaTypeFloor, bidFloor)) + } + } + }); + } + // get highest from impObj.bidfllor and floor from floor module + // as we are using Math.max, it is ok if we have not got any floor from floorModule, then value of bidFloor will be -1 + if (impObj.bidfloor) { + bidFloor = Math.max(bidFloor, impObj.bidfloor) + } + + // assign value only if bidFloor is > 0 + impObj.bidfloor = ((!isNaN(bidFloor) && bidFloor > 0) ? bidFloor : UNDEFINED); +} + function _getDigiTrustObject(key) { function getDigiTrustId() { let digiTrustUser = window.DigiTrust && (config.getConfig('digiTrustId') || window.DigiTrust.getUser({member: key})); diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 817661ef51f..00d36e483d6 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -1107,6 +1107,90 @@ describe('PubMatic adapter', function () { expect(data2.regs).to.equal(undefined);// USP/CCPAs }); + describe('setting imp.floor using floorModule', function() { + /* + Use the minimum value among floor from floorModule per mediaType + If params.adfloor is set then take max(kadfloor, min(floors from floorModule)) + set imp.bidfloor only if it is more than 0 + */ + + let newRequest; + let floorModuleTestData; + let getFloor = function(req) { + return floorModuleTestData[req.mediaType]; + }; + + beforeEach(() => { + floorModuleTestData = { + 'banner': { + 'currency': 'USD', + 'floor': 1.50 + }, + 'video': { + 'currency': 'USD', + 'floor': 2.50 + }, + 'native': { + 'currency': 'USD', + 'floor': 3.50 + } + }; + newRequest = utils.deepClone(bannerVideoAndNativeBidRequests); + newRequest[0].getFloor = getFloor; + }); + + it('bidfloor should be undefined if calculation is <= 0', function() { + floorModuleTestData.banner.floor = 0; // lowest of them all + newRequest[0].params.kadfloor = undefined; + let request = spec.buildRequests(newRequest); + let data = JSON.parse(request.data); + data = data.imp[0]; + expect(data.bidfloor).to.equal(undefined); + }); + + it('ignore floormodule o/p if floor is not number', function() { + floorModuleTestData.banner.floor = 'INR'; + newRequest[0].params.kadfloor = undefined; + let request = spec.buildRequests(newRequest); + let data = JSON.parse(request.data); + data = data.imp[0]; + expect(data.bidfloor).to.equal(2.5); // video will be lowest now + }); + + it('ignore floormodule o/p if currency is not matched', function() { + floorModuleTestData.banner.currency = 'INR'; + newRequest[0].params.kadfloor = undefined; + let request = spec.buildRequests(newRequest); + let data = JSON.parse(request.data); + data = data.imp[0]; + expect(data.bidfloor).to.equal(2.5); // video will be lowest now + }); + + it('kadfloor is not passed, use minimum from floorModule', function() { + newRequest[0].params.kadfloor = undefined; + let request = spec.buildRequests(newRequest); + let data = JSON.parse(request.data); + data = data.imp[0]; + expect(data.bidfloor).to.equal(1.5); + }); + + it('kadfloor is passed as 3, use kadfloor as it is highest', function() { + newRequest[0].params.kadfloor = '3.0';// yes, we want it as a string + let request = spec.buildRequests(newRequest); + let data = JSON.parse(request.data); + data = data.imp[0]; + expect(data.bidfloor).to.equal(3); + }); + + it('kadfloor is passed as 1, use min of fllorModule as it is highest', function() { + newRequest[0].params.kadfloor = '1.0';// yes, we want it as a string + let request = spec.buildRequests(newRequest); + let data = JSON.parse(request.data); + data = data.imp[0]; + expect(data.bidfloor).to.equal(1.5); + }); + }); + it('Request should have digitrust params', function() { window.DigiTrust = { getUser: function () { From 9b4def57762bb73f0db0084459ed1ba76ef17350 Mon Sep 17 00:00:00 2001 From: colbertk <50499465+colbertk@users.noreply.github.com> Date: Thu, 18 Jun 2020 14:15:36 -0400 Subject: [PATCH 426/496] Triplelift Adaptor: Use Floors Module (#5329) * access floor from floors module * int -> float and null check * let -> const --- modules/tripleliftBidAdapter.js | 18 +++++++++++++++++- test/spec/modules/tripleliftBidAdapter_spec.js | 9 +++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/modules/tripleliftBidAdapter.js b/modules/tripleliftBidAdapter.js index 8b21f334233..af904aedc11 100644 --- a/modules/tripleliftBidAdapter.js +++ b/modules/tripleliftBidAdapter.js @@ -111,7 +111,7 @@ function _buildPostBody(bidRequests) { return { id: index, tagid: bid.params.inventoryCode, - floor: bid.params.floor, + floor: _getFloor(bid), banner: { format: _sizes(bid.sizes) } @@ -138,6 +138,22 @@ function _buildPostBody(bidRequests) { return data; } +function _getFloor (bid) { + let floor = null; + if (typeof bid.getFloor === 'function') { + const floorInfo = bid.getFloor({ + currency: 'USD', + mediaType: 'banner', + size: _sizes(bid.sizes) + }); + if (typeof floorInfo === 'object' && + floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) { + floor = parseFloat(floorInfo.floor); + } + } + return floor !== null ? floor : bid.params.floor; +} + function getUnifiedIdEids(bidRequests) { return getEids(bidRequests, 'tdid', 'adserver.org', 'TDID'); } diff --git a/test/spec/modules/tripleliftBidAdapter_spec.js b/test/spec/modules/tripleliftBidAdapter_spec.js index 675b8b6c532..73373293114 100644 --- a/test/spec/modules/tripleliftBidAdapter_spec.js +++ b/test/spec/modules/tripleliftBidAdapter_spec.js @@ -299,6 +299,15 @@ describe('triplelift adapter', function () { const { data: payload } = request; expect(payload.ext).to.deep.equal(undefined); }); + it('should get floor from floors module if available', function() { + const floorInfo = { + currency: 'USD', + floor: 1.99 + }; + bidRequests[0].getFloor = () => floorInfo; + const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); + expect(request.data.imp[0].floor).to.equal(1.99); + }); }); describe('interpretResponse', function () { From a394bc62aabbc87afefe55bcb905e17ad2ca7523 Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Fri, 19 Jun 2020 11:06:10 -0400 Subject: [PATCH 427/496] appnexusBidAdapter - fix video params (#5394) * appnexusBidAdapter - fix video params * remove mimes field --- modules/appnexusBidAdapter.js | 35 ++++++++++++++++++-- modules/appnexusBidAdapter.md | 2 +- test/spec/modules/appnexusBidAdapter_spec.js | 4 +-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 5e3b6a06011..d853ca184ce 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -11,11 +11,29 @@ import { getStorageManager } from '../src/storageManager.js'; const BIDDER_CODE = 'appnexus'; const URL = 'https://ib.adnxs.com/ut/v3/prebid'; -const VIDEO_TARGETING = ['id', 'mimes', 'minduration', 'maxduration', - 'startdelay', 'skippable', 'playback_method', 'frameworks']; +const VIDEO_TARGETING = ['id', 'minduration', 'maxduration', + 'skippable', 'playback_method', 'frameworks', 'context', 'skipoffset']; const USER_PARAMS = ['age', 'externalUid', 'segments', 'gender', 'dnt', 'language']; const APP_DEVICE_PARAMS = ['geo', 'device_id']; // appid is collected separately const DEBUG_PARAMS = ['enabled', 'dongle', 'member_id', 'debug_timeout']; +const VIDEO_MAPPING = { + playback_method: { + 'unknown': 0, + 'auto_play_sound_on': 1, + 'auto_play_sound_off': 2, + 'click_to_play': 3, + 'mouse_over': 4, + 'auto_play_sound_unknown': 5 + }, + context: { + 'unknown': 0, + 'pre_roll': 1, + 'mid_roll': 2, + 'post_roll': 3, + 'outstream': 4, + 'in-banner': 5 + } +}; const NATIVE_MAPPING = { body: 'description', body2: 'desc2', @@ -711,7 +729,18 @@ function bidToTag(bid) { // place any valid video params on the tag Object.keys(bid.params.video) .filter(param => includes(VIDEO_TARGETING, param)) - .forEach(param => tag.video[param] = bid.params.video[param]); + .forEach(param => { + switch (param) { + case 'context': + case 'playback_method': + let type = bid.params.video[param]; + type = (utils.isArray(type)) ? type[0] : type; + tag.video[param] = VIDEO_MAPPING[param][type]; + break; + default: + tag.video[param] = bid.params.video[param]; + } + }); } if (bid.renderer) { diff --git a/modules/appnexusBidAdapter.md b/modules/appnexusBidAdapter.md index a1d12243888..6ec40e83b41 100644 --- a/modules/appnexusBidAdapter.md +++ b/modules/appnexusBidAdapter.md @@ -99,7 +99,7 @@ var adUnits = [ placementId: 13232385, video: { skippable: true, - playback_method: ['auto_play_sound_off'] + playback_method: 'auto_play_sound_off' } } } diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js index 7d6f9c6789c..a0ed6af6b89 100644 --- a/test/spec/modules/appnexusBidAdapter_spec.js +++ b/test/spec/modules/appnexusBidAdapter_spec.js @@ -248,12 +248,12 @@ describe('AppNexusAdapter', function () { const payload = JSON.parse(request.data); expect(payload.tags[0].video).to.deep.equal({ skippable: true, - playback_method: ['auto_play_sound_off'], + playback_method: 2, custom_renderer_present: true }); expect(payload.tags[1].video).to.deep.equal({ skippable: true, - playback_method: ['auto_play_sound_off'] + playback_method: 2 }); }); From aa877b2dea15763f3da25e835350f3c54df10b54 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Fri, 19 Jun 2020 08:21:20 -0700 Subject: [PATCH 428/496] PubMatic adds support for bidUserIdAsEids (#5397) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * id value should be string only * id value should be string; changed test data * pubmatic using userIdAsEids commented unnecessary code PubMatic will no longer read Digitrust from config or independent library setup PubMatic will no loner read TTDID from config or independent library setup * chnages in test cases for userIdAsEids commented unnecessary test cases PubMatic will no longer read Digitrust from config or independent library setup PubMatic will no loner read TTDID from config or independent library setup * deleted commented code and test cases * deleted a commented line * lint effect --- modules/pubmaticBidAdapter.js | 88 +-- test/spec/modules/pubmaticBidAdapter_spec.js | 530 +++---------------- 2 files changed, 82 insertions(+), 536 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 8a05a1c90df..7314d81aee6 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -10,7 +10,6 @@ const USER_SYNC_URL_IFRAME = 'https://ads.pubmatic.com/AdServer/js/showad.js#PIX const USER_SYNC_URL_IMAGE = 'https://image8.pubmatic.com/AdServer/ImgSync?p='; const DEFAULT_CURRENCY = 'USD'; const AUCTION_TYPE = 1; -const PUBMATIC_DIGITRUST_KEY = 'nFIn8aLzbd'; const UNDEFINED = undefined; const DEFAULT_WIDTH = 0; const DEFAULT_HEIGHT = 0; @@ -617,91 +616,10 @@ function _addFloorFromFloorModule(impObj, bid) { impObj.bidfloor = ((!isNaN(bidFloor) && bidFloor > 0) ? bidFloor : UNDEFINED); } -function _getDigiTrustObject(key) { - function getDigiTrustId() { - let digiTrustUser = window.DigiTrust && (config.getConfig('digiTrustId') || window.DigiTrust.getUser({member: key})); - return (digiTrustUser && digiTrustUser.success && digiTrustUser.identity) || null; - } - let digiTrustId = getDigiTrustId(); - // Verify there is an ID and this user has not opted out - if (!digiTrustId || (digiTrustId.privacy && digiTrustId.privacy.optout)) { - return null; - } - return digiTrustId; -} - -function _handleDigitrustId(eids) { - let digiTrustId = _getDigiTrustObject(PUBMATIC_DIGITRUST_KEY); - if (digiTrustId !== null) { - eids.push({ - 'source': 'digitru.st', - 'uids': [{ - 'id': digiTrustId.id || '', - 'atype': 1, - 'ext': { - 'keyv': parseInt(digiTrustId.keyv) || 0 - } - }] - }); - } -} - -function _handleTTDId(eids, validBidRequests) { - let ttdId = null; - let adsrvrOrgId = config.getConfig('adsrvrOrgId'); - if (utils.isStr(utils.deepAccess(validBidRequests, '0.userId.tdid'))) { - ttdId = validBidRequests[0].userId.tdid; - } else if (adsrvrOrgId && utils.isStr(adsrvrOrgId.TDID)) { - ttdId = adsrvrOrgId.TDID; - } - - if (ttdId !== null) { - eids.push({ - 'source': 'adserver.org', - 'uids': [{ - 'id': ttdId, - 'atype': 1, - 'ext': { - 'rtiPartner': 'TDID' - } - }] - }); - } -} - -/** - * Produces external userid object in ortb 3.0 model. - */ -function _addExternalUserId(eids, value, source, atype) { - if (utils.isStr(value)) { - eids.push({ - source, - uids: [{ - id: value, - atype - }] - }); - } -} - function _handleEids(payload, validBidRequests) { - let eids = []; - _handleDigitrustId(eids); - _handleTTDId(eids, validBidRequests); - const bidRequest = validBidRequests[0]; - if (bidRequest && bidRequest.userId) { - _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.pubcid`), 'pubcid.org', 1); - _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.digitrustid.data.id`), 'digitru.st', 1); - _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.id5id`), 'id5-sync.com', 1); - _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.criteoId`), 'criteo.com', 1);// replacing criteoRtus - _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.idl_env`), 'liveramp.com', 1); - _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.lipb.lipbid`), 'liveintent.com', 1); - _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.parrableid`), 'parrable.com', 1); - _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.britepoolid`), 'britepool.com', 1); - _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.netId`), 'netid.de', 1); - } - if (eids.length > 0) { - payload.user.eids = eids; + const bidUserIdAsEids = utils.deepAccess(validBidRequests, '0.userIdAsEids'); + if (utils.isArray(bidUserIdAsEids) && bidUserIdAsEids.length > 0) { + utils.deepSetValue(payload, 'user.eids', bidUserIdAsEids); } } diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 00d36e483d6..45259767133 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -2,6 +2,7 @@ import {expect} from 'chai'; import {spec} from 'modules/pubmaticBidAdapter.js'; import * as utils from 'src/utils.js'; import {config} from 'src/config.js'; +import { createEidsArray } from 'modules/userId/eids.js'; const constants = require('src/constants.json'); describe('PubMatic adapter', function () { @@ -1191,318 +1192,48 @@ describe('PubMatic adapter', function () { }); }); - it('Request should have digitrust params', function() { - window.DigiTrust = { - getUser: function () { - } - }; - var bidRequest = {}; - let sandbox = sinon.sandbox.create(); - sandbox.stub(window.DigiTrust, 'getUser').callsFake(() => - ({ - success: true, - identity: { - privacy: {optout: false}, - id: 'testId', - keyv: 4 - } - }) - ); - - let request = spec.buildRequests(bidRequests, bidRequest); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'digitru.st', - 'uids': [{ - 'id': 'testId', - 'atype': 1, - 'ext': { - 'keyv': 4 - } - }] - }]); - sandbox.restore(); - delete window.DigiTrust; - }); - - it('Request should not have digitrust params when DigiTrust not loaded', function() { - let request = spec.buildRequests(bidRequests, {}); + it('should NOT include coppa flag in bid request if coppa config is not present', () => { + const request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); + if (data.regs) { + // in case GDPR is set then data.regs will exist + expect(data.regs.coppa).to.equal(undefined); + } else { + expect(data.regs).to.equal(undefined); + } }); - it('Request should not have digitrust params due to optout', function() { - window.DigiTrust = { - getUser: function () { - } - }; + it('should include coppa flag in bid request if coppa is set to true', () => { let sandbox = sinon.sandbox.create(); - sandbox.stub(window.DigiTrust, 'getUser').callsFake(() => - ({ - success: true, - identity: { - privacy: {optout: true}, - id: 'testId', - keyv: 4 - } - }) - ); - - let request = spec.buildRequests(bidRequests, {}); + sandbox.stub(config, 'getConfig').callsFake(key => { + const config = { + 'coppa': true + }; + return config[key]; + }); + const request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); + expect(data.regs.coppa).to.equal(1); sandbox.restore(); - delete window.DigiTrust; }); - it('Request should not have digitrust params due to failure', function() { - window.DigiTrust = { - getUser: function () { - } - }; + it('should NOT include coppa flag in bid request if coppa is set to false', () => { let sandbox = sinon.sandbox.create(); - sandbox.stub(window.DigiTrust, 'getUser').callsFake(() => - ({ - success: false, - identity: { - privacy: {optout: false}, - id: 'testId', - keyv: 4 - } - }) - ); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); - sandbox.restore(); - delete window.DigiTrust; - }); - - describe('DigiTrustId from config', function() { - var origGetConfig; - let sandbox; - beforeEach(() => { - sandbox = sinon.sandbox.create(); - window.DigiTrust = { - getUser: sandbox.spy() + sandbox.stub(config, 'getConfig').callsFake(key => { + const config = { + 'coppa': false }; + return config[key]; }); - - afterEach(() => { - sandbox.restore(); - delete window.DigiTrust; - }); - - it('Request should have digiTrustId config params', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - digiTrustId: { - success: true, - identity: { - privacy: {optout: false}, - id: 'testId', - keyv: 4 - } - } - }; - return config[key]; - }); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'digitru.st', - 'uids': [{ - 'id': 'testId', - 'atype': 1, - 'ext': { - 'keyv': 4 - } - }] - }]); - // should not have called DigiTrust.getUser() - expect(window.DigiTrust.getUser.notCalled).to.equal(true); - }); - - it('Request should not have digiTrustId config params due to optout', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - digiTrustId: { - success: true, - identity: { - privacy: {optout: true}, - id: 'testId', - keyv: 4 - } - } - } - return config[key]; - }); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); - // should not have called DigiTrust.getUser() - expect(window.DigiTrust.getUser.notCalled).to.equal(true); - }); - - it('Request should not have digiTrustId config params due to failure', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - digiTrustId: { - success: false, - identity: { - privacy: {optout: false}, - id: 'testId', - keyv: 4 - } - } - } - return config[key]; - }); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); - // should not have called DigiTrust.getUser() - expect(window.DigiTrust.getUser.notCalled).to.equal(true); - }); - - it('Request should not have digiTrustId config params if they do not exist', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = {}; - return config[key]; - }); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); - // should have called DigiTrust.getUser() once - expect(window.DigiTrust.getUser.calledOnce).to.equal(true); - }); - - it('should NOT include coppa flag in bid request if coppa config is not present', () => { - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - if (data.regs) { - // in case GDPR is set then data.regs will exist - expect(data.regs.coppa).to.equal(undefined); - } else { - expect(data.regs).to.equal(undefined); - } - }); - - it('should include coppa flag in bid request if coppa is set to true', () => { - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'coppa': true - }; - return config[key]; - }); - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.regs.coppa).to.equal(1); - }); - - it('should NOT include coppa flag in bid request if coppa is set to false', () => { - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'coppa': false - }; - return config[key]; - }); - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - if (data.regs) { - // in case GDPR is set then data.regs will exist - expect(data.regs.coppa).to.equal(undefined); - } else { - expect(data.regs).to.equal(undefined); - } - }); - }); - - describe('AdsrvrOrgId from config', function() { - let sandbox; - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('Request should have adsrvrOrgId config params', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - adsrvrOrgId: { - 'TDID': '5e740345-c25e-436d-b466-5f2f9fa95c17', - 'TDID_LOOKUP': 'TRUE', - 'TDID_CREATED_AT': '2018-10-01T07:05:40' - } - }; - return config[key]; - }); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'adserver.org', - 'uids': [{ - 'id': '5e740345-c25e-436d-b466-5f2f9fa95c17', - 'atype': 1, - 'ext': { - 'rtiPartner': 'TDID' - } - }] - }]); - }); - - it('Request should NOT have adsrvrOrgId config params if id in adsrvrOrgId is NOT string', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - adsrvrOrgId: { - 'TDID': 1, - 'TDID_LOOKUP': 'TRUE', - 'TDID_CREATED_AT': '2018-10-01T07:05:40' - } - }; - return config[key]; - }); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); - }); - - it('Request should NOT have adsrvrOrgId config params if adsrvrOrgId is NOT object', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - adsrvrOrgId: null - }; - return config[key]; - }); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); - }); - - it('Request should NOT have adsrvrOrgId config params if id in adsrvrOrgId is NOT set', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - adsrvrOrgId: { - 'TDID_LOOKUP': 'TRUE', - 'TDID_CREATED_AT': '2018-10-01T07:05:40' - } - }; - return config[key]; - }); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); - }); + const request = spec.buildRequests(bidRequests, {}); + let data = JSON.parse(request.data); + if (data.regs) { + // in case GDPR is set then data.regs will exist + expect(data.regs.coppa).to.equal(undefined); + } else { + expect(data.regs).to.equal(undefined); + } + sandbox.restore(); }); describe('AdsrvrOrgId from userId module', function() { @@ -1518,6 +1249,7 @@ describe('PubMatic adapter', function () { it('Request should have AdsrvrOrgId config params', function() { bidRequests[0].userId = {}; bidRequests[0].userId.tdid = 'TTD_ID_FROM_USER_ID_MODULE'; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ @@ -1545,6 +1277,7 @@ describe('PubMatic adapter', function () { }); bidRequests[0].userId = {}; bidRequests[0].userId.tdid = 'TTD_ID_FROM_USER_ID_MODULE'; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ @@ -1575,161 +1308,12 @@ describe('PubMatic adapter', function () { }); }); - describe('AdsrvrOrgId and Digitrust', function() { - // here we are considering cases only of accepting DigiTrustId from config - let sandbox; - beforeEach(() => { - sandbox = sinon.sandbox.create(); - window.DigiTrust = { - getUser: sandbox.spy() - }; - }); - - afterEach(() => { - sandbox.restore(); - delete window.DigiTrust; - }); - - it('Request should have id of both AdsrvrOrgId and Digitrust if both have returned valid ids', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - adsrvrOrgId: { - 'TDID': '5e740345-c25e-436d-b466-5f2f9fa95c17', - 'TDID_LOOKUP': 'TRUE', - 'TDID_CREATED_AT': '2018-10-01T07:05:40' - }, - digiTrustId: { - success: true, - identity: { - privacy: {optout: false}, - id: 'testId', - keyv: 4 - } - } - }; - return config[key]; - }); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'digitru.st', - 'uids': [{ - 'id': 'testId', - 'atype': 1, - 'ext': { - 'keyv': 4 - } - }] - }, { - 'source': 'adserver.org', - 'uids': [{ - 'id': '5e740345-c25e-436d-b466-5f2f9fa95c17', - 'atype': 1, - 'ext': { - 'rtiPartner': 'TDID' - } - }] - }]); - }); - - it('Request should have id of only AdsrvrOrgId and NOT Digitrust if only AdsrvrOrgId have returned valid id', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - adsrvrOrgId: { - 'TDID': '5e740345-c25e-436d-b466-5f2f9fa95c17', - 'TDID_LOOKUP': 'TRUE', - 'TDID_CREATED_AT': '2018-10-01T07:05:40' - }, - digiTrustId: { - success: true, - identity: { - privacy: {optout: true}, - id: 'testId', - keyv: 4 - } - } - }; - return config[key]; - }); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'adserver.org', - 'uids': [{ - 'id': '5e740345-c25e-436d-b466-5f2f9fa95c17', - 'atype': 1, - 'ext': { - 'rtiPartner': 'TDID' - } - }] - }]); - }); - - it('Request should have id of only Digitrust and NOT AdsrvrOrgId if only Digitrust have returned valid id', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - adsrvrOrgId: { - 'TDID_LOOKUP': 'TRUE', - 'TDID_CREATED_AT': '2018-10-01T07:05:40' - }, - digiTrustId: { - success: true, - identity: { - privacy: {optout: false}, - id: 'testId', - keyv: 4 - } - } - }; - return config[key]; - }); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'digitru.st', - 'uids': [{ - 'id': 'testId', - 'atype': 1, - 'ext': { - 'keyv': 4 - } - }] - }]); - }); - - it('Request should NOT have id of Digitrust and NOT AdsrvrOrgId if only both have NOT returned valid ids', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - adsrvrOrgId: { - 'TDID_LOOKUP': 'TRUE', - 'TDID_CREATED_AT': '2018-10-01T07:05:40' - }, - digiTrustId: { - success: true, - identity: { - privacy: {optout: true}, - id: 'testId', - keyv: 4 - } - } - }; - return config[key]; - }); - - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); - }); - }); - describe('UserIds from request', function() { describe('pubcommon Id', function() { it('send the pubcommon id if it is present', function() { bidRequests[0].userId = {}; bidRequests[0].userId.pubcid = 'pub_common_user_id'; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ @@ -1744,18 +1328,22 @@ describe('PubMatic adapter', function () { it('do not pass if not string', function() { bidRequests[0].userId = {}; bidRequests[0].userId.pubcid = 1; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.pubcid = []; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.pubcid = null; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.pubcid = {}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); @@ -1766,6 +1354,7 @@ describe('PubMatic adapter', function () { it('send the digitrust id if it is present', function() { bidRequests[0].userId = {}; bidRequests[0].userId.digitrustid = {data: {id: 'digitrust_user_id'}}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ @@ -1780,18 +1369,22 @@ describe('PubMatic adapter', function () { it('do not pass if not string', function() { bidRequests[0].userId = {}; bidRequests[0].userId.digitrustid = {data: {id: 1}}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.digitrustid = {data: {id: []}}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.digitrustid = {data: {id: null}}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.digitrustid = {data: {id: {}}}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); @@ -1802,6 +1395,7 @@ describe('PubMatic adapter', function () { it('send the id5 id if it is present', function() { bidRequests[0].userId = {}; bidRequests[0].userId.id5id = 'id5-user-id'; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ @@ -1816,18 +1410,22 @@ describe('PubMatic adapter', function () { it('do not pass if not string', function() { bidRequests[0].userId = {}; bidRequests[0].userId.id5id = 1; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.id5id = []; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.id5id = null; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.id5id = {}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); @@ -1838,6 +1436,7 @@ describe('PubMatic adapter', function () { it('send the criteo id if it is present', function() { bidRequests[0].userId = {}; bidRequests[0].userId.criteoId = 'criteo-user-id'; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ @@ -1852,18 +1451,22 @@ describe('PubMatic adapter', function () { it('do not pass if not string', function() { bidRequests[0].userId = {}; bidRequests[0].userId.criteoId = 1; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.criteoId = []; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.criteoId = null; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.criteoId = {}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); @@ -1874,6 +1477,7 @@ describe('PubMatic adapter', function () { it('send the identity-link id if it is present', function() { bidRequests[0].userId = {}; bidRequests[0].userId.idl_env = 'identity-link-user-id'; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ @@ -1888,18 +1492,22 @@ describe('PubMatic adapter', function () { it('do not pass if not string', function() { bidRequests[0].userId = {}; bidRequests[0].userId.idl_env = 1; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.idl_env = []; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.idl_env = null; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.idl_env = {}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); @@ -1910,6 +1518,7 @@ describe('PubMatic adapter', function () { it('send the LiveIntent id if it is present', function() { bidRequests[0].userId = {}; bidRequests[0].userId.lipb = { lipbid: 'live-intent-user-id' }; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ @@ -1924,18 +1533,22 @@ describe('PubMatic adapter', function () { it('do not pass if not string', function() { bidRequests[0].userId = {}; bidRequests[0].userId.lipb = { lipbid: 1 }; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.lipb.lipbid = []; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.lipb.lipbid = null; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.lipb.lipbid = {}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); @@ -1946,6 +1559,7 @@ describe('PubMatic adapter', function () { it('send the Parrable id if it is present', function() { bidRequests[0].userId = {}; bidRequests[0].userId.parrableid = 'parrable-user-id'; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ @@ -1960,18 +1574,22 @@ describe('PubMatic adapter', function () { it('do not pass if not string', function() { bidRequests[0].userId = {}; bidRequests[0].userId.parrableid = 1; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.parrableid = []; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.parrableid = null; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.parrableid = {}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); @@ -1982,6 +1600,7 @@ describe('PubMatic adapter', function () { it('send the Britepool id if it is present', function() { bidRequests[0].userId = {}; bidRequests[0].userId.britepoolid = 'britepool-user-id'; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ @@ -1996,18 +1615,22 @@ describe('PubMatic adapter', function () { it('do not pass if not string', function() { bidRequests[0].userId = {}; bidRequests[0].userId.britepoolid = 1; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.britepoolid = []; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.britepoolid = null; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.britepoolid = {}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); @@ -2018,6 +1641,7 @@ describe('PubMatic adapter', function () { it('send the NetId if it is present', function() { bidRequests[0].userId = {}; bidRequests[0].userId.netId = 'netid-user-id'; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ @@ -2032,18 +1656,22 @@ describe('PubMatic adapter', function () { it('do not pass if not string', function() { bidRequests[0].userId = {}; bidRequests[0].userId.netId = 1; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.netId = []; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.netId = null; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); bidRequests[0].userId.netId = {}; + bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); request = spec.buildRequests(bidRequests, {}); data = JSON.parse(request.data); expect(data.user.eids).to.equal(undefined); From 4e59331aa49bc612657cd705113a511aa6e2fe38 Mon Sep 17 00:00:00 2001 From: lowendavid <66423906+lowendavid@users.noreply.github.com> Date: Mon, 22 Jun 2020 09:28:43 +0200 Subject: [PATCH 429/496] External ids (#5351) * externalIds (SIM-657) Added external ids and associated unit test. * externalIds - Added DEFAULT_PARAMS_WITH_EIDS that contains the external id information for the unit test * externalIds (SIM-657) uses createEidsArray found in the eid.js * externalIds cleanup spaces and tabs, adding a missing import for createEids in eids.js * externalIds adding a space where it is needed to fix a wonderful test. --- modules/smartadserverBidAdapter.js | 7 ++ .../modules/smartadserverBidAdapter_spec.js | 66 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/modules/smartadserverBidAdapter.js b/modules/smartadserverBidAdapter.js index 15808a516c8..97dd43fc5ba 100644 --- a/modules/smartadserverBidAdapter.js +++ b/modules/smartadserverBidAdapter.js @@ -9,6 +9,9 @@ import { import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { + createEidsArray +} from './userId/eids.js'; const BIDDER_CODE = 'smartadserver'; export const spec = { code: BIDDER_CODE, @@ -99,6 +102,10 @@ export const spec = { payload.gdpr = bidderRequest.gdprConsent.gdprApplies; // we're handling the undefined case server side } + if (bid && bid.userId) { + payload.eids = createEidsArray(bid.userId); + } + if (bidderRequest && bidderRequest.uspConsent) { payload.us_privacy = bidderRequest.uspConsent; } diff --git a/test/spec/modules/smartadserverBidAdapter_spec.js b/test/spec/modules/smartadserverBidAdapter_spec.js index 5e6397f1b2e..2faad47aca8 100644 --- a/test/spec/modules/smartadserverBidAdapter_spec.js +++ b/test/spec/modules/smartadserverBidAdapter_spec.js @@ -42,6 +42,45 @@ describe('Smart bid adapter tests', function () { transactionId: 'zsfgzzg' }]; + var DEFAULT_PARAMS_WITH_EIDS = [{ + adUnitCode: 'sas_42', + bidId: 'abcd1234', + mediaTypes: { + banner: { + sizes: [ + [300, 250], + [300, 200] + ] + } + }, + bidder: 'smartadserver', + params: { + domain: 'https://prg.smartadserver.com', + siteId: '1234', + pageId: '5678', + formatId: '90', + target: 'test=prebid', + bidfloor: 0.420, + buId: '7569', + appName: 'Mozilla', + ckId: 42 + }, + requestId: 'efgh5678', + transactionId: 'zsfgzzg', + userId: { + britepoolid: '1111', + criteoId: '1111', + digitrustid: { data: { id: 'DTID', keyv: 4, privacy: { optout: false }, producer: 'ABC', version: 2 } }, + id5id: '1111', + idl_env: '1111', + lipbid: '1111', + parrableid: 'eidVersion.encryptionKeyReference.encryptedValue', + pubcid: '1111', + tdid: '1111', + netId: 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg', + } + }]; + // Default params without optional ones var DEFAULT_PARAMS_WO_OPTIONAL = [{ adUnitCode: 'sas_42', @@ -434,6 +473,33 @@ describe('Smart bid adapter tests', function () { }); }); + describe('External ids tests', function () { + it('Verify external ids in request and ids found', function () { + config.setConfig({ + 'currency': { + 'adServerCurrency': 'EUR' + } + }); + const request = spec.buildRequests(DEFAULT_PARAMS_WITH_EIDS); + expect(request[0]).to.have.property('url').and.to.equal('https://prg.smartadserver.com/prebid/v1'); + expect(request[0]).to.have.property('method').and.to.equal('POST'); + const requestContent = JSON.parse(request[0].data); + + expect(requestContent).to.have.property('eids'); + expect(requestContent.eids).to.not.equal(null).and.to.not.be.undefined; + expect(requestContent.eids.length).to.greaterThan(0); + for (let index in requestContent.eids) { + let eid = requestContent.eids[index]; + expect(eid.source).to.not.equal(null).and.to.not.be.undefined; + expect(eid.uids).to.not.equal(null).and.to.not.be.undefined; + for (let uidsIndex in eid.uids) { + let uid = eid.uids[uidsIndex]; + expect(uid.id).to.not.equal(null).and.to.not.be.undefined; + } + } + }); + }); + describe('Supply Chain Serializer tests', function () { it('Verify a multi node supply chain serialization matches iab example', function() { let schain = { From 57f8beb8215acb81d8093f8145d7f5943ab901d0 Mon Sep 17 00:00:00 2001 From: Aparna Rao Date: Mon, 22 Jun 2020 08:53:52 -0400 Subject: [PATCH 430/496] 33Across: CCPA Compliance + Schain support (#5365) * check gdpr in buildRequest * User sync based on whether gdpr applies or not * check if consent data exists during user sync * split user sync into further branches: 1) when gdpr does not apply 2) when consent data is unavailable * contribute viewability to ttxRequest * update tests * remove window mock from tests * use local variables * introduce ServerRequestBuilder * add withOptions() method to ServerRequestBuilder * add semicolons * sync up package-lock.json with upstream/master * stub window.top in tests * introduce getTopWindowSize() for test purpose * reformat code * add withSite() method to TtxRequestBuilder add withSite() method to TtxRequestBuilder * add isIframe() and _isViewabilityMeasurable() * handle NON_MEASURABLE viewability in nested iframes * consider page visibility, stub utils functions getWindowTop() and getWindowSelf() * contribute viewability as 0 for inactive tab * add prebidjs version to ttx request * send caller as an array * fix JSDoc in utils.js * send viewability as non measurable when unable to locate target HTMLElement, add warning message * introduce mapAdSlotPathToElementId() * introduce getAdSlotHTMLElement(), add logging * introduce mapAdSlotPathToElementId() * update logging in ad unit path to element id mapping * rephrase logging, fix tests * update adapter documentation * remove excessive logging * improve logging * revert change * fix return of _mapAdUnitPathToElementId() * improve logging of _mapAdUnitPathToElementId() * do not use Array.find() * return id once element is found * return id once element is found * let -> const * Removing killswitch behavior for GDPR * Updated comments to reflect current gdpr logic * URI encode consent string * Updated example site ID to help Prebid team e2e test our adapter * send page url in ortb * Removed redundant pageUrl default * Restored package-log.json that mirrors prebid's repo * Sending USP string during buildRequest * Adding USP consent data to user sync * add unit test for syncing without bidrequest * Changed to uspConsent to make the connatation consistent * Resetting adapter state in adapter after user sync rather than exposing it. * removed console log * Adding schain info * remove setting empty format ext * better tests invalid values * removing validation of schain * Fixed lint errors Co-authored-by: Gleb Glushtsov Co-authored-by: Gleb Glushtsov Co-authored-by: Gleb Glushtsov Co-authored-by: Aparna Hegde Co-authored-by: Aparna Hegde Co-authored-by: Aparna Hegde Co-authored-by: Aparna Hegde Co-authored-by: Aparna Hegde Co-authored-by: Aparna Hegde --- modules/33acrossBidAdapter.js | 52 +++- test/spec/modules/33acrossBidAdapter_spec.js | 261 +++++++++++++++++-- 2 files changed, 280 insertions(+), 33 deletions(-) diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js index 95524190e74..07773ebe999 100644 --- a/modules/33acrossBidAdapter.js +++ b/modules/33acrossBidAdapter.js @@ -6,7 +6,9 @@ const BIDDER_CODE = '33across'; const END_POINT = 'https://ssc.33across.com/api/v1/hb'; const SYNC_ENDPOINT = 'https://ssc-cms.33across.com/ps/?m=xch&rt=html&ru=deb'; -const adapterState = {}; +const adapterState = { + uniqueSiteIds: [] +}; const NON_MEASURABLE = 'nm'; @@ -65,7 +67,7 @@ function _getAdSlotHTMLElement(adUnitCode) { // Infer the necessary data from valid bid for a minimal ttxRequest and create HTTP request // NOTE: At this point, TTX only accepts request for a single impression -function _createServerRequest(bidRequest, gdprConsent = {}, pageUrl) { +function _createServerRequest(bidRequest, gdprConsent = {}, uspConsent, pageUrl) { const ttxRequest = {}; const params = bidRequest.params; const element = _getAdSlotHTMLElement(bidRequest.adUnitCode); @@ -84,7 +86,7 @@ function _createServerRequest(bidRequest, gdprConsent = {}, pageUrl) { ttxRequest.imp = []; ttxRequest.imp[0] = { banner: { - format: sizes.map(size => Object.assign(size, {ext: {}})) + format: sizes }, ext: { ttx: { @@ -97,6 +99,7 @@ function _createServerRequest(bidRequest, gdprConsent = {}, pageUrl) { if (pageUrl) { ttxRequest.site.page = pageUrl; } + // Go ahead send the bidId in request to 33exchange so it's kept track of in the bid response and // therefore in ad targetting process ttxRequest.id = bidRequest.bidId; @@ -109,19 +112,28 @@ function _createServerRequest(bidRequest, gdprConsent = {}, pageUrl) { }; ttxRequest.regs = { ext: { - gdpr: (gdprConsent.gdprApplies === true) ? 1 : 0 + gdpr: (gdprConsent.gdprApplies === true) ? 1 : 0, + us_privacy: uspConsent || null } }; ttxRequest.ext = { ttx: { prebidStartedAt: Date.now(), - caller: [{ + caller: [ { 'name': 'prebidjs', 'version': '$prebid.version$' - }] + } ] } }; + if (bidRequest.schain) { + ttxRequest.source = { + ext: { + schain: bidRequest.schain + } + } + } + // Finally, set the openRTB 'test' param if this is to be a test bid if (params.test === 1) { ttxRequest.test = 1; @@ -134,6 +146,7 @@ function _createServerRequest(bidRequest, gdprConsent = {}, pageUrl) { contentType: 'text/plain', withCredentials: true }; + // Allow the ability to configure the HB endpoint for testing purposes. const ttxSettings = config.getConfig('ttxSettings'); const url = (ttxSettings && ttxSettings.url) || END_POINT; @@ -148,15 +161,15 @@ function _createServerRequest(bidRequest, gdprConsent = {}, pageUrl) { } // Sync object will always be of type iframe for TTX -function _createSync({siteId = 'zzz000000000003zzz', gdprConsent = {}}) { +function _createSync({ siteId = 'zzz000000000003zzz', gdprConsent = {}, uspConsent }) { const ttxSettings = config.getConfig('ttxSettings'); const syncUrl = (ttxSettings && ttxSettings.syncUrl) || SYNC_ENDPOINT; - const {consentString, gdprApplies} = gdprConsent; + const { consentString, gdprApplies } = gdprConsent; const sync = { type: 'iframe', - url: `${syncUrl}&id=${siteId}&gdpr_consent=${encodeURIComponent(consentString)}` + url: `${syncUrl}&id=${siteId}&gdpr_consent=${encodeURIComponent(consentString)}&us_privacy=${encodeURIComponent(uspConsent)}` }; if (typeof gdprApplies === 'boolean') { @@ -192,7 +205,7 @@ function _getBoundingBox(element, { w, h } = {}) { function _transformSizes(sizes) { if (utils.isArray(sizes) && sizes.length === 2 && !utils.isArray(sizes[0])) { - return [_getSize(sizes)]; + return [ _getSize(sizes) ]; } return sizes.map(_getSize); @@ -239,7 +252,8 @@ function _getPercentInView(element, topWin, { w, h } = {}) { bottom: topWin.innerHeight }, elementBoundingBox ]); - let elementInViewArea, elementTotalArea; + let elementInViewArea, + elementTotalArea; if (elementInViewBoundingBox !== null) { // Some or all of the element is in view @@ -301,11 +315,12 @@ function buildRequests(bidRequests, bidderRequest) { gdprApplies: false }, bidderRequest && bidderRequest.gdprConsent); + const uspConsent = bidderRequest && bidderRequest.uspConsent; const pageUrl = (bidderRequest && bidderRequest.refererInfo) ? (bidderRequest.refererInfo.referer) : (undefined); adapterState.uniqueSiteIds = bidRequests.map(req => req.params.siteId).filter(utils.uniques); - return bidRequests.map(req => _createServerRequest(req, gdprConsent, pageUrl)); + return bidRequests.map(req => _createServerRequest(req, gdprConsent, uspConsent, pageUrl)); } // NOTE: At this point, the response from 33exchange will only ever contain one bid i.e. the highest bid @@ -324,8 +339,17 @@ function interpretResponse(serverResponse, bidRequest) { // Else no syncs // For logic on how we handle gdpr data see _createSyncs and module's unit tests // '33acrossBidAdapter#getUserSyncs' -function getUserSyncs(syncOptions, responses, gdprConsent) { - return (syncOptions.iframeEnabled) ? adapterState.uniqueSiteIds.map((siteId) => _createSync({gdprConsent, siteId})) : ([]); +function getUserSyncs(syncOptions, responses, gdprConsent, uspConsent) { + const syncUrls = ( + (syncOptions.iframeEnabled) + ? adapterState.uniqueSiteIds.map((siteId) => _createSync({ gdprConsent, uspConsent, siteId })) + : ([]) + ); + + // Clear adapter state of siteID's since we don't need this info anymore. + adapterState.uniqueSiteIds = []; + + return syncUrls; } export const spec = { diff --git a/test/spec/modules/33acrossBidAdapter_spec.js b/test/spec/modules/33acrossBidAdapter_spec.js index d27cc99b5bc..0e67b7efb63 100644 --- a/test/spec/modules/33acrossBidAdapter_spec.js +++ b/test/spec/modules/33acrossBidAdapter_spec.js @@ -22,13 +22,11 @@ describe('33acrossBidAdapter:', function () { format: [ { w: 300, - h: 250, - ext: {} + h: 250 }, { w: 728, - h: 90, - ext: {} + h: 90 } ], ext: { @@ -56,7 +54,8 @@ describe('33acrossBidAdapter:', function () { }, regs: { ext: { - gdpr: 0 + gdpr: 0, + us_privacy: null } }, ext: { @@ -92,12 +91,30 @@ describe('33acrossBidAdapter:', function () { }); Object.assign(ttxRequest, { regs: { - ext: { gdpr } + ext: Object.assign( + {}, + ttxRequest.regs.ext, + { gdpr } + ) } }); return this; }; + this.withUspConsent = (consent) => { + Object.assign(ttxRequest, { + regs: { + ext: Object.assign( + {}, + ttxRequest.regs.ext, + { us_privacy: consent } + ) + } + }); + + return this; + }; + this.withSite = site => { Object.assign(ttxRequest, { site }); return this; @@ -111,6 +128,18 @@ describe('33acrossBidAdapter:', function () { return this; }; + this.withSchain = schain => { + Object.assign(ttxRequest, { + source: { + ext: { + schain + } + } + }); + + return this; + }; + this.build = () => ttxRequest; } @@ -320,7 +349,7 @@ describe('33acrossBidAdapter:', function () { context('when width or height of the element is zero', function() { it('try to use alternative values', function() { const ttxRequest = new TtxRequestBuilder() - .withSizes([{ w: 800, h: 2400, ext: {} }]) + .withSizes([{ w: 800, h: 2400 }]) .withViewability({amount: 25}) .build(); const serverRequest = new ServerRequestBuilder() @@ -454,6 +483,84 @@ describe('33acrossBidAdapter:', function () { }); }); + context('when us_privacy consent data exists', function() { + let bidderRequest; + + beforeEach(function() { + bidderRequest = { + uspConsent: 'foo' + } + }); + + it('returns corresponding server requests with us_privacy consent data', function() { + const ttxRequest = new TtxRequestBuilder() + .withUspConsent('foo') + .build(); + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .build(); + const builtServerRequests = spec.buildRequests(bidRequests, bidderRequest); + + expect(builtServerRequests).to.deep.equal([serverRequest]); + }); + + it('returns corresponding test server requests with us_privacy consent data', function() { + sandbox.stub(config, 'getConfig').callsFake(() => { + return { + 'url': 'https://foo.com/hb/' + } + }); + + const ttxRequest = new TtxRequestBuilder() + .withUspConsent('foo') + .build(); + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .withUrl('https://foo.com/hb/') + .build(); + const builtServerRequests = spec.buildRequests(bidRequests, bidderRequest); + + expect(builtServerRequests).to.deep.equal([serverRequest]); + }); + }); + + context('when us_privacy consent data does not exist', function() { + let bidderRequest; + + beforeEach(function() { + bidderRequest = {}; + }); + + it('returns corresponding server requests with default us_privacy data', function() { + const ttxRequest = new TtxRequestBuilder() + .build(); + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .build(); + const builtServerRequests = spec.buildRequests(bidRequests, bidderRequest); + + expect(builtServerRequests).to.deep.equal([serverRequest]); + }); + + it('returns corresponding test server requests with default us_privacy consent data', function() { + sandbox.stub(config, 'getConfig').callsFake(() => { + return { + 'url': 'https://foo.com/hb/' + } + }); + + const ttxRequest = new TtxRequestBuilder() + .build(); + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .withUrl('https://foo.com/hb/') + .build(); + const builtServerRequests = spec.buildRequests(bidRequests, bidderRequest); + + expect(builtServerRequests).to.deep.equal([serverRequest]); + }); + }); + context('when referer value is available', function() { it('returns corresponding server requests with site.page set', function() { const bidderRequest = { @@ -492,6 +599,74 @@ describe('33acrossBidAdapter:', function () { expect(builtServerRequests).to.deep.equal([serverRequest]); }); }); + + context('when there is schain object in the bidRequest', function() { + it('builds request with schain info in source', function() { + const schainValues = [ + { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'bidderA.com', + 'sid': '00001', + 'hp': 1 + } + ] + }, + { + 'ver': '1.0', + 'complete': 1, + }, + { + 'ver': '1.0', + 'complete': 1, + 'nodes': [] + }, + { + 'ver': '1.0', + 'complete': '1', + 'nodes': [ + { + 'asi': 'bidderA.com', + 'sid': '00001', + 'hp': 1 + } + ] + } + ]; + + schainValues.forEach((schain) => { + bidRequests[0].schain = schain; + + const ttxRequest = new TtxRequestBuilder() + .withSchain(schain) + .build(); + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .build(); + + const builtServerRequests = spec.buildRequests(bidRequests, {}); + + expect(builtServerRequests).to.deep.equal([serverRequest]); + }); + }); + }); + + context('when there no schain object is passed', function() { + it('does not set source field', function() { + const ttxRequest = new TtxRequestBuilder() + .build(); + + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .build(); + + const builtServerRequests = spec.buildRequests(bidRequests, {}); + + expect(builtServerRequests).to.deep.equal([serverRequest]); + }); + }); }); describe('interpretResponse', function() { @@ -693,11 +868,11 @@ describe('33acrossBidAdapter:', function () { const expectedSyncs = [ { type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=undefined` + url: `${syncs[0].url}&gdpr_consent=undefined&us_privacy=undefined` }, { type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=undefined` + url: `${syncs[1].url}&gdpr_consent=undefined&us_privacy=undefined` } ] @@ -713,11 +888,11 @@ describe('33acrossBidAdapter:', function () { const expectedSyncs = [ { type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=undefined&gdpr=1` + url: `${syncs[0].url}&gdpr_consent=undefined&us_privacy=undefined&gdpr=1` }, { type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=undefined&gdpr=1` + url: `${syncs[1].url}&gdpr_consent=undefined&us_privacy=undefined&gdpr=1` } ]; @@ -733,11 +908,11 @@ describe('33acrossBidAdapter:', function () { const expectedSyncs = [ { type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=consent123A&gdpr=1` + url: `${syncs[0].url}&gdpr_consent=consent123A&us_privacy=undefined&gdpr=1` }, { type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=consent123A&gdpr=1` + url: `${syncs[1].url}&gdpr_consent=consent123A&us_privacy=undefined&gdpr=1` } ]; @@ -753,11 +928,11 @@ describe('33acrossBidAdapter:', function () { const expectedSyncs = [ { type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=undefined&gdpr=0` + url: `${syncs[0].url}&gdpr_consent=undefined&us_privacy=undefined&gdpr=0` }, { type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=undefined&gdpr=0` + url: `${syncs[1].url}&gdpr_consent=undefined&us_privacy=undefined&gdpr=0` } ]; expect(syncResults).to.deep.equal(expectedSyncs); @@ -772,11 +947,11 @@ describe('33acrossBidAdapter:', function () { const expectedSyncs = [ { type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=consent123A` + url: `${syncs[0].url}&gdpr_consent=consent123A&us_privacy=undefined` }, { type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=consent123A` + url: `${syncs[1].url}&gdpr_consent=consent123A&us_privacy=undefined` } ]; expect(syncResults).to.deep.equal(expectedSyncs); @@ -791,16 +966,64 @@ describe('33acrossBidAdapter:', function () { const expectedSyncs = [ { type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=consent123A&gdpr=0` + url: `${syncs[0].url}&gdpr_consent=consent123A&us_privacy=undefined&gdpr=0` }, { type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=consent123A&gdpr=0` + url: `${syncs[1].url}&gdpr_consent=consent123A&us_privacy=undefined&gdpr=0` } ]; expect(syncResults).to.deep.equal(expectedSyncs); }); }); + + context('when there is no usPrivacy data', function() { + it('returns sync urls with undefined consent string as param', function() { + spec.buildRequests(bidRequests); + + const syncResults = spec.getUserSyncs(syncOptions, {}); + const expectedSyncs = [ + { + type: 'iframe', + url: `${syncs[0].url}&gdpr_consent=undefined&us_privacy=undefined` + }, + { + type: 'iframe', + url: `${syncs[1].url}&gdpr_consent=undefined&us_privacy=undefined` + } + ] + + expect(syncResults).to.deep.equal(expectedSyncs); + }) + }); + + context('when there is usPrivacy data', function() { + it('returns sync urls with consent string as param', function() { + spec.buildRequests(bidRequests); + + const syncResults = spec.getUserSyncs(syncOptions, {}, {}, 'foo'); + const expectedSyncs = [ + { + type: 'iframe', + url: `${syncs[0].url}&gdpr_consent=undefined&us_privacy=foo` + }, + { + type: 'iframe', + url: `${syncs[1].url}&gdpr_consent=undefined&us_privacy=foo` + } + ]; + + expect(syncResults).to.deep.equal(expectedSyncs); + }); + }); + + context('when user sync is invoked without a bid request phase', function() { + it('results in an empty syncs array', function() { + const syncResults = spec.getUserSyncs(syncOptions, {}, {}, 'foo'); + + expect(syncResults).to.deep.equal([]); + }); + }); }); }); }); From ba6d90438bc6d6f3e0660b8a65d3593587586979 Mon Sep 17 00:00:00 2001 From: mshuhaliia <48407028+mshuhaliia@users.noreply.github.com> Date: Mon, 22 Jun 2020 16:58:49 +0300 Subject: [PATCH 431/496] added waardex adapter (#5349) * added waardex adapter * removed support http from adapter Co-authored-by: Max Shuhaliia --- modules/waardexBidAdapter.js | 218 ++++++++++++++++++++ modules/waardexBidAdapter.md | 60 ++++++ test/spec/modules/waardexBidAdapter_spec.js | 190 +++++++++++++++++ 3 files changed, 468 insertions(+) create mode 100644 modules/waardexBidAdapter.js create mode 100644 modules/waardexBidAdapter.md create mode 100644 test/spec/modules/waardexBidAdapter_spec.js diff --git a/modules/waardexBidAdapter.js b/modules/waardexBidAdapter.js new file mode 100644 index 00000000000..255bf24098b --- /dev/null +++ b/modules/waardexBidAdapter.js @@ -0,0 +1,218 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; + +const domain = 'hb.justbidit.xyz'; +const httpsPort = 8843; +const path = '/prebid'; + +const ENDPOINT = `https://${domain}:${httpsPort}${path}`; + +const BIDDER_CODE = 'waardex'; + +/** + * @param {Array} requestSizes + * + * @returns {Array} + * */ +function transformSizes(requestSizes) { + let sizes = []; + if ( + Array.isArray(requestSizes) && + !Array.isArray(requestSizes[0]) + ) { + sizes[0] = { + width: parseInt(requestSizes[0], 10) || 0, + height: parseInt(requestSizes[1], 10) || 0, + }; + } else if ( + Array.isArray(requestSizes) && + Array.isArray(requestSizes[0]) + ) { + sizes = requestSizes.map(item => { + return { + width: parseInt(item[0], 10) || 0, + height: parseInt(item[1], 10) || 0, + } + }); + } + return sizes; +} + +/** + * @param {Object} banner + * @param {Array} banner.sizes + * + * @returns {Object} + * */ +function createBannerObject(banner) { + return { + sizes: transformSizes(banner.sizes), + }; +} + +/** + * @param {Array} validBidRequests + * + * @returns {Object} + * */ +function buildBidRequests(validBidRequests) { + return validBidRequests.map((validBidRequest) => { + const params = validBidRequest.params; + + const item = { + bidId: validBidRequest.bidId, + placementId: params.placementId, + bidfloor: parseFloat(params.bidfloor) || 0, + position: parseInt(params.position) || 1, + instl: parseInt(params.instl) || 0, + }; + if (validBidRequest.mediaTypes[BANNER]) { + item[BANNER] = createBannerObject(validBidRequest.mediaTypes[BANNER]); + } + return item; + }); +} + +/** + * @param {Object} bidderRequest + * @param {String} bidderRequest.userAgent + * @param {String} bidderRequest.refererInfo + * @param {String} bidderRequest.uspConsent + * @param {Object} bidderRequest.gdprConsent + * @param {String} bidderRequest.gdprConsent.consentString + * @param {String} bidderRequest.gdprConsent.gdprApplies + * + * @returns {Object} - { + * ua: string, + * language: string, + * [referer]: string, + * [us_privacy]: string, + * [consent_string]: string, + * [consent_required]: string, + * [coppa]: boolean, + * } + * */ +function getCommonBidsData(bidderRequest) { + const payload = { + ua: navigator.userAgent || '', + language: navigator.language && navigator.language.indexOf('-') !== -1 ? navigator.language.split('-')[0] : '', + + }; + if (bidderRequest && bidderRequest.refererInfo) { + payload.referer = encodeURIComponent(bidderRequest.refererInfo.referer); + } + if (bidderRequest && bidderRequest.uspConsent) { + payload.us_privacy = bidderRequest.uspConsent; + } + if (bidderRequest && bidderRequest.gdprConsent) { + payload.gdpr_consent = { + consent_string: bidderRequest.gdprConsent.consentString, + consent_required: bidderRequest.gdprConsent.gdprApplies, + } + } + payload.coppa = !!config.getConfig('coppa'); + + return payload; +} + +/** + * this function checks either bid response is valid or noе + * + * @param {Object} bid + * @param {string} bid.requestId + * @param {number} bid.cpm + * @param {string} bid.creativeId + * @param {number} bid.ttl + * @param {string} bid.currency + * @param {number} bid.width + * @param {number} bid.height + * @param {string} bid.ad + * + * @returns {boolean} + * */ +function isBidValid(bid) { + if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { + return false; + } + + return Boolean(bid.width && bid.height && bid.ad); +} + +/** + * @param {Object} serverBid + * + * @returns {Object|null} + * */ +function createBid(serverBid) { + const bid = { + requestId: serverBid.id, + cpm: serverBid.price, + currency: 'USD', + width: serverBid.w, + height: serverBid.h, + creativeId: serverBid.crid, + netRevenue: true, + ttl: 3000, + ad: serverBid.adm, + dealId: serverBid.dealid, + meta: { + cid: serverBid.cid, + adomain: serverBid.adomain, + mediaType: serverBid.ext.mediaType + }, + }; + + return isBidValid(bid) ? bid : null; +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER], + + isBidRequestValid: (bid) => Boolean(bid.bidId && bid.params && +bid.params.placementId && +bid.params.pubId), + + /** + * @param {Object[]} validBidRequests - array of valid bid requests + * @param {Object} bidderRequest - an array of valid bid requests + * + * */ + buildRequests(validBidRequests, bidderRequest) { + const payload = getCommonBidsData(bidderRequest); + payload.bidRequests = buildBidRequests(validBidRequests); + + let pubId = ''; + if (validBidRequests[0] && validBidRequests[0].params && +validBidRequests[0].params.pubId) { + pubId = +validBidRequests[0].params.pubId; + } + + const url = `${ENDPOINT}?pubId=${pubId}`; + + return { + method: 'POST', + url, + data: payload + }; + }, + + /** + * Unpack the response from the server into a list of bids. + */ + interpretResponse(serverResponse, bidRequest) { + const bids = []; + serverResponse = serverResponse.body; + + if (serverResponse.seatbid && serverResponse.seatbid[0]) { + const oneSeatBid = serverResponse.seatbid[0]; + oneSeatBid.bid.forEach(serverBid => { + const bid = createBid(serverBid); + if (bid) { + bids.push(bid); + } + }); + } + return bids; + }, +} + +registerBidder(spec); diff --git a/modules/waardexBidAdapter.md b/modules/waardexBidAdapter.md new file mode 100644 index 00000000000..44ee720d31a --- /dev/null +++ b/modules/waardexBidAdapter.md @@ -0,0 +1,60 @@ +# Overview + +``` +Module Name: Waardex Bid Adapter +Module Type: Bidder Adapter +Maintainer: info@prebid.org +``` + +# Description + +Connects to Waardex exchange for bids. + +Waardex bid adapter supports Banner. + +# Test Parameters + +``` + +var sizes = [ + [300, 250] +]; +var PREBID_TIMEOUT = 5000; +var FAILSAFE_TIMEOUT = 5000; + +var adUnits = [{ + code: '/19968336/header-bid-tag-0', + mediaTypes: { + banner: { + sizes: sizes, + }, + }, + bids: [{ + bidder: 'waardex', + params: { + placementId: 13144370, + position: 1, // add position openrtb + bidfloor: 0.5, + instl: 0, // 1 - full screen + pubId: 1, + } + }] +},{ + code: '/19968336/header-bid-tag-1', + mediaTypes: { + banner: { + sizes: sizes, + }, + }, + bids: [{ + bidder: 'waardex', + params: { + placementId: 333333333333, + position: 1, // add position openrtb + bidfloor: 0.5, + instl: 0, // 1 - full screen + pubId: 1, + } + }] +}]; +``` diff --git a/test/spec/modules/waardexBidAdapter_spec.js b/test/spec/modules/waardexBidAdapter_spec.js new file mode 100644 index 00000000000..fae70335d3c --- /dev/null +++ b/test/spec/modules/waardexBidAdapter_spec.js @@ -0,0 +1,190 @@ +import {expect} from 'chai'; +import {spec} from '../../../modules/waardexBidAdapter.js'; +import { auctionManager } from 'src/auctionManager.js'; +import { deepClone } from 'src/utils.js'; + +describe('waardexBidAdapter', () => { + const validBid = { + bidId: '112435ry', + bidder: 'waardex', + params: { + placementId: 1, + traffic: 'banner', + pubId: 1, + } + }; + + describe('isBidRequestValid', () => { + it('Should return true. bidId and params such as placementId and pubId are present', () => { + expect(spec.isBidRequestValid(validBid)).to.be.true; + }); + it('Should return false. bidId is not present in bid object', () => { + const invalidBid = deepClone(validBid); + delete invalidBid.bidId; + expect(spec.isBidRequestValid(invalidBid)).to.be.false; + }); + it('Should return false. placementId is not present in bid.params object', () => { + const invalidBid = deepClone(validBid); + delete invalidBid.params.placementId; + expect(spec.isBidRequestValid(invalidBid)).to.be.false; + }); + it('Should return false. pubId is not present in bid.params object', () => { + const invalidBid = deepClone(validBid); + delete invalidBid.params.pubId; + expect(spec.isBidRequestValid(invalidBid)).to.be.false; + }); + }); + + describe('buildRequests', () => { + let getAdUnitsStub; + const validBidRequests = [{ + bidId: 'fergr675ujgh', + mediaTypes: { + banner: { + sizes: [[300, 600], [300, 250]] + } + }, + params: { + placementId: 1, + bidfloor: 1.5, + position: 1, + instl: 1, + pubId: 100 + }, + }]; + + const bidderRequest = { + refererInfo: { + referer: 'https://www.google.com/?some_param=some_value' + }, + }; + + beforeEach(() => getAdUnitsStub = sinon.stub(auctionManager, 'getAdUnits').callsFake(() => [])); + afterEach(() => getAdUnitsStub.restore()); + + it('should return valid build request object', () => { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const { + data: payload, + url, + method, + } = request; + + expect(payload.bidRequests[0]).deep.equal({ + bidId: validBidRequests[0].bidId, + placementId: validBidRequests[0].params.placementId, + bidfloor: validBidRequests[0].params.bidfloor, + position: validBidRequests[0].params.position, + instl: validBidRequests[0].params.instl, + banner: { + sizes: [ + { + width: validBidRequests[0].mediaTypes.banner.sizes[0][0], + height: validBidRequests[0].mediaTypes.banner.sizes[0][1] + }, + { + width: validBidRequests[0].mediaTypes.banner.sizes[1][0], + height: validBidRequests[0].mediaTypes.banner.sizes[1][1] + }, + ], + } + }); + const ENDPOINT = `https://hb.justbidit.xyz:8843/prebid?pubId=${validBidRequests[0].params.pubId}`; + expect(url).to.equal(ENDPOINT); + expect(method).to.equal('POST'); + }); + }); + + describe('interpretResponse', () => { + const serverResponse = { + body: { + seatbid: [{ + bid: [{ + id: 'someId', + price: 3.3, + w: 250, + h: 300, + crid: 'dspCreativeIdHere', + adm: 'html markup here', + dealId: '123456789', + cid: 'dsp campaign id', + adomain: 'advertisers domain', + ext: { + mediaType: 'banner', + }, + }], + }], + }, + }; + + it('bid response is valid', () => { + const result = spec.interpretResponse(serverResponse); + const expected = [{ + requestId: serverResponse.body.seatbid[0].bid[0].id, + cpm: serverResponse.body.seatbid[0].bid[0].price, + currency: 'USD', + width: serverResponse.body.seatbid[0].bid[0].w, + height: serverResponse.body.seatbid[0].bid[0].h, + creativeId: serverResponse.body.seatbid[0].bid[0].crid, + netRevenue: true, + ttl: 3000, + ad: serverResponse.body.seatbid[0].bid[0].adm, + dealId: serverResponse.body.seatbid[0].bid[0].dealid, + meta: { + cid: serverResponse.body.seatbid[0].bid[0].cid, + adomain: serverResponse.body.seatbid[0].bid[0].adomain, + mediaType: serverResponse.body.seatbid[0].bid[0].ext.mediaType, + }, + }]; + expect(result).deep.equal(expected); + }); + + it('invalid bid response. requestId is not exists in bid response', () => { + const invalidServerResponse = deepClone(serverResponse); + delete invalidServerResponse.body.seatbid[0].bid[0].id; + + const result = spec.interpretResponse(invalidServerResponse); + expect(result).deep.equal([]); + }); + + it('invalid bid response. cpm is not exists in bid response', () => { + const invalidServerResponse = deepClone(serverResponse); + delete invalidServerResponse.body.seatbid[0].bid[0].price; + + const result = spec.interpretResponse(invalidServerResponse); + expect(result).deep.equal([]); + }); + + it('invalid bid response. creativeId is not exists in bid response', () => { + const invalidServerResponse = deepClone(serverResponse); + delete invalidServerResponse.body.seatbid[0].bid[0].crid; + + const result = spec.interpretResponse(invalidServerResponse); + expect(result).deep.equal([]); + }); + + it('invalid bid response. width is not exists in bid response', () => { + const invalidServerResponse = deepClone(serverResponse); + delete invalidServerResponse.body.seatbid[0].bid[0].w; + + const result = spec.interpretResponse(invalidServerResponse); + expect(result).deep.equal([]); + }); + + it('invalid bid response. height is not exists in bid response', () => { + const invalidServerResponse = deepClone(serverResponse); + delete invalidServerResponse.body.seatbid[0].bid[0].h; + + const result = spec.interpretResponse(invalidServerResponse); + expect(result).deep.equal([]); + }); + + it('invalid bid response. ad is not exists in bid response', () => { + const invalidServerResponse = deepClone(serverResponse); + delete invalidServerResponse.body.seatbid[0].bid[0].adm; + + const result = spec.interpretResponse(invalidServerResponse); + expect(result).deep.equal([]); + }); + }); +}); From cc845b00bd21ddd3ee91d00315a92a7dca37b33c Mon Sep 17 00:00:00 2001 From: Mirko Feddern <3244291+mirkorean@users.noreply.github.com> Date: Mon, 22 Jun 2020 20:29:23 +0200 Subject: [PATCH 432/496] Add customParams to yieldlab configuration (#5374) Customers are using custom parameters to our endpoint to use them downstream. We need a way of supporting this in prebid. --- modules/yieldlabBidAdapter.js | 5 +++++ test/spec/modules/yieldlabBidAdapter_spec.js | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/modules/yieldlabBidAdapter.js b/modules/yieldlabBidAdapter.js index 6cfa0c1a548..9c2b6abf475 100644 --- a/modules/yieldlabBidAdapter.js +++ b/modules/yieldlabBidAdapter.js @@ -42,6 +42,11 @@ export const spec = { if (bid.userIdAsEids && Array.isArray(bid.userIdAsEids)) { query.ids = createUserIdString(bid.userIdAsEids) } + if (bid.params.customParams && utils.isPlainObject(bid.params.customParams)) { + for (let prop in bid.params.customParams) { + query[prop] = bid.params.customParams[prop] + } + } }) if (bidderRequest && bidderRequest.gdprConsent) { diff --git a/test/spec/modules/yieldlabBidAdapter_spec.js b/test/spec/modules/yieldlabBidAdapter_spec.js index 5dcd112228a..097f85b9b8d 100644 --- a/test/spec/modules/yieldlabBidAdapter_spec.js +++ b/test/spec/modules/yieldlabBidAdapter_spec.js @@ -12,6 +12,10 @@ const REQUEST = { 'key1': 'value1', 'key2': 'value2' }, + 'customParams': { + 'extraParam': true, + 'foo': 'bar' + }, 'extId': 'abc' }, 'bidderRequestId': '143346cf0f1731', @@ -88,6 +92,10 @@ describe('yieldlabBidAdapter', function () { expect(request.url).to.include('ids=netid.de%3AfH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg') }) + it('passes extra params to bid request', function () { + expect(request.url).to.include('extraParam=true&foo=bar') + }) + const gdprRequest = spec.buildRequests(bidRequests, { gdprConsent: { consentString: 'BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA', From 263c6cc2fdf70259dcc055e7590b3683277866f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Udi=20Talias=20=E2=9A=9B=EF=B8=8F?= Date: Tue, 23 Jun 2020 11:19:52 +0300 Subject: [PATCH 433/496] Vidazoo Adapter: Feature/user-id (#5386) * feat(module): multi size request * fix getUserSyncs added tests * update(module): package-lock.json from master * feat(client): add user id request support * fix(client): lint errors Co-authored-by: roman --- modules/vidazooBidAdapter.js | 37 ++++++++++++++++++++- test/spec/modules/vidazooBidAdapter_spec.js | 26 ++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/modules/vidazooBidAdapter.js b/modules/vidazooBidAdapter.js index 19c3f1db8e8..81e24a976e3 100644 --- a/modules/vidazooBidAdapter.js +++ b/modules/vidazooBidAdapter.js @@ -14,6 +14,18 @@ const EXTERNAL_SYNC_TYPE = { IFRAME: 'iframe', IMAGE: 'image' }; +export const SUPPORTED_ID_SYSTEMS = { + 'britepoolid': 1, + 'criteoId': 1, + 'digitrustid': 1, + 'id5id': 1, + 'idl_env': 1, + 'lipb': 1, + 'netId': 1, + 'parrableid': 1, + 'pubcid': 1, + 'tdid': 1, +}; function isBidRequestValid(bid) { const params = bid.params || {}; @@ -21,7 +33,7 @@ function isBidRequestValid(bid) { } function buildRequest(bid, topWindowUrl, sizes, bidderRequest) { - const { params, bidId } = bid; + const { params, bidId, userId } = bid; const { bidFloor, cId, pId, ext } = params; const hashUrl = hashCode(topWindowUrl); const dealId = getNextDealId(hashUrl); @@ -35,6 +47,9 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest) { sizes: sizes, dealId: dealId, }; + + appendUserIdsToRequestPayload(data, userId); + if (bidderRequest.gdprConsent) { if (bidderRequest.gdprConsent.consentString) { data.gdprConsent = bidderRequest.gdprConsent.consentString; @@ -59,6 +74,26 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest) { return dto; } +function appendUserIdsToRequestPayload(payloadRef, userIds) { + let key; + utils._each(userIds, (userId, idSystemProviderName) => { + if (SUPPORTED_ID_SYSTEMS[idSystemProviderName]) { + key = `uid.${idSystemProviderName}`; + + switch (idSystemProviderName) { + case 'digitrustid': + payloadRef[key] = utils.deepAccess(userId, 'data.id'); + break; + case 'lipb': + payloadRef[key] = userId.lipbid; + break; + default: + payloadRef[key] = userId; + } + } + }); +} + function buildRequests(validBidRequests, bidderRequest) { const topWindowUrl = bidderRequest.refererInfo.referer; const requests = []; diff --git a/test/spec/modules/vidazooBidAdapter_spec.js b/test/spec/modules/vidazooBidAdapter_spec.js index 9b7b6a73a21..443f9b9d028 100644 --- a/test/spec/modules/vidazooBidAdapter_spec.js +++ b/test/spec/modules/vidazooBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec as adapter, URL } from 'modules/vidazooBidAdapter.js'; +import { spec as adapter, URL, SUPPORTED_ID_SYSTEMS } from 'modules/vidazooBidAdapter.js'; import * as utils from 'src/utils.js'; const BID = { @@ -210,4 +210,28 @@ describe('VidazooBidAdapter', function () { expect(responses[0].ttl).to.equal(300); }); }); + + describe(`user id system`, function () { + Object.keys(SUPPORTED_ID_SYSTEMS).forEach((idSystemProvider) => { + const id = Date.now().toString(); + const bid = utils.deepClone(BID); + + const userId = (function () { + switch (idSystemProvider) { + case 'digitrustid': return { data: { id: id } }; + case 'lipb': return { lipbid: id }; + default: return id; + } + })(); + + bid.userId = { + [idSystemProvider]: userId + }; + + it(`should include 'uid.${idSystemProvider}' in request params`, function () { + const requests = adapter.buildRequests([bid], BIDDER_REQUEST); + expect(requests[0].data[`uid.${idSystemProvider}`]).to.equal(id); + }); + }); + }); }); From d9d7c0cbe0873ab85ef82c3085b311263dbcaf63 Mon Sep 17 00:00:00 2001 From: Janko Ulaga Date: Tue, 23 Jun 2020 22:34:58 +0200 Subject: [PATCH 434/496] LiveIntentId submodule updates (#5407) * LiveIntentId submodule. Bumped the live-connect-js version with changes: - fixed the problem where userId/index.js was sending the full config on `decode`, while the docs claim it should only send `.params` - removed the uuid lib - removed the support for legacy LI first party cookies - removed the redundant config parameter `providedIdentifierName` - support for running live-connect inside of multiple wrappers * LiveIntentId submodule. Removed reading of non-accessible and therefore redundant code snippets * Removed excessive config logging. * Making the publisher id parameter optional. * Removed unneeded check. --- integrationExamples/gpt/userId_example.html | 10 ++++++++ modules/liveIntentIdSystem.js | 24 ++++++-------------- modules/userId/index.js | 4 ++-- package-lock.json | 18 +++++---------- package.json | 2 +- test/spec/modules/liveIntentIdSystem_spec.js | 15 ------------ 6 files changed, 26 insertions(+), 47 deletions(-) diff --git a/integrationExamples/gpt/userId_example.html b/integrationExamples/gpt/userId_example.html index 7886e5b13ca..53c58e8e87e 100644 --- a/integrationExamples/gpt/userId_example.html +++ b/integrationExamples/gpt/userId_example.html @@ -189,6 +189,16 @@ name: "sharedid", expires: 28 } + }, { + name: "liveIntentId", + params: { + publisherId: "9896876" + }, + storage: { + type: "cookie", + name: "_li_pbid", + expires: 28 + } }], syncDelay: 5000, auctionDelay: 1000 diff --git a/modules/liveIntentIdSystem.js b/modules/liveIntentIdSystem.js index b0e8cfc1c0f..bd2638e5936 100644 --- a/modules/liveIntentIdSystem.js +++ b/modules/liveIntentIdSystem.js @@ -21,6 +21,9 @@ let liveConnect = null; * This function is used in tests */ export function reset() { + if (window && window.liQ) { + window.liQ = []; + } eventFired = false; liveConnect = null; } @@ -45,16 +48,12 @@ function parseLiveIntentCollectorConfig(collectConfig) { } function initializeLiveConnect(configParams) { + configParams = configParams || {}; if (liveConnect) { return liveConnect; } - const publisherId = configParams && configParams.publisherId; - if (!publisherId && typeof publisherId !== 'string') { - utils.logError(`${MODULE_NAME} - publisherId must be defined, not a '${publisherId}'`); - return; - } - + const publisherId = configParams.publisherId || 'any'; const identityResolutionConfig = { source: 'prebid', publisherId: publisherId @@ -65,20 +64,11 @@ function initializeLiveConnect(configParams) { if (configParams.partner) { identityResolutionConfig.source = configParams.partner } - if (configParams.storage && configParams.storage.expires) { - identityResolutionConfig.expirationDays = configParams.storage.expires; - } - if (configParams.ajaxTimeout) { - identityResolutionConfig.ajaxTimeout = configParams.ajaxTimeout; - } const liveConnectConfig = parseLiveIntentCollectorConfig(configParams.liCollectConfig); liveConnectConfig.wrapperName = 'prebid'; liveConnectConfig.identityResolutionConfig = identityResolutionConfig; liveConnectConfig.identifiersToResolve = configParams.identifiersToResolve || []; - if (configParams.providedIdentifierName) { - liveConnectConfig.providedIdentifierName = configParams.providedIdentifierName; - } const usPrivacyString = uspDataHandler.getConsentData(); if (usPrivacyString) { liveConnectConfig.usPrivacyString = usPrivacyString; @@ -120,10 +110,10 @@ export const liveIntentIdSubmodule = { return { 'lipb': { ...base, ...value } }; } - if (configParams) { + if (!liveConnect) { initializeLiveConnect(configParams); - tryFireEvent(); } + tryFireEvent(); return (value && typeof value['unifiedId'] === 'string') ? composeIdObject(value) : undefined; }, diff --git a/modules/userId/index.js b/modules/userId/index.js index a47565a53de..88a0a636caf 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -449,7 +449,7 @@ function initSubmodules(submodules, consentData) { if (storedId) { // cache decoded value (this is copied to every adUnit bid) - submodule.idObj = submodule.submodule.decode(storedId, submodule.config); + submodule.idObj = submodule.submodule.decode(storedId, submodule.config.params); } } else if (submodule.config.value) { // cache decoded value (this is copied to every adUnit bid) @@ -458,7 +458,7 @@ function initSubmodules(submodules, consentData) { const response = submodule.submodule.getId(submodule.config.params, consentData, undefined); if (utils.isPlainObject(response)) { if (typeof response.callback === 'function') { submodule.callback = response.callback; } - if (response.id) { submodule.idObj = submodule.submodule.decode(response.id, submodule.config); } + if (response.id) { submodule.idObj = submodule.submodule.decode(response.id, submodule.config.params); } } } carry.push(submodule); diff --git a/package-lock.json b/package-lock.json index 583d25d3459..2fc53a75352 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.23.0-pre", + "version": "3.24.0-pre", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -15211,15 +15211,14 @@ "dev": true }, "live-connect-js": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/live-connect-js/-/live-connect-js-1.1.1.tgz", - "integrity": "sha512-PsYiZ6R6ecBQgcg3BWvzGf2TNOqpNFK1lUyfYAUEZ+DPwPciKNRM3CQIDtytVvR9vsH7nhotMaU3bBgb7iuPfQ==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/live-connect-js/-/live-connect-js-1.1.10.tgz", + "integrity": "sha512-G/LJKN3b21DZILCQRyataC/znLvJRyogtu7mAkKlkhP9B9UJ8bcOL7ihW/clD2PsT4hVUkeabHhUGsPCmhsjFw==", "requires": { "@kiosked/ulid": "^3.0.0", - "abab": "^2.0.2", + "abab": "^2.0.3", "browser-cookies": "^1.2.0", - "tiny-hashes": "1.0.1", - "tiny-uuid4": "^1.0.1" + "tiny-hashes": "1.0.1" } }, "livereload-js": { @@ -20779,11 +20778,6 @@ } } }, - "tiny-uuid4": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tiny-uuid4/-/tiny-uuid4-1.0.1.tgz", - "integrity": "sha1-vUTp3V9fvRdo1tH78wIMiGobd2Y=" - }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/package.json b/package.json index c84e354bd1b..5f08b7356fa 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,6 @@ "fun-hooks": "^0.9.9", "jsencrypt": "^3.0.0-rc.1", "just-clone": "^1.0.2", - "live-connect-js": "1.1.1" + "live-connect-js": "1.1.10" } } diff --git a/test/spec/modules/liveIntentIdSystem_spec.js b/test/spec/modules/liveIntentIdSystem_spec.js index 85e0d30b348..b19d38d5859 100644 --- a/test/spec/modules/liveIntentIdSystem_spec.js +++ b/test/spec/modules/liveIntentIdSystem_spec.js @@ -33,21 +33,6 @@ describe('LiveIntentId', function () { resetLiveIntentIdSubmodule(); }); - it('should log an error if no configParams were passed when getId', function () { - liveIntentIdSubmodule.getId(); - expect(logErrorStub.calledOnce).to.be.true; - }); - - it('should log an error if publisherId configParam was not passed when getId', function () { - liveIntentIdSubmodule.getId({}); - expect(logErrorStub.calledOnce).to.be.true; - }); - - it('should log an error if publisherId configParam was not passed when decode', function () { - liveIntentIdSubmodule.decode({}, {}); - expect(logErrorStub.calledOnce).to.be.true; - }); - it('should initialize LiveConnect with a us privacy string when getId, and include it in all requests', function () { consentDataStub.returns('1YNY'); let callBackSpy = sinon.spy(); From 18d1e10ec47944ab1fb529cba79bd3741797c5a1 Mon Sep 17 00:00:00 2001 From: Aparna Rao Date: Tue, 23 Jun 2020 19:11:49 -0400 Subject: [PATCH 435/496] 33Across: Adding floors support (#5408) * check gdpr in buildRequest * User sync based on whether gdpr applies or not * check if consent data exists during user sync * split user sync into further branches: 1) when gdpr does not apply 2) when consent data is unavailable * contribute viewability to ttxRequest * update tests * remove window mock from tests * use local variables * introduce ServerRequestBuilder * add withOptions() method to ServerRequestBuilder * add semicolons * sync up package-lock.json with upstream/master * stub window.top in tests * introduce getTopWindowSize() for test purpose * reformat code * add withSite() method to TtxRequestBuilder add withSite() method to TtxRequestBuilder * add isIframe() and _isViewabilityMeasurable() * handle NON_MEASURABLE viewability in nested iframes * consider page visibility, stub utils functions getWindowTop() and getWindowSelf() * contribute viewability as 0 for inactive tab * add prebidjs version to ttx request * send caller as an array * fix JSDoc in utils.js * send viewability as non measurable when unable to locate target HTMLElement, add warning message * introduce mapAdSlotPathToElementId() * introduce getAdSlotHTMLElement(), add logging * introduce mapAdSlotPathToElementId() * update logging in ad unit path to element id mapping * rephrase logging, fix tests * update adapter documentation * remove excessive logging * improve logging * revert change * fix return of _mapAdUnitPathToElementId() * improve logging of _mapAdUnitPathToElementId() * do not use Array.find() * return id once element is found * return id once element is found * let -> const * Removing killswitch behavior for GDPR * Updated comments to reflect current gdpr logic * URI encode consent string * Updated example site ID to help Prebid team e2e test our adapter * send page url in ortb * Removed redundant pageUrl default * Restored package-log.json that mirrors prebid's repo * Sending USP string during buildRequest * Adding USP consent data to user sync * add unit test for syncing without bidrequest * Changed to uspConsent to make the connatation consistent * Resetting adapter state in adapter after user sync rather than exposing it. * removed console log * Adding schain info * remove setting empty format ext * better tests invalid values * removing validation of schain * Fixed lint errors * First cut for bidfloors support * fixed where getFloors is read * fixed merge conflicts Co-authored-by: Gleb Glushtsov Co-authored-by: Gleb Glushtsov Co-authored-by: Gleb Glushtsov Co-authored-by: Aparna Hegde Co-authored-by: Aparna Hegde Co-authored-by: Aparna Hegde Co-authored-by: Aparna Hegde Co-authored-by: Aparna Hegde Co-authored-by: Aparna Hegde --- modules/33acrossBidAdapter.js | 49 +++++++++++++- test/spec/modules/33acrossBidAdapter_spec.js | 67 ++++++++++++++++++++ 2 files changed, 113 insertions(+), 3 deletions(-) diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js index 07773ebe999..5df2af7f32e 100644 --- a/modules/33acrossBidAdapter.js +++ b/modules/33acrossBidAdapter.js @@ -5,6 +5,8 @@ import * as utils from '../src/utils.js'; const BIDDER_CODE = '33across'; const END_POINT = 'https://ssc.33across.com/api/v1/hb'; const SYNC_ENDPOINT = 'https://ssc-cms.33across.com/ps/?m=xch&rt=html&ru=deb'; +const MEDIA_TYPE = 'banner'; +const CURRENCY = 'USD'; const adapterState = { uniqueSiteIds: [] @@ -67,11 +69,27 @@ function _getAdSlotHTMLElement(adUnitCode) { // Infer the necessary data from valid bid for a minimal ttxRequest and create HTTP request // NOTE: At this point, TTX only accepts request for a single impression -function _createServerRequest(bidRequest, gdprConsent = {}, uspConsent, pageUrl) { +function _createServerRequest({bidRequest, gdprConsent = {}, uspConsent, pageUrl}) { const ttxRequest = {}; const params = bidRequest.params; const element = _getAdSlotHTMLElement(bidRequest.adUnitCode); const sizes = _transformSizes(bidRequest.sizes); + + let format; + + // We support size based bidfloors so obtain one if there's a rule associated + if (typeof bidRequest.getFloor === 'function') { + let getFloor = bidRequest.getFloor.bind(bidRequest); + + format = sizes.map((size) => { + const formatExt = _getBidFloors(getFloor, size); + + return Object.assign({}, size, formatExt); + }); + } else { + format = sizes; + } + const minSize = _getMinSize(sizes); const viewabilityAmount = _isViewabilityMeasurable(element) @@ -86,7 +104,7 @@ function _createServerRequest(bidRequest, gdprConsent = {}, uspConsent, pageUrl) ttxRequest.imp = []; ttxRequest.imp[0] = { banner: { - format: sizes + format }, ext: { ttx: { @@ -179,6 +197,24 @@ function _createSync({ siteId = 'zzz000000000003zzz', gdprConsent = {}, uspConse return sync; } +function _getBidFloors(getFloor, size) { + const bidFloors = getFloor({ + currency: CURRENCY, + mediaType: MEDIA_TYPE, + size: [ size.w, size.h ] + }); + + if (!isNaN(bidFloors.floor) && (bidFloors.currency === CURRENCY)) { + return { + ext: { + ttx: { + bidfloors: [ bidFloors.floor ] + } + } + } + } +} + function _getSize(size) { return { w: parseInt(size[0], 10), @@ -320,7 +356,14 @@ function buildRequests(bidRequests, bidderRequest) { adapterState.uniqueSiteIds = bidRequests.map(req => req.params.siteId).filter(utils.uniques); - return bidRequests.map(req => _createServerRequest(req, gdprConsent, uspConsent, pageUrl)); + return bidRequests.map(bidRequest => _createServerRequest( + { + bidRequest, + gdprConsent, + uspConsent, + pageUrl + }) + ); } // NOTE: At this point, the response from 33exchange will only ever contain one bid i.e. the highest bid diff --git a/test/spec/modules/33acrossBidAdapter_spec.js b/test/spec/modules/33acrossBidAdapter_spec.js index 0e67b7efb63..3721cef18d9 100644 --- a/test/spec/modules/33acrossBidAdapter_spec.js +++ b/test/spec/modules/33acrossBidAdapter_spec.js @@ -140,6 +140,22 @@ describe('33acrossBidAdapter:', function () { return this; }; + this.withFormatFloors = floors => { + const format = ttxRequest.imp[0].banner.format.map((fm, i) => { + return Object.assign(fm, { + ext: { + ttx: { + bidfloors: [ floors[i] ] + } + } + }) + }); + + ttxRequest.imp[0].banner.format = format; + + return this; + }; + this.build = () => ttxRequest; } @@ -667,6 +683,57 @@ describe('33acrossBidAdapter:', function () { expect(builtServerRequests).to.deep.equal([serverRequest]); }); }); + + context('when price floor module is not enabled in bidRequest', function() { + it('does not set any bidfloors in ttxRequest', function() { + const ttxRequest = new TtxRequestBuilder() + .build(); + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .build(); + const builtServerRequests = spec.buildRequests(bidRequests, {}); + + expect(builtServerRequests).to.deep.equal([serverRequest]); + }); + }); + + context('when price floor module is enabled in bidRequest', function() { + it('does not set any bidfloors in ttxRequest if there is no floor', function() { + bidRequests[0].getFloor = () => ({}); + + const ttxRequest = new TtxRequestBuilder() + .build(); + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .build(); + const builtServerRequests = spec.buildRequests(bidRequests, {}); + + expect(builtServerRequests).to.deep.equal([serverRequest]); + }); + + it('sets bidfloors in ttxRequest if there is a floor', function() { + bidRequests[0].getFloor = ({size, currency, mediaType}) => { + const floor = (size[0] === 300 && size[1] === 250) ? 1.0 : 0.10 + return ( + { + floor, + currency: 'USD' + } + ); + }; + + const ttxRequest = new TtxRequestBuilder() + .withFormatFloors([ 1.0, 0.10 ]) + .build(); + + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .build(); + const builtServerRequests = spec.buildRequests(bidRequests, {}); + + expect(builtServerRequests).to.deep.equal([serverRequest]); + }); + }); }); describe('interpretResponse', function() { From 9c47806da57db5e1a547d22be891c9599b76e1bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Udi=20Talias=20=E2=9A=9B=EF=B8=8F?= Date: Wed, 24 Jun 2020 02:13:11 +0300 Subject: [PATCH 436/496] Vidazoo Adapter: Feature/screen-size (#5385) * feat(module): multi size request * fix getUserSyncs added tests * update(module): package-lock.json from master * feat(client): add screen resolution as request param * feat(client): add `res` param to spec * fix(client): screen size inside test Co-authored-by: roman --- modules/vidazooBidAdapter.js | 1 + test/spec/modules/vidazooBidAdapter_spec.js | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/vidazooBidAdapter.js b/modules/vidazooBidAdapter.js index 81e24a976e3..cc955b14715 100644 --- a/modules/vidazooBidAdapter.js +++ b/modules/vidazooBidAdapter.js @@ -46,6 +46,7 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest) { publisherId: pId, sizes: sizes, dealId: dealId, + res: `${screen.width}x${screen.height}` }; appendUserIdsToRequestPayload(data, userId); diff --git a/test/spec/modules/vidazooBidAdapter_spec.js b/test/spec/modules/vidazooBidAdapter_spec.js index 443f9b9d028..fb9c540708b 100644 --- a/test/spec/modules/vidazooBidAdapter_spec.js +++ b/test/spec/modules/vidazooBidAdapter_spec.js @@ -140,6 +140,7 @@ describe('VidazooBidAdapter', function () { bidId: '2d52001cabd527', publisherId: '59ac17c192832d0011283fe3', dealId: 1, + res: `${window.top.screen.width}x${window.top.screen.height}`, 'ext.param1': 'loremipsum', 'ext.param2': 'dolorsitamet', } From 6cfe4cc662766bf7b4cc398aec36d8d7a4d4e86d Mon Sep 17 00:00:00 2001 From: justinkuo-appier <66933026+justinkuo-appier@users.noreply.github.com> Date: Wed, 24 Jun 2020 07:18:01 +0800 Subject: [PATCH 437/496] Appier: add support for aliases (#5392) * Add initial partial implementation for Appier bidder adapter. * Use relative protocol for bidder API url. * Handle server response for Appier adapter and add related unit tests. * Support farm-specific prebid server and allow overriding the server with setConfig(). * Add doc for Appier bid adapter. * Fix const correctness. * Append requestId to the beacon image URL of Appier adapter to reduce the risks of being cached by proxy servers or browsers. * Send bidderRequest.refererInfo to Appier bidder server. * Remove the show beacon since now we generate it in the backend server. * Only generate a show beacon url if it's not provided by the backend. * Add version information for Appier adapter using semver (starts from 1.0.0). * Add a new adapter for Appier bidder. * Add a new adapter for Appier bidder. * add appier analyticsAdapter skeleton. * update initial working version. * refactor and remove debug messages. * fix config checking logic. * implement bidAdjustment and add timeout before send event. * unify cache operation into cacheManager to avoid direct key/value operation. * Update server name. * correct currency impl and message payload. remove unused debug messages. * update var naming. * rename creative vars. cleanup comments. * add test cases for AnalyticsAdapter. * update test specs file. * remove spec from main branch. * add unit tests for AnalyticsAdapter, #1 - Happy cases. * refactor tests. * update unit tests for AnalyticsAdapter. * add tests for bid-adjusted, bid-timeout events * fix bid adjustment test case. * add nobid case in analytics unit test. * add test case for delayed bids and prebidWon messages. * Use logInfo and logError utilility functions instead of console.log() to print debug messages. * handle timeout status message correctly. * correct isTimeout setting logic and test cases. * replace for...of by array.forEach for IE11 * apply auto formatter. * refactor: extract timeout logic to a helper function * tag analytic version with 0.1.0-beta for iCook release * Re-implement the appier analytics adapter with a simpler design and correctly handle timeouts. * Remove unused variables. * Rename methods to improve consistency. * Code cleanup: rename methods and avoid duplicated code. * Fix wrong bid response data caused by non-deterministic event ordering of prebid.js. * Send bid message immediately on auction end without delay. * add withCredentials in ajax call to get client cookie. * Fix broken unit test for appier analytic adapter. * add prediction id support. * update predictionId/configId format in tests. * Init refined appier analytics testing * hotfix: appier analytics support browserstack bug * feat: add aliases Co-authored-by: Hong Jen-Yee (PCMan) Co-authored-by: Yuan-Hung Huang Co-authored-by: kdchang Co-authored-by: chih-ping-weng --- modules/appierBidAdapter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/appierBidAdapter.js b/modules/appierBidAdapter.js index 660820daca3..1940233a0b4 100644 --- a/modules/appierBidAdapter.js +++ b/modules/appierBidAdapter.js @@ -16,6 +16,7 @@ const BIDDER_API_ENDPOINT = '/v1/prebid/bid'; export const spec = { code: 'appier', + aliases: ['appierBR', 'appierExt', 'appierGM'], supportedMediaTypes: SUPPORTED_AD_TYPES, /** From 3857643d60ad77c5539130317a1cf3bc85272ea2 Mon Sep 17 00:00:00 2001 From: arasaki-yuki <35788388+arasaki-yuki@users.noreply.github.com> Date: Wed, 24 Jun 2020 17:50:57 +0900 Subject: [PATCH 438/496] Add GMOSSP Adapter (#5377) * Add GMOSSP Adapter * fix test param --- modules/gmosspBidAdapter.js | 134 +++++++++++++++++ modules/gmosspBidAdapter.md | 36 +++++ test/spec/modules/gmosspBidAdapter_spec.js | 162 +++++++++++++++++++++ 3 files changed, 332 insertions(+) create mode 100644 modules/gmosspBidAdapter.js create mode 100644 modules/gmosspBidAdapter.md create mode 100644 test/spec/modules/gmosspBidAdapter_spec.js diff --git a/modules/gmosspBidAdapter.js b/modules/gmosspBidAdapter.js new file mode 100644 index 00000000000..d9dc8f7641a --- /dev/null +++ b/modules/gmosspBidAdapter.js @@ -0,0 +1,134 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; +import { BANNER } from '../src/mediaTypes.js'; + +const BIDDER_CODE = 'gmossp'; +const ENDPOINT = 'https://sp.gmossp-sp.jp/hb/prebid/query.ad'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER], + + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bid) { + return !!(bid.params.sid); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @param {validBidRequests[]} - an array of bids + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function (validBidRequests, bidderRequest) { + const bidRequests = []; + + const url = bidderRequest.refererInfo.referer; + const cur = getCurrencyType(); + const dnt = utils.getDNT() ? '1' : '0'; + + for (let i = 0; i < validBidRequests.length; i++) { + let queryString = ''; + + const request = validBidRequests[i]; + const tid = request.transactionId; + const bid = request.bidId; + const ver = '$prebid.version$'; + const sid = utils.getBidIdParameter('sid', request.params); + + queryString = utils.tryAppendQueryString(queryString, 'tid', tid); + queryString = utils.tryAppendQueryString(queryString, 'bid', bid); + queryString = utils.tryAppendQueryString(queryString, 'ver', ver); + queryString = utils.tryAppendQueryString(queryString, 'sid', sid); + queryString = utils.tryAppendQueryString(queryString, 'url', url); + queryString = utils.tryAppendQueryString(queryString, 'cur', cur); + queryString = utils.tryAppendQueryString(queryString, 'dnt', dnt); + + bidRequests.push({ + method: 'GET', + url: ENDPOINT, + data: queryString + }); + } + return bidRequests; + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function (bidderResponse, requests) { + const res = bidderResponse.body; + + if (utils.isEmpty(res)) { + return []; + } + + try { + res.imps.forEach(impTracker => { + const tracker = utils.createTrackPixelHtml(impTracker); + res.ad += tracker; + }); + } catch (error) { + utils.logError('Error appending tracking pixel', error); + } + + const bid = { + requestId: res.bid, + cpm: res.price, + currency: res.cur, + width: res.w, + height: res.h, + ad: res.ad, + creativeId: res.creativeId, + netRevenue: true, + ttl: res.ttl || 300 + }; + + return [bid]; + }, + + /** + * Register the user sync pixels which should be dropped after the auction. + * + * @param {SyncOptions} syncOptions Which user syncs are allowed? + * @param {ServerResponse[]} serverResponses List of server's responses. + * @return {UserSync[]} The user syncs which should be dropped. + */ + getUserSyncs: function(syncOptions, serverResponses) { + const syncs = []; + if (!serverResponses.length) { + return syncs; + } + + serverResponses.forEach(res => { + if (syncOptions.pixelEnabled && res.body && res.body.syncs.length) { + res.body.syncs.forEach(sync => { + syncs.push({ + type: 'image', + url: sync + }) + }) + } + }) + return syncs; + }, + +}; + +function getCurrencyType() { + if (config.getConfig('currency.adServerCurrency')) { + return config.getConfig('currency.adServerCurrency'); + } + return 'JPY'; +} + +registerBidder(spec); diff --git a/modules/gmosspBidAdapter.md b/modules/gmosspBidAdapter.md new file mode 100644 index 00000000000..4f63582ef9a --- /dev/null +++ b/modules/gmosspBidAdapter.md @@ -0,0 +1,36 @@ +# Overview + +``` +Module Name: GMOSSP Bid Adapter +Module Type: Bidder Adapter +Maintainer: dev@ml.gmo-am.jp +``` + +# Description +Connects to GMOSSP exchange for bids. +GMOSSP bid adapter supports Banner. + +# Test Parameters +``` +var adUnits = [ + // Banner adUnit + { + code: 'test-div', + mediaTypes: { + banner: { + sizes: [ + [300, 250], + [320, 50], + [320, 100] + ] + } + }, + bids: [{ + bidder: 'gmossp', + params: { + sid: '61590' + } + }] + } +]; +``` \ No newline at end of file diff --git a/test/spec/modules/gmosspBidAdapter_spec.js b/test/spec/modules/gmosspBidAdapter_spec.js new file mode 100644 index 00000000000..5de3db623c5 --- /dev/null +++ b/test/spec/modules/gmosspBidAdapter_spec.js @@ -0,0 +1,162 @@ +import { expect } from 'chai'; +import { spec } from 'modules/gmosspBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import * as utils from 'src/utils.js'; + +const ENDPOINT = 'https://sp.gmossp-sp.jp/hb/prebid/query.ad'; + +describe('GmosspAdapter', function () { + const adapter = newBidder(spec); + + describe('inherited functions', function () { + it('exists and is a function', function () { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', function () { + let bid = { + bidder: 'gmossp', + params: { + sid: '123456' + } + }; + + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when required params are not passed', function () { + let bid = Object.assign({}, bid); + delete bid.params; + bid.params = {}; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + const bidRequests = [ + { + bidder: 'gmossp', + params: { + sid: '123456' + }, + adUnitCode: 'adunit-code', + sizes: [ + [300, 250], + [320, 50], + [320, 100], + ], + bidId: '2b84475b5b636e', + bidderRequestId: '1f4001782ac16c', + auctionId: 'aba03555-4802-4c45-9f15-05ffa8594cff', + transactionId: '791e9d84-af92-4903-94da-24c7426d9d0c' + } + ]; + + const bidderRequest = { + refererInfo: { + referer: 'https://hoge.com' + } + }; + + it('sends bid request to ENDPOINT via GET', function () { + const requests = spec.buildRequests(bidRequests, bidderRequest); + expect(requests[0].url).to.equal(ENDPOINT); + expect(requests[0].method).to.equal('GET'); + expect(requests[0].data).to.equal('tid=791e9d84-af92-4903-94da-24c7426d9d0c&bid=2b84475b5b636e&ver=$prebid.version$&sid=123456&url=https%3A%2F%2Fhoge.com&cur=JPY&dnt=0&'); + }); + }); + + describe('interpretResponse', function () { + const bidderRequests = [ + { + bidder: 'gmossp', + params: { + sid: '123456' + }, + adUnitCode: 'adunit-code', + sizes: [ + [300, 250], + [320, 50], + [320, 100], + ], + bidId: '2b84475b5b636e', + bidderRequestId: '1f4001782ac16c', + auctionId: 'aba03555-4802-4c45-9f15-05ffa8594cff', + transactionId: '791e9d84-af92-4903-94da-24c7426d9d0c' + } + ]; + + it('should get correct banner bid response', function() { + const response = { + bid: '2b84475b5b636e', + price: 20, + w: 300, + h: 250, + ad: '
', + creativeId: '985ec572b32be309.76973017', + cur: 'JPY', + dealId: '', + imps: [ + 'https://sp.gmossp-sp.jp/hb/prebid/imp.ad' + ], + syncs: [ + 'https://sync.dsp.reemo-ad.jp' + ], + ttl: 300 + }; + + const expectedResponse = [ + { + requestId: '2b84475b5b636e', + cpm: 20, + currency: 'JPY', + width: 300, + height: 250, + ad: '
', + creativeId: '985ec572b32be309.76973017', + netRevenue: true, + ttl: 300 + } + ]; + + const result = spec.interpretResponse({ body: response }, bidderRequests); + expect(result).to.have.lengthOf(1); + + response.imps.forEach(impTracker => { + const tracker = utils.createTrackPixelHtml(impTracker); + expectedResponse[0].ad += tracker; + }); + + expect(result).to.deep.have.same.members(expectedResponse); + }); + + it('handles nobid responses', function () { + const response = ''; + + const result = spec.interpretResponse({ body: response }, bidderRequests); + expect(result.length).to.equal(0); + }); + }); + + describe('getUserSyncs', function () { + const bidResponse = { + body: { + ad: {}, + syncs: [ + 'https://hoge.com' + ] + } + }; + it('should return returns pixel syncs', function () { + const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, [bidResponse]); + expect(syncs).to.deep.equal([ + { + type: 'image', + url: 'https://hoge.com' + } + ]) + }) + }); +}); From abad8101e8583bd86d9ead81d41cc35cef28e06a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Udi=20Talias=20=E2=9A=9B=EF=B8=8F?= Date: Wed, 24 Jun 2020 22:17:46 +0300 Subject: [PATCH 439/496] Vidazoo Adapter: Feature/unit code (#5413) * feat(module): multi size request * fix getUserSyncs added tests * update(module): package-lock.json from master * feat(client): send adUnitCode on request payload Co-authored-by: roman --- modules/vidazooBidAdapter.js | 3 ++- test/spec/modules/vidazooBidAdapter_spec.js | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/vidazooBidAdapter.js b/modules/vidazooBidAdapter.js index cc955b14715..0cb5ad661e9 100644 --- a/modules/vidazooBidAdapter.js +++ b/modules/vidazooBidAdapter.js @@ -33,7 +33,7 @@ function isBidRequestValid(bid) { } function buildRequest(bid, topWindowUrl, sizes, bidderRequest) { - const { params, bidId, userId } = bid; + const { params, bidId, userId, adUnitCode } = bid; const { bidFloor, cId, pId, ext } = params; const hashUrl = hashCode(topWindowUrl); const dealId = getNextDealId(hashUrl); @@ -43,6 +43,7 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest) { cb: Date.now(), bidFloor: bidFloor, bidId: bidId, + adUnitCode: adUnitCode, publisherId: pId, sizes: sizes, dealId: dealId, diff --git a/test/spec/modules/vidazooBidAdapter_spec.js b/test/spec/modules/vidazooBidAdapter_spec.js index fb9c540708b..9441494fd88 100644 --- a/test/spec/modules/vidazooBidAdapter_spec.js +++ b/test/spec/modules/vidazooBidAdapter_spec.js @@ -4,6 +4,7 @@ import * as utils from 'src/utils.js'; const BID = { 'bidId': '2d52001cabd527', + 'adUnitCode': 'div-gpt-ad-12345-0', 'params': { 'cId': '59db6b3b4ffaa70004f45cdc', 'pId': '59ac17c192832d0011283fe3', @@ -138,6 +139,7 @@ describe('VidazooBidAdapter', function () { cb: 1000, bidFloor: 0.1, bidId: '2d52001cabd527', + adUnitCode: 'div-gpt-ad-12345-0', publisherId: '59ac17c192832d0011283fe3', dealId: 1, res: `${window.top.screen.width}x${window.top.screen.height}`, From d76ec12263eeb673dffc432c305f0d58a3f5ee7a Mon Sep 17 00:00:00 2001 From: John Rosendahl Date: Thu, 25 Jun 2020 02:54:28 -0500 Subject: [PATCH 440/496] Sovrn - Update Supported ID's, include adunitcode in ad request (#5403) * added tdid and ad-unit-code * fixed tdid * removed digitrust * repush * add package-lock from upstream master * Delete package-lock.json * add package-lock from upstream master Co-authored-by: Ankit Prakash Co-authored-by: Wesley Whitney Co-authored-by: John Rosendahl --- modules/sovrnBidAdapter.js | 36 ++++++++++++----------- test/spec/modules/sovrnBidAdapter_spec.js | 26 ++++++++-------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js index 98c8c8e3b33..f3260668b74 100644 --- a/modules/sovrnBidAdapter.js +++ b/modules/sovrnBidAdapter.js @@ -25,18 +25,13 @@ export const spec = { let sovrnImps = []; let iv; let schain; - let digitrust; + let unifiedID; utils._each(bidReqs, function (bid) { - if (!digitrust) { - const bidRequestDigitrust = utils.deepAccess(bid, 'userId.digitrustid.data'); - if (bidRequestDigitrust && (!bidRequestDigitrust.privacy || !bidRequestDigitrust.privacy.optout)) { - digitrust = { - id: bidRequestDigitrust.id, - keyv: bidRequestDigitrust.keyv - } - } + if (!unifiedID) { + unifiedID = utils.deepAccess(bid, 'userId.tdid'); } + if (bid.schain) { schain = schain || bid.schain; } @@ -47,6 +42,7 @@ export const spec = { bidSizes = bidSizes.filter(size => utils.isArray(size)) const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)})) sovrnImps.push({ + adunitcode: bid.adUnitCode, id: bid.bidId, banner: { format: processedSizes, @@ -88,15 +84,22 @@ export const spec = { utils.deepSetValue(sovrnBidReq, 'regs.ext.us_privacy', bidderRequest.uspConsent); } - if (digitrust) { - utils.deepSetValue(sovrnBidReq, 'user.ext.digitrust', { - id: digitrust.id, - keyv: digitrust.keyv - }) + if (unifiedID) { + const idArray = [{ + source: 'adserver.org', + uids: [ + { + id: unifiedID, + ext: { + rtiPartner: 'TDID' + } + } + ] + }] + utils.deepSetValue(sovrnBidReq, 'user.ext.eids', idArray) } - let url = `https://ap.lijit.com/rtb/bid?` + - `src=$$REPO_AND_VERSION$$`; + let url = `https://ap.lijit.com/rtb/bid?src=$$REPO_AND_VERSION$$`; if (iv) url += `&iv=${iv}`; return { @@ -176,7 +179,6 @@ export const spec = { .forEach(url => tracks.push({ type: 'image', url })) } } - return tracks } catch (e) { return [] diff --git a/test/spec/modules/sovrnBidAdapter_spec.js b/test/spec/modules/sovrnBidAdapter_spec.js index c82cc32207a..54ccff870eb 100644 --- a/test/spec/modules/sovrnBidAdapter_spec.js +++ b/test/spec/modules/sovrnBidAdapter_spec.js @@ -70,12 +70,17 @@ describe('sovrnBidAdapter', function() { }); it('sets the proper banner object', function() { - const payload = JSON.parse(request.data); + const payload = JSON.parse(request.data) expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]) expect(payload.imp[0].banner.w).to.equal(1) expect(payload.imp[0].banner.h).to.equal(1) }) + it('includes the ad unit code int the request', function() { + const payload = JSON.parse(request.data); + expect(payload.imp[0].adunitcode).to.equal('adunit-code') + }) + it('accepts a single array as a size', function() { const singleSize = [{ 'bidder': 'sovrn', @@ -234,7 +239,7 @@ describe('sovrnBidAdapter', function() { expect(data.source.ext.schain.nodes.length).to.equal(1) }); - it('should add digitrust data if present', function() { + it('should add the unifiedID if present', function() { const digitrustRequests = [{ 'bidder': 'sovrn', 'params': { @@ -249,12 +254,7 @@ describe('sovrnBidAdapter', function() { 'bidderRequestId': '22edbae2733bf6', 'auctionId': '1d1a030790a475', 'userId': { - 'digitrustid': { - 'data': { - 'id': 'digitrust-id-123', - 'keyv': 4 - } - } + 'tdid': 'SOMESORTOFID', } }].concat(bidRequests); const bidderRequest = { @@ -262,13 +262,13 @@ describe('sovrnBidAdapter', function() { referer: 'http://example.com/page.html', } }; - const data = JSON.parse(spec.buildRequests(digitrustRequests, bidderRequest).data); - expect(data.user.ext.digitrust.id).to.equal('digitrust-id-123'); - expect(data.user.ext.digitrust.keyv).to.equal(4); - }); + const data = JSON.parse(spec.buildRequests(digitrustRequests, bidderRequest).data); + expect(data.user.ext.eids[0].source).to.equal('adserver.org') + expect(data.user.ext.eids[0].uids[0].id).to.equal('SOMESORTOFID') + expect(data.user.ext.eids[0].uids[0].ext.rtiPartner).to.equal('TDID') + }) }); - describe('interpretResponse', function () { let response; beforeEach(function () { From 4e0df1ac3f7771ea0bdbf643043d94e4ef47a856 Mon Sep 17 00:00:00 2001 From: Corey Kress Date: Thu, 25 Jun 2020 09:31:02 -0400 Subject: [PATCH 441/496] [Synacormedia] adapter should use format for multi-size banner requests (#5410) * CAP-1614 - updated docs to show correct size for banner and some other small fixes * CAP-1636 support schain object in prebid * CAP-1636 updated the review comments * CAP-1849 - split up banner and video impressions to use format Co-authored-by: Corey Kress Co-authored-by: Rajkumar Natarajan --- modules/synacormediaBidAdapter.js | 106 ++++++++++++----- modules/synacormediaBidAdapter.md | 6 +- .../modules/synacormediaBidAdapter_spec.js | 112 +++++++++++------- 3 files changed, 148 insertions(+), 76 deletions(-) diff --git a/modules/synacormediaBidAdapter.js b/modules/synacormediaBidAdapter.js index 2ca2aeeae82..8f069f551ee 100644 --- a/modules/synacormediaBidAdapter.js +++ b/modules/synacormediaBidAdapter.js @@ -71,38 +71,18 @@ export const spec = { pos = 0; } const videoOrBannerKey = this.isVideoBid(bid) ? 'video' : 'banner'; - getAdUnitSizes(bid) - .filter(size => BLOCKED_AD_SIZES.indexOf(size.join('x')) === -1) - .forEach((size, i) => { - if (!size || size.length != 2) { - return; - } - const size0 = size[0]; - const size1 = size[1]; - const imp = { - id: `${videoOrBannerKey.substring(0, 1)}${bid.bidId}-${size0}x${size1}`, - tagid: placementId - }; - if (bidFloor !== null && !isNaN(bidFloor)) { - imp.bidfloor = bidFloor; - } + const adSizes = getAdUnitSizes(bid) + .filter(size => BLOCKED_AD_SIZES.indexOf(size.join('x')) === -1); - const videoOrBannerValue = { - w: size0, - h: size1, - pos - }; - if (videoOrBannerKey === 'video') { - if (bid.mediaTypes.video) { - this.setValidVideoParams(bid.mediaTypes.video, bid.params.video); - } - if (bid.params.video) { - this.setValidVideoParams(bid.params.video, videoOrBannerValue); - } - } - imp[videoOrBannerKey] = videoOrBannerValue; - openRtbBidRequest.imp.push(imp); - }); + let imps = []; + if (videoOrBannerKey === 'banner') { + imps = this.buildBannerImpressions(adSizes, bid, placementId, pos, bidFloor, videoOrBannerKey); + } else if (videoOrBannerKey === 'video') { + imps = this.buildVideoImpressions(adSizes, bid, placementId, pos, bidFloor, videoOrBannerKey); + } + if (imps.length > 0) { + imps.forEach(i => openRtbBidRequest.imp.push(i)); + } }); if (openRtbBidRequest.imp.length && seatId) { @@ -118,6 +98,70 @@ export const spec = { } }, + buildBannerImpressions: function(adSizes, bid, placementId, pos, bidFloor, videoOrBannerKey) { + let format = []; + let imps = []; + adSizes.forEach((size, i) => { + if (!size || size.length !== 2) { + return; + } + + format.push({ + w: size[0], + h: size[1], + }); + }); + + if (format.length > 0) { + const imp = { + id: `${videoOrBannerKey.substring(0, 1)}${bid.bidId}`, + banner: { + format, + pos + }, + tagid: placementId, + }; + if (bidFloor !== null && !isNaN(bidFloor)) { + imp.bidfloor = bidFloor; + } + imps.push(imp); + } + return imps; + }, + + buildVideoImpressions: function(adSizes, bid, placementId, pos, bidFloor, videoOrBannerKey) { + let imps = []; + adSizes.forEach((size, i) => { + if (!size || size.length != 2) { + return; + } + const size0 = size[0]; + const size1 = size[1]; + const imp = { + id: `${videoOrBannerKey.substring(0, 1)}${bid.bidId}-${size0}x${size1}`, + tagid: placementId + }; + if (bidFloor !== null && !isNaN(bidFloor)) { + imp.bidfloor = bidFloor; + } + + const videoOrBannerValue = { + w: size0, + h: size1, + pos + }; + if (bid.mediaTypes.video) { + this.setValidVideoParams(bid.mediaTypes.video, bid.params.video); + } + if (bid.params.video) { + this.setValidVideoParams(bid.params.video, videoOrBannerValue); + } + imp[videoOrBannerKey] = videoOrBannerValue; + imps.push(imp); + }); + return imps; + }, + setValidVideoParams: function (sourceObj, destObj) { Object.keys(sourceObj) .filter(param => includes(VIDEO_PARAMS, param) && sourceObj[param] !== null && (!isNaN(parseInt(sourceObj[param], 10)) || !(sourceObj[param].length < 1))) diff --git a/modules/synacormediaBidAdapter.md b/modules/synacormediaBidAdapter.md index 857cf15d240..fd71f07b3a3 100644 --- a/modules/synacormediaBidAdapter.md +++ b/modules/synacormediaBidAdapter.md @@ -42,8 +42,10 @@ https://track.technoratimedia.com/openrtb/tags?ID=%%PATTERN:hb_cache_id_synacorm code: 'test-div2', mediaTypes: { video: { - context: 'instream', - playerSize: [[300, 250]], + context: 'instream', + playerSize: [ + [300, 250] + ], } }, bids: [{ diff --git a/test/spec/modules/synacormediaBidAdapter_spec.js b/test/spec/modules/synacormediaBidAdapter_spec.js index f6fa7a20594..e15481d47e5 100644 --- a/test/spec/modules/synacormediaBidAdapter_spec.js +++ b/test/spec/modules/synacormediaBidAdapter_spec.js @@ -68,9 +68,13 @@ describe('synacormediaBidAdapter ', function () { }, mediaTypes: { banner: { - h: 600, - pos: 0, - w: 300, + format: [ + { + w: 300, + h: 600 + } + ], + pos: 0 } }, }; @@ -173,21 +177,19 @@ describe('synacormediaBidAdapter ', function () { let expectedDataImp1 = { banner: { - h: 250, - pos: 0, - w: 300, - }, - id: 'b9876abcd-300x250', - tagid: '1234', - bidfloor: 0.5 - }; - let expectedDataImp2 = { - banner: { - h: 600, - pos: 0, - w: 300, + format: [ + { + h: 250, + w: 300 + }, + { + h: 600, + w: 300 + } + ], + pos: 0 }, - id: 'b9876abcd-300x600', + id: 'b9876abcd', tagid: '1234', bidfloor: 0.5 }; @@ -201,7 +203,7 @@ describe('synacormediaBidAdapter ', function () { expect(req.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?'); expect(req.data).to.exist.and.to.be.an('object'); expect(req.data.id).to.equal('xyz123'); - expect(req.data.imp).to.eql([expectedDataImp1, expectedDataImp2]); + expect(req.data.imp).to.eql([expectedDataImp1]); // video test let reqVideo = spec.buildRequests([validBidRequestVideo], bidderRequestVideo); @@ -230,13 +232,17 @@ describe('synacormediaBidAdapter ', function () { expect(req).to.have.property('url'); expect(req.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?'); expect(req.data.id).to.equal('xyz123'); - expect(req.data.imp).to.eql([expectedDataImp1, expectedDataImp2, { + expect(req.data.imp).to.eql([expectedDataImp1, { banner: { - h: 600, - pos: 0, - w: 300, + format: [ + { + h: 600, + w: 300 + } + ], + pos: 0 }, - id: 'bfoobar-300x600', + id: 'bfoobar', tagid: '5678', bidfloor: 0.5 }]); @@ -260,11 +266,15 @@ describe('synacormediaBidAdapter ', function () { expect(req.data.imp).to.eql([ { banner: { - h: 250, - pos: 0, - w: 300, + format: [ + { + h: 250, + w: 300 + } + ], + pos: 0 }, - id: 'bfoobar-300x250', + id: 'bfoobar', tagid: '5678', bidfloor: 0.5 } @@ -289,11 +299,15 @@ describe('synacormediaBidAdapter ', function () { expect(req.data.imp).to.eql([ { banner: { - h: 250, - pos: 0, - w: 300, + format: [ + { + h: 250, + w: 300 + } + ], + pos: 0 }, - id: 'b9876abcd-300x250', + id: 'b9876abcd', tagid: '1234', } ]); @@ -316,11 +330,15 @@ describe('synacormediaBidAdapter ', function () { expect(req.data.imp).to.eql([ { banner: { - h: 250, - pos: 0, - w: 300, + format: [ + { + h: 250, + w: 300 + } + ], + pos: 0 }, - id: 'b9876abcd-300x250', + id: 'b9876abcd', tagid: '1234', } ]); @@ -344,11 +362,15 @@ describe('synacormediaBidAdapter ', function () { expect(req.data.imp).to.eql([ { banner: { - h: 250, - w: 300, - pos: 1, + format: [ + { + h: 250, + w: 300 + } + ], + pos: 1 }, - id: 'b9876abcd-300x250', + id: 'b9876abcd', tagid: '1234' } ]); @@ -371,11 +393,15 @@ describe('synacormediaBidAdapter ', function () { expect(req.data.imp).to.eql([ { banner: { - h: 250, - w: 300, - pos: 0, + format: [ + { + h: 250, + w: 300 + } + ], + pos: 0 }, - id: 'b9876abcd-300x250', + id: 'b9876abcd', tagid: '1234' } ]); From d14b9910a3cfbae58e5c4155ab643d0b3de29916 Mon Sep 17 00:00:00 2001 From: Jozef Bartek <31618107+jbartek25@users.noreply.github.com> Date: Thu, 25 Jun 2020 15:31:11 +0200 Subject: [PATCH 442/496] Improve Digital: adapter improvements (#5399) * Improve Digital: CCPA support * Outstream video support * Lint fixes * Improve Digital: outstream and deal improvements --- modules/improvedigitalBidAdapter.js | 30 ++++++++----------- .../modules/improvedigitalBidAdapter_spec.js | 9 ++++-- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index dfabf4eef55..3c000258ede 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -8,7 +8,7 @@ const BIDDER_CODE = 'improvedigital'; const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; export const spec = { - version: '7.0.0', + version: '7.1.0', code: BIDDER_CODE, gvlid: 253, aliases: ['id'], @@ -123,7 +123,7 @@ export const spec = { // Deal ID. Composite ads can have multiple line items and the ID of the first // dealID line item will be used. - if (utils.isNumber(bidObject.lid) && bidObject.buying_type === 'deal_id') { + if (utils.isNumber(bidObject.lid) && bidObject.buying_type && bidObject.buying_type !== 'rtb') { bid.dealId = bidObject.lid; } else if (Array.isArray(bidObject.lid) && Array.isArray(bidObject.buying_type) && @@ -131,7 +131,7 @@ export const spec = { let isDeal = false; bidObject.buying_type.forEach((bt, i) => { if (isDeal) return; - if (bt === 'deal_id') { + if (bt && bt !== 'rtb') { isDeal = true; bid.dealId = bidObject.lid[i]; } @@ -182,9 +182,10 @@ export const spec = { }; function isInstreamVideo(bid) { + const mediaTypes = Object.keys(utils.deepAccess(bid, 'mediaTypes', {})); const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video'); const context = utils.deepAccess(bid, 'mediaTypes.video.context'); - return bid.mediaType === 'video' || (videoMediaType && context !== 'outstream'); + return bid.mediaType === 'video' || (mediaTypes.length === 1 && videoMediaType && context !== 'outstream'); } function isOutstreamVideo(bid) { @@ -197,30 +198,23 @@ function outstreamRender(bid) { bid.renderer.push(() => { window.ANOutstreamVideo.renderAd({ sizes: [bid.width, bid.height], - width: bid.width, - height: bid.height, targetId: bid.adUnitCode, adResponse: bid.adResponse, - rendererOptions: { - showBigPlayButton: false, - showProgressBar: 'bar', - showVolume: false, - allowFullscreen: true, - skippable: false, - } - }); + rendererOptions: bid.renderer.getConfig() + }, handleOutstreamRendererEvents.bind(null, bid)); }); } +function handleOutstreamRendererEvents(bid, id, eventName) { + bid.renderer.handleVideoEvent({ id, eventName }); +} + function createRenderer(bidRequest) { const renderer = Renderer.install({ id: bidRequest.adUnitCode, url: RENDERER_URL, loaded: false, - config: { - player_width: bidRequest.mediaTypes.video.playerSize[0][0], - player_height: bidRequest.mediaTypes.video.playerSize[0][1] - }, + config: utils.deepAccess(bidRequest, 'renderer.options'), adUnitCode: bidRequest.adUnitCode }); try { diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 1466b509c54..5a20944a6ed 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -778,10 +778,15 @@ describe('Improve Digital Adapter Tests', function () { expect(bids[0].dealId).to.not.exist; response.body.bid[0].lid = 268515; - response.body.bid[0].buying_type = 'classic'; + response.body.bid[0].buying_type = 'rtb'; bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].dealId).to.not.exist; + response.body.bid[0].lid = 268515; + response.body.bid[0].buying_type = 'classic'; + bids = spec.interpretResponse(response, {bidderRequest}); + expect(bids[0].dealId).to.equal(268515); + response.body.bid[0].lid = 268515; response.body.bid[0].buying_type = 'deal_id'; bids = spec.interpretResponse(response, {bidderRequest}); @@ -798,7 +803,7 @@ describe('Improve Digital Adapter Tests', function () { expect(bids[0].dealId).to.not.exist; response.body.bid[0].lid = [ 268515, 12456, 34567 ]; - response.body.bid[0].buying_type = [ 'classic', 'deal_id', 'deal_id' ]; + response.body.bid[0].buying_type = [ 'rtb', 'deal_id', 'deal_id' ]; bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].dealId).to.equal(12456); }); From 9186d64daf4961b9fa06de3b33e9f95fb2053ccc Mon Sep 17 00:00:00 2001 From: guiann Date: Thu, 25 Jun 2020 15:31:19 +0200 Subject: [PATCH 443/496] Ayl gdp rdefault value (#5391) * Remove useless bidderCode in bid response * send all the available sizes in the bid request * Use the banner sizes if given * avoid compatibility issue with old bid format * Remove gdpr default apply value * minor: use better variable name * Add unit test on unspecified gdprApplies Co-authored-by: Guillaume --- modules/adyoulikeBidAdapter.js | 4 ++-- test/spec/modules/adyoulikeBidAdapter_spec.js | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/modules/adyoulikeBidAdapter.js b/modules/adyoulikeBidAdapter.js index 412acdde3dd..725ee0f5626 100644 --- a/modules/adyoulikeBidAdapter.js +++ b/modules/adyoulikeBidAdapter.js @@ -48,7 +48,7 @@ export const spec = { if (bidderRequest && bidderRequest.gdprConsent) { payload.gdprConsent = { consentString: bidderRequest.gdprConsent.consentString, - consentRequired: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true + consentRequired: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : null }; } @@ -80,7 +80,7 @@ export const spec = { try { bidRequests = JSON.parse(request.data).Bids; - } catch (e) { + } catch (err) { // json error initial request can't be read } diff --git a/test/spec/modules/adyoulikeBidAdapter_spec.js b/test/spec/modules/adyoulikeBidAdapter_spec.js index 3573681dd17..d2d4e10c17f 100644 --- a/test/spec/modules/adyoulikeBidAdapter_spec.js +++ b/test/spec/modules/adyoulikeBidAdapter_spec.js @@ -275,6 +275,29 @@ describe('Adyoulike Adapter', function () { expect(payload.uspConsent).to.exist.and.to.equal(uspConsentData); }); + it('should not set a default value for gdpr consentRequired', function () { + let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; + let uspConsentData = '1YCC'; + let bidderRequest = { + 'auctionId': '1d1a030790a475', + 'bidderRequestId': '22edbae2733bf6', + 'timeout': 3000, + 'gdprConsent': { + consentString: consentString + }, + 'uspConsent': uspConsentData + }; + + bidderRequest.bids = bidRequestWithSinglePlacement; + + const request = spec.buildRequests(bidRequestWithSinglePlacement, bidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.gdprConsent).to.exist; + expect(payload.gdprConsent.consentString).to.exist.and.to.equal(consentString); + expect(payload.gdprConsent.consentRequired).to.be.null; + }); + it('sends bid request to endpoint with single placement', function () { const request = spec.buildRequests(bidRequestWithSinglePlacement, bidderRequest); const payload = JSON.parse(request.data); From 0dd9faa7646a5175eccc0b2a5c936936f67e52ee Mon Sep 17 00:00:00 2001 From: Robert Ray Martinez III Date: Thu, 25 Jun 2020 12:22:00 -0700 Subject: [PATCH 444/496] Price floors new schema support AB Test (#5390) * Price floors new schema support AB Test * Add new serve-fast command + lint fix * update comment * Only sum up modelWeights once and set as prop! Fix minor bug in handleFetchResponse to overwrite skipRate --- gulpfile.js | 13 +- modules/priceFloors.js | 63 ++++++++- test/spec/modules/priceFloors_spec.js | 186 ++++++++++++++++++++++++++ 3 files changed, 252 insertions(+), 10 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 58e294bc559..64152baa7ba 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -341,12 +341,12 @@ function injectFakeServerEndpointDev() { function startFakeServer() { const fakeServer = spawn('node', ['./test/fake-server/index.js', `--port=${FAKE_SERVER_PORT}`]); - fakeServer.stdout.on('data', (data) => { - console.log(`stdout: ${data}`); - }); - fakeServer.stderr.on('data', (data) => { - console.log(`stderr: ${data}`); - }); + fakeServer.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + fakeServer.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + }); } // support tasks @@ -372,6 +372,7 @@ gulp.task('build', gulp.series(clean, 'build-bundle-prod')); gulp.task('build-postbid', gulp.series(escapePostbidConfig, buildPostbid)); gulp.task('serve', gulp.series(clean, lint, gulp.parallel('build-bundle-dev', watch, test))); +gulp.task('serve-fast', gulp.series(clean, gulp.parallel('build-bundle-dev', watch))); gulp.task('serve-fake', gulp.series(clean, gulp.parallel('build-bundle-dev', watch), injectFakeServerEndpointDev, test, startFakeServer)); gulp.task('default', gulp.series(clean, makeWebpackPkg)); diff --git a/modules/priceFloors.js b/modules/priceFloors.js index e84576d3474..6d35a0a74cc 100644 --- a/modules/priceFloors.js +++ b/modules/priceFloors.js @@ -295,11 +295,29 @@ export function updateAdUnitsForAuction(adUnits, floorData, auctionId) { }); } +export function pickRandomModel(modelGroups, weightSum) { + // we loop through the models subtracting the current model weight from our random number + // once we are at or below zero, we return the associated model + let random = Math.floor(Math.random() * weightSum + 1) + for (let i = 0; i < modelGroups.length; i++) { + random -= modelGroups[i].modelWeight; + if (random <= 0) { + return modelGroups[i]; + } + } +}; + /** * @summary Updates the adUnits accordingly and returns the necessary floorsData for the current auction */ export function createFloorsDataForAuction(adUnits, auctionId) { let resolvedFloorsData = utils.deepClone(_floorsConfig); + // if using schema 2 pick a model here: + if (utils.deepAccess(resolvedFloorsData, 'data.floorsSchemaVersion') === 2) { + // merge the models specific stuff into the top level data settings (now it looks like floorsSchemaVersion 1!) + let { modelGroups, ...rest } = resolvedFloorsData.data; + resolvedFloorsData.data = Object.assign(rest, pickRandomModel(modelGroups, rest.modelWeightSum)); + } // if we do not have a floors data set, we will try to use data set on adUnits let useAdUnitData = Object.keys(utils.deepAccess(resolvedFloorsData, 'data.values') || {}).length === 0; @@ -372,6 +390,36 @@ function validateRules(floorsData, numFields, delimiter) { return Object.keys(floorsData.values).length > 0; } +function modelIsValid(model) { + // schema.fields has only allowed attributes + if (!validateSchemaFields(utils.deepAccess(model, 'schema.fields'))) { + return false; + } + return validateRules(model, model.schema.fields.length, model.schema.delimiter || '|') +} + +/** + * @summary Mapping of floor schema version to it's corresponding validation + */ +const floorsSchemaValidation = { + 1: data => modelIsValid(data), + 2: data => { + // model groups should be an array with at least one element + if (!Array.isArray(data.modelGroups) || data.modelGroups.length === 0) { + return false; + } + // every model should have valid schema, as well as an accompanying modelWeight + data.modelWeightSum = 0; + return data.modelGroups.every(model => { + if (typeof model.modelWeight === 'number' && modelIsValid(model)) { + data.modelWeightSum += model.modelWeight; + return true; + } + return false; + }); + } +}; + /** * @summary Fields array should have at least one entry and all should match allowed fields * Each rule in the values array should have a 'key' and 'floor' param @@ -382,11 +430,12 @@ export function isFloorsDataValid(floorsData) { if (typeof floorsData !== 'object') { return false; } - // schema.fields has only allowed attributes - if (!validateSchemaFields(utils.deepAccess(floorsData, 'schema.fields'))) { + floorsData.floorsSchemaVersion = floorsData.floorsSchemaVersion || 1; + if (typeof floorsSchemaValidation[floorsData.floorsSchemaVersion] !== 'function') { + utils.logError(`${MODULE_NAME}: Unknown floorsSchemaVersion: `, floorsData.floorsSchemaVersion); return false; } - return validateRules(floorsData, floorsData.schema.fields.length, floorsData.schema.delimiter || '|') + return floorsSchemaValidation[floorsData.floorsSchemaVersion](floorsData); } /** @@ -458,7 +507,13 @@ export function handleFetchResponse(fetchResponse) { floorResponse = fetchResponse; } // Update the global floors object according to the fetched data - _floorsConfig.data = parseFloorData(floorResponse, 'fetch') || _floorsConfig.data; + const fetchData = parseFloorData(floorResponse, 'fetch'); + if (fetchData) { + // set .data to it + _floorsConfig.data = fetchData; + // set skipRate override if necessary + _floorsConfig.skipRate = utils.isNumber(fetchData.skipRate) ? fetchData.skipRate : _floorsConfig.skipRate; + } // if any auctions are waiting for fetch to finish, we need to continue them! resumeDelayedAuctions(); diff --git a/test/spec/modules/priceFloors_spec.js b/test/spec/modules/priceFloors_spec.js index 2a816aef104..9d35554c27f 100644 --- a/test/spec/modules/priceFloors_spec.js +++ b/test/spec/modules/priceFloors_spec.js @@ -407,6 +407,89 @@ describe('the price floors module', function () { fetchStatus: undefined }); }); + it('should randomly pick a model if floorsSchemaVersion is 2', function () { + let inputFloors = { + ...basicFloorConfig, + data: { + floorsSchemaVersion: 2, + currency: 'USD', + modelGroups: [ + { + modelVersion: 'model-1', + modelWeight: 10, + schema: { + delimiter: '|', + fields: ['mediaType'] + }, + values: { + 'banner': 1.0, + '*': 2.5 + } + }, { + modelVersion: 'model-2', + modelWeight: 40, + schema: { + delimiter: '|', + fields: ['size'] + }, + values: { + '300x250': 1.0, + '*': 2.5 + } + }, { + modelVersion: 'model-3', + modelWeight: 50, + schema: { + delimiter: '|', + fields: ['domain'] + }, + values: { + 'www.prebid.org': 1.0, + '*': 2.5 + } + } + ] + } + }; + handleSetFloorsConfig(inputFloors); + + // stub random to give us wanted vals + let randValue; + sandbox.stub(Math, 'random').callsFake(() => randValue); + + // 0 - 10 should use first model + randValue = 0.05; + runStandardAuction(); + validateBidRequests(true, { + skipped: false, + modelVersion: 'model-1', + location: 'setConfig', + skipRate: 0, + fetchStatus: undefined + }); + + // 11 - 50 should use second model + randValue = 0.40; + runStandardAuction(); + validateBidRequests(true, { + skipped: false, + modelVersion: 'model-2', + location: 'setConfig', + skipRate: 0, + fetchStatus: undefined + }); + + // 51 - 100 should use third model + randValue = 0.75; + runStandardAuction(); + validateBidRequests(true, { + skipped: false, + modelVersion: 'model-3', + location: 'setConfig', + skipRate: 0, + fetchStatus: undefined + }); + }); it('should not overwrite previous data object if the new one is bad', function () { handleSetFloorsConfig({...basicFloorConfig}); handleSetFloorsConfig({ @@ -547,6 +630,44 @@ describe('the price floors module', function () { fetchStatus: 'success' }); }); + it('it should correctly overwrite skipRate with fetch skipRate', function () { + // so floors does not skip + sandbox.stub(Math, 'random').callsFake(() => 0.99); + // init the fake server with response stuff + let fetchFloorData = { + ...basicFloorData, + modelVersion: 'fetch model name', // change the model name + }; + fetchFloorData.skipRate = 95; + fakeFloorProvider.respondWith(JSON.stringify(fetchFloorData)); + + // run setConfig indicating fetch + handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakeFloorProvider.json'}}); + + // floor provider should be called + expect(fakeFloorProvider.requests.length).to.equal(1); + expect(fakeFloorProvider.requests[0].url).to.equal('http://www.fakeFloorProvider.json'); + + // start the auction it should delay and not immediately call `continueAuction` + runStandardAuction(); + + // exposedAdUnits should be undefined if the auction has not continued + expect(exposedAdUnits).to.be.undefined; + + // make the fetch respond + fakeFloorProvider.respond(); + expect(exposedAdUnits).to.not.be.undefined; + + // the exposedAdUnits should be from the fetch not setConfig level data + // and fetchStatus is success since fetch worked + validateBidRequests(true, { + skipped: false, + modelVersion: 'fetch model name', + location: 'fetch', + skipRate: 95, + fetchStatus: 'success' + }); + }); it('Should not break if floor provider returns 404', function () { // run setConfig indicating fetch handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakeFloorProvider.json'}}); @@ -615,6 +736,11 @@ describe('the price floors module', function () { expect(logErrorSpy.calledOnce).to.equal(true); }); describe('isFloorsDataValid', function () { + it('should return false if unknown floorsSchemaVersion', function () { + let inputFloorData = utils.deepClone(basicFloorData); + inputFloorData.floorsSchemaVersion = 3; + expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); + }); it('should work correctly for fields array', function () { let inputFloorData = utils.deepClone(basicFloorData); expect(isFloorsDataValid(inputFloorData)).to.to.equal(true); @@ -670,6 +796,66 @@ describe('the price floors module', function () { expect(isFloorsDataValid(inputFloorData)).to.to.equal(true); expect(inputFloorData.values).to.deep.equal({ 'test-div-1|native': 1.0 }); }); + it('should work correctly for floorsSchemaVersion 2', function () { + let inputFloorData = { + floorsSchemaVersion: 2, + currency: 'USD', + modelGroups: [ + { + modelVersion: 'model-1', + modelWeight: 10, + schema: { + delimiter: '|', + fields: ['mediaType'] + }, + values: { + 'banner': 1.0, + '*': 2.5 + } + }, { + modelVersion: 'model-2', + modelWeight: 40, + schema: { + delimiter: '|', + fields: ['size'] + }, + values: { + '300x250': 1.0, + '*': 2.5 + } + }, { + modelVersion: 'model-3', + modelWeight: 50, + schema: { + delimiter: '|', + fields: ['domain'] + }, + values: { + 'www.prebid.org': 1.0, + '*': 2.5 + } + } + ] + }; + expect(isFloorsDataValid(inputFloorData)).to.to.equal(true); + + // remove one of the modelWeight's and it should be false + delete inputFloorData.modelGroups[1].modelWeight; + expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); + inputFloorData.modelGroups[1].modelWeight = 40; + + // remove values from a model and it should not validate + const tempValues = {...inputFloorData.modelGroups[0].values}; + delete inputFloorData.modelGroups[0].values; + expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); + inputFloorData.modelGroups[0].values = tempValues; + + // modelGroups should be an array and have at least one entry + delete inputFloorData.modelGroups; + expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); + inputFloorData.modelGroups = []; + expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); + }); }); describe('getFloor', function () { let bidRequest = { From 03bd2d3b6f18629eab217aa3371047ea6142d45c Mon Sep 17 00:00:00 2001 From: robertrmartinez Date: Thu, 25 Jun 2020 12:29:53 -0700 Subject: [PATCH 445/496] Prebid 3.24.0 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5f08b7356fa..c203d896ddc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.24.0-pre", + "version": "3.24.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 81d0c58b9ce7144fb5dfa64ff31f028af8ef81d2 Mon Sep 17 00:00:00 2001 From: robertrmartinez Date: Thu, 25 Jun 2020 13:28:35 -0700 Subject: [PATCH 446/496] Increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c203d896ddc..db35edf3b9d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.24.0", + "version": "3.25.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 240e605e2d5bb88987f598c46c4df7df37a9d7da Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Mon, 29 Jun 2020 00:47:14 -0700 Subject: [PATCH 447/496] Removing Digitrust related test case for PubMatic bidder (#5426) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * removed digitrust test case --- test/spec/modules/pubmaticBidAdapter_spec.js | 41 -------------------- 1 file changed, 41 deletions(-) diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 45259767133..7a33df6fdfa 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -1350,47 +1350,6 @@ describe('PubMatic adapter', function () { }); }); - describe('Digitrust Id', function() { - it('send the digitrust id if it is present', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.digitrustid = {data: {id: 'digitrust_user_id'}}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'digitru.st', - 'uids': [{ - 'id': 'digitrust_user_id', - 'atype': 1 - }] - }]); - }); - - it('do not pass if not string', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.digitrustid = {data: {id: 1}}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.digitrustid = {data: {id: []}}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.digitrustid = {data: {id: null}}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.digitrustid = {data: {id: {}}}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - }); - }); - describe('ID5 Id', function() { it('send the id5 id if it is present', function() { bidRequests[0].userId = {}; From 2a06f084343d413b7ec9a9e55219bd6df188190a Mon Sep 17 00:00:00 2001 From: Pablo Brud Date: Mon, 29 Jun 2020 12:31:47 -0300 Subject: [PATCH 448/496] CCPA modifications in the NextRoll adapter (#5409) * Add native support * Add response testing * DRY test * Change required from bool to int * Set mediaType * Fixes objects * Fixes object access * Remove ad property, only set it for banner * Update tests * Moving hardcoding values to constants * Update docs with native information * Revert "Add native support" * Getting rid of CCPA adapter validation (#9) * fix linter errors (#10) Co-authored-by: Ricardo Azpeitia Pimentel Co-authored-by: Abimael Martinez --- modules/nextrollBidAdapter.js | 144 +++++++++---------- test/spec/modules/nextrollBidAdapter_spec.js | 46 +----- 2 files changed, 75 insertions(+), 115 deletions(-) diff --git a/modules/nextrollBidAdapter.js b/modules/nextrollBidAdapter.js index 56fca22d2c3..02ebcd3f87a 100644 --- a/modules/nextrollBidAdapter.js +++ b/modules/nextrollBidAdapter.js @@ -30,12 +30,12 @@ export const spec = { */ buildRequests: function (validBidRequests, bidderRequest) { let topLocation = utils.parseUrl(utils.deepAccess(bidderRequest, 'refererInfo.referer')); - let consent = hasCCPAConsent(bidderRequest); - return validBidRequests.map((bidRequest, index) => { + + return validBidRequests.map((bidRequest) => { return { method: 'POST', options: { - withCredentials: consent, + withCredentials: true, }, url: BIDDER_ENDPOINT, data: { @@ -59,9 +59,10 @@ export const spec = { site: _getSite(bidRequest, topLocation), seller: _getSeller(bidRequest), device: _getDevice(bidRequest), + regs: _getRegs(bidderRequest) } - } - }) + }; + }); }, /** @@ -82,22 +83,22 @@ export const spec = { } function _getBanner(bidRequest) { - let sizes = _getSizes(bidRequest) - if (sizes === undefined) return undefined - return {format: sizes} + let sizes = _getSizes(bidRequest); + if (sizes === undefined) return undefined; + return {format: sizes}; } function _getNative(mediaTypeNative) { - if (mediaTypeNative === undefined) return undefined - let assets = _getNativeAssets(mediaTypeNative) - if (assets === undefined || assets.length == 0) return undefined + if (mediaTypeNative === undefined) return undefined; + let assets = _getNativeAssets(mediaTypeNative); + if (assets === undefined || assets.length == 0) return undefined; return { request: { native: { assets: assets } } - } + }; } /* @@ -114,44 +115,44 @@ const NATIVE_ASSET_MAP = [ {id: 4, kind: 'img', key: 'logo', type: 2}, {id: 5, kind: 'data', key: 'sponsoredBy', type: 1}, {id: 6, kind: 'data', key: 'body', type: 2} -] +]; const ASSET_KIND_MAP = { title: _getTitleAsset, img: _getImageAsset, data: _getDataAsset, -} +}; function _getAsset(mediaTypeNative, assetMap) { - let asset = mediaTypeNative[assetMap.key] - if (asset === undefined) return undefined - let assetFunc = ASSET_KIND_MAP[assetMap.kind] + const asset = mediaTypeNative[assetMap.key]; + if (asset === undefined) return undefined; + const assetFunc = ASSET_KIND_MAP[assetMap.kind]; return { id: assetMap.id, required: (assetMap.required || !!asset.required) ? 1 : 0, [assetMap.kind]: assetFunc(asset, assetMap) - } + }; } function _getTitleAsset(title, _assetMap) { - return {len: title.len || 0} + return {len: title.len || 0}; } function _getMinAspectRatio(aspectRatio, property) { - if (!utils.isPlainObject(aspectRatio)) return 1 + if (!utils.isPlainObject(aspectRatio)) return 1; - let ratio = aspectRatio['ratio_' + property] - let min = aspectRatio['min_' + property] + const ratio = aspectRatio['ratio_' + property]; + const min = aspectRatio['min_' + property]; - if (utils.isNumber(ratio)) return ratio - if (utils.isNumber(min)) return min + if (utils.isNumber(ratio)) return ratio; + if (utils.isNumber(min)) return min; - return 1 + return 1; } function _getImageAsset(image, assetMap) { - let sizes = image.sizes - let aspectRatio = image.aspect_ratios ? image.aspect_ratios[0] : undefined + const sizes = image.sizes; + const aspectRatio = image.aspect_ratios ? image.aspect_ratios[0] : undefined; return { type: assetMap.type, @@ -159,24 +160,26 @@ function _getImageAsset(image, assetMap) { h: (sizes ? sizes[1] : undefined), wmin: _getMinAspectRatio(aspectRatio, 'width'), hmin: _getMinAspectRatio(aspectRatio, 'height'), - } + }; } function _getDataAsset(data, assetMap) { return { type: assetMap.type, len: data.len || 0 - } + }; } function _getNativeAssets(mediaTypeNative) { - return NATIVE_ASSET_MAP.map(assetMap => _getAsset(mediaTypeNative, assetMap)).filter(asset => asset !== undefined) + return NATIVE_ASSET_MAP + .map(assetMap => _getAsset(mediaTypeNative, assetMap)) + .filter(asset => asset !== undefined); } function _getUser(requests) { - let id = utils.deepAccess(requests, '0.userId.nextroll'); + const id = utils.deepAccess(requests, '0.userId.nextroll'); if (id === undefined) { - return + return; } return { @@ -186,7 +189,7 @@ function _getUser(requests) { id }] } - } + }; } function _buildResponse(bidResponse, bid) { @@ -200,15 +203,15 @@ function _buildResponse(bidResponse, bid) { currency: 'USD', netRevenue: true, ttl: 300 - } + }; if (utils.isStr(bid.adm)) { - response.mediaType = BANNER - response.ad = utils.replaceAuctionPrice(bid.adm, bid.price) + response.mediaType = BANNER; + response.ad = utils.replaceAuctionPrice(bid.adm, bid.price); } else { - response.mediaType = NATIVE - response.native = _getNativeResponse(bid.adm, bid.price) + response.mediaType = NATIVE; + response.native = _getNativeResponse(bid.adm, bid.price); } - return response + return response; } const privacyLink = 'https://info.evidon.com/pub_info/573'; @@ -222,30 +225,30 @@ function _getNativeResponse(adm, price) { impressionTrackers: adm.imptrackers.map(impTracker => utils.replaceAuctionPrice(impTracker, price)), privacyLink: privacyLink, privacyIcon: privacyIcon - } + }; return adm.assets.reduce((accResponse, asset) => { - let assetMaps = NATIVE_ASSET_MAP.filter(assetMap => assetMap.id === asset.id && asset[assetMap.kind] !== undefined) - if (assetMaps.length === 0) return accResponse - let assetMap = assetMaps[0] - accResponse[assetMap.key] = _getAssetResponse(asset, assetMap) - return accResponse - }, baseResponse) + const assetMaps = NATIVE_ASSET_MAP.filter(assetMap => assetMap.id === asset.id && asset[assetMap.kind] !== undefined); + if (assetMaps.length === 0) return accResponse; + const assetMap = assetMaps[0]; + accResponse[assetMap.key] = _getAssetResponse(asset, assetMap); + return accResponse; + }, baseResponse); } function _getAssetResponse(asset, assetMap) { switch (assetMap.kind) { case 'title': - return asset.title.text + return asset.title.text; case 'img': return { url: asset.img.url, width: asset.img.w, height: asset.img.h - } + }; case 'data': - return asset.data.value + return asset.data.value; } } @@ -256,25 +259,25 @@ function _getSite(bidRequest, topLocation) { publisher: { id: utils.getBidIdParameter('publisherId', bidRequest.params) } - } + }; } function _getSeller(bidRequest) { return { id: utils.getBidIdParameter('sellerId', bidRequest.params) - } + }; } function _getSizes(bidRequest) { if (!utils.isArray(bidRequest.sizes)) { - return undefined + return undefined; } return bidRequest.sizes.filter(_isValidSize).map(size => { return { w: size[0], h: size[1] } - }) + }); } function _isValidSize(size) { @@ -288,7 +291,18 @@ function _getDevice(_bidRequest) { language: navigator['language'], os: _getOs(navigator.userAgent.toLowerCase()), osv: _getOsVersion(navigator.userAgent) + }; +} + +function _getRegs(bidderRequest) { + if (!bidderRequest || !bidderRequest.uspConsent) { + return undefined; } + return { + ext: { + us_privacy: bidderRequest.uspConsent + } + }; } function _getOs(userAgent) { @@ -308,7 +322,7 @@ function _getOs(userAgent) { } function _getOsVersion(userAgent) { - let clientStrings = [ + const clientStrings = [ { s: 'Android', r: /Android/ }, { s: 'iOS', r: /(iPhone|iPad|iPod)/ }, { s: 'Mac OS X', r: /Mac OS X/ }, @@ -328,26 +342,4 @@ function _getOsVersion(userAgent) { return cs ? cs.s : 'unknown'; } -export function hasCCPAConsent(bidderRequest) { - if (bidderRequest === undefined) return true; - if (typeof bidderRequest.uspConsent !== 'string') { - return true; - } - const usps = bidderRequest.uspConsent; - const version = usps[0]; - - // If we don't support the consent string, assume no-consent. - if (version !== '1' || usps.length < 3) { - return false; - } - - const notice = usps[1]; - const optOut = usps[2]; - - if (notice === 'N' || optOut === 'Y') { - return false; - } - return true; -} - registerBidder(spec); diff --git a/test/spec/modules/nextrollBidAdapter_spec.js b/test/spec/modules/nextrollBidAdapter_spec.js index e1d85244931..7722443e584 100644 --- a/test/spec/modules/nextrollBidAdapter_spec.js +++ b/test/spec/modules/nextrollBidAdapter_spec.js @@ -124,6 +124,13 @@ describe('nextrollBidAdapter', function() { expect(bannerObject.format[0].w).to.be.equal(300); expect(bannerObject.format[0].h).to.be.equal(200); }); + + it('sets the CCPA consent string', function () { + const us_privacy = '1YYY'; + const request = spec.buildRequests([validBid], {'uspConsent': us_privacy})[0]; + + expect(request.data.regs.ext.us_privacy).to.be.equal(us_privacy); + }); }); describe('interpretResponse', function () { @@ -258,43 +265,4 @@ describe('nextrollBidAdapter', function() { expect(response[0].native).to.be.deep.equal(expectedResponse) }) }) - - describe('hasCCPAConsent', function() { - function ccpaRequest(consentString) { - return { - bidderCode: 'bidderX', - auctionId: 'e3a336ad-2222-4a1c-bbbb-ecc7c5554a34', - uspConsent: consentString - }; - } - - const noNoticeCases = ['1NYY', '1NNN', '1N--']; - noNoticeCases.forEach((ccpaString, index) => { - it(`No notice should indicate no consent (case ${index})`, function () { - const req = ccpaRequest(ccpaString); - expect(hasCCPAConsent(req)).to.be.false; - }); - }); - - const noConsentCases = ['1YYY', '1YYN', '1YY-']; - noConsentCases.forEach((ccpaString, index) => { - it(`Opt-Out should indicate no consent (case ${index})`, function () { - const req = ccpaRequest(ccpaString); - expect(hasCCPAConsent(req)).to.be.false; - }); - }); - - const consentCases = [undefined, '1YNY', '1YN-', '1Y--', '1---']; - consentCases.forEach((ccpaString, index) => { - it(`should indicate consent (case ${index})`, function() { - const req = ccpaRequest(ccpaString); - expect(hasCCPAConsent(req)).to.be.true; - }) - }); - - it('builds a request with no credentials', function () { - const noConsent = ccpaRequest('1YYY'); - expect(spec.buildRequests([validBid], noConsent)[0].options.withCredentials).to.be.false; - }); - }); }); From ccf10b6dd5b0b3e41d01a35198ab7a83e2ce4df1 Mon Sep 17 00:00:00 2001 From: Rich Audience Date: Mon, 29 Jun 2020 20:21:47 +0200 Subject: [PATCH 449/496] Add Render RichAudience Adapter (#5357) * Add Render RichAudience Adapter * Update richaudienceBidAdapter.md & Add Try/Catch Co-authored-by: sgimenez --- modules/richaudienceBidAdapter.js | 55 ++++++-- modules/richaudienceBidAdapter.md | 31 ++++- .../modules/richaudienceBidAdapter_spec.js | 118 +++++++++++++++++- 3 files changed, 188 insertions(+), 16 deletions(-) diff --git a/modules/richaudienceBidAdapter.js b/modules/richaudienceBidAdapter.js index 22db9709c7c..43bef356a73 100755 --- a/modules/richaudienceBidAdapter.js +++ b/modules/richaudienceBidAdapter.js @@ -2,6 +2,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {config} from '../src/config.js'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import * as utils from '../src/utils.js'; +import { Renderer } from '../src/Renderer.js'; const BIDDER_CODE = 'richaudience'; let REFERER = ''; @@ -46,7 +47,7 @@ export const spec = { transactionId: bid.transactionId, timeout: config.getConfig('bidderTimeout'), user: raiSetEids(bid), - demand: raiGetDemandType(bid) ? 'video' : 'display', + demand: raiGetDemandType(bid), videoData: raiGetVideoInfo(bid) }; @@ -97,8 +98,18 @@ export const spec = { if (response.media_type === 'video') { bidResponse.vastXml = response.vastXML; + try { + if (JSON.parse(bidRequest.data).videoData.format == 'outstream') { + bidResponse.renderer = Renderer.install({ + url: 'https://cdn3.richaudience.com/prebidVideo/player.js' + }); + bidResponse.renderer.setRender(renderer); + } + } catch (e) { + bidResponse.ad = response.adm; + } } else { - bidResponse.ad = response.adm + bidResponse.ad = response.adm; } bidResponses.push(bidResponse); @@ -121,7 +132,7 @@ export const spec = { var consent = ''; if (gdprConsent && typeof gdprConsent.consentString === 'string' && typeof gdprConsent.consentString != 'undefined') { - consent = `pubconsent='${gdprConsent.consentString}'&euconsent='${gdprConsent.consentString}'` + consent = `consentString=’${gdprConsent.consentString}` } if (syncOptions.iframeEnabled) { @@ -165,20 +176,23 @@ function raiGetSizes(bid) { } function raiGetDemandType(bid) { + let raiFormat = 'display'; if (bid.mediaTypes != undefined) { if (bid.mediaTypes.video != undefined) { - return true; + raiFormat = 'video'; } } - return false; + return raiFormat; } function raiGetVideoInfo(bid) { - let videoData = []; - if (raiGetDemandType(bid)) { - videoData.push({format: bid.mediaTypes.video.context}); - videoData.push({playerSize: bid.mediaTypes.video.playerSize}); - videoData.push({mimes: bid.mediaTypes.video.mimes}); + let videoData; + if (raiGetDemandType(bid) == 'video') { + videoData = { + format: bid.mediaTypes.video.context, + playerSize: bid.mediaTypes.video.playerSize, + mimes: bid.mediaTypes.video.mimes + }; } return videoData; } @@ -206,3 +220,24 @@ function raiSetUserId(bid, eids, source, value) { }); } } + +function renderer(bid) { + bid.renderer.push(() => { + renderAd(bid) + }); +} + +function renderAd(bid) { + let raOutstreamHBPassback = `${bid.vastXml}`; + let raPlayerHB = { + config: bid.params[0].player != undefined ? { + end: bid.params[0].player.end != null ? bid.params[0].player.end : 'close', + init: bid.params[0].player.init != null ? bid.params[0].player.init : 'close', + skin: bid.params[0].player.skin != null ? bid.params[0].player.skin : 'light', + } : {end: 'close', init: 'close', skin: 'light'}, + pid: bid.params[0].pid, + adUnit: bid.adUnitCode + }; + + window.raParams(raPlayerHB, raOutstreamHBPassback, true); +} diff --git a/modules/richaudienceBidAdapter.md b/modules/richaudienceBidAdapter.md index 852af5f1844..932cdb8f8de 100644 --- a/modules/richaudienceBidAdapter.md +++ b/modules/richaudienceBidAdapter.md @@ -3,7 +3,7 @@ ``` Module Name: Rich Audience Bidder Adapter Module Type: Bidder Adapter -Maintainer: cert@richaudience.com +Maintainer: cert@richaudience.com ``` # Description @@ -15,7 +15,7 @@ Please reach out to your account manager for more information. # Test Parameters -## Web +## Web - DISPLAY ``` var adUnits = [ { @@ -45,6 +45,33 @@ Please reach out to your account manager for more information. ]; ``` +## Web - VIDEO +``` + var adUnits = [{ + code: 'video1', + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 480] + } + }, + + bids: [{ + bidder: 'richaudience', + params: { + pid: 'OjUW9KhuQV', + supplyType: 'site', + player: { + init: "open", + end: "close", + skin: "light" + } + } + }] + + }]; +``` + ## In-app ``` var adUnits = [ diff --git a/test/spec/modules/richaudienceBidAdapter_spec.js b/test/spec/modules/richaudienceBidAdapter_spec.js index 2bc699b4640..f18e67a3ac5 100644 --- a/test/spec/modules/richaudienceBidAdapter_spec.js +++ b/test/spec/modules/richaudienceBidAdapter_spec.js @@ -29,12 +29,12 @@ describe('Richaudience adapter tests', function () { user: {} }]; - var DEFAULT_PARAMS_VIDEO = [{ + var DEFAULT_PARAMS_VIDEO_IN = [{ adUnitCode: 'test-div', bidId: '2c7c8e9c900244', mediaTypes: { video: { - context: 'instream', // or 'outstream' + context: 'instream', playerSize: [640, 480], mimes: ['video/mp4'] } @@ -52,6 +52,57 @@ describe('Richaudience adapter tests', function () { user: {} }]; + var DEFAULT_PARAMS_VIDEO_OUT = [{ + adUnitCode: 'test-div', + bidId: '2c7c8e9c900244', + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 480], + mimes: ['video/mp4'] + } + }, + bidder: 'richaudience', + params: { + bidfloor: 0.5, + pid: 'ADb1f40rmi', + supplyType: 'site' + }, + auctionId: '0cb3144c-d084-4686-b0d6-f5dbe917c563', + bidRequestsCount: 1, + bidderRequestId: '1858b7382993ca', + transactionId: '29df2112-348b-4961-8863-1b33684d95e6', + user: {} + }]; + + var DEFAULT_PARAMS_VIDEO_OUT_PARAMS = [{ + adUnitCode: 'test-div', + bidId: '2c7c8e9c900244', + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 480], + mimes: ['video/mp4'] + } + }, + bidder: 'richaudience', + params: { + bidfloor: 0.5, + pid: 'ADb1f40rmi', + supplyType: 'site', + player: { + init: 'close', + end: 'close', + skin: 'dark' + } + }, + auctionId: '0cb3144c-d084-4686-b0d6-f5dbe917c563', + bidRequestsCount: 1, + bidderRequestId: '1858b7382993ca', + transactionId: '29df2112-348b-4961-8863-1b33684d95e6', + user: {} + }]; + var DEFAULT_PARAMS_APP = [{ adUnitCode: 'test-div', bidId: '2c7c8e9c900244', @@ -191,6 +242,45 @@ describe('Richaudience adapter tests', function () { expect(requestContent).to.have.property('numIframes').and.to.equal(0); }) + it('Verify build request to prebid video inestream', function() { + const request = spec.buildRequests(DEFAULT_PARAMS_VIDEO_IN, { + gdprConsent: { + consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', + gdprApplies: true + }, + refererInfo: { + referer: 'https://domain.com', + numIframes: 0 + } + }); + + expect(request[0]).to.have.property('method').and.to.equal('POST'); + const requestContent = JSON.parse(request[0].data); + + expect(requestContent).to.have.property('demand').and.to.equal('video'); + expect(requestContent.videoData).to.have.property('format').and.to.equal('instream'); + // expect(requestContent.videoData.playerSize[0][0]).to.equal('640'); + // expect(requestContent.videoData.playerSize[0][0]).to.equal('480'); + }) + + it('Verify build request to prebid video outstream', function() { + const request = spec.buildRequests(DEFAULT_PARAMS_VIDEO_OUT, { + gdprConsent: { + consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', + gdprApplies: true + }, + refererInfo: { + referer: 'https://domain.com', + numIframes: 0 + } + }); + + expect(request[0]).to.have.property('method').and.to.equal('POST'); + const requestContent = JSON.parse(request[0].data); + + expect(requestContent.videoData).to.have.property('format').and.to.equal('outstream'); + }) + describe('gdpr test', function () { it('Verify build request with GDPR', function () { config.setConfig({ @@ -502,8 +592,26 @@ describe('Richaudience adapter tests', function () { expect(bid.dealId).to.equal('dealId'); }); - it('no banner media response', function () { - const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { + it('no banner media response inestream', function () { + const request = spec.buildRequests(DEFAULT_PARAMS_VIDEO_IN, { + gdprConsent: { + consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', + gdprApplies: true + }, + refererInfo: { + referer: 'https://domain.com', + numIframes: 0 + } + }); + + const bids = spec.interpretResponse(BID_RESPONSE_VIDEO, request[0]); + const bid = bids[0]; + expect(bid.mediaType).to.equal('video'); + expect(bid.vastXml).to.equal(''); + }); + + it('no banner media response outstream', function () { + const request = spec.buildRequests(DEFAULT_PARAMS_VIDEO_OUT, { gdprConsent: { consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', gdprApplies: true @@ -516,7 +624,9 @@ describe('Richaudience adapter tests', function () { const bids = spec.interpretResponse(BID_RESPONSE_VIDEO, request[0]); const bid = bids[0]; + expect(bid.mediaType).to.equal('video'); expect(bid.vastXml).to.equal(''); + expect(bid.renderer.url).to.equal('https://cdn3.richaudience.com/prebidVideo/player.js'); }); it('Verifies bidder_code', function () { From bcfc972986d5590dcc5215c48c242f1fbc665e8f Mon Sep 17 00:00:00 2001 From: matthieularere-msq <63732822+matthieularere-msq@users.noreply.github.com> Date: Tue, 30 Jun 2020 04:42:40 +0200 Subject: [PATCH 450/496] =?UTF-8?q?Mediasquare:=20Add=20support=20for=20us?= =?UTF-8?q?pConsent=20+=20schain=20userIds=20support.=20Plu=E2=80=A6=20(#5?= =?UTF-8?q?396)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Mediasquare: Add support for uspConsent + schain userIds support. Plus enhance userSync * fix iframeEnabled and pixelEnabled + suggested shortand statement --- modules/mediasquareBidAdapter.js | 36 ++++++++-------- .../modules/mediasquareBidAdapter_spec.js | 42 +++++++++++-------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/modules/mediasquareBidAdapter.js b/modules/mediasquareBidAdapter.js index 91adfacb64d..cb52c288caf 100644 --- a/modules/mediasquareBidAdapter.js +++ b/modules/mediasquareBidAdapter.js @@ -21,7 +21,7 @@ export const spec = { * @return boolean True if this is a valid bid, and false otherwise. */ isBidRequestValid: function(bid) { - return !!(bid.params.owner || bid.params.code); + return !!(bid.params.owner && bid.params.code); }, /** * Make a server request from the list of BidRequests. @@ -49,13 +49,17 @@ export const spec = { const payload = { codes: codes, referer: encodeURIComponent(bidderRequest.refererInfo.referer) - // schain: validBidRequests.schain, }; - if (bidderRequest && bidderRequest.gdprConsent) { - payload.gdpr = { - consent_string: bidderRequest.gdprConsent.consentString, - consent_required: bidderRequest.gdprConsent.gdprApplies - }; + if (bidderRequest) { // modules informations (gdpr, ccpa, schain, userId) + if (bidderRequest.gdprConsent) { + payload.gdpr = { + consent_string: bidderRequest.gdprConsent.consentString, + consent_required: bidderRequest.gdprConsent.gdprApplies + }; + } + if (bidderRequest.uspConsent) { payload.uspConsent = bidderRequest.uspConsent; } + if (bidderRequest.schain) { payload.schain = bidderRequest.schain; } + if (bidderRequest.userId) { payload.userId = bidderRequest.userId; } }; if (test) { payload.debug = true; } const payloadString = JSON.stringify(payload); @@ -109,25 +113,19 @@ export const spec = { * @param {ServerResponse[]} serverResponses List of server's responses. * @return {UserSync[]} The user syncs which should be dropped. */ - getUserSyncs: function(syncOptions, serverResponses, gdprConsent) { + getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { let params = ''; let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD; - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - if (typeof gdprConsent.gdprApplies === 'boolean') { params += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; } else { params += `&gdpr_consent=${gdprConsent.consentString}`; } - } - if (syncOptions.iframeEnabled) { + if (serverResponses[0].body.hasOwnProperty('cookies') && typeof serverResponses[0].body.cookies === 'object') { + return serverResponses[0].body.cookies; + } else { + if (gdprConsent && typeof gdprConsent.consentString === 'string') { params += typeof gdprConsent.gdprApplies === 'boolean' ? `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}` : `&gdpr_consent=${gdprConsent.consentString}`; } + if (uspConsent && typeof uspConsent === 'string') { params += '&uspConsent=' + uspConsent } return { type: 'iframe', url: endpoint + BIDDER_ENDPOINT_SYNC + '?type=iframe' + params }; } - if (syncOptions.pixelEnabled) { - return { - type: 'image', - url: endpoint + BIDDER_ENDPOINT_SYNC + '?type=pixel' + params - }; - } - return false; }, /** diff --git a/test/spec/modules/mediasquareBidAdapter_spec.js b/test/spec/modules/mediasquareBidAdapter_spec.js index 56c1fd105fe..351fbb40228 100644 --- a/test/spec/modules/mediasquareBidAdapter_spec.js +++ b/test/spec/modules/mediasquareBidAdapter_spec.js @@ -39,7 +39,7 @@ describe('MediaSquare bid adapter tests', function () { 'bidder': 'msqClassic', 'code': 'test/publishername_atf_desktop_rg_pave', 'bid_id': 'aaaa1234', - }] + }], }}; const DEFAULT_OPTIONS = { @@ -51,7 +51,21 @@ describe('MediaSquare bid adapter tests', function () { refererInfo: { referer: 'https://www.prebid.org', canonicalUrl: 'https://www.prebid.org/the/link/to/the/page' - } + }, + uspConsent: '111222333', + userId: {'id5id': '1111'}, + schain: { + 'ver': '1.0', + 'complete': 1, + 'nodes': [{ + 'asi': 'exchange1.com', + 'sid': '1234', + 'hp': 1, + 'rid': 'bid-request-1', + 'name': 'publisher', + 'domain': 'publisher.com' + }] + }, }; it('Verify build request', function () { const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); @@ -103,21 +117,15 @@ describe('MediaSquare bid adapter tests', function () { const won = spec.onBidWon(response[0]); expect(won).to.equal(true); }); - it('Verifies user sync', function () { - var syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: false, - }, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent); + it('Verifies user sync without cookie in bid response', function () { + var syncs = spec.getUserSyncs({}, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent); expect(syncs).to.have.property('type').and.to.equal('iframe'); - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true, - }, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent); - expect(syncs).to.have.property('type').and.to.equal('image'); - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false, - }, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent); - expect(syncs).to.equal(false); + }); + it('Verifies user sync with cookies in bid response', function () { + BID_RESPONSE.body.cookies = [{'type': 'image', 'url': 'http://www.cookie.sync.org/'}]; + var syncs = spec.getUserSyncs({}, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent); + expect(syncs).to.have.lengthOf(1); + expect(syncs[0]).to.have.property('type').and.to.equal('image'); + expect(syncs[0]).to.have.property('url').and.to.equal('http://www.cookie.sync.org/'); }); }); From 76d5c51ec0af20c8404465263281c7caec30704e Mon Sep 17 00:00:00 2001 From: Scott Date: Tue, 30 Jun 2020 17:05:01 +0200 Subject: [PATCH 451/496] upgrade id5IdSystem to use v2 of our fetch endpoint (#5406) - allow publishers to pass deterministic signals - add a counter to provide analytics on the number of auctions using the id5Id --- modules/id5IdSystem.js | 99 ++++++- modules/userId/userId.md | 5 +- test/spec/modules/id5IdSystem_spec.js | 383 ++++++++++++++++++++++++++ test/spec/modules/userId_spec.js | 54 +--- 4 files changed, 477 insertions(+), 64 deletions(-) create mode 100644 test/spec/modules/id5IdSystem_spec.js diff --git a/modules/id5IdSystem.js b/modules/id5IdSystem.js index 151782791af..3449926c896 100644 --- a/modules/id5IdSystem.js +++ b/modules/id5IdSystem.js @@ -1,13 +1,22 @@ /** * This module adds ID5 to the User ID module * The {@link module:modules/userId} module is required - * @module modules/unifiedIdSystem + * @module modules/id5IdSystem * @requires module:modules/userId */ import * as utils from '../src/utils.js' -import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook.js'; +import { ajax } from '../src/ajax.js'; +import { submodule } from '../src/hook.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { getStorageManager } from '../src/storageManager.js'; + +const MODULE_NAME = 'id5Id'; +const GVLID = 131; +const BASE_NB_COOKIE_NAME = 'pbjs-id5id'; +const NB_COOKIE_EXP_DAYS = (30 * 24 * 60 * 60 * 1000); // 30 days + +const storage = getStorageManager(GVLID, MODULE_NAME); /** @type {Submodule} */ export const id5IdSubmodule = { @@ -16,11 +25,13 @@ export const id5IdSubmodule = { * @type {string} */ name: 'id5Id', + /** * Vendor id of ID5 * @type {Number} */ - gvlid: 131, + gvlid: GVLID, + /** * decode the stored id value for passing to bid requests * @function decode @@ -28,25 +39,46 @@ export const id5IdSubmodule = { * @returns {(Object|undefined)} */ decode(value) { - return (value && typeof value['ID5ID'] === 'string') ? { 'id5id': value['ID5ID'] } : undefined; + if (value && typeof value.ID5ID === 'string') { + // don't lose our legacy value from cache + return { 'id5id': value.ID5ID }; + } else if (value && typeof value.universal_uid === 'string') { + return { 'id5id': value.universal_uid }; + } else { + return undefined; + } }, + /** * performs action to obtain id and return a value in the callback's response argument - * @function + * @function getId * @param {SubmoduleParams} [configParams] * @param {ConsentData} [consentData] * @param {(Object|undefined)} cacheIdObj * @returns {IdResponse|undefined} */ getId(configParams, consentData, cacheIdObj) { - if (!configParams || typeof configParams.partner !== 'number') { - utils.logError(`User ID - ID5 submodule requires partner to be defined as a number`); + if (!hasRequiredParams(configParams)) { return undefined; } const hasGdpr = (consentData && typeof consentData.gdprApplies === 'boolean' && consentData.gdprApplies) ? 1 : 0; const gdprConsentString = hasGdpr ? consentData.consentString : ''; - const storedUserId = this.decode(cacheIdObj); - const url = `https://id5-sync.com/g/v1/${configParams.partner}.json?1puid=${storedUserId ? storedUserId.id5id : ''}&gdpr=${hasGdpr}&gdpr_consent=${gdprConsentString}`; + const url = `https://id5-sync.com/g/v2/${configParams.partner}.json?gdpr_consent=${gdprConsentString}&gdpr=${hasGdpr}`; + const referer = getRefererInfo(); + const signature = (cacheIdObj && cacheIdObj.signature) ? cacheIdObj.signature : ''; + const pubId = (cacheIdObj && cacheIdObj.ID5ID) ? cacheIdObj.ID5ID : ''; // TODO: remove when 1puid isn't needed + const data = { + 'partner': configParams.partner, + '1puid': pubId, // TODO: remove when 1puid isn't needed + 'nbPage': incrementNb(configParams), + 'o': 'pbjs', + 'pd': configParams.pd || '', + 'rf': referer.referer, + 's': signature, + 'top': referer.reachedTop ? 1 : 0, + 'u': referer.stack[0] || window.location.href, + 'v': '$prebid.version$' + }; const resp = function (callback) { const callbacks = { @@ -55,6 +87,7 @@ export const id5IdSubmodule = { if (response) { try { responseObj = JSON.parse(response); + resetNb(configParams); } catch (error) { utils.logError(error); } @@ -66,10 +99,54 @@ export const id5IdSubmodule = { callback(); } }; - ajax(url, callbacks, undefined, { method: 'GET', withCredentials: true }); + ajax(url, callbacks, JSON.stringify(data), { method: 'POST', withCredentials: true }); }; return {callback: resp}; + }, + + /** + * Similar to Submodule#getId, this optional method returns response to for id that exists already. + * If IdResponse#id is defined, then it will be written to the current active storage even if it exists already. + * If IdResponse#callback is defined, then it'll called at the end of auction. + * It's permissible to return neither, one, or both fields. + * @function extendId + * @param {SubmoduleParams} configParams + * @param {Object} cacheIdObj - existing id, if any + * @return {(IdResponse|function(callback:function))} A response object that contains id and/or callback. + */ + extendId(configParams, cacheIdObj) { + incrementNb(configParams); + return cacheIdObj; } }; +function hasRequiredParams(configParams) { + if (!configParams || typeof configParams.partner !== 'number') { + utils.logError(`User ID - ID5 submodule requires partner to be defined as a number`); + return false; + } + return true; +} +function nbCookieName(configParams) { + return hasRequiredParams(configParams) ? `${BASE_NB_COOKIE_NAME}-${configParams.partner}-nb` : undefined; +} +function nbCookieExpStr(expDays) { + return (new Date(Date.now() + expDays)).toUTCString(); +} +function storeNbInCookie(configParams, nb) { + storage.setCookie(nbCookieName(configParams), nb, nbCookieExpStr(NB_COOKIE_EXP_DAYS), 'Lax'); +} +function getNbFromCookie(configParams) { + const cacheNb = storage.getCookie(nbCookieName(configParams)); + return (cacheNb) ? parseInt(cacheNb) : 0; +} +function incrementNb(configParams) { + const nb = (getNbFromCookie(configParams) + 1); + storeNbInCookie(configParams, nb); + return nb; +} +function resetNb(configParams) { + storeNbInCookie(configParams, 0); +} + submodule('userId', id5IdSubmodule); diff --git a/modules/userId/userId.md b/modules/userId/userId.md index eb9e985a1d6..20b140c3900 100644 --- a/modules/userId/userId.md +++ b/modules/userId/userId.md @@ -25,12 +25,13 @@ pbjs.setConfig({ }, { name: "id5Id", params: { - partner: 173 //Set your real ID5 partner ID here for production, please ask for one at http://id5.io/prebid + partner: 173, //Set your real ID5 partner ID here for production, please ask for one at https://id5.io/universal-id + pd: "some-pd-string" // See https://console.id5.io/docs/public/prebid for details }, storage: { type: "cookie", name: "id5id", - expires: 5, // Expiration of cookies in days + expires: 90, // Expiration of cookies in days refreshInSeconds: 8*3600 // User Id cache lifetime in seconds, defaulting to 'expires' }, }, { diff --git a/test/spec/modules/id5IdSystem_spec.js b/test/spec/modules/id5IdSystem_spec.js new file mode 100644 index 00000000000..5080cd94bd8 --- /dev/null +++ b/test/spec/modules/id5IdSystem_spec.js @@ -0,0 +1,383 @@ +import { init, requestBidsHook, setSubmoduleRegistry, coreStorage } from 'modules/userId/index.js'; +import { config } from 'src/config.js'; +import { id5IdSubmodule } from 'modules/id5IdSystem.js'; +import { server } from 'test/mocks/xhr.js'; +import events from 'src/events.js'; +import CONSTANTS from 'src/constants.json'; + +let expect = require('chai').expect; + +describe('ID5 ID System', function() { + const ID5_MODULE_NAME = 'id5Id'; + const ID5_EIDS_NAME = ID5_MODULE_NAME.toLowerCase(); + const ID5_SOURCE = 'id5-sync.com'; + const ID5_PARTNER = 173; + const ID5_ENDPOINT = `https://id5-sync.com/g/v2/${ID5_PARTNER}.json`; + const ID5_COOKIE_NAME = 'id5idcookie'; + const ID5_NB_COOKIE_NAME = `pbjs-id5id-${ID5_PARTNER}-nb`; + const ID5_EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; + const ID5_STORED_ID = 'storedid5id'; + const ID5_STORED_SIGNATURE = '123456'; + const ID5_STORED_OBJ = { + 'universal_uid': ID5_STORED_ID, + 'signature': ID5_STORED_SIGNATURE + }; + const ID5_LEGACY_STORED_OBJ = { + 'ID5ID': ID5_STORED_ID + } + const ID5_RESPONSE_ID = 'newid5id'; + const ID5_RESPONSE_SIGNATURE = 'abcdef'; + const ID5_JSON_RESPONSE = { + 'universal_uid': ID5_RESPONSE_ID, + 'signature': ID5_RESPONSE_SIGNATURE, + 'link_type': 0 + }; + + function getId5FetchConfig(storageName = ID5_COOKIE_NAME, storageType = 'cookie') { + return { + name: ID5_MODULE_NAME, + params: { + partner: ID5_PARTNER + }, + storage: { + name: storageName, + type: storageType, + expires: 90 + } + } + } + function getId5ValueConfig(value) { + return { + name: ID5_MODULE_NAME, + value: { + id5id: value + } + } + } + function getUserSyncConfig(userIds) { + return { + userSync: { + userIds: userIds, + syncDelay: 0 + } + } + } + function getFetchCookieConfig() { + return getUserSyncConfig([getId5FetchConfig()]); + } + function getFetchLocalStorageConfig() { + return getUserSyncConfig([getId5FetchConfig(ID5_COOKIE_NAME, 'html5')]); + } + function getValueConfig(value) { + return getUserSyncConfig([getId5ValueConfig(value)]); + } + function getAdUnitMock(code = 'adUnit-code') { + return { + code, + mediaTypes: {banner: {}, native: {}}, + sizes: [[300, 200], [300, 600]], + bids: [{bidder: 'sampleBidder', params: {placementId: 'banner-only-bidder'}}] + }; + } + + describe('Xhr Requests from getId()', function() { + const responseHeader = { 'Content-Type': 'application/json' }; + let callbackSpy = sinon.spy(); + + beforeEach(function() { + callbackSpy.resetHistory(); + }); + afterEach(function () { + + }); + + it('should fail if no partner is provided in the config', function() { + expect(id5IdSubmodule.getId()).to.be.eq(undefined); + }); + + it('should call the ID5 server with 1puid field for legacy storedObj format', function () { + let submoduleCallback = id5IdSubmodule.getId(getId5FetchConfig().params, undefined, ID5_LEGACY_STORED_OBJ).callback; + submoduleCallback(callbackSpy); + + let request = server.requests[0]; + let requestBody = JSON.parse(request.requestBody); + expect(request.url).to.contain(ID5_ENDPOINT); + expect(request.withCredentials).to.be.true; + expect(requestBody.s).to.eq(''); + expect(requestBody.partner).to.eq(ID5_PARTNER); + expect(requestBody['1puid']).to.eq(ID5_STORED_ID); + + request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); + expect(callbackSpy.calledOnce).to.be.true; + expect(callbackSpy.lastCall.lastArg).to.deep.equal(ID5_JSON_RESPONSE); + }); + + it('should call the ID5 server with signature field for new storedObj format', function () { + let submoduleCallback = id5IdSubmodule.getId(getId5FetchConfig().params, undefined, ID5_STORED_OBJ).callback; + submoduleCallback(callbackSpy); + + let request = server.requests[0]; + let requestBody = JSON.parse(request.requestBody); + expect(request.url).to.contain(ID5_ENDPOINT); + expect(request.withCredentials).to.be.true; + expect(requestBody.s).to.eq(ID5_STORED_SIGNATURE); + expect(requestBody.partner).to.eq(ID5_PARTNER); + expect(requestBody['1puid']).to.eq(''); + + request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); + expect(callbackSpy.calledOnce).to.be.true; + expect(callbackSpy.lastCall.lastArg).to.deep.equal(ID5_JSON_RESPONSE); + }); + + it('should call the ID5 server with pd field when pd config is set', function () { + const pubData = 'b50ca08271795a8e7e4012813f23d505193d75c0f2e2bb99baa63aa822f66ed3'; + + let config = getId5FetchConfig().params; + config.pd = pubData; + + let submoduleCallback = id5IdSubmodule.getId(config, undefined, ID5_STORED_OBJ).callback; + submoduleCallback(callbackSpy); + + let request = server.requests[0]; + let requestBody = JSON.parse(request.requestBody); + expect(request.url).to.contain(ID5_ENDPOINT); + expect(request.withCredentials).to.be.true; + expect(requestBody.s).to.eq(ID5_STORED_SIGNATURE); + expect(requestBody.pd).to.eq(pubData); + expect(requestBody['1puid']).to.eq(''); + + request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); + expect(callbackSpy.calledOnce).to.be.true; + expect(callbackSpy.lastCall.lastArg).to.deep.equal(ID5_JSON_RESPONSE); + }); + + it('should call the ID5 server with empty pd field when pd config is not set', function () { + let config = getId5FetchConfig().params; + config.pd = undefined; + + let submoduleCallback = id5IdSubmodule.getId(config, undefined, ID5_STORED_OBJ).callback; + submoduleCallback(callbackSpy); + + let request = server.requests[0]; + let requestBody = JSON.parse(request.requestBody); + expect(request.url).to.contain(ID5_ENDPOINT); + expect(request.withCredentials).to.be.true; + expect(requestBody.pd).to.eq(''); + + request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); + expect(callbackSpy.calledOnce).to.be.true; + expect(callbackSpy.lastCall.lastArg).to.deep.equal(ID5_JSON_RESPONSE); + }); + + it('should call the ID5 server with nb=1 when no stored value exists', function () { + coreStorage.setCookie(ID5_NB_COOKIE_NAME, '', ID5_EXPIRED_COOKIE_DATE); + + let submoduleCallback = id5IdSubmodule.getId(getId5FetchConfig().params, undefined, ID5_STORED_OBJ).callback; + submoduleCallback(callbackSpy); + + let request = server.requests[0]; + let requestBody = JSON.parse(request.requestBody); + expect(request.url).to.contain(ID5_ENDPOINT); + expect(request.withCredentials).to.be.true; + expect(requestBody.nbPage).to.eq(1); + + request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); + expect(callbackSpy.calledOnce).to.be.true; + expect(callbackSpy.lastCall.lastArg).to.deep.equal(ID5_JSON_RESPONSE); + + expect(coreStorage.getCookie(ID5_NB_COOKIE_NAME)).to.be.eq('0'); + }); + + it('should call the ID5 server with incremented nb when stored value exists', function () { + let expStr = (new Date(Date.now() + 25000).toUTCString()); + coreStorage.setCookie(ID5_NB_COOKIE_NAME, '1', expStr); + + let submoduleCallback = id5IdSubmodule.getId(getId5FetchConfig().params, undefined, ID5_STORED_OBJ).callback; + submoduleCallback(callbackSpy); + + let request = server.requests[0]; + let requestBody = JSON.parse(request.requestBody); + expect(request.url).to.contain(ID5_ENDPOINT); + expect(request.withCredentials).to.be.true; + expect(requestBody.nbPage).to.eq(2); + + request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); + expect(callbackSpy.calledOnce).to.be.true; + expect(callbackSpy.lastCall.lastArg).to.deep.equal(ID5_JSON_RESPONSE); + + expect(coreStorage.getCookie(ID5_NB_COOKIE_NAME)).to.be.eq('0'); + }); + }); + + describe('Request Bids Hook', function() { + let adUnits; + + beforeEach(function() { + sinon.stub(events, 'getEvents').returns([]); + coreStorage.setCookie(ID5_COOKIE_NAME, '', ID5_EXPIRED_COOKIE_DATE); + coreStorage.setCookie(`${ID5_COOKIE_NAME}_last`, '', ID5_EXPIRED_COOKIE_DATE); + coreStorage.setCookie(ID5_NB_COOKIE_NAME, '', ID5_EXPIRED_COOKIE_DATE); + adUnits = [getAdUnitMock()]; + }); + afterEach(function() { + events.getEvents.restore(); + coreStorage.setCookie(ID5_COOKIE_NAME, '', ID5_EXPIRED_COOKIE_DATE); + coreStorage.setCookie(`${ID5_COOKIE_NAME}_last`, '', ID5_EXPIRED_COOKIE_DATE); + coreStorage.setCookie(ID5_NB_COOKIE_NAME, '', ID5_EXPIRED_COOKIE_DATE); + }); + + it('should add stored ID from cookie to bids', function (done) { + let expStr = (new Date(Date.now() + 25000).toUTCString()); + coreStorage.setCookie(ID5_COOKIE_NAME, JSON.stringify(ID5_STORED_OBJ), expStr); + + setSubmoduleRegistry([id5IdSubmodule]); + init(config); + config.setConfig(getFetchCookieConfig()); + + requestBidsHook(function () { + adUnits.forEach(unit => { + unit.bids.forEach(bid => { + expect(bid).to.have.deep.nested.property(`userId.${ID5_EIDS_NAME}`); + expect(bid.userId.id5id).to.equal(ID5_STORED_ID); + expect(bid.userIdAsEids[0]).to.deep.equal({ + source: ID5_SOURCE, + uids: [{ id: ID5_STORED_ID, atype: 1 }] + }); + }); + }); + done(); + }, { adUnits }); + }); + + it('should add config value ID to bids', function (done) { + setSubmoduleRegistry([id5IdSubmodule]); + init(config); + config.setConfig(getValueConfig(ID5_STORED_ID)); + + requestBidsHook(function () { + adUnits.forEach(unit => { + unit.bids.forEach(bid => { + expect(bid).to.have.deep.nested.property(`userId.${ID5_EIDS_NAME}`); + expect(bid.userId.id5id).to.equal(ID5_STORED_ID); + expect(bid.userIdAsEids[0]).to.deep.equal({ + source: ID5_SOURCE, + uids: [{ id: ID5_STORED_ID, atype: 1 }] + }); + }); + }); + done(); + }, { adUnits }); + }); + + it('should set nb=1 in cookie when no stored value exists', function () { + let expStr = (new Date(Date.now() + 25000).toUTCString()); + coreStorage.setCookie(ID5_COOKIE_NAME, JSON.stringify(ID5_STORED_OBJ), expStr); + coreStorage.setCookie(ID5_NB_COOKIE_NAME, '', ID5_EXPIRED_COOKIE_DATE); + + setSubmoduleRegistry([id5IdSubmodule]); + init(config); + config.setConfig(getFetchCookieConfig()); + + let innerAdUnits; + requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); + + expect(coreStorage.getCookie(ID5_NB_COOKIE_NAME)).to.be.eq('1'); + }); + + it('should increment nb in cookie when stored value exists', function () { + let expStr = (new Date(Date.now() + 25000).toUTCString()); + coreStorage.setCookie(ID5_COOKIE_NAME, JSON.stringify(ID5_STORED_OBJ), expStr); + coreStorage.setCookie(ID5_NB_COOKIE_NAME, '1', expStr); + + setSubmoduleRegistry([id5IdSubmodule]); + init(config); + config.setConfig(getFetchCookieConfig()); + + let innerAdUnits; + requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); + + expect(coreStorage.getCookie(ID5_NB_COOKIE_NAME)).to.be.eq('2'); + }); + + it('should call ID5 servers with signature and incremented nb post auction if refresh needed', function () { + let expStr = (new Date(Date.now() + 25000).toUTCString()); + coreStorage.setCookie(ID5_COOKIE_NAME, JSON.stringify(ID5_STORED_OBJ), expStr); + coreStorage.setCookie(`${ID5_COOKIE_NAME}_last`, (new Date(Date.now() - 50000).toUTCString()), expStr); + coreStorage.setCookie(ID5_NB_COOKIE_NAME, '1', expStr); + + let id5Config = getFetchCookieConfig(); + id5Config.userSync.userIds[0].storage.refreshInSeconds = 2; + + setSubmoduleRegistry([id5IdSubmodule]); + init(config); + config.setConfig(id5Config); + + let innerAdUnits; + requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); + + expect(coreStorage.getCookie(ID5_NB_COOKIE_NAME)).to.be.eq('2'); + + expect(server.requests).to.be.empty; + events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); + + let request = server.requests[0]; + let requestBody = JSON.parse(request.requestBody); + expect(request.url).to.contain(ID5_ENDPOINT); + expect(requestBody.s).to.eq(ID5_STORED_SIGNATURE); + expect(requestBody.nbPage).to.eq(2); + + const responseHeader = { 'Content-Type': 'application/json' }; + request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); + + expect(coreStorage.getCookie(ID5_COOKIE_NAME)).to.be.eq(JSON.stringify(ID5_JSON_RESPONSE)); + expect(coreStorage.getCookie(ID5_NB_COOKIE_NAME)).to.be.eq('0'); + }); + + it('should call ID5 servers with 1puid and nb=1 post auction if refresh needed for legacy stored object', function () { + let expStr = (new Date(Date.now() + 25000).toUTCString()); + coreStorage.setCookie(ID5_COOKIE_NAME, JSON.stringify(ID5_LEGACY_STORED_OBJ), expStr); + coreStorage.setCookie(`${ID5_COOKIE_NAME}_last`, (new Date(Date.now() - 50000).toUTCString()), expStr); + + let id5Config = getFetchCookieConfig(); + id5Config.userSync.userIds[0].storage.refreshInSeconds = 2; + + setSubmoduleRegistry([id5IdSubmodule]); + init(config); + config.setConfig(id5Config); + + let innerAdUnits; + requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); + + expect(coreStorage.getCookie(ID5_NB_COOKIE_NAME)).to.be.eq('1'); + + expect(server.requests).to.be.empty; + events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); + + let request = server.requests[0]; + let requestBody = JSON.parse(request.requestBody); + expect(request.url).to.contain(ID5_ENDPOINT); + expect(requestBody['1puid']).to.eq(ID5_STORED_ID); + expect(requestBody.nbPage).to.eq(1); + + const responseHeader = { 'Content-Type': 'application/json' }; + request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); + + expect(coreStorage.getCookie(ID5_COOKIE_NAME)).to.be.eq(JSON.stringify(ID5_JSON_RESPONSE)); + expect(coreStorage.getCookie(ID5_NB_COOKIE_NAME)).to.be.eq('0'); + }); + }); + + describe('Decode stored object', function() { + const decodedObject = { 'id5id': ID5_STORED_ID }; + + it('should properly decode from a stored object', function() { + expect(id5IdSubmodule.decode(ID5_STORED_OBJ)).to.deep.equal(decodedObject); + }); + it('should properly decode from a legacy stored object', function() { + expect(id5IdSubmodule.decode(ID5_LEGACY_STORED_OBJ)).to.deep.equal(decodedObject); + }); + it('should return undefined if passed a string', function() { + expect(id5IdSubmodule.decode('somestring')).to.eq(undefined); + }); + }); +}); diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index 8ce81ea85b0..5dda322f3c8 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -971,54 +971,6 @@ describe('User ID', function() { done(); }, {adUnits}); }); - it('test hook from id5id cookies when refresh needed', function(done) { - // simulate existing browser local storage values - coreStorage.setCookie('id5id', JSON.stringify({'ID5ID': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('id5id_last', (new Date(Date.now() - 7200 * 1000)).toUTCString(), (new Date(Date.now() + 5000).toUTCString())); - - sinon.stub(utils, 'logError'); // getId should failed with a logError as it has no partnerId - - setSubmoduleRegistry([id5IdSubmodule]); - init(config); - config.setConfig(getConfigMock(['id5Id', 'id5id', 'cookie', 10, 3600])); - - requestBidsHook(function() { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.id5id'); - expect(bid.userId.id5id).to.equal('testid5id'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'id5-sync.com', - uids: [{id: 'testid5id', atype: 1}] - }); - }); - }); - sinon.assert.calledOnce(utils.logError); - coreStorage.setCookie('id5id', '', EXPIRED_COOKIE_DATE); - utils.logError.restore(); - done(); - }, {adUnits}); - }); - - it('test hook from id5id value-based config', function(done) { - setSubmoduleRegistry([id5IdSubmodule]); - init(config); - config.setConfig(getConfigValueMock('id5Id', {'id5id': 'testid5id'})); - - requestBidsHook(function() { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.id5id'); - expect(bid.userId.id5id).to.equal('testid5id'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'id5-sync.com', - uids: [{id: 'testid5id', atype: 1}] - }); - }); - }); - done(); - }, {adUnits}); - }); it('test hook from liveIntentId html5', function(done) { // simulate existing browser local storage values @@ -1126,7 +1078,7 @@ describe('User ID', function() { it('test hook when pubCommonId, unifiedId, id5Id, identityLink, britepoolId, netId and sharedId have data to pass', function(done) { coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('unifiedid', JSON.stringify({'TDID': 'testunifiedid'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('id5id', JSON.stringify({'ID5ID': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); + coreStorage.setCookie('id5id', JSON.stringify({'universal_uid': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('idl_env', 'AiGNC8Z5ONyZKSpIPf', (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), (new Date(Date.now() + 5000).toUTCString())); @@ -1203,7 +1155,7 @@ describe('User ID', function() { it('test hook when pubCommonId, unifiedId, id5Id, britepoolId, netId and sharedId have their modules added before and after init', function(done) { coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('unifiedid', JSON.stringify({'TDID': 'cookie-value-add-module-variations'}), new Date(Date.now() + 5000).toUTCString()); - coreStorage.setCookie('id5id', JSON.stringify({'ID5ID': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); + coreStorage.setCookie('id5id', JSON.stringify({'universal_uid': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('idl_env', 'AiGNC8Z5ONyZKSpIPf', new Date(Date.now() + 5000).toUTCString()); coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), (new Date(Date.now() + 5000).toUTCString())); @@ -1296,7 +1248,7 @@ describe('User ID', function() { it('should add new id system ', function(done) { coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('unifiedid', JSON.stringify({'TDID': 'cookie-value-add-module-variations'}), new Date(Date.now() + 5000).toUTCString()); - coreStorage.setCookie('id5id', JSON.stringify({'ID5ID': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); + coreStorage.setCookie('id5id', JSON.stringify({'universal_uid': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('idl_env', 'AiGNC8Z5ONyZKSpIPf', new Date(Date.now() + 5000).toUTCString()); coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), new Date(Date.now() + 5000).toUTCString()); From c9bcc958c082f7ea74289b0e93c6d64b697e2550 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal <7393273+jaiminpanchal27@users.noreply.github.com> Date: Tue, 30 Jun 2020 11:24:03 -0400 Subject: [PATCH 452/496] Add tradedesk user id to appnexus adapter (#5346) * Add tradedesk id support * Updating appnexus payload for criteo Co-authored-by: Jaimin Panchal --- modules/appnexusBidAdapter.js | 22 ++++++++++--- test/spec/modules/appnexusBidAdapter_spec.js | 34 +++++++++++++------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index d853ca184ce..d489f55bd7e 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -207,14 +207,26 @@ export const spec = { }); } + let eids = []; const criteoId = utils.deepAccess(bidRequests[0], `userId.criteoId`); if (criteoId) { - let tpuids = []; - tpuids.push({ - 'provider': 'criteo', - 'user_id': criteoId + eids.push({ + source: 'criteo.com', + id: criteoId }); - payload.tpuids = tpuids; + } + + const tdid = utils.deepAccess(bidRequests[0], `userId.tdid`); + if (tdid) { + eids.push({ + source: 'adserver.org', + id: tdid, + rti_partner: 'TDID' + }); + } + + if (eids.length) { + payload.eids = eids; } if (tags[0].publisher_id) { diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js index a0ed6af6b89..7e985045c45 100644 --- a/test/spec/modules/appnexusBidAdapter_spec.js +++ b/test/spec/modules/appnexusBidAdapter_spec.js @@ -738,18 +738,6 @@ describe('AppNexusAdapter', function () { }); }); - it('should populate tpids array when userId is available', function () { - const bidRequest = Object.assign({}, bidRequests[0], { - userId: { - criteoId: 'sample-userid' - } - }); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - expect(payload.tpuids).to.deep.equal([{provider: 'criteo', user_id: 'sample-userid'}]); - }); - it('should populate schain if available', function () { const bidRequest = Object.assign({}, bidRequests[0], { schain: { @@ -819,6 +807,28 @@ describe('AppNexusAdapter', function () { const request = spec.buildRequests(bidRequests, bidderRequest); expect(request.options).to.deep.equal({withCredentials: false}); }); + + it('should populate eids array when ttd id and criteo is available', function () { + const bidRequest = Object.assign({}, bidRequests[0], { + userId: { + tdid: 'sample-userid', + criteoId: 'sample-criteo-userid' + } + }); + + const request = spec.buildRequests([bidRequest]); + const payload = JSON.parse(request.data); + expect(payload.eids).to.deep.include({ + source: 'adserver.org', + id: 'sample-userid', + rti_partner: 'TDID' + }); + + expect(payload.eids).to.deep.include({ + source: 'criteo.com', + id: 'sample-criteo-userid', + }); + }); }) describe('interpretResponse', function () { From 4121e1aa04ff748b9bb59cbad4e3aa173dd8dddd Mon Sep 17 00:00:00 2001 From: invibes <51820283+invibes@users.noreply.github.com> Date: Wed, 1 Jul 2020 12:58:20 +0300 Subject: [PATCH 453/496] Add TCF2 Support for Invibes (#5378) * added tcf 2.0 * Updated adapter to support gdprEnforcement * reverted storage manager initialization Co-authored-by: florin_nedelcu_invibes --- modules/invibesBidAdapter.js | 65 ++- test/spec/modules/invibesBidAdapter_spec.js | 435 ++++++++++++++++++-- 2 files changed, 453 insertions(+), 47 deletions(-) diff --git a/modules/invibesBidAdapter.js b/modules/invibesBidAdapter.js index e839c173a93..220aed47e15 100644 --- a/modules/invibesBidAdapter.js +++ b/modules/invibesBidAdapter.js @@ -1,7 +1,6 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { getStorageManager } from '../src/storageManager.js'; -const storage = getStorageManager(); const CONSTANTS = { BIDDER_CODE: 'invibes', @@ -14,8 +13,11 @@ const CONSTANTS = { INVIBES_VENDOR_ID: 436 }; +const storage = getStorageManager(CONSTANTS.INVIBES_VENDOR_ID); + export const spec = { code: CONSTANTS.BIDDER_CODE, + gvlid: CONSTANTS.INVIBES_VENDOR_ID, /** * @param {object} bid * @return boolean @@ -364,13 +366,70 @@ function acceptPostMessage(e) { } function readGdprConsent(gdprConsent) { - if (gdprConsent && gdprConsent.vendorData && gdprConsent.vendorData.vendorConsents) { - return !!gdprConsent.vendorData.vendorConsents[CONSTANTS.INVIBES_VENDOR_ID.toString(10)] === true ? 2 : -2; + if (gdprConsent && gdprConsent.vendorData) { + if (!gdprConsent.vendorData.gdprApplies || gdprConsent.vendorData.hasGlobalConsent) { + return 2; + } + + let purposeConsents = getPurposeConsents(gdprConsent.vendorData); + + if (purposeConsents == null) { return 0; } + let properties = Object.keys(purposeConsents); + let purposeConsentsCounter = getPurposeConsentsCounter(gdprConsent.vendorData); + + if (properties.length < purposeConsentsCounter) { + return 0; + } + + for (let i = 0; i < purposeConsentsCounter; i++) { + if (!purposeConsents[properties[i]] || purposeConsents[properties[i]] === 'false') { return 0; } + } + + let vendorConsents = getVendorConsents(gdprConsent.vendorData); + if (vendorConsents == null || vendorConsents[CONSTANTS.INVIBES_VENDOR_ID.toString(10)] == null) { + return 4; + } + + if (vendorConsents[CONSTANTS.INVIBES_VENDOR_ID.toString(10)] === false) { return 0; } + + return 2; } return 0; } +function getPurposeConsentsCounter(vendorData) { + if (vendorData.purpose && vendorData.purpose.consents) { + return 10; + } + + return 5; +} + +function getPurposeConsents(vendorData) { + if (vendorData.purpose && vendorData.purpose.consents) { + return vendorData.purpose.consents; + } + + if (vendorData.purposeConsents) { + return vendorData.purposeConsents; + } + + return null; +} + +function getVendorConsents(vendorData) { + if (vendorData.vendor && vendorData.vendor.consents) { + return vendorData.vendor.consents; + } + + if (vendorData.vendorConsents) { + return vendorData.vendorConsents; + } + + return null; +} + const ivLogger = initLogger(); /// Local domain cookie management ===================== diff --git a/test/spec/modules/invibesBidAdapter_spec.js b/test/spec/modules/invibesBidAdapter_spec.js index d21405a8b9d..b75c6a4578f 100644 --- a/test/spec/modules/invibesBidAdapter_spec.js +++ b/test/spec/modules/invibesBidAdapter_spec.js @@ -1,5 +1,5 @@ -import { expect } from 'chai'; -import { spec, resetInvibes, stubDomainOptions } from 'modules/invibesBidAdapter.js'; +import {expect} from 'chai'; +import {spec, resetInvibes, stubDomainOptions, readGdprConsent} from 'modules/invibesBidAdapter.js'; describe('invibesBidAdapter:', function () { const BIDDER_CODE = 'invibes'; @@ -40,14 +40,15 @@ describe('invibesBidAdapter:', function () { } ]; - let StubbedPersistence = function(initialValue) { + let StubbedPersistence = function (initialValue) { var value = initialValue; return { load: function () { let str = value || ''; try { return JSON.parse(str); - } catch (e) { } + } catch (e) { + } }, save: function (obj) { value = JSON.stringify(obj); @@ -67,7 +68,7 @@ describe('invibesBidAdapter:', function () { describe('isBidRequestValid:', function () { context('valid bid request:', function () { - it('returns true when bidder params.placementId is set', function() { + it('returns true when bidder params.placementId is set', function () { const validBid = { bidder: BIDDER_CODE, params: { @@ -88,7 +89,7 @@ describe('invibesBidAdapter:', function () { expect(spec.isBidRequestValid(invalidBid)).to.be.false; }); - it('returns false when placementId is not set', function() { + it('returns false when placementId is not set', function () { const invalidBid = { bidder: BIDDER_CODE, params: { @@ -99,7 +100,7 @@ describe('invibesBidAdapter:', function () { expect(spec.isBidRequestValid(invalidBid)).to.be.false; }); - it('returns false when bid response was previously received', function() { + it('returns false when bid response was previously received', function () { const validBid = { bidder: BIDDER_CODE, params: { @@ -107,7 +108,7 @@ describe('invibesBidAdapter:', function () { } } - top.window.invibes.bidResponse = { prop: 'prop' }; + top.window.invibes.bidResponse = {prop: 'prop'}; expect(spec.isBidRequestValid(validBid)).to.be.false; }); }); @@ -126,7 +127,7 @@ describe('invibesBidAdapter:', function () { }); it('has location, html id, placement and width/height', function () { - const request = spec.buildRequests(bidRequests, { auctionStart: Date.now() }); + const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); const parsedData = request.data; expect(parsedData.location).to.exist; expect(parsedData.videoAdHtmlId).to.exist; @@ -137,37 +138,37 @@ describe('invibesBidAdapter:', function () { it('has capped ids if local storage variable is correctly formatted', function () { localStorage.ivvcap = '{"9731":[1,1768600800000]}'; - const request = spec.buildRequests(bidRequests, { auctionStart: Date.now() }); + const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); expect(request.data.capCounts).to.equal('9731=1'); }); it('does not have capped ids if local storage variable is incorrectly formatted', function () { localStorage.ivvcap = ':[1,1574334216992]}'; - const request = spec.buildRequests(bidRequests, { auctionStart: Date.now() }); + const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); expect(request.data.capCounts).to.equal(''); }); it('does not have capped ids if local storage variable is expired', function () { localStorage.ivvcap = '{"9731":[1,1574330064104]}'; - const request = spec.buildRequests(bidRequests, { auctionStart: Date.now() }); + const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); expect(request.data.capCounts).to.equal(''); }); it('sends query string params from localstorage 1', function () { - localStorage.ivbs = JSON.stringify({ bvci: 1 }); - const request = spec.buildRequests(bidRequests, { auctionStart: Date.now() }); + localStorage.ivbs = JSON.stringify({bvci: 1}); + const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); expect(request.data.bvci).to.equal(1); }); it('sends query string params from localstorage 2', function () { - localStorage.ivbs = JSON.stringify({ invibbvlog: true }); - const request = spec.buildRequests(bidRequests, { auctionStart: Date.now() }); + localStorage.ivbs = JSON.stringify({invibbvlog: true}); + const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); expect(request.data.invibbvlog).to.equal(true); }); it('does not send query string params from localstorage if unknwon', function () { - localStorage.ivbs = JSON.stringify({ someparam: true }); - const request = spec.buildRequests(bidRequests, { auctionStart: Date.now() }); + localStorage.ivbs = JSON.stringify({someparam: true}); + const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); expect(request.data.someparam).to.be.undefined; }); @@ -191,65 +192,401 @@ describe('invibesBidAdapter:', function () { it('try to graduate but not enough count - doesnt send the domain id', function () { global.document.cookie = 'ivbsdid={"id":"dvdjkams6nkq","cr":1521818537626,"hc":0}'; - let bidderRequest = { gdprConsent: { vendorData: { vendorConsents: { 436: true } } } }; + let bidderRequest = {gdprConsent: {vendorData: {vendorConsents: {436: true}}}}; let request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.lId).to.not.exist; }); it('try to graduate but not old enough - doesnt send the domain id', function () { - let bidderRequest = { gdprConsent: { vendorData: { vendorConsents: { 436: true } } } }; + let bidderRequest = {gdprConsent: {vendorData: {vendorConsents: {436: true}}}}; global.document.cookie = 'ivbsdid={"id":"dvdjkams6nkq","cr":' + Date.now() + ',"hc":5}'; let request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.lId).to.not.exist; }); it('graduate and send the domain id', function () { - let bidderRequest = { gdprConsent: { vendorData: { vendorConsents: { 436: true } } } }; - stubDomainOptions(new StubbedPersistence('{"id":"dvdjkams6nkq","cr":1521818537626,"hc":7}')); + let bidderRequest = {gdprConsent: {vendorData: {vendorConsents: {436: true}}}}; + stubDomainOptions(new StubbedPersistence('{"id":"dvdjkams6nkq","cr":1521818537626,"hc":7}')); let request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.lId).to.exist; }); it('send the domain id if already graduated', function () { - let bidderRequest = { gdprConsent: { vendorData: { vendorConsents: { 436: true } } } }; - stubDomainOptions(new StubbedPersistence('{"id":"f8zoh044p9oi"}')); + let bidderRequest = {gdprConsent: {vendorData: {vendorConsents: {436: true}}}}; + stubDomainOptions(new StubbedPersistence('{"id":"f8zoh044p9oi"}')); let request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.lId).to.exist; expect(top.window.invibes.dom.tempId).to.exist; }); it('send the domain id after replacing it with new format', function () { - let bidderRequest = { gdprConsent: { vendorData: { vendorConsents: { 436: true } } } }; - stubDomainOptions(new StubbedPersistence('{"id":"f8zoh044p9oi.8537626"}')); + let bidderRequest = {gdprConsent: {vendorData: {vendorConsents: {436: true}}}}; + stubDomainOptions(new StubbedPersistence('{"id":"f8zoh044p9oi.8537626"}')); let request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.lId).to.exist; expect(top.window.invibes.dom.tempId).to.exist; }); - it('dont send the domain id if consent declined', function () { - let bidderRequest = { gdprConsent: { vendorData: { vendorConsents: { 436: false } } } }; + it('dont send the domain id if consent declined on tcf v1', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendorConsents: {436: false} + } + } + }; + stubDomainOptions(new StubbedPersistence('{"id":"f8zoh044p9oi.8537626"}')); + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.lId).to.not.exist; + expect(top.window.invibes.dom.tempId).to.not.exist; + expect(request.data.oi).to.equal(0); + }); + + it('dont send the domain id if consent declined on tcf v2', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendor: {consents: {436: false}} + } + } + }; stubDomainOptions(new StubbedPersistence('{"id":"f8zoh044p9oi.8537626"}')); let request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.lId).to.not.exist; expect(top.window.invibes.dom.tempId).to.not.exist; + expect(request.data.oi).to.equal(0); }); it('dont send the domain id if no consent', function () { - let bidderRequest = { }; - stubDomainOptions(new StubbedPersistence('{"id":"f8zoh044p9oi.8537626"}')); + let bidderRequest = {}; + stubDomainOptions(new StubbedPersistence('{"id":"f8zoh044p9oi.8537626"}')); let request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.lId).to.not.exist; expect(top.window.invibes.dom.tempId).to.not.exist; }); it('try to init id but was already loaded on page - does not increment the id again', function () { - let bidderRequest = { gdprConsent: { vendorData: { vendorConsents: { 436: true } } } }; + let bidderRequest = {gdprConsent: {vendorData: {vendorConsents: {436: true}}}}; global.document.cookie = 'ivbsdid={"id":"dvdjkams6nkq","cr":1521818537626,"hc":0}'; let request = spec.buildRequests(bidRequests, bidderRequest); request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.lId).to.not.exist; expect(top.window.invibes.dom.tempId).to.exist; }); + + it('should send oi = 0 when vendorData is null', function () { + let bidderRequest = { + gdprConsent: { + vendorData: null + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(0); + }); + + it('should send oi = 2 when consent was approved on tcf v2', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendor: {consents: {436: true}}, + purpose: { + consents: { + 1: true, + 2: true, + 3: true, + 4: true, + 5: true, + 6: true, + 7: true, + 8: true, + 9: true, + 10: true + } + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(2); + }); + + it('should send oi = 0 when vendor consents for invibes are false on tcf v2', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendor: {consents: {436: false}}, + purpose: { + consents: { + 1: true, + 2: true, + 3: true, + 4: true, + 5: true, + 6: true, + 7: true, + 8: true, + 9: true, + 10: true + } + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(0); + }); + + it('should send oi = 0 when purpose consents weren\'t approved on tcf v2', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendor: {consents: {436: true}}, + purpose: { + consents: { + 1: true, + 2: false, + 3: false, + 4: true, + 5: true, + 6: true, + 7: true, + 8: true, + 9: true, + 10: true + } + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(0); + }); + + it('should send oi = 0 when purpose consents are less then 10 on tcf v2', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendor: {consents: {436: true}}, + purpose: { + consents: { + 1: true, + 2: false, + 3: false, + 4: true, + 5: true + } + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(0); + }); + + it('should send oi = 4 when vendor consents are null on tcf v2', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendor: {consents: null}, + purpose: { + consents: { + 1: true, + 2: true, + 3: true, + 4: true, + 5: true, + 6: true, + 7: true, + 8: true, + 9: true, + 10: true + } + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(4); + }); + + it('should send oi = 4 when vendor consents for invibes is null on tcf v2', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendor: {consents: {436: null}}, + purpose: { + consents: { + 1: true, + 2: true, + 3: true, + 4: true, + 5: true, + 6: true, + 7: true, + 8: true, + 9: true, + 10: true + } + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(4); + }); + + it('should send oi = 4 when vendor consents for invibes is null on tcf v1', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendorConsents: {436: null}, + purposeConsents: { + 1: true, + 2: true, + 3: true, + 4: true, + 5: true + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(4); + }); + + it('should send oi = 4 when vendor consents consents are null on tcf v1', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendorConsents: null, + purposeConsents: { + 1: true, + 2: true, + 3: true, + 4: true, + 5: true + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(4); + }); + + it('should send oi = 2 when gdpr doesn\'t apply or has global consent', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: false, + hasGlobalConsent: true, + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(2); + }); + + it('should send oi = 2 when consent was approved on tcf v1', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendorConsents: {436: true}, + purposeConsents: { + 1: true, + 2: true, + 3: true, + 4: true, + 5: true + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(2); + }); + + it('should send oi = 0 when purpose consents weren\'t approved on tcf v1', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendorConsents: {436: true}, + purposeConsents: { + 1: false, + 2: false, + 3: true, + 4: true, + 5: true + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(0); + }); + + it('should send oi = 0 when purpose consents are less then 5 on tcf v1', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendorConsents: {436: true}, + purposeConsents: { + 1: false, + 2: false, + 3: true + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(0); + }); + + it('should send oi = 0 when vendor consents for invibes are false on tcf v1', function () { + let bidderRequest = { + gdprConsent: { + vendorData: { + gdprApplies: true, + hasGlobalConsent: false, + vendorConsents: {436: false}, + purposeConsents: { + 1: true, + 2: true, + 3: true, + 4: true, + 5: true + } + } + } + }; + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.oi).to.equal(0); + }); }); describe('interpretResponse', function () { @@ -285,37 +622,47 @@ describe('invibesBidAdapter:', function () { context('when the response is not valid', function () { it('handles response with no bids requested', function () { - let emptyResult = spec.interpretResponse({ body: response }); + let emptyResult = spec.interpretResponse({body: response}); expect(emptyResult).to.be.empty; }); it('handles empty response', function () { - let emptyResult = spec.interpretResponse(null, { bidRequests }); + let emptyResult = spec.interpretResponse(null, {bidRequests}); expect(emptyResult).to.be.empty; }); it('handles response with bidding is not configured', function () { - let emptyResult = spec.interpretResponse({ body: { Ads: [{ BidPrice: 1 }] } }, { bidRequests }); + let emptyResult = spec.interpretResponse({body: {Ads: [{BidPrice: 1}]}}, {bidRequests}); expect(emptyResult).to.be.empty; }); it('handles response with no ads are received', function () { - let emptyResult = spec.interpretResponse({ body: { BidModel: { PlacementId: '12345' }, AdReason: 'No ads' } }, { bidRequests }); + let emptyResult = spec.interpretResponse({ + body: { + BidModel: {PlacementId: '12345'}, + AdReason: 'No ads' + } + }, {bidRequests}); expect(emptyResult).to.be.empty; }); it('handles response with no ads are received - no ad reason', function () { - let emptyResult = spec.interpretResponse({ body: { BidModel: { PlacementId: '12345' } } }, { bidRequests }); + let emptyResult = spec.interpretResponse({body: {BidModel: {PlacementId: '12345'}}}, {bidRequests}); expect(emptyResult).to.be.empty; }); it('handles response when no placement Id matches', function () { - let emptyResult = spec.interpretResponse({ body: { BidModel: { PlacementId: '123456' }, Ads: [{ BidPrice: 1 }] } }, { bidRequests }); + let emptyResult = spec.interpretResponse({ + body: { + BidModel: {PlacementId: '123456'}, + Ads: [{BidPrice: 1}] + } + }, {bidRequests}); expect(emptyResult).to.be.empty; }); it('handles response when placement Id is not present', function () { - let emptyResult = spec.interpretResponse({ BidModel: { }, Ads: [{ BidPrice: 1 }] }, { bidRequests }); + let emptyResult = spec.interpretResponse({BidModel: {}, Ads: [{BidPrice: 1}]}, {bidRequests}); expect(emptyResult).to.be.empty; }); }); @@ -324,20 +671,20 @@ describe('invibesBidAdapter:', function () { it('responds with a valid bid', function () { top.window.invibes.setCookie('a', 'b', 370); top.window.invibes.setCookie('c', 'd', 0); - let result = spec.interpretResponse({ body: response }, { bidRequests }); + let result = spec.interpretResponse({body: response}, {bidRequests}); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); it('responds with a valid bid and uses logger', function () { localStorage.InvibesDEBUG = true; - let result = spec.interpretResponse({ body: response }, { bidRequests }); + let result = spec.interpretResponse({body: response}, {bidRequests}); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); it('does not make multiple bids', function () { localStorage.InvibesDEBUG = false; - let result = spec.interpretResponse({ body: response }, { bidRequests }); - let secondResult = spec.interpretResponse({ body: response }, { bidRequests }); + let result = spec.interpretResponse({body: response}, {bidRequests}); + let secondResult = spec.interpretResponse({body: response}, {bidRequests}); expect(secondResult).to.be.empty; }); }); @@ -353,7 +700,7 @@ describe('invibesBidAdapter:', function () { it('returns an iframe with params if enabled', function () { top.window.invibes.optIn = 1; global.document.cookie = 'ivvbks=17639.0,1,2'; - let response = spec.getUserSyncs({ iframeEnabled: true }); + let response = spec.getUserSyncs({iframeEnabled: true}); expect(response.type).to.equal('iframe'); expect(response.url).to.include(SYNC_ENDPOINT); expect(response.url).to.include('optIn'); @@ -362,7 +709,7 @@ describe('invibesBidAdapter:', function () { }); it('returns undefined if iframe not enabled ', function () { - let response = spec.getUserSyncs({ iframeEnabled: false }); + let response = spec.getUserSyncs({iframeEnabled: false}); expect(response).to.equal(undefined); }); }); From d8e5796827a46455185292e4a498628ecdb09bc6 Mon Sep 17 00:00:00 2001 From: Nick Jacob Date: Wed, 1 Jul 2020 17:06:56 -0400 Subject: [PATCH 454/496] add AMX adapter (#5383) --- modules/amxBidAdapter.js | 279 +++++++++++++++++ modules/amxBidAdapter.md | 37 +++ test/spec/modules/amxBidAdapter_spec.js | 390 ++++++++++++++++++++++++ 3 files changed, 706 insertions(+) create mode 100644 modules/amxBidAdapter.js create mode 100644 modules/amxBidAdapter.md create mode 100644 test/spec/modules/amxBidAdapter_spec.js diff --git a/modules/amxBidAdapter.js b/modules/amxBidAdapter.js new file mode 100644 index 00000000000..8d7e9682325 --- /dev/null +++ b/modules/amxBidAdapter.js @@ -0,0 +1,279 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { parseUrl, deepAccess, _each, formatQS, getUniqueIdentifierStr, triggerPixel } from '../src/utils.js'; + +const BIDDER_CODE = 'amx'; +const SIMPLE_TLD_TEST = /\.co\.\w{2,4}$/; +const DEFAULT_ENDPOINT = 'https://prebid.a-mo.net/a/c'; +const VERSION = 'pba1.0'; +const xmlDTDRxp = /^\s*<\?xml[^\?]+\?>/; +const VAST_RXP = /^\s*<\??(?:vast|xml)/i; +const TRACKING_ENDPOINT = 'https://1x1.a-mo.net/hbx/'; + +const getLocation = (request) => + parseUrl(deepAccess(request, 'refererInfo.canonicalUrl', location.href)) + +const largestSize = (sizes, mediaTypes) => { + const allSizes = sizes + .concat(deepAccess(mediaTypes, `${BANNER}.sizes`, []) || []) + .concat(deepAccess(mediaTypes, `${VIDEO}.sizes`, []) || []) + + return allSizes.sort((a, b) => (b[0] * b[1]) - (a[0] * a[1]))[0]; +} + +const generateDTD = (xmlDocument) => + ``; + +const isVideoADM = (html) => html != null && VAST_RXP.test(html); +const getMediaType = (bid) => isVideoADM(bid.adm) ? VIDEO : BANNER; +const nullOrType = (value, type) => + value == null || (typeof value) === type // eslint-disable-line valid-typeof + +function getID(loc) { + const host = loc.hostname.split('.'); + const short = host.slice( + host.length - (SIMPLE_TLD_TEST.test(loc.host) ? 3 : 2) + ).join('.'); + return btoa(short).replace(/=+$/, ''); +} + +const enc = encodeURIComponent; + +function nestedQs (qsData) { + const out = []; + Object.keys(qsData || {}).forEach((key) => { + out.push(enc(key) + '=' + enc(String(qsData[key]))); + }); + + return enc(out.join('&')); +} + +function createBidMap(bids) { + const out = {}; + for (const bid of bids) { + out[bid.bidId] = convertRequest(bid) + } + return out; +} + +const trackEvent = (eventName, data) => + triggerPixel(`${TRACKING_ENDPOINT}g_${eventName}?${formatQS({ + ...data, + ts: Date.now(), + eid: getUniqueIdentifierStr(), + })}`); + +function convertRequest(bid) { + const size = largestSize(bid.sizes, bid.mediaTypes) || [0, 0]; + const av = bid.mediaType === VIDEO || VIDEO in bid.mediaTypes; + const tid = deepAccess(bid, 'params.tagId') + + const params = { + av, + aw: size[0], + ah: size[1], + tf: 0, + }; + + if (typeof tid === 'string' && tid.length > 0) { + params.i = tid; + } + return params; +} + +function decorateADM(bid) { + const impressions = deepAccess(bid, 'ext.himp', []) + .concat(bid.nurl != null ? [bid.nurl] : []) + .filter((imp) => imp != null && imp.length > 0) + .map((src) => ``) + .join(''); + return bid.adm + impressions; +} + +function decorateVideoADM(bid) { + const doc = new DOMParser().parseFromString(bid.adm, 'text/xml'); + if (doc.querySelector('parsererror') != null) { + return null; + } + + const root = doc.querySelector('InLine,Wrapper') + if (root == null) { + return null; + } + + const pixels = [bid.nurl].concat(bid.ext.himp || []) + .filter((url) => url != null); + + _each(pixels, (pxl) => { + const imagePixel = doc.createElement('Impression'); + const cdata = doc.createCDATASection(pxl); + imagePixel.appendChild(cdata); + root.appendChild(imagePixel); + }); + + const dtdMatch = xmlDTDRxp.exec(bid.adm); + return (dtdMatch != null ? dtdMatch[0] : generateDTD(doc)) + doc.documentElement.outerHTML; +} + +function resolveSize(bid, request, bidId) { + if (bid.w != null && bid.w > 1 && bid.h != null && bid.h > 1) { + return [bid.w, bid.h]; + } + + const bidRequest = request.m[bidId]; + if (bidRequest == null) { + return [0, 0]; + } + + return [bidRequest.aw, bidRequest.ah]; +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], + + isBidRequestValid(bid) { + return nullOrType(deepAccess(bid, 'params.endpoint', null), 'string') && + nullOrType(deepAccess(bid, 'params.tagId', null), 'string') && + nullOrType(deepAccess(bid, 'params.testMode', null), 'boolean'); + }, + + buildRequests(bidRequests, bidderRequest) { + const loc = getLocation(bidderRequest); + const tagId = deepAccess(bidRequests[0], 'params.tagId', null); + const testMode = deepAccess(bidRequests[0], 'params.testMode', 0); + + const payload = { + a: bidderRequest.auctionId, + B: 0, + b: loc.host, + tm: testMode, + V: '$prebid.version$', + i: (testMode && tagId != null) ? tagId : getID(loc), + l: {}, + f: 0.01, + cv: VERSION, + st: 'prebid', + h: screen.height, + w: screen.width, + gs: deepAccess(bidderRequest, 'gdprConsent.gdprApplies', '0'), + gc: deepAccess(bidderRequest, 'gdprConsent.consentString', ''), + u: deepAccess(bidderRequest, 'refererInfo.canonicalUrl', loc.href), + do: loc.host, + re: deepAccess(bidderRequest, 'refererInfo.referer'), + usp: bidderRequest.uspConsent || '1---', + smt: 9, + d: '', + m: createBidMap(bidRequests), + }; + + return { + data: payload, + method: 'POST', + url: deepAccess(bidRequests[0], 'params.endpoint', DEFAULT_ENDPOINT), + withCredentials: true, + }; + }, + + getUserSyncs(syncOptions, serverResponses) { + return (serverResponses || []) + .flatMap(({ body: response }) => + response != null && response.p != null ? (response.p.hreq || []) : []) + .map((syncPixel) => + ({ + type: syncPixel.indexOf('__st=iframe') !== -1 ? 'iframe' : 'image', + url: syncPixel + }) + ).filter(({ + type + }) => syncOptions.iframeEnabled || type === 'image') + }, + + interpretResponse(serverResponse, request) { + // validate the body/response + const response = serverResponse.body; + if (response == null || typeof response === 'string') { + return []; + } + + return Object.keys(response.r).flatMap((bidID) => { + const biddata = response.r[bidID]; + return biddata.flatMap((siteBid) => + siteBid.b.map((bid) => { + const mediaType = getMediaType(bid); + const ad = mediaType === BANNER ? decorateADM(bid) : decorateVideoADM(bid); + if (ad == null) { + return null; + } + + const size = resolveSize(bid, request.data, bidID); + + return ({ + requestId: bidID, + cpm: bid.price, + width: size[0], + height: size[1], + creativeId: bid.crid, + currency: 'USD', + netRevenue: true, + [mediaType === VIDEO ? 'vastXml' : 'ad']: ad, + meta: { + advertiserDomains: bid.adomain, + mediaType, + }, + ttl: mediaType === VIDEO ? 90 : 70 + }); + })).filter((possibleBid) => possibleBid != null); + }); + }, + + onSetTargeting(targetingData) { + if (targetingData == null) { + return; + } + + trackEvent('pbst', { + A: targetingData.bidder, + w: targetingData.width, + h: targetingData.height, + bid: targetingData.adId, + c1: targetingData.mediaType, + np: targetingData.cpm, + aud: targetingData.requestId, + a: targetingData.adUnitCode, + c2: nestedQs(targetingData.adserverTargeting), + }); + }, + + onTimeout(timeoutData) { + if (timeoutData == null) { + return; + } + + trackEvent('pbto', { + A: timeoutData.bidder, + bid: timeoutData.bidId, + a: timeoutData.adUnitCode, + cn: timeoutData.timeout, + aud: timeoutData.auctionId, + }); + }, + + onBidWon(bidWinData) { + if (bidWinData == null) { + return; + } + + trackEvent('pbwin', { + A: bidWinData.bidder, + w: bidWinData.width, + h: bidWinData.height, + bid: bidWinData.adId, + C: bidWinData.mediaType === BANNER ? 0 : 1, + np: bidWinData.cpm, + a: bidWinData.adUnitCode, + }); + }, +}; + +registerBidder(spec); diff --git a/modules/amxBidAdapter.md b/modules/amxBidAdapter.md new file mode 100644 index 00000000000..c06c2e7157c --- /dev/null +++ b/modules/amxBidAdapter.md @@ -0,0 +1,37 @@ +Overview +======== + +``` +Module Name: AMX Adapter +Module Type: Bidder Adapter +Maintainer: prebid.support@amxrtb.com +``` + +Description +=========== + +This module connects web publishers to AMX RTB video and display demand. + +# Bid Parameters + +| Key | Required | Example | Description | +| --- | -------- | ------- | ----------- | +| `endpoint` | **yes** | `https://prebid.a-mo.net/a/c` | The url including https:// and any path | +| `testMode` | no | `true` | this will activate test mode / 100% fill with sample ads | +| `tagId` | no | `"eh3hffb"` | can be used for more specific targeting of inventory. Your account manager will provide this ID if needed | + +# Test Parameters + +``` +var adUnits = [{ + code: 'test-div', + sizes: [[300, 250]], + bids: [{ + bidder: 'amx', + params: { + testMode: true, + endpoint: 'https://prebid.a-mo.net/a/c', + }, + }] +}] +``` diff --git a/test/spec/modules/amxBidAdapter_spec.js b/test/spec/modules/amxBidAdapter_spec.js new file mode 100644 index 00000000000..e19de368361 --- /dev/null +++ b/test/spec/modules/amxBidAdapter_spec.js @@ -0,0 +1,390 @@ +import * as utils from 'src/utils.js'; +import { config } from 'src/config.js'; +import { expect } from 'chai'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { spec } from 'modules/amxBidAdapter.js'; +import { BANNER, VIDEO } from 'src/mediaTypes'; +import { formatQS } from 'src/utils'; + +const sampleRequestId = '82c91e127a9b93e'; +const sampleDisplayAd = (additionalImpressions) => `${additionalImpressions}`; +const sampleDisplayCRID = '78827819'; +// minimal example vast +const sampleVideoAd = (addlImpression) => ` +00:00:15${addlImpression} +`.replace(/\n+/g, '') + +const embeddedTrackingPixel = `https://1x1.a-mo.net/hbx/g_impression?A=sample&B=20903`; +const sampleNurl = 'https://example.exchange/nurl'; + +const sampleBidderRequest = { + gdprConsent: { + gdprApplies: true, + consentString: utils.getUniqueIdentifierStr(), + vendorData: {} + }, + auctionId: utils.getUniqueIdentifierStr(), + uspConsent: '1YYY', + refererInfo: { + referer: 'https://www.prebid.org', + canonicalUrl: 'https://www.prebid.org/the/link/to/the/page' + } +}; + +const sampleBidRequestBase = { + bidder: spec.code, + params: { + endpoint: 'https://httpbin.org/post', + }, + sizes: [[320, 50]], + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + adUnitCode: 'div-gpt-ad-example', + transactionId: utils.getUniqueIdentifierStr(), + bidId: sampleRequestId, + auctionId: utils.getUniqueIdentifierStr(), +}; + +const sampleBidRequestVideo = { + ...sampleBidRequestBase, + bidId: sampleRequestId + '_video', + sizes: [[300, 150]], + mediaTypes: { + [VIDEO]: { + sizes: [[360, 250]] + } + } +}; + +const sampleServerResponse = { + 'p': { + 'hreq': ['https://1x1.a-mo.net/hbx/g_sync?partner=test', 'https://1x1.a-mo.net/hbx/g_syncf?__st=iframe'] + }, + 'r': { + [sampleRequestId]: [ + { + 'b': [ + { + 'adid': '78827819', + 'adm': sampleDisplayAd(''), + 'adomain': [ + 'example.com' + ], + 'crid': sampleDisplayCRID, + 'ext': { + 'himp': [ + embeddedTrackingPixel + ], + }, + 'nurl': sampleNurl, + 'h': 600, + 'id': '2014691335735134254', + 'impid': '1', + 'price': 0.25, + 'w': 300 + }, + { + 'adid': '222976952', + 'adm': sampleVideoAd(''), + 'adomain': [ + 'example.com' + ], + 'crid': sampleDisplayCRID, + 'ext': { + 'himp': [ + embeddedTrackingPixel + ], + }, + 'nurl': sampleNurl, + 'h': 1, + 'id': '7735706981389902829', + 'impid': '1', + 'price': 0.25, + 'w': 1 + }, + ], + } + ] + }, +} + +describe('AmxBidAdapter', () => { + describe('isBidRequestValid', () => { + it('endpoint must be an optional string', () => { + expect(spec.isBidRequestValid({params: { endpoint: 1 }})).to.equal(false) + expect(spec.isBidRequestValid({params: { endpoint: 'test' }})).to.equal(true) + }); + + it('tagId is an optional string', () => { + expect(spec.isBidRequestValid({params: { tagId: 1 }})).to.equal(false) + expect(spec.isBidRequestValid({params: { tagId: 'test' }})).to.equal(true) + }); + + it('testMode is an optional boolean', () => { + expect(spec.isBidRequestValid({params: { testMode: 1 }})).to.equal(false) + expect(spec.isBidRequestValid({params: { testMode: false }})).to.equal(true) + }); + + it('none of the params are required', () => { + expect(spec.isBidRequestValid({})).to.equal(true) + }); + }) + describe('getUserSync', () => { + it('will only sync from valid server responses', () => { + const syncs = spec.getUserSyncs({ iframeEnabled: true }); + expect(syncs).to.eql([]); + }); + + it('will return valid syncs from a server response', () => { + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [{body: sampleServerResponse}]); + expect(syncs.length).to.equal(2); + expect(syncs[0].type).to.equal('image'); + expect(syncs[1].type).to.equal('iframe'); + }); + + it('will filter out iframe syncs based on options', () => { + const syncs = spec.getUserSyncs({ iframeEnabled: false }, [{body: sampleServerResponse}, {body: sampleServerResponse}]); + expect(syncs.length).to.equal(2); + expect(syncs).to.satisfy((allSyncs) => allSyncs.every((sync) => sync.type === 'image')) + }); + }); + + describe('buildRequests', () => { + it('will default to prebid.a-mo.net endpoint', () => { + const { url } = spec.buildRequests([], sampleBidderRequest); + expect(url).to.equal('https://prebid.a-mo.net/a/c') + }); + + it('reads test mode from the first bid request', () => { + const { data } = spec.buildRequests([{ + ...sampleBidRequestBase, + params: { + testMode: true + } + }], sampleBidderRequest); + expect(data.tm).to.equal(true); + }); + + it('handles referer data and GDPR, USP Consent', () => { + const { data } = spec.buildRequests([sampleBidRequestBase], sampleBidderRequest); + delete data.m; // don't deal with "m" in this test + + expect(data).to.deep.equal({ + a: sampleBidderRequest.auctionId, + B: 0, + b: 'www.prebid.org', + tm: 0, + V: '$prebid.version$', + i: btoa('prebid.org').replace(/=+$/, ''), + l: {}, + f: 0.01, + cv: 'pba1.0', + st: 'prebid', + h: screen.height, + w: screen.width, + gs: sampleBidderRequest.gdprConsent.gdprApplies, + gc: sampleBidderRequest.gdprConsent.consentString, + u: sampleBidderRequest.refererInfo.canonicalUrl, + do: 'www.prebid.org', + re: sampleBidderRequest.refererInfo.referer, + usp: sampleBidderRequest.uspConsent, + smt: 9, + d: '', + }) + }); + + it('can build a banner request', () => { + const { method, url, data } = spec.buildRequests([sampleBidRequestBase, { + ...sampleBidRequestBase, + bidId: sampleRequestId + '_2', + params: { + ...sampleBidRequestBase.params, + tagId: 'example' + } + }], sampleBidderRequest) + + expect(url).to.equal(sampleBidRequestBase.params.endpoint) + expect(method).to.equal('POST'); + expect(Object.keys(data.m).length).to.equal(2); + expect(data.m[sampleRequestId]).to.deep.equal({ + av: false, + aw: 300, + ah: 250, + tf: 0 + }); + expect(data.m[sampleRequestId + '_2']).to.deep.equal({ + av: false, + aw: 300, + i: 'example', + ah: 250, + tf: 0 + }); + }); + + it('can build a video request', () => { + const { data } = spec.buildRequests([sampleBidRequestVideo], sampleBidderRequest); + expect(Object.keys(data.m).length).to.equal(1); + expect(data.m[sampleRequestId + '_video']).to.deep.equal({ + av: true, + aw: 360, + ah: 250, + tf: 0 + }); + }); + }); + + describe('interpretResponse', () => { + const baseBidResponse = { + requestId: sampleRequestId, + cpm: 0.25, + creativeId: sampleDisplayCRID, + currency: 'USD', + netRevenue: true, + meta: { + advertiserDomains: ['example.com'], + }, + }; + + const baseRequest = { + data: { + m: { + [sampleRequestId]: { + aw: 300, + ah: 250, + }, + } + } + }; + + it('will handle a nobid response', () => { + const parsed = spec.interpretResponse({ body: '' }, baseRequest) + expect(parsed).to.eql([]) + }); + + it('can parse a display ad', () => { + const parsed = spec.interpretResponse({ body: sampleServerResponse }, baseRequest) + expect(parsed.length).to.equal(2) + + // we should have display, video, display + expect(parsed[0]).to.deep.equal({ + ...baseBidResponse, + meta: { + ...baseBidResponse.meta, + mediaType: BANNER, + }, + width: 300, + height: 600, // from the bid itself + ttl: 70, + ad: sampleDisplayAd( + `` + + `` + ), + }); + }); + + it('can parse a video ad', () => { + const parsed = spec.interpretResponse({ body: sampleServerResponse }, baseRequest) + expect(parsed.length).to.equal(2) + + // we should have display, video, display + expect(parsed[1]).to.deep.equal({ + ...baseBidResponse, + meta: { + ...baseBidResponse.meta, + mediaType: VIDEO, + }, + width: 300, + height: 250, + ttl: 90, + vastXml: sampleVideoAd( + `` + + `` + ), + }); + }); + }); + + describe('analytics methods', () => { + let firedPixels = []; + let _Image = window.Image; + before(() => { + _Image = window.Image; + window.Image = class FakeImage { + set src(value) { + firedPixels.push(value) + } + } + }); + + beforeEach(() => { + firedPixels = []; + }); + + after(() => { + window.Image = _Image; + }); + + it('will fire an event for onSetTargeting', () => { + spec.onSetTargeting({ + bidder: 'example', + width: 300, + height: 250, + adId: 'ad-id', + mediaType: BANNER, + cpm: 1.23, + requestId: utils.getUniqueIdentifierStr(), + adUnitCode: 'div-gpt-ad', + adserverTargeting: { + hb_pb: '1.23', + hb_adid: 'ad-id', + hb_bidder: 'example' + } + }); + expect(firedPixels.length).to.equal(1) + expect(firedPixels[0]).to.match(/\/hbx\/g_pbst/) + const parsed = new URL(firedPixels[0]); + const nestedData = parsed.searchParams.get('c2'); + expect(nestedData).to.equal(formatQS({ + hb_pb: '1.23', + hb_adid: 'ad-id', + hb_bidder: 'example' + })); + }); + + it('will log an event for timeout', () => { + spec.onTimeout({ + bidder: 'example', + bidId: 'test-bid-id', + adUnitCode: 'div-gpt-ad', + timeout: 300, + auctionId: utils.getUniqueIdentifierStr() + }); + expect(firedPixels.length).to.equal(1) + expect(firedPixels[0]).to.match(/\/hbx\/g_pbto/) + }); + + it('will log an event for prebid win', () => { + spec.onBidWon({ + bidder: 'example', + adId: 'test-ad-id', + width: 300, + height: 250, + mediaType: VIDEO, + cpm: 1.34, + adUnitCode: 'div-gpt-ad', + timeout: 300, + auctionId: utils.getUniqueIdentifierStr() + }); + expect(firedPixels.length).to.equal(1) + expect(firedPixels[0]).to.match(/\/hbx\/g_pbwin/) + + const pixel = firedPixels[0]; + const url = new URL(pixel); + expect(url.searchParams.get('C')).to.equal('1') + expect(url.searchParams.get('np')).to.equal('1.34') + }); + }); +}); From 8c87a9e90b0d810c81b5d4f5adf434be9b439003 Mon Sep 17 00:00:00 2001 From: hendrikiseke1979 <53309111+hendrikiseke1979@users.noreply.github.com> Date: Wed, 1 Jul 2020 23:29:01 +0200 Subject: [PATCH 455/496] remove onBidWon callback from adapter (#5414) * orbidder adapter: add withCredentials:true header to BidRequest and onBidWon Requests * add blank in order to trigger build again * remove blank to trigger build ... again * adding extra line to trigger build ... again * add prebid version to request * add unit test for version parameter * add version parameter to win requests * fix comment * trigger rebuild * trigger rebuild * remove onBidWon callback from adapter Co-authored-by: Volk, Rainer Co-authored-by: RainerVolk4014 <53347752+RainerVolk4014@users.noreply.github.com> Co-authored-by: siggi-otto <57615762+siggi-otto@users.noreply.github.com> Co-authored-by: Hendrik Iseke <39734979+hiseke@users.noreply.github.com> Co-authored-by: Hendrik Iseke Co-authored-by: rvolk <> --- modules/orbidderBidAdapter.js | 19 ----------- test/spec/modules/orbidderBidAdapter_spec.js | 34 -------------------- 2 files changed, 53 deletions(-) diff --git a/modules/orbidderBidAdapter.js b/modules/orbidderBidAdapter.js index d7ce5aa859a..d14e2bebd72 100644 --- a/modules/orbidderBidAdapter.js +++ b/modules/orbidderBidAdapter.js @@ -1,5 +1,3 @@ -import {detectReferer} from '../src/refererDetection.js'; -import {ajax} from '../src/ajax.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import { getStorageManager } from '../src/storageManager.js'; @@ -7,7 +5,6 @@ const storage = getStorageManager(); export const spec = { code: 'orbidder', - bidParams: {}, orbidderHost: (() => { let ret = 'https://orbidder.otto.de'; try { @@ -48,7 +45,6 @@ export const spec = { params: bidRequest.params } }; - spec.bidParams[bidRequest.bidId] = bidRequest.params; if (bidderRequest && bidderRequest.gdprConsent) { ret.data.gdprConsent = { consentString: bidderRequest.gdprConsent.consentString, @@ -76,21 +72,6 @@ export const spec = { } return bidResponses; }, - - onBidWon(bid) { - const getRefererInfo = detectReferer(window); - - bid.v = $$PREBID_GLOBAL$$.version; - bid.pageUrl = getRefererInfo().referer; - if (spec.bidParams[bid.requestId] && (typeof bid.params === 'undefined')) { - bid.params = [spec.bidParams[bid.requestId]]; - } - spec.ajaxCall(`${spec.orbidderHost}/win`, JSON.stringify(bid)); - }, - - ajaxCall(endpoint, data) { - ajax(endpoint, null, data, { withCredentials: true }); - } }; registerBidder(spec); diff --git a/test/spec/modules/orbidderBidAdapter_spec.js b/test/spec/modules/orbidderBidAdapter_spec.js index c20f11da5b5..eec6ccd19f6 100644 --- a/test/spec/modules/orbidderBidAdapter_spec.js +++ b/test/spec/modules/orbidderBidAdapter_spec.js @@ -153,40 +153,6 @@ describe('orbidderBidAdapter', () => { }); }); - describe('onCallbackHandler', () => { - let ajaxStub; - const bidObj = { - adId: 'testId', - test: 1, - pageUrl: 'www.someurl.de', - referrer: 'www.somereferrer.de', - requestId: '123req456' - }; - - spec.bidParams['123req456'] = {'accountId': '123acc456'}; - - let bidObjClone = deepClone(bidObj); - bidObjClone.v = $$PREBID_GLOBAL$$.version; - bidObjClone.pageUrl = detectReferer(window)().referer; - bidObjClone.params = [{'accountId': '123acc456'}]; - - beforeEach(() => { - ajaxStub = sinon.stub(spec, 'ajaxCall'); - }); - - afterEach(() => { - ajaxStub.restore(); - }); - - it('calls orbidder\'s callback endpoint', () => { - spec.onBidWon(bidObj); - expect(ajaxStub.calledOnce).to.equal(true); - expect(ajaxStub.firstCall.args[0].indexOf('https://')).to.equal(0); - expect(ajaxStub.firstCall.args[0]).to.equal(`${spec.orbidderHost}/win`); - expect(ajaxStub.firstCall.args[1]).to.equal(JSON.stringify(bidObjClone)); - }); - }); - describe('interpretResponse', () => { it('should get correct bid response', () => { const serverResponse = [ From af604da31fb9350f48576cbf2b5f77232a6ba932 Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Thu, 2 Jul 2020 19:23:06 -0400 Subject: [PATCH 456/496] Make default s2s ttl configurable (#5419) * make default s2s ttl configurable --- modules/prebidServerBidAdapter/index.js | 4 ++- .../modules/prebidServerBidAdapter_spec.js | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js index 96986ed185c..7536851f5e1 100644 --- a/modules/prebidServerBidAdapter/index.js +++ b/modules/prebidServerBidAdapter/index.js @@ -71,6 +71,7 @@ config.setDefaults({ * @property {string} endpoint endpoint to contact * === optional params below === * @property {number} [timeout] timeout for S2S bidders - should be lower than `pbjs.requestBids({timeout})` + * @property {number} [defaultTtl] ttl for S2S bidders when pbs does not return a ttl on the response - defaults to 60` * @property {boolean} [cacheMarkup] whether to cache the adm result * @property {string} [adapter] adapter code to use for S2S * @property {string} [syncEndpoint] endpoint URL for syncing cookies @@ -832,7 +833,8 @@ const OPEN_RTB_PROTOCOL = { bidObject.currency = (response.cur) ? response.cur : DEFAULT_S2S_CURRENCY; // TODO: Remove when prebid-server returns ttl and netRevenue - bidObject.ttl = (bid.ttl) ? bid.ttl : DEFAULT_S2S_TTL; + const configTtl = _s2sConfig.defaultTtl || DEFAULT_S2S_TTL; + bidObject.ttl = (bid.ttl) ? bid.ttl : configTtl; bidObject.netRevenue = (bid.netRevenue) ? bid.netRevenue : DEFAULT_S2S_NETREVENUE; bids.push({ adUnit: bid.impid, bid: bidObject }); diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index b4544a2ec48..d99ec9d421d 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -1702,6 +1702,24 @@ describe('S2S Adapter', function () { expect(response).to.have.property('cpm', 0.5); expect(response).to.not.have.property('vastUrl'); expect(response).to.not.have.property('videoCacheKey'); + expect(response).to.have.property('ttl', 60); + }); + + it('respects defaultTtl', function () { + const s2sConfig = Object.assign({}, CONFIG, { + endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', + defaultTtl: 30 + }); + config.setConfig({ s2sConfig }); + + adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); + server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); + + sinon.assert.calledOnce(events.emit); + const event = events.emit.firstCall.args; + sinon.assert.calledOnce(addBidResponse); + const response = addBidResponse.firstCall.args[1]; + expect(response).to.have.property('ttl', 30); }); it('handles OpenRTB video responses', function () { @@ -2155,6 +2173,15 @@ describe('S2S Adapter', function () { }) }); + it('should set default s2s ttl', function () { + config.setConfig({ + s2sConfig: { + defaultTtl: 30 + } + }); + expect(config.getConfig('s2sConfig').defaultTtl).to.deep.equal(30); + }); + it('should set syncUrlModifier', function () { config.setConfig({ s2sConfig: { From 2b4fa39ca75293fa521e5ce06de79e19c0ecf51b Mon Sep 17 00:00:00 2001 From: AaronColbyPrice <67345931+AaronColbyPrice@users.noreply.github.com> Date: Thu, 2 Jul 2020 16:48:39 -0700 Subject: [PATCH 457/496] Conversant: update prebid url (#5441) * Updating Conversant bid adapter URL to new 'cvx' * Updating Conversant bid adapter URL to new 'cvx' - updating tests to match * Updating Conversant bid adapter URL to new 'cvx': rolling back package-lock.json to avoid conflict --- modules/conversantBidAdapter.js | 2 +- test/spec/modules/conversantBidAdapter_spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/conversantBidAdapter.js b/modules/conversantBidAdapter.js index 2ecdb2b7e98..3b3d04dc498 100644 --- a/modules/conversantBidAdapter.js +++ b/modules/conversantBidAdapter.js @@ -7,7 +7,7 @@ const GVLID = 24; export const storage = getStorageManager(GVLID); const BIDDER_CODE = 'conversant'; -const URL = 'https://web.hb.ad.cpe.dotomi.com/s2s/header/24'; +const URL = 'https://web.hb.ad.cpe.dotomi.com/cvx/client/hb/ortb/25'; export const spec = { code: BIDDER_CODE, diff --git a/test/spec/modules/conversantBidAdapter_spec.js b/test/spec/modules/conversantBidAdapter_spec.js index 7c6d6e5dd6c..d802cd288ef 100644 --- a/test/spec/modules/conversantBidAdapter_spec.js +++ b/test/spec/modules/conversantBidAdapter_spec.js @@ -210,7 +210,7 @@ describe('Conversant adapter tests', function() { }; const request = spec.buildRequests(bidRequests, bidderRequest); expect(request.method).to.equal('POST'); - expect(request.url).to.equal('https://web.hb.ad.cpe.dotomi.com/s2s/header/24'); + expect(request.url).to.equal('https://web.hb.ad.cpe.dotomi.com/cvx/client/hb/ortb/25'); const payload = request.data; expect(payload).to.have.property('id', 'req000'); From 86ddf586dc655993fd04902d7e61d78da87a8c7c Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Thu, 2 Jul 2020 19:50:36 -0400 Subject: [PATCH 458/496] Update padsquad for meta.advertiserDomains (#5439) * Update padsquadBidAdapter_spec.js * Update padsquadBidAdapter.js * Update padsquadBidAdapter.js --- modules/padsquadBidAdapter.js | 1 + test/spec/modules/padsquadBidAdapter_spec.js | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/padsquadBidAdapter.js b/modules/padsquadBidAdapter.js index 088cac265b9..24b1d5be3be 100644 --- a/modules/padsquadBidAdapter.js +++ b/modules/padsquadBidAdapter.js @@ -83,6 +83,7 @@ export const spec = { ad: bid.adm, ttl: DEFAULT_BID_TTL, creativeId: bid.crid, + meta: { advertiserDomains: bid.adomain }, netRevenue: DEFAULT_NET_REVENUE, currency: DEFAULT_CURRENCY, }) diff --git a/test/spec/modules/padsquadBidAdapter_spec.js b/test/spec/modules/padsquadBidAdapter_spec.js index d30b1f34a9e..7d0858ed25e 100644 --- a/test/spec/modules/padsquadBidAdapter_spec.js +++ b/test/spec/modules/padsquadBidAdapter_spec.js @@ -212,6 +212,7 @@ describe('Padsquad bid adapter', function () { expect(bids[index]).to.have.property('height', RESPONSE.body.seatbid[0].bid[index].h); expect(bids[index]).to.have.property('ad', RESPONSE.body.seatbid[0].bid[index].adm); expect(bids[index]).to.have.property('creativeId', RESPONSE.body.seatbid[0].bid[index].crid); + expect(bids[index].meta.advertiserDomains).to.deep.equal(RESPONSE.body.seatbid[0].bid[index].adomain); expect(bids[index]).to.have.property('ttl', 30); expect(bids[index]).to.have.property('netRevenue', true); } From 2bb347f6522f475b7c4fda7adbd7d437396efae1 Mon Sep 17 00:00:00 2001 From: mamatic <52153441+mamatic@users.noreply.github.com> Date: Fri, 3 Jul 2020 01:52:47 +0200 Subject: [PATCH 459/496] ATS-identityLinkId - add additional info logging events (#5442) --- modules/identityLinkIdSystem.js | 7 +++++-- test/spec/modules/identityLinkIdSystem_spec.js | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/identityLinkIdSystem.js b/modules/identityLinkIdSystem.js index 7f70b7329e7..c516c06d11a 100644 --- a/modules/identityLinkIdSystem.js +++ b/modules/identityLinkIdSystem.js @@ -46,8 +46,10 @@ export const identityLinkSubmodule = { // Check ats during callback so it has a chance to initialise. // If ats library is available, use it to retrieve envelope. If not use standard third party endpoint if (window.ats) { + utils.logInfo('ATS exists!'); window.ats.retrieveEnvelope(function (envelope) { if (envelope) { + utils.logInfo('An envelope can be retrieved from ATS!'); callback(JSON.parse(envelope).envelope); } else { getEnvelope(url, callback); @@ -63,6 +65,7 @@ export const identityLinkSubmodule = { }; // return envelope from third party endpoint function getEnvelope(url, callback) { + utils.logInfo('A 3P retrieval is attempted!'); const callbacks = { success: response => { let responseObj; @@ -70,13 +73,13 @@ function getEnvelope(url, callback) { try { responseObj = JSON.parse(response); } catch (error) { - utils.logError(error); + utils.logInfo(error); } } callback((responseObj && responseObj.envelope) ? responseObj.envelope : ''); }, error: error => { - utils.logError(`identityLink: ID fetch encountered an error`, error); + utils.logInfo(`identityLink: ID fetch encountered an error`, error); callback(); } }; diff --git a/test/spec/modules/identityLinkIdSystem_spec.js b/test/spec/modules/identityLinkIdSystem_spec.js index e6850fc77b0..0d539d5988c 100644 --- a/test/spec/modules/identityLinkIdSystem_spec.js +++ b/test/spec/modules/identityLinkIdSystem_spec.js @@ -86,7 +86,6 @@ describe('IdentityLinkId tests', function () { responseHeader, 'Unavailable' ); - expect(logErrorStub.calledOnce).to.be.true; expect(callBackSpy.calledOnce).to.be.true; }); }); From 833da08fe24ffc67028111db718b9d396ae7e0ea Mon Sep 17 00:00:00 2001 From: mamatic <52153441+mamatic@users.noreply.github.com> Date: Fri, 3 Jul 2020 02:00:25 +0200 Subject: [PATCH 460/496] ATS-change logError to logInfo type (#5443) --- modules/userId/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/userId/index.js b/modules/userId/index.js index 88a0a636caf..1c5768edae1 100644 --- a/modules/userId/index.js +++ b/modules/userId/index.js @@ -251,7 +251,7 @@ function processSubmoduleCallbacks(submodules, cb) { // cache decoded value (this is copied to every adUnit bid) submodule.idObj = submodule.submodule.decode(idObj); } else { - utils.logError(`${MODULE_NAME}: ${submodule.submodule.name} - request id responded with an empty value`); + utils.logInfo(`${MODULE_NAME}: ${submodule.submodule.name} - request id responded with an empty value`); } done(); }); From 1c8a275b81aa685c966a9c131e8f65d7ab5a0ad4 Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Fri, 3 Jul 2020 20:48:27 -0400 Subject: [PATCH 461/496] Revert "add AMX adapter (#5383)" (#5455) This reverts commit d8e5796827a46455185292e4a498628ecdb09bc6. --- modules/amxBidAdapter.js | 279 ----------------- modules/amxBidAdapter.md | 37 --- test/spec/modules/amxBidAdapter_spec.js | 390 ------------------------ 3 files changed, 706 deletions(-) delete mode 100644 modules/amxBidAdapter.js delete mode 100644 modules/amxBidAdapter.md delete mode 100644 test/spec/modules/amxBidAdapter_spec.js diff --git a/modules/amxBidAdapter.js b/modules/amxBidAdapter.js deleted file mode 100644 index 8d7e9682325..00000000000 --- a/modules/amxBidAdapter.js +++ /dev/null @@ -1,279 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import { parseUrl, deepAccess, _each, formatQS, getUniqueIdentifierStr, triggerPixel } from '../src/utils.js'; - -const BIDDER_CODE = 'amx'; -const SIMPLE_TLD_TEST = /\.co\.\w{2,4}$/; -const DEFAULT_ENDPOINT = 'https://prebid.a-mo.net/a/c'; -const VERSION = 'pba1.0'; -const xmlDTDRxp = /^\s*<\?xml[^\?]+\?>/; -const VAST_RXP = /^\s*<\??(?:vast|xml)/i; -const TRACKING_ENDPOINT = 'https://1x1.a-mo.net/hbx/'; - -const getLocation = (request) => - parseUrl(deepAccess(request, 'refererInfo.canonicalUrl', location.href)) - -const largestSize = (sizes, mediaTypes) => { - const allSizes = sizes - .concat(deepAccess(mediaTypes, `${BANNER}.sizes`, []) || []) - .concat(deepAccess(mediaTypes, `${VIDEO}.sizes`, []) || []) - - return allSizes.sort((a, b) => (b[0] * b[1]) - (a[0] * a[1]))[0]; -} - -const generateDTD = (xmlDocument) => - ``; - -const isVideoADM = (html) => html != null && VAST_RXP.test(html); -const getMediaType = (bid) => isVideoADM(bid.adm) ? VIDEO : BANNER; -const nullOrType = (value, type) => - value == null || (typeof value) === type // eslint-disable-line valid-typeof - -function getID(loc) { - const host = loc.hostname.split('.'); - const short = host.slice( - host.length - (SIMPLE_TLD_TEST.test(loc.host) ? 3 : 2) - ).join('.'); - return btoa(short).replace(/=+$/, ''); -} - -const enc = encodeURIComponent; - -function nestedQs (qsData) { - const out = []; - Object.keys(qsData || {}).forEach((key) => { - out.push(enc(key) + '=' + enc(String(qsData[key]))); - }); - - return enc(out.join('&')); -} - -function createBidMap(bids) { - const out = {}; - for (const bid of bids) { - out[bid.bidId] = convertRequest(bid) - } - return out; -} - -const trackEvent = (eventName, data) => - triggerPixel(`${TRACKING_ENDPOINT}g_${eventName}?${formatQS({ - ...data, - ts: Date.now(), - eid: getUniqueIdentifierStr(), - })}`); - -function convertRequest(bid) { - const size = largestSize(bid.sizes, bid.mediaTypes) || [0, 0]; - const av = bid.mediaType === VIDEO || VIDEO in bid.mediaTypes; - const tid = deepAccess(bid, 'params.tagId') - - const params = { - av, - aw: size[0], - ah: size[1], - tf: 0, - }; - - if (typeof tid === 'string' && tid.length > 0) { - params.i = tid; - } - return params; -} - -function decorateADM(bid) { - const impressions = deepAccess(bid, 'ext.himp', []) - .concat(bid.nurl != null ? [bid.nurl] : []) - .filter((imp) => imp != null && imp.length > 0) - .map((src) => ``) - .join(''); - return bid.adm + impressions; -} - -function decorateVideoADM(bid) { - const doc = new DOMParser().parseFromString(bid.adm, 'text/xml'); - if (doc.querySelector('parsererror') != null) { - return null; - } - - const root = doc.querySelector('InLine,Wrapper') - if (root == null) { - return null; - } - - const pixels = [bid.nurl].concat(bid.ext.himp || []) - .filter((url) => url != null); - - _each(pixels, (pxl) => { - const imagePixel = doc.createElement('Impression'); - const cdata = doc.createCDATASection(pxl); - imagePixel.appendChild(cdata); - root.appendChild(imagePixel); - }); - - const dtdMatch = xmlDTDRxp.exec(bid.adm); - return (dtdMatch != null ? dtdMatch[0] : generateDTD(doc)) + doc.documentElement.outerHTML; -} - -function resolveSize(bid, request, bidId) { - if (bid.w != null && bid.w > 1 && bid.h != null && bid.h > 1) { - return [bid.w, bid.h]; - } - - const bidRequest = request.m[bidId]; - if (bidRequest == null) { - return [0, 0]; - } - - return [bidRequest.aw, bidRequest.ah]; -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - - isBidRequestValid(bid) { - return nullOrType(deepAccess(bid, 'params.endpoint', null), 'string') && - nullOrType(deepAccess(bid, 'params.tagId', null), 'string') && - nullOrType(deepAccess(bid, 'params.testMode', null), 'boolean'); - }, - - buildRequests(bidRequests, bidderRequest) { - const loc = getLocation(bidderRequest); - const tagId = deepAccess(bidRequests[0], 'params.tagId', null); - const testMode = deepAccess(bidRequests[0], 'params.testMode', 0); - - const payload = { - a: bidderRequest.auctionId, - B: 0, - b: loc.host, - tm: testMode, - V: '$prebid.version$', - i: (testMode && tagId != null) ? tagId : getID(loc), - l: {}, - f: 0.01, - cv: VERSION, - st: 'prebid', - h: screen.height, - w: screen.width, - gs: deepAccess(bidderRequest, 'gdprConsent.gdprApplies', '0'), - gc: deepAccess(bidderRequest, 'gdprConsent.consentString', ''), - u: deepAccess(bidderRequest, 'refererInfo.canonicalUrl', loc.href), - do: loc.host, - re: deepAccess(bidderRequest, 'refererInfo.referer'), - usp: bidderRequest.uspConsent || '1---', - smt: 9, - d: '', - m: createBidMap(bidRequests), - }; - - return { - data: payload, - method: 'POST', - url: deepAccess(bidRequests[0], 'params.endpoint', DEFAULT_ENDPOINT), - withCredentials: true, - }; - }, - - getUserSyncs(syncOptions, serverResponses) { - return (serverResponses || []) - .flatMap(({ body: response }) => - response != null && response.p != null ? (response.p.hreq || []) : []) - .map((syncPixel) => - ({ - type: syncPixel.indexOf('__st=iframe') !== -1 ? 'iframe' : 'image', - url: syncPixel - }) - ).filter(({ - type - }) => syncOptions.iframeEnabled || type === 'image') - }, - - interpretResponse(serverResponse, request) { - // validate the body/response - const response = serverResponse.body; - if (response == null || typeof response === 'string') { - return []; - } - - return Object.keys(response.r).flatMap((bidID) => { - const biddata = response.r[bidID]; - return biddata.flatMap((siteBid) => - siteBid.b.map((bid) => { - const mediaType = getMediaType(bid); - const ad = mediaType === BANNER ? decorateADM(bid) : decorateVideoADM(bid); - if (ad == null) { - return null; - } - - const size = resolveSize(bid, request.data, bidID); - - return ({ - requestId: bidID, - cpm: bid.price, - width: size[0], - height: size[1], - creativeId: bid.crid, - currency: 'USD', - netRevenue: true, - [mediaType === VIDEO ? 'vastXml' : 'ad']: ad, - meta: { - advertiserDomains: bid.adomain, - mediaType, - }, - ttl: mediaType === VIDEO ? 90 : 70 - }); - })).filter((possibleBid) => possibleBid != null); - }); - }, - - onSetTargeting(targetingData) { - if (targetingData == null) { - return; - } - - trackEvent('pbst', { - A: targetingData.bidder, - w: targetingData.width, - h: targetingData.height, - bid: targetingData.adId, - c1: targetingData.mediaType, - np: targetingData.cpm, - aud: targetingData.requestId, - a: targetingData.adUnitCode, - c2: nestedQs(targetingData.adserverTargeting), - }); - }, - - onTimeout(timeoutData) { - if (timeoutData == null) { - return; - } - - trackEvent('pbto', { - A: timeoutData.bidder, - bid: timeoutData.bidId, - a: timeoutData.adUnitCode, - cn: timeoutData.timeout, - aud: timeoutData.auctionId, - }); - }, - - onBidWon(bidWinData) { - if (bidWinData == null) { - return; - } - - trackEvent('pbwin', { - A: bidWinData.bidder, - w: bidWinData.width, - h: bidWinData.height, - bid: bidWinData.adId, - C: bidWinData.mediaType === BANNER ? 0 : 1, - np: bidWinData.cpm, - a: bidWinData.adUnitCode, - }); - }, -}; - -registerBidder(spec); diff --git a/modules/amxBidAdapter.md b/modules/amxBidAdapter.md deleted file mode 100644 index c06c2e7157c..00000000000 --- a/modules/amxBidAdapter.md +++ /dev/null @@ -1,37 +0,0 @@ -Overview -======== - -``` -Module Name: AMX Adapter -Module Type: Bidder Adapter -Maintainer: prebid.support@amxrtb.com -``` - -Description -=========== - -This module connects web publishers to AMX RTB video and display demand. - -# Bid Parameters - -| Key | Required | Example | Description | -| --- | -------- | ------- | ----------- | -| `endpoint` | **yes** | `https://prebid.a-mo.net/a/c` | The url including https:// and any path | -| `testMode` | no | `true` | this will activate test mode / 100% fill with sample ads | -| `tagId` | no | `"eh3hffb"` | can be used for more specific targeting of inventory. Your account manager will provide this ID if needed | - -# Test Parameters - -``` -var adUnits = [{ - code: 'test-div', - sizes: [[300, 250]], - bids: [{ - bidder: 'amx', - params: { - testMode: true, - endpoint: 'https://prebid.a-mo.net/a/c', - }, - }] -}] -``` diff --git a/test/spec/modules/amxBidAdapter_spec.js b/test/spec/modules/amxBidAdapter_spec.js deleted file mode 100644 index e19de368361..00000000000 --- a/test/spec/modules/amxBidAdapter_spec.js +++ /dev/null @@ -1,390 +0,0 @@ -import * as utils from 'src/utils.js'; -import { config } from 'src/config.js'; -import { expect } from 'chai'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { spec } from 'modules/amxBidAdapter.js'; -import { BANNER, VIDEO } from 'src/mediaTypes'; -import { formatQS } from 'src/utils'; - -const sampleRequestId = '82c91e127a9b93e'; -const sampleDisplayAd = (additionalImpressions) => `${additionalImpressions}`; -const sampleDisplayCRID = '78827819'; -// minimal example vast -const sampleVideoAd = (addlImpression) => ` -00:00:15${addlImpression} -`.replace(/\n+/g, '') - -const embeddedTrackingPixel = `https://1x1.a-mo.net/hbx/g_impression?A=sample&B=20903`; -const sampleNurl = 'https://example.exchange/nurl'; - -const sampleBidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: utils.getUniqueIdentifierStr(), - vendorData: {} - }, - auctionId: utils.getUniqueIdentifierStr(), - uspConsent: '1YYY', - refererInfo: { - referer: 'https://www.prebid.org', - canonicalUrl: 'https://www.prebid.org/the/link/to/the/page' - } -}; - -const sampleBidRequestBase = { - bidder: spec.code, - params: { - endpoint: 'https://httpbin.org/post', - }, - sizes: [[320, 50]], - mediaTypes: { - [BANNER]: { - sizes: [[300, 250]] - } - }, - adUnitCode: 'div-gpt-ad-example', - transactionId: utils.getUniqueIdentifierStr(), - bidId: sampleRequestId, - auctionId: utils.getUniqueIdentifierStr(), -}; - -const sampleBidRequestVideo = { - ...sampleBidRequestBase, - bidId: sampleRequestId + '_video', - sizes: [[300, 150]], - mediaTypes: { - [VIDEO]: { - sizes: [[360, 250]] - } - } -}; - -const sampleServerResponse = { - 'p': { - 'hreq': ['https://1x1.a-mo.net/hbx/g_sync?partner=test', 'https://1x1.a-mo.net/hbx/g_syncf?__st=iframe'] - }, - 'r': { - [sampleRequestId]: [ - { - 'b': [ - { - 'adid': '78827819', - 'adm': sampleDisplayAd(''), - 'adomain': [ - 'example.com' - ], - 'crid': sampleDisplayCRID, - 'ext': { - 'himp': [ - embeddedTrackingPixel - ], - }, - 'nurl': sampleNurl, - 'h': 600, - 'id': '2014691335735134254', - 'impid': '1', - 'price': 0.25, - 'w': 300 - }, - { - 'adid': '222976952', - 'adm': sampleVideoAd(''), - 'adomain': [ - 'example.com' - ], - 'crid': sampleDisplayCRID, - 'ext': { - 'himp': [ - embeddedTrackingPixel - ], - }, - 'nurl': sampleNurl, - 'h': 1, - 'id': '7735706981389902829', - 'impid': '1', - 'price': 0.25, - 'w': 1 - }, - ], - } - ] - }, -} - -describe('AmxBidAdapter', () => { - describe('isBidRequestValid', () => { - it('endpoint must be an optional string', () => { - expect(spec.isBidRequestValid({params: { endpoint: 1 }})).to.equal(false) - expect(spec.isBidRequestValid({params: { endpoint: 'test' }})).to.equal(true) - }); - - it('tagId is an optional string', () => { - expect(spec.isBidRequestValid({params: { tagId: 1 }})).to.equal(false) - expect(spec.isBidRequestValid({params: { tagId: 'test' }})).to.equal(true) - }); - - it('testMode is an optional boolean', () => { - expect(spec.isBidRequestValid({params: { testMode: 1 }})).to.equal(false) - expect(spec.isBidRequestValid({params: { testMode: false }})).to.equal(true) - }); - - it('none of the params are required', () => { - expect(spec.isBidRequestValid({})).to.equal(true) - }); - }) - describe('getUserSync', () => { - it('will only sync from valid server responses', () => { - const syncs = spec.getUserSyncs({ iframeEnabled: true }); - expect(syncs).to.eql([]); - }); - - it('will return valid syncs from a server response', () => { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, [{body: sampleServerResponse}]); - expect(syncs.length).to.equal(2); - expect(syncs[0].type).to.equal('image'); - expect(syncs[1].type).to.equal('iframe'); - }); - - it('will filter out iframe syncs based on options', () => { - const syncs = spec.getUserSyncs({ iframeEnabled: false }, [{body: sampleServerResponse}, {body: sampleServerResponse}]); - expect(syncs.length).to.equal(2); - expect(syncs).to.satisfy((allSyncs) => allSyncs.every((sync) => sync.type === 'image')) - }); - }); - - describe('buildRequests', () => { - it('will default to prebid.a-mo.net endpoint', () => { - const { url } = spec.buildRequests([], sampleBidderRequest); - expect(url).to.equal('https://prebid.a-mo.net/a/c') - }); - - it('reads test mode from the first bid request', () => { - const { data } = spec.buildRequests([{ - ...sampleBidRequestBase, - params: { - testMode: true - } - }], sampleBidderRequest); - expect(data.tm).to.equal(true); - }); - - it('handles referer data and GDPR, USP Consent', () => { - const { data } = spec.buildRequests([sampleBidRequestBase], sampleBidderRequest); - delete data.m; // don't deal with "m" in this test - - expect(data).to.deep.equal({ - a: sampleBidderRequest.auctionId, - B: 0, - b: 'www.prebid.org', - tm: 0, - V: '$prebid.version$', - i: btoa('prebid.org').replace(/=+$/, ''), - l: {}, - f: 0.01, - cv: 'pba1.0', - st: 'prebid', - h: screen.height, - w: screen.width, - gs: sampleBidderRequest.gdprConsent.gdprApplies, - gc: sampleBidderRequest.gdprConsent.consentString, - u: sampleBidderRequest.refererInfo.canonicalUrl, - do: 'www.prebid.org', - re: sampleBidderRequest.refererInfo.referer, - usp: sampleBidderRequest.uspConsent, - smt: 9, - d: '', - }) - }); - - it('can build a banner request', () => { - const { method, url, data } = spec.buildRequests([sampleBidRequestBase, { - ...sampleBidRequestBase, - bidId: sampleRequestId + '_2', - params: { - ...sampleBidRequestBase.params, - tagId: 'example' - } - }], sampleBidderRequest) - - expect(url).to.equal(sampleBidRequestBase.params.endpoint) - expect(method).to.equal('POST'); - expect(Object.keys(data.m).length).to.equal(2); - expect(data.m[sampleRequestId]).to.deep.equal({ - av: false, - aw: 300, - ah: 250, - tf: 0 - }); - expect(data.m[sampleRequestId + '_2']).to.deep.equal({ - av: false, - aw: 300, - i: 'example', - ah: 250, - tf: 0 - }); - }); - - it('can build a video request', () => { - const { data } = spec.buildRequests([sampleBidRequestVideo], sampleBidderRequest); - expect(Object.keys(data.m).length).to.equal(1); - expect(data.m[sampleRequestId + '_video']).to.deep.equal({ - av: true, - aw: 360, - ah: 250, - tf: 0 - }); - }); - }); - - describe('interpretResponse', () => { - const baseBidResponse = { - requestId: sampleRequestId, - cpm: 0.25, - creativeId: sampleDisplayCRID, - currency: 'USD', - netRevenue: true, - meta: { - advertiserDomains: ['example.com'], - }, - }; - - const baseRequest = { - data: { - m: { - [sampleRequestId]: { - aw: 300, - ah: 250, - }, - } - } - }; - - it('will handle a nobid response', () => { - const parsed = spec.interpretResponse({ body: '' }, baseRequest) - expect(parsed).to.eql([]) - }); - - it('can parse a display ad', () => { - const parsed = spec.interpretResponse({ body: sampleServerResponse }, baseRequest) - expect(parsed.length).to.equal(2) - - // we should have display, video, display - expect(parsed[0]).to.deep.equal({ - ...baseBidResponse, - meta: { - ...baseBidResponse.meta, - mediaType: BANNER, - }, - width: 300, - height: 600, // from the bid itself - ttl: 70, - ad: sampleDisplayAd( - `` + - `` - ), - }); - }); - - it('can parse a video ad', () => { - const parsed = spec.interpretResponse({ body: sampleServerResponse }, baseRequest) - expect(parsed.length).to.equal(2) - - // we should have display, video, display - expect(parsed[1]).to.deep.equal({ - ...baseBidResponse, - meta: { - ...baseBidResponse.meta, - mediaType: VIDEO, - }, - width: 300, - height: 250, - ttl: 90, - vastXml: sampleVideoAd( - `` + - `` - ), - }); - }); - }); - - describe('analytics methods', () => { - let firedPixels = []; - let _Image = window.Image; - before(() => { - _Image = window.Image; - window.Image = class FakeImage { - set src(value) { - firedPixels.push(value) - } - } - }); - - beforeEach(() => { - firedPixels = []; - }); - - after(() => { - window.Image = _Image; - }); - - it('will fire an event for onSetTargeting', () => { - spec.onSetTargeting({ - bidder: 'example', - width: 300, - height: 250, - adId: 'ad-id', - mediaType: BANNER, - cpm: 1.23, - requestId: utils.getUniqueIdentifierStr(), - adUnitCode: 'div-gpt-ad', - adserverTargeting: { - hb_pb: '1.23', - hb_adid: 'ad-id', - hb_bidder: 'example' - } - }); - expect(firedPixels.length).to.equal(1) - expect(firedPixels[0]).to.match(/\/hbx\/g_pbst/) - const parsed = new URL(firedPixels[0]); - const nestedData = parsed.searchParams.get('c2'); - expect(nestedData).to.equal(formatQS({ - hb_pb: '1.23', - hb_adid: 'ad-id', - hb_bidder: 'example' - })); - }); - - it('will log an event for timeout', () => { - spec.onTimeout({ - bidder: 'example', - bidId: 'test-bid-id', - adUnitCode: 'div-gpt-ad', - timeout: 300, - auctionId: utils.getUniqueIdentifierStr() - }); - expect(firedPixels.length).to.equal(1) - expect(firedPixels[0]).to.match(/\/hbx\/g_pbto/) - }); - - it('will log an event for prebid win', () => { - spec.onBidWon({ - bidder: 'example', - adId: 'test-ad-id', - width: 300, - height: 250, - mediaType: VIDEO, - cpm: 1.34, - adUnitCode: 'div-gpt-ad', - timeout: 300, - auctionId: utils.getUniqueIdentifierStr() - }); - expect(firedPixels.length).to.equal(1) - expect(firedPixels[0]).to.match(/\/hbx\/g_pbwin/) - - const pixel = firedPixels[0]; - const url = new URL(pixel); - expect(url.searchParams.get('C')).to.equal('1') - expect(url.searchParams.get('np')).to.equal('1.34') - }); - }); -}); From 76e680e0a629d2a62dc6de450d89fe1a60b13d21 Mon Sep 17 00:00:00 2001 From: Catalin Ciocov Date: Mon, 6 Jul 2020 00:47:39 +0300 Subject: [PATCH 462/496] Inskin Bid adapter small changes (#5373) * Add plr_AdSlot parameter needed by Inskin Pagescroll ad format * Send additional TCF related information to Inskin's ad server * Fixed linting issues. * Added unit tests --- modules/inskinBidAdapter.js | 129 +++++++++++++++++++++ test/spec/modules/inskinBidAdapter_spec.js | 85 ++++++++++++++ 2 files changed, 214 insertions(+) diff --git a/modules/inskinBidAdapter.js b/modules/inskinBidAdapter.js index a89a1b20219..2a55b5280db 100644 --- a/modules/inskinBidAdapter.js +++ b/modules/inskinBidAdapter.js @@ -57,6 +57,9 @@ export const spec = { parallel: true }, validBidRequests[0].params); + data.keywords = data.keywords || []; + const restrictions = []; + if (bidderRequest && bidderRequest.gdprConsent) { data.consent = { gdprVendorId: 150, @@ -64,6 +67,33 @@ export const spec = { // will check if the gdprApplies field was populated with a boolean value (ie from page config). If it's undefined, then default to true gdprConsentRequired: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true }; + + if (bidderRequest.gdprConsent.apiVersion === 2) { + const purposes = [ + {id: 1, kw: 'nocookies'}, + {id: 2, kw: 'nocontext'}, + {id: 3, kw: 'nodmp'}, + {id: 4, kw: 'nodata'}, + {id: 7, kw: 'noclicks'}, + {id: 9, kw: 'noresearch'} + ]; + + const d = bidderRequest.gdprConsent.vendorData; + + if (d) { + if (d.purposeOneTreatment) { + data.keywords.push('cst-nodisclosure'); + restrictions.push('nodisclosure'); + } + + purposes.map(p => { + if (!checkConsent(p.id, d)) { + data.keywords.push('cst-' + p.kw); + restrictions.push(p.kw); + } + }); + } + } } validBidRequests.map(bid => { @@ -78,6 +108,11 @@ export const spec = { placement.adTypes.push(5, 9, 163, 2163, 3006); + if (restrictions.length) { + placement.properties = placement.properties || {}; + placement.properties.restrictions = restrictions; + } + if (placement.networkId && placement.siteId) { data.placements.push(placement); } @@ -153,6 +188,7 @@ export const spec = { const id = 'ism_tag_' + Math.floor((Math.random() * 10e16)); window[id] = { + plr_AdSlot: e.source.frameElement, bidId: e.data.bidId, bidPrice: bidsMap[e.data.bidId].price, serverResponse @@ -242,4 +278,97 @@ function retrieveAd(bidId, decision) { return "', + 'adid': '98493581', + 'adomain': [ + 'http://prebid.org' + ], + 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581', + 'cid': '9325', + 'crid': '98493581', + 'cat': [ + 'IAB3-1' + ], + 'w': 300, + 'h': 600, + 'ext': { + 'prebid': { + 'type': 'banner' + }, + 'bidder': { + 'appnexus': { + 'brand_id': 555545, + 'auction_id': 6500448734132353000, + 'bidder_id': 2, + 'bid_ad_type': 0 + } + } + } + }, + { + 'id': '677903815252395010', + 'impid': '2899ec066a91ff0', + 'price': 0.9, + 'adm': '', + 'adid': '98493580', + 'adomain': [ + 'http://prebid.org' + ], + 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581', + 'cid': '9320', + 'crid': '98493580', + 'cat': [ + 'IAB3-1' + ], + 'w': 300, + 'h': 600, + 'ext': { + 'prebid': { + 'type': 'banner' + }, + 'bidder': { + 'appnexus': { + 'brand_id': 555540, + 'auction_id': 6500448734132353000, + 'bidder_id': 2, + 'bid_ad_type': 0 + } + } + } + } ], + 'seat': 'appnexus' + } + ], + 'cur': 'GBP', /* NOTE - this is where cur is, not in the seatbids. */ + 'ext': { + 'responsetimemillis': { + 'appnexus': 47, + 'openx': 30 + } + }, + 'timing': { + 'start': 1536848078.089177, + 'end': 1536848078.142203, + 'TimeTaken': 0.05302619934082031 + } + }, + 'headers': {} +}; +/* +A bidder returns a bid for both sizes in an adunit + */ +var validResponse2BidsSameAdunit = { + 'body': { + 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba', + 'seatbid': [ + { + 'bid': [ + { + 'id': '677903815252395017', + 'impid': '2899ec066a91ff8', + 'price': 0.5, + 'adm': '', + 'adid': '98493581', + 'adomain': [ + 'http://prebid.org' + ], + 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581', + 'cid': '9325', + 'crid': '98493581', + 'cat': [ + 'IAB3-1' + ], + 'w': 300, + 'h': 600, + 'ext': { + 'prebid': { + 'type': 'banner' + }, + 'bidder': { + 'appnexus': { + 'brand_id': 555545, + 'auction_id': 6500448734132353000, + 'bidder_id': 2, + 'bid_ad_type': 0 + } + } + } + }, + { + 'id': '677903815252395010', + 'impid': '2899ec066a91ff8', + 'price': 0.9, + 'adm': '', + 'adid': '98493580', + 'adomain': [ + 'http://prebid.org' + ], + 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581', + 'cid': '9320', + 'crid': '98493580', + 'cat': [ + 'IAB3-1' + ], + 'w': 300, + 'h': 250, + 'ext': { + 'prebid': { + 'type': 'banner' + }, + 'bidder': { + 'appnexus': { + 'brand_id': 555540, + 'auction_id': 6500448734132353000, + 'bidder_id': 2, + 'bid_ad_type': 0 + } + } + } + } ], + 'seat': 'ozappnexus' + } + ], + 'cur': 'GBP', /* NOTE - this is where cur is, not in the seatbids. */ + 'ext': { + 'responsetimemillis': { + 'appnexus': 47, + 'openx': 30 + } + }, + 'timing': { + 'start': 1536848078.089177, + 'end': 1536848078.142203, + 'TimeTaken': 0.05302619934082031 + } + }, + 'headers': {} +}; +/* + +SPECIAL CONSIDERATION FOR VIDEO TESTS: + +DO NOT USE _validVideoResponse directly - the interpretResponse function will modify it (adding a renderer!!!) so all +subsequent calls will already have a renderer attached!!! + +*/ +function getCleanValidVideoResponse() { + return JSON.parse(JSON.stringify(_validVideoResponse)); +} +var _validVideoResponse = { + 'body': { + 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba', + 'seatbid': [ + { + 'bid': [ + { + 'id': '2899ec066a91ff8', + 'impid': '2899ec066a91ff8', + 'price': 31.7, + 'adm': '', + 'adomain': [ + 'sarr.properties' + ], + 'crid': 'ozone-655', + 'cat': [ + 'IAB21' + ], + 'w': 640, + 'h': 360, + 'ext': { + 'prebid': { + 'type': 'video' + } + }, + 'adId': '2899ec066a91ff8-2', + 'cpm': 31.7, + 'bidId': '2899ec066a91ff8', + 'requestId': '2899ec066a91ff8', + 'width': 640, + 'height': 360, + 'ad': '', + 'netRevenue': true, + 'creativeId': 'ozone-655', + 'currency': 'USD', + 'ttl': 300, + 'adserverTargeting': { + 'oz_ozbeeswax': 'ozbeeswax', + 'oz_ozbeeswax_pb': '31.7', + 'oz_ozbeeswax_crid': 'ozone-655', + 'oz_ozbeeswax_adv': 'sarr.properties', + 'oz_ozbeeswax_imp_id': '49d16ccc28663a8', + 'oz_ozbeeswax_adId': '49d16ccc28663a8-2', + 'oz_ozbeeswax_pb_r': '20.00', + 'oz_ozbeeswax_omp': '1', + 'oz_ozbeeswax_vid': 'outstream', + 'oz_auc_id': 'efa7fea0-7e87-4811-be86-fefb38c35fbb', + 'oz_winner': 'ozbeeswax', + 'oz_response_id': 'efa7fea0-7e87-4811-be86-fefb38c35fbb', + 'oz_winner_auc_id': '49d16ccc28663a8', + 'oz_winner_imp_id': '49d16ccc28663a8', + 'oz_pb_v': '2.4.0', + 'hb_bidder': 'ozone', + 'hb_adid': '49d16ccc28663a8-2', + 'hb_pb': '20.00', + 'hb_size': '640x360', + 'hb_source': 'client', + 'hb_format': 'banner' + }, + 'originalCpm': 31.7, + 'originalCurrency': 'USD' + } + ], + 'seat': 'ozbeeswax' + } + ], + 'ext': { + 'responsetimemillis': { + 'beeswax': 9, + 'openx': 43, + 'ozappnexus': 31, + 'ozbeeswax': 7 + } + }, + 'timing': { + 'start': 1536848078.089177, + 'end': 1536848078.142203, + 'TimeTaken': 0.05302619934082031 + } + }, + 'headers': {} +}; + +var validBidResponse1adWith2Bidders = { + 'body': { + 'id': '91221f96-b931-4acc-8f05-c2a1186fa5ac', + 'seatbid': [ + { + 'bid': [ + { + 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba', + 'impid': '2899ec066a91ff8', + 'price': 0.36754, + 'adm': '', + 'adid': '134928661', + 'adomain': [ + 'somecompany.com' + ], + 'iurl': 'https:\/\/ams1-ib.adnxs.com\/cr?id=134928661', + 'cid': '8825', + 'crid': '134928661', + 'cat': [ + 'IAB8-15', + 'IAB8-16', + 'IAB8-4', + 'IAB8-1', + 'IAB8-14', + 'IAB8-6', + 'IAB8-13', + 'IAB8-3', + 'IAB8-17', + 'IAB8-12', + 'IAB8-8', + 'IAB8-7', + 'IAB8-2', + 'IAB8-9', + 'IAB8', + 'IAB8-11' + ], + 'w': 300, + 'h': 250, + 'ext': { + 'prebid': { + 'type': 'banner' + }, + 'bidder': { + 'appnexus': { + 'brand_id': 14640, + 'auction_id': 1.8369641905139e+18, + 'bidder_id': 2, + 'bid_ad_type': 0 + } + } + } + } + ], + 'seat': 'appnexus' + }, + { + 'bid': [ + { + 'id': '75665207-a1ca-49db-ba0e-a5e9c7d26f32', + 'impid': '37fff511779365a', + 'price': 1.046, + 'adm': '
removed
', + 'adomain': [ + 'kx.com' + ], + 'crid': '13005', + 'w': 300, + 'h': 250, + 'ext': { + 'prebid': { + 'type': 'banner' + } + } + } + ], + 'seat': 'openx' + } + ], + 'ext': { + 'responsetimemillis': { + 'appnexus': 91, + 'openx': 109, + 'ozappnexus': 46, + 'ozbeeswax': 2, + 'pangaea': 91 + } + } + }, + 'headers': {} +}; + +/* +testing 2 ads, 2 bidders, one bidder bids for both slots in one adunit + */ + +var multiRequest1 = [ + { + 'bidder': 'ozone', + 'params': { + 'publisherId': 'OZONERUP0001', + 'siteId': '4204204201', + 'placementId': '0420420421', + 'customData': [ + { + 'settings': {}, + 'targeting': { + 'sens': 'f', + 'pt1': '/uk', + 'pt2': 'uk', + 'pt3': 'network-front', + 'pt4': 'ng', + 'pt5': [ + 'uk' + ], + 'pt7': 'desktop', + 'pt8': [ + 'tfmqxwj7q', + 'penl4dfdk', + 'uayf5jmv3', + 't8nyiude5', + 'sek9ghqwi' + ], + 'pt9': '|k0xw2vqzp33kklb3j5w4|||' + } + } + ], + 'lotameData': { + 'Profile': { + 'tpid': '4e5c21fc7c181c2b1eb3a73d543a27f6', + 'pid': '3a45fd4872fa01f35c49586d8dcb7c60', + 'Audiences': { + 'Audience': [ + { + 'id': '439847', + 'abbr': 'all' + }, + { + 'id': '446197', + 'abbr': 'Arts, Culture & Literature' + }, + { + 'id': '446198', + 'abbr': 'Business' + } + ] + } + } + } + }, + 'mediaTypes': { + 'banner': { + 'sizes': [ + [ + 300, + 250 + ], + [ + 300, + 600 + ] + ] + } + }, + 'adUnitCode': 'mpu', + 'transactionId': '6480bac7-31b5-4723-9145-ad8966660651', + 'sizes': [ + [ + 300, + 250 + ], + [ + 300, + 600 + ] + ], + 'bidId': '2d30e86db743a8', + 'bidderRequestId': '1d03a1dfc563fc', + 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0 + }, + { + 'bidder': 'ozone', + 'params': { + 'publisherId': 'OZONERUP0001', + 'siteId': '4204204201', + 'placementId': '0420420421', + 'customData': [ + { + 'settings': {}, + 'targeting': { + 'sens': 'f', + 'pt1': '/uk', + 'pt2': 'uk', + 'pt3': 'network-front', + 'pt4': 'ng', + 'pt5': [ + 'uk' + ], + 'pt7': 'desktop', + 'pt8': [ + 'tfmqxwj7q', + 'penl4dfdk', + 't8nxz6qzd', + 't8nyiude5', + 'sek9ghqwi' + ], + 'pt9': '|k0xw2vqzp33kklb3j5w4|||' + } + } + ], + 'lotameData': { + 'Profile': { + 'tpid': '4e5c21fc7c181c2b1eb3a73d543a27f6', + 'pid': '3a45fd4872fa01f35c49586d8dcb7c60', + 'Audiences': { + 'Audience': [ + { + 'id': '439847', + 'abbr': 'all' + }, + { + 'id': '446197', + 'abbr': 'Arts, Culture & Literature' + }, + { + 'id': '446198', + 'abbr': 'Business' + } + ] + } + } + } + }, + 'mediaTypes': { + 'banner': { + 'sizes': [ + [ + 728, + 90 + ], + [ + 970, + 250 + ] + ] + } + }, + 'adUnitCode': 'leaderboard', + 'transactionId': 'a49988e6-ae7c-46c4-9598-f18db49892a0', + 'sizes': [ + [ + 728, + 90 + ], + [ + 970, + 250 + ] + ], + 'bidId': '3025f169863b7f8', + 'bidderRequestId': '1d03a1dfc563fc', + 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0 + } +]; + +// WHEN sent as bidderRequest to buildRequests you should send the child: .bidderRequest +var multiBidderRequest1 = { + bidderRequest: { + 'bidderCode': 'ozone', + 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', + 'bidderRequestId': '1d03a1dfc563fc', + 'bids': [ + { + 'bidder': 'ozone', + 'params': { + 'publisherId': 'OZONERUP0001', + 'siteId': '4204204201', + 'placementId': '0420420421', + 'customData': [ + { + 'settings': {}, + 'targeting': { + 'sens': 'f', + 'pt1': '/uk', + 'pt2': 'uk', + 'pt3': 'network-front', + 'pt4': 'ng', + 'pt5': [ + 'uk' + ], + 'pt7': 'desktop', + 'pt8': [ + 'tfmqxwj7q', + 'txeh7uyo0', + 't8nxz6qzd', + 't8nyiude5', + 'sek9ghqwi' + ], + 'pt9': '|k0xw2vqzp33kklb3j5w4|||' + } + } + ], + 'lotameData': { + 'Profile': { + 'tpid': '4e5c21fc7c181c2b1eb3a73d543a27f6', + 'pid': '3a45fd4872fa01f35c49586d8dcb7c60', + 'Audiences': { + 'Audience': [ + { + 'id': '439847', + 'abbr': 'all' + }, + { + 'id': '446197', + 'abbr': 'Arts, Culture & Literature' + }, + { + 'id': '446198', + 'abbr': 'Business' + } + ] + } + } + } + }, + 'mediaTypes': { + 'banner': { + 'sizes': [ + [ + 300, + 250 + ], + [ + 300, + 600 + ] + ] + } + }, + 'adUnitCode': 'mpu', + 'transactionId': '6480bac7-31b5-4723-9145-ad8966660651', + 'sizes': [ + [ + 300, + 250 + ], + [ + 300, + 600 + ] + ], + 'bidId': '2d30e86db743a8', + 'bidderRequestId': '1d03a1dfc563fc', + 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0 + }, + { + 'bidder': 'ozone', + 'params': { + 'publisherId': 'OZONERUP0001', + 'siteId': '4204204201', + 'placementId': '0420420421', + 'customData': [ + { + 'settings': {}, + 'targeting': { + 'sens': 'f', + 'pt1': '/uk', + 'pt2': 'uk', + 'pt3': 'network-front', + 'pt4': 'ng', + 'pt5': [ + 'uk' + ], + 'pt7': 'desktop', + 'pt8': [ + 'tfmqxwj7q', + 'penl4dfdk', + 't8nxz6qzd', + 't8nyiude5', + 'sek9ghqwi' + ], + 'pt9': '|k0xw2vqzp33kklb3j5w4|||' + } + } + ], + 'lotameData': { + 'Profile': { + 'tpid': '4e5c21fc7c181c2b1eb3a73d543a27f6', + 'pid': '3a45fd4872fa01f35c49586d8dcb7c60', + 'Audiences': { + 'Audience': [ + { + 'id': '439847', + 'abbr': 'all' + }, + { + 'id': '446197', + 'abbr': 'Arts, Culture & Literature' + }, + { + 'id': '446198', + 'abbr': 'Business' + } + ] + } + } + } + }, + 'mediaTypes': { + 'banner': { + 'sizes': [ + [ + 728, + 90 + ], + [ + 970, + 250 + ] + ] + } + }, + 'adUnitCode': 'leaderboard', + 'transactionId': 'a49988e6-ae7c-46c4-9598-f18db49892a0', + 'sizes': [ + [ + 728, + 90 + ], + [ + 970, + 250 + ] + ], + 'bidId': '3025f169863b7f8', + 'bidderRequestId': '1d03a1dfc563fc', + 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0 + } + ], + 'auctionStart': 1592918645574, + 'timeout': 3000, + 'refererInfo': { + 'referer': 'http://ozone.ardm.io/adapter/2.4.0/620x350-switch.html?guardian=true&pbjs_debug=true', + 'reachedTop': true, + 'numIframes': 0, + 'stack': [ + 'http://ozone.ardm.io/adapter/2.4.0/620x350-switch.html?guardian=true&pbjs_debug=true' + ] + }, + 'gdprConsent': { + 'consentString': 'BOvy5sFO1dBa2AKAiBENDP-AAAAwVrv7_77-_9f-_f__9uj3Gr_v_f__32ccL5tv3h_7v-_7fi_-0nV4u_1tft9ydk1-5ctDztp507iakiPHmqNeb9n_mz1eZpRP58E09j53z7Ew_v8_v-b7BCPN_Y3v-8K96kA', + 'vendorData': { + 'metadata': 'BOvy5sFO1dBa2AKAiBENDPA', + 'gdprApplies': true, + 'hasGlobalConsent': false, + 'hasGlobalScope': false, + 'purposeConsents': { + '1': true, + '2': true, + '3': true, + '4': true, + '5': true + }, + 'vendorConsents': { + '1': true, + '2': true, + '3': false, + '4': true, + '5': true + } + }, + 'gdprApplies': true + }, + 'start': 1592918645578 + } +}; + +var multiResponse1 = { 'body': { - 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba', + 'id': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', 'seatbid': [ { 'bid': [ { - 'id': '677903815252395017', - 'impid': '2899ec066a91ff8', - 'price': 0.5, - 'adm': '', - 'adid': '98493581', + 'id': '4419718600113204943', + 'impid': '2d30e86db743a8', + 'price': 0.2484, + 'adm': '', + 'adid': '119683582', 'adomain': [ - 'http://prebid.org' + 'https://ozoneproject.com' ], - 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581', - 'cid': '9325', - 'crid': '98493581', + 'iurl': 'https://ams1-ib.adnxs.com/cr?id=119683582', + 'cid': '9979', + 'crid': '119683582', 'cat': [ - 'IAB3-1' + 'IAB3' ], 'w': 300, - 'h': 600, + 'h': 250, 'ext': { 'prebid': { - 'type': 'video' + 'type': 'banner' }, 'bidder': { - 'unruly': { - 'renderer': { - 'config': { - 'targetingUUID': 'aafd3388-afaf-41f4-b271-0ac8e0325a7f', - 'siteId': 1052815, - 'featureOverrides': {} - }, - 'url': 'https://video.unrulymedia.com/native/native-loader.js#supplyMode=prebid?cb=6284685353877994', - 'id': 'unruly_inarticle' - }, - 'vast_url': 'data:text/xml;base64,PD94bWwgdmVyc2lvbj0i' + 'ozone': {}, + 'appnexus': { + 'brand_id': 734921, + 'auction_id': 2995348111857539600, + 'bidder_id': 2, + 'bid_ad_type': 0 } } - } - } - ], - 'seat': 'unruly' - } - ], - 'ext': { - 'responsetimemillis': { - 'appnexus': 47, - 'openx': 30 - } - }, - 'timing': { - 'start': 1536848078.089177, - 'end': 1536848078.142203, - 'TimeTaken': 0.05302619934082031 - } - }, - 'headers': {} -}; -var validBidResponse1adWith2Bidders = { - 'body': { - 'id': '91221f96-b931-4acc-8f05-c2a1186fa5ac', - 'seatbid': [ - { - 'bid': [ + }, + 'cpm': 0.2484, + 'bidId': '2d30e86db743a8', + 'requestId': '2d30e86db743a8', + 'width': 300, + 'height': 250, + 'ad': '', + 'netRevenue': true, + 'creativeId': '119683582', + 'currency': 'USD', + 'ttl': 300, + 'originalCpm': 0.2484, + 'originalCurrency': 'USD' + }, { - 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba', - 'impid': '2899ec066a91ff8', - 'price': 0.36754, - 'adm': '', - 'adid': '134928661', + 'id': '18552976939844681', + 'impid': '3025f169863b7f8', + 'price': 0.0621, + 'adm': '', + 'adid': '120179216', 'adomain': [ - 'somecompany.com' - ], - 'iurl': 'https:\/\/ams1-ib.adnxs.com\/cr?id=134928661', - 'cid': '8825', - 'crid': '134928661', - 'cat': [ - 'IAB8-15', - 'IAB8-16', - 'IAB8-4', - 'IAB8-1', - 'IAB8-14', - 'IAB8-6', - 'IAB8-13', - 'IAB8-3', - 'IAB8-17', - 'IAB8-12', - 'IAB8-8', - 'IAB8-7', - 'IAB8-2', - 'IAB8-9', - 'IAB8', - 'IAB8-11' + 'appnexus.com' ], - 'w': 300, + 'iurl': 'https://ams1-ib.adnxs.com/cr?id=120179216', + 'cid': '9979', + 'crid': '120179216', + 'w': 970, 'h': 250, 'ext': { 'prebid': { 'type': 'banner' }, 'bidder': { + 'ozone': {}, 'appnexus': { - 'brand_id': 14640, - 'auction_id': 1.8369641905139e+18, + 'brand_id': 1, + 'auction_id': 3449036134472542700, 'bidder_id': 2, 'bid_ad_type': 0 } } - } + }, + 'cpm': 0.0621, + 'bidId': '3025f169863b7f8', + 'requestId': '3025f169863b7f8', + 'width': 970, + 'height': 250, + 'ad': '', + 'netRevenue': true, + 'creativeId': '120179216', + 'currency': 'USD', + 'ttl': 300, + 'originalCpm': 0.0621, + 'originalCurrency': 'USD' + }, + { + 'id': '18552976939844999', + 'impid': '3025f169863b7f8', + 'price': 0.521, + 'adm': '', + 'adid': '120179216', + 'adomain': [ + 'appnexus.com' + ], + 'iurl': 'https://ams1-ib.adnxs.com/cr?id=120179216', + 'cid': '9999', + 'crid': '120179299', + 'w': 728, + 'h': 90, + 'ext': { + 'prebid': { + 'type': 'banner' + }, + 'bidder': { + 'ozone': {}, + 'appnexus': { + 'brand_id': 1, + 'auction_id': 3449036134472542700, + 'bidder_id': 2, + 'bid_ad_type': 0 + } + } + }, + 'cpm': 0.521, + 'bidId': '3025f169863b7f8', + 'requestId': '3025f169863b7f8', + 'width': 728, + 'height': 90, + 'ad': '', + 'netRevenue': true, + 'creativeId': '120179299', + 'currency': 'USD', + 'ttl': 300, + 'originalCpm': 0.0621, + 'originalCurrency': 'USD' } ], - 'seat': 'appnexus' + 'seat': 'ozappnexus' }, { 'bid': [ { - 'id': '75665207-a1ca-49db-ba0e-a5e9c7d26f32', - 'impid': '37fff511779365a', - 'price': 1.046, - 'adm': '
removed
', - 'adomain': [ - 'kx.com' - ], - 'crid': '13005', + 'id': '1c605e8a-4992-4ec6-8a5c-f82e2938c2db', + 'impid': '2d30e86db743a8', + 'price': 0.01, + 'adm': '
', + 'crid': '540463358', 'w': 300, 'h': 250, 'ext': { 'prebid': { 'type': 'banner' + }, + 'bidder': { + 'ozone': {} } - } + }, + 'cpm': 0.01, + 'bidId': '2d30e86db743a8', + 'requestId': '2d30e86db743a8', + 'width': 300, + 'height': 250, + 'ad': '
', + 'netRevenue': true, + 'creativeId': '540463358', + 'currency': 'USD', + 'ttl': 300, + 'originalCpm': 0.01, + 'originalCurrency': 'USD' + }, + { + 'id': '3edeb4f7-d91d-44e2-8aeb-4a2f6d295ce5', + 'impid': '3025f169863b7f8', + 'price': 0.01, + 'adm': '
', + 'crid': '540221061', + 'w': 970, + 'h': 250, + 'ext': { + 'prebid': { + 'type': 'banner' + }, + 'bidder': { + 'ozone': {} + } + }, + 'cpm': 0.01, + 'bidId': '3025f169863b7f8', + 'requestId': '3025f169863b7f8', + 'width': 970, + 'height': 250, + 'ad': '
', + 'netRevenue': true, + 'creativeId': '540221061', + 'currency': 'USD', + 'ttl': 300, + 'originalCpm': 0.01, + 'originalCurrency': 'USD' } ], 'seat': 'openx' } ], 'ext': { + 'debug': {}, 'responsetimemillis': { - 'appnexus': 91, - 'openx': 109, - 'ozappnexus': 46, - 'ozbeeswax': 2, - 'pangaea': 91 + 'beeswax': 6, + 'openx': 91, + 'ozappnexus': 40, + 'ozbeeswax': 6 } } }, 'headers': {} }; +/* +--------------------end of 2 slots, 2 ---------------------------- + */ + describe('ozone Adapter', function () { describe('isBidRequestValid', function () { // A test ad unit that will consistently return test creatives @@ -473,7 +1589,7 @@ describe('ozone Adapter', function () { publisherId: '9876abcd12-3', siteId: '1234567890', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], - lotameData: {'Profile': {'tpid': 'c8ef27a0d4ba771a81159f0d2e792db4', 'Audiences': {'Audience': [{'id': '99999', 'abbr': 'sports'}, {'id': '88888', 'abbr': 'movie'}, {'id': '77777', 'abbr': 'blogger'}], 'ThirdPartyAudience': [{'id': '123', 'name': 'Automobiles'}, {'id': '456', 'name': 'Ages: 30-39'}]}}}, + lotameData: {'Profile': {'tpid': 'c8ef27a0d4ba771a81159f0d2e792db4', 'Audiences': {'Audience': [{'id': '99999', 'abbr': 'sports'}, {'id': '88888', 'abbr': 'movie'}, {'id': '77777', 'abbr': 'blogger'}]}}}, }, siteId: 1234567890 } @@ -854,26 +1970,26 @@ describe('ozone Adapter', function () { describe('buildRequests', function () { it('sends bid request to OZONEURI via POST', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); expect(request.url).to.equal(OZONEURI); expect(request.method).to.equal('POST'); }); it('sends data as a string', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); expect(request.data).to.be.a('string'); }); it('sends all bid parameters', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); }); it('adds all parameters inside the ext object only', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); expect(request.data).to.be.a('string'); var data = JSON.parse(request.data); - expect(data.imp[0].ext.ozone.lotameData).to.be.an('object'); + expect(data.ext.ozone.lotameData).to.be.an('object'); expect(data.imp[0].ext.ozone.customData).to.be.an('array'); expect(request).not.to.have.key('lotameData'); expect(request).not.to.have.key('customData'); @@ -882,10 +1998,10 @@ describe('ozone Adapter', function () { it('ignores ozoneData in & after version 2.1.1', function () { let validBidRequestsWithOzoneData = validBidRequests; validBidRequestsWithOzoneData[0].params.ozoneData = {'networkID': '3048', 'dfpSiteID': 'd.thesun', 'sectionID': 'homepage', 'path': '/', 'sec_id': 'null', 'sec': 'sec', 'topics': 'null', 'kw': 'null', 'aid': 'null', 'search': 'null', 'article_type': 'null', 'hide_ads': '', 'article_slug': 'null'}; - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); expect(request.data).to.be.a('string'); var data = JSON.parse(request.data); - expect(data.imp[0].ext.ozone.lotameData).to.be.an('object'); + expect(data.ext.ozone.lotameData).to.be.an('object'); expect(data.imp[0].ext.ozone.customData).to.be.an('array'); expect(data.imp[0].ext.ozone.ozoneData).to.be.undefined; expect(request).not.to.have.key('lotameData'); @@ -893,33 +2009,33 @@ describe('ozone Adapter', function () { }); it('has correct bidder', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); expect(request.bidderRequest.bids[0].bidder).to.equal(BIDDER_CODE); }); it('handles mediaTypes element correctly', function () { - const request = spec.buildRequests(validBidRequestsWithBannerMediaType, validBidderRequest); + const request = spec.buildRequests(validBidRequestsWithBannerMediaType, validBidderRequest.bidderRequest); expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); }); it('handles no ozone, lotame or custom data', function () { - const request = spec.buildRequests(validBidRequestsMinimal, validBidderRequest); + const request = spec.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest); expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); }); it('handles video mediaType element correctly, with outstream video', function () { - const request = spec.buildRequests(validBidRequestsWithNonBannerMediaTypesAndValidOutstreamVideo, validBidderRequest); + const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest.bidderRequest); expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); }); it('should not crash when there is no sizes element at all', function () { - const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); + const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); }); it('should be able to handle non-single requests', function () { config.setConfig({'ozone': {'singleRequest': false}}); - const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); + const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); expect(request).to.be.a('array'); expect(request[0]).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); // need to reset the singleRequest config flag: @@ -928,7 +2044,7 @@ describe('ozone Adapter', function () { it('should add gdpr consent information to the request when ozone is true', function () { let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest; + let bidderRequest = validBidderRequest.bidderRequest; bidderRequest.gdprConsent = { consentString: consentString, gdprApplies: true, @@ -947,9 +2063,9 @@ describe('ozone Adapter', function () { }); // mirror - it('should add gdpr consent information to the request when ozone.oz_enforceGdpr is false and vendorData is missing vendorConsents (Mirror)', function () { + it('should add gdpr consent information to the request when vendorData is missing vendorConsents (Mirror)', function () { let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest; + let bidderRequest = validBidderRequest.bidderRequest; bidderRequest.gdprConsent = { consentString: consentString, gdprApplies: true, @@ -964,43 +2080,9 @@ describe('ozone Adapter', function () { expect(payload.regs.ext.gdpr).to.equal(1); expect(payload.user.ext.consent).to.equal(consentString); }); - it('should add gdpr consent information to the request when ozone.oz_enforceGdpr is NOT PRESENT and vendorData is missing vendorConsents (Mirror)', function () { - let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest; - bidderRequest.gdprConsent = { - consentString: consentString, - gdprApplies: true, - vendorData: { - metadata: consentString, - gdprApplies: true - } - } - const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.regs.ext.gdpr).to.equal(1); - expect(payload.user.ext.consent).to.equal(consentString); - config.resetConfig(); - }); - it('should kill the auction request when ozone.oz_enforceGdpr is true & vendorData is missing vendorConsents (Mirror)', function () { - let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest; - bidderRequest.gdprConsent = { - consentString: consentString, - gdprApplies: true, - vendorData: { - metadata: consentString, - gdprApplies: true - } - } - config.setConfig({'ozone': {'oz_enforceGdpr': true}}); - const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest); - expect(request.length).to.equal(0); - config.resetConfig(); - }); - it('should set regs.ext.gdpr flag to 0 when gdprApplies is false', function () { let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest; + let bidderRequest = validBidderRequest.bidderRequest; bidderRequest.gdprConsent = { consentString: consentString, gdprApplies: false, @@ -1019,7 +2101,7 @@ describe('ozone Adapter', function () { it('should not have imp[N].ext.ozone.userId', function () { let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest; + let bidderRequest = validBidderRequest.bidderRequest; bidderRequest.gdprConsent = { consentString: consentString, gdprApplies: false, @@ -1063,14 +2145,14 @@ describe('ozone Adapter', function () { // 'pubcid': '5555', // remove pubcid from here to emulate the OLD module & cause the failover code to kick in 'tdid': '6666' }; - const request = spec.buildRequests(bidRequests, validBidderRequest); + const request = spec.buildRequests(bidRequests, validBidderRequest.bidderRequest); const payload = JSON.parse(request.data); expect(payload.ext.ozone.pubcid).to.equal(bidRequests[0]['crumbs']['pubcid']); delete validBidRequests[0].userId; // tidy up now, else it will screw with other tests }); it('should add a user.ext.eids object to contain user ID data in the new location (Nov 2019)', function() { - const request = spec.buildRequests(validBidRequestsWithUserIdData, validBidderRequest); + const request = spec.buildRequests(validBidRequestsWithUserIdData, validBidderRequest.bidderRequest); const payload = JSON.parse(request.data); expect(payload.user).to.exist; expect(payload.user.ext).to.exist; @@ -1096,7 +2178,7 @@ describe('ozone Adapter', function () { spec.getGetParametersAsObject = function() { return {'oztestmode': 'mytestvalue_123'}; }; - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); const data = JSON.parse(request.data); expect(data.imp[0].ext.ozone.customData).to.be.an('array'); expect(data.imp[0].ext.ozone.customData[0].targeting.oztestmode).to.equal('mytestvalue_123'); @@ -1106,7 +2188,7 @@ describe('ozone Adapter', function () { spec.getGetParametersAsObject = function() { return {'oztestmode': 'mytestvalue_123'}; }; - const request = spec.buildRequests(validBidRequestsMinimal, validBidderRequest); + const request = spec.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest); const data = JSON.parse(request.data); expect(data.imp[0].ext.ozone.customData).to.be.an('array'); expect(data.imp[0].ext.ozone.customData[0].targeting.oztestmode).to.equal('mytestvalue_123'); @@ -1117,7 +2199,7 @@ describe('ozone Adapter', function () { specMock.getGetParametersAsObject = function() { return {'ozstoredrequest': '1122334455'}; // 10 digits are valid }; - const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest); + const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest); const data = JSON.parse(request.data); expect(data.ext.ozone.oz_rw).to.equal(1); expect(data.imp[0].ext.prebid.storedrequest.id).to.equal('1122334455'); @@ -1127,7 +2209,7 @@ describe('ozone Adapter', function () { specMock.getGetParametersAsObject = function() { return {'ozstoredrequest': 'BADVAL'}; // 10 digits are valid }; - const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest); + const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest); const data = JSON.parse(request.data); expect(data.ext.ozone.oz_rw).to.equal(0); expect(data.imp[0].ext.prebid.storedrequest.id).to.equal('1310000099'); @@ -1137,9 +2219,9 @@ describe('ozone Adapter', function () { spec.getGetParametersAsObject = function() { return {'oz_lotameid': '123abc', 'oz_lotamepid': 'pid123', 'oz_lotametpid': '123eee'}; }; - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); const payload = JSON.parse(request.data); - expect(payload.imp[0].ext.ozone.lotameData.Profile.Audiences.Audience[0].id).to.equal('123abc'); + expect(payload.ext.ozone.lotameData.Profile.Audiences.Audience[0].id).to.equal('123abc'); expect(payload.ext.ozone.oz_lot_rw).to.equal(1); }); it('should pick up the value of valid lotame override parameters when there is an empty lotame object', function () { @@ -1148,11 +2230,11 @@ describe('ozone Adapter', function () { spec.getGetParametersAsObject = function() { return {'oz_lotameid': '123abc', 'oz_lotamepid': 'pid123', 'oz_lotametpid': '123eeetpid'}; }; - const request = spec.buildRequests(nolotameBidReq, validBidderRequest); + const request = spec.buildRequests(nolotameBidReq, validBidderRequest.bidderRequest); const payload = JSON.parse(request.data); - expect(payload.imp[0].ext.ozone.lotameData.Profile.Audiences.Audience[0].id).to.equal('123abc'); - expect(payload.imp[0].ext.ozone.lotameData.Profile.tpid).to.equal('123eeetpid'); - expect(payload.imp[0].ext.ozone.lotameData.Profile.pid).to.equal('pid123'); + expect(payload.ext.ozone.lotameData.Profile.Audiences.Audience[0].id).to.equal('123abc'); + expect(payload.ext.ozone.lotameData.Profile.tpid).to.equal('123eeetpid'); + expect(payload.ext.ozone.lotameData.Profile.pid).to.equal('pid123'); expect(payload.ext.ozone.oz_lot_rw).to.equal(1); }); it('should pick up the value of valid lotame override parameters when there is NO "lotame" key at all', function () { @@ -1161,27 +2243,29 @@ describe('ozone Adapter', function () { spec.getGetParametersAsObject = function() { return {'oz_lotameid': '123abc', 'oz_lotamepid': 'pid123', 'oz_lotametpid': '123eeetpid'}; }; - const request = spec.buildRequests(nolotameBidReq, validBidderRequest); + const request = spec.buildRequests(nolotameBidReq, validBidderRequest.bidderRequest); const payload = JSON.parse(request.data); - expect(payload.imp[0].ext.ozone.lotameData.Profile.Audiences.Audience[0].id).to.equal('123abc'); - expect(payload.imp[0].ext.ozone.lotameData.Profile.tpid).to.equal('123eeetpid'); - expect(payload.imp[0].ext.ozone.lotameData.Profile.pid).to.equal('pid123'); + expect(payload.ext.ozone.lotameData.Profile.Audiences.Audience[0].id).to.equal('123abc'); + expect(payload.ext.ozone.lotameData.Profile.tpid).to.equal('123eeetpid'); + expect(payload.ext.ozone.lotameData.Profile.pid).to.equal('pid123'); expect(payload.ext.ozone.oz_lot_rw).to.equal(1); + spec.propertyBag = originalPropertyBag; // tidy up }); // NOTE - only one negative test case; // you can't send invalid lotame params to buildRequests because 'validate' will have rejected them it('should not use lotame override parameters if they dont exist', function () { + expect(spec.propertyBag.lotameWasOverridden).to.equal(0); spec.getGetParametersAsObject = function() { return {}; // no lotame override params }; - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); const payload = JSON.parse(request.data); expect(payload.ext.ozone.oz_lot_rw).to.equal(0); }); it('should pick up the config value of coppa & set it in the request', function () { config.setConfig({'coppa': true}); - const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); + const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); const payload = JSON.parse(request.data); expect(payload.regs).to.include.keys('coppa'); expect(payload.regs.coppa).to.equal(1); @@ -1189,22 +2273,75 @@ describe('ozone Adapter', function () { }); it('should pick up the config value of coppa & only set it in the request if its true', function () { config.setConfig({'coppa': false}); - const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); + const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); const payload = JSON.parse(request.data); expect(utils.deepAccess(payload, 'regs.coppa')).to.be.undefined; config.resetConfig(); }); + it('should handle oz_omp_floor correctly', function () { + config.setConfig({'ozone': {'oz_omp_floor': 1.56}}); + const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); + const payload = JSON.parse(request.data); + expect(utils.deepAccess(payload, 'ext.ozone.oz_omp_floor')).to.equal(1.56); + config.resetConfig(); + }); + it('should ignore invalid oz_omp_floor values', function () { + config.setConfig({'ozone': {'oz_omp_floor': '1.56'}}); + const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); + const payload = JSON.parse(request.data); + expect(utils.deepAccess(payload, 'ext.ozone.oz_omp_floor')).to.be.undefined; + config.resetConfig(); + }); + it('should should contain a unique page view id in the auction request which persists across calls', function () { + let request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + let payload = JSON.parse(request.data); + expect(utils.deepAccess(payload, 'ext.ozone.pv')).to.be.a('string'); + request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest.bidderRequest); + let payload2 = JSON.parse(request.data); + expect(utils.deepAccess(payload2, 'ext.ozone.pv')).to.be.a('string'); + expect(utils.deepAccess(payload2, 'ext.ozone.pv')).to.equal(utils.deepAccess(payload, 'ext.ozone.pv')); + }); + it('should indicate that the whitelist was used when it contains valid data', function () { + config.setConfig({'ozone': {'oz_whitelist_adserver_keys': ['oz_ozappnexus_pb', 'oz_ozappnexus_imp_id']}}); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.ext.ozone.oz_kvp_rw).to.equal(1); + config.resetConfig(); + }); + it('should indicate that the whitelist was not used when it contains no data', function () { + config.setConfig({'ozone': {'oz_whitelist_adserver_keys': []}}); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.ext.ozone.oz_kvp_rw).to.equal(0); + config.resetConfig(); + }); + it('should indicate that the whitelist was not used when it is not set in the config', function () { + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.ext.ozone.oz_kvp_rw).to.equal(0); + }); + it('should have openrtb video params', function() { + let allowed = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin', 'skipafter', 'sequence', 'battr', 'maxextended', 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', 'pos', 'companionad', 'api', 'companiontype', 'ext']; + const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest.bidderRequest); + const payload = JSON.parse(request.data); + const vid = (payload.imp[0].video); + const keys = Object.keys(vid); + for (let i = 0; i < keys.length; i++) { + expect(allowed).to.include(keys[i]); + } + expect(payload.imp[0].video.ext).to.include({'context': 'outstream'}); + }); }); describe('interpretResponse', function () { it('should build bid array', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); const result = spec.interpretResponse(validResponse, request); expect(result.length).to.equal(1); }); it('should have all relevant fields', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); const result = spec.interpretResponse(validResponse, request); const bid = result[0]; expect(bid.cpm).to.equal(validResponse.body.seatbid[0].bid[0].cpm); @@ -1213,16 +2350,15 @@ describe('ozone Adapter', function () { }); it('should build bid array with gdpr', function () { - let validBR = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); + let validBR = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr.bidderRequest)); validBR.gdprConsent = {'gdprApplies': 1, 'consentString': 'This is the gdpr consent string'}; const request = spec.buildRequests(validBidRequests, validBR); // works the old way, with GDPR not enforced by default - // const request = spec.buildRequests(validBidRequests, bidderRequestWithFullGdpr); // works with oz_enforceGdpr true by default const result = spec.interpretResponse(validResponse, request); expect(result.length).to.equal(1); }); it('should build bid array with only partial gdpr', function () { - var validBidderRequestWithGdpr = bidderRequestWithPartialGdpr; + var validBidderRequestWithGdpr = bidderRequestWithPartialGdpr.bidderRequest; validBidderRequestWithGdpr.gdprConsent = {'gdprApplies': 1, 'consentString': 'This is the gdpr consent string'}; const request = spec.buildRequests(validBidRequests, validBidderRequestWithGdpr); }); @@ -1239,24 +2375,164 @@ describe('ozone Adapter', function () { expect(result).to.be.empty; }); - it('should have video renderer', function () { - const request = spec.buildRequests(validBidRequestsWithNonBannerMediaTypesAndValidOutstreamVideo, validBidderRequest); - const result = spec.interpretResponse(validOutstreamResponse, request); + it('should have video renderer for outstream video', function () { + const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest1OutstreamVideo2020.bidderRequest); + const result = spec.interpretResponse(getCleanValidVideoResponse(), validBidderRequest1OutstreamVideo2020); const bid = result[0]; expect(bid.renderer).to.be.an.instanceOf(Renderer); }); + it('should have NO video renderer for instream video', function () { + let instreamRequestsObj = JSON.parse(JSON.stringify(validBidRequests1OutstreamVideo2020)); + instreamRequestsObj[0].mediaTypes.video.context = 'instream'; + let instreamBidderReq = JSON.parse(JSON.stringify(validBidderRequest1OutstreamVideo2020)); + instreamBidderReq.bidderRequest.bids[0].mediaTypes.video.context = 'instream'; + const request = spec.buildRequests(instreamRequestsObj, validBidderRequest1OutstreamVideo2020.bidderRequest); + const result = spec.interpretResponse(getCleanValidVideoResponse(), instreamBidderReq); + const bid = result[0]; + expect(bid.hasOwnProperty('renderer')).to.be.false; + }); + it('should correctly parse response where there are more bidders than ad slots', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); const result = spec.interpretResponse(validBidResponse1adWith2Bidders, request); expect(result.length).to.equal(2); }); it('should have a ttl of 600', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); const result = spec.interpretResponse(validResponse, request); expect(result[0].ttl).to.equal(300); }); + + it('should handle oz_omp_floor_dollars correctly, inserting 1 as necessary', function () { + config.setConfig({'ozone': {'oz_omp_floor': 0.01}}); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + const result = spec.interpretResponse(validResponse, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_omp')).to.equal('1'); + config.resetConfig(); + }); + it('should handle oz_omp_floor_dollars correctly, inserting 0 as necessary', function () { + config.setConfig({'ozone': {'oz_omp_floor': 2.50}}); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + const result = spec.interpretResponse(validResponse, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_omp')).to.equal('0'); + config.resetConfig(); + }); + it('should handle missing oz_omp_floor_dollars correctly, inserting nothing', function () { + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + const result = spec.interpretResponse(validResponse, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_omp')).to.be.undefined; + }); + it('should handle ext.bidder.ozone.floor correctly, setting flr & rid as necessary', function () { + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + let vres = JSON.parse(JSON.stringify(validResponse)); + vres.body.seatbid[0].bid[0].ext.bidder.ozone = {floor: 1, ruleId: 'ZjbsYE1q'}; + const result = spec.interpretResponse(vres, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr')).to.equal(1); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid')).to.equal('ZjbsYE1q'); + config.resetConfig(); + }); + it('should handle ext.bidder.ozone.floor correctly, inserting 0 as necessary', function () { + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + let vres = JSON.parse(JSON.stringify(validResponse)); + vres.body.seatbid[0].bid[0].ext.bidder.ozone = {floor: 0, ruleId: 'ZjbXXE1q'}; + const result = spec.interpretResponse(vres, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr')).to.equal(0); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid')).to.equal('ZjbXXE1q'); + config.resetConfig(); + }); + it('should handle ext.bidder.ozone.floor correctly, inserting nothing as necessary', function () { + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + let vres = JSON.parse(JSON.stringify(validResponse)); + vres.body.seatbid[0].bid[0].ext.bidder.ozone = {}; + const result = spec.interpretResponse(vres, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr', null)).to.equal(null); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid', null)).to.equal(null); + config.resetConfig(); + }); + it('should handle ext.bidder.ozone.floor correctly, when bidder.ozone is not there', function () { + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + let vres = JSON.parse(JSON.stringify(validResponse)); + const result = spec.interpretResponse(vres, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr', null)).to.equal(null); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid', null)).to.equal(null); + config.resetConfig(); + }); + it('should handle a valid whitelist, removing items not on the list & leaving others', function () { + config.setConfig({'ozone': {'oz_whitelist_adserver_keys': ['oz_appnexus_crid', 'oz_appnexus_adId']}}); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + const result = spec.interpretResponse(validResponse, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adv')).to.be.undefined; + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adId')).to.equal('2899ec066a91ff8-0-0'); + config.resetConfig(); + }); + it('should ignore a whitelist if enhancedAdserverTargeting is false', function () { + config.setConfig({'ozone': {'oz_whitelist_adserver_keys': ['oz_appnexus_crid', 'oz_appnexus_imp_id'], 'enhancedAdserverTargeting': false}}); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + const result = spec.interpretResponse(validResponse, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adv')).to.be.undefined; + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_imp_id')).to.be.undefined; + config.resetConfig(); + }); + it('should correctly handle enhancedAdserverTargeting being false', function () { + config.setConfig({'ozone': {'enhancedAdserverTargeting': false}}); + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + const result = spec.interpretResponse(validResponse, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adv')).to.be.undefined; + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_imp_id')).to.be.undefined; + config.resetConfig(); + }); + it('should add flr into ads request if floor exists in the auction response', function () { + const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest.bidderRequest); + let validres = JSON.parse(JSON.stringify(validResponse2Bids)); + validres.body.seatbid[0].bid[0].ext.bidder.ozone = {'floor': 1}; + const result = spec.interpretResponse(validres, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr')).to.equal(1); + expect(utils.deepAccess(result[1].adserverTargeting, 'oz_appnexus_flr', '')).to.equal(''); + }); + it('should add rid into ads request if ruleId exists in the auction response', function () { + const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest.bidderRequest); + let validres = JSON.parse(JSON.stringify(validResponse2Bids)); + validres.body.seatbid[0].bid[0].ext.bidder.ozone = {'ruleId': 123}; + const result = spec.interpretResponse(validres, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid')).to.equal(123); + expect(utils.deepAccess(result[1].adserverTargeting, 'oz_appnexus_rid', '')).to.equal(''); + }); + it('should add oz_ozappnexus_sid (cid value) for all appnexus bids', function () { + const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest.bidderRequest); + let validres = JSON.parse(JSON.stringify(validResponse2BidsSameAdunit)); + const result = spec.interpretResponse(validres, request); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_ozappnexus_sid')).to.equal(result[0].cid); + }); + it('should add unique adId values to each bid', function() { + const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); + let validres = JSON.parse(JSON.stringify(validResponse2BidsSameAdunit)); + const result = spec.interpretResponse(validres, request); + expect(result.length).to.equal(1); + expect(result[0]['price']).to.equal(0.9); + expect(result[0]['adserverTargeting']['oz_ozappnexus_adId']).to.equal('2899ec066a91ff8-0-1'); + }); + it('should correctly process an auction with 2 adunits & multiple bidders one of which bids for both adslots', function() { + let validres = JSON.parse(JSON.stringify(multiResponse1)); + let request = spec.buildRequests(multiRequest1, multiBidderRequest1.bidderRequest); + let result = spec.interpretResponse(validres, request); + expect(result.length).to.equal(4); // one of the 5 bids will have been removed + expect(result[1]['price']).to.equal(0.521); + expect(result[1]['impid']).to.equal('3025f169863b7f8'); + expect(result[1]['id']).to.equal('18552976939844999'); + expect(result[1]['adserverTargeting']['oz_ozappnexus_adId']).to.equal('3025f169863b7f8-0-2'); + // change the bid values so a different second bid for an impid by the same bidder gets dropped + validres = JSON.parse(JSON.stringify(multiResponse1)); + validres.body.seatbid[0].bid[1].price = 1.1; + validres.body.seatbid[0].bid[1].cpm = 1.1; + request = spec.buildRequests(multiRequest1, multiBidderRequest1.bidderRequest); + result = spec.interpretResponse(validres, request); + expect(result[1]['price']).to.equal(1.1); + expect(result[1]['impid']).to.equal('3025f169863b7f8'); + expect(result[1]['id']).to.equal('18552976939844681'); + expect(result[1]['adserverTargeting']['oz_ozappnexus_adId']).to.equal('3025f169863b7f8-0-1'); + }); }); describe('userSyncs', function () { @@ -1270,7 +2546,7 @@ describe('ozone Adapter', function () { }); it('should append the various values if they exist', function() { // get the cookie bag populated - spec.buildRequests(validBidRequests, validBidderRequest); + spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', gdpr1); expect(result).to.be.an('array'); expect(result[0].url).to.include('publisherId=9876abcd12-3'); @@ -1383,83 +2659,7 @@ describe('ozone Adapter', function () { expect(result).to.be.false; config.resetConfig(); }); - it('should return true if oz_enforceGdpr is true and consentString is undefined', function() { - config.setConfig({'ozone': {'oz_enforceGdpr': true}}); - let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); - delete req.gdprConsent.consentString; - let result = spec.blockTheRequest(req); - expect(result).to.be.true; - config.resetConfig(); - }); - it('should return false if oz_enforceGdpr is false and consentString is undefined', function() { - config.setConfig({'ozone': {'oz_enforceGdpr': false}}); - let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); - delete req.gdprConsent.consentString; - let result = spec.blockTheRequest(req); - expect(result).to.be.false; - config.resetConfig(); - }); - it('should return false if oz_enforceGdpr is NOT SET (default) and consentString is undefined', function() { - let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); - delete req.gdprConsent.consentString; - let result = spec.blockTheRequest(req); - expect(result).to.be.false; - }); - it('should return false if gdprApplies is false', function() { - config.setConfig({'ozone': {'oz_request': true}}); - let req = {'gdprConsent': {'gdprApplies': false}}; - let result = spec.blockTheRequest(req); - expect(result).to.be.false; - config.resetConfig(); - }); - it('should return false if gdprConsent key does not exist', function() { - let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); - config.setConfig({'ozone': {'oz_enforceGdpr': true}}); - delete req.gdprConsent; - let result = spec.blockTheRequest(req); - expect(result).to.be.false; - config.resetConfig(); - }); - it('should return false if gdpr is set, and all is ok', function() { - let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); - config.setConfig({'ozone': {'oz_enforceGdpr': true}}); - let result = spec.blockTheRequest(req); - expect(result).to.be.false; - config.resetConfig(); - }); - }); - - describe('failsGdprCheck', function() { - it('should return false for a a fully accepted user', function () { - let result = spec.failsGdprCheck(bidderRequestWithFullGdpr); - expect(result).to.be.false; - }); - it('should return false if gdprConsent is not present on the bidder object', function () { - let result = spec.failsGdprCheck(validBidderRequest); - expect(result).to.be.false; - }); - it('should return true if gdpr applies and vendorData is not an array', function () { - let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); - req.gdprConsent.vendorData = null; - let result = spec.failsGdprCheck(req); - expect(result).to.be.true; - }); - it('should return true if gdpr applies and purposeConsents do not contain all the required true values', function () { - let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); - req.gdprConsent.vendorData.purposeConsents[1] = false; - let result = spec.failsGdprCheck(req); - expect(result).to.be.true; - }); - it('should return true if gdpr applies and vendorConsents[524] is not true', function () { - config.setConfig({'ozone': {'oz_enforceGdpr': true}}); - let req = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); - req.gdprConsent.vendorData.vendorConsents[524] = false; - let result = spec.failsGdprCheck(req); - expect(result).to.be.true; - config.resetConfig(); - }); }); - describe('makeLotameObjectFromOverride', function() { it('should update an object with valid lotame data', function () { let objLotameOverride = {'oz_lotametpid': '1234', 'oz_lotameid': '12345', 'oz_lotamepid': '123456'}; @@ -1498,4 +2698,125 @@ describe('ozone Adapter', function () { expect(result).to.be.false; }); }); + describe('getPageId', function() { + it('should return the same Page ID for multiple calls', function () { + let result = spec.getPageId(); + expect(result).to.be.a('string'); + let result2 = spec.getPageId(); + expect(result2).to.equal(result); + }); + }); + describe('getBidRequestForBidId', function() { + it('should locate a bid inside a bid array', function () { + let result = spec.getBidRequestForBidId('2899ec066a91ff8', validBidRequestsMulti); + expect(result.testId).to.equal(1); + result = spec.getBidRequestForBidId('2899ec066a91ff0', validBidRequestsMulti); + expect(result.testId).to.equal(2); + }); + }); + describe('getVideoContextForBidId', function() { + it('should locate the video context inside a bid', function () { + let result = spec.getVideoContextForBidId('2899ec066a91ff8', validBidRequestsWithNonBannerMediaTypesAndValidOutstreamVideo); + expect(result).to.equal('outstream'); + }); + }); + describe('getLotameOverrideParams', function() { + it('should get 3 valid lotame params that exist in GET params', function () { + // mock the getGetParametersAsObject function to simulate GET parameters for lotame overrides: + spec.getGetParametersAsObject = function() { + return {'oz_lotameid': '123abc', 'oz_lotamepid': 'pid123', 'oz_lotametpid': 'tpid123'}; + }; + let result = spec.getLotameOverrideParams(); + expect(Object.keys(result).length).to.equal(3); + }); + it('should get only 1 valid lotame param that exists in GET params', function () { + // mock the getGetParametersAsObject function to simulate GET parameters for lotame overrides: + spec.getGetParametersAsObject = function() { + return {'oz_lotameid': '123abc', 'xoz_lotamepid': 'pid123', 'xoz_lotametpid': 'tpid123'}; + }; + let result = spec.getLotameOverrideParams(); + expect(Object.keys(result).length).to.equal(1); + }); + }); + describe('unpackVideoConfigIntoIABformat', function() { + it('should correctly unpack a usual video config', function () { + let mediaTypes = { + playerSize: [640, 480], + mimes: ['video/mp4'], + context: 'outstream', + testKey: 'parent value' + }; + let bid_params_video = { + skippable: true, + playback_method: ['auto_play_sound_off'], + playbackmethod: 2, /* start on load, no sound */ + minduration: 5, + maxduration: 60, + skipmin: 5, + skipafter: 5, + testKey: 'child value' + }; + let result = spec.unpackVideoConfigIntoIABformat(mediaTypes, bid_params_video); + expect(result.mimes).to.be.an('array').that.includes('video/mp4'); + expect(result.ext.context).to.equal('outstream'); + expect(result.ext.skippable).to.be.true; // note - we add skip in a different step: addVideoDefaults + expect(result.ext.testKey).to.equal('child value'); + }); + }); + describe('addVideoDefaults', function() { + it('should correctly add video defaults', function () { + let mediaTypes = { + playerSize: [640, 480], + mimes: ['video/mp4'], + context: 'outstream', + }; + let bid_params_video = { + skippable: true, + playback_method: ['auto_play_sound_off'], + playbackmethod: 2, /* start on load, no sound */ + minduration: 5, + maxduration: 60, + skipmin: 5, + skipafter: 5, + testKey: 'child value' + }; + let result = spec.addVideoDefaults({}, mediaTypes, mediaTypes); + expect(result.placement).to.equal(3); + expect(result.skip).to.equal(0); + result = spec.addVideoDefaults({}, mediaTypes, bid_params_video); + expect(result.skip).to.equal(1); + }); + it('should correctly add video defaults including skippable in parent', function () { + let mediaTypes = { + playerSize: [640, 480], + mimes: ['video/mp4'], + context: 'outstream', + skippable: true + }; + let bid_params_video = { + playback_method: ['auto_play_sound_off'], + playbackmethod: 2, /* start on load, no sound */ + minduration: 5, + maxduration: 60, + skipmin: 5, + skipafter: 5, + testKey: 'child value' + }; + let result = spec.addVideoDefaults({}, mediaTypes, bid_params_video); + expect(result.placement).to.equal(3); + expect(result.skip).to.equal(1); + }); + }); + describe('removeSingleBidderMultipleBids', function() { + it('should remove the multi bid by ozappnexus for adslot 2d30e86db743a8', function() { + let validres = JSON.parse(JSON.stringify(multiResponse1)); + expect(validres.body.seatbid[0].bid.length).to.equal(3); + expect(validres.body.seatbid[0].seat).to.equal('ozappnexus'); + let response = spec.removeSingleBidderMultipleBids(validres.body.seatbid); + expect(response.length).to.equal(2); + expect(response[0].bid.length).to.equal(2); + expect(response[0].seat).to.equal('ozappnexus'); + expect(response[1].bid.length).to.equal(2); + }); + }); }); From 1ea0d26b761be239fa9a73f4b7dfd29660f62865 Mon Sep 17 00:00:00 2001 From: relaido <63339139+relaido@users.noreply.github.com> Date: Fri, 10 Jul 2020 00:30:52 +0900 Subject: [PATCH 474/496] Change endpoint (#5459) * add relaido adapter * remove event listener * fixed UserSyncs and e.data * fix conflicts * change endpoint url Co-authored-by: ishigami_shingo --- modules/relaidoBidAdapter.js | 2 +- test/spec/modules/relaidoBidAdapter_spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/relaidoBidAdapter.js b/modules/relaidoBidAdapter.js index a2c97495a7e..b3b8a647137 100644 --- a/modules/relaidoBidAdapter.js +++ b/modules/relaidoBidAdapter.js @@ -45,7 +45,7 @@ function buildRequests(validBidRequests, bidderRequest) { const bidRequest = validBidRequests[i]; const placementId = utils.getBidIdParameter('placementId', bidRequest.params); const bidDomain = bidRequest.params.domain || BIDDER_DOMAIN; - const bidUrl = `https://${bidDomain}/vast/v1/out/bid/${placementId}`; + const bidUrl = `https://${bidDomain}/bid/v1/prebid/${placementId}`; const uuid = getUuid(); const mediaType = getMediaType(bidRequest); diff --git a/test/spec/modules/relaidoBidAdapter_spec.js b/test/spec/modules/relaidoBidAdapter_spec.js index 492f7d2ca08..cd4918460db 100644 --- a/test/spec/modules/relaidoBidAdapter_spec.js +++ b/test/spec/modules/relaidoBidAdapter_spec.js @@ -136,7 +136,7 @@ describe('RelaidoAdapter', function () { expect(bidRequests).to.have.lengthOf(1); const request = bidRequests[0]; expect(request.method).to.equal('GET'); - expect(request.url).to.equal('https://api.relaido.jp/vast/v1/out/bid/100000'); + expect(request.url).to.equal('https://api.relaido.jp/bid/v1/prebid/100000'); expect(request.bidId).to.equal(bidRequest.bidId); expect(request.width).to.equal(bidRequest.mediaTypes.video.playerSize[0][0]); expect(request.height).to.equal(bidRequest.mediaTypes.video.playerSize[0][1]); From 8f17bb51e444197133d3b645827adfb280c9b43f Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 9 Jul 2020 15:14:33 -0400 Subject: [PATCH 475/496] Add lotame id system (#5388) * Add a LotameIdSystem as a new User ID module * Now using our own caching system * Add more test cases; Switch names to be constants * Add test cases * Handle "expiring" local storage like the built in code does * Switch to using the expiry_ms from the endpoint as the cookie expiration * Update to the official naming; Remove the lastUpdate storage as we don't use it and depend on what comes from the endpoint; Update to use the dev bcp endpoint for now * Fix tests, numbers vs strings....; Add gdpr_applies query param * Fix the timestamp becoming an invalid date * Clear out the panorama id when on optout * Add eid support * Switch to the prod version of the url * Update test wording * From PR feedback Only care about the core_id if a profile_id is also returned so it won't look like we can store a core_id and then promptly delete it Return just the core_id from getId() * Add eid test for lotamePanoramaId --- integrationExamples/gpt/userId_example.html | 9 +- modules/.submodules.json | 1 + modules/lotamePanoramaIdSystem.js | 244 ++++++++++ modules/lotamePanoramaIdSystem.md | 25 + modules/userId/eids.js | 6 + test/spec/modules/eids_spec.js | 12 + .../modules/lotamePanoramaIdSystem_spec.js | 449 ++++++++++++++++++ 7 files changed, 744 insertions(+), 2 deletions(-) create mode 100644 modules/lotamePanoramaIdSystem.js create mode 100644 modules/lotamePanoramaIdSystem.md create mode 100644 test/spec/modules/lotamePanoramaIdSystem_spec.js diff --git a/integrationExamples/gpt/userId_example.html b/integrationExamples/gpt/userId_example.html index 53c58e8e87e..69e2c713fb8 100644 --- a/integrationExamples/gpt/userId_example.html +++ b/integrationExamples/gpt/userId_example.html @@ -179,7 +179,8 @@ name: 'idl_env', expires: 30 } - }, { + }, + { name: "sharedId", params: { syncTime: 60 // in seconds, default is 24 hours @@ -189,7 +190,11 @@ name: "sharedid", expires: 28 } - }, { + }, + { + name: 'lotamePanoramaId' + }, + { name: "liveIntentId", params: { publisherId: "9896876" diff --git a/modules/.submodules.json b/modules/.submodules.json index 25ae3c3884b..ba8af4e6550 100644 --- a/modules/.submodules.json +++ b/modules/.submodules.json @@ -7,6 +7,7 @@ "parrableIdSystem", "britepoolIdSystem", "liveIntentIdSystem", + "lotamePanoramaId", "criteoIdSystem", "netIdSystem", "identityLinkIdSystem", diff --git a/modules/lotamePanoramaIdSystem.js b/modules/lotamePanoramaIdSystem.js new file mode 100644 index 00000000000..cdf9131dd68 --- /dev/null +++ b/modules/lotamePanoramaIdSystem.js @@ -0,0 +1,244 @@ +/** + * This module adds LotamePanoramaId to the User ID module + * The {@link module:modules/userId} module is required + * @module modules/lotamePanoramaId + * @requires module:modules/userId + */ +import * as utils from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { submodule } from '../src/hook.js'; +import { getStorageManager } from '../src/storageManager.js'; + +const KEY_ID = 'panoramaId'; +const KEY_EXPIRY = `${KEY_ID}_expiry`; +const KEY_PROFILE = '_cc_id'; +const MODULE_NAME = 'lotamePanoramaId'; +const NINE_MONTHS_MS = 23328000 * 1000; +const DAYS_TO_CACHE = 7; +const DAY_MS = 60 * 60 * 24 * 1000; + +export const storage = getStorageManager(null, MODULE_NAME); + +/** + * Set the Lotame First Party Profile ID in the first party namespace + * @param {String} profileId + */ +function setProfileId(profileId) { + if (storage.cookiesAreEnabled()) { + let expirationDate = new Date(utils.timestamp() + NINE_MONTHS_MS).toUTCString(); + storage.setCookie(KEY_PROFILE, profileId, expirationDate, 'Lax', undefined, undefined); + } + if (storage.hasLocalStorage()) { + storage.setDataInLocalStorage(KEY_PROFILE, profileId, undefined); + } +} + +/** + * Get the Lotame profile id by checking cookies first and then local storage + */ +function getProfileId() { + if (storage.cookiesAreEnabled()) { + return storage.getCookie(KEY_PROFILE, undefined); + } + if (storage.hasLocalStorage()) { + return storage.getDataFromLocalStorage(KEY_PROFILE, undefined); + } +} + +/** + * Get a value from browser storage by checking cookies first and then local storage + * @param {String} key + */ +function getFromStorage(key) { + let value = null; + if (storage.cookiesAreEnabled()) { + value = storage.getCookie(key, undefined); + } + if (storage.hasLocalStorage() && value === null) { + const storedValueExp = storage.getDataFromLocalStorage( + `${key}_exp`, undefined + ); + if (storedValueExp === '') { + value = storage.getDataFromLocalStorage(key, undefined); + } else if (storedValueExp) { + if ((new Date(storedValueExp)).getTime() - Date.now() > 0) { + value = storage.getDataFromLocalStorage(key, undefined); + } + } + } + return value; +} + +/** + * Save a key/value pair to the browser cache (cookies and local storage) + * @param {String} key + * @param {String} value + * @param {Number} expirationTimestamp + */ +function saveLotameCache( + key, + value, + expirationTimestamp = utils.timestamp() + DAYS_TO_CACHE * DAY_MS +) { + if (key && value) { + let expirationDate = new Date(expirationTimestamp).toUTCString(); + if (storage.cookiesAreEnabled()) { + storage.setCookie( + key, + value, + expirationDate, + 'Lax', + undefined, + undefined + ); + } + if (storage.hasLocalStorage()) { + storage.setDataInLocalStorage( + `${key}_exp`, + String(expirationTimestamp), + undefined + ); + storage.setDataInLocalStorage(key, value, undefined); + } + } +} + +/** + * Retrieve all the cached values from cookies and/or local storage + */ +function getLotameLocalCache() { + let cache = { + data: getFromStorage(KEY_ID), + expiryTimestampMs: 0, + }; + + try { + const rawExpiry = getFromStorage(KEY_EXPIRY); + if (utils.isStr(rawExpiry)) { + cache.expiryTimestampMs = parseInt(rawExpiry, 0); + } + } catch (error) { + utils.logError(error); + } + + return cache; +} + +/** + * Clear a cached value from cookies and local storage + * @param {String} key + */ +function clearLotameCache(key) { + if (key) { + if (storage.cookiesAreEnabled()) { + let expirationDate = new Date(0).toUTCString(); + storage.setCookie(key, '', expirationDate, 'Lax', undefined, undefined); + } + if (storage.hasLocalStorage()) { + storage.removeDataFromLocalStorage(key, undefined); + } + } +} +/** @type {Submodule} */ +export const lotamePanoramaIdSubmodule = { + + /** + * used to link submodule with config + * @type {string} + */ + name: MODULE_NAME, + + /** + * Decode the stored id value for passing to bid requests + * @function decode + * @param {(Object|string)} value + * @returns {(Object|undefined)} + */ + decode(value, configParams) { + return utils.isStr(value) ? { 'lotamePanoramaId': value } : undefined; + }, + + /** + * Retrieve the Lotame Panorama Id + * @function + * @param {SubmoduleParams} [configParams] + * @param {ConsentData} [consentData] + * @param {(Object|undefined)} cacheIdObj + * @returns {IdResponse|undefined} + */ + getId(configParams, consentData, cacheIdObj) { + let localCache = getLotameLocalCache(); + + let refreshNeeded = Date.now() > localCache.expiryTimestampMs; + + if (!refreshNeeded) { + return { + id: localCache.data + }; + } + + const storedUserId = getProfileId(); + + const resolveIdFunction = function (callback) { + let queryParams = {}; + if (storedUserId) { + queryParams.fp = storedUserId + } + + if (consentData && utils.isBoolean(consentData.gdprApplies)) { + queryParams.gdpr_applies = consentData.gdprApplies; + if (consentData.gdprApplies) { + queryParams.gdpr_consent = consentData.consentString; + } + } + const url = utils.buildUrl({ + protocol: 'https', + host: `id.crwdcntrl.net`, + pathname: '/id', + search: utils.isEmpty(queryParams) ? undefined : queryParams, + }); + ajax( + url, + (response) => { + let coreId; + if (response) { + try { + let responseObj = JSON.parse(response); + saveLotameCache(KEY_EXPIRY, responseObj.expiry_ts); + + if (utils.isStr(responseObj.profile_id)) { + setProfileId(responseObj.profile_id); + + if (utils.isStr(responseObj.core_id)) { + saveLotameCache( + KEY_ID, + responseObj.core_id, + responseObj.expiry_ts + ); + coreId = responseObj.core_id; + } else { + clearLotameCache(KEY_ID); + } + } else { + clearLotameCache(KEY_PROFILE); + clearLotameCache(KEY_ID); + } + } catch (error) { + utils.logError(error); + } + } + callback(coreId); + }, + undefined, + { + method: 'GET', + withCredentials: true + } + ); + }; + + return { callback: resolveIdFunction }; + }, +}; + +submodule('userId', lotamePanoramaIdSubmodule); diff --git a/modules/lotamePanoramaIdSystem.md b/modules/lotamePanoramaIdSystem.md new file mode 100644 index 00000000000..e960f4b5695 --- /dev/null +++ b/modules/lotamePanoramaIdSystem.md @@ -0,0 +1,25 @@ +# Overview + +``` +Module Name: Lotame Panorama Id System +Module Type: Id System +Maintainer: prebid@lotame.com +``` + +# Description + +Retrieve the Lotame Panorama Id + +# Usage + +``` + pbjs.que.push(function() { + pbjs.setConfig({ + usersync: { + userIds: [ + { + name: 'lotamePanoramaId' // The only parameter that is needed + }], + } + }); +``` \ No newline at end of file diff --git a/modules/userId/eids.js b/modules/userId/eids.js index 842737183a8..1261e2ea7d9 100644 --- a/modules/userId/eids.js +++ b/modules/userId/eids.js @@ -62,6 +62,12 @@ const USER_IDS_CONFIG = { atype: 1 }, + // lotamePanoramaId + lotamePanoramaId: { + source: 'crwdcntrl.net', + atype: 1, + }, + // DigiTrust 'digitrustid': { getValue: function (data) { diff --git a/test/spec/modules/eids_spec.js b/test/spec/modules/eids_spec.js index 160277204df..1cbc2911ef5 100644 --- a/test/spec/modules/eids_spec.js +++ b/test/spec/modules/eids_spec.js @@ -107,6 +107,18 @@ describe('eids array generation for known sub-modules', function() { }); }); + it('lotamePanoramaId', function () { + const userId = { + lotamePanoramaId: 'some-random-id-value', + }; + const newEids = createEidsArray(userId); + expect(newEids.length).to.equal(1); + expect(newEids[0]).to.deep.equal({ + source: 'crwdcntrl.net', + uids: [{ id: 'some-random-id-value', atype: 1 }], + }); + }); + it('DigiTrust; getValue call', function() { const userId = { digitrustid: { diff --git a/test/spec/modules/lotamePanoramaIdSystem_spec.js b/test/spec/modules/lotamePanoramaIdSystem_spec.js new file mode 100644 index 00000000000..c6d3383374a --- /dev/null +++ b/test/spec/modules/lotamePanoramaIdSystem_spec.js @@ -0,0 +1,449 @@ +import { + lotamePanoramaIdSubmodule, + storage, +} from 'modules/lotamePanoramaIdSystem.js'; +import * as utils from 'src/utils.js'; +import { server } from 'test/mocks/xhr.js'; + +const responseHeader = { 'Content-Type': 'application/json' }; + +describe('LotameId', function() { + let logErrorStub; + let getCookieStub; + let setCookieStub; + let getLocalStorageStub; + let setLocalStorageStub; + let removeFromLocalStorageStub; + let timeStampStub; + + const nowTimestamp = new Date().getTime(); + + beforeEach(function () { + logErrorStub = sinon.stub(utils, 'logError'); + getCookieStub = sinon.stub(storage, 'getCookie'); + setCookieStub = sinon.stub(storage, 'setCookie'); + getLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); + setLocalStorageStub = sinon.stub(storage, 'setDataInLocalStorage'); + removeFromLocalStorageStub = sinon.stub( + storage, + 'removeDataFromLocalStorage' + ); + timeStampStub = sinon.stub(utils, 'timestamp').returns(nowTimestamp); + }); + + afterEach(function () { + logErrorStub.restore(); + getCookieStub.restore(); + setCookieStub.restore(); + getLocalStorageStub.restore(); + setLocalStorageStub.restore(); + removeFromLocalStorageStub.restore(); + timeStampStub.restore(); + }); + + describe('caching initial data received from the remote server', function () { + let request; + let callBackSpy = sinon.spy(); + + beforeEach(function() { + let submoduleCallback = lotamePanoramaIdSubmodule.getId({}).callback; + submoduleCallback(callBackSpy); + + request = server.requests[0]; + + request.respond( + 200, + responseHeader, + JSON.stringify({ + profile_id: '4ec137245858469eb94a4e248f238694', + expiry_ts: 10, + core_id: + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87a', + }) + ); + }); + + it('should call the remote server when getId is called', function () { + expect(request.url).to.be.eq('https://id.crwdcntrl.net/id'); + + expect(callBackSpy.calledOnce).to.be.true; + }); + + it('should save the first party id', function () { + sinon.assert.calledWith( + setLocalStorageStub, + '_cc_id', + '4ec137245858469eb94a4e248f238694' + ); + sinon.assert.calledWith( + setCookieStub, + '_cc_id', + '4ec137245858469eb94a4e248f238694' + ); + }); + + it('should save the expiry', function () { + sinon.assert.calledWith( + setLocalStorageStub, + 'panoramaId_expiry', 10); + + sinon.assert.calledWith( + setCookieStub, + 'panoramaId_expiry', 10 + ); + }); + + it('should save the id', function () { + sinon.assert.calledWith( + setLocalStorageStub, + 'panoramaId', + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87a' + ); + + sinon.assert.calledWith( + setCookieStub, + 'panoramaId', + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87a' + ); + }); + }); + + describe('No stored values', function() { + describe('and receives the profile id but no panorama id', function() { + let request; + let callBackSpy = sinon.spy(); + + beforeEach(function() { + let submoduleCallback = lotamePanoramaIdSubmodule.getId({}).callback; + submoduleCallback(callBackSpy); + request = server.requests[0]; + + request.respond( + 200, + responseHeader, + JSON.stringify({ + profile_id: '4ec137245858469eb94a4e248f238694', + expiry_ts: 3800000, + }) + ); + }); + + it('should save the profile id', function() { + sinon.assert.calledWith( + setLocalStorageStub, + '_cc_id', + '4ec137245858469eb94a4e248f238694' + ); + sinon.assert.calledWith( + setCookieStub, + '_cc_id', + '4ec137245858469eb94a4e248f238694' + ); + }); + + it('should save the panorama id expiry', function () { + sinon.assert.calledWith( + setLocalStorageStub, + 'panoramaId_expiry', + 3800000 + ); + + sinon.assert.calledWith(setCookieStub, 'panoramaId_expiry', 3800000); + }); + + it('should NOT save the panorama id', function () { + sinon.assert.neverCalledWith( + setLocalStorageStub, + 'panoramaId', + sinon.match.any + ); + + sinon.assert.calledWith( + removeFromLocalStorageStub, + 'panoramaId' + ); + + sinon.assert.calledWith( + setCookieStub, + 'panoramaId', + '', + 'Thu, 01 Jan 1970 00:00:00 GMT', + 'Lax' + ); + }); + }); + + describe('and receives both the profile id and the panorama id', function () { + let request; + let callBackSpy = sinon.spy(); + + beforeEach(function () { + let submoduleCallback = lotamePanoramaIdSubmodule.getId({}).callback; + submoduleCallback(callBackSpy); + request = server.requests[0]; + + request.respond( + 200, + responseHeader, + JSON.stringify({ + profile_id: '4ec137245858469eb94a4e248f238694', + core_id: + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87b', + expiry_ts: 3600000, + }) + ); + }); + it('should save the profile id', function () { + sinon.assert.calledWith( + setLocalStorageStub, + '_cc_id', + '4ec137245858469eb94a4e248f238694' + ); + sinon.assert.calledWith( + setCookieStub, + '_cc_id', + '4ec137245858469eb94a4e248f238694' + ); + }); + + it('should save the panorama id expiry', function () { + sinon.assert.calledWith( + setLocalStorageStub, + 'panoramaId_expiry', + 3600000 + ); + + sinon.assert.calledWith(setCookieStub, 'panoramaId_expiry', 3600000); + }); + + it('should save the panorama id', function () { + sinon.assert.calledWith( + setLocalStorageStub, + 'panoramaId', + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87b' + ); + + sinon.assert.calledWith( + setCookieStub, + 'panoramaId', + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87b' + ); + }); + }); + }); + + describe('With a panorama id found', function() { + describe('and it is too early to try again', function () { + let submoduleCallback; + + beforeEach(function () { + getCookieStub + .withArgs('panoramaId_expiry') + .returns(String(Date.now() + 100000)); + getCookieStub + .withArgs('panoramaId') + .returns( + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87c' + ); + + submoduleCallback = lotamePanoramaIdSubmodule.getId({}); + }); + + it('should not call the remote server when getId is called', function () { + expect(submoduleCallback).to.be.eql({ + id: 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87c', + }); + }); + }); + + describe('and can try again', function () { + let request; + let callBackSpy = sinon.spy(); + + beforeEach(function () { + getCookieStub.withArgs('panoramaId_expiry').returns('1000'); + getCookieStub + .withArgs('panoramaId') + .returns( + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87d' + ); + + let submoduleCallback = lotamePanoramaIdSubmodule.getId({}).callback; + submoduleCallback(callBackSpy); + + request = server.requests[0]; + + request.respond( + 200, + responseHeader, + JSON.stringify({ + profile_id: '4ec137245858469eb94a4e248f238694', + core_id: + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87d', + expiry_ts: 3600000 + }) + ); + }); + + it('should call the remote server when getId is called', function () { + expect(callBackSpy.calledOnce).to.be.true; + }); + }); + + describe('receives an optout request', function () { + let request; + let callBackSpy = sinon.spy(); + + beforeEach(function () { + getCookieStub.withArgs('panoramaId_expiry').returns('1000'); + getCookieStub + .withArgs('panoramaId') + .returns( + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87d' + ); + + let submoduleCallback = lotamePanoramaIdSubmodule.getId({}).callback; + submoduleCallback(callBackSpy); + + request = server.requests[0]; + + request.respond( + 200, + responseHeader, + JSON.stringify({ + expiry_ts: Date.now() + (30 * 24 * 60 * 60 * 1000), + }) + ); + }); + + it('should call the remote server when getId is called', function () { + expect(callBackSpy.calledOnce).to.be.true; + }); + + it('should clear the panorama id', function () { + sinon.assert.calledWith( + removeFromLocalStorageStub, + 'panoramaId' + ); + + sinon.assert.calledWith( + setCookieStub, + 'panoramaId', + '', + 'Thu, 01 Jan 1970 00:00:00 GMT', + 'Lax' + ); + }); + + it('should clear the profile id', function () { + sinon.assert.calledWith(removeFromLocalStorageStub, '_cc_id'); + + sinon.assert.calledWith( + setCookieStub, + '_cc_id', + '', + 'Thu, 01 Jan 1970 00:00:00 GMT', + 'Lax' + ); + }); + }); + }); + + describe('With no panorama id found', function() { + beforeEach(function() { + getCookieStub.withArgs('panoramaId').returns(null); + getLocalStorageStub.withArgs('panoramaId').returns(null); + }) + describe('and it is too early to try again', function () { + let submoduleCallback; + + beforeEach(function () { + getCookieStub + .withArgs('panoramaId_expiry') + .returns(String(Date.now() + 100000)); + + submoduleCallback = lotamePanoramaIdSubmodule.getId({}); + }); + + it('should not call the remote server when getId is called', function () { + expect(submoduleCallback).to.be.eql({ + id: null + }); + }); + }); + + describe('and can try again', function () { + let request; + let callBackSpy = sinon.spy(); + + beforeEach(function () { + getLocalStorageStub + .withArgs('panoramaId_expiry') + .returns('1000'); + + let submoduleCallback = lotamePanoramaIdSubmodule.getId({}).callback; + submoduleCallback(callBackSpy); + + request = server.requests[0]; + + request.respond( + 200, + responseHeader, + JSON.stringify({ + profile_id: '4ec137245858469eb94a4e248f238694', + core_id: + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87e', + expiry_ts: 3600000 + }) + ); + }); + + it('should call the remote server when getId is called', function () { + expect(callBackSpy.calledOnce).to.be.true; + }); + }); + }); + + describe('when gdpr applies', function () { + let request; + let callBackSpy = sinon.spy(); + + beforeEach(function () { + let submoduleCallback = lotamePanoramaIdSubmodule.getId({}, { + gdprApplies: true, + consentString: 'consentGiven' + }).callback; + submoduleCallback(callBackSpy); + + request = server.requests[0]; + + request.respond( + 200, + responseHeader, + JSON.stringify({ + profile_id: '4ec137245858469eb94a4e248f238694', + core_id: + 'ca22992567e3cd4d116a5899b88a55d0d857a23610db939ae6ac13ba2335d87f', + expiry_ts: 3600000, + }) + ); + }); + + it('should call the remote server when getId is called', function () { + expect(callBackSpy.calledOnce).to.be.true; + }); + + it('should pass the gdpr consent string back', function() { + expect(request.url).to.be.eq( + 'https://id.crwdcntrl.net/id?gdpr_applies=true&gdpr_consent=consentGiven' + ); + }); + }); + + it('should retrieve the id when decode is called', function() { + var id = lotamePanoramaIdSubmodule.decode('1234'); + expect(id).to.be.eql({ + 'lotamePanoramaId': '1234' + }); + }); +}); From 0f706bad95190e908aca4b9ea952e8105d90e31a Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Thu, 9 Jul 2020 16:04:57 -0400 Subject: [PATCH 476/496] Prebid 3.25.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index db35edf3b9d..bcc25d215ec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.25.0-pre", + "version": "3.25.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 656b352d39c7324797c5c191fa176850aef7c1f6 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Thu, 9 Jul 2020 16:18:28 -0400 Subject: [PATCH 477/496] Increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bcc25d215ec..4eb14fc5144 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.25.0", + "version": "3.26.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From a2ec9c23a02ab11cbf3c145e40beb682ee77884b Mon Sep 17 00:00:00 2001 From: Adam Browning <19834421+adam-browning@users.noreply.github.com> Date: Fri, 10 Jul 2020 18:07:51 +0300 Subject: [PATCH 478/496] oneVideo Adapter Support for Global & Bidder Specific Supply Chain Object Module (SAPR-13809) (#5465) * bidData Debug true if .source exists * capture and pass config.schain * changing from config.schain to bid.schain * updated schain unit tests * updated schain unit tests * added schain examples to .md file * backup before merging master * updated schain logic to use bidRequest.schain instead of global schain only * updated schain test to new bidRequest.schain logic * Update package-lock.json * Delete package-lock.json * restoring package.lock * restored package-lock.json --- modules/oneVideoBidAdapter.js | 8 ++ modules/oneVideoBidAdapter.md | 110 +++++++++++++++++-- test/spec/modules/oneVideoBidAdapter_spec.js | 66 +++++++++-- 3 files changed, 168 insertions(+), 16 deletions(-) diff --git a/modules/oneVideoBidAdapter.js b/modules/oneVideoBidAdapter.js index 00f7086e7fb..8ccdd4f9c56 100644 --- a/modules/oneVideoBidAdapter.js +++ b/modules/oneVideoBidAdapter.js @@ -1,5 +1,6 @@ import * as utils from '../src/utils.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; + const BIDDER_CODE = 'oneVideo'; export const spec = { code: 'oneVideo', @@ -258,6 +259,13 @@ function getRequestData(bid, consentData, bidRequest) { if (bid.params.video.hp == 1) { bidData.source.ext.schain.nodes[0].hp = bid.params.video.hp; } + } else if (bid.schain) { + bidData.source = { + ext: { + schain: bid.schain + } + } + bidData.source.ext.schain.nodes[0].rid = bidData.id; } if (bid.params.site && bid.params.site.id) { bidData.site.id = bid.params.site.id diff --git a/modules/oneVideoBidAdapter.md b/modules/oneVideoBidAdapter.md index d50d57a4628..1dbdc473294 100644 --- a/modules/oneVideoBidAdapter.md +++ b/modules/oneVideoBidAdapter.md @@ -5,11 +5,10 @@ **Maintainer**: deepthi.neeladri.sravana@verizonmedia.com # Description - Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to fetch bids. - -# Instream Video adUnit example & parameters +# Integration Examples: +## Instream Video adUnit example & parameters *Note:* The Video SSP ad server will respond with an VAST XML to load into your defined player. ``` var adUnits = [ @@ -34,7 +33,7 @@ Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to position: 1, delivery: [2], playbackmethod: [1,5], - sid: , + sid: YOUR_VSSP_ORG_ID, hp: 1, rewarded: 1, placement: 1, @@ -54,7 +53,7 @@ Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to } ] ``` -# Outstream Video adUnit example & parameters +## Outstream Video adUnit example & parameters *Note:* The Video SSP ad server will load it's own Outstream Renderer (player) as a fallback if no player is defined on the publisher page. The Outstream player will inject into the div id that has an identical adUnit code. ``` var adUnits = [ @@ -79,7 +78,7 @@ Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to position: 1, delivery: [2], playbackmethod: [1,5], - sid: , + sid: YOUR_VSSP_ORG_ID, hp: 1, rewarded: 1, placement: 1, @@ -100,7 +99,7 @@ Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to ] ``` -# S2S / Video: Dynamic Ad Placement (DAP) adUnit example & parameters +## S2S / Video: Dynamic Ad Placement (DAP) adUnit example & parameters *Note:* The Video SSP ad server will respond with HTML embed tag to be injected into an iFrame you create. ``` var adUnits = [ @@ -135,7 +134,7 @@ Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to } ] ``` -# Prebid.js / Banner: Dynamic Ad Placement (DAP) adUnit example & parameters +## Prebid.js / Banner: Dynamic Ad Placement (DAP) adUnit example & parameters *Note:* The Video SSP ad server will respond with HTML embed tag to be injected into an iFrame created by Google Ad Manager (GAM). ``` var adUnits = [ @@ -168,3 +167,98 @@ Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to } ] ``` + +# Supply Chain Object Support +The oneVideoBidAdapter supports 2 methods for passing/creating an schain object. +1. By passing your Video SSP Org ID in the bid.video.params.sid - The adapter will create a new schain object and our ad-server will fill in the data for you. +2. Using the Prebid Supply Chain Object Module - The adapter will capture the schain object +*Note:* You cannot pass both schain object and bid.video.params.sid together. Option 1 will always be the default. + +## Create new schain using bid.video.params.sid +sid = your Video SSP Organization ID. +This is for direct publishers only. +``` +var adUnits = [ + { + code: 'video1', + mediaTypes: { + video: { + context: 'instream', + playerSize: [480, 640] + } + }, + bids: [ + { + bidder: 'oneVideo', + params: { + video: { + playerWidth: 480, + playerHeight: 640, + mimes: ['video/mp4', 'application/javascript'], + protocols: [2,5], + api: [2], + sid: + }, + site: { + id: 1, + page: 'https://verizonmedia.com', + referrer: 'https://verizonmedia.com' + }, + pubId: 'HBExchange' + } + } + ] + } + ] +``` + +## Pass global schain using pbjs.setConfig(SCHAIN_OBJECT) +For both Authorized resellers and direct publishers. +``` +pbjs.setConfig({ + "schain": { + "validation": "strict", + "config": { + "ver": "1.0", + "complete": 1, + "nodes": [{ + "asi": "some-platform.com", + "sid": "111111", + "hp": 1 + }] + } + } +}); + +var adUnits = [ + { + code: 'video1', + mediaTypes: { + video: { + context: 'instream', + playerSize: [480, 640] + } + }, + bids: [ + { + bidder: 'oneVideo', + params: { + video: { + playerWidth: 480, + playerHeight: 640, + mimes: ['video/mp4', 'application/javascript'], + protocols: [2,5], + api: [2], + }, + site: { + id: 1, + page: 'https://verizonmedia.com', + referrer: 'https://verizonmedia.com' + }, + pubId: 'HBExchange' + } + } + ] + } + ] +``` diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js index 26412634200..8d12ada9d32 100644 --- a/test/spec/modules/oneVideoBidAdapter_spec.js +++ b/test/spec/modules/oneVideoBidAdapter_spec.js @@ -238,6 +238,63 @@ describe('OneVideoBidAdapter', function () { expect(data.imp[0].video.w).to.equal(width); expect(data.imp[0].video.h).to.equal(height); }); + + it('it should create new schain and send it if video.params.sid exists', function () { + const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const data = requests[0].data; + const schain = data.source.ext.schain; + expect(schain.nodes.length).to.equal(1); + expect(schain.nodes[0].sid).to.equal(bidRequest.params.video.sid); + expect(schain.nodes[0].rid).to.equal(data.id); + }) + + it('should send Global or Bidder specific schain if sid is not passed in video.params.sid', function () { + bidRequest.params.video.sid = null; + const globalSchain = { + ver: '1.0', + complete: 1, + nodes: [{ + asi: 'some-platform.com', + sid: '111111', + rid: bidRequest.id, + hp: 1 + }] + }; + bidRequest.schain = globalSchain; + const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const data = requests[0].data; + const schain = data.source.ext.schain; + expect(schain.nodes.length).to.equal(1); + expect(schain).to.equal(globalSchain); + }); + + it('should ignore Global or Bidder specific schain if video.params.sid exists and send new schain', function () { + const globalSchain = { + ver: '1.0', + complete: 1, + nodes: [{ + asi: 'some-platform.com', + sid: '111111', + rid: bidRequest.id, + hp: 1 + }] + }; + bidRequest.schain = globalSchain; + const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const data = requests[0].data; + const schain = data.source.ext.schain; + expect(schain.nodes.length).to.equal(1); + expect(schain.complete).to.equal(1); + expect(schain.nodes[0].sid).to.equal(bidRequest.params.video.sid); + expect(schain.nodes[0].rid).to.equal(data.id); + }) + + it('should append hp to new schain created by sid if video.params.hp is passed', function () { + const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const data = requests[0].data; + const schain = data.source.ext.schain; + expect(schain.nodes[0].hp).to.equal(bidRequest.params.video.hp); + }) }); describe('spec.interpretResponse', function () { @@ -360,15 +417,8 @@ describe('OneVideoBidAdapter', function () { expect(request[0].data.regs.ext.gdpr).to.equal(1); expect(request[0].data.regs.ext.us_privacy).to.equal(bidderRequest.uspConsent); }); - - it('should send schain object', function () { - const requests = spec.buildRequests([ bidRequest ], bidderRequest); - const data = requests[0].data; - expect(data.source.ext.schain.nodes[0].sid).to.equal(bidRequest.params.video.sid); - expect(data.source.ext.schain.nodes[0].rid).to.equal(data.id); - expect(data.source.ext.schain.nodes[0].hp).to.equal(bidRequest.params.video.hp); - }); }); + describe('should send banner object', function () { it('should send banner object when display is 1 and context="instream" (DAP O&O)', function () { bidRequest = { From a365dfd96c2c9572d75502107ad99a3b21f2b1a5 Mon Sep 17 00:00:00 2001 From: Nick Jacob Date: Mon, 13 Jul 2020 07:07:57 -0400 Subject: [PATCH 479/496] Add AMX adapter (#5464) * add AMX adapter (after fixing ie11 test failure) * revert karma config + CR changes --- modules/amxBidAdapter.js | 317 +++++++++++++++++++ modules/amxBidAdapter.md | 37 +++ test/spec/modules/amxBidAdapter_spec.js | 384 ++++++++++++++++++++++++ 3 files changed, 738 insertions(+) create mode 100644 modules/amxBidAdapter.js create mode 100644 modules/amxBidAdapter.md create mode 100644 test/spec/modules/amxBidAdapter_spec.js diff --git a/modules/amxBidAdapter.js b/modules/amxBidAdapter.js new file mode 100644 index 00000000000..90fcf878d62 --- /dev/null +++ b/modules/amxBidAdapter.js @@ -0,0 +1,317 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { parseUrl, deepAccess, _each, formatQS, getUniqueIdentifierStr, triggerPixel } from '../src/utils.js'; + +const BIDDER_CODE = 'amx'; +const SIMPLE_TLD_TEST = /\.co\.\w{2,4}$/; +const DEFAULT_ENDPOINT = 'https://prebid.a-mo.net/a/c'; +const VERSION = 'pba1.0'; +const xmlDTDRxp = /^\s*<\?xml[^\?]+\?>/; +const VAST_RXP = /^\s*<\??(?:vast|xml)/i; +const TRACKING_ENDPOINT = 'https://1x1.a-mo.net/hbx/'; + +const getLocation = (request) => + parseUrl(deepAccess(request, 'refererInfo.canonicalUrl', location.href)) + +const largestSize = (sizes, mediaTypes) => { + const allSizes = sizes + .concat(deepAccess(mediaTypes, `${BANNER}.sizes`, []) || []) + .concat(deepAccess(mediaTypes, `${VIDEO}.sizes`, []) || []) + + return allSizes.sort((a, b) => (b[0] * b[1]) - (a[0] * a[1]))[0]; +} + +function flatMap(input, mapFn) { + if (input == null) { + return [] + } + return input.map(mapFn) + .reduce((acc, item) => item != null && acc.concat(item), []) +} + +const generateDTD = (xmlDocument) => + ``; + +const isVideoADM = (html) => html != null && VAST_RXP.test(html); +const getMediaType = (bid) => isVideoADM(bid.adm) ? VIDEO : BANNER; +const nullOrType = (value, type) => + value == null || (typeof value) === type // eslint-disable-line valid-typeof + +function getID(loc) { + const host = loc.hostname.split('.'); + const short = host.slice( + host.length - (SIMPLE_TLD_TEST.test(loc.host) ? 3 : 2) + ).join('.'); + return btoa(short).replace(/=+$/, ''); +} + +const enc = encodeURIComponent; + +function nestedQs (qsData) { + const out = []; + Object.keys(qsData || {}).forEach((key) => { + out.push(enc(key) + '=' + enc(String(qsData[key]))); + }); + + return enc(out.join('&')); +} + +function createBidMap(bids) { + const out = {}; + _each(bids, (bid) => { + out[bid.bidId] = convertRequest(bid) + }) + return out; +} + +const trackEvent = (eventName, data) => + triggerPixel(`${TRACKING_ENDPOINT}g_${eventName}?${formatQS({ + ...data, + ts: Date.now(), + eid: getUniqueIdentifierStr(), + })}`); + +function convertRequest(bid) { + const size = largestSize(bid.sizes, bid.mediaTypes) || [0, 0]; + const isVideoBid = bid.mediaType === VIDEO || VIDEO in bid.mediaTypes + const av = isVideoBid || size[1] > 100; + const tid = deepAccess(bid, 'params.tagId') + + const params = { + av, + vr: isVideoBid, + aw: size[0], + ah: size[1], + tf: 0, + }; + + if (typeof tid === 'string' && tid.length > 0) { + params.i = tid; + } + return params; +} + +function decorateADM(bid) { + const impressions = deepAccess(bid, 'ext.himp', []) + .concat(bid.nurl != null ? [bid.nurl] : []) + .filter((imp) => imp != null && imp.length > 0) + .map((src) => ``) + .join(''); + return bid.adm + impressions; +} + +function transformXmlSimple(bid) { + const pixels = [] + _each([bid.nurl].concat(bid.ext != null && bid.ext.himp != null ? bid.ext.himp : []), (pixel) => { + if (pixel != null) { + pixels.push(``) + } + }); + // find the current "Impression" here & slice ours in + const impressionIndex = bid.adm.indexOf(' url != null); + + _each(pixels, (pxl) => { + const imagePixel = doc.createElement('Impression'); + const cdata = doc.createCDATASection(pxl); + imagePixel.appendChild(cdata); + root.appendChild(imagePixel); + }); + + const dtdMatch = xmlDTDRxp.exec(bid.adm); + return (dtdMatch != null ? dtdMatch[0] : generateDTD(doc)) + getOuterHTML(doc.documentElement); +} + +function resolveSize(bid, request, bidId) { + if (bid.w != null && bid.w > 1 && bid.h != null && bid.h > 1) { + return [bid.w, bid.h]; + } + + const bidRequest = request.m[bidId]; + if (bidRequest == null) { + return [0, 0]; + } + + return [bidRequest.aw, bidRequest.ah]; +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], + + isBidRequestValid(bid) { + return nullOrType(deepAccess(bid, 'params.endpoint', null), 'string') && + nullOrType(deepAccess(bid, 'params.tagId', null), 'string') && + nullOrType(deepAccess(bid, 'params.testMode', null), 'boolean'); + }, + + buildRequests(bidRequests, bidderRequest) { + const loc = getLocation(bidderRequest); + const tagId = deepAccess(bidRequests[0], 'params.tagId', null); + const testMode = deepAccess(bidRequests[0], 'params.testMode', 0); + + const payload = { + a: bidderRequest.auctionId, + B: 0, + b: loc.host, + tm: testMode, + V: '$prebid.version$', + i: (testMode && tagId != null) ? tagId : getID(loc), + l: {}, + f: 0.01, + cv: VERSION, + st: 'prebid', + h: screen.height, + w: screen.width, + gs: deepAccess(bidderRequest, 'gdprConsent.gdprApplies', '0'), + gc: deepAccess(bidderRequest, 'gdprConsent.consentString', ''), + u: deepAccess(bidderRequest, 'refererInfo.canonicalUrl', loc.href), + do: loc.host, + re: deepAccess(bidderRequest, 'refererInfo.referer'), + usp: bidderRequest.uspConsent || '1---', + smt: 1, + d: '', + m: createBidMap(bidRequests), + }; + + return { + data: payload, + method: 'POST', + url: deepAccess(bidRequests[0], 'params.endpoint', DEFAULT_ENDPOINT), + withCredentials: true, + }; + }, + + getUserSyncs(syncOptions, serverResponses) { + if (serverResponses == null || serverResponses.length === 0) { + return [] + } + const output = [] + _each(serverResponses, function ({ body: response }) { + if (response != null && response.p != null && response.p.hreq) { + _each(response.p.hreq, function (syncPixel) { + const pixelType = syncPixel.indexOf('__st=iframe') !== -1 ? 'iframe' : 'image'; + if (syncOptions.iframeEnabled || pixelType === 'image') { + output.push({ + url: syncPixel, + type: pixelType, + }); + } + }); + } + }); + return output; + }, + + interpretResponse(serverResponse, request) { + // validate the body/response + const response = serverResponse.body; + if (response == null || typeof response === 'string') { + return []; + } + + return flatMap(Object.keys(response.r), (bidID) => { + return flatMap(response.r[bidID], (siteBid) => + siteBid.b.map((bid) => { + const mediaType = getMediaType(bid); + // let ad = null; + let ad = mediaType === BANNER ? decorateADM(bid) : decorateVideoADM(bid); + if (ad == null) { + return null; + } + + const size = resolveSize(bid, request.data, bidID); + + return ({ + requestId: bidID, + cpm: bid.price, + width: size[0], + height: size[1], + creativeId: bid.crid, + currency: 'USD', + netRevenue: true, + [mediaType === VIDEO ? 'vastXml' : 'ad']: ad, + meta: { + advertiserDomains: bid.adomain, + mediaType, + }, + ttl: mediaType === VIDEO ? 90 : 70 + }); + })).filter((possibleBid) => possibleBid != null); + }); + }, + + onSetTargeting(targetingData) { + if (targetingData == null) { + return; + } + + trackEvent('pbst', { + A: targetingData.bidder, + w: targetingData.width, + h: targetingData.height, + bid: targetingData.adId, + c1: targetingData.mediaType, + np: targetingData.cpm, + aud: targetingData.requestId, + a: targetingData.adUnitCode, + c2: nestedQs(targetingData.adserverTargeting), + }); + }, + + onTimeout(timeoutData) { + if (timeoutData == null) { + return; + } + + trackEvent('pbto', { + A: timeoutData.bidder, + bid: timeoutData.bidId, + a: timeoutData.adUnitCode, + cn: timeoutData.timeout, + aud: timeoutData.auctionId, + }); + }, + + onBidWon(bidWinData) { + if (bidWinData == null) { + return; + } + + trackEvent('pbwin', { + A: bidWinData.bidder, + w: bidWinData.width, + h: bidWinData.height, + bid: bidWinData.adId, + C: bidWinData.mediaType === BANNER ? 0 : 1, + np: bidWinData.cpm, + a: bidWinData.adUnitCode, + }); + }, +}; + +registerBidder(spec); diff --git a/modules/amxBidAdapter.md b/modules/amxBidAdapter.md new file mode 100644 index 00000000000..5526ef8b6b9 --- /dev/null +++ b/modules/amxBidAdapter.md @@ -0,0 +1,37 @@ +Overview +======== + +``` +Module Name: AMX Adapter +Module Type: Bidder Adapter +Maintainer: prebid.support@amxrtb.com +``` + +Description +=========== + +This module connects web publishers to AMX RTB video and display demand. + +# Bid Parameters + +| Key | Required | Example | Description | +| --- | -------- | ------- | ----------- | +| `endpoint` | **yes** | `https://prebid.a-mo.net/a/c` | The url including https:// and any path | +| `testMode` | no | `true` | this will activate test mode / 100% fill with sample ads | +| `tagId` | no | `"cHJlYmlkLm9yZw"` | can be used for more specific targeting of inventory. Your account manager will provide this ID if needed | + +# Test Parameters + +``` +var adUnits = [{ + code: 'test-div', + sizes: [[300, 250]], + bids: [{ + bidder: 'amx', + params: { + testMode: true, + tagId: 'cHJlYmlkLm9yZw' + }, + }] +}] +``` diff --git a/test/spec/modules/amxBidAdapter_spec.js b/test/spec/modules/amxBidAdapter_spec.js new file mode 100644 index 00000000000..790f3bf2581 --- /dev/null +++ b/test/spec/modules/amxBidAdapter_spec.js @@ -0,0 +1,384 @@ +import * as utils from 'src/utils.js'; +import { expect } from 'chai'; +import { spec } from 'modules/amxBidAdapter.js'; +import { BANNER, VIDEO } from 'src/mediaTypes.js'; + +const sampleRequestId = '82c91e127a9b93e'; +const sampleDisplayAd = (additionalImpressions) => `${additionalImpressions}`; +const sampleDisplayCRID = '78827819'; +// minimal example vast +const sampleVideoAd = (addlImpression) => ` +00:00:15${addlImpression} +`.replace(/\n+/g, '') + +const embeddedTrackingPixel = `https://1x1.a-mo.net/hbx/g_impression?A=sample&B=20903`; +const sampleNurl = 'https://example.exchange/nurl'; + +const sampleBidderRequest = { + gdprConsent: { + gdprApplies: true, + consentString: utils.getUniqueIdentifierStr(), + vendorData: {} + }, + auctionId: utils.getUniqueIdentifierStr(), + uspConsent: '1YYY', + refererInfo: { + referer: 'https://www.prebid.org', + canonicalUrl: 'https://www.prebid.org/the/link/to/the/page' + } +}; + +const sampleBidRequestBase = { + bidder: spec.code, + params: { + endpoint: 'https://httpbin.org/post', + }, + sizes: [[320, 50]], + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + adUnitCode: 'div-gpt-ad-example', + transactionId: utils.getUniqueIdentifierStr(), + bidId: sampleRequestId, + auctionId: utils.getUniqueIdentifierStr(), +}; + +const sampleBidRequestVideo = { + ...sampleBidRequestBase, + bidId: sampleRequestId + '_video', + sizes: [[300, 150]], + mediaTypes: { + [VIDEO]: { + sizes: [[360, 250]] + } + } +}; + +const sampleServerResponse = { + 'p': { + 'hreq': ['https://1x1.a-mo.net/hbx/g_sync?partner=test', 'https://1x1.a-mo.net/hbx/g_syncf?__st=iframe'] + }, + 'r': { + [sampleRequestId]: [ + { + 'b': [ + { + 'adid': '78827819', + 'adm': sampleDisplayAd(''), + 'adomain': [ + 'example.com' + ], + 'crid': sampleDisplayCRID, + 'ext': { + 'himp': [ + embeddedTrackingPixel + ], + }, + 'nurl': sampleNurl, + 'h': 600, + 'id': '2014691335735134254', + 'impid': '1', + 'price': 0.25, + 'w': 300 + }, + { + 'adid': '222976952', + 'adm': sampleVideoAd(''), + 'adomain': [ + 'example.com' + ], + 'crid': sampleDisplayCRID, + 'ext': { + 'himp': [ + embeddedTrackingPixel + ], + }, + 'nurl': sampleNurl, + 'h': 1, + 'id': '7735706981389902829', + 'impid': '1', + 'price': 0.25, + 'w': 1 + }, + ], + } + ] + }, +} + +describe('AmxBidAdapter', () => { + describe('isBidRequestValid', () => { + it('endpoint must be an optional string', () => { + expect(spec.isBidRequestValid({params: { endpoint: 1 }})).to.equal(false) + expect(spec.isBidRequestValid({params: { endpoint: 'test' }})).to.equal(true) + }); + + it('tagId is an optional string', () => { + expect(spec.isBidRequestValid({params: { tagId: 1 }})).to.equal(false) + expect(spec.isBidRequestValid({params: { tagId: 'test' }})).to.equal(true) + }); + + it('testMode is an optional boolean', () => { + expect(spec.isBidRequestValid({params: { testMode: 1 }})).to.equal(false) + expect(spec.isBidRequestValid({params: { testMode: false }})).to.equal(true) + }); + + it('none of the params are required', () => { + expect(spec.isBidRequestValid({})).to.equal(true) + }); + }) + describe('getUserSync', () => { + it('will only sync from valid server responses', () => { + const syncs = spec.getUserSyncs({ iframeEnabled: true }); + expect(syncs).to.eql([]); + }); + + it('will return valid syncs from a server response', () => { + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [{body: sampleServerResponse}]); + expect(syncs.length).to.equal(2); + expect(syncs[0].type).to.equal('image'); + expect(syncs[1].type).to.equal('iframe'); + }); + + it('will filter out iframe syncs based on options', () => { + const syncs = spec.getUserSyncs({ iframeEnabled: false }, [{body: sampleServerResponse}, {body: sampleServerResponse}]); + expect(syncs.length).to.equal(2); + expect(syncs).to.satisfy((allSyncs) => allSyncs.every((sync) => sync.type === 'image')) + }); + }); + + describe('buildRequests', () => { + it('will default to prebid.a-mo.net endpoint', () => { + const { url } = spec.buildRequests([], sampleBidderRequest); + expect(url).to.equal('https://prebid.a-mo.net/a/c') + }); + + it('reads test mode from the first bid request', () => { + const { data } = spec.buildRequests([{ + ...sampleBidRequestBase, + params: { + testMode: true + } + }], sampleBidderRequest); + expect(data.tm).to.equal(true); + }); + + it('handles referer data and GDPR, USP Consent', () => { + const { data } = spec.buildRequests([sampleBidRequestBase], sampleBidderRequest); + delete data.m; // don't deal with "m" in this test + expect(data.gs).to.equal(sampleBidderRequest.gdprConsent.gdprApplies) + expect(data.gc).to.equal(sampleBidderRequest.gdprConsent.consentString) + expect(data.usp).to.equal(sampleBidderRequest.uspConsent) + }); + + it('can build a banner request', () => { + const { method, url, data } = spec.buildRequests([sampleBidRequestBase, { + ...sampleBidRequestBase, + bidId: sampleRequestId + '_2', + params: { + ...sampleBidRequestBase.params, + tagId: 'example' + } + }], sampleBidderRequest) + + expect(url).to.equal(sampleBidRequestBase.params.endpoint) + expect(method).to.equal('POST'); + expect(Object.keys(data.m).length).to.equal(2); + expect(data.m[sampleRequestId]).to.deep.equal({ + av: true, + aw: 300, + ah: 250, + tf: 0, + vr: false + }); + expect(data.m[sampleRequestId + '_2']).to.deep.equal({ + av: true, + aw: 300, + i: 'example', + ah: 250, + tf: 0, + vr: false, + }); + }); + + it('can build a video request', () => { + const { data } = spec.buildRequests([sampleBidRequestVideo], sampleBidderRequest); + expect(Object.keys(data.m).length).to.equal(1); + expect(data.m[sampleRequestId + '_video']).to.deep.equal({ + av: true, + aw: 360, + ah: 250, + tf: 0, + vr: true + }); + }); + }); + + describe('interpretResponse', () => { + const baseBidResponse = { + requestId: sampleRequestId, + cpm: 0.25, + creativeId: sampleDisplayCRID, + currency: 'USD', + netRevenue: true, + meta: { + advertiserDomains: ['example.com'], + }, + }; + + const baseRequest = { + data: { + m: { + [sampleRequestId]: { + aw: 300, + ah: 250, + }, + } + } + }; + + it('will handle a nobid response', () => { + const parsed = spec.interpretResponse({ body: '' }, baseRequest) + expect(parsed).to.eql([]) + }); + + it('can parse a display ad', () => { + const parsed = spec.interpretResponse({ body: sampleServerResponse }, baseRequest) + expect(parsed.length).to.equal(2) + + // we should have display, video, display + expect(parsed[0]).to.deep.equal({ + ...baseBidResponse, + meta: { + ...baseBidResponse.meta, + mediaType: BANNER, + }, + width: 300, + height: 600, // from the bid itself + ttl: 70, + ad: sampleDisplayAd( + `` + + `` + ), + }); + }); + + it('can parse a video ad', () => { + const parsed = spec.interpretResponse({ body: sampleServerResponse }, baseRequest) + expect(parsed.length).to.equal(2) + + // we should have display, video, display + const xml = parsed[1].vastXml + delete parsed[1].vastXml + + expect(xml).to.have.string(``) + expect(xml).to.have.string(``) + + expect(parsed[1]).to.deep.equal({ + ...baseBidResponse, + meta: { + ...baseBidResponse.meta, + mediaType: VIDEO, + }, + width: 300, + height: 250, + ttl: 90, + }); + }); + }); + + describe('analytics methods', () => { + let firedPixels = []; + let _Image = window.Image; + before(() => { + _Image = window.Image; + window.Image = class FakeImage { + set src(value) { + firedPixels.push(value) + } + } + }); + + beforeEach(() => { + firedPixels = []; + }); + + after(() => { + window.Image = _Image; + }); + + it('will fire an event for onSetTargeting', () => { + spec.onSetTargeting({ + bidder: 'example', + width: 300, + height: 250, + adId: 'ad-id', + mediaType: BANNER, + cpm: 1.23, + requestId: utils.getUniqueIdentifierStr(), + adUnitCode: 'div-gpt-ad', + adserverTargeting: { + hb_pb: '1.23', + hb_adid: 'ad-id', + hb_bidder: 'example' + } + }); + expect(firedPixels.length).to.equal(1) + expect(firedPixels[0]).to.match(/\/hbx\/g_pbst/) + try { + const parsed = new URL(firedPixels[0]); + const nestedData = parsed.searchParams.get('c2'); + expect(nestedData).to.equal(utils.formatQS({ + hb_pb: '1.23', + hb_adid: 'ad-id', + hb_bidder: 'example' + })); + } catch (e) { + // unsupported browser; try testing for string + const pixel = firedPixels[0]; + expect(pixel).to.have.string(encodeURIComponent('hb_pb=1.23')) + expect(pixel).to.have.string(encodeURIComponent('hb_adid=ad-id')) + } + }); + + it('will log an event for timeout', () => { + spec.onTimeout({ + bidder: 'example', + bidId: 'test-bid-id', + adUnitCode: 'div-gpt-ad', + timeout: 300, + auctionId: utils.getUniqueIdentifierStr() + }); + expect(firedPixels.length).to.equal(1) + expect(firedPixels[0]).to.match(/\/hbx\/g_pbto/) + }); + + it('will log an event for prebid win', () => { + spec.onBidWon({ + bidder: 'example', + adId: 'test-ad-id', + width: 300, + height: 250, + mediaType: VIDEO, + cpm: 1.34, + adUnitCode: 'div-gpt-ad', + timeout: 300, + auctionId: utils.getUniqueIdentifierStr() + }); + expect(firedPixels.length).to.equal(1) + expect(firedPixels[0]).to.match(/\/hbx\/g_pbwin/) + + const pixel = firedPixels[0]; + try { + const url = new URL(pixel); + expect(url.searchParams.get('C')).to.equal('1') + expect(url.searchParams.get('np')).to.equal('1.34') + } catch (e) { + expect(pixel).to.have.string('C=1') + expect(pixel).to.have.string('np=1.34') + } + }); + }); +}); From 4b0eb0b81d4264e28d5b86af0393ee1d9b4a79f4 Mon Sep 17 00:00:00 2001 From: Adam Browning <19834421+adam-browning@users.noreply.github.com> Date: Mon, 13 Jul 2020 22:37:20 +0300 Subject: [PATCH 480/496] oneVideo Adapter End2End Testing Parameter Support (SAPR-13942) (#5466) * bidData Debug true if .source exists * capture and pass config.schain * changing from config.schain to bid.schain * updated schain unit tests * updated schain unit tests * added schain examples to .md file * added e2etest unit tests * updated e2etest settings object * moved e2etest to correct position * added global test endpoint * fixed eslint typo * updated unit test for new global test endpoint * backup before merging master * updated schain logic to use bidRequest.schain instead of global schain only * updated schain test to new bidRequest.schain logic * Update package-lock.json * Delete package-lock.json * restoring package.lock * restored package-lock.json * fixed lint issue --- modules/oneVideoBidAdapter.js | 20 ++++++++++-- modules/oneVideoBidAdapter.md | 32 ++++++++++++++++++++ test/spec/modules/oneVideoBidAdapter_spec.js | 22 +++++++++++++- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/modules/oneVideoBidAdapter.js b/modules/oneVideoBidAdapter.js index 8ccdd4f9c56..26b0a7dccc2 100644 --- a/modules/oneVideoBidAdapter.js +++ b/modules/oneVideoBidAdapter.js @@ -6,6 +6,7 @@ export const spec = { code: 'oneVideo', VERSION: '3.0.3', ENDPOINT: 'https://ads.adaptv.advertising.com/rtb/openrtb?ext_id=', + E2ETESTENDPOINT: 'https://ads-wc.v.ssp.yahoo.com/rtb/openrtb?ext_id=', SYNC_ENDPOINT1: 'https://cm.g.doubleclick.net/pixel?google_nid=adaptv_dbm&google_cm&google_sc', SYNC_ENDPOINT2: 'https://pr-bh.ybp.yahoo.com/sync/adaptv_ortb/{combo_uid}', SYNC_ENDPOINT3: 'https://match.adsrvr.org/track/cmf/generic?ttd_pid=adaptv&ttd_tpi=1', @@ -53,11 +54,17 @@ export const spec = { let consentData = bidRequest ? bidRequest.gdprConsent : null; return bids.map(bid => { + let url = spec.ENDPOINT + let pubId = bid.params.pubId; + if (bid.params.video.e2etest) { + url = spec.E2ETESTENDPOINT; + pubId = 'HBExchange'; + } return { method: 'POST', /** removing adding local protocal since we * can get cookie data only if we call with https. */ - url: spec.ENDPOINT + bid.params.pubId, + url: url + pubId, data: getRequestData(bid, consentData, bidRequest), bidRequest: bid } @@ -290,7 +297,16 @@ function getRequestData(bid, consentData, bidRequest) { bidData.regs.ext.us_privacy = bidRequest.uspConsent } } - + if (bid.params.video.e2etest) { + bidData.imp[0].bidfloor = null; + bidData.imp[0].video.w = 300; + bidData.imp[0].video.h = 250; + bidData.imp[0].video.mimes = ['video/mp4', 'application/javascript']; + bidData.imp[0].video.api = [2]; + bidData.site.page = 'https://verizonmedia.com'; + bidData.site.ref = 'https://verizonmedia.com'; + bidData.tmax = 1000; + } return bidData; } diff --git a/modules/oneVideoBidAdapter.md b/modules/oneVideoBidAdapter.md index 1dbdc473294..72f251aac04 100644 --- a/modules/oneVideoBidAdapter.md +++ b/modules/oneVideoBidAdapter.md @@ -168,6 +168,38 @@ Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to ] ``` +# End 2 End Testing Mode +By passing bid.params.video.e2etest = true you will be able to receive a test creative when connecting via VPN location U.S West Coast. This will allow you to trubleshoot how your player/ad-server parses and uses the VAST XML response. +This automatically sets default values for the outbound bid-request to respond from our test exchange. +No need to override the site/ref urls or change your pubId +``` +var adUnits = [ + { + code: 'video-1', + mediaTypes: { + video: { + context: "instream", + playerSize: [480, 640] + } + }, + bids: [ + { + bidder: 'oneVideo', + params: { + video: { + playerWidth: 300, + playerHeight: 250, + mimes: ['video/mp4', 'application/javascript'], + e2etest: true + } + pubId: 'YOUR_PUBLISHER_ID' + } + } + ] + } +] +``` + # Supply Chain Object Support The oneVideoBidAdapter supports 2 methods for passing/creating an schain object. 1. By passing your Video SSP Org ID in the bid.video.params.sid - The adapter will create a new schain object and our ad-server will fill in the data for you. diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js index 8d12ada9d32..a91e9ac27e8 100644 --- a/test/spec/modules/oneVideoBidAdapter_spec.js +++ b/test/spec/modules/oneVideoBidAdapter_spec.js @@ -1,7 +1,6 @@ import { expect } from 'chai'; import { spec } from 'modules/oneVideoBidAdapter.js'; import * as utils from 'src/utils.js'; -import {config} from 'src/config.js'; describe('OneVideoBidAdapter', function () { let bidRequest; @@ -239,6 +238,27 @@ describe('OneVideoBidAdapter', function () { expect(data.imp[0].video.h).to.equal(height); }); + it('should set pubId to HBExchange when bid.params.video.e2etest = true', function () { + bidRequest.params.video.e2etest = true; + const requests = spec.buildRequests([ bidRequest ], bidderRequest); + expect(requests[0].method).to.equal('POST'); + expect(requests[0].url).to.equal(spec.E2ETESTENDPOINT + 'HBExchange'); + }); + + it('should attach End 2 End test data', function () { + bidRequest.params.video.e2etest = true; + const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const data = requests[0].data; + expect(data.imp[0].bidfloor).to.not.exist; + expect(data.imp[0].video.w).to.equal(300); + expect(data.imp[0].video.h).to.equal(250); + expect(data.imp[0].video.mimes).to.eql(['video/mp4', 'application/javascript']); + expect(data.imp[0].video.api).to.eql([2]); + expect(data.site.page).to.equal('https://verizonmedia.com'); + expect(data.site.ref).to.equal('https://verizonmedia.com'); + expect(data.tmax).to.equal(1000); + }); + it('it should create new schain and send it if video.params.sid exists', function () { const requests = spec.buildRequests([ bidRequest ], bidderRequest); const data = requests[0].data; From f87f86cf8053a827c8e798afbdfc9e6cd422b4c1 Mon Sep 17 00:00:00 2001 From: Nick Duitz <42961155+nduitz@users.noreply.github.com> Date: Tue, 14 Jul 2020 16:59:07 +0200 Subject: [PATCH 481/496] Welect adapter (#5457) * welect-adapter initial commit * fix available checking * update post request to correctly send application/json data * fix and update tests * change placementAlias to placemenId * update docs * cleanup * no need to parse rawsizes * use strict checking --- modules/welectBidAdapter.js | 87 +++++++++ modules/welectBidAdapter.md | 30 +++ test/spec/modules/welectBidAdapter_spec.js | 205 +++++++++++++++++++++ 3 files changed, 322 insertions(+) create mode 100644 modules/welectBidAdapter.js create mode 100644 modules/welectBidAdapter.md create mode 100644 test/spec/modules/welectBidAdapter_spec.js diff --git a/modules/welectBidAdapter.js b/modules/welectBidAdapter.js new file mode 100644 index 00000000000..3913cfde6a0 --- /dev/null +++ b/modules/welectBidAdapter.js @@ -0,0 +1,87 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; + +const BIDDER_CODE = 'welect'; +const DEFAULT_DOMAIN = 'www.welect.de'; + +export const spec = { + code: BIDDER_CODE, + aliases: ['wlt'], + supportedMediaTypes: ['video'], + + // short code + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bid) { + return utils.deepAccess(bid, 'mediaTypes.video.context') === 'instream' && !!(bid.params.placementId); + }, + /** + * Make a server request from the list of BidRequests. + * + * @param {validBidRequests[]} - an array of bids + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function (validBidRequests) { + return validBidRequests.map(bidRequest => { + let rawSizes = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize') || bidRequest.sizes; + let size = rawSizes[0] + + let domain = bidRequest.params.domain || DEFAULT_DOMAIN; + + let url = `https://${domain}/api/v2/preflight/by_alias/${bidRequest.params.placementId}`; + + let gdprConsent = null; + + if (bidRequest && bidRequest.gdprConsent) { + gdprConsent = { + gdpr_consent: + { + gdpr_applies: bidRequest.gdprConsent.gdprApplies, + gdpr_consent: bidRequest.gdprConsent.gdprConsent + } + } + } + + const data = { + width: size[0], + height: size[1], + bid_id: bidRequest.bidId, + ...gdprConsent + } + + return { + method: 'POST', + url: url, + data: data, + options: { + contentType: 'application/json', + withCredentials: false, + crossOrigin: true, + } + } + }); + }, + /** + * Unpack the response from the server into a list of bids. + * + * @param {ServerResponse} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function (serverResponse, bidRequest) { + const responseBody = serverResponse.body; + + if (typeof responseBody !== 'object' || responseBody.available !== true) { + return []; + } + + const bidResponses = []; + const bidResponse = responseBody.bidResponse; + bidResponses.push(bidResponse); + return bidResponses; + } +} +registerBidder(spec); diff --git a/modules/welectBidAdapter.md b/modules/welectBidAdapter.md new file mode 100644 index 00000000000..7f72a0bd949 --- /dev/null +++ b/modules/welectBidAdapter.md @@ -0,0 +1,30 @@ +# Overview + +``` +Module Name: Welect Bidder Adapter +Module Type: Welect Adapter +Maintainer: nick.duitz@9elements.com +``` + +# Description + +Module that connects to Welect's demand sources + +# Test Parameters +``` +var adUnits = [ + { + bidder: 'welect', + params: { + placementId: 'exampleId', + domain: 'www.welect.de' + }, + sizes: [[640, 360]], + mediaTypes: { + video: { + context: 'instream' + } + }, + }; +]; +``` \ No newline at end of file diff --git a/test/spec/modules/welectBidAdapter_spec.js b/test/spec/modules/welectBidAdapter_spec.js new file mode 100644 index 00000000000..2b929be5586 --- /dev/null +++ b/test/spec/modules/welectBidAdapter_spec.js @@ -0,0 +1,205 @@ +import {expect} from 'chai'; +import {spec as adapter} from 'modules/welectBidAdapter.js'; + +describe('WelectAdapter', function () { + describe('Check methods existance', function () { + it('exists and is a function', function () { + expect(adapter.isBidRequestValid).to.exist.and.to.be.a('function'); + }); + it('exists and is a function', function () { + expect(adapter.buildRequests).to.exist.and.to.be.a('function'); + }); + it('exists and is a function', function () { + expect(adapter.interpretResponse).to.exist.and.to.be.a('function'); + }); + }); + + describe('Check method isBidRequestValid return', function () { + let bid = { + bidder: 'welect', + params: { + placementId: 'exampleAlias', + domain: 'www.welect.de' + }, + sizes: [[640, 360]], + mediaTypes: { + video: { + context: 'instream' + } + }, + }; + let bid2 = { + bidder: 'welect', + params: { + domain: 'www.welect.de' + }, + mediaTypes: { + video: { + context: 'instream', + playerSize: [640, 360] + } + }, + }; + + it('should be true', function () { + expect(adapter.isBidRequestValid(bid)).to.be.true; + }); + + it('should be false because the placementId is missing', function () { + expect(adapter.isBidRequestValid(bid2)).to.be.false; + }); + }); + + describe('Check buildRequests method', function () { + // Bids to be formatted + let bid1 = { + bidder: 'welect', + params: { + placementId: 'exampleAlias' + }, + sizes: [[640, 360]], + mediaTypes: { + video: { + context: 'instream' + } + }, + bidId: 'abdc' + }; + let bid2 = { + bidder: 'welect', + params: { + placementId: 'exampleAlias', + domain: 'www.welect2.de' + }, + sizes: [[640, 360]], + mediaTypes: { + video: { + context: 'instream' + } + }, + bidId: 'abdc', + gdprConsent: { + gdprApplies: 1, + gdprConsent: 'some_string' + } + }; + + let data1 = { + bid_id: 'abdc', + width: 640, + height: 360 + } + + let data2 = { + bid_id: 'abdc', + width: 640, + height: 360, + gdpr_consent: { + gdpr_applies: 1, + gdpr_consent: 'some_string' + } + } + + // Formatted requets + let request1 = { + method: 'POST', + url: 'https://www.welect.de/api/v2/preflight/by_alias/exampleAlias', + data: data1, + options: { + contentType: 'application/json', + withCredentials: false, + crossOrigin: true, + } + }; + + let request2 = { + method: 'POST', + url: 'https://www.welect2.de/api/v2/preflight/by_alias/exampleAlias', + data: data2, + options: { + contentType: 'application/json', + withCredentials: false, + crossOrigin: true, + } + } + + it('defaults to www.welect.de, without gdpr object', function () { + expect(adapter.buildRequests([bid1])).to.deep.equal([request1]); + }) + + it('must return the right formatted requests, with gdpr object', function () { + expect(adapter.buildRequests([bid2])).to.deep.equal([request2]); + }); + }); + + describe('Check interpretResponse method return', function () { + // invalid server response + let unavailableResponse = { + body: { + available: false + } + }; + + let availableResponse = { + body: { + available: true, + bidResponse: { + ad: { + video: 'some vast url' + }, + cpm: 17, + creativeId: 'svmpreview', + currency: 'EUR', + netRevenue: true, + requestId: 'some bid id', + ttl: 120, + vastUrl: 'some vast url', + height: 640, + width: 320 + } + } + } + // bid Request + let bid = { + data: { + bid_id: 'some bid id', + width: 640, + height: 320, + gdpr_consent: { + gdpr_applies: 1, + gdpr_consent: 'some_string' + } + }, + method: 'POST', + url: 'https://www.welect.de/api/v2/preflight/by_alias/exampleAlias', + options: { + contentType: 'application/json', + withCredentials: false, + crossOrigin: true, + } + }; + // Formatted reponse + let result = { + ad: { + video: 'some vast url' + }, + cpm: 17, + creativeId: 'svmpreview', + currency: 'EUR', + height: 640, + netRevenue: true, + requestId: 'some bid id', + ttl: 120, + vastUrl: 'some vast url', + width: 320 + } + + it('if response reflects unavailability, should be empty', function () { + expect(adapter.interpretResponse(unavailableResponse, bid)).to.deep.equal([]); + }); + + it('if response reflects availability, should equal result', function() { + expect(adapter.interpretResponse(availableResponse, bid)).to.deep.equal([result]) + }) + }); +}); From 41f77997854ba86309a8cf2009bffb146e346308 Mon Sep 17 00:00:00 2001 From: Index Exchange 3 Prebid Team Date: Tue, 14 Jul 2020 11:06:54 -0400 Subject: [PATCH 482/496] Added support for Liveramp userId submodule & read sizes from adUnit.mediaTypes.banner (#5436) * Added support for Liveramp userId submodule * To send requests for missing sizes for IX Co-authored-by: IX-Prebid-Support --- modules/ixBidAdapter.js | 135 ++++++++++++- modules/ixBidAdapter.md | 11 +- test/spec/modules/ixBidAdapter_spec.js | 269 ++++++++++++++++++++++++- 3 files changed, 401 insertions(+), 14 deletions(-) diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index f4c42080f58..62d4b015aa7 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -170,7 +170,7 @@ function includesSize(sizeArray, size) { * * @param {*} bidFloor The bidFloor parameter inside bid request config. * @param {*} bidFloorCur The bidFloorCur parameter inside bid request config. - * @return {boolean} True if this is a valid biFfloor parameters format, and false + * @return {boolean} True if this is a valid bidFloor parameters format, and false * otherwise. */ function isValidBidFloorParams(bidFloor, bidFloorCur) { @@ -194,6 +194,39 @@ function getBidRequest(id, impressions) { return find(impressions, imp => imp.id === id); } +/** + * Adds a User ID module's response into user Eids array. + * + * @param {array} userEids An array of objects containing user ids, + * will be attached to bid request later. + * @param {object} seenIdPartners An object with Identity partners names already added, + * updated with new partner name. + * @param {*} id The id obtained from User ID module. + * @param {string} source The URL of the User ID module. + * @param {string} ixlPartnerName The name of the Identity Partner in IX Library. + * @param {string} rtiPartner The name of the User ID provider in Prebid. + * @return {boolean} True if successfully added the ID to the userEids, false otherwise. + */ +function addUserEids(userEids, seenIdPartners, id, source, ixlPartnerName, rtiPartner) { + if (id) { + // mark the partnername that IX RTI uses + seenIdPartners[ixlPartnerName] = 1; + userEids.push({ + source: source, + uids: [{ + id: id, + ext: { + rtiPartner: rtiPartner + } + }] + }); + return true; + } + + utils.logWarn('Tried to add a user ID from Prebid, the ID received was null'); + return false; +} + /** * Builds a request object to be sent to the ad server based on bid requests. * @@ -210,6 +243,17 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { // Always use secure HTTPS protocol. let baseUrl = SECURE_BID_URL; + // Dict for identity partners already populated from prebid + let seenIdPartners = {}; + + // Get ids from Prebid User ID Modules + const userId = validBidRequests[0].userId; + if (userId && typeof userId === 'object') { + if (userId.idl_env) { + addUserEids(userEids, seenIdPartners, userId.idl_env, 'liveramp.com', 'LiveRampIp', 'idl'); + } + } + // RTI ids will be included in the bid request if the function getIdentityInfo() is loaded // and if the data for the partner exist if (window.headertag && typeof window.headertag.getIdentityInfo === 'function') { @@ -217,9 +261,12 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { if (identityInfo && typeof identityInfo === 'object') { for (const partnerName in identityInfo) { if (identityInfo.hasOwnProperty(partnerName)) { - let response = identityInfo[partnerName]; - if (!response.responsePending && response.data && typeof response.data === 'object' && Object.keys(response.data).length) { - userEids.push(response.data); + // check if not already populated by prebid cache + if (!seenIdPartners.hasOwnProperty(partnerName)) { + let response = identityInfo[partnerName]; + if (!response.responsePending && response.data && typeof response.data === 'object' && Object.keys(response.data).length) { + userEids.push(response.data); + } } } } @@ -327,6 +374,67 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { }; } +/** + * + * @param {array} bannerSizeList list of banner sizes + * @param {array} bannerSize the size to be removed + * @return {boolean} true if succesfully removed, false if not found + */ + +function removeFromSizes(bannerSizeList, bannerSize) { + for (let i = 0; i < bannerSizeList.length; i++) { + if (bannerSize[0] == bannerSizeList[i][0] && bannerSize[1] == bannerSizeList[i][1]) { + bannerSizeList.splice(i, 1); + return true; + } + } + // size not found + return false; +} + +/** + * Updates the Object to track missing banner sizes. + * + * @param {object} validBidRequest The bid request for an ad unit's with a configured size. + * @param {object} missingBannerSizes The object containing missing banner sizes + * @param {object} imp The impression for the bidrequest + */ +function updateMissingSizes(validBidRequest, missingBannerSizes, imp) { + const transactionID = validBidRequest.transactionId; + if (missingBannerSizes.hasOwnProperty(transactionID)) { + let currentSizeList = []; + if (missingBannerSizes[transactionID].hasOwnProperty('missingSizes')) { + currentSizeList = missingBannerSizes[transactionID].missingSizes; + } + removeFromSizes(currentSizeList, validBidRequest.params.size); + missingBannerSizes[transactionID].missingSizes = currentSizeList; + } else { + // New Ad Unit + if (utils.deepAccess(validBidRequest, 'mediaTypes.banner.sizes')) { + let sizeList = utils.deepClone(validBidRequest.mediaTypes.banner.sizes); + removeFromSizes(sizeList, validBidRequest.params.size); + let newAdUnitEntry = { 'missingSizes': sizeList, + 'impression': imp + }; + missingBannerSizes[transactionID] = newAdUnitEntry; + } + } +} + +/** + * + * @param {object} imp Impression object to be modified + * @param {array} newSize The new size to be applied + * @return {object} newImp Updated impression object + */ +function createMissingBannerImp(imp, newSize) { + const newImp = utils.deepClone(imp); + newImp.ext.sid = `${newSize[0]}x${newSize[1]}`; + newImp.banner.w = newSize[0]; + newImp.banner.h = newSize[1]; + return newImp; +} + export const spec = { code: BIDDER_CODE, @@ -389,6 +497,9 @@ export const spec = { let videoImps = []; let validBidRequest = null; + // To capture the missing sizes i.e not configured for ix + let missingBannerSizes = {}; + for (let i = 0; i < validBidRequests.length; i++) { validBidRequest = validBidRequests[i]; @@ -399,10 +510,22 @@ export const spec = { utils.logError('Bid size is not included in video playerSize') } } - if (validBidRequest.mediaType === BANNER || utils.deepAccess(validBidRequest, 'mediaTypes.banner') || (!validBidRequest.mediaType && !validBidRequest.mediaTypes)) { - bannerImps.push(bidToBannerImp(validBidRequest)); + let imp = bidToBannerImp(validBidRequest); + bannerImps.push(imp); + updateMissingSizes(validBidRequest, missingBannerSizes, imp); + } + } + // Finding the missing banner sizes ,and making impressions for them + for (var transactionID in missingBannerSizes) { + if (missingBannerSizes.hasOwnProperty(transactionID)) { + let missingSizes = missingBannerSizes[transactionID].missingSizes; + for (let i = 0; i < missingSizes.length; i++) { + let origImp = missingBannerSizes[transactionID].impression; + let newImp = createMissingBannerImp(origImp, missingSizes[i]); + bannerImps.push(newImp); + } } } diff --git a/modules/ixBidAdapter.md b/modules/ixBidAdapter.md index fcbc4ea89e3..b5cb0d9d2c1 100644 --- a/modules/ixBidAdapter.md +++ b/modules/ixBidAdapter.md @@ -393,14 +393,11 @@ FAQs ### Why do I have to input size in `adUnits[].bids[].params` for IX when the size is already in the ad unit? -There are two important reasons why we require it: +There is one important reason why we recommend it: -1. An IX site ID maps to a single size, whereas an ad unit can have multiple -sizes. To ensure that the right site ID is mapped to the correct size in the ad -unit we require the size to be explicitly stated. - -2. An ad unit may have sizes that IX does not support. By explicitly stating the -size, you can choose not to have IX bid on certain sizes that are invalid. +1. An IX site ID is recommended to map to a single size, whereas an ad unit can have multiple +sizes. To ensure that the right site ID is mapped to the correct size in the ad unit, +we require the size to be explicitly stated or our bidder will auto assign the site ID to sizes that are not assigned. ### How do I view IX's bid request in the network? diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js index 114a2226770..680ffdc0fcc 100644 --- a/test/spec/modules/ixBidAdapter_spec.js +++ b/test/spec/modules/ixBidAdapter_spec.js @@ -190,6 +190,22 @@ describe('IndexexchangeAdapter', function () { v: 8.1 }; + const DEFAULT_USERID_DATA = { + idl_env: '1234-5678-9012-3456', // Liveramp + }; + + const DEFAULT_USERID_PAYLOAD = [ + { + source: 'liveramp.com', + uids: [{ + id: DEFAULT_USERID_DATA.idl_env, + ext: { + rtiPartner: 'idl' + } + }] + } + ]; + describe('inherited functions', function () { it('should exists and is a function', function () { const adapter = newBidder(spec); @@ -365,13 +381,16 @@ describe('IndexexchangeAdapter', function () { request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; query = request.data; }); + afterEach(function () { delete window.headertag; }); + describe('buildRequestSingleRTI', function () { before(function () { testCopy = JSON.parse(JSON.stringify(DEFAULT_IDENTITY_RESPONSE)); }); + it('payload should have correct format and value (single identity partner)', function () { const payload = JSON.parse(query.r); @@ -400,6 +419,7 @@ describe('IndexexchangeAdapter', function () { } ); }); + it('payload should have correct format and value (single identity w/ multi ids)', function () { const payload = JSON.parse(query.r); @@ -443,6 +463,7 @@ describe('IndexexchangeAdapter', function () { } } }); + it('payload should have correct format and value (multiple identity partners)', function () { const payload = JSON.parse(query.r); @@ -519,6 +540,177 @@ describe('IndexexchangeAdapter', function () { }); }); + describe('buildRequestsUserId', function () { + let validIdentityResponse; + let validUserIdPayload; + + beforeEach(function () { + window.headertag = {}; + window.headertag.getIdentityInfo = function () { + return validIdentityResponse; + }; + }); + + afterEach(function () { + delete window.headertag; + }); + + it('IX adapter reads LiveRamp IDL envelope from Prebid and adds it to Video', function () { + const cloneValidBid = utils.deepClone(DEFAULT_VIDEO_VALID_BID); + cloneValidBid[0].userId = utils.deepClone(DEFAULT_USERID_DATA); + + const request = spec.buildRequests(cloneValidBid, DEFAULT_OPTION)[0]; + const payload = JSON.parse(request.data.r); + + expect(payload.user.eids).to.have.lengthOf(1); + expect(payload.user.eids).to.deep.include(DEFAULT_USERID_PAYLOAD[0]); + }); + + it('We continue to send in IXL identity info and Prebid takes precedence over IXL', function () { + validIdentityResponse = { + AdserverOrgIp: { + responsePending: false, + data: { + source: 'adserver.org', + uids: [ + { + id: '1234-5678-9012-3456', + ext: { + rtiPartner: 'TDID' + } + }, + { + id: 'FALSE', + ext: { + rtiPartner: 'TDID_LOOKUP' + } + }, + { + id: '2020-06-24T14:43:48.860Z', + ext: { + rtiPartner: 'TDID_CREATED_AT' + } + } + ] + } + }, + MerkleIp: { + responsePending: false, + data: { + source: 'merkle.com', + uids: [{ + id: '1234-5678-9012-3456', + ext: { + keyID: '1234-5678', + enc: 1 + } + }] + } + }, + LiveRampIp: { + source: 'liveramp.com', + uids: [ + { + id: '0000-1234-4567-8901', + ext: { + rtiPartner: 'idl' + } + } + ] + } + }; + + const cloneValidBid = utils.deepClone(DEFAULT_BANNER_VALID_BID); + cloneValidBid[0].userId = utils.deepClone(DEFAULT_USERID_DATA) + + const request = spec.buildRequests(cloneValidBid, DEFAULT_OPTION)[0]; + const payload = JSON.parse(request.data.r); + + validUserIdPayload = utils.deepClone(DEFAULT_USERID_PAYLOAD); + validUserIdPayload.push({ + source: 'merkle.com', + uids: [{ + id: '1234-5678-9012-3456', + ext: { + keyID: '1234-5678', + enc: 1 + } + }] + }) + validUserIdPayload.push({ + source: 'adserver.org', + uids: [ + { + id: '1234-5678-9012-3456', + ext: { + rtiPartner: 'TDID' + } + }, + { + id: 'FALSE', + ext: { + rtiPartner: 'TDID_LOOKUP' + } + }, + { + id: '2020-06-24T14:43:48.860Z', + ext: { + rtiPartner: 'TDID_CREATED_AT' + } + } + ] + }) + + expect(payload.user).to.exist; + expect(payload.user.eids).to.have.lengthOf(3); + expect(payload.user.eids).to.deep.include(validUserIdPayload[0]); + expect(payload.user.eids).to.deep.include(validUserIdPayload[1]); + expect(payload.user.eids).to.deep.include(validUserIdPayload[2]); + }); + + it('IXL and Prebid are mutually exclusive', function () { + validIdentityResponse = { + LiveIntentIp: { + responsePending: false, + data: { + source: 'liveintent.com', + uids: [{ + id: '1234-5678-9012-3456', + ext: { + keyID: '1234-5678', + rtiPartner: 'LDID', + enc: 1 + } + }] + } + } + }; + + const cloneValidBid = utils.deepClone(DEFAULT_VIDEO_VALID_BID); + cloneValidBid[0].userId = utils.deepClone(DEFAULT_USERID_DATA); + + const request = spec.buildRequests(cloneValidBid, DEFAULT_OPTION)[0]; + + validUserIdPayload = utils.deepClone(DEFAULT_USERID_PAYLOAD); + validUserIdPayload.push({ + source: 'liveintent.com', + uids: [{ + id: '1234-5678-9012-3456', + ext: { + keyID: '1234-5678', + rtiPartner: 'LDID', + enc: 1 + } + }] + }); + + const payload = JSON.parse(request.data.r); + expect(payload.user.eids).to.have.lengthOf(2); + expect(payload.user.eids).to.deep.include(validUserIdPayload[0]); + expect(payload.user.eids).to.deep.include(validUserIdPayload[1]); + }); + }); + describe('buildRequests', function () { const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; const requestUrl = request.url; @@ -561,7 +753,7 @@ describe('IndexexchangeAdapter', function () { expect(payload.source.ext.schain).to.deep.equal(SAMPLE_SCHAIN); expect(payload.imp).to.exist; expect(payload.imp).to.be.an('array'); - expect(payload.imp).to.have.lengthOf(1); + expect(payload.imp).to.have.lengthOf(2); }); it('payload should not include schain when not provided', function () { @@ -735,6 +927,7 @@ describe('IndexexchangeAdapter', function () { const request = spec.buildRequests([DEFAULT_BANNER_VALID_BID[0], DEFAULT_VIDEO_VALID_BID[0]]); const bannerImp = JSON.parse(request[0].data.r).imp[0]; + expect(JSON.parse(request[0].data.r).imp).to.have.lengthOf(2); expect(JSON.parse(request[0].data.v)).to.equal(BANNER_ENDPOINT_VERSION); expect(bannerImp.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidId); expect(bannerImp.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidId); @@ -749,6 +942,80 @@ describe('IndexexchangeAdapter', function () { expect(videoImp.video.w).to.equal(DEFAULT_VIDEO_VALID_BID[0].params.size[0]); expect(videoImp.video.h).to.equal(DEFAULT_VIDEO_VALID_BID[0].params.size[1]); }); + + it('request should contain the extra banner ad sizes that IX is not configured for using the first site id in the ad unit', function () { + const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); + bid.sizes.push([336, 280], [970, 90]); + bid.mediaTypes.banner.sizes.push([336, 280], [970, 90]); + const bid2 = utils.deepClone(bid); + bid2.params.siteId = '124'; + bid2.params.size = [300, 600]; + bid2.params.bidId = '2b3c4d5e'; + + const request = spec.buildRequests([bid, bid2], DEFAULT_OPTION)[0]; + const impressions = JSON.parse(request.data.r).imp; + + expect(impressions).to.be.an('array'); + expect(impressions).to.have.lengthOf(4); + + expect(impressions[0].ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()) + expect(impressions[1].ext.siteID).to.equal(bid2.params.siteId) + expect(impressions[2].ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()) + expect(impressions[3].ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()) + + expect(impressions[0].banner.w).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[0]); + expect(impressions[0].banner.h).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[1]); + expect(impressions[1].banner.w).to.equal(bid2.params.size[0]); + expect(impressions[1].banner.h).to.equal(bid2.params.size[1]); + expect(impressions[2].banner.w).to.equal(bid.mediaTypes.banner.sizes[2][0]); + expect(impressions[2].banner.h).to.equal(bid.mediaTypes.banner.sizes[2][1]); + expect(impressions[3].banner.w).to.equal(bid.mediaTypes.banner.sizes[3][0]); + expect(impressions[3].banner.h).to.equal(bid.mediaTypes.banner.sizes[3][1]); + }); + + it('request should contain the extra banner ad sizes and their corresponding site ids when there is multiple ad units', function () { + const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); + bid.params.siteId = '124'; + bid.adUnitCode = 'div-gpt-ad-156456451554-1' + bid.transactionId = '152e36d1-1241-4242-t35e-y1dv34d12315'; + bid.bidId = '2f6g5s5e'; + bid.params.size = [336, 280] + bid.sizes = [[336, 280], [970, 90]] + bid.mediaTypes.banner.sizes = [[336, 280], [970, 90]] + + const request = spec.buildRequests([DEFAULT_BANNER_VALID_BID[0], bid], DEFAULT_OPTION)[0]; + + const impressions = JSON.parse(request.data.r).imp; + expect(impressions).to.be.an('array'); + expect(impressions).to.have.lengthOf(4); + + expect(impressions[0].ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()) + expect(impressions[1].ext.siteID).to.equal(bid.params.siteId) + expect(impressions[2].ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()) + expect(impressions[3].ext.siteID).to.equal(bid.params.siteId) + + expect(impressions[0].banner.w).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[0]); + expect(impressions[0].banner.h).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[1]); + expect(impressions[1].banner.w).to.equal(bid.params.size[0]); + expect(impressions[1].banner.h).to.equal(bid.params.size[1]); + expect(impressions[2].banner.w).to.equal(DEFAULT_BANNER_VALID_BID[0].mediaTypes.banner.sizes[1][0]); + expect(impressions[2].banner.h).to.equal(DEFAULT_BANNER_VALID_BID[0].mediaTypes.banner.sizes[1][1]); + expect(impressions[3].banner.w).to.equal(bid.mediaTypes.banner.sizes[1][0]); + expect(impressions[3].banner.h).to.equal(bid.mediaTypes.banner.sizes[1][1]); + + expect(impressions[0].ext.sid).to.equal(`${DEFAULT_BANNER_VALID_BID[0].params.size[0].toString()}x${DEFAULT_BANNER_VALID_BID[0].params.size[1].toString()}`); + expect(impressions[1].ext.sid).to.equal(`${bid.params.size[0].toString()}x${bid.params.size[1].toString()}`); + expect(impressions[2].ext.sid).to.equal(`${DEFAULT_BANNER_VALID_BID[0].mediaTypes.banner.sizes[1][0].toString()}x${DEFAULT_BANNER_VALID_BID[0].mediaTypes.banner.sizes[1][1].toString()}`); + expect(impressions[3].ext.sid).to.equal(`${bid.mediaTypes.banner.sizes[1][0].toString()}x${bid.mediaTypes.banner.sizes[1][1].toString()}`); + }); + + it('request should not contain the extra video ad sizes that IX is not configured for', function () { + const request = spec.buildRequests(DEFAULT_VIDEO_VALID_BID, DEFAULT_OPTION); + const impressions = JSON.parse(request[0].data.r).imp; + + expect(impressions).to.be.an('array'); + expect(impressions).to.have.lengthOf(1); + }); }); describe('buildRequestVideo', function () { From 5fb426b2f76191a7e27aee57396dd974af9e5a66 Mon Sep 17 00:00:00 2001 From: yuvalgg <57989766+yuvalgg@users.noreply.github.com> Date: Wed, 15 Jul 2020 16:35:59 +0300 Subject: [PATCH 483/496] Feature/intent iq id added (#5428) * Added intentiq id sub module * Update eids with intentiq * Added intentiq submodule into unit tests * IntentIqId added Support in all of userId tests Support in eids module Added the iiqSystem submodule Support to userId example html file * Added SharedID to spec tests * Fixed unit tests --- integrationExamples/gpt/userId_example.html | 13 +- modules/intentIqIdSystem.js | 68 +++++++++++ modules/userId/eids.js | 6 + test/spec/modules/userId_spec.js | 125 ++++++++++++-------- 4 files changed, 164 insertions(+), 48 deletions(-) create mode 100644 modules/intentIqIdSystem.js diff --git a/integrationExamples/gpt/userId_example.html b/integrationExamples/gpt/userId_example.html index 69e2c713fb8..4acbe0aae31 100644 --- a/integrationExamples/gpt/userId_example.html +++ b/integrationExamples/gpt/userId_example.html @@ -140,7 +140,18 @@ name: "unifiedid", expires: 30 }, - }, { + },{ + name: "intentIqId", + params: { + partner: 0, //Set your real IntentIQ partner ID here for production. + }, + storage: { + type: "cookie", + name: "intentIqId", + expires: 30 + }, + }, + { name: "id5Id", params: { partner: 173 //Set your real ID5 partner ID here for production, please ask for one at http://id5.io/prebid diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js new file mode 100644 index 00000000000..7d497ea9b1a --- /dev/null +++ b/modules/intentIqIdSystem.js @@ -0,0 +1,68 @@ +/** + * This module adds IntentIqId to the User ID module + * The {@link module:modules/userId} module is required + * @module modules/intentIqIdSystem + * @requires module:modules/userId + */ + +import * as utils from '../src/utils.js' +import {ajax} from '../src/ajax.js'; +import {submodule} from '../src/hook.js' + +const MODULE_NAME = 'intentIqId'; + +/** @type {Submodule} */ +export const intentIqIdSubmodule = { + /** + * used to link submodule with config + * @type {string} + */ + name: MODULE_NAME, + /** + * decode the stored id value for passing to bid requests + * @function + * @param {{ctrid:string}} value + * @returns {{intentIqId:string}} + */ + decode(value) { + return (value && typeof value['ctrid'] === 'string') ? { 'intentIqId': value['ctrid'] } : undefined; + }, + /** + * performs action to obtain id and return a value in the callback's response argument + * @function + * @param {SubmoduleParams} [configParams] + * @returns {IdResponse|undefined} + */ + getId(configParams) { + if (!configParams || typeof configParams.partner !== 'number') { + utils.logError('User ID - intentIqId submodule requires a valid partner to be defined'); + return; + } + + // use protocol relative urls for http or https + const url = `https://api.intentiq.com/profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=${configParams.partner}&pt=17&dpn=1`; + const resp = function (callback) { + const callbacks = { + success: response => { + let responseObj; + if (response) { + try { + responseObj = JSON.parse(response); + } catch (error) { + utils.logError(error); + } + } + callback(responseObj); + }, + error: error => { + utils.logError(`${MODULE_NAME}: ID fetch encountered an error`, error); + callback(); + } + }; + ajax(url, callbacks, undefined, {method: 'GET', withCredentials: true}); + }; + return {callback: resp}; + } +}; + +submodule('userId', intentIqIdSubmodule); diff --git a/modules/userId/eids.js b/modules/userId/eids.js index 1261e2ea7d9..d3f32fbdd31 100644 --- a/modules/userId/eids.js +++ b/modules/userId/eids.js @@ -5,6 +5,12 @@ const USER_IDS_CONFIG = { // key-name : {config} + // intentIqId + 'intentIqId': { + source: 'intentiq.com', + atype: 1 + }, + // pubCommonId 'pubcid': { source: 'pubcid.org', diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index 5dda322f3c8..d038074cb10 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -20,6 +20,7 @@ import {id5IdSubmodule} from 'modules/id5IdSystem.js'; import {identityLinkSubmodule} from 'modules/identityLinkIdSystem.js'; import {liveIntentIdSubmodule} from 'modules/liveIntentIdSystem.js'; import {netIdSubmodule} from 'modules/netIdSystem.js'; +import {intentIqIdSubmodule} from 'modules/intentIqIdSystem.js'; import {sharedIdSubmodule} from 'modules/sharedIdSystem.js'; import {server} from 'test/mocks/xhr.js'; @@ -28,7 +29,7 @@ let expect = require('chai').expect; const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; describe('User ID', function() { - function getConfigMock(configArr1, configArr2, configArr3, configArr4, configArr5, configArr6, configArr7) { + function getConfigMock(configArr1, configArr2, configArr3, configArr4, configArr5, configArr6, configArr7, configArr8) { return { userSync: { syncDelay: 0, @@ -39,7 +40,8 @@ describe('User ID', function() { (configArr4 && configArr4.length >= 3) ? getStorageMock.apply(null, configArr4) : null, (configArr5 && configArr5.length >= 3) ? getStorageMock.apply(null, configArr5) : null, (configArr6 && configArr6.length >= 3) ? getStorageMock.apply(null, configArr6) : null, - (configArr7 && configArr7.length >= 3) ? getStorageMock.apply(null, configArr7) : null + (configArr7 && configArr7.length >= 3) ? getStorageMock.apply(null, configArr7) : null, + (configArr8 && configArr8.length >= 3) ? getStorageMock.apply(null, configArr8) : null ].filter(i => i) } } @@ -338,22 +340,22 @@ describe('User ID', function() { }); it('handles config with no usersync object', function() { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule]); init(config); config.setConfig({}); // usersync is undefined, and no logInfo message for 'User ID - usersync config updated' expect(typeof utils.logInfo.args[0]).to.equal('undefined'); }); - it('handles config with empty usersync object', function() { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); + it('handles config with empty usersync object', function () { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule]); init(config); config.setConfig({userSync: {}}); expect(typeof utils.logInfo.args[0]).to.equal('undefined'); }); - it('handles config with usersync and userIds that are empty objs', function() { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); + it('handles config with usersync and userIds that are empty objs', function () { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule]); init(config); config.setConfig({ userSync: { @@ -363,8 +365,8 @@ describe('User ID', function() { expect(typeof utils.logInfo.args[0]).to.equal('undefined'); }); - it('handles config with usersync and userIds with empty names or that dont match a submodule.name', function() { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); + it('handles config with usersync and userIds with empty names or that dont match a submodule.name', function () { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule]); init(config); config.setConfig({ userSync: { @@ -380,16 +382,16 @@ describe('User ID', function() { expect(typeof utils.logInfo.args[0]).to.equal('undefined'); }); - it('config with 1 configurations should create 1 submodules', function() { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); + it('config with 1 configurations should create 1 submodules', function () { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule]); init(config); config.setConfig(getConfigMock(['unifiedId', 'unifiedid', 'cookie'])); expect(utils.logInfo.args[0][0]).to.exist.and.to.equal('User ID - usersync config updated for 1 submodules'); }); - it('config with 8 configurations should result in 8 submodules add', function() { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, liveIntentIdSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule]); + it('config with 9 configurations should result in 9 submodules add', function () { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, liveIntentIdSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule]); init(config); config.setConfig({ userSync: { @@ -417,14 +419,17 @@ describe('User ID', function() { }, { name: 'sharedId', storage: {name: 'sharedid', type: 'cookie'} + }, { + name: 'intentIqId', + storage: { name: 'intentIqId', type: 'cookie' } }] } }); - expect(utils.logInfo.args[0][0]).to.exist.and.to.equal('User ID - usersync config updated for 8 submodules'); + expect(utils.logInfo.args[0][0]).to.exist.and.to.equal('User ID - usersync config updated for 9 submodules'); }); - it('config syncDelay updates module correctly', function() { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); + it('config syncDelay updates module correctly', function () { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule]); init(config); config.setConfig({ userSync: { @@ -438,8 +443,8 @@ describe('User ID', function() { expect(syncDelay).to.equal(99); }); - it('config auctionDelay updates module correctly', function() { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); + it('config auctionDelay updates module correctly', function () { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule]); init(config); config.setConfig({ userSync: { @@ -453,8 +458,8 @@ describe('User ID', function() { expect(auctionDelay).to.equal(100); }); - it('config auctionDelay defaults to 0 if not a number', function() { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule]); + it('config auctionDelay defaults to 0 if not a number', function () { + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule]); init(config); config.setConfig({ userSync: { @@ -1075,16 +1080,41 @@ describe('User ID', function() { }, {adUnits}); }); - it('test hook when pubCommonId, unifiedId, id5Id, identityLink, britepoolId, netId and sharedId have data to pass', function(done) { + it('test hook from intentIqId cookies', function(done) { + // simulate existing browser local storage values + coreStorage.setCookie('intentIqId', JSON.stringify({'ctrid': 'abcdefghijk'}), (new Date(Date.now() + 5000).toUTCString())); + + setSubmoduleRegistry([intentIqIdSubmodule]); + init(config); + config.setConfig(getConfigMock(['intentIqId', 'intentIqId', 'cookie'])); + + requestBidsHook(function() { + adUnits.forEach(unit => { + unit.bids.forEach(bid => { + expect(bid).to.have.deep.nested.property('userId.intentIqId'); + expect(bid.userId.intentIqId).to.equal('abcdefghijk'); + expect(bid.userIdAsEids[0]).to.deep.equal({ + source: 'intentiq.com', + uids: [{id: 'abcdefghijk', atype: 1}] + }); + }); + }); + coreStorage.setCookie('intentIqId', '', EXPIRED_COOKIE_DATE); + done(); + }, {adUnits}); + }); + + it('test hook when pubCommonId, unifiedId, id5Id, identityLink, britepoolId, intentIqId, sharedId and netId have data to pass', function(done) { coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('unifiedid', JSON.stringify({'TDID': 'testunifiedid'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('id5id', JSON.stringify({'universal_uid': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('idl_env', 'AiGNC8Z5ONyZKSpIPf', (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), (new Date(Date.now() + 5000).toUTCString())); + coreStorage.setCookie('intentIqId', JSON.stringify({'ctrid': 'testintentIqId'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('sharedid', JSON.stringify({'id': 'test_sharedId', 'ts': 1590525289611}), (new Date(Date.now() + 5000).toUTCString())); - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule]); + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule]); init(config); config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'], ['unifiedId', 'unifiedid', 'cookie'], @@ -1092,7 +1122,8 @@ describe('User ID', function() { ['identityLink', 'idl_env', 'cookie'], ['britepoolId', 'britepoolid', 'cookie'], ['netId', 'netId', 'cookie'], - ['sharedId', 'sharedid', 'cookie'])); + ['sharedId', 'sharedid', 'cookie'], + ['intentIqId', 'intentIqId', 'cookie'])); requestBidsHook(function() { adUnits.forEach(unit => { @@ -1120,7 +1151,10 @@ describe('User ID', function() { id: 'test_sharedId', third: 'test_sharedId' }); - expect(bid.userIdAsEids.length).to.equal(7); + // also check that intentIqId id data was copied to bid + expect(bid).to.have.deep.nested.property('userId.intentIqId'); + expect(bid.userId.intentIqId).to.equal('testintentIqId'); + expect(bid.userIdAsEids.length).to.equal(8); }); }); coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); @@ -1130,29 +1164,12 @@ describe('User ID', function() { coreStorage.setCookie('britepoolid', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('netId', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); + coreStorage.setCookie('intentIqId', '', EXPIRED_COOKIE_DATE); done(); }, {adUnits}); }); - it('test hook when sharedId (opted out) have data to pass', function(done) { - coreStorage.setCookie('sharedid', JSON.stringify({'id': '00000000000000000000000000', 'ts': 1590525289611}), (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([sharedIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['sharedId', 'sharedid', 'cookie'])); - - requestBidsHook(function() { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid.userIdAsEids).to.be.undefined; - }); - }); - coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook when pubCommonId, unifiedId, id5Id, britepoolId, netId and sharedId have their modules added before and after init', function(done) { + it('test hook when pubCommonId, unifiedId, id5Id, britepoolId, intentIqId, sharedId and netId have their modules added before and after init', function(done) { coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('unifiedid', JSON.stringify({'TDID': 'cookie-value-add-module-variations'}), new Date(Date.now() + 5000).toUTCString()); coreStorage.setCookie('id5id', JSON.stringify({'universal_uid': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); @@ -1160,6 +1177,7 @@ describe('User ID', function() { coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('sharedid', JSON.stringify({'id': 'test_sharedId', 'ts': 1590525289611}), (new Date(Date.now() + 5000).toUTCString())); + coreStorage.setCookie('intentIqId', JSON.stringify({'ctrid': 'testintentIqId'}), (new Date(Date.now() + 5000).toUTCString())); setSubmoduleRegistry([]); @@ -1175,6 +1193,7 @@ describe('User ID', function() { attachIdSystem(britepoolIdSubmodule); attachIdSystem(netIdSubmodule); attachIdSystem(sharedIdSubmodule); + attachIdSystem(intentIqIdSubmodule); config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'], ['unifiedId', 'unifiedid', 'cookie'], @@ -1182,7 +1201,8 @@ describe('User ID', function() { ['identityLink', 'idl_env', 'cookie'], ['britepoolId', 'britepoolid', 'cookie'], ['netId', 'netId', 'cookie'], - ['sharedId', 'sharedid', 'cookie'])); + ['sharedId', 'sharedid', 'cookie'], + ['intentIqId', 'intentIqId', 'cookie'])); requestBidsHook(function() { adUnits.forEach(unit => { @@ -1210,7 +1230,10 @@ describe('User ID', function() { id: 'test_sharedId', third: 'test_sharedId' }); - expect(bid.userIdAsEids.length).to.equal(7); + // also check that intentIqId id data was copied to bid + expect(bid).to.have.deep.nested.property('userId.intentIqId'); + expect(bid.userId.intentIqId).to.equal('testintentIqId'); + expect(bid.userIdAsEids.length).to.equal(8); }); }); coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); @@ -1220,6 +1243,7 @@ describe('User ID', function() { coreStorage.setCookie('britepoolid', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('netId', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); + coreStorage.setCookie('intentIqId', '', EXPIRED_COOKIE_DATE); done(); }, {adUnits}); }); @@ -1253,9 +1277,10 @@ describe('User ID', function() { coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), new Date(Date.now() + 5000).toUTCString()); coreStorage.setCookie('sharedid', JSON.stringify({'id': 'test_sharedId', 'ts': 1590525289611}), new Date(Date.now() + 5000).toUTCString()); + coreStorage.setCookie('intentIqId', JSON.stringify({'ctrid': 'testintentIqId'}), (new Date(Date.now() + 5000).toUTCString())); coreStorage.setCookie('MOCKID', JSON.stringify({'MOCKID': '123456778'}), new Date(Date.now() + 5000).toUTCString()); - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule]); + setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule]); init(config); config.setConfig({ @@ -1275,6 +1300,8 @@ describe('User ID', function() { name: 'netId', storage: {name: 'netId', type: 'cookie'} }, { name: 'sharedId', storage: {name: 'sharedid', type: 'cookie'} + }, { + name: 'intentIqId', storage: { name: 'intentIqId', type: 'cookie' } }, { name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} }] @@ -1325,7 +1352,10 @@ describe('User ID', function() { // check MockId data was copied to bid expect(bid).to.have.deep.nested.property('userId.mid'); expect(bid.userId.mid).to.equal('123456778'); - expect(bid.userIdAsEids.length).to.equal(7);// mid is unknown for eids.js + // also check that intentIqId id data was copied to bid + expect(bid).to.have.deep.nested.property('userId.intentIqId'); + expect(bid.userId.intentIqId).to.equal('testintentIqId'); + expect(bid.userIdAsEids.length).to.equal(8); }); }); coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); @@ -1335,6 +1365,7 @@ describe('User ID', function() { coreStorage.setCookie('britepoolid', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('netId', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); + coreStorage.setCookie('intentIqId', '', EXPIRED_COOKIE_DATE); coreStorage.setCookie('MOCKID', '', EXPIRED_COOKIE_DATE); done(); }, {adUnits}); From eca4da96b84cbe6000f6555a2e85b231014db4b3 Mon Sep 17 00:00:00 2001 From: Scott Date: Thu, 16 Jul 2020 00:16:02 +0200 Subject: [PATCH 484/496] update ID5 cookie name (#5478) --- modules/id5IdSystem.js | 4 ++-- modules/userId/userId.md | 2 +- test/spec/modules/id5IdSystem_spec.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/id5IdSystem.js b/modules/id5IdSystem.js index 3449926c896..ae3c7e55863 100644 --- a/modules/id5IdSystem.js +++ b/modules/id5IdSystem.js @@ -13,7 +13,7 @@ import { getStorageManager } from '../src/storageManager.js'; const MODULE_NAME = 'id5Id'; const GVLID = 131; -const BASE_NB_COOKIE_NAME = 'pbjs-id5id'; +const BASE_NB_COOKIE_NAME = 'id5id.1st'; const NB_COOKIE_EXP_DAYS = (30 * 24 * 60 * 60 * 1000); // 30 days const storage = getStorageManager(GVLID, MODULE_NAME); @@ -128,7 +128,7 @@ function hasRequiredParams(configParams) { return true; } function nbCookieName(configParams) { - return hasRequiredParams(configParams) ? `${BASE_NB_COOKIE_NAME}-${configParams.partner}-nb` : undefined; + return hasRequiredParams(configParams) ? `${BASE_NB_COOKIE_NAME}_${configParams.partner}_nb` : undefined; } function nbCookieExpStr(expDays) { return (new Date(Date.now() + expDays)).toUTCString(); diff --git a/modules/userId/userId.md b/modules/userId/userId.md index 20b140c3900..566d719c90d 100644 --- a/modules/userId/userId.md +++ b/modules/userId/userId.md @@ -30,7 +30,7 @@ pbjs.setConfig({ }, storage: { type: "cookie", - name: "id5id", + name: "id5id.1st", expires: 90, // Expiration of cookies in days refreshInSeconds: 8*3600 // User Id cache lifetime in seconds, defaulting to 'expires' }, diff --git a/test/spec/modules/id5IdSystem_spec.js b/test/spec/modules/id5IdSystem_spec.js index 5080cd94bd8..05ecec8dc36 100644 --- a/test/spec/modules/id5IdSystem_spec.js +++ b/test/spec/modules/id5IdSystem_spec.js @@ -14,7 +14,7 @@ describe('ID5 ID System', function() { const ID5_PARTNER = 173; const ID5_ENDPOINT = `https://id5-sync.com/g/v2/${ID5_PARTNER}.json`; const ID5_COOKIE_NAME = 'id5idcookie'; - const ID5_NB_COOKIE_NAME = `pbjs-id5id-${ID5_PARTNER}-nb`; + const ID5_NB_COOKIE_NAME = `id5id.1st_${ID5_PARTNER}_nb`; const ID5_EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; const ID5_STORED_ID = 'storedid5id'; const ID5_STORED_SIGNATURE = '123456'; From c727ca66ddfd34ce2946f42e73da1bbd938415cb Mon Sep 17 00:00:00 2001 From: hdeodhar <35999856+hdeodhar@users.noreply.github.com> Date: Wed, 15 Jul 2020 23:26:36 +0100 Subject: [PATCH 485/496] Added new size - Id 7 (125x125) (#5483) --- modules/rubiconBidAdapter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index f09bc51e2c5..cd621010a9b 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -28,6 +28,7 @@ var sizeMap = { 1: '468x60', 2: '728x90', 5: '120x90', + 7: '125x125', 8: '120x600', 9: '160x600', 10: '300x600', From e43b4142f3791187e622d87ff9f33e92ae8a1d2a Mon Sep 17 00:00:00 2001 From: Nick Jacob Date: Wed, 15 Jul 2020 18:34:07 -0400 Subject: [PATCH 486/496] removing endpoint as required parameter + updating contact email (#5489) --- modules/amxBidAdapter.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/amxBidAdapter.md b/modules/amxBidAdapter.md index 5526ef8b6b9..4577f5f4f7c 100644 --- a/modules/amxBidAdapter.md +++ b/modules/amxBidAdapter.md @@ -4,7 +4,7 @@ Overview ``` Module Name: AMX Adapter Module Type: Bidder Adapter -Maintainer: prebid.support@amxrtb.com +Maintainer: prebid@amxrtb.com ``` Description @@ -16,7 +16,6 @@ This module connects web publishers to AMX RTB video and display demand. | Key | Required | Example | Description | | --- | -------- | ------- | ----------- | -| `endpoint` | **yes** | `https://prebid.a-mo.net/a/c` | The url including https:// and any path | | `testMode` | no | `true` | this will activate test mode / 100% fill with sample ads | | `tagId` | no | `"cHJlYmlkLm9yZw"` | can be used for more specific targeting of inventory. Your account manager will provide this ID if needed | From b110d9776340b4dc8f0f0a6b76409be3654cda43 Mon Sep 17 00:00:00 2001 From: JonGoSonobi Date: Wed, 15 Jul 2020 20:52:10 -0400 Subject: [PATCH 487/496] removed digitrust from sonobi adapter (#5491) --- modules/sonobiBidAdapter.js | 22 ------------ test/spec/modules/sonobiBidAdapter_spec.js | 41 ---------------------- 2 files changed, 63 deletions(-) diff --git a/modules/sonobiBidAdapter.js b/modules/sonobiBidAdapter.js index ee201a72bf2..a55992cec22 100644 --- a/modules/sonobiBidAdapter.js +++ b/modules/sonobiBidAdapter.js @@ -8,7 +8,6 @@ import { userSync } from '../src/userSync.js'; const BIDDER_CODE = 'sonobi'; const STR_ENDPOINT = 'https://apex.go.sonobi.com/trinity.json'; const PAGEVIEW_ID = generateUUID(); -const SONOBI_DIGITRUST_KEY = 'fhnS5drwmH'; const OUTSTREAM_REDNERER_URL = 'https://mtrx.go.sonobi.com/sbi_outstream_renderer.js'; export const spec = { @@ -114,13 +113,6 @@ export const spec = { } } - const digitrust = _getDigiTrustObject(SONOBI_DIGITRUST_KEY); - - if (digitrust) { - payload.digid = digitrust.id; - payload.digkeyv = digitrust.keyv; - } - if (validBidRequests[0].schain) { payload.schain = JSON.stringify(validBidRequests[0].schain) } @@ -336,20 +328,6 @@ export function _getPlatform(context = window) { return 'desktop'; } -// https://github.com/digi-trust/dt-cdn/wiki/Integration-Guide -function _getDigiTrustObject(key) { - function getDigiTrustId() { - let digiTrustUser = window.DigiTrust && (config.getConfig('digiTrustId') || window.DigiTrust.getUser({member: key})); - return (digiTrustUser && digiTrustUser.success && digiTrustUser.identity) || null; - } - let digiTrustId = getDigiTrustId(); - // Verify there is an ID and this user has not opted out - if (!digiTrustId || (digiTrustId.privacy && digiTrustId.privacy.optout)) { - return null; - } - return digiTrustId; -} - function newRenderer(adUnitCode, bid, rendererOptions = {}) { const renderer = Renderer.install({ id: bid.aid, diff --git a/test/spec/modules/sonobiBidAdapter_spec.js b/test/spec/modules/sonobiBidAdapter_spec.js index 019edd84c9f..52821072a21 100644 --- a/test/spec/modules/sonobiBidAdapter_spec.js +++ b/test/spec/modules/sonobiBidAdapter_spec.js @@ -303,47 +303,6 @@ describe('SonobiBidAdapter', function () { }, uspConsent: 'someCCPAString' }; - it('should include the digitrust id and keyv', () => { - window.DigiTrust = { - getUser: function () { - } - }; - let sandbox = sinon.sandbox.create(); - sandbox.stub(window.DigiTrust, 'getUser').callsFake(() => - ({ - success: true, - identity: { - id: 'Vb0YJIxTMJV4W0GHRdJ3MwyiOVYJjYEgc2QYdBSG', - keyv: 4, - version: 2, - privacy: {} - } - }) - ); - const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.data.digid).to.equal('Vb0YJIxTMJV4W0GHRdJ3MwyiOVYJjYEgc2QYdBSG'); - expect(bidRequests.data.digkeyv).to.equal(4); - sandbox.restore(); - delete window.DigiTrust; - }); - - it('should not include the digitrust id and keyv', () => { - window.DigiTrust = { - getUser: function () { - } - }; - let sandbox = sinon.sandbox.create(); - sandbox.stub(window.DigiTrust, 'getUser').callsFake(() => - ({ - success: false - }) - ); - const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.data.digid).to.be.undefined; - expect(bidRequests.data.digkeyv).to.be.undefined; - sandbox.restore(); - delete window.DigiTrust; - }); it('should return a properly formatted request', function () { const bidRequests = spec.buildRequests(bidRequest, bidderRequests) From dbfa54315beb2b48681ee80d2137941b71390cc4 Mon Sep 17 00:00:00 2001 From: mamatic <52153441+mamatic@users.noreply.github.com> Date: Thu, 16 Jul 2020 03:01:02 +0200 Subject: [PATCH 488/496] ATS-analytics - fix check for safari browser (#5474) * ATS-analytics - fix check for safari browser * ATS-analytics - add unit tests for browser checks * ATS-analytics - fix unit tests for browser checks * ATS-analytics - fix unit tests for browser safari checks * ATS-analytics - change name for browser do not found * ATS-analytics - add new logic for determine user browser * ATS-analytics - add test for checking firefox browser --- modules/atsAnalyticsAdapter.js | 22 ++++++- test/spec/modules/atsAnalyticsAdapter_spec.js | 62 ++++++++++++++++++- 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/modules/atsAnalyticsAdapter.js b/modules/atsAnalyticsAdapter.js index 7bf2ca75c17..ad488aa50d9 100644 --- a/modules/atsAnalyticsAdapter.js +++ b/modules/atsAnalyticsAdapter.js @@ -18,7 +18,7 @@ function bidRequestedHandler(args) { bidder: bid.bidder, bid_id: bid.bidId, auction_id: args.auctionId, - user_browser: (browserIsFirefox() || browserIsEdge() || browserIsChrome() || browserIsSafari()), + user_browser: checkUserBrowser(), user_platform: navigator.platform, auction_start: new Date(args.auctionStart).toJSON(), domain: window.location.hostname, @@ -38,6 +38,24 @@ function bidResponseHandler(args) { }; } +export function checkUserBrowser() { + let firefox = browserIsFirefox(); + let chrome = browserIsChrome(); + let edge = browserIsEdge(); + let safari = browserIsSafari(); + if (firefox) { + return firefox; + } if (chrome) { + return chrome; + } if (edge) { + return edge; + } if (safari) { + return safari; + } else { + return 'Unknown' + } +} + export function browserIsFirefox() { if (typeof InstallTrigger !== 'undefined') { return 'Firefox'; @@ -67,7 +85,7 @@ export function browserIsChrome() { } export function browserIsSafari() { - if (navigator.vendor.indexOf('Apple')) { + if (window.safari !== undefined) { return 'Safari' } else { return false; diff --git a/test/spec/modules/atsAnalyticsAdapter_spec.js b/test/spec/modules/atsAnalyticsAdapter_spec.js index 3dd6f261c11..849ccf88c51 100644 --- a/test/spec/modules/atsAnalyticsAdapter_spec.js +++ b/test/spec/modules/atsAnalyticsAdapter_spec.js @@ -2,7 +2,7 @@ import atsAnalyticsAdapter from '../../../modules/atsAnalyticsAdapter.js'; import { expect } from 'chai'; import adapterManager from 'src/adapterManager.js'; import {server} from '../../mocks/xhr.js'; -import {browserIsChrome, browserIsEdge, browserIsFirefox, browserIsSafari} from '../../../modules/atsAnalyticsAdapter.js'; +import {checkUserBrowser, browserIsChrome, browserIsEdge, browserIsSafari, browserIsFirefox} from '../../../modules/atsAnalyticsAdapter.js'; let events = require('src/events'); let constants = require('src/constants.json'); @@ -77,7 +77,7 @@ describe('ats analytics adapter', function () { 'bidder': 'appnexus', 'bid_id': '30c77d079cdf17', 'auction_id': 'a5b849e5-87d7-4205-8300-d063084fcfb7', - 'user_browser': (browserIsFirefox() || browserIsEdge() || browserIsChrome() || browserIsSafari()), + 'user_browser': checkUserBrowser(), 'user_platform': navigator.platform, 'auction_start': '2020-02-03T14:14:25.161Z', 'domain': window.location.hostname, @@ -146,5 +146,63 @@ describe('ats analytics adapter', function () { expect(atsAnalyticsAdapter.context.host).to.equal(initOptions.host); expect(atsAnalyticsAdapter.context.pid).to.equal(initOptions.pid); }) + it('check browser is not safari', function () { + window.safari = undefined; + let browser = browserIsSafari(); + expect(browser).to.equal(false); + }) + it('check browser is safari', function () { + window.safari = {}; + let browser = browserIsSafari(); + expect(browser).to.equal('Safari'); + }) + it('check browser is not chrome', function () { + window.chrome = { + app: undefined, + webstore: undefined, + runtime: undefined + }; + let browser = browserIsChrome(); + expect(browser).to.equal(false); + }) + it('check browser is chrome', function () { + window.chrome = { + app: {}, + webstore: {}, + runtime: {} + }; + let browser = browserIsChrome(); + expect(browser).to.equal('Chrome'); + }) + it('check browser is edge', function () { + Object.defineProperty(window, 'StyleMedia', { + value: {}, + writable: true + }); + Object.defineProperty(document, 'documentMode', { + value: undefined, + writable: true + }); + let browser = browserIsEdge(); + expect(browser).to.equal('Edge'); + }) + it('check browser is not edge', function () { + Object.defineProperty(document, 'documentMode', { + value: {}, + writable: true + }); + let browser = browserIsEdge(); + expect(browser).to.equal(false); + }) + it('check browser is firefox', function () { + global.InstallTrigger = {}; + let browser = browserIsFirefox(); + expect(browser).to.equal('Firefox'); + }) + it('check browser is not firefox', function () { + global.InstallTrigger = undefined; + let browser = browserIsFirefox(); + expect(browser).to.equal(false); + }) }) }) From 1049d07102adc315297537c5edf2ea137534c457 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Thu, 16 Jul 2020 07:02:02 -0700 Subject: [PATCH 489/496] PubMatic bidAdapter and analyticsAdapter (#5495) * added support for pubcommon, digitrust, id5id * added support for IdentityLink * changed the source for id5 * added unit test cases * changed source param for identityLink * passing piId in bid object * piId will be logged in PubMatic analytics too * if testGroupId is set in pbjs config then that value will be passed in PM analytics call * bid.piId ==> bid.partnerImpId * chnaged key names, added a Todo * capping testGroupId in 0-15; defaults to 0 * testGroupId should be INT --- modules/pubmaticAnalyticsAdapter.js | 12 ++++++++++- modules/pubmaticBidAdapter.js | 3 ++- .../modules/pubmaticAnalyticsAdapter_spec.js | 21 +++++++++++++++++++ test/spec/modules/pubmaticBidAdapter_spec.js | 2 ++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/modules/pubmaticAnalyticsAdapter.js b/modules/pubmaticAnalyticsAdapter.js index a19c6f095ad..d94c098db5d 100755 --- a/modules/pubmaticAnalyticsAdapter.js +++ b/modules/pubmaticAnalyticsAdapter.js @@ -152,6 +152,7 @@ function parseBidResponse(bid) { 'mediaType', 'params', 'mi', + 'partnerImpId', // partner impression ID 'dimensions', () => utils.pick(bid, [ 'width', 'height' @@ -188,7 +189,8 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) { 'mi': bid.bidResponse ? (bid.bidResponse.mi || undefined) : undefined, 'af': bid.bidResponse ? (bid.bidResponse.mediaType || undefined) : undefined, 'ocpm': bid.bidResponse ? (bid.bidResponse.originalCpm || 0) : 0, - 'ocry': bid.bidResponse ? (bid.bidResponse.originalCurrency || CURRENCY_USD) : CURRENCY_USD + 'ocry': bid.bidResponse ? (bid.bidResponse.originalCurrency || CURRENCY_USD) : CURRENCY_USD, + 'piid': bid.bidResponse ? (bid.bidResponse.partnerImpId || EMPTY_STRING) : EMPTY_STRING }); return partnerBids; }, []) @@ -218,6 +220,13 @@ function executeBidsLoggerCall(e, highestCpmBids) { outputObj['tst'] = Math.round((new window.Date()).getTime() / 1000); outputObj['pid'] = '' + profileId; outputObj['pdvid'] = '' + profileVersionId; + outputObj['tgid'] = (function() { + var testGroupId = parseInt(config.getConfig('testGroupId') || 0); + if (testGroupId <= 15 && testGroupId >= 0) { + return testGroupId; + } + return 0; + })(); // GDPR support if (auctionCache.gdprConsent) { @@ -267,6 +276,7 @@ function executeBidWonLoggerCall(auctionId, adUnitId) { pixelURL += '&en=' + enc(winningBid.bidResponse.bidPriceUSD); pixelURL += '&eg=' + enc(winningBid.bidResponse.bidGrossCpmUSD); pixelURL += '&kgpv=' + enc(winningBid.params.kgpv || adUnitId); + pixelURL += '&piid=' + enc(winningBid.bidResponse.partnerImpId || EMPTY_STRING); ajax( pixelURL, null, diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 7314d81aee6..a050d499640 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -952,7 +952,8 @@ export const spec = { referrer: parsedReferrer, ad: bid.adm, pm_seat: seatbidder.seat || null, - pm_dspid: bid.ext && bid.ext.dspid ? bid.ext.dspid : null + pm_dspid: bid.ext && bid.ext.dspid ? bid.ext.dspid : null, + partnerImpId: bid.id || '' // partner impression Id }; if (parsedRequest.imp && parsedRequest.imp.length > 0) { parsedRequest.imp.forEach(req => { diff --git a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js index bb9aa20f1b4..537ba4483cf 100755 --- a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +++ b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js @@ -31,6 +31,7 @@ const BID = { 'mediaType': 'video', 'statusMessage': 'Bid available', 'bidId': '2ecff0db240757', + 'partnerImpId': 'partnerImpressionID-1', 'adId': 'fake_ad_id', 'source': 's2s', 'requestId': '2ecff0db240757', @@ -69,6 +70,7 @@ const BID = { const BID2 = Object.assign({}, BID, { adUnitCode: '/19968336/header-bid-tag-1', bidId: '3bd4ebb1c900e2', + partnerImpId: 'partnerImpressionID-2', adId: 'fake_ad_id_2', requestId: '3bd4ebb1c900e2', width: 728, @@ -297,6 +299,10 @@ describe('pubmatic analytics adapter', function () { return [MOCK.BID_RESPONSE[0], MOCK.BID_RESPONSE[1]] }); + config.setConfig({ + testGroupId: 15 + }); + events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); @@ -322,6 +328,7 @@ describe('pubmatic analytics adapter', function () { expect(data.tst).to.equal(1519767016); expect(data.cns).to.equal('here-goes-gdpr-consent-string'); expect(data.gdpr).to.equal(1); + expect(data.tgid).to.equal(15); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); // slot 1 @@ -331,6 +338,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[0].ps.length).to.equal(1); expect(data.s[0].ps[0].pn).to.equal('pubmatic'); expect(data.s[0].ps[0].bidid).to.equal('2ecff0db240757'); + expect(data.s[0].ps[0].piid).to.equal('partnerImpressionID-1'); expect(data.s[0].ps[0].db).to.equal(0); expect(data.s[0].ps[0].kgpv).to.equal('/19968336/header-bid-tag-0'); expect(data.s[0].ps[0].kgpsv).to.equal('/19968336/header-bid-tag-0'); @@ -354,6 +362,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].ps.length).to.equal(1); expect(data.s[1].ps[0].pn).to.equal('pubmatic'); expect(data.s[1].ps[0].bidid).to.equal('3bd4ebb1c900e2'); + expect(data.s[1].ps[0].piid).to.equal('partnerImpressionID-2'); expect(data.s[1].ps[0].db).to.equal(0); expect(data.s[1].ps[0].kgpv).to.equal('this-is-a-kgpv'); expect(data.s[1].ps[0].kgpsv).to.equal('this-is-a-kgpv'); @@ -389,6 +398,7 @@ describe('pubmatic analytics adapter', function () { expect(data.pn).to.equal('pubmatic'); expect(data.eg).to.equal('1.23'); expect(data.en).to.equal('1.23'); + expect(data.piid).to.equal('partnerImpressionID-1'); }); it('bidCpmAdjustment: USD: Logger: best case + win tracker', function() { @@ -419,6 +429,7 @@ describe('pubmatic analytics adapter', function () { expect(data.pid).to.equal('1111'); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); + expect(data.tgid).to.equal(0); // slot 1 expect(data.s[0].sn).to.equal('/19968336/header-bid-tag-0'); expect(data.s[0].sz).to.deep.equal(['640x480']); @@ -446,6 +457,10 @@ describe('pubmatic analytics adapter', function () { }); it('bidCpmAdjustment: JPY: Logger: best case + win tracker', function() { + config.setConfig({ + testGroupId: 25 + }); + setConfig({ adServerCurrency: 'JPY', rates: { @@ -479,6 +494,7 @@ describe('pubmatic analytics adapter', function () { let data = getLoggerJsonFromRequest(request.requestBody); expect(data.pubid).to.equal('9999'); expect(data.pid).to.equal('1111'); + expect(data.tgid).to.equal(0);// test group id should be between 0-15 else set to 0 expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); // slot 1 @@ -508,6 +524,10 @@ describe('pubmatic analytics adapter', function () { }); it('Logger: when bid is not submitted, default bid status 1 check: pubmatic set as s2s', function() { + config.setConfig({ + testGroupId: '25' + }); + events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); @@ -520,6 +540,7 @@ describe('pubmatic analytics adapter', function () { expect(requests.length).to.equal(2); // 1 logger and 1 win-tracker let request = requests[1]; // logger is executed late, trackers execute first let data = getLoggerJsonFromRequest(request.requestBody); + expect(data.tgid).to.equal(0);// test group id should be an INT between 0-15 else set to 0 expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); expect(data.s[1].ps).to.be.an('array'); diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 7a33df6fdfa..abc440ac8ea 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -2306,6 +2306,7 @@ describe('PubMatic adapter', function () { expect(response[0].ad).to.equal(bidResponses.body.seatbid[0].bid[0].adm); expect(response[0].pm_seat).to.equal(bidResponses.body.seatbid[0].seat); expect(response[0].pm_dspid).to.equal(bidResponses.body.seatbid[0].bid[0].ext.dspid); + expect(response[0].partnerImpId).to.equal(bidResponses.body.seatbid[0].bid[0].id); expect(response[1].requestId).to.equal(bidResponses.body.seatbid[1].bid[0].impid); expect(response[1].cpm).to.equal((bidResponses.body.seatbid[1].bid[0].price).toFixed(2)); @@ -2328,6 +2329,7 @@ describe('PubMatic adapter', function () { expect(response[1].ad).to.equal(bidResponses.body.seatbid[1].bid[0].adm); expect(response[1].pm_seat).to.equal(bidResponses.body.seatbid[1].seat || null); expect(response[1].pm_dspid).to.equal(bidResponses.body.seatbid[1].bid[0].ext.dspid); + expect(response[0].partnerImpId).to.equal(bidResponses.body.seatbid[0].bid[0].id); }); it('should check for dealChannel value selection', function () { From f8e08d3079ebe74806370ac0581aa5bf1eb8f42d Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 16 Jul 2020 12:25:15 -0400 Subject: [PATCH 490/496] Prebid 3.26.0 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4eb14fc5144..a4dadc2c976 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.26.0-pre", + "version": "3.26.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From f1d077fd10c76599ded74c73c432d4a6e1ea545e Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Thu, 16 Jul 2020 21:56:07 +0530 Subject: [PATCH 491/496] Appnexus Bid Adapter - rtb.trackers field optional (#5471) * make rtb.trackers field options * add check to entire try block * fix failing test case --- modules/appnexusBidAdapter.js | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index f853d9b597b..df0b60cb7d7 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -72,7 +72,7 @@ export const spec = { * @param {object} bid The bid to validate. * @return boolean True if this is a valid bid, and false otherwise. */ - isBidRequestValid: function(bid) { + isBidRequestValid: function (bid) { return !!(bid.params.placementId || (bid.params.member && bid.params.invCode)); }, @@ -82,12 +82,12 @@ export const spec = { * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. * @return ServerRequest Info describing the request to the server. */ - buildRequests: function(bidRequests, bidderRequest) { + buildRequests: function (bidRequests, bidderRequest) { const tags = bidRequests.map(bidToTag); const userObjBid = find(bidRequests, hasUserInfo); let userObj = {}; if (config.getConfig('coppa') === true) { - userObj = {'coppa': true}; + userObj = { 'coppa': true }; } if (userObjBid) { Object.keys(userObjBid.params.user) @@ -243,7 +243,7 @@ export const spec = { * @param {*} serverResponse A successful response from the server. * @return {Bid[]} An array of bids which were nested inside the server. */ - interpretResponse: function(serverResponse, {bidderRequest}) { + interpretResponse: function (serverResponse, { bidderRequest }) { serverResponse = serverResponse.body; const bids = []; if (!serverResponse || serverResponse.error) { @@ -295,14 +295,14 @@ export const spec = { * Returns mapping file info. This info will be used by bidderFactory to preload mapping file and store data in local storage * @returns {mappingFileInfo} */ - getMappingFileInfo: function() { + getMappingFileInfo: function () { return { url: mappingFileUrl, refreshInDays: 2 } }, - getUserSyncs: function(syncOptions) { + getUserSyncs: function (syncOptions) { if (syncOptions.iframeEnabled) { return [{ type: 'iframe', @@ -311,7 +311,7 @@ export const spec = { } }, - transformBidParams: function(params, isOpenRtb) { + transformBidParams: function (params, isOpenRtb) { params = utils.convertTypes({ 'member': 'string', 'invCode': 'string', @@ -344,7 +344,7 @@ export const spec = { * Add element selector to javascript tracker to improve native viewability * @param {Bid} bid */ - onBidWon: function(bid) { + onBidWon: function (bid) { if (bid.native) { reloadViewabilityScriptWithCorrectParameters(bid); } @@ -645,9 +645,11 @@ function newBid(serverBid, rtbBid, bidderRequest) { ad: rtbBid.rtb.banner.content }); try { - const url = rtbBid.rtb.trackers[0].impression_urls[0]; - const tracker = utils.createTrackPixelHtml(url); - bid.ad += tracker; + if (rtbBid.rtb.trackers) { + const url = rtbBid.rtb.trackers[0].impression_urls[0]; + const tracker = utils.createTrackPixelHtml(url); + bid.ad += tracker; + } } catch (error) { utils.logError('Error appending tracking pixel', error); } @@ -675,7 +677,7 @@ function bidToTag(bid) { tag.reserve = bid.params.reserve; } if (bid.params.position) { - tag.position = {'above': 1, 'below': 2}[bid.params.position] || 0; + tag.position = { 'above': 1, 'below': 2 }[bid.params.position] || 0; } if (bid.params.trafficSourceCode) { tag.traffic_source_code = bid.params.trafficSourceCode; @@ -715,7 +717,7 @@ function bidToTag(bid) { if (bid.nativeParams) { const nativeRequest = buildNativeRequest(bid.nativeParams); - tag[NATIVE] = {layouts: [nativeRequest]}; + tag[NATIVE] = { layouts: [nativeRequest] }; } } @@ -756,7 +758,7 @@ function bidToTag(bid) { } if (bid.renderer) { - tag.video = Object.assign({}, tag.video, {custom_renderer_present: true}); + tag.video = Object.assign({}, tag.video, { custom_renderer_present: true }); } let adUnit = find(auctionManager.getAdUnits(), au => bid.transactionId === au.transactionId); From 307ef969e1155d2489764abfa1b03c3d7de993e6 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 16 Jul 2020 13:50:41 -0400 Subject: [PATCH 492/496] Set up 3.27-pre --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a4dadc2c976..7fef561be33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "3.26.0", + "version": "3.27.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From bab94f082e6bb0b62e1e89376ae276f57168bbc5 Mon Sep 17 00:00:00 2001 From: mmprebid <67095277+mmprebid@users.noreply.github.com> Date: Fri, 17 Jul 2020 11:57:31 +0530 Subject: [PATCH 493/496] TrueReach Bidder Adapter (#5423) * Added Trureach Prebid Adapter * cleaned up truereach bidder adapter for release * truereach bidder adapter md file for release * [truereach] bidder adapter and md files update. bidderUrl no more configurable. * [Prebid] supporting nurl * [Prebid] changes required due to code style * [Prebid] prebid unit test * [Prebid] added advertiserDomains in response object * [Prebid] Secure Bidder Url. Co-authored-by: Nitin Kumar Co-authored-by: arnav Co-authored-by: arnav --- modules/truereachBidAdapter.js | 128 ++++++++++++++++++ modules/truereachBidAdapter.md | 44 ++++++ test/spec/modules/truereachBidAdapter_spec.js | 84 ++++++++++++ 3 files changed, 256 insertions(+) create mode 100755 modules/truereachBidAdapter.js create mode 100644 modules/truereachBidAdapter.md create mode 100644 test/spec/modules/truereachBidAdapter_spec.js diff --git a/modules/truereachBidAdapter.js b/modules/truereachBidAdapter.js new file mode 100755 index 00000000000..2de7edbc04d --- /dev/null +++ b/modules/truereachBidAdapter.js @@ -0,0 +1,128 @@ +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER } from '../src/mediaTypes.js'; + +const SUPPORTED_AD_TYPES = [BANNER]; +const BIDDER_CODE = 'truereach'; +const BIDDER_URL = 'https://ads.momagic.com/exchange/openrtb25/'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: SUPPORTED_AD_TYPES, + + isBidRequestValid: function (bidRequest) { + return (bidRequest.params.site_id && bidRequest.params.bidfloor && + utils.deepAccess(bidRequest, 'mediaTypes.banner') && (utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes.length') > 0)); + }, + + buildRequests: function (validBidRequests, bidderRequest) { + if (validBidRequests.length === 0) { + return []; + } + + let queryParams = buildCommonQueryParamsFromBids(validBidRequests, bidderRequest); + + let siteId = utils.deepAccess(validBidRequests[0], 'params.site_id'); + + let url = BIDDER_URL + siteId + '?hb=1&transactionId=' + validBidRequests[0].transactionId; + + return { + method: 'POST', + url: url, + data: queryParams, + options: { withCredentials: true } + }; + }, + + interpretResponse: function ({ body: serverResponse }, serverRequest) { + const bidResponses = []; + + if ((!serverResponse || !serverResponse.id) || + (!serverResponse.seatbid || serverResponse.seatbid.length === 0 || !serverResponse.seatbid[0].bid || serverResponse.seatbid[0].bid.length === 0)) { + return bidResponses; + } + + let adUnits = serverResponse.seatbid[0].bid; + let bidderBid = adUnits[0]; + + let responseCPM = parseFloat(bidderBid.price); + if (responseCPM === 0) { + return bidResponses; + } + + let responseAd = bidderBid.adm; + + if (bidderBid.nurl) { + let responseNurl = ''; + responseAd += responseNurl; + } + + const bidResponse = { + requestId: bidderBid.impid, + cpm: responseCPM, + currency: serverResponse.cur || 'USD', + width: parseInt(bidderBid.w), + height: parseInt(bidderBid.h), + ad: decodeURIComponent(responseAd), + ttl: 180, + creativeId: bidderBid.crid, + netRevenue: false + }; + if (bidderBid.adomain && bidderBid.adomain.length) { + bidResponse.meta = { + advertiserDomains: bidderBid.adomain, + }; + } + + bidResponses.push(bidResponse); + + return bidResponses; + }, + +}; + +function buildCommonQueryParamsFromBids(validBidRequests, bidderRequest) { + let adW = 0; + let adH = 0; + let adSizes = Array.isArray(validBidRequests[0].params.sizes) ? validBidRequests[0].params.sizes : validBidRequests[0].sizes; + let sizeArrayLength = adSizes.length; + if (sizeArrayLength === 2 && typeof adSizes[0] === 'number' && typeof adSizes[1] === 'number') { + adW = adSizes[0]; + adH = adSizes[1]; + } else { + adW = adSizes[0][0]; + adH = adSizes[0][1]; + } + + let bidFloor = Number(utils.deepAccess(validBidRequests[0], 'params.bidfloor')); + + let domain = window.location.host; + let page = window.location.host + window.location.pathname + location.search + location.hash; + + let defaultParams = { + id: utils.getUniqueIdentifierStr(), + imp: [ + { + id: validBidRequests[0].bidId, + banner: { + w: adW, + h: adH + }, + bidfloor: bidFloor + } + ], + site: { + domain: domain, + page: page + }, + device: { + ua: window.navigator.userAgent + }, + tmax: config.getConfig('bidderTimeout') + }; + + return defaultParams; +} + +registerBidder(spec); diff --git a/modules/truereachBidAdapter.md b/modules/truereachBidAdapter.md new file mode 100644 index 00000000000..8a926565092 --- /dev/null +++ b/modules/truereachBidAdapter.md @@ -0,0 +1,44 @@ +# Overview + +``` +Module Name: TrueReach Bidder Adapter +Module Type: Bidder Adapter +Maintainer: mm.github@momagic.com +``` + +# Description + +Module that connects to TrueReach's demand sources + +# Test Parameters +``` + var adUnits = [{ + code: 'test-banner', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bids: [{ + bidder: 'truereach', + params: { + site_id: '0142010a-8400-1b01-72cb-a553b9000009', + bidfloor: 0.1 + } + }] + }]; +``` + +# Bid Parameters + +`mediaTypes -> banner -> sizes` must be `defined`. + +Also, the following parameters are `required` to be set- + +| Name | Type | Description +| ---- | ---- | ----------- +| `site_id` | String | TrueReach provided site ID +| `bidfloor` | Number | Minimum price (CPM) in USD. Must be greater than 0. + +# Additional Details +[TrueReach Ads](http://doc.truereach.co.in/docs/prebid/js-bidder-adapter.html) diff --git a/test/spec/modules/truereachBidAdapter_spec.js b/test/spec/modules/truereachBidAdapter_spec.js new file mode 100644 index 00000000000..5fe053ceb91 --- /dev/null +++ b/test/spec/modules/truereachBidAdapter_spec.js @@ -0,0 +1,84 @@ +import { expect } from 'chai'; +import { spec } from 'modules/truereachBidAdapter.js'; + +describe('truereachBidAdapterTests', function () { + it('validate_pub_params', function () { + expect(spec.isBidRequestValid({ + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bidder: 'truereach', + params: { + site_id: '0142010a-8400-1b01-72cb-a553b9000009', + bidfloor: 0.1 + } + })).to.equal(true); + }); + + it('validate_generated_params', function () { + let bidRequestData = [{ + bidId: '34ce3f3b15190a', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bidder: 'truereach', + params: { + site_id: '0142010a-8400-1b01-72cb-a553b9000009', + bidfloor: 0.1 + }, + sizes: [[300, 250]] + }]; + + let request = spec.buildRequests(bidRequestData, {}); + let req_data = request.data; + + expect(request.method).to.equal('POST'); + expect(req_data.imp[0].id).to.equal('34ce3f3b15190a'); + expect(req_data.imp[0].banner.w).to.equal(300); + expect(req_data.imp[0].banner.h).to.equal(250); + expect(req_data.imp[0].bidfloor).to.equal(0.1); + }); + + it('validate_response_params', function () { + let serverResponse = { + body: { + 'id': '34ce3f3b15190a', + 'seatbid': [{ + 'bid': [{ + 'id': '0142010a-8400-0801-72dc-04a99e6f7fc0:1ed', + 'impid': '34ce3f3b15190a', + 'price': 2.55, + 'adm': '', + 'adid': '493', + 'adomain': ['https://www.momagic.com/'], + 'iurl': '', + 'cid': '260', + 'crid': '0142010a-8400-1b01-72cb-afb296000012', + 'w': 300, + 'h': 250 + }] + }], + 'bidid': '0142010a-8400-0801-72dc-04a99e6f7fc1', + 'cur': 'USD' + } + }; + + let bids = spec.interpretResponse(serverResponse, {}); + expect(bids).to.have.lengthOf(1); + let bid = bids[0]; + expect(bid.requestId).to.equal('34ce3f3b15190a'); + expect(bid.cpm).to.equal(2.55); + expect(bid.currency).to.equal('USD'); + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); + expect(bid.ad).to.equal(''); + expect(bid.ttl).to.equal(180); + expect(bid.creativeId).to.equal('0142010a-8400-1b01-72cb-afb296000012'); + expect(bid.netRevenue).to.equal(false); + expect(bid.meta.advertiserDomains[0]).to.equal('https://www.momagic.com/'); + }); +}); From b25e57dbf3678236a852dac9b9c3c11b18d19a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Proch=C3=A1zka?= Date: Fri, 17 Jul 2020 15:10:22 +0200 Subject: [PATCH 494/496] New Bid adapter: Performax (#5480) * Performax adapater * Repair md * Remove unused functions, change to singlequoutes Co-authored-by: VasekProchazka --- modules/performaxBidAdapter.js | 56 ++++ modules/performaxBidAdapter.md | 36 +++ test/spec/modules/performaxBidAdapter_spec.js | 274 ++++++++++++++++++ 3 files changed, 366 insertions(+) create mode 100644 modules/performaxBidAdapter.js create mode 100644 modules/performaxBidAdapter.md create mode 100644 test/spec/modules/performaxBidAdapter_spec.js diff --git a/modules/performaxBidAdapter.js b/modules/performaxBidAdapter.js new file mode 100644 index 00000000000..8e22a0b2da9 --- /dev/null +++ b/modules/performaxBidAdapter.js @@ -0,0 +1,56 @@ +import {logWarn} from '../src/utils.js'; +import {registerBidder} from '../src/adapters/bidderFactory.js'; + +const CLIENT = 'hellboy:v0.0.1' +const BIDDER_CODE = 'performax'; +const BIDDER_SHORT_CODE = 'px'; +const ENDPOINT = 'https://dale.performax.cz/hb'; + +export const spec = { + code: BIDDER_CODE, + aliases: [BIDDER_SHORT_CODE], + + isBidRequestValid: function (bid) { + return !!bid.params.slotId; + }, + + buildUrl: function (validBidRequests, bidderRequest) { + const slotIds = validBidRequests.map(request => request.params.slotId); + let url = [`${ENDPOINT}?slotId[]=${slotIds.join()}`]; + url.push('client=' + CLIENT); + url.push('auctionId=' + bidderRequest.auctionId); + return url.join('&'); + }, + + buildRequests: function (validBidRequests, bidderRequest) { + return { + method: 'POST', + url: this.buildUrl(validBidRequests, bidderRequest), + data: {'validBidRequests': validBidRequests, 'bidderRequest': bidderRequest}, + options: {contentType: 'application/json'}, + } + }, + + buildHtml: function (ad) { + const keys = Object.keys(ad.data || {}); + return ad.code.replace( + new RegExp('\\$(' + keys.join('|') + ')\\$', 'g'), + (matched, key) => ad.data[key] || matched + ); + }, + + interpretResponse: function (serverResponse, request) { + let bidResponses = []; + for (let i = 0; i < serverResponse.body.length; i++) { + const ad = serverResponse.body[i].ad; + if (ad.type === 'empty') { + logWarn(`One of ads is empty (reason=${ad.reason})`); + continue; + } + serverResponse.body[i].ad = this.buildHtml(ad); + bidResponses.push(serverResponse.body[i]); + } + return bidResponses; + } +} +registerBidder(spec); diff --git a/modules/performaxBidAdapter.md b/modules/performaxBidAdapter.md new file mode 100644 index 00000000000..4cf2984a79d --- /dev/null +++ b/modules/performaxBidAdapter.md @@ -0,0 +1,36 @@ +# Overview + +``` +Module Name: Performax Bid Adapter +Module Type: Bidder Adapter +Maintainer: development@performax.cz +``` + +# Description + +Connects to Performax exchange for bids. + +Performax bid adapter supports Banner. + + +# Sample Banner Ad Unit: For Publishers + +```javascript + var adUnits = [ + { + code: 'performax-div', + sizes: [[300, 300]], + bids: [ + { + bidder: "performax", + params: { + slotId: 28 // required + } + } + ] + } + ]; +``` + +Where: +* slotId - id of slot in PX system diff --git a/test/spec/modules/performaxBidAdapter_spec.js b/test/spec/modules/performaxBidAdapter_spec.js new file mode 100644 index 00000000000..43c256b9d13 --- /dev/null +++ b/test/spec/modules/performaxBidAdapter_spec.js @@ -0,0 +1,274 @@ +import * as utils from 'src/utils.js'; +import { expect } from 'chai'; +import { spec } from 'modules/performaxBidAdapter'; + +describe('PerformaxAdapter', function () { + let bidRequests, bidderRequest; + let serverResponse, serverRequest; + + const URL = + 'https://dale.performax.cz/hb?slotId[]=3,2&client=hellboy:v0.0.1&auctionId=144b5079-8cbf-49a5-aca7-a68b3296cd6c'; + + bidRequests = [ + { + adUnitCode: 'postbid_iframe', + auctionId: '144b5079-8cbf-49a5-aca7-a68b3296cd6c', + bidId: '2a4332f6b2bc74', + bidRequestsCount: 1, + bidder: 'performax', + bidderRequestId: '1c7d8bf204f11e', + bidderRequestsCount: 1, + bidderWinsCount: 0, + mediaTypes: { + banner: { + sizes: [[300, 300]], + }, + }, + params: { + slotId: 3, + }, + sizes: [[300, 300]], + src: 'client', + transactionId: '14969d09-0068-4d5b-a34e-e35091561dee', + }, + { + adUnitCode: 'postbid_iframe2', + auctionId: '144b5079-8cbf-49a5-aca7-a68b3296cd6c', + bidId: '300bb0ac6a156a', + bidRequestsCount: 1, + bidder: 'performax', + bidderRequestId: '1c7d8bf204f11e', + bidderRequestsCount: 1, + bidderWinsCount: 0, + mediaTypes: { + banner: { + sizes: [[300, 300]], + }, + }, + params: { + slotId: 2, + }, + sizes: [[300, 300]], + src: 'client', + transactionId: '107cbebd-8c36-4456-b28c-91a19ba80151', + }, + ]; + + bidderRequest = { + auctionId: '144b5079-8cbf-49a5-aca7-a68b3296cd6c', + auctionStart: 1594281941845, + bidderCode: 'performax', + bidderRequestId: '1c7d8bf204f11e', + bids: bidRequests, + refererInfo: { + canonicalUrl: '', + numIframes: 0, + reachedTop: true, + referer: '', + }, + stack: [''], + start: 1594281941935, + timeout: 3600, + }; + + serverResponse = { + body: [ + { + ad: { + code: '$SYS_ID$ $VAR_NAME$ rest of the code', + data: { + SYS_ID: 1, + VAR_NAME: 'name', + }, + format_id: 2, + id: 11, + size: { + width: 300, + height: 300, + }, + tag_ids: [], + type: 'creative', + }, + cpm: 30, + creativeId: 'creative:11', + currency: 'CZK', + height: 300, + meta: { + agencyId: 1, + mediaType: 'banner', + }, + netRevenue: true, + requestId: '2a4332f6b2bc74', + ttl: 60, + width: 300, + }, + { + ad: { + code: '', + reason: 'Slot 2 does not allow HB requests', + type: 'empty', + }, + cpm: 0, + creativeId: null, + currency: 'CZK', + height: null, + meta: { + agencyId: null, + mediaType: 'banner', + }, + netRevenue: true, + requestId: '1c7d8bf204f11e', + ttl: 60, + width: 300, + }, + ], + }; + + serverRequest = { + data: { + bidderRequest: bidderRequest, + validBidRequests: bidRequests, + }, + method: 'POST', + options: { + contentType: 'application/json', + }, + url: URL, + }; + + describe('Bid validations', function () { + it('Valid bid', function () { + let validBid = { + bidder: 'performax', + params: { + slotId: 2, + }, + }, + isValid = spec.isBidRequestValid(validBid); + expect(isValid).to.equal(true); + }); + + it('Invalid bid: required param is missing', function () { + let invalidBid = { + bidder: 'performax', + params: { + invalidParam: 2, + }, + }, + isValid = spec.isBidRequestValid(invalidBid); + expect(isValid).to.equal(false); + }); + }); + + describe('Build Url', function () { + it('Should return url', function () { + let url = spec.buildUrl(bidRequests, bidderRequest); + expect(url).to.equal(URL); + }); + }); + + describe('Build Request', function () { + it('Should not modify bidRequests and bidder Requests', function () { + let originalBidRequests = utils.deepClone(bidRequests); + let originalBidderRequest = utils.deepClone(bidderRequest); + let request = spec.buildRequests(bidRequests, bidderRequest); + + expect(bidRequests).to.deep.equal(originalBidRequests); + expect(bidderRequest).to.deep.equal(originalBidderRequest); + }); + + it('Endpoint checking', function () { + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.url).to.equal(URL); + expect(request.method).to.equal('POST'); + expect(request.options).to.deep.equal({ + contentType: 'application/json', + }); + }); + + it('Request params checking', function () { + let request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.data.validBidRequests).to.deep.equal(bidRequests); + expect(request.data.bidderRequest).to.deep.equal(bidderRequest); + }); + }); + + describe('Build Html', function () { + it('Ad with data: should return build html', function () { + let validAd = { + code: '$SYS_ID$ $VAR_NAME$ rest of the code', + data: { + SYS_ID: 1, + VAR_NAME: 'name', + }, + format_id: 2, + id: 11, + size: { + width: 300, + height: 300, + }, + tag_ids: [], + type: 'creative', + }; + let html = spec.buildHtml(validAd); + expect(html).to.equal('1 name rest of the code'); + }); + + it('Ad with partial data: should return html without data change', function () { + let adWithPartialData = { + code: '$SYS_ID$ $VAR_NAME$ rest of the code', + data: { + VAR_NAME: 'name', + }, + format_id: 2, + id: 11, + size: { + width: 300, + height: 300, + }, + tag_ids: [], + type: 'creative', + }; + let html = spec.buildHtml(adWithPartialData); + expect(html).to.equal('$SYS_ID$ name rest of the code'); + }); + + it('Ad without data: should return html without data change', function () { + let adWithoutData = { + code: '$SYS_ID$ $VAR_NAME$ rest of the code', + format_id: 2, + id: 11, + size: { + width: 300, + height: 300, + }, + tag_ids: [], + type: 'creative', + }; + let html = spec.buildHtml(adWithoutData); + expect(html).to.equal('$SYS_ID$ $VAR_NAME$ rest of the code'); + }); + }); + + describe('Interpret Response', function () { + it('Ad without data: should return html without data change', function () { + let ads = spec.interpretResponse(serverResponse, serverRequest); + expect(ads).to.have.length(1); + expect(ads[0]).to.deep.equal({ + ad: '1 name rest of the code', + cpm: 30, + creativeId: 'creative:11', + currency: 'CZK', + height: 300, + meta: { + agencyId: 1, + mediaType: 'banner', + }, + netRevenue: true, + requestId: '2a4332f6b2bc74', + ttl: 60, + width: 300, + }); + }); + }); +}); From 2f861c9ce2eb589c0ef198515b5093f9aac0b31a Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Fri, 17 Jul 2020 13:56:45 -0400 Subject: [PATCH 495/496] Add meta.advertiserDomains to pbs adapter (#5437) * Update prebidServerBidAdapter_spec.js * Update index.js * Update index.js * Update index.js --- modules/prebidServerBidAdapter/index.js | 2 ++ test/spec/modules/prebidServerBidAdapter_spec.js | 3 +++ 2 files changed, 5 insertions(+) diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js index 7536851f5e1..a5dcf1b1d3b 100644 --- a/modules/prebidServerBidAdapter/index.js +++ b/modules/prebidServerBidAdapter/index.js @@ -831,6 +831,8 @@ const OPEN_RTB_PROTOCOL = { bidObject.creativeId = bid.crid; if (bid.burl) { bidObject.burl = bid.burl; } bidObject.currency = (response.cur) ? response.cur : DEFAULT_S2S_CURRENCY; + bidObject.meta = bidObject.meta || {}; + if (bid.adomain) { bidObject.meta.advertiserDomains = bid.adomain; } // TODO: Remove when prebid-server returns ttl and netRevenue const configTtl = _s2sConfig.defaultTtl || DEFAULT_S2S_TTL; diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index d99ec9d421d..294ada6f988 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -1700,6 +1700,9 @@ describe('S2S Adapter', function () { expect(response).to.have.property('bidderCode', 'appnexus'); expect(response).to.have.property('requestId', '123'); expect(response).to.have.property('cpm', 0.5); + expect(response).to.have.property('meta'); + expect(response.meta).to.have.property('advertiserDomains'); + expect(response.meta.advertiserDomains[0]).to.equal('appnexus.com'); expect(response).to.not.have.property('vastUrl'); expect(response).to.not.have.property('videoCacheKey'); expect(response).to.have.property('ttl', 60); From 884e7fc3d358c95b934e6de828c4fed84fef501f Mon Sep 17 00:00:00 2001 From: Paris Holley Date: Mon, 20 Jul 2020 04:08:55 -0400 Subject: [PATCH 496/496] mantis privacy support, removed unsupported media types (#5494) * mantis privacy support, removed unsupported media types * code coverage * lint fix --- modules/mantisBidAdapter.js | 97 +++++++++++----------- test/spec/modules/mantisBidAdapter_spec.js | 92 ++++++++++++++++++++ 2 files changed, 140 insertions(+), 49 deletions(-) diff --git a/modules/mantisBidAdapter.js b/modules/mantisBidAdapter.js index 19e70a3e68b..960fbe27c73 100644 --- a/modules/mantisBidAdapter.js +++ b/modules/mantisBidAdapter.js @@ -16,15 +16,7 @@ function pixel(url, parent) { img.style.cssText = 'display:none !important;'; (parent || document.body).appendChild(img); } -function isDesktop(ignoreTouch) { - var supportsTouch = !ignoreTouch && ('ontouchstart' in window || navigator.msMaxTouchPoints); - if (inIframe()) { - return !supportsTouch; - } - var width = window.innerWidth || window.document.documentElement.clientWidth || window.document.body.clientWidth; - return !supportsTouch && (!width || width >= (window.mantis_breakpoint || 768)); -} -function onVisible(element, doOnVisible, time, pct) { +export function onVisible(win, element, doOnVisible, time, pct) { var started = null; var notified = false; var onNotVisible = null; @@ -78,15 +70,15 @@ function onVisible(element, doOnVisible, time, pct) { }); }; if (isAmp()) { - listener = window.context.observeIntersection(function (changes) { + listener = win.context.observeIntersection(function (changes) { changes.forEach(function (change) { doCheck(change.rootBounds.width, change.rootBounds.height, change.boundingClientRect); }); }); } interval = setInterval(function () { - var winHeight = (window.innerHeight || document.documentElement.clientHeight); - var winWidth = (window.innerWidth || document.documentElement.clientWidth); + var winHeight = (win.innerHeight || document.documentElement.clientHeight); + var winWidth = (win.innerWidth || document.documentElement.clientWidth); doCheck(winWidth, winHeight, element.getBoundingClientRect()); }, 100); } @@ -136,9 +128,6 @@ function isArray(value) { } function jsonToQuery(data, chain, form) { - if (!data) { - return null; - } var parts = form || []; for (var key in data) { var queryKey = key; @@ -152,8 +141,6 @@ function jsonToQuery(data, chain, form) { var aval = val[index]; if (isObject(aval)) { jsonToQuery(aval, akey, parts); - } else if (isSendable(aval)) { - parts.push(akey + '=' + encodeURIComponent(aval)); } } } else if (isObject(val) && val != data) { @@ -173,9 +160,7 @@ function buildMantisUrl(path, data, domain) { secure: isSecure(), version: 9 }; - if (!inIframe() || isAmp()) { - params.mobile = !isAmp() && isDesktop(true) ? 'false' : 'true'; - } + if (window.mantis_uuid) { params.uuid = window.mantis_uuid; } else if (storage.hasLocalStorage()) { @@ -206,20 +191,20 @@ function buildMantisUrl(path, data, domain) { params.referrer = window.context.referrer; } } - Object.keys(data || {}).forEach(function (key) { + Object.keys(data).forEach(function (key) { params[key] = data[key]; }); var query = jsonToQuery(params); return (window.mantis_domain === undefined ? domain || 'https://mantodea.mantisadnetwork.com' : window.mantis_domain) + path + '?' + query; } -const spec = { +export const spec = { code: 'mantis', - supportedMediaTypes: ['banner', 'video', 'native'], + supportedMediaTypes: ['banner'], isBidRequestValid: function (bid) { return !!(bid.params.property && (bid.params.code || bid.params.zoneId || bid.params.zone)); }, - buildRequests: function (validBidRequests) { + buildRequests: function (validBidRequests, bidderRequest) { var property = null; validBidRequests.some(function (bid) { if (bid.params.property) { @@ -229,6 +214,7 @@ const spec = { }); const query = { measurable: true, + usp: bidderRequest && bidderRequest.uspConsent, bids: validBidRequests.map(function (bid) { return { bidId: bid.bidId, @@ -240,6 +226,12 @@ const spec = { }), property: property }; + + if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { + // we purposefully do not track data for users in the EU + query.consent = false; + } + return { method: 'GET', url: buildMantisUrl('/prebid/display', query) + '&foo', @@ -262,47 +254,54 @@ const spec = { }; }); }, - getUserSyncs: function (syncOptions) { + getUserSyncs: function (syncOptions, serverResponses, gdprConsent, uspConsent) { if (syncOptions.iframeEnabled) { return [{ type: 'iframe', - url: buildMantisUrl('/prebid/iframe') + url: buildMantisUrl('/prebid/iframe', {gdpr: gdprConsent, uspConsent: uspConsent}) }]; } if (syncOptions.pixelEnabled) { return [{ type: 'image', - url: buildMantisUrl('/prebid/pixel') + url: buildMantisUrl('/prebid/pixel', {gdpr: gdprConsent, uspConsent: uspConsent}) }]; } } }; + +export function sfPostMessage ($sf, width, height, callback) { + var viewed = false; + // eslint-disable-next-line no-undef + $sf.ext.register(width, height, function () { + // eslint-disable-next-line no-undef + if ($sf.ext.inViewPercentage() < 50 || viewed) { + return; + } + viewed = true; + callback(); + }); +}; + +export function iframePostMessage (win, name, callback) { + var frames = document.getElementsByTagName('iframe'); + for (var i = 0; i < frames.length; i++) { + var frame = frames[i]; + if (frame.name == name) { + onVisible(win, frame, function (stop) { + callback(); + stop(); + }, 1000, 0.50); + } + } +} + onMessage('iframe', function (data) { if (window.$sf) { - var viewed = false; - // eslint-disable-next-line no-undef - $sf.ext.register(data.width, data.height, function () { - // eslint-disable-next-line no-undef - if ($sf.ext.inViewPercentage() < 50 || viewed) { - return; - } - viewed = true; - pixel(data.pixel); - }); + sfPostMessage(window.$sf, data.width, data.height, () => pixel(data.pixel)); } else { - var frames = document.getElementsByTagName('iframe'); - for (var i = 0; i < frames.length; i++) { - var frame = frames[i]; - if (frame.name == data.frame) { - onVisible(frame, function (stop) { - pixel(data.pixel); - stop(); - }, 1000, 0.50); - } - } + iframePostMessage(window, data.frame, () => pixel(data.pixel)); } }); -export { spec }; - registerBidder(spec); diff --git a/test/spec/modules/mantisBidAdapter_spec.js b/test/spec/modules/mantisBidAdapter_spec.js index 1dad60f5d98..d9ab3c69a24 100644 --- a/test/spec/modules/mantisBidAdapter_spec.js +++ b/test/spec/modules/mantisBidAdapter_spec.js @@ -1,9 +1,21 @@ import {expect} from 'chai'; import {spec} from 'modules/mantisBidAdapter.js'; import {newBidder} from 'src/adapters/bidderFactory.js'; +import {sfPostMessage, iframePostMessage} from 'modules/mantisBidAdapter'; describe('MantisAdapter', function () { const adapter = newBidder(spec); + let sandbox; + let clock; + + beforeEach(function() { + sandbox = sinon.sandbox.create(); + clock = sandbox.useFakeTimers(); + }); + + afterEach(function() { + sandbox.restore(); + }); describe('isBidRequestValid', function () { let bid = { @@ -31,6 +43,68 @@ describe('MantisAdapter', function () { }); }); + describe('viewability', function() { + it('iframe (viewed)', () => { + let viewed = false; + + sandbox.stub(document, 'getElementsByTagName').withArgs('iframe').returns([ + { + name: 'mantis', + getBoundingClientRect: () => ({ + top: 10, + bottom: 260, + left: 10, + right: 190, + width: 300, + height: 250 + }) + } + ]); + + iframePostMessage({innerHeight: 500, innerWidth: 500}, 'mantis', () => viewed = true); + + sandbox.clock.runAll(); + + expect(viewed).to.equal(true); + }); + + it('safeframe (viewed)', () => { + let viewed = false; + + sfPostMessage({ + ext: { + register: (width, height, callback) => { + expect(width).to.equal(100); + expect(height).to.equal(200); + + callback(); + }, + inViewPercentage: () => 60 + } + }, 100, 200, () => viewed = true); + + expect(viewed).to.equal(true); + }); + + it('safeframe (unviewed)', () => { + let viewed = false; + + sfPostMessage({ + ext: { + register: (width, height, callback) => { + expect(width).to.equal(100); + expect(height).to.equal(200); + + callback(); + }, + inViewPercentage: () => 30 + } + }, 100, 200, () => viewed = true); + + expect(viewed).to.equal(false); + }); + }); + describe('buildRequests', function () { let bidRequests = [ { @@ -47,6 +121,24 @@ describe('MantisAdapter', function () { } ]; + it('gdpr consent not required', function () { + const request = spec.buildRequests(bidRequests, {gdprConsent: {gdprApplies: false}}); + + expect(request.url).not.to.include('consent=false'); + }); + + it('gdpr consent required', function () { + const request = spec.buildRequests(bidRequests, {gdprConsent: {gdprApplies: true}}); + + expect(request.url).to.include('consent=false'); + }); + + it('usp consent', function () { + const request = spec.buildRequests(bidRequests, {uspConsent: 'foobar'}); + + expect(request.url).to.include('usp=foobar'); + }); + it('domain override', function () { window.mantis_domain = 'https://foo'; const request = spec.buildRequests(bidRequests);