From f6202e93a0f03488c1e898f980002e68aa8de217 Mon Sep 17 00:00:00 2001 From: Bill Newman Date: Thu, 8 Oct 2020 02:47:40 +0300 Subject: [PATCH 001/149] Colussus Prebid server adapter info (#2306) * Updated docs Colossusssp Adapter * Update colossusssp.md Add media types * Update colossusssp.md add usp consent support * adding schain flag * gdpr and user ids * id5id support * Prebid server info * Remove PBS params * Add colossus PBS docs * Add short note for pbs adapter parametres * Add note for pbjs parametres * Fix * remove duplicate string Co-authored-by: Vladislav Isaiko Co-authored-by: bretg Co-authored-by: Aiholkin --- dev-docs/bidders/colossus.md | 22 ++++++++++++++++++++++ dev-docs/bidders/colossusssp.md | 7 +++++-- 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 dev-docs/bidders/colossus.md diff --git a/dev-docs/bidders/colossus.md b/dev-docs/bidders/colossus.md new file mode 100644 index 0000000000..c5849b2dc6 --- /dev/null +++ b/dev-docs/bidders/colossus.md @@ -0,0 +1,22 @@ +--- +layout: bidder +title: Colossus +description: Prebid Colossus Bidder Adaptor +biddercode: colossus +usp_supported: true +schain_supported: true +media_types: banner, video, native +userIds: britepoolid, identityLink, unifiedId, id5Id +gdpr: true +pbjs: false +pbs: true +--- + +### Prebid.Server Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|----------------|----------|----------------------------------------------------------|------------|-----------| +| `TagID` | required | Placement Id will be generated on Colossus SSP Platform. | `'0'` | `string` | + +*For prebidJS parametres, look into colossusssp.md* diff --git a/dev-docs/bidders/colossusssp.md b/dev-docs/bidders/colossusssp.md index 0f5554caf8..e64677b05d 100644 --- a/dev-docs/bidders/colossusssp.md +++ b/dev-docs/bidders/colossusssp.md @@ -2,19 +2,22 @@ layout: bidder title: Colossus description: Prebid Colossus Bidder Adaptor -pbjs: true biddercode: colossusssp usp_supported: true schain_supported: true media_types: banner, video, native userIds: britepoolid, identityLink, unifiedId, id5Id gdpr: true +pbjs: true +pbs: false --- -### Bid Params +### Prebid.JS Bid Params {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |----------------|----------|----------------------------------------------------------|------------|-----------| | `placement_id` | required | Placement Id will be generated on Colossus SSP Platform. | `0` | `integer` | | `traffic` | optional | Type traffic | `'banner'` | `string` | + +*For colossus prebid server parametres, look into colossus.md* From dcc4230be72ec111966574f2ad8e9b702a2e8b5c Mon Sep 17 00:00:00 2001 From: SmartyAdsSSP <41569976+SmartyAdsSSP@users.noreply.github.com> Date: Thu, 8 Oct 2020 16:00:39 +0300 Subject: [PATCH 002/149] init smartyads docs (#2366) * init smartyads docs * putting PBJS support back the same doc file is used to generate both the PBJS and PBS bidder list. You guys have a PBJS adapter. I changed back to pbjs: true. Co-authored-by: bretg --- dev-docs/bidders/smartyads.md | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/dev-docs/bidders/smartyads.md b/dev-docs/bidders/smartyads.md index 540885edac..ba70abfa42 100644 --- a/dev-docs/bidders/smartyads.md +++ b/dev-docs/bidders/smartyads.md @@ -2,21 +2,29 @@ layout: bidder title: SmartyAds description: Prebid SmartyAds Bidder Adaptor -pbjs: true biddercode: smartyads -media_types: native +gdpr_supported: true +tcf2_supported: true +usp_supported: true +coppa_supported: true +schain_supported: true +userId: (list of supported vendors) +media_types: banner, video, native +safeframes_ok: true +bidder_supports_deals: true +pbjs: true +pbs: true --- -### Bid Params Prebid 0.34 +### Note: -{: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|-------------|----------|-------------|---------|----------| -| `banner_id` | required | | | `string` | +The Example Bidding adapter requires setup before beginning. Please contact us at sales@smartyads.com -### Bid Params Prebid 1.x +### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|---------------|----------|-------------|---------|----------| -| `placementId` | required | | | `string` | +| Name | Scope | Description | Example | Type | +|---------------|----------|-----------------------|-----------|-----------| +| `host` | required | Region id | `'ns1'` | `string` | +| `sourceid` | required | Partner id | `'smartyads'` | `string` | +| `accountid` | required | Endpoint id | `'hash'` | `string` | From e67b10a7a4bc0976e89ac2aa68dde979cef9872d Mon Sep 17 00:00:00 2001 From: Michael Griego Date: Thu, 8 Oct 2020 08:08:39 -0500 Subject: [PATCH 003/149] Update refererInfo spec to match AMP updates (#1803) Related: https://github.com/prebid/Prebid.js/pull/4846 --- dev-docs/bidder-adaptor.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidder-adaptor.md b/dev-docs/bidder-adaptor.md index 1ee40082b3..9252ed1066 100644 --- a/dev-docs/bidder-adaptor.md +++ b/dev-docs/bidder-adaptor.md @@ -303,8 +303,9 @@ Referrer information should be passed to your endpoint in contexts where the ori - `referer`: a string containing the detected top-level URL. - `reachedTop`: a boolean specifying whether Prebid was able to walk up to the top window. - `numIframes`: the number of iFrames. -- `stack`: a string of comma-separated URLs of all origins. +- `stack`: an array of URLs of all windows from the top window down to the current window. - `canonicalUrl`: a string containing the canonical (search engine friendly) URL defined in top-most window. +- `isAmp`: a boolean specifying whether the detected referer was determined based on AMP page information. The URL returned by `refererInfo` is in raw format. We recommend encoding the URL before adding it to the request payload to ensure it will be sent and interpreted correctly. From 6eb84b3a2ac0e5a858ed1b13077342571999ae99 Mon Sep 17 00:00:00 2001 From: Ben Anderson Date: Thu, 8 Oct 2020 10:32:45 -0400 Subject: [PATCH 004/149] new userId module - neustar's fabrick (#2399) * adding neustar fabrick * new userId module - neustar's fabrick * adding fabrick to download.md * Minor naming changes for Neustar Fabrick section Co-authored-by: Anderson, Ben --- dev-docs/modules/userId.md | 75 +++++++++++++++++++++++++++++++++++++- download.md | 3 ++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index 8624cca848..652e2c4b2f 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -58,7 +58,7 @@ of sub-objects. The table below has the options that are common across ID system {: .table .table-bordered .table-striped } | Param under userSync.userIds[] | Scope | Type | Description | Example | | --- | --- | --- | --- | --- | -| name | Required | String | May be: `"britepoolId"`, `"criteo"`, `"haloId"`, `"id5id"`, `identityLink`, `"intentIqId"`, `"liveIntentId"`, `"lotamePanoramaId"`, `"merkleId"`, `"netId"`, `"parrableId"`, `"quantcastId"`, `"pubCommonId"`, `"pubProvidedId"`, `"sharedId"`, `"unifiedId"`, `"zeotapIdPlus"` | `"unifiedId"` | +| name | Required | String | May be: `"britepoolId"`, `"criteo"`, `"fabrickId"`, `"haloId"`, `"id5id"`, `identityLink`, `"intentIqId"`, `"liveIntentId"`, `"lotamePanoramaId"`, `"merkleId"`, `"netId"`, `"parrableId"`, `"quantcastId"`, `"pubCommonId"`, `"pubProvidedId"`, `"sharedId"`, `"unifiedId"`, `"zeotapIdPlus"` | `"unifiedId"` | | params | Based on User ID sub-module | Object | | | | storage | Optional | Object | The publisher can specify some kind of local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. This is not needed when `value` is specified or the ID system is managing its own storage | | | storage.type | Required | String | Must be either `"cookie"` or `"html5"`. This is where the results of the user ID will be stored. | `"cookie"` | @@ -153,6 +153,79 @@ pbjs.setConfig({ }); {% endhighlight %} +### Fabrick ID by Neustar + +[Neustar Fabrick™](https://www.home.neustar/fabrick) is a unified identity ecosystem that powers connections between brands, publishers, and consumers to accelerate marketing performance across online and offline channels. + +Add it to your Prebid.js package with: + +{: .alert.alert-info :} +gulp build --modules=fabrickIdSystem + +#### Fabrick Registration + +Please reach out to [integrations@team.neustar](mailto:integrations@team.neustar) to request your `apiKey`. + +#### Fabrick Configuration + +{: .table .table-bordered .table-striped } +| Param under userSync.userIds[] | Scope | Type | Description | Example | +| --- | --- | --- | --- | --- | +| name | Required | String | The name of this module. | `"fabrickId"` | +| params | Required | Object | Container of all module params. | | +| params.apiKey | Required | String | This is your apiKey as provided by Neustar. | | +| params.e | | String | This is a hashed email address used to link a user to their Fabrick ID. | | +| params.p | | String | This is a hashed phone number used to link a user to their Fabrick ID. | | +| params.i4 | | String | This is an IPv4 address used to link a user to their Fabrick ID. | | +| params.i6 | | String | This is an IPv6 address used to link a user to their Fabrick ID. | | +| params.m | | String | This is a mobile advertising ID (IDFA/AAID) used to link a user to their Fabrick ID. | | +| params.ia | | String | This is an identifier for advertising (IFA) used to link a user to their Fabrick ID. | | +| params.iv | | String | This is an identifier for vendors (IFV) used to link a user to their Fabrick ID. | | + +#### Fabrick Examples + +1) Publisher passes an apiKey and hashed email address and elects to store the Fabrick ID envelope in a cookie. + +{% highlight javascript %} +pbjs.setConfig({ + userSync: { + userIds: [{ + name: 'fabrickId', + params: { + apiKey: '123456789', // provided to you by Neustar + e: '31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66' // example hashed email address (sha256) + }, + storage: { + name: 'pbjs_fabrickId', + type: 'cookie', + expires: 7 + } + }] + } +}); +{% endhighlight %} + +2) Publisher passes an apiKey and hashed email address and elects to store the fabrickId envelope in HTML5 localStorage. + +{% highlight javascript %} +pbjs.setConfig({ + userSync: { + userIds: [{ + name: 'fabrickId', + params: { + apiKey: '123456789', // provided to you by Neustar + e: '31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66' // example hashed email address (sha256) + }, + storage: { + type: "html5", + name: "pbjs_fabrickId", + expires: 7 + } + }] + } +}); +{% endhighlight %} + ### Halo ID from Audigent 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. Our HaloId module allows for user id resolution and Audigent user data segmentation to be retrieved for users across the web. For assistance setting up your module please contact us at [prebid@audigent.com](prebid@audigent.com). diff --git a/download.md b/download.md index 02bb783a1e..2ee2bfbf6c 100644 --- a/download.md +++ b/download.md @@ -515,6 +515,9 @@ Prebid.js is open source software that is offered for free as a convenience. Whi
+ +
+
From 2516d43fa2d44c42182e6f79db6f2ec5f7b76236 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 8 Oct 2020 15:58:26 -0400 Subject: [PATCH 005/149] updating supported user IDs (#2397) --- dev-docs/bidders/rubicon.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/rubicon.md b/dev-docs/bidders/rubicon.md index 9445015b89..4fd9c38560 100644 --- a/dev-docs/bidders/rubicon.md +++ b/dev-docs/bidders/rubicon.md @@ -9,7 +9,7 @@ usp_supported: true coppa_supported: true schain_supported: true media_types: video -userIds: identityLink, liveIntentId, unifiedId +userIds: identityLink, liveIntentId, sharedId, pubCommonId, pubProvidedId, unifiedId prebid_member: true safeframes_ok: true bidder_supports_deals: true From e557c7e7e73745e061d243c05263d95054e03a1b Mon Sep 17 00:00:00 2001 From: Scott Date: Thu, 8 Oct 2020 22:01:21 +0200 Subject: [PATCH 006/149] update id5 docs with new structure (#2393) --- dev-docs/modules/userId.md | 82 +++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index 652e2c4b2f..f292ab606a 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -71,7 +71,7 @@ of sub-objects. The table below has the options that are common across ID system ### BritePool -BritePool ID, provided by [BritePool](https://britepool.com) is a Universal Identity resolution which does not depend on 3rd party cookies. +BritePool ID, provided by [BritePool](https://britepool.com) is a Universal Identity resolution which does not depend on 3rd party cookies. Add it to your Prebid.js package with: @@ -80,7 +80,7 @@ gulp build --modules=britepoolIdSystem #### BritePool Registration -Please reach out to [prebid@britepool.com](mailto:prebid@britepool.com) and request your `api_key`. +Please reach out to [prebid@britepool.com](mailto:prebid@britepool.com) and request your `api_key`. The BritePool privacy policy is at [https://britepool.com/services-privacy-notice/](https://britepool.com/services-privacy-notice/). @@ -294,7 +294,7 @@ pbjs.setConfig({ ### ID5 Universal ID -The ID5 Universal ID is a shared, neutral identifier that publishers and ad tech platforms can use to recognise users even in environments where 3rd party cookies are not available. The ID5 Universal ID is designed to respect users' privacy choices and publishers’ preferences throughout the advertising value chain. For more information about the ID5 Universal ID and detailed integration docs, please visit [our documentation](https://console.id5.io/docs/public/prebid). We also recommend that you sign up for our [release notes](https://id5.io/universal-id/release-notes) to stay up-to-date with any changes to the implementation of the ID5 Universal ID in Prebid. +The ID5 Universal ID is a shared, neutral identifier that publishers and ad tech platforms can use to recognise users even in environments where 3rd party cookies are not available. The ID5 Universal ID is designed to respect users' privacy choices and publishers’ preferences throughout the advertising value chain. For more information about the ID5 Universal ID and detailed integration docs, please visit [our documentation](https://wiki.id5.io/x/BIAZ). We also recommend that you sign up for our [release notes](https://id5.io/universal-id/release-notes) to stay up-to-date with any changes to the implementation of the ID5 Universal ID in Prebid. #### ID5 Universal ID Registration @@ -317,7 +317,7 @@ The following configuration parameters are available: | name | Required | String | The name of this module: `"id5Id"` | `"id5Id"` | | params | Required | Object | Details for the ID5 Universal ID. | | | params.partner | Required | Number | This is the ID5 Partner Number obtained from registering with ID5. | `173` | -| params.pd | Optional | String | Publisher-supplied data used for linking ID5 IDs across domains. See [our documentation](https://wiki.id5.io/display/PD/Prebid.js+UserId+Module) for details on generating the string. Omit the parameter or leave as an empty string if no data to supply | `"MT1iNTBjY..."` | +| params.pd | Optional | String | Publisher-supplied data used for linking ID5 IDs across domains. See [our documentation](https://wiki.id5.io/x/BIAZ) for details on generating the string. Omit the parameter or leave as an empty string if no data to supply | `"MT1iNTBjY..."` | {: .alert.alert-info :} **NOTE:** The ID5 Universal ID that is delivered to Prebid will be encrypted by ID5 with a rotating key to avoid unauthorized usage and to enforce privacy requirements. Therefore, we strongly recommend setting `storage.refreshInSeconds` to `8` hours (`8*3600` seconds) to ensure all demand partners receive an ID that has been encrypted with the latest key, has up-to-date privacy signals, and allows them to transact against it. @@ -354,7 +354,11 @@ pbjs.setConfig({ userSync: { userIds: [{ name: "id5Id", - value: { "id5id": "ID5-8ekgswyBTQqnkEKy0ErmeQ1GN5wV4pSmA-RE4eRedA" } + value: { + id5id: { + uid: "ID5-8ekgswyBTQqnkEKy0ErmeQ1GN5wV4pSmA-RE4eRedA" + } + } }] } }); @@ -548,11 +552,11 @@ The adapters can be implemented to use the lipibid as the identifier and segment Please register with us if you’re not a LiveIntent customer already: [https://www.liveintent.com/prebid-registration/](https://www.liveintent.com/prebid-registration/) -When adding LiveIntent’s ID to your Prebid.js package, you disclose or make available Personal Information to LiveIntent. This information made available to LiveIntent is used to (i) connect with and reference data that already exists in LiveIntent’s graph (the “LiveIntent Graph”), and (ii) authenticate and validate data in aggregate to improve the performance of the services LiveIntent provides. By activating LiveIntent’s module, you hereby confirm that with regard to all individuals to whom Personal Information relates, you have, at or before the point of collecting Personal Information or making Personal Information available to LiveIntent, provided any legally required notices, obtained any legally required consents, and provided individuals with an opportunity to opt-out of the sharing of Personal Information, if such an opt-out is required under applicable laws, such that LiveIntent can provide service to you as described here and in LiveIntent’s privacy policies for the services which can be found at [https://www.liveintent.com/services-privacy-policy/](https://www.liveintent.com/services-privacy-policy/) +When adding LiveIntent’s ID to your Prebid.js package, you disclose or make available Personal Information to LiveIntent. This information made available to LiveIntent is used to (i) connect with and reference data that already exists in LiveIntent’s graph (the “LiveIntent Graph”), and (ii) authenticate and validate data in aggregate to improve the performance of the services LiveIntent provides. By activating LiveIntent’s module, you hereby confirm that with regard to all individuals to whom Personal Information relates, you have, at or before the point of collecting Personal Information or making Personal Information available to LiveIntent, provided any legally required notices, obtained any legally required consents, and provided individuals with an opportunity to opt-out of the sharing of Personal Information, if such an opt-out is required under applicable laws, such that LiveIntent can provide service to you as described here and in LiveIntent’s privacy policies for the services which can be found at [https://www.liveintent.com/services-privacy-policy/](https://www.liveintent.com/services-privacy-policy/) #### How does LiveIntent ID work -The LiveIntent ID sub-module resolves the identity of audiences by connecting impression opportunities to a stable identifier (nonID). In order to provide resolution one or more first-party cookies are used to create a stable identifier. +The LiveIntent ID sub-module resolves the identity of audiences by connecting impression opportunities to a stable identifier (nonID). In order to provide resolution one or more first-party cookies are used to create a stable identifier. How does LiveIntent ID sub-module decide, which first-party cookies to use: 1. By default LiveIntent ID sub-module generates its own first-party identifier on the publisher’s domain. Publishers have the option to disable the cookie generation when configuring the LiveIntent ID sub-module. @@ -600,11 +604,11 @@ pbjs.setConfig({ params: { publisherId: "9896876" }, - storage: { - type: “cookie”, - name: “pbjs_li_nonid”, //create a cookie with this name - expires: 1 // cookie is stored for 1 day - } + storage: { + type: “cookie”, + name: “pbjs_li_nonid”, //create a cookie with this name + expires: 1 // cookie is stored for 1 day + } }] } }) @@ -620,11 +624,11 @@ pbjs.setConfig({ publisherId: "9896876", identifiersToResolve: ["my-own-cookie"] }, - storage: { - type: “cookie”, - name: “pbjs_li_nonid”, //create a cookie with this name - expires: 1 // cookie is stored for 1 day - } + storage: { + type: “cookie”, + name: “pbjs_li_nonid”, //create a cookie with this name + expires: 1 // cookie is stored for 1 day + } }] } }) @@ -649,11 +653,11 @@ pbjs.setConfig({ appId: "a-0012" } }, - storage: { - type: “cookie”, - name: “pbjs_li_nonid”, //create a cookie with this name - expires: 1 // cookie is stored for 1 day - } + storage: { + type: “cookie”, + name: “pbjs_li_nonid”, //create a cookie with this name + expires: 1 // cookie is stored for 1 day + } }] } }) @@ -919,7 +923,7 @@ In either case, bid adapters will receive the eid values after consent is valida 2. This design allows for the setting of any number of uuids in the eids object. Publishers may work with multiple ID providers and nest their own id within the same eids object. The opportunity to link a 1st party uuid and a 3rd party generated UUID presents publishers with a unique ability to address their users in a way demand sources will understand. -3. Finally, this module allows publishers to broadcast their user id, derived from in-house tech, directly to buyers within the confines of existing compliance (CCPA & GDPR) frameworks. +3. Finally, this module allows publishers to broadcast their user id, derived from in-house tech, directly to buyers within the confines of existing compliance (CCPA & GDPR) frameworks. 4. The `eids.uids.ext.stype` "source-type" extension helps downstream entities know what do with the data. Currently defined values are: @@ -967,17 +971,17 @@ pbjs.setConfig({ ### Shared ID User ID Submodule -The Shared ID User Module generates a UUID that can be utilized to improve user matching. This module enables timely synchronization and handles opt-out via sharedId.org. This module does not require any registration. +The Shared ID User Module generates a UUID that can be utilized to improve user matching. This module enables timely synchronization and handles opt-out via sharedId.org. 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. +Your Prebid build must include the modules for both **userId** and **sharedId** submodule. Add it to your Prebid.js package with: ex: $ gulp build --modules=userId,sharedIdSystem #### Prebid Params -Individual params may be set for the Shared ID User ID Submodule. +Individual params may be set for the Shared ID User ID Submodule. ``` pbjs.setConfig({ usersync: { @@ -1125,7 +1129,7 @@ Bidders that want to support the User ID module in Prebid.js, need to update the | CriteoID | Criteo | bidRequest.userId.criteoId | `"1111"` | | Halo ID | Audigent | bidRequest.userId.haloId | `{"haloId":"user-halo-id", "auSeg":["segment1","segment2"]}` | | ID+ | Zeotap | bidRequest.userId.IDP | `"1111"` | -| ID5 ID | ID5 | bidRequest.userId.id5id | `"1111"` | +| ID5 ID | ID5 | bidRequest.userId.id5id | `{ uid: "1111", ext: { linkType: 2 } }` | | IdentityLink | Trade Desk | bidRequest.userId.idl_env | `"1111"` | | IntentIQ ID | IntentIQ | bidRequest.userId.intentiqid | `"1111"` | | LiveIntent ID | Live Intent | bidRequest.userId.lipb.lipbid | `"1111"` | @@ -1173,7 +1177,10 @@ Bidders that want to support the User ID module in Prebid Server, need to update "source": "id5-sync.com", "uids": [{ "id": "ID5-12345" - }] + }], + "ext": { + "linkType": 2 + } }, { source: "parrable.com", @@ -1182,7 +1189,7 @@ Bidders that want to support the User ID module in Prebid Server, need to update }] },{ "source": "audigent.com", - "atype": 1, + "atype": 1, "uids": [{ "id": "11111111" }] @@ -1260,9 +1267,9 @@ If you need to export the user IDs stored by Prebid User ID module, the `getUser pbjs.getUserIds() // returns object like bidRequest.userId. e.g. {"pubcid":"1111", "tdid":"2222"} ``` -You can use `getUserIdsAsEids()` to get the user IDs stored by Prebid User ID module in ORTB Eids format. Refer [eids.md](https://github.com/prebid/Prebid.js/blob/master/modules/userId/eids.md) for output format. +You can use [`getUserIdsAsEids()`](https://docs.prebid.org/dev-docs/publisher-api-reference.html#userId.getUserIdsAsEids) to get the user IDs stored by Prebid User ID module in ORTB Eids format. Refer [eids.md](https://github.com/prebid/Prebid.js/blob/master/modules/userId/eids.md) for output format. ``` -pbjs.getUserIdsAsEids() // returns userIds in ORTB Eids format. e.g. +pbjs.getUserIdsAsEids() // returns userIds in ORTB Eids format. e.g. [ { source: 'pubcid.org', @@ -1281,9 +1288,20 @@ pbjs.getUserIdsAsEids() // returns userIds in ORTB Eids format. e.g. rtiPartner: 'TDID' } }] + }, + + { + source: 'id5-sync.com', + uids: [{ + id: 'ID5-12345', + atype: 1 + }, + ext: { + linkType: 2 + }] } ] -``` +``` ## Passing UserIds to Google Ad Manager for targeting From ae07750eaca3800c3bff97a96f7bf5dd3ac3944f Mon Sep 17 00:00:00 2001 From: mimenet <64042452+mimenet@users.noreply.github.com> Date: Thu, 8 Oct 2020 13:07:00 -0700 Subject: [PATCH 007/149] initial check-in: document targetingControls.allowTargetingKeys (#2346) * initial check-in: document targetingControls.allowTargetingKeys * update documentation to include the names and values of the default targeting keys. also changed presentation order so implementation example appears after context. --- dev-docs/publisher-api-reference.md | 54 +++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/dev-docs/publisher-api-reference.md b/dev-docs/publisher-api-reference.md index 4269d8dd94..fe047088b1 100644 --- a/dev-docs/publisher-api-reference.md +++ b/dev-docs/publisher-api-reference.md @@ -2037,6 +2037,7 @@ The `targetingControls` object passed to `pbjs.setConfig` provides some options |------------+---------+---------------------------------| | auctionKeyMaxChars | integer | Specifies the maximum number of characters the system can add to ad server targeting. | | alwaysIncludeDeals | boolean | If [enableSendAllBids](#setConfig-Send-All-Bids) is false, set this value to `true` to ensure that deals are sent along with the winning bid | +| allowTargetingKeys | Array of Strings | Selects supported default targeting keys. | {: .alert.alert-info :} Note that this feature overlaps and can be used in conjunction with [sendBidsControl.bidLimit](/dev-docs/publisher-api-reference.html#setConfig-Send-Bids-Control). @@ -2081,6 +2082,59 @@ Between these two values (Prebid's targeting key count and the overall ad URL qu Between this feature and the overlapping [sendBidsControl.bidLimit](/dev-docs/publisher-api-reference.html#setConfig-Send-Bids-Control), you should be able to make sure that there's not too much data going to the ad server. +##### Details on the allowTargetingKeys setting + +When this property is set up, the `allowTargetingKeys` creates a default targeting key mask based on the default targeting keys defined in CONSTANTS.TARGETING_KEYS and CONSTANTS.NATIVE_KEYS. Any default keys that do not match the mask will not be sent to the adserver. This setting can be helpful if you find that your prebid implementation is by default sending key values that your adserver isn't configured to process. When extraneous key values are sent, the ad server request can be truncated, which can cause potential issues with the delivery or rendering of the ad. + +To accomplish this, Prebid does the following: +* Collect original targeting generated by the auction. +* Generate new targeting filtered against allowed keys. + * Custom targeting keys are always added to targeting. + * Default targeting keys are added to targeting only if they match an allowed key named in `setConfig`. +* New targeting replaces original targeting before targeting is flattened. + +The targeting key names and the associated prefix value filtered by `allowTargetingKeys`: +{: .table .table-bordered .table-striped } +| Name | Value | +|------------+------------| +| BIDDER | `hb_bidder` | +| AD_ID | `hb_adid` | +| PRICE_BUCKET | `hb_pb` | +| SIZE | `hb_size` | +| DEAL | `hb_deal` | +| SOURCE | `hb_source` | +| FORMAT | `hb_format` | +| UUID | `hb_uuid` | +| CACHE_ID | `hb_cache_id` | +| CACHE_HOST | `hb_cache_host` | +| title | `hb_native_title` | +| body | `hb_native_body` | +| body2 | `hb_native_body2` | +| privacyLink | `hb_native_privacy` | +| privacyIcon | `hb_native_privicon` | +| sponsoredBy | `hb_native_brand` | +| image | `hb_native_image` | +| icon | `hb_native_icon` | +| clickUrl | `hb_native_linkurl` | +| displayUrl | `hb_native_displayurl` | +| cta | `hb_native_cta` | +| rating | `hb_native_rating` | +| address | `hb_native_address` | +| downloads | `hb_native_downloads` | +| likes | `hb_native_likes` | +| phone | `hb_native_phone` | +| price | `hb_native_price` | +| salePrice | `hb_native_saleprice` | + +Below is an example config containing `allowTargetingKeys` excluding all default targeting keys except `hb_bidder`, `hb_adid`, and `hb_pb`: + +```javascript +config.setConfig({ + targetingControls: { + allowTargetingKeys: ['BIDDER', 'AD_ID', 'PRICE_BUCKET'] + } +}); +``` From 6d3c76ee4c8b378255fd7cca55e6a5b4ac2a9b87 Mon Sep 17 00:00:00 2001 From: Alexey Elymanov Date: Thu, 8 Oct 2020 23:08:45 +0300 Subject: [PATCH 008/149] between docs (#2299) * between docs * gitignore * between adapter docs fix Co-authored-by: Alexey Elymanov --- .gitignore | 2 ++ dev-docs/bidders/between.md | 15 ++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 0d439cb11e..ad4754cd5e 100755 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ Gemfile.lock /vendor /.bundle .jekyll-metadata +*ads.txt.bkp* + diff --git a/dev-docs/bidders/between.md b/dev-docs/bidders/between.md index 7772f33712..72e2d906b4 100644 --- a/dev-docs/bidders/between.md +++ b/dev-docs/bidders/between.md @@ -1,16 +1,17 @@ --- layout: bidder -title: BetweenDigital -description: between bid adapter +title: Between +description: Prebid Between Bidder Adaptor pbjs: true +pbs: true biddercode: between +media_types: banner --- ### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | -|------------+----------+-------------------------------------------+-----------| -| `w` | required | width of placement(Number) | 240 | -| `h` | required | height of placement(Number) | 400 | -| `s` | required | Section ID, provided by betweendigital | 12345 | +| Name | Scope | Description | Example | Type | +|---------------|----------|-------------|---------|----------| +| `host` | required | between host url prefix | `eu` | `string` | + From 7b28bd7fd737a0aed183ff906c1dec0ae3d78048 Mon Sep 17 00:00:00 2001 From: wojciech-bialy-wpm <67895844+wojciech-bialy-wpm@users.noreply.github.com> Date: Thu, 8 Oct 2020 22:20:06 +0200 Subject: [PATCH 009/149] Sspbc adapter - update md file (prebid support, vendor id) (#2404) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add sspbc adapter * add sspbc adapter * sspBC adaptor: update bidder description Co-authored-by: Wojciech Biały --- dev-docs/bidders/sspBCAdapter.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/sspBCAdapter.md b/dev-docs/bidders/sspBCAdapter.md index beb818194c..357636a711 100644 --- a/dev-docs/bidders/sspBCAdapter.md +++ b/dev-docs/bidders/sspBCAdapter.md @@ -2,11 +2,12 @@ layout: bidder title: sspBC description: Prebid sspBC Bidder Adaptor - +pbjs: true biddercode: sspBC media_types: banner gdpr_supported: true tcf2_supported: true +gvl_id: 676 --- @@ -19,4 +20,4 @@ tcf2_supported: true | `siteId` | required | site id | `'235911'` | `string` | | `domain` | optional | site domain | `'somesite.com'` | `string` | | `page` | optional | page url | `'somesite.com/index.html'` | `string` | -| `tmax` | optional | tmax for server connection | `250` | `integer` | +| `tmax` | optional | tmax for server connection | `400` | `integer` | From 38b156079594b6bd46ca212af56ddcbc8d418515 Mon Sep 17 00:00:00 2001 From: jdwieland8282 Date: Fri, 9 Oct 2020 10:28:02 -0600 Subject: [PATCH 010/149] Update userId.md (#2410) adding more details to the pubprovided id modulee --- dev-docs/modules/userId.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index f292ab606a..d23a009dfa 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -933,6 +933,20 @@ In either case, bid adapters will receive the eid values after consent is valida 5. Bid adapters listening for "userIds.pubProvidedId" will not receive a string, please use the userIdAsEids value/function to return the userid as a string. +Add it to your Prebid.js package with: + +{: .alert.alert-info :} gulp build --modules=pubProvidedId + +#### PubProvided Configuration + +{: .table .table-bordered .table-striped } +| Params under usersync.userIds[]| Scope | Type | Description | Example | +| --- | --- | --- | --- | --- | +| name | Required | String | ID value for the ID module | `"PubProvided"` | +| params | Optional | Object | Details for syncing. | | +| params.eidsFunction | Optional | function | any function that exists in the page | getIdsFn() | +| uids.atype | optional | int | ADCOM - Type of user agent the match is from | `"1"` | +| uids.ext.stype | Optional | String | Description of how the id was generated and by whom ('ppuid','DMP','other') | `DMP` | ### Quantcast ID From 7bde4c6b368f018bc1d1aa4fa21adbe2e133816c Mon Sep 17 00:00:00 2001 From: jdwieland8282 Date: Fri, 9 Oct 2020 10:36:58 -0600 Subject: [PATCH 011/149] Update userId.md --- dev-docs/modules/userId.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index d23a009dfa..cf16a9f01f 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -935,7 +935,9 @@ In either case, bid adapters will receive the eid values after consent is valida Add it to your Prebid.js package with: -{: .alert.alert-info :} gulp build --modules=pubProvidedId +{: .alert.alert-info :} +gulp build --modules=pubProvidedId + #### PubProvided Configuration From c91ff3743de545fe7b6cf31e6af14e3b602526f0 Mon Sep 17 00:00:00 2001 From: pro-nsk <32703851+pro-nsk@users.noreply.github.com> Date: Wed, 14 Oct 2020 21:20:10 +0700 Subject: [PATCH 012/149] Add Qwarry bid adapter (#2380) * Qwarry adapter description * fix * add pbjs: true * add quotes to example string parameter Co-authored-by: Alexander Kascheev --- dev-docs/bidders/qwarry.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 dev-docs/bidders/qwarry.md diff --git a/dev-docs/bidders/qwarry.md b/dev-docs/bidders/qwarry.md new file mode 100644 index 0000000000..424448bf0f --- /dev/null +++ b/dev-docs/bidders/qwarry.md @@ -0,0 +1,17 @@ +--- +layout: bidder +title: Qwarry +description: Prebid Qwarry Bidder Adaptor +biddercode: qwarry +media_types: banner, video +pbjs: true +--- + + + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------------|----------|------------------------------------------|----------------------------------------|----------| +| `zoneToken` | required | The ID issued by Qwarry to the publisher | `'8a80d8e9-0cf9-4329-8486-6f5bbcd8a61a'` | `string` | From c3c9de87ca7c778743d640c7b4ba7a5821b9c845 Mon Sep 17 00:00:00 2001 From: jdwieland8282 Date: Wed, 14 Oct 2020 08:57:44 -0600 Subject: [PATCH 013/149] Update userId.md updating gulp build alert & removing reference to the requirement that the userid module be built along side the subadapter, that happens automatically now. --- dev-docs/modules/userId.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index cf16a9f01f..4f54809d40 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -990,10 +990,10 @@ pbjs.setConfig({ The Shared ID User Module generates a UUID that can be utilized to improve user matching. This module enables timely synchronization and handles opt-out via sharedId.org. 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. Add it to your Prebid.js package with: -ex: $ gulp build --modules=userId,sharedIdSystem +{: .alert.alert-info :} +ex: $ gulp build --modules=sharedIdSystem #### Prebid Params From c4cdc40c8a2413e3213b6b61ba729dfb7b660920 Mon Sep 17 00:00:00 2001 From: Gena Date: Wed, 14 Oct 2020 20:18:27 +0300 Subject: [PATCH 014/149] Update adtarget table (#2421) --- dev-docs/bidders/adtarget.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/adtarget.md b/dev-docs/bidders/adtarget.md index 083d097c49..f4d0ae40d9 100644 --- a/dev-docs/bidders/adtarget.md +++ b/dev-docs/bidders/adtarget.md @@ -9,6 +9,7 @@ userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrable schain_supported: true coppa_supported: true usp_supported: true +tcf2_supported: true pbjs: true pbs: true --- From 96ead611f16e9e0c6f90d126a6a1b5ca242caf24 Mon Sep 17 00:00:00 2001 From: Gena Date: Wed, 14 Oct 2020 20:18:52 +0300 Subject: [PATCH 015/149] update selectmedia name in doc (#2419) --- dev-docs/bidders/selectmedia.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/selectmedia.md b/dev-docs/bidders/selectmedia.md index 0dc5f79eba..9b582590ed 100644 --- a/dev-docs/bidders/selectmedia.md +++ b/dev-docs/bidders/selectmedia.md @@ -1,6 +1,6 @@ --- layout: bidder -title: Select Media +title: Select Media Display description: Prebid Select Media Bidder Adapter pbjs: true biddercode: selectmedia From ca71a811e17811e478d0af5c996e20f20b46e59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Giraudel?= Date: Wed, 14 Oct 2020 19:23:59 +0200 Subject: [PATCH 016/149] Wrong label in PBS Java page (#2415) Labels were referencing the Go version of PBS --- prebid-server/versions/pbs-versions-java.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prebid-server/versions/pbs-versions-java.md b/prebid-server/versions/pbs-versions-java.md index ae665e225d..4fa6ad51fc 100644 --- a/prebid-server/versions/pbs-versions-java.md +++ b/prebid-server/versions/pbs-versions-java.md @@ -34,8 +34,8 @@ PBS-Java look over the [feature list](/prebid-server/features/pbs-feature-idx.ht The repositories are currently in the Rubicon-Project GitHub organization, but will soon move to the Prebid org. -- [Prebid Server - Go](https://github.com/rubicon-project/prebid-server-java) -- [Prebid Cache Server - Go](https://github.com/prebid/prebid-cache-java) +- [Prebid Server - Java](https://github.com/rubicon-project/prebid-server-java) +- [Prebid Cache Server - Java](https://github.com/prebid/prebid-cache-java) ## Installation From c0a5d87db751e91d3630aee5072a8f9b8d9224c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Giraudel?= Date: Wed, 14 Oct 2020 19:24:43 +0200 Subject: [PATCH 017/149] Typo (#2414) --- prebid-server/use-cases/pbs-pbjs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prebid-server/use-cases/pbs-pbjs.md b/prebid-server/use-cases/pbs-pbjs.md index 414d745f3c..472ff3c43a 100644 --- a/prebid-server/use-cases/pbs-pbjs.md +++ b/prebid-server/use-cases/pbs-pbjs.md @@ -170,7 +170,7 @@ Next comes the auction and response: 1. Enforce privacy regulations 1. Call the bidders 1. Collect responses -1. Cache teh VAST XML as instructed (for video) +1. Cache the VAST XML as instructed (for video) 1. Prepare the OpenRTB response ### The Page Gets the Response From 439ac93ba88da47f1d8350f0cd44ab4350a09310 Mon Sep 17 00:00:00 2001 From: andbeyondmedia <38574037+andbeyondmedia@users.noreply.github.com> Date: Wed, 14 Oct 2020 22:58:54 +0530 Subject: [PATCH 018/149] Update andbeyond.md (#2411) Changing Email --- dev-docs/bidders/andbeyond.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/andbeyond.md b/dev-docs/bidders/andbeyond.md index 1d60ed19cb..d32c64179d 100644 --- a/dev-docs/bidders/andbeyond.md +++ b/dev-docs/bidders/andbeyond.md @@ -8,7 +8,7 @@ biddercode: andbeyond ### Note: -The andbeyond Bidding adaptor requires setup and approval before beginning. Please reach out to for more details +The andbeyond Bidding adaptor requires setup and approval before beginning. Please reach out to for more details ### Bid Params From ca1aa4d90a98cd9401cc1dcbb8d469f78e62cea4 Mon Sep 17 00:00:00 2001 From: Renzo Toscani <7190938+rtoscani@users.noreply.github.com> Date: Wed, 14 Oct 2020 14:30:55 -0300 Subject: [PATCH 019/149] add IDx User Id docs (#2408) * add IDx User Id docs * add IDx entry --- dev-docs/modules/userId.md | 35 ++++++++++++++++++++++++++++++++++- download.md | 3 +++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index 4f54809d40..aee4fa53c2 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -58,7 +58,8 @@ of sub-objects. The table below has the options that are common across ID system {: .table .table-bordered .table-striped } | Param under userSync.userIds[] | Scope | Type | Description | Example | | --- | --- | --- | --- | --- | -| name | Required | String | May be: `"britepoolId"`, `"criteo"`, `"fabrickId"`, `"haloId"`, `"id5id"`, `identityLink`, `"intentIqId"`, `"liveIntentId"`, `"lotamePanoramaId"`, `"merkleId"`, `"netId"`, `"parrableId"`, `"quantcastId"`, `"pubCommonId"`, `"pubProvidedId"`, `"sharedId"`, `"unifiedId"`, `"zeotapIdPlus"` | `"unifiedId"` | + +| name | Required | String | May be: `"britepoolId"`, `"criteo"`, `"fabrickId"`, `"haloId"`, `"id5id"`, `identityLink`, `"idx"`, `"intentIqId"`, `"liveIntentId"`, `"lotamePanoramaId"`, `"merkleId"`, `"netId"`, `"parrableId"`, `"quantcastId"`, `"pubCommonId"`, `"pubProvidedId"`, `"sharedId"`, `"unifiedId"`, `"zeotapIdPlus"` | `"unifiedId"` | | params | Based on User ID sub-module | Object | | | | storage | Optional | Object | The publisher can specify some kind of local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. This is not needed when `value` is specified or the ID system is managing its own storage | | | storage.type | Required | String | Must be either `"cookie"` or `"html5"`. This is where the results of the user ID will be stored. | `"cookie"` | @@ -434,6 +435,38 @@ pbjs.setConfig({ }); {% endhighlight %} +### IDx + +IDX is an alternative cookieless ID that uses anonymized and verified identifiers, provided by the users with explicit consent, which enables buy, sell, and measure targeted advertising at scale. IDX is created by Retargetly, a data company that owns the biggest consumer graph in Latin America. + +This sub-module enables the user’s IDx to be available in the bid request. + +More information of IDx can be found in [https://idx.lat/](https://idx.lat/) + +Add it to your Prebid.js package with: + +{: .alert.alert-info :} +gulp build --modules=idxIdSystem + +#### IDx Configuration + +{: .table .table-bordered .table-striped } +| Param under userSync.userIds[] | Scope | Type | Description | Example | +| --- | --- | --- | --- | --- | +| name | Required | String | `"idx"` | `"idx"` | + +#### IDx Example + +{% highlight javascript %} +pbjs.setConfig({ + userSync: { + userIds: [{ + name: "idx" + }] + } +}); +{% endhighlight %} + ### IntentIQ ID The IntentIQ ID solution is provided by intentiq.com. diff --git a/download.md b/download.md index 2ee2bfbf6c..c53055d9f4 100644 --- a/download.md +++ b/download.md @@ -527,6 +527,9 @@ Prebid.js is open source software that is offered for free as a convenience. Whi
+ +
+
From 841b14b95e4934fd29c1588e846abf508bbade88 Mon Sep 17 00:00:00 2001 From: hybrid-ai <58724131+hybrid-ai@users.noreply.github.com> Date: Wed, 14 Oct 2020 20:33:23 +0300 Subject: [PATCH 020/149] Hybrid adapter. Added docs for In-Image format (#2341) * Added documentation for Hybrid.ai Adapter * added quotes around string params * Added gdpr support flag * Added docs for In-Image format Co-authored-by: s.shevtsov Co-authored-by: bretg --- dev-docs/bidders/hybrid.md | 194 ++++++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 4 deletions(-) diff --git a/dev-docs/bidders/hybrid.md b/dev-docs/bidders/hybrid.md index 7eaaeef996..462fb58a13 100644 --- a/dev-docs/bidders/hybrid.md +++ b/dev-docs/bidders/hybrid.md @@ -18,10 +18,11 @@ The code below returns a demo ad. ### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|---------------------|---------------------|-------------------------------------------------------------------|-------------------------------------|----------| -| `placeId` | required | The place id. | '5af45ad34d506ee7acad0c26' | `string` | -| `placement` | required | Adunit placement, possible values: banner, video | 'banner' | `string` | +| Name | Scope | Description | Example | Type | +|---------------------|------------------------|-------------------------------------------------------------------|--------------------------------------|----------| +| `placeId` | required | The place id. | '5af45ad34d506ee7acad0c26' | `string` | +| `placement` | required | Adunit placement, possible values: banner, video, inImage | 'banner' | `string` | +| `imageUrl` | required for inImage | URL of the image on which the banner will be displayed | 'https://hybrid.ai/images/image.jpg' | `string` | ### Sample Banner Ad Unit @@ -64,3 +65,188 @@ var adUnits = [{ }] }]; ``` + +### Sample In-Image Ad Unit + +```js +var adUnits = [{ + code: 'test-div', + mediaTypes: { + banner: { + sizes: [0, 0] + } + }, + bids: [{ + bidder: "hybrid", + params: { + placement: "inImage", + placeId: "102030405060708090000020", + imageUrl: "https://hybrid.ai/images/image.jpg" + } + }] +}]; +``` + +### Example page with In-Image + +```html + + + + + Prebid.js Banner Example + + + + + +

Prebid.js InImage Banner Test

+
+ + +
+ + +``` + +### Example page with In-Image and GPT + +```html + + + + + Prebid.js Banner Example + + + + + + +

Prebid.js Banner Ad Unit Test

+
+ + +
+ + +``` From d73b242417192ed55e927cdef0a36871cad0a166 Mon Sep 17 00:00:00 2001 From: hamper Date: Wed, 14 Oct 2020 20:37:22 +0300 Subject: [PATCH 021/149] add vuukle adapter (#2355) --- dev-docs/bidders/vuukle.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 dev-docs/bidders/vuukle.md diff --git a/dev-docs/bidders/vuukle.md b/dev-docs/bidders/vuukle.md new file mode 100644 index 0000000000..e1a9561379 --- /dev/null +++ b/dev-docs/bidders/vuukle.md @@ -0,0 +1,14 @@ +--- +layout: bidder +title: Vuukle +description: vuukle bid adapter +pbjs: true +biddercode: vuukle +--- + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------------+----------+-----------------------------------+----------|----------| +| `placement` | optional | Placement id, provided by vuukle | `'1'` | `string` | From 37808ec6989ff7973c789dd85cbab835bf31461f Mon Sep 17 00:00:00 2001 From: Neelanjan Sen <14229985+Fawke@users.noreply.github.com> Date: Wed, 14 Oct 2020 23:11:17 +0530 Subject: [PATCH 022/149] add docs (#2394) --- dev-docs/bidders/appnexus.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/appnexus.md b/dev-docs/bidders/appnexus.md index 319650605b..528673ed2d 100644 --- a/dev-docs/bidders/appnexus.md +++ b/dev-docs/bidders/appnexus.md @@ -42,6 +42,7 @@ All AppNexus placements included in a single call to `requestBids` must belong t | `member` | optional | The member ID from AppNexus. Must be used with `invCode`. | `'12345'` | `string` | | `invCode` | optional | The inventory code from AppNexus. Must be used with `member`. | `'abc123'` | `string` | | `publisherId` | optional | The publisher ID from AppNexus. It is used by the AppNexus end point to identify the publisher when `placementId` is not provided and `invCode` goes wrong. The `publisherId` parameter can be either a `string` or `integer` for Prebid.js, however `integer` is preferred. | `12345` | `integer` | +| `frameworks` | optional | Array of integers listing API frameworks for Banner supported by the publisher. | `integer` | | `user` | optional | Object that specifies information about an external user. See [User Object](#appnexus-user-object) for details. | `user: { age: 25, gender: 0, dnt: true}` | `object` | | `allowSmallerSizes` | optional | If `true`, ads smaller than the values in your ad unit's `sizes` array will be allowed to serve. Defaults to `false`. | `true` | `boolean` | | `usePaymentRule` | optional | If `true`, Appnexus will return net price to Prebid.js after publisher payment rules have been applied. | `true` | `boolean` | @@ -70,7 +71,7 @@ All AppNexus placements included in a single call to `requestBids` must belong t | `skippable` | Boolean which, if `true`, means the user can click a button to skip the video ad. Defaults to `false`. | `boolean` | |`skipoffset`| Integer that defines the number of seconds until an ad can be skipped. Assumes `skippable` setting was set to `true`. | `integer` | | `playback_method` | A string that sets the playback method supported by the publisher. Allowed values: `"auto_play_sound_on"`; `"auto_play_sound_off"`; `"click_to_play"`; `"mouseover"`; `"auto_play_sound_unknown"`. | `string` | -| `frameworks` | Array of integers listing API frameworks supported by the publisher. Allowed values: None: `0`; VPAID 1.0: `1`; VPAID 2.0: `2`; MRAID 1.0: `3`; MRAID 2.0: `4`; ORMMA: `5`. | `Array` | +| `frameworks` | Array of integers listing API frameworks supported by the publisher. Allowed values: None: `0`; VPAID 1.0: `1`; VPAID 2.0: `2`; MRAID 1.0: `3`; MRAID 2.0: `4`; ORMMA: `5`; OMID 1.0 `6`. | `Array` |
From a7ce086d670058f54bc2334acc01b5a7cba124ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Dlouh=C3=BD?= Date: Wed, 14 Oct 2020 19:42:06 +0200 Subject: [PATCH 023/149] Add stroeerCore bidder documentation (#1) (#2400) * Add stroeerCore bidder documenation (#1) * Add bid params table * re-ordered sections also demoted the ad unit config to level 3 instead of level 2 Co-authored-by: bretg --- dev-docs/bidders/stroeerCore.md | 49 +++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 dev-docs/bidders/stroeerCore.md diff --git a/dev-docs/bidders/stroeerCore.md b/dev-docs/bidders/stroeerCore.md new file mode 100644 index 0000000000..affaac4de6 --- /dev/null +++ b/dev-docs/bidders/stroeerCore.md @@ -0,0 +1,49 @@ +--- +layout: bidder +title: StroeerCore +description: Stroeer Bidder Adapter +biddercode: stroeerCore +media_types: banner +gdpr_supported: false +schain_supported: false +coppa_supported: false +usp_supported: false +tcf2_supported: true +safeframes_ok: true +prebid_member: false +pbjs: true +pbs: false +gvl_id: 136 +bidder_supports_deals: true +--- + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|--------------------|------------------------------|----------| +| `sid` | required | Slot ID | `'06b782cc-091b-4f53-9cd2-0291679aa1ac'`| `string` | + +### Config Notes + +* Slot id (`sid`) is required. The adapter will ignore bid requests from prebid if `sid` is not provided. This must be in the decoded form. For example, "1234" as opposed to "MTM0ODA=". +* The server ignores dimensions that are not supported by the slot or by the platform (such as 987x123). + +### Ad unit configuration for publishers + +```javascript +const adUnits = [{ + code: 'div-gpt-ad-1460505748561-0', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [{ + bidder: 'stroeerCore', + params: { + sid: "06b782cc-091b-4f53-9cd2-0291679aa1ac" + } + }] +}]; +``` From 8b61f0900d0b3122ba167b8f93b7ef6ee0f23b0b Mon Sep 17 00:00:00 2001 From: liranbaruch Date: Wed, 14 Oct 2020 20:42:42 +0300 Subject: [PATCH 024/149] Adding test mode documentation for the IronSource bidder (#2401) * 1.Change ironsource to be lower case all over 2.add pbjs: true * Add test mode definition --- dev-docs/bidders/ironsource.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev-docs/bidders/ironsource.md b/dev-docs/bidders/ironsource.md index 126b2900d9..3c2add5d2f 100644 --- a/dev-docs/bidders/ironsource.md +++ b/dev-docs/bidders/ironsource.md @@ -24,6 +24,7 @@ The IronSource adapter requires setup and approval. Please reach out to prebid-d | `isOrg` | required | String | IronSource publisher Id provided by your IronSource representative | "56f91cd4d3e3660002000033" | `floorPrice` | optional | Number | Minimum price in USD.

**WARNING:**
Misuse of this parameter can impact revenue | 2.00 | `ifa` | optional | String | The ID for advertisers (also referred to as "IDFA") | "XXX-XXX" +| `testMode` | optional | Boolean | This activates the test mode | false ## Example ```javascript @@ -43,6 +44,7 @@ var adUnits = [ isOrg: '56f91cd4d3e3660002000033', // Required floorPrice: 5.00, // Optional ifa: 'XXX-XXX', // Optional + testMode: false // Optional } }] } From 7bedbdc3a9f872c57768020f845a16ddb28b8ca5 Mon Sep 17 00:00:00 2001 From: Thomas Ladd Date: Wed, 14 Oct 2020 12:44:33 -0500 Subject: [PATCH 025/149] Docs for refreshUserIds publisher api method (#2402) * Docs for refreshUserIds publisher api method Relates to https://github.com/prebid/Prebid.js/pull/5819 * Remove `=> undefined` from refreshUserIds title --- .../main.scssc | Bin 0 -> 529 bytes dev-docs/publisher-api-reference.md | 25 ++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 .sass-cache/e54a2b524845b6c18a57dadf1796966da31d0138/main.scssc diff --git a/.sass-cache/e54a2b524845b6c18a57dadf1796966da31d0138/main.scssc b/.sass-cache/e54a2b524845b6c18a57dadf1796966da31d0138/main.scssc new file mode 100644 index 0000000000000000000000000000000000000000..b3701f0ddf119bd5c2a9645f14c84969c2d01306 GIT binary patch literal 529 zcmbu6F;BxV5QRISP*O?}QxOa54@d%O+QyMk7Aj>yh?a>Va_UQCDX}A;D})gLolDBX zh}eA3_I>x>h2GMeyMl)?4*?=r6!Rhw;e8YpC6sZr2<}#Kz)P_TmO<>E3^lvna74zo z27s{_t?iQ*Fk%ll(GiJ8wl7q)vc9U;b*5?Xxf@v$YukFIgeZBrnOWc z9d?zXKA0WkhO0ejHa&7Sy-1`^J!6v;EjKoAHEMSA`^mFL*^y3@5%oJyby*@4sy?h4A;%R)@lG4HQy%$I6r1&yl?Q4VTKp9io%C zTk<5ERvQaOv)ki9*^fXmttkimK(aj~prN?3+5C?{!mP=-0bb|-=rB!@7Ls>c$=|tA TQtc_j;RbA%Ma8lD8mzwo6*;b- literal 0 HcmV?d00001 diff --git a/dev-docs/publisher-api-reference.md b/dev-docs/publisher-api-reference.md index fe047088b1..4d63511e46 100644 --- a/dev-docs/publisher-api-reference.md +++ b/dev-docs/publisher-api-reference.md @@ -78,6 +78,7 @@ Functions added by optional modules * [.adServers.freewheel.getTargeting(options)](#module_pbjs.getTargeting) - requires [Freewheel Module](/dev-docs/modules/freewheel.html) * [.getUserIds()](#userId.getUserIds) - requires [User Id Module](/dev-docs/modules/userId.html) * [.getUserIdsAsEids()](#userId.getUserIdsAsEids) - requires [User Id Module](/dev-docs/modules/userId.html) + * [.refreshUserIds(options, callback)](#userId.refreshUserIds) - requires [User Id Module](/dev-docs/modules/userId.html)
@@ -546,6 +547,30 @@ pbjs.getUserIdsAsEids() // returns userIds in ORTB Eids format. e.g.
+ + +### pbjs.refreshUserIds(options, callback) + +{: .alert.alert-info :} +To use this function, include the [UserId module](/dev-docs/modules/userId.html) in your Prebid.js build. + +The `refreshUserIds` function allows you to force either all or a subset of userId submodules to reinitialize their id values. You might want to do this if an event on your page occurred that would change the id value of a submodule. For example, a user logging in. + +{: .table .table-bordered .table-striped } +| Param | Scope | Type | Description | +| --- | --- | --- | --- | +| options | optional | Object | Options object | +| options.submoduleNames | optional | Array of strings | The userId submodule names that should be refreshed. If this option is omitted, all userId submodules are refreshed. | +| callback | optional | Function | Callback that is called after refreshing user ids has completed | + + +``` +pbjs.refreshUserIds(); +pbjs.refreshUserIds({ submoduleNames: ['britepoolId'] }, () => console.log("Done!")); +``` + +
+ ### pbjs.getNoBids() ⇒ `Array` From f758d6f0e536a86fe4f0d778ac91cd5374c335b5 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 15 Oct 2020 16:35:30 -0400 Subject: [PATCH 026/149] getting started page not showing jsfiddle (#2425) --- dev-docs/getting-started.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dev-docs/getting-started.md b/dev-docs/getting-started.md index 06a28bc39b..6b49b01937 100644 --- a/dev-docs/getting-started.md +++ b/dev-docs/getting-started.md @@ -19,7 +19,15 @@ The easiest way to get started with Prebid.js is to use the example code below. {% include dev-docs/build-from-source-warning.md %} - + +
+

(Sorry, jsfiddle code examples aren't available with your cookie privacy settings.)

+

Cookie Settings


+
+ + ### Next Steps From 0be195213050ba3061b5b4f10fef16ef0a5a5315 Mon Sep 17 00:00:00 2001 From: bretg Date: Fri, 16 Oct 2020 16:08:30 -0400 Subject: [PATCH 027/149] adding adservertargeting docs (#2428) --- .../openrtb2/pbs-endpoint-auction.md | 117 +++++++++++++----- prebid-server/features/pbs-feature-idx.md | 1 + 2 files changed, 87 insertions(+), 31 deletions(-) diff --git a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md index 7100f4f584..0119d9e878 100644 --- a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md +++ b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md @@ -605,6 +605,33 @@ In this scenario, Prebid Server sends the first schain object to `bidderA` and t If there's already an source.ext.schain and a bidder is named in ext.prebid.schains (or covered by the wildcard condition), ext.prebid.schains takes precedent. +#### User IDs + +Prebid Server adapters can support the [Prebid.js User ID modules](http://prebid.org/dev-docs/modules/userId.html) by reading the following extensions and passing them through to their server endpoints: + +``` +{ + "user": { + "ext": { + "eids": [{ + "source": "adserver.org", + "uids": [{ + "id": "111111111111", + "ext": { + "rtiPartner": "TDID" + } + }] + }, + { + "source": "pubcommon", + "id":"11111111" + } + ] + } + } +} +``` + #### Rewarded Video (PBS-Java only) Rewarded video is a way to incentivize users to watch ads by giving them 'points' for viewing an ad. A Prebid Server @@ -741,37 +768,6 @@ Setting up the storedresponse DB entries is the responsibility of each Prebid Se See Prebid.org troubleshooting pages for how to utilize this feature within the context of the browser. -#### User IDs - -Prebid Server adapters can support the [Prebid.js User ID modules](http://prebid.org/dev-docs/modules/userId.html) by reading the following extensions and passing them through to their server endpoints: - -``` -{ - "user": { - "ext": { - "eids": [{ - "source": "adserver.org", - "uids": [{ - "id": "111111111111", - "ext": { - "rtiPartner": "TDID" - } - }] - }, - { - "source": "pubcommon", - "id":"11111111" - } - ], - "digitrust": { - "id": "11111111111", - "keyv": 4 - } - } - } -} -``` - #### First Party Data Support (PBS-Java only) This is the Prebid Server version of the Prebid.js First Party Data feature. It's a standard way for the page (or app) to supply first party data and control which bidders have access to it. @@ -822,6 +818,65 @@ Prebid Server enforces the data permissioning. So before passing the values to t Each adapter must be coded to read the values from these locations and pass it to their endpoints appropriately. +#### Custom Targeting (PBS-Java only) + +An OpenRTB extension, whether in the the original request or the [stored-request](/prebid-server/features/pbs-storedreqs.html), can customize the ad server targeting generated by PBS. + +The OpenRTB field is `ext.prebid.adservertargeting`. Here's an example: + +``` + ext.prebid.adservertargeting: [{ + "key": "hb_amp_ow", // the targeting key + "source": "bidrequest", // pull the value from the path specified in the bid request object + "value": "ext.prebid.amp.data.ow" // path to value in the bidrequest + },{ + "key": "hb_static_thing", + "source": "static", // just use the 'value' provided + "value": "my-static-value" + },{ + "key": "{{BIDDER}}_custom1", // {{BIDDER}} is a macro to be resolved + "source": "bidresponse", // pull the value from the path specified in the bid response object + "value": "seatbid.bid.ext.custom1" + } + }] +``` +`ext.prebid.adservertargeting` is an array objects. Each object has the following format: + +{: .table .table-bordered .table-striped } +| Attribute | Required? | Description | Example | Type | +| --- | --- | --- | --- | --- | +| key | yes | Defines the key part of the targeting key-value-pair. May contain a ``{{BIDDER}}` macro which is resolved to the biddercode. | "hb_custom_thing" | string | +| source | yes | Defines where to get the value part of the key-value-pair. Options are "static", "bidrequest", and "bidresponse". | "bidresponse" | string | +| value | yes | Along with `source`, defines the value part of the targeting key-value-pair. If source=bidrequest or source=bidresponse, `value` is taken to be an openrtb path. | "seatbid.bid.ext.custom1" | string | + +In order to pull AMP parameters out into targeting, Prebid Server places AMP query string parameters in ext.prebid.amp.data. e.g. +``` + "ext": { + "prebid": { + "amp": { + "data": { + "adc": "GA1.2.662776284.1602172186", + "curl": "https://example.com/index.html", + "debug": "1", + "pvid": "", // page view ID + "ms": "", // multi-size + "ow": "", // override-width + "oh": "", // override-height + "w": "300", + "h": "50", + "gdpr_consent": "", + "purl": "https://example.com/index.html", + "slot": "/11111/amp_test", + "timeout": "1000", + "targeting": "{\"site\":{\"attr\":\"val\"}}", + "tag_id": "amp-AMP_Test-300x250", + "account": "22222" + } + } + } + } +``` + ### OpenRTB Ambiguities This section describes the ways in which Prebid Server **implements** OpenRTB spec ambiguous parts. diff --git a/prebid-server/features/pbs-feature-idx.md b/prebid-server/features/pbs-feature-idx.md index 18683d93b4..7e830f9850 100644 --- a/prebid-server/features/pbs-feature-idx.md +++ b/prebid-server/features/pbs-feature-idx.md @@ -16,6 +16,7 @@ title: Prebid Server | Features | [AMP](/prebid-server/use-cases/pbs-amp.html) | Core | Reads and responds to the /openrtb2/amp endpoint | | | | Targeting | Core | Request can specify `includewinners` and `includebidderkeys`. These cause PBS to emit seatbid[].bid[].ext.prebid.targeting values. | | | | Targeting | Format | Request can specify `includeformat`, which causes PBS to emit hb_format along with other targeting values like hb_pb, etc. | | | +| Targeting | [Custom Targeting](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#custom-targeting-pbs-java-only) | Request can specify `ext.prebid.adservertargeting`, which causes PBS to emit custom targeting values. | | | | [Price Granularity](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#targeting) | Core | Request can define quantization rules. Bids are quantized before being added to ad server targeting. | | | | Price Granularity | Mediatype pricegranularity | Request can define different quantization rules for different mediatypes. Bids are quantized before being added to ad server targeting. | | | | [GDPR](/prebid-server/features/pbs-privacy.html) | TCF 1.1 core | Able to: read the TCF1.1 global vendor list, parse incoming TCF1.1 consent strings, and [take appropriate enforcement action](https://docs.google.com/document/d/1g0zAYc_EfqyilKD8N2qQ47uz0hdahY-t8vfb-vxZL5w/edit). | | | From 305895a760aafc9860f2f4f326f7d81ef1e73dd7 Mon Sep 17 00:00:00 2001 From: jdwieland8282 Date: Fri, 16 Oct 2020 16:23:08 -0600 Subject: [PATCH 028/149] Add files via upload --- assets/images/dev-docs/IDlib.png | Bin 0 -> 45996 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/images/dev-docs/IDlib.png diff --git a/assets/images/dev-docs/IDlib.png b/assets/images/dev-docs/IDlib.png new file mode 100644 index 0000000000000000000000000000000000000000..b414ce5678688b9c44709f1f0b395737f24d0968 GIT binary patch literal 45996 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

O5y#!!pW_-gs2oxn<7cUMNd!Rw*r8!hqPyBEWq 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%0A)8-6+h^E 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 R&xnqJkNXl&=VC{0?4Mlg0A2t9 literal 0 HcmV?d00001 From 49f519824f0d9be24d5c379bada2ffc098f1bd39 Mon Sep 17 00:00:00 2001 From: bretg Date: Mon, 19 Oct 2020 11:32:05 -0400 Subject: [PATCH 029/149] adding pbjs flag to concert adapter (#2430) --- dev-docs/bidders/concert.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/concert.md b/dev-docs/bidders/concert.md index e53bde4b96..889f3c10aa 100644 --- a/dev-docs/bidders/concert.md +++ b/dev-docs/bidders/concert.md @@ -3,6 +3,7 @@ layout: bidder title: Concert description: Prebid Concert Bidder Adaptor hide: true +pbjs: true biddercode: concert media_types: banner gdpr_supported: true From fa0c09db051ae9d0e9ac8dfd8695a5e84ccf6605 Mon Sep 17 00:00:00 2001 From: bretg Date: Mon, 19 Oct 2020 14:06:00 -0400 Subject: [PATCH 030/149] adding didomi note (#2431) --- dev-docs/cmp-best-practices.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dev-docs/cmp-best-practices.md b/dev-docs/cmp-best-practices.md index c6c6ba8bff..2285d78446 100644 --- a/dev-docs/cmp-best-practices.md +++ b/dev-docs/cmp-best-practices.md @@ -65,6 +65,10 @@ Community members are welcome to contribute more specific implementation approaches here. Please do not attempt to extoll the virtues of one CMP over another -- just help others with interface idiosyncacies. +### Didomi + +Please follow the guidelines in the [Didomi documentation](https://developers.didomi.io/cmp/web-sdk/third-parties/custom-integrations/no-tag-manager) to make sure that the CMP is loaded before the ad server and Prebid.js. + ### LiveRamp LiveRamp has verified that they create the tcfapi functions and set gdprApplies=false when their CMP is removed from a geo. From 4a240846d7ebedf8ad0e35a4c790cdd39841ad8a Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 20 Oct 2020 11:11:33 -0400 Subject: [PATCH 031/149] pbjs_version_notes feature (#2436) --- dev-docs/bidders/triplelift.md | 1 + download.md | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/dev-docs/bidders/triplelift.md b/dev-docs/bidders/triplelift.md index 308df7dfaf..ee1b7a2072 100644 --- a/dev-docs/bidders/triplelift.md +++ b/dev-docs/bidders/triplelift.md @@ -11,6 +11,7 @@ biddercode: triplelift userIds: criteo, identityLink, unifiedId pbjs: true pbs: true +pbjs_version_notes: avoid 4.3 - 4.12 --- ### Bid Params diff --git a/download.md b/download.md index c53055d9f4..030ddb1a4e 100644 --- a/download.md +++ b/download.md @@ -182,11 +182,8 @@ Prebid.js is open source software that is offered for free as a convenience. Whi

From ec0b4e2ac46f8bd8c9b5053089e357104307720b Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 21 Oct 2020 10:30:50 -0400 Subject: [PATCH 032/149] fixed userId page formatting (#2440) --- dev-docs/modules/userId.md | 1 - 1 file changed, 1 deletion(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index aee4fa53c2..bb6c224f42 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -58,7 +58,6 @@ of sub-objects. The table below has the options that are common across ID system {: .table .table-bordered .table-striped } | Param under userSync.userIds[] | Scope | Type | Description | Example | | --- | --- | --- | --- | --- | - | name | Required | String | May be: `"britepoolId"`, `"criteo"`, `"fabrickId"`, `"haloId"`, `"id5id"`, `identityLink`, `"idx"`, `"intentIqId"`, `"liveIntentId"`, `"lotamePanoramaId"`, `"merkleId"`, `"netId"`, `"parrableId"`, `"quantcastId"`, `"pubCommonId"`, `"pubProvidedId"`, `"sharedId"`, `"unifiedId"`, `"zeotapIdPlus"` | `"unifiedId"` | | params | Based on User ID sub-module | Object | | | | storage | Optional | Object | The publisher can specify some kind of local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. This is not needed when `value` is specified or the ID system is managing its own storage | | From 61c20ac07ba2b4bb46d228df766030c822dbbefa Mon Sep 17 00:00:00 2001 From: Bryan Szekely <49168870+bszekely1@users.noreply.github.com> Date: Wed, 21 Oct 2020 12:20:58 -0400 Subject: [PATCH 033/149] Floor min (#2438) * Prebid SDK 1.8: bid response callback and OMSDK * prebidSDK1_8: updated language * prebidSDK1_8: typos * Floors: added floor providers * FloorMin docs --- dev-docs/modules/floors.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/dev-docs/modules/floors.md b/dev-docs/modules/floors.md index 498ce08abf..8e7d52bc91 100644 --- a/dev-docs/modules/floors.md +++ b/dev-docs/modules/floors.md @@ -278,6 +278,7 @@ Schema 1 restricts floors providers or publishers to applying only one data grou {: .table .table-bordered .table-striped } | Param | Type | Description | Default | |---+---+---+---+---| +| floorMin | float | The mimimum CPM floor used by the Floors Module (as of 4.13). The Floors Module will take the greater of floorMin and the matched rule CPM when evaluating getFloor() and enforcing floors. | - | | floorProvider | string | Optional atribute (as of prebid version 4.1) used to signal to the Floor Provider's Analytics adapter their floors are being applied. They can opt to log only floors that are applied when they are the provider. If floorProvider is supplied in both the top level of the floors object and within the data object, the data object's configuration shall prevail.| - | | enforcement | object | Controls the enforcement behavior within the Floors Module.| - | | skipRate | integer | skipRate is a random function whose input value is any integer 0 through 100 to determine when to skip all floor logic, where 0 is always use floor data and 100 is always skip floor data. The use case is for publishers or floor providers to learn bid behavior when floors are applied or skipped. Analytics adapters will have access to model version (if defined) when skipped is true to signal the Floors Module is in floors mode. If skipRate is supplied in both the root level of the floors object and within the data object, the skipRate configuration within the data object shall prevail. | 0 | @@ -324,6 +325,7 @@ While some attributes are common in both schema versions, for completeness, all {: .table .table-bordered .table-striped } | Param | Type | Description | Default | |---+---+---+---+---| +| floorMin | float | The mimimum CPM floor used by the Floors Module (as of 4.13). The Floors Module will take the greater of floorMin and the matched rule CPM when evaluating getFloor() and enforcing floors. | - | | floorProvider | string | Optional atribute (as of prebid version 4.1) used to signal to the Floor Provider's Analytics adapter their floors are being applied. They can opt to log only floors that are applied when they are the provider. If floorProvider is supplied in both the top level of the floors object and within the data object, the data object's configuration shall prevail.| - | | enforcement | object | Controls the enforcement behavior within the Floors Module.| - | | skipRate | integer | skipRate is a random function whose input value is any integer 0 through 100 to determine when to skip all floor logic, where 0 is always use floor data and 100 is always skip floor data. The use case is for publishers or floor providers to learn bid behavior when floors are applied or skipped. Analytics adapters will have access to model version (if defined) when skipped is true to signal the Floors Module is in floors mode. If skipRate is supplied in both the root level of the floors object and within the data object, the skipRate configuration within the data object shall prevail. | 0 | @@ -1030,23 +1032,24 @@ The price floors module will do this by leveraging the already existing implemen {: .table .table-bordered .table-striped } | bidRequest.floorData. | Type | Description | example | |---+---+---+---+---| -| skipped | Boolean | Whether the skipRate resolved to be true or false| true | -| modelVersion | String | The name of the model| ‘floor-model-4.3’ | -| location | String | Where the Floors Module derived the rule set. Values are one of 'adUnit', 'setConfig', 'fetch' or 'noData'. If the Floors Module code is invoked and no floors object is able to be found (either by error or other condition) the floorsModule will set location to 'noData'. When on data is found, it is up to the analtyics adapter to decide what to log. All available values will be provided in teh bidRequest object. | ‘fetch’ | | fetchStatus | String | Provides details on the status of a fetch for a JSON floors file when fetches are attempted. Valid values are: 'success' (when fetch returns an http 200 status), 'timeout' (when fetch results not returned before either auction delay or prebid timeout) or 'error' (any http status other than 200 or other error condition). To determine if fetch succeeds but returns invalid floors data, refer to the location field to infer invalid data if 'fetch' is not resultant value. | ‘success’ | +| floorMin | float | The mimimum CPM floor used by the Floors Module (as of 4.13). The Floors Module will take the greater of floorMin and the matched rule CPM when evaluating getFloor() and enforcing floors. | 0.10 | +| floorProvider | string | Optional atribute (as of prebid version 4.1) used to signal to the Floor Provider's Analytics adapter their floors are being applied. They can opt to log only floors that are applied when they are the provider. If floorProvider is supplied in both the top level of the floors object and within the data object, the data object's configuration shall prevail.| "rubicon" | +| location | String | Where the Floors Module derived the rule set. Values are one of 'adUnit', 'setConfig', 'fetch' or 'noData'. If the Floors Module code is invoked and no floors object is able to be found (either by error or other condition) the floorsModule will set location to 'noData'. When on data is found, it is up to the analtyics adapter to decide what to log. All available values will be provided in teh bidRequest object. | ‘fetch’ | +| modelVersion | String | The name of the model| ‘floor-model-4.3’ | | skipRate | integer | skipRate will be populated when a skip rate is configured in the Prebid Floors Module, even if the skipRate is evaluated to false. Skip Rate is used to determine when to skip all floors logic. | 15 | +| skipped | Boolean | Whether the skipRate resolved to be true or false| true | **bidResponse**: When a bid response is being processed it is important for analytics adapters to know the decision which was made and the context of the rule selection. Here is the data which is attached to each bidResponse: {: .table .table-bordered .table-striped } | bidResponse.floorData. | Type | Description | example | |---+---+---+---+---| -| floorValue | number | The value of the floor chosen | 2.33 | -| modelVersion | String | The name of the model| ‘floor-model-4.3’ | -| floorRule | String | The matching rule for the given bidResponse | ‘div-1\|300x250\|\*’ | -| floorCurrency | string | Currency of the matched floor | ‘USD’ | | cpmAfterAdjustments | number | The bidder response CPM after any applicable adjustments (currency and / or bidCpmAdjustments) | 2.20 | | enforcements | object | The input floor enforcements object. Keys are enforceJS, enforcePBS, floorDeald, bidAdjustment | { enforceJS: true, enforcePBS: false, floorDeals: false, bidAdjustment: true } | +| floorCurrency | string | Currency of the matched floor | ‘USD’ | +| floorRule | String | The matching rule for the given bidResponse | ‘div-1\|300x250\|\*’ | +| floorRuleValue | number | The value of the floor chosen | 2.33 | | matchedFields | object | Fields of the prebid auction used to match against the floorData.schema.fields. | { mediaType: ‘banner’, Size: ‘300x250, Domain: ‘www.prebid.org’, gptSlot: ‘/12345/prebid/sports’ } | ### Prebid Server Interface @@ -1151,5 +1154,9 @@ If the currency function is unable to derive the correct cpm in any of the scena {: .table } | Partners| Contact | +<<<<<<< HEAD +| | Contact Magnite (Formerly Rubicon Project) support at [globalsupport@mangite.com](mailto:globalsupport@magnite.com) to use Magnite as a floor provider. | +======= | | Contact Magnite (Formerly Rubicon Project) support at [globalsupport@mangite.com](mailto:globalsupport@magnite.com) to use Magnite as a floor provider. | -| pubx.ai | Reach out to PubX at [hello@pubx.ai](mailto:hello@pubx.ai) to learn more about our AI-powered dynamic floor optimization. | \ No newline at end of file +| pubx.ai | Reach out to PubX at [hello@pubx.ai](mailto:hello@pubx.ai) to learn more about our AI-powered dynamic floor optimization. | +>>>>>>> 4a240846d7ebedf8ad0e35a4c790cdd39841ad8a From 38d55838b597ecb10f3fa6960faaf48215fb634d Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 21 Oct 2020 16:37:28 -0400 Subject: [PATCH 034/149] fixed conflict in floors doc (#2442) --- dev-docs/modules/floors.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dev-docs/modules/floors.md b/dev-docs/modules/floors.md index 8e7d52bc91..44db14da5c 100644 --- a/dev-docs/modules/floors.md +++ b/dev-docs/modules/floors.md @@ -1154,9 +1154,5 @@ If the currency function is unable to derive the correct cpm in any of the scena {: .table } | Partners| Contact | -<<<<<<< HEAD -| | Contact Magnite (Formerly Rubicon Project) support at [globalsupport@mangite.com](mailto:globalsupport@magnite.com) to use Magnite as a floor provider. | -======= | | Contact Magnite (Formerly Rubicon Project) support at [globalsupport@mangite.com](mailto:globalsupport@magnite.com) to use Magnite as a floor provider. | | pubx.ai | Reach out to PubX at [hello@pubx.ai](mailto:hello@pubx.ai) to learn more about our AI-powered dynamic floor optimization. | ->>>>>>> 4a240846d7ebedf8ad0e35a4c790cdd39841ad8a From 61939e450aadc2037364bc4d47ef5526788ef611 Mon Sep 17 00:00:00 2001 From: Bryan Szekely <49168870+bszekely1@users.noreply.github.com> Date: Wed, 21 Oct 2020 16:52:03 -0400 Subject: [PATCH 035/149] Floor min (#2443) * Prebid SDK 1.8: bid response callback and OMSDK * prebidSDK1_8: updated language * prebidSDK1_8: typos * Floors: added floor providers * FloorMin docs * floorMin: merge conflict correction From 9a625dbff1fe92f0090b3a5ffa980b76eee93b3b Mon Sep 17 00:00:00 2001 From: omerBrowsi <54346241+omerBrowsi@users.noreply.github.com> Date: Thu, 22 Oct 2020 00:25:41 +0300 Subject: [PATCH 036/149] How to create new RTD submodule (#2268) * auction delay and timeout * RTD docs * testing ability to make commits * review revisions * changing getData to addTargeting * revised for phase 3 * removing auctionId param from callback * added display name to browsi Co-authored-by: bretg --- _data/sidebar.yml | 8 + assets/images/prebid-rtd-architecture.jpg | Bin 0 -> 83217 bytes dev-docs/add-rtd-submodule.md | 280 ++++++++++++++++++++++ dev-docs/modules/browsiRtdProvider.md | 9 +- dev-docs/modules/index.md | 23 +- download.md | 4 +- 6 files changed, 318 insertions(+), 6 deletions(-) create mode 100644 assets/images/prebid-rtd-architecture.jpg create mode 100644 dev-docs/add-rtd-submodule.md diff --git a/_data/sidebar.yml b/_data/sidebar.yml index 3e6518302b..4e7b4bf487 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -350,6 +350,14 @@ sectionTitle: subgroup: 4 +- sbSecId: 1 + title: How to Add A Real Time Data submodule + link: /dev-docs/add-rtd-submodule.html + isHeader: 0 + isSectionHeader: 0 + sectionTitle: + subgroup: 4 + - sbSecId: 1 title: Prebid Modules link: diff --git a/assets/images/prebid-rtd-architecture.jpg b/assets/images/prebid-rtd-architecture.jpg new file mode 100644 index 0000000000000000000000000000000000000000..18340beeacaaaf8a7e89585bf63bd5ebb9f08229 GIT binary patch literal 83217 zcmeFZ2UJs8*Ef!XT~QH&(v_;A4NAa(ppFy)0Rt&O2q;A$p-7h|qcfre0Ra;P1eBIW zf&@Y@HcCK1N;Jr)*Y=&;zh1j{?%c6+&+ff@_w3%Y zXYc-l`}giUuy4;EK7PIf2M-#Tb zu+*xFepO_YfO`#ac5m|fPlaV}j2}^w2gHMtkQUqlM|zg8Vy2Z#taNP5$d%3(Yci31 zpZqxW_>Hr#&vYlb7gHByYppy>Y_oEzEJsNraecK&SxgW+d(Tq`$AA;d6{)NMIkHw< zyxjQNRf)E8+p7scw>0I-K38QQ>uDCgHqgVU`w3d;f|%=m_i*QGX_QeE!NKB*OUmw{ zg}c!nO1?RQY;qzxU%zx=49_7|NDl6UK|6&7hGQSC>viXtxP4Y}ZF^T?6I)LtCNETV zE}6E~3gg~`w;u_1$c{^F)$gcTx*ip%bJ9LmRK^^1t5BQj?PKaX`IC6w6l_VNp+%V5 zy#K8Syi8r=*0bW$>L^5SRz|9e5?8{XdZZ@M85xAamKOEEXDb77&aF(9iEd6ti zcLD^nWJzv{wr2KH8T^_8glh>0>XpGLXrj9C6X=xD zL^406`jlS*q7=`ucT}&Y+OsmwrY4QZmXIY!Z z7fu;ArPIhjYk%K7njJyy^XW8YLsnyblpb_>=oYJ}=a*yoElAMyP`UQ#56>MMa%Zh+ z`-|FjXpJ|+`{pRIm1Z(#R<4PrIo_Ej-ue~5IRj5beNG#?CydnThkrpRf>`M~RLwK%<+5eh2v2z4*acfh>^@t+b0lkF=hP0bVcg6%d#1GEk@Rwyxe-n;0ol zgM#p{Hcw|bA*t|3dF_1!nl+FN8_)7P3w;M}$?+mwc4697jQz!=_}3osK3Qt7jhCwa zd=%|U^Lf{1CwcZ$wk#s9JKMX}w8p^eX}S+ONREdNf56Z1_nkl8EpHhYhWU1B}I`MW<)Uld78&N4A31!xPDz2R+GVB(I<>< zM~Gv&I(g1wVGvQmM`VV&0NGfH<=LH&U8AtE?XD1WxT2xK?(p2RLJ6{XwoOO{pH;y93VW&peq`Y$(n+K^DL0 zNhBopLg=LD?em%^`eMu+Qag(B3jh@PJg%Zhb7Ds?Ma9=&`g2}Q#XRN!Sez2!@)l=H+aVP zXLp!+FgRZQvRPTrD&Z{_HPu8$18^ohNe8_wHWUCFndE)C4LGNfcT3Sfcc?h`mxC9B zj||kJ*OAzz9|2d4D)=VsBE>1o9t!VYzw4`B%ImJe4^-~o0X>|%g>Xy#ZLsZ>Eri;? z)qerI@HaQqb}w?+B#hnKm@tS7+)>~A$Vo`A1oqNw|NM_v>@Y-bue56hRxr%L>@bk7 zo=yhNEIfMtcT1f|VEwpv@)Y0GLR(BEA`mbx`FdKz*w4(7skN7QA}j8srbM(usclWJ zyc8qQ8wy?6cK&}(K!0yfh>e$h=3`KOD?{^gY@idQDNCA)Uqwqb0#n_)J-*G{P|ZD- zS^%oA_TdNcH`>}P14EtlzEj?^Hfn1rsP(JPVWqUYP~45S1;2ph+bQc~rQ2ZNykZ;h z17TupdX`sfjpYl>q=cvCQ>xzXpI(H$Bmevj<=^l_*2Z#;ts&p=<=z+HAt=tvVbQWD zO=U*%bKC9Tb2U&ql~-OJ)XYJj3=PdRb)La`%44}AP4`ny$zLzOL$G=?9PyNr2Wg+s)Gw2M z`mFRyT{rsPt8OEfZe~(Cye22hv7Y$As#nr{RUm0~e|Sc(W#s^4P$T3P{-eQ8aA>#+Jn$qKdcE~i1Jh~5oK-gD2*_CZ~%e$oF2i6((<6j3l_$D5YPG>Z%tbszCD@AL-$C{3RA$p@hsZO?cs_ei8F#0lo)se4gWhd}v1*1y0VJ z>-c4qRLrQLYxUc)mTYGbKP^bbNGr*Qdw%_$m)+~hrq_W?l0Qgeu0aqw+up1MfEp@V z)a6+;T<&-iO>v~l>w4an!Spgk$mILC$Tx}a<{q!@G=@AWDJatHPId=rT2tU9tVfdu zjh72t4?a3|JrB|#kYO;Ft7B7<$xw4X)Nxt*Xpx;O=*f{#NBk~_E3MG>O40H{ZmeS{ zbSfLem5viiKXsII%0Rvip_N5U-nsAT?2>;PX`iRx(iDSJTSGTcoFUGFxq=aegEnDJWw5kp)6eo-_tb@%YZ z>Pbma%c&M>5Cx!#V#4_C)t<;qphIkj9R0>cC&?3ncp?kvJnEL`h|>VUHh2t@G@hqK znHn}z0buDsu;1lVF=tS1G(ROJ?aC3Cm;R;}aWDiG5TbF(b?jPMi6p$smBTANiAfZd zjSf7U{IFvsED7J_+kSlEsT{xb+@8X--GM+C+WwNZwrW{fXx*C`zwA&gVcrs0)=yGW zf#;k%<^xr2cg?Q47ZUcBLc9At@~!B`e$k7NBs3?`JnN$<$;dsPK>CC*l63AGFl9d?mLxdNeh&vF?YAu<@h>ED%jsT^k z$j_)YH*?gd(acw6x9yHcs zBljt_Eukvo(j*9tpBnDsSNX(Pvxb;dTEyh|ZPuQ>hVK^q?{{fQxO?aI?rTMZG^_5H zdD!jj&A0N)@<7}yK)D43LlZ=jtVMP^lcLdvQY3fje)#Ar$PoAG4Sm*A`H{nwy?o=0x0Y+co3DNhnO|xj53Ji3Zonkg4+iHxte)X zXR2aC!`bn`YA-kcE`)^))w`5s8q1XVk`eF|xQ>R_pd_3lWvjT|s7OTJ=t-H^SOEqh z8q#_OLo0>HfpMZ`LENNz|C&gx77>!nr7GhzW5AaeRpY2}^1{6PD^4ywvxIGZl|ZIu z$6>SaE>bCWofU6W)xrF0$t+4kce{an9t05zjtLK*!sHc2zv;G;B{O$yUupu|XOrkz z7?ONyYVf0cRT&C_5Il&6>W-uv)T`lQ=fQ8iQ_k@4Z2xwZiK8jr8W)WpTEDoi=}rD- zF8ukAtqU!{9QN9*i`758GhmfGx&!)6t?l0|v~e_%TTQeLo*z$F^&)=y-p0Op;a~pP zy3*pzVbw9c4&EVEbz!xp{})@|thE1>3`S7Kg*hVZm$%-W`eN*K!TXmpZ-K0npu&r& z?GK@Y8heuh9f;ZKal)2M*CR%UwVBLO-zz`B#+7JQ2i$GBGr0#O=-uO=hFMc-z)u5Y z9$ZiZCiitRqBMl^`d&_9=@&2~m{4DShWxXv?Qeu1w$ukc-M!`sNW%A8Trjv%G(onG z%=)SIO0_z*{^$y+^`x9-I-0Xw!4*7JNA(1aMoq0GkyHD(yxGI703|T{L;eDFiF_M4 zkMFR%r=IJ(jJS8u%H40t2fb*9yXghvF{*H4bbM%}^yN@5ecjtPopcezs z9Q=gXj+P>m(~leflb^apCfdJ=sv5d&t4t*_pTNv(pv|@U7EMNTuxs4%$TYF53txZ?)*r@mxeFVXL!G>k?-v|G1eR9$?DmZ z9rRB*NWN}HQO++1%eyDr`>-=NSA$5SSg9NYiK^?+lAH5Y)`I_33wt{XfXI z0ejM1O67-lI8P!!!_Ejq($0RKJYJb+Bkwr&Zy-HVu-xS> z{_+No;Iq2tWaAyOZl^BzQA!Y9gM|&^#<4UiU;|m$1=0- z&c8F@GtNLaig_zOa99qNV~nvWu}6}m<_PC<<3bG{|07&(6Rh>mUTd;1?fpc(kULCo zaXdl+sC8UkFN`CHaXWz6BlSxT`ETo1`i(|1%n>t~_@vokYbJv4oHHWqv2gzs<>|pQ zON2!Ya#=(1(xKTHY?x0FrMxWW_Sae6q;qnuaf~)IrL+C)$APq-KJv8k$M<@hLwyV3 zmiqiK9`6IQADZ2#Csu7H6x)o@ELul^UT(O$TjU-3ha-8D*=Z^FI3kzpG6&1s;x6^s zWWtQio`hJeCbLjOJt4clYCo^fW>cQ9fCR5k$44Xu*N5j3fdP^~0H5wbY#|J+tv**$ z0qaB6zQ7WHfNdd^_^rManWwd2A=IzS@+Zflo}f6U_npsyboiB48*$Wj9}dk=?XV`e zcfWFMj32N9U~fMYBt>}MYq&)?&;EWjg-&+RoU@~xR!Uq`SxHN>T&r0fL{&Kq*&3V3 z^d`8rPDRt236!j!lG(xX5>YGQ7K?G)pMEB8i#+aa5z}|eGtx;6JXxL}5n_kkhkwMX z^!g}NLKME7EcKxiT3_C}H}Twzq+9GM!=y+iEbvWv8{JcDMABM_4^IxEl-rXMk1A z)8%DH>JH#l19}L;)vdR^ZNfRO>l73p{ayn)Gyw2Ay4l^%Kjqd=eON=jUPDkG_jXjP0K{9rW}%2 zpEdO$*eF9gua6bKw;~(@&(kNb<J$hjq!b`?2X*3oYFWv-?-0d9kK$%t^eB<+_`C%hvg5BFR( zX6DyP%aP#gKCu>_eF2Iy2?~9QxH6}qcEQJdcV0u>7)VMQK>VCrm!y^X!fEa$l3+*+ zc*av+D~_E0)Q=iE){G`T%`8O`M@LHAmjT=T1n3&9c7M+VdW0B}el8!2m@7(}t6B6O zWI-2A0S$`=nbcn60M@duRVckWl@l*vgvJq{;z>6e=AzxTk}8xjSzHV*l4;W+uj6iO zEl1_7!nwaX9s%{U#{!)?JWCuIx%D34?S;V&W3HCn*vIC*`xK4ZLye4>AleU`zRSR%Rzf>EER_79xef|0?3h*Kk>iv z(4D-UGmDhfHwY|lYq1?uaw~rQSaXBN^g&#B%G7#tpuU0HXHaViq}2z160YwTx-;E7 zRUBt{cQhxcE3h{aE{;IA;uY2l3L*WD_g01$(lrT}Yu->ccphu#)3HJ=TBN9G_>6Pg zm`kX}_FeZ}e6-f<9N&Vz8C1JsvLrM`C9Gen+F0*?q+xN-_Pe4xFxp*8Ri#&*y zN3N7q$#e(rOpxL%H0*4v7zFPxRGeOMa0^tMN@d9^`c&dY8pQHI?5<;Q`WYapk94Kt zfGw>>@ZeK~R%3dD_}QXlsyHu@Y@dFcb-GXnpN^2Wk01}35-K)VcZ+T^@jf>AUUO7` z`DZ0Ua9O*hhFYJ4wIf@=B#?pdyWpOLX?%$RK8pnxg3aaL#KeLrLK3D6HN=$TubgIr zSqYj>8QR6e#U^D+NihejY?PIYO%UfF`O*?a;X^PIRJ?H zcG45SQ&oI7*$-Ro57@Vg=?vh?*Y{le{I*E40qO03&Th!irNqpYy1`>OF+u(SHI!a) zNwL9MaOKr=7hq?*`a=JeDgA;q{$Qrz8Wf}~zzT)c`$EY40m@#P}-%i9j^6*NARU$tp zD|uY-pUIUjdNmgD1s{hd1&KWANIz=Lm9bmGh|ugNu)$-*`{b(5gQK7cXPq}QTq|Sy zQbn96qoogJ05MSlL7{%eQWi`_0T5k}{rqx@3dSZ0#aA-yl@=$@DZ zX_Pg(EAfeMKWqj;SV-GrQ-uf?eTyZKqwV^$Fqp2cDP~@xaGM^ z`hNXsOp*CQPGk`&HQI8(*#^70L7v*&Ag9agpoyvPv{y_jvdJEY%->D!KV?0R^X`5h zt_p@lSHF@QUVYEeWF&zhlCWX~AeeyYgl-bgCbG0Djf9C|*U z^+x=H_N-Wu-i<`Gt4xT02Zx)qY~3#xl4o`!_6W7EgAr_%ngV)Nqm<@wbP75#^%CNa zq@8E5xyn%gdQ7#GW=orXevg$KEYoV`V=({Q!4U&7qd5bg^Gf$VJb%TMJT2wm7@vTQ zC1R)S5TNxhF`c|KY}Key2ME<{B7(_#wC-`|M+eIqf*gayGL5y8-@P*Zk?^ z`X?Uz1%z}1_;mAyXM|VAXeO_NiPfMQPfT~ddzbRUM0$FIZ3D)u-ACL!!jfv_DT|kD zJp76_7D5ND0aKLaI^KM)`&%$2>XaRrUep)R1825 zx4#*A2@>1O!lW@BFdrYR{L1q|w2AJQd#)pDi#p}pkm>l1L#+Z2cNGwW~l6^kDr55Sy z{tT_;oBtXD5-``-eh?L`=G*dicr#RDZ9k89kiFIc$uBze5CoHsNxcZUR*^-HMxLEZ zkb5bsJC#9jl4^#Wb*V!MNJq_7!fPI2mbJy&UpHqft1VaCva(;RjN|kDRb8h}0?Zr4 z@4yWNdy_&9^@mIKywm;BQy#G4`=l^Q*3RVYl=EfSZdOr7dTe8CqXSHYSnEA;W3vnX91Ht56#F}R{qVPF-8ai6&+oib ze+~$KZ)@Md(0`B|{syr$D$ZNY@i0qRKDfkv@q4bec;3Fn1HYFm0pp_mPt^OT7)6}v zgGua<-o@>P2rDZ@#5)u1%QIk<4E@q5ZWBWy4|$U}FVa^G$)ebD$(3c7;okpBdrSGN z5d@tQ(h>1PjB)}##cV0#Hce}m*4>!!6xfP-?-%JUWm)L9hE<1fQ&IP>;l~+8pO&ev zu2YHCFj?O#1HSv6pnIbFvM*(!^_UZe*RZ;n5`v9e0J|NUwL-X&_o;v@ z=?8}o1lX;pqOjfbzm@lVMf$d|``xVXloxvQ*+!(=IP#ihBSn(l;2DEq`HCa?B*X>V48a!2iC4eBqra0bogN{_I=(b#{hHE#D*{_EFycu?}1=HOEE#CMV-|-vJxfK)s z8sG89nDDmKeP@kEgKc{|EZ4?etdukqd9_IiQkf<7V<%nGZz%+hCS*IJ8$|KxI}0zZ zB#oGeLSRk0w)bA;iv?U8fIk@Fr^eBlp&8MY{T8xn1>@RhqsF35o8X&!SrEj6L}~;a z8M7F%6Dc*Y^a7Xp6*3tgSJk8A_TrH~o*O()flzO#^#Ba7QCr_Tnb0L8wnkacF<$R% zpVU;A@(V4D-se|!xLdHjAW!}1@knzgMMnsOUxdw2>WSswymT_pD_s3Egnlpa&k*__ z$a@f50QW5j|Ig%K>|V^ib#`+2(P`-}%x0l$49Mk2PtFUTuGI$VK4S43nwi%PM@%FM zTT+8X$~&`Pd}mL8KN+t8-br0i6i_}~ViFK*<+U2B*ZR?-OULvTes`}7-B(p?(Kj#J z)-g+KjzM#_%+@GpZ>j4`==U`Ui44^DcxZqLn}E8uu_f(A&y3;=fZ~$ zy)@bGjxbb=)9j0K5NSs!;2`|`FyrqO;SXE=UYiEq76|osTdu!aN%#JLVR-)67ykKL zTK}DV{e=_+LT{H8+G>?6_)V2P%QvwLWh(mb9dtQd)=K3;IW_GLG3^VO^b19-yhDv2roZoBGfStpgXq%9OiNNd$RYG+ zdkr?Tt2BRG?bOXleB8KS4lNwJc!Q9~?%__x2CC)8La)G}Lk|~V8xyc;9H@PX z{H0HVp6sWTI{hnbnGck*u&b@LpQe^WdFo3y>16qzW}r(<6zLh+WYD`tuW0pZ0CE)XDd+pvLF7SDZDVCxTtf^AC}f`t%4Ze z0l&5;mm!$cmyqdX59z2KGB>AcIT}c3Mc-{rpIb;dbZM9j5_|d+X^GGWrC)qtnAiOE=rWAi+5eH@Ja% zur~cw+-q-gxC?QztupC(GfZl1VDhWZhp2G7d+hHC;oCwSlokzh zAvVvL9uQOt>NFt!?dmV`Mubv*U|z2|P$3A}5O00|kdkrr&f5IZoT=G|7M!UgZlX5O z>z|FS5Fmu7ooxL|vs?&y&gz&w@~H#Zw=4?=p5f}wqKY3k|7g>u@Ott9vAAbODGFtL z5n^?{wEulRhoriyr<;Qf@9Thqh0vK?2iOC2gF;W0wdPB|_f_Gm)%X}u(hKslf|hRC z=UD*R^&w-yg~djhbu&%9D}B9DNv@9ehODlVu^g_g4IP&xt>;#D%2BA)RsPPR&*g0V z>eV_jcO(@0$jf}$1mvXH7%VKSrm9bk;)-_np|NE0v!e--Yo!t4y`Gxuzw9qSojjT5 zO|ElG@Fk??uSDs|>S;VuSKr_X3jG-Lij=rWJnjoh^0xPVPq)W{^{ z6cR~+bTx7IqPUyt+Xqzr2F2VF%}ZpiWFvwUI1#L2jF~KxO(%e!mgwY5#s#{=3OOuy zIyquiRaiPBDbBJFJ1lRs8rDrSBh_QYW?et3I6xid)fPj5)y6nmrMX8-DT-!EMnS8u z?5@+{c`%#k(6fGfjITs{8Z7|!GzJnN9n9u9KOk^}=aykzWb^Cmnrrbno{#*;K|&{q zLYc?5*4f%Xi=c0?*qlX~nMTWc?=(b{Of%2hQaJZ&#K zX?@)3`irKsNp$WLIA<(tB)$i?=KHxDeYD98A?1zh>ApY2g~79UxAucNh$bzQrtN)c4)0 zh8iE9v9;qQZSYJHMz)NK|LxWPU-atVI>o<HhsYvoj2p)!$`HxHIbWzP(!L1w4*r*zJpPCcrgBINg=N{$uXvAkE#EWU0G z-T7fX`J6Ec4bUbbVDoPfPu!!$g;v|kM-XkjdqYvs&M z+Kn3nHuBFnP5Few`BqZA{d^}v|=Jh@_~7UJpKW^gNc1*O&?d)Zri?NOwx z?%tZV%utMIoNjQ!s7R&Zn~p=B;yVCUvelnN@fRLh=Oj=B+#9R_;y}3VuR zv$y(?XqOg0amX=^>+LLW6MrwtSlJ7bH?Hd35S)`_#2g51q8W$bn3oG$+Y2LF15cTb zijCqOBP6Ka>A9`8Hzxw_hRQy;(%|u|R@v`LrLn`u^{j_Bm=qK7QYypu%6aZc@Y6fM zaCO~qkQh z7v>fVp2qZxp~<5wA8#G#sJ=d!{SGHQRh2iu@ZD5h+w%LT-wlFT^B^1!^pL6IEI1Ww zSAXVlEoI0z8rKZ>v1iy+pybjz%!ia4C8KA{OE-8VOc^?ebA`hV_8if326hJYD7bPo zN^*W~eobm$;Tehi>m;*?fg7C@#hY96i6BdM_Govf>q)2JSlR?RneTPHM8pvsV|@Sp zT)i+g^iD|m#mS(vw9?tY!Vk~i!`JYQ{-cj^=U7fwS=il}!={zYiqmEyIw1R5d+jxo zq1MtJ8e+jawUkje3g$;72g{$MxT6%2!UDQR8+O5ktze_bX8Q!qGK8wo_VmgWU ziA0Li>zh|zxC>Wr@LU`6ZL{_0P^1^hW!~-3Z03GqDnMc{t?Wo(+FhyfL0`^OXaRs# zT1;)TocBIa9$+tjtU!{vM5}9*JnaObf~`d$tF!h0lO&@o* zF9Zu8IdoQ^=B$*@UpqfNho;8ploU~4DhOrex(ke%SHc|cS34ZmU|d5>XF^TQ9#AK2 zMbxI)Wj&r&j5|XXpn-6O&?X>qJ`|uGa)rX)k-9f9Q7kvYF{oC$n`Tc|fB~q`CUaM+ zkM5Y^@#pp26W&LhZZMTXFUPEt#{w)$vzmOdxv+?7G^3|$a-@wl$(ua=#MVRfy6{z| zd`(`k4P=AIhEQb-oGb!TPIVxa^WSOiNW$5!I&MNsafR7gbp1EBxG{K%=_{;$qkybK z(r^WF5T2_BwOfL&FqNk7ii_Whcr<^ru_-kL>5V1tRlM`jP&@=M@6BShu?kOi<9^gh z4@~PaZhtc=#!d&pDCHlPOyneyad2}4^lhSe{|e<ON`HdM^?x-iGeEV%7M~bNGjnN_4$?3MW?K)J{P+d3paY>jXRnvkNcUy zAjgBTa9vZcBC_s6p5RDXbl{z=4IZ&PyPKH}lil`~Ghk|oO`_T()7+9a>JJz76QV0y zX-B)1Faxllg(ipY3i3}Ws5;^%>iVR`>@}A=7?o$Z-NOL@pu*ELU^+CzwUV%_Izcwx z)ZUw{z?!!W>UfMZ6SSUQO|J)v07tI8lx@|wk&Q#wUndy%N}o)3dsw0gE*Yf`N5O}u zKvvfaI!h{MQE)ruBa!&NIvBnSGfa#wbpd^u_x&W}iI6YM$k)|1BcDLd>%TFbI}0fA zUEB*E1$NTzWXoSvfYh_#U;uz00j_d3aF^9-z3_q>`HL}TT7yavUH8hisD!E#Plo_Mc1h14# zN2h{uI*0K{JSwo_PFx=W9-&fn!q#AtN_Sv-DP_&3fhekd@bTWEKJGsyW&6 zrZD(g-t{GrKMWDu{7~^Q%TYY4;^YZYd6~hQ^D7b3goS0@sGtfNZ=fc|sawmwI`>Bm zpz2zyy(wcX$DFV`JYOk?5$N~ICDSk~y4U1_c~R{G6)WFLiO(YTndl`Hn2~1m1c~i< z^$L+eZ$Eh*qcn5E+UpPD26RIyhqS}wye2e|0R#K!t@ph+{zco|u_J_ozAmiq6IN21 ztelgFoIDLLac7TNrf0`L`f+BV!ZCO~xr7XY5Ti^(rmk)t7V%9s$A52H*0uq1RyHj= z30s&7#0K5(6?|9!CRoNHK0awUHxB}V0gjBz_E<`3+zqW^r%TCI)j{~rZSbJL@c%mp zh>lqwMq{>}zeWe6jiN>N?g=RQbJ+~D+lCdCLW9964s8T*7RvH@rEK-Ub zx;P( zV*zB^gt>wIip${i&2;Q;&VK$=XF8uGu|fQs&Tszxa64@G=?B+G?)P_{o-7J-JwXxP zPZ1crqsxs=abIAFv3wA5=`-FlP+qeS^p6jFmjc*FZ0N4Cg=R{eId%uXn@f7;c;(fb=rf(|7|V9kOZOutbamHjAO1^WE!*vm-_vO- zs?odCwRiw>x9f9{{!4$XC;*U-fVOwQQ3HvsrIpyMo>=@6Ke5_gUV}V4{N&ENJ&0!& zk)ItHVM^5@M}tH=tAw-=Gd+lxKa=mkMm_DnSWenCc-ifg2wzaCj%Ix+0(`pq6@CAW z@ZOgCUwsz85nkI;{|E9n;KQyhmEL@`0XrQHEyb9Et0h>OnZ#m5uS`r`UW6u@g3h9l z;*%#fH``}tsuFbY^WJD_2>%c4|1qxr)`oWdhUGtlNj>g3V5KkVk<=FLWx#Mf2~-9w z8cNS7+MANe-6Zsw@Z*2^3I2t` z?}9~=)?dA%A{BU;evJ$1w0#~hXDS_Td}*QZ=6llJPj#a`!zIKy3=0CInTC|4ubp?> z^r8OaWB7keuz%XnH=ze7@i&GZIiI19?5)3<(ak8dxzi896t@KmsY-eppY@2gT;mOC30EIk-oHRU#eb*)eSm9aSmxgq4zd(68JWA5@LUsV*JOi z`8GR478yTzMEA>!oHfd=e~aJw<4XT+clW@-i-gWFl~4UMU}4zSkGuL^ff`0d^4-c2 z%eSpo;a^~e@WEBRmUBNUoJ03xztf5JPkz}?jH#{xW2dV}*)@5t+L#?h!2A~5(E&;q zU^4X#@S0;wp?+b_a7Ih6F4O=Fo*ksjC-2%4jQ@4Q{+67uHM!xd<9G|BSH zFTwcBQ)$z7zoFm!6zjauS*Omfo$W;~REW@pcn)=;;Q^OU6U)R#wdI&@@GS1q$uhc& zNl0Vl={~9a`N;eKg}Y;J|ISn3Zk?t%_l)vm@7Jsq=ak~L(yv)7?t_&u6S1#ZD}9xz zZJSvu<;y;UPnNg+yEZfEFVN82;L&Kzqxw*Oq(l|%E4S#9rBw{G{JEPMd0l$8BkH@| z{gg2LjJNi{dNR3IMP^~!)&D6EMZ;N?*GP;j-#qq%mONrmaQ14V$lyXZB~%x7s9%X8 zv@b=_8)Vm&qhds^sTtnP4Z5fh+XTg+IMyp`4~Ncx?#b1EhShi;L52WucxPCkF?HtB z8}AofP2u(hA8tU4?$~Dj*L<$3r;gY{-+D8n=~bgzHr0AEz}I@o;d))Mf---wM7Qg5 zXJ}sLTdb*ZBUmPCs9q0Ru>4zY)BoV~{{`B<+>ym+6+Y3-4Qo3)Sv%R$FEzR9DLX@U z8J;LJ#m{fLVzp69BMoUXBX!*`{z)DB7u9e#QWh=S!c;y_e}1=_W&A3j*TLjVRc%%6 z`9E3}eo%!}+tTwU%OkH02MAdy!-H`&j)6kr+0QJ^($tg3eRCaADN>qN!9t3;y1_~1 z327~t*N*T9*?xEe8!vU6N?7R?oL8e48U=pLvc~!=;shrsK8I5c(;aNMQjXXKX)zkw zH}_cP57JiEO@w0mqWzJ!z45ZdBB-_H*vaF>qEfW=>aS2Y%H6hCDdoGlHY7!trJfwF zfxM1uN`)6FQ&DKygV9xlF&2MC@9Mbdo|7{vpUItJL>-G5m$^ZSrPsf){1~8K(Flc} zC;q}Nw3%F_xXTW-A^Dv6LipR;pg+xp_~|M>KWe+w8hD(LT4URb_uunK>*xm+f%>h<;icw!T<=sf@L z0hD?HriRafh0!}m&wCc%THD0+2bHny9G+%Vh_UTDmttFf>c&?Jm2jcUHZ=RP^pxJS z6`Rq`yuYF~rVk5y?1~#HbdUF_ZQIkZvvZW+j1n7l;G7+qu!#WmeX1e@h_+T(EbrF`wH`k?Cp zW@dJB6>CaYs(8Z_tA$o-Rf|#auq%zeZ;8rF*`iHaA>;{i($phg3}oZYXlBLM z9=x8zb+DWYbrDZLu&dOq^0-G3JZU+8N`rOU0kgk!yc1&OdQ#k#`1B6=YFsK@gKD#s zx?sqr%q5W3V&bGcgi`X0Rox@8-JZ!iOY`?)Pv@Uk$P?{rTUpqxr{LJ9KvTyi?*u z|5u#xoIGYqzZWH?qRkkn2tme0GTiE8bB%GXPH^d&VvC$ySI`B>(I zRt&{fFV0a7QL6A@svIWUq!53N5UTltt-F-w8*6vk*}Lu`L(`%l%nbQ6c%Sr#U%cEK zc!`DX>cWoX!jD4bI(P93EXP<@YpwsY94g7@OOkvWxaFO0r-Qw=vL6mr{N7Ivf?!##7+tT#~kib@s9SvA~8YWp7^nmy5>Kabv%Er zuKxY>0i0`90cvvghnNNGujDwY#zJI8-px69XD7)^GO^&qU1>gQVUtn6))G# z1g$txu>EHrxIK85O)yZEBU`44Mf>!`zUh*Jxnb9T-TPGbB*EXfjqIVY5Nuo7A){W7 z%G*>5Urvl)d=jz2Q-%whA}nq>RBH#6onPTfD~zIxDl=cY37hOt<67{626_RGkoxpx2eKWnz$83U}W=jwF0xxQ+6w6%3B7#pkG8^ivM0P(M!kM5d>i zd>cb9@v!Xh8$&y$PTcJJP^W}I+DE#*aENr8DB8j=#-1^dk^-LmrD!xo-nG)&JJ>e;wX5<1 z(1oky_s)`=s4b|Pp6PaXw8<+2ViToL_RYWv!~q|h{flRxN#L3|k}T)b3v#O`)4hjU??=?_`wML9PtEPW8wC638geNMw_8Ix z4_J8w_%(#IzCF(1&@_zDC(z}1V{tOWAqZmeQlP}d>YVIEOE2&~x%@v3)PGC`Z)zXc zBBkmax8)%@ddV<;EF_5`+{x*i9~+Mq%c~jj9(9b9w#|uZGN=$4LWB8D>i$SyZDQ}g z?F=^EOutT-)+8^7#e_xw{BJ?2+kkChE@hnI9g>sCJuq2o&&eafAulr4DAzWZq?_(& z<6j*S@&wJK-d~awXH+`m9UgYH88mP342AE0oVH*Ou-_UV`}+e}2;usfnw7M0HSV3> z#9{c@b$OP!wvM4!_|dlY#%OiWxruh*n{N(}x&7zt{x0p~k3RNK?`{3AO(B@9rB8c4 z77Sy!9s9b;JTnrVEM%6@N6Z_y-G}tTs2XQX9uaalqBWz$HUQ-i2u?D27cU~14}vjh zRGVnvoc!vG2?xoCb`!-};UD7%6HX|xll2rCES67Mw&qP~bfuw0RTmWv+(emQiRm=3 zUy?G)J_0Ov)>6xc0~dG~MTMGVgY1Ul1eJe1uY-E!vGr{j%-r6vcn!pUHV5L8lzoc=sRNJA=2bxM+! z$f6b`i*9F*E4JU1pU`!E_-60W-?!BC@xS)`n3e8T|anw+Ffy*Ke|> zWh*}{G$gnO)Rf~q9<4oynh84*<#>+^CU(q&$W?lXgvCKZ569Q`t%jO(zMp(h5 z3%3W&c)asm-%#4fxom-|U zr!S?gP()!Zn$4a?$VoxL1qzH$8vqb9xs#fdDpxD0$^e5NI6(NRx|`RgJ7s5@TWdF) za~n49{P9ObmxmEo*(BG8>|ERqhS*s^PO}{Ge%{h$umEcXYbuoMsdW65SlPW3t;y#~ zQQo~?-M(#u^gOh(V<>>3W)aB;zAqLtedtX6BGYBoavzP>Z+v3O}ALGO_{Eqre8Beu2aW z?dENm?)KX-SS!@3XGs6G6q%B8Y3P!p9Y*K~nKD`|^rBk*y2eh}J)19dETU9cWGQX` zTz-C+jKHfo!{dpO6TY5kFlGL!=%N2h2mMPL_|H$p`)cKxoxFLw9Z-U^wqTidNk=XCFPt4KDIqb>E#0@s3e<+{>Uy$W0p-`wfHHe_FdwXSMBTzSCto8a zy)ean9y(_WrBb3V9k$ebJc`rojBEiKHaw$wUpl!28Q_(w$yu6mLjC;i^nnhwPQTdp zBO>*WsJZFIn}IB2WXN30!VTj!P*j{8g+-(=9mfW{Wfv``AF$`6MgnDbRy`}@cmv6a zlTg6?K0)>RNJaJ{kWB^Zke|hwav?OVy033dw5J*J7x#<-g2`*+$cypAYC@|t6X!w{ zTLcb+Ls|`N*vp!Y@Q0v>2GYH4qGN{vVfpb8M4XeNn4#<03@sB^`zCu*T?)z$8rBpbr&fe4dad2O$$7=bYHZpEBbci$gk{~z|wJF3ZaUHi<~MiCvPNz;+0hBgQR0l`rSNH>rW5}MLU z0!Rr;lMy!v2*FT-bft!b00|@znxjZ>0!bh=hbrBn3y6Mk_C9Brea`H5_F3y&-}>?g zE3B2|U2pQd&-1+ZeO03vIZ!KLl;?ip}h@SWxw;9fYfrOeNoZmcp zeO0Fw3z@Yh0vJ$&q-3S(LqCi7R5y_CGlcYSXhgA_L%1))EV}v`QDe-?f&kbCduf| z#unK(hyNzG${>+0@;RYVfYMAP!}fzAMJm-;@$OxzD@# z2Y{+(>RE4oKxCaZWM`#K)g`E)cms(*OSz?i-c=*Nj9lx_fiOQ&#P( zBGA%Md#BvbJ4oa(XlA~d&cYO><-A8PK^KE%(Y*{e1Jz8EwvMiE2iGxPk{w#3Tf7)M zAcUqleZ0Kqc=U&9XNt)&8drrX!BwlpW;cDeo%2aV>#D2Iv8;H!?c!#pR$_X3V(%j- z>wD<(8*Eh~T;A7SH$Q~6#k2H;V$MOwKgG!FM0i8eV#oHjENaWk-#gDcYM7V~ZugG`lTj1#Wi2$9t$dgj3a7blBtc8|Kp#QW#)$^^t4)Mjv(Z^Mk-BaeRGU5C4 zApUk(rx(n_8+d}jZeS=W6&0jsdG_KI{Oq!+rkrf5x^U6;z=SDrC9~$`*s6uls#~`? z2RSAyAxAP5pA|kQJz%Xb-_`etGCDW)0S`s{q(pDNCf0{tNjc8Si&>OPkSwlWL`Bk@ z)I^L?s-9jQj(70J#fp%sBQ1ku3FtQ^u6ij}REMWeIcF%O90`BZoIlk+xXZ4d5%H;= zyu;+IM+R1AbrZ6rFx@_LVW()8LeL_Mb2%9){9HL-=F_^-{&{qrg=$|0qUfI0NQqTA ztWyaS0O7)pnWr9jA{PVGL94`ABz)BDCdbQCA$(3J0Ug^-uQ9(N6r8Pc*{dKn_WADh z#2fOnQnjEff%ZG8JIr$j-)vJwT>e^Mg2;w zaWrA~q%^@s)Jnlf0rI~1#_nO$53DnTSyDROW&twyd6U*d=*l7g3KttWo!Cjp$xfOq zu?ItbAq)N5_EgPeI8LUhXf;S1W+-H+Vc9yHBJ@jMW@d_TLE@eII(c;<-*WZ}vVN#U z6och<0SML8TUsv0$KGH{o>R`9myx=G$Eq0m{xV^_1Whgz60 z9mOt%?p1N97bFoD(7I*SByp3mrbCW`=|~#}NDJBbWhU@#J;q9`6mS{4h#~b4qL|7) z$KpaS9epn6+`JgK(g>A_i-!vue;6Ck1tC>}q*=t7wXBh9%rJh``N#3gtgyns$t{y6 z`_)mSq!E=(7@Zn49obn8{)wh&pygdGg;bG+`pIvf?_>Gi=i7`tT+mrA&kFpGHc;<- z?cvQfAy-Iw4T1}~!lXkJPtXlMkc#(m<~1caVqCcg2G9;=I(rYeY`-A1qzdB zw81l(J8pif77Ap2NA$9J^ZDe3%xgqe+Jzn-lee5R1WbkR-R0Ie#xtDz7>4ShficMS6KgDbaA zXDr>7*}U{Tv+yye&5nE3oAG!c-g*tI)(m|_EO?TdE99jSRp{WKi-)hXHq~>F3e2)B z8DVkRx?a#7B?BFa=J$meR2t^7>rJa5Ggq(lZDdFxbxOF3E+1KnF*p9;Kp>F){0v{O z2l#2s)|cubn&<^vr`s+71DB$*qxKx8qdK1Sy_#LpJXORTWI;pm6{$34ncs#VG^P(I z`9|o@uP5=_pRa${|1|ntS%BwPzxmhD!cV<-t2&Qe9ipEi?r-uP`du=Dkfl|lWgcd4 z`H+Jps9Y7x{YnBiT(-_v<$PKUvCG-?`^x&a!*ZW-ht2-zgrX>nAqth*<$%u6?v{&h z+tAXO7ST}Q#)i25+LL^ha_jd+ir@7`ZvO70|EYieczkoqmEXuYH(^M}#)L<&VWY07;=TnL7MRk@G(;JckZvRd>(6Cw0yHJtutcr#{9o9a`Yf)3<@ z)2`WlxK)gY8_+aq{0^A|yJ_O@j}A`1Q>k`Mu05+t)AMcj@HbL~ zSUg*GTo5egg=^Iq!z`qs$%{TN+xBAqel+sk>lMOvrxw!Na!j7MG05{Tg%o!p-X^fE zEej4c;Fqz+t+|VH!>aXV(D=R^TZU}})^wMkj$KB`%2%kmpYe!2>1$Z1qpFxV=q2FN zK~iCMR4$h2vwq%H%RlY0`EoDuZEguts-BwHf5>IxGnW8m-Y}i8fGTu9A?chW)2So` zLn1Y2XX{F7xE2eEJJJB6Hb68Rm#aU9rwD^W_9}zDMF}C|VP@~W+^dE+sM|gbR&SMn zYUV@~VFG`;cvsy@Jxj`lcpkM4Vo#^^z_=-Aw-%~ZUgcMHxKbAthC0wSoVN*60m)Fo zFpXUlk%-hjma3c9?Uc)AHYff-G2*n(Z1_)2ojh=_vYP4IZ*_CNxad`}sciQItiDcVDwXCVyFrV@mgoLh26?bY}ZrIiimA>uq4@Yk34E4*$KkU;z?5-z)i6ruSG0< z+z4hOuB{=fztV;-p4InR4%}V#|?ZcpjyFbipqD~JD z)Ng#>Iusl9UE=wYn00GqrxvlbnK9I52VUvoPGz=-{|L41$C2+*<`C~a^;Xd_K#HNOu)+1;QcdA-El|8)RmYWW7 z3OSvqo7E?6HE)<3?)(+J5tE{tuCUO(m^%(i7&*1=(j=FT^IFF&7GShPM67@0sT!K3D%7>2FpZ?XGgJ9A_^WVt7X9$@{V?c^BAA4iG3X^ht z0ILxA7%M_(6JY$wx6t~%uyUhAUd@;a8Uq-olaTXx>YT)>0SGt3PS)NFV}jFMyK7f* zV;bTtlBg_K*^MUKJ8>X_V^(lmw+2M^TnXb4c`0@rm1ULKAVLJl+hyWbbR;F>ca%|2 zlHDw?YF1g@S$l0}w<*qQren(_JJ2gC_}wmhNqvmka!du?<~hmeoO2dP+hHJAy8>>@ zdUGbss)?2A!JcFj(FHp52ip+dX{U#s z^&wj{MHwdPYTvKu+kk_H@KFnQYu?B%Yq?v!>9YrrdpA!6Ad{F7Ban7pOo)1}3b^ll zMb3+p-{526GqruoW{=M3DVdMdr;f3Q=BvF;ygy~#oS}KJ&vYZb@mjL+He*qno?_>v zn~Yv&i@TR2d_Ow7q2?COw0vf(7HwYDBTbHhF@R}y+zeIv(wQL$I_J4Qc@AxepDl2^-I}>7nKA{1CV7-`Oz`T zl=jh?`$DuOH<&$cz`l$o2;D+H?k`C+F|RyMAXMn~-i-N_fG$Z)TY{nr94z9AW63bu z;IQL2gPjnHUh-ny+l%Ru3YD8RqD@UkYWu$uGm5l^=R-PA5t| z^QtNG9#KWwwP##@o%dSVMsk!*>XP>MDlI};W3#E6lLP}pX3I6G*scu=nTNCDblqZo z^mN6O*jFk3I$?L3fc0*5t*S^HYkGQV;nqRR;ZreoS$qh1Z;H}85s#A3JQHcm4eK&P zGv}K5#`w2urm=WqVp>IQoQQTNP|11R1$WcxW}Y+>D0G@)X+Xrn0E`|7kJ$Jd(=Q$@ z-D_9pP$hP?TG5p@^?{=9v;lS>ofni_@J5^Z;7vaj8fs#4(p@1Tr1vz_uePA>p=g}% zOQ$v!yXMJ5IsEA>kLUwBdS0B3L#`lL&V!dP}x`4xulK+Vj0 zTAd9yiA3b_!p;ZLCvGtu$cxrKZpw>^p+tGxFrsj@Mnb`hdV>84Y~{ccH|l}z0$}UA2z({m2wtY z9p)TI(|4o`=wGx4he*jwpc^(XY^9J2)Kv(#&)jnh6}Xrx_lD!9L9S4UDEq#7bs=Kd zHzRqKZp%783i!+;M{=jI?f{DyNl5v@=&TxLI;L7+&#U-(qdZ`BBzF&tciXZKyvw`i zV&G3Ev{p-rJsh~W(`PGjMRzuLk5v5esFOV1K{3(8dbIq~l=HToh) zNT=F~ws-2`UhmyE#JyUcQyQqaM9q?PQBet$!iA||9g>WvRO_bDF9!=QrwlBaTTKjG zUliEuT!$vTC% zU$QN!#P$6!HwBl&iDh$Sf_ELI2Qo6JHyPc~Pcs4BZQ=fo;qTVM|G{Sb$koYOseaNX zb|SaK*XzM&o~#+cyCxV=*;ftrp2*_R(Te_(I6`hdUUnL&wg_36H#Dg0J@MoJX2ixm zMBTp}Tk?lPq%Gsn8zh5mzr}! z)xJ~~EuNgt`J;xWHZ_UAmOVjNh|yEl41O>d$n=@VPZj=P zy2f%Gn(W!GS^6Qf8@_yx*MXgXj98kO+x-rpE-D1In>PgLN$uK{*FznI@1XwCUg&cQ z_pA8_Th*2Z!``=F``;qJFud2e@o=D2TP;3Jc33XnYLJ!#Ne=LS*VEQt=qd1-2kMNh zIe&!WHwZU)S5nqk>D9Ygt0+^JU*}%`&^79O6-QR5xD4b9y{@blFprIp1zBu3VB;%I zPdZNQjJ+BO7k(ZJ)-r^!AU*Ph#M0vMPX!>;9%yL4PFQIO3mO))AtmLuw7C$L8bH75I1!~@Bu9xuN&yMc(a|w&{3mby)wKBK9{OL_+JGE=N+x&}T0OkC zY*S9uG$~n7)!+J*B;vLYH49o?ObnW^ZcV1>bbS5808l3JBHp|(K#le*a_&9v-oPz) zyMa&PdsYD!+&#f}XJ3zNM>aUl-x)8FyStT$HjaQxyjXo#BkP~~X`WcLwXe+2C6E45 z!|7jUh5li8>z_DSFicm1l4+i`wS3lN7Q;5W!Aiu7Lrg5(O8r7YjtzaYeNDz^x{nHs zQPtc~nXT(Z|G?*H^Dbam^+1K&I(v@X&G><2rKgJP149kA48f*b=PCAroryrmCRdUu zevMn~;FNmL=2*IK_eq7nlCuh!iiG@=DvZDW_5bkyuez(Fp7ia?d-;ejH#09=L%AtZ zx%siwty}q}*_Xv14~`6G$n-K=U;B?uA(fSU{J0T#S{L@0_KxgBk^aM2QghD_QT;Sc z#eq|gF1c^WtIFpj}bh%iyd65fav9|uF=e{E?Jgh7X-q-~%&O1rTXRHrmkH7zele6fmjTzMhPPD|@ zt#PgGdo$^yQvEOaOxKgw2J|@>pCwjM&?;>Jo%$qMn<<s;NRu_s$tRRfw*`h63SZH2 zRM@JEcuOr79!+@DKeB+7%PW3BGSc3??DnWKzQMAk?Nf&RNrdKnoJBt2$DqAGXz7M% zxd%^%G*kiCjE~fCVjP}VfNa+B8Y~7=kabD^8D8D!z|);a*Gv2WYcbFu|2gAZf7rj| zf`_dhDOd=-q{egp1K*22<|9{yn9a*CcvyCtQoqM<5bqqEy`>p+p4JU@L>8ldr&)UT z=du0A`@a8>kAC%_Yc15r-r0XT&D9>HQo>3dR=hBBSE(hLwZ!JTv`hlZN(WPd`Q2JDo z7}ii?NkNRbltFAo^9+#^{8K}Oh2iV$Z+AppYbJ)jj+iubR4kqJczB|EbU~2@Zaml_ zX^fa4Vs#0`XE^M_9IkApMY~|+#r@yT=WkF_PdZ;=4rs+a>T@78fZ}H2QMRxlgHrn2 zaVLO!_M|{q=~Q+zL^ZiLL{mPEB|sJXrz+Uvd%sb9n=`0%rL12I6CNYhsOjS6^o}Qp z4QsH_s{ySd*-&L$WG=0(?W{m=Z|mFKO$N`bzXeCzM3gN&Wc;`TC0`1Ie@yIkr8iEC z@D^~F8f3N%A(mJPZ{tF?ZkRHE8pg0Be1=4E|^yip% zI~Yx;5FRgOwe^baoA^0%cI*g+x8MpLQJcR7K>jH)y%67K z=;76~lk_ZI&Umc4DDQE3h}eu7n8N@&-;q3a!l7XD`kK0qZ#BfTZG!x~xC+>B=toHJ zKLm8aD4{oiad~j5#Vlh=dwdb@^!CpV1f8KSS9eUhTw}nGMD}V!>l1Iia8z zZ&uUgTF08lz4Ox(3+l3Sj4#?n*YyTzN-&Ro_*YKwA?zo0YuSnm-a;QTw}2*Qe#5A_ z<-p($dwWF-XTdp%WEKvjD&&+c$`6f><%ki8v0i^!<^I-M$@6PT?&yBYk#X@pnejJV zo7cWD$^Qz~by7Y4uuH*wEty-y#lP4A9Rm4THc3l|E(m&uyA8CGouMNPj3&6aC!Kg6 z_+9#L+=7y?^wP@YCL(=4G`9I7Q)Q9$TC|}nPN8HcKE_=uS2x;-Zt=1&H2wfB$*Un>gC`dKpv~d z>Ab47&#B>~jQfUX9BxqIuD}<{1{$*)B`R z`$X{(CFTk_fHM9#$4v}T)9+C?zIA+9V6NT}tkV~TD{q}8I-@<3{Tl#JT~M0snJKee zln4T{p*z~TmRTYHQq?Q4I`T7*NW}0RjH-9fjT z3^R527z;Y)ed#@uJ?Pr57U@NO_k>fj6?c7DXy;gr&sio(DnII|{Tp^)D+hVbe~${J zFuG@mEDuSoZ(2^;o_AV2o{9paQBpSZzHxf`yCefa zWv$c9Z!)L8r1@0sg(eN=Aj)LSk%S*1FaNDfdal~;zrW%C>E8^$|9|j6`*(qw8Uf)G z;n2pEQ(S__+?7JUGc0koOa0m3QX+cMSx9<6aCDM5Bd83u+Ka#vgXFI1Oidy`{Rdy z>L6@A9^S95v0qeczqfQ{5+ax9FNv06f=+Ny5Ub6m%eW;>zDUn~LiwXgE=P=l!$=Q@`)RE>D{ z$pmNo?jc#pK6+s`y{0!HqN0)*GG{~4)BbLD4&@SHOqg1LZ2G`Yq>XYShgeS?ipz~n z^4A%lhUse{xc2S5B1UgtqxlRZ=#m!IX4Ig&%1FYl&myl)8U-`z{LnQ740hT}ve{6$ zm$kf5GBbEN-pqbkjNK4lTI51C6Vq$gbXskdMWfgp{#LBDvXyPMv-X;9rQNbvcaC_q zyC_Td+MZ-3jJJzV#<$7nHjTyZnf|^{e?UdH)G2(HSc6D#cRfYJ9jQM?ZjcaANc zeNJWt*kn*@GHZGQ2)316Lxu$+{365_f+Q(q;?4d2r?$#8h<MOk7!Hbf%MA?e&gc&M3QSE?h4e0i_1 zW?Ltl150vCrq>vy9hjF+FNEiaM07zLZSBBKgR-{w)HzP5?G{kI!6qpZ=yo*|yc za8Hxbs3xGH6;M4xUd77f7=da0Y3Qnd0Td?9FWHk*kt0(o(UQ25boZ6QmYX|*m>}7z z2$vL!xL2yF@5`C9h5az!9-K}}{DEBLlxHpUP5>w8FBUt)IODLf2~+a_6UT3R>1w}B zEx5&UN53SBOp#9-icc4^nfBR24b^4FK3;s+%FT%TV`0Z%WJ!OcdiI~Mn6O=(?_E1^ zaF2!J+PGqTDoBQ%#|5^aC4YW}l*Wlun9=*%vCduGTaSfE=WK5d%85|48XMr{)j${P z_Krl*R3L~sho-s3&pcz;_|~auZywK@4umBN$y*^JUF!lvN6qZkPpn{WoFdYTonnO< zT}81Mp0f20ssKxz!Q$fgX)`3o{$daQ<}3;5Fxt7(z|M_O*1# zlw@^>)WYQg$S4+naqmI1=|w2u)=@PHrTJsXix;0gZymOrZ$}Q6qEbff{R+db_%$8) zt^{+v=eQ|0H&Dhj*sx!XKz69|e?IY){P0N21(hp^ks)y?RWKs`AZ}IOwkHP|!m``q z>Y})6^I!9c{u00Qcfatz(KPt#*96@Cv;SYY=Jp3+Jm>nA)b_IMKizT|Ss>Do~x z?SxxUNAFb*=_-lAZk@>|)7qrx&KF^|)Em#rwa>DZx}5!mf@ltt&vO^di1+z&!aE9lH-%s<>aM>Ng%s<<;<86+qkR-yP8f|Kc2}Azsq> zKI5c%J!d!$I!*@!55?-<+vE00OUnD|le_#!+tagRWESLcPbhUo)vdud`=Ljb#jNt_1Fxy$&-zN`3A%GyC_WmwYH3#io6 zePuAsyYJ@2oUM5Wrp7kbI7QisdNADuL`ZSQ2FYT9;p$cC8byO0m*GEAhr>z}3%7A# zrVV9Y;{JfG3HX3}-YTFbxCYTIp9@*Vn;G#khyehM6a{Q@;p;HM`t*r{wRCbC7L+vV zw@dPYg`_MSW6}}%g;6=P>e;9BoV6}aPQCV#+06AbzmfbccbxyN)UV$)n*OHfV*ds6 z_nxO$JyO(^8z~!0y>bb^lmU~~mST*I%ojX!QBl7&4}i-88;pdHm{PBA=NT#_)@E87N?p2Z@D6akLf&T_CGx!e)bhu- z^2HR((bCji2W5rioPMuV`G){eEAX-Wqg)lzT8eSAF3h0Ce8b=~PgS9FrtcxjlI*e8Gz@Zt4eld8|vsOW_6cd3H+w{2{1bTu4P{4txL;_bah1n zh0AoiOCPV$+0}&+S)6@zCPttFWN_phd3f1c-7x|URqX7CVg8{ zH|3REi5kj69hfYBAd8`fOE09fmlGAQ2OYeU86CG{vBTS?g&CzaPLCar3_L^f+S^ua zlqS}*t=~9aynyns%pEq;QwSKdG67zBQjg#9rkf6EN_H&<%Om=YI$b&CZo!kMi4(rt z%1Q6o@blRb!yq$D3e;BVR0&WqR;lUDi*itmz+6B(@lyfXPYD;l97eBMQ>b=^@8ulI zV-14L9WA_KTW)-yioW%&m7=@&2ep`H|InJ+wj&Fd^H2G>gZOzEIBo2JT3my6j4FYe(mb_~tpTL)nKNPc-6Gyf9 zXO^8Uc}ZLbT9e4)gaV>|sXw~_>jhGKQl^Fjm)+=HoXX5vx@!$+df8A*8BaTLJk7x# zu7{hv>11VM1vQ=fx#}g{7JABH{efodfSs&UgMKihBq2uwquDPZf7_Qo-LPy)!>gAs zCD5$@T#8aa;4!6IS751o%c0{(RVCWa6Ofx_p>clFo>K=lL@hWLl^n)4kf< znytPX;Oh_-Kvz;5!wC`7_X>?8m$b6mkx$9%-PZbqO|og&2_IV7iJXq=`*g?mRdo#= z<*S{DjgYduY9@5ptsuZ?YTY}3(f*MBDLpminE6tduJC??dLj$yw}rX?ERaxK#Zf82 zkIS7ymeWVg(8YL-%@iyNAA}rhJ4j3Dnvwklc|c zV|nGhH?MhD*(q8E((}`pLR8?Kqmi#sE!2TtlhvE6k*a|a(iK$F&|1294dh2iEKtzM zSk^YYxkbtX3NOAdAe3tu<kfOe^B(vb3I zTV58;1pNZc8t7{f)znGgQg(PV3L9d2OPtU9;lkT$U71KgSR)}mtkx19M2_J3(4#?v%n%^0q5?) zG_e-HbiuppN*)|17$vNsX*OKeT1se0{)Ir`&}BvTo^-Kiv8NOIdp+USY89LTQy+z3 zmal$s5$o^Zc*y@_CZ6;FX=vB|Si(*ztB;w?KK&`hwg1~zmxh9aMjKr^S1OZ}O1ySP z$_-U?kkY+49s=&fVYzA|!Ou zW8ac?Fj1!~ZD!3xE`hDKt&=WNqdo`B*0F zYx=*!0W7R9_u-sSeCS9;TM5~vuOO>>;D&Bquq3T<88l3WFX{Q7a<~$HPl)R^ad1R< z-v4d!ko(92o@a^0)yQ(FL1q(0=A!KKPgURS|HP56*P4}z#+ zz+QC%mrmPw4;qDmNPHfgQ-}sg9O2cy$ zGLsVhY=%3MJxHGWqGtYzH1`i@(!k^<64e%xOcsvN8dzv;x%xgpcq5ptPUBV(?n;G^ z9v?eID_$M0caX$6!xT)Et6olHgiVt2LJA7z4P>EeE1JEKYfJ*mUy|8mogWw9t$%Z@ z?RPr+-`ns1fnv5rl&VL6SW1j+&v3)U zQ}$8q5{#!KmzRopOT=}@<0dW_m_SqIt>y0!%gBt^FYHcKoAGJf=1of1k$za|4+T>V zm!KzoBDcliguI3y>LF<-Op;yHPMv2d3ccF3hnq=-x9c9A@KgS%d5kg6RcTa#U;0$_ z>6w_A2;7eN#@WD7&`aNdLbh;5d{JvG>g#nL+|NECCjJh-weRx%XP@rx(-U#VsKa|N z>4%$Y$88K=v??&NubG7vrq4a)3TB_pRtysy1;()hmOWcxfF`OSRTrc_+)R?rg`yWt;dq`eL@A) zfuZOzGo%eh6(0NORgw_Vr!_4PZm2Cl z4-u*T2P<)=rT%yW{TUKs8deW&jV7_*Z(BhLhX30G&03*=_%$| z?eHM@Qa{MoPxUiTQ7I~e_3_0h$FL_yFDU5VZ@jz1|CLVopO<0c?6G@`zzl82H$@;4 zf46%+{d&$)L^gHwT0nrQ#g0vz_a)kw%RC`%s|2uo!e|`whQFj4V=FZvD3M;6Y zX&P{%@iD~gcx;<=VU7Kq;u=XJn_WvKCMD+P=B`3EliQCSleg#7p$;4IDay*2Mr40u z6NkMp7|rHRC{A1)J-@)bzT6d)uq=e`ty?)YWY@oNT>gB#uVlF)klL}}GRm$?6A)Mk#X36MFkzba^R2WDF=o^prx}j=yEZ9T^k&CW zzi?9?u8xDueO4SMX*G%5J>@z7tk{3rBA=44vS+&as5;XW<$fNbu9KrGGQ>H@O4G+N zu1=SE)gz`p^V9&I|KF{@6^+viMjap8>9p<-Bjvs@5ub_b4Xw21kY?gzy53{cYc9Cr z$mYgGHu3ybAL%e4IkL=`oEC2uH^uC+VRdCEmL3VjK!i*;o1kWZunUFpBbftLL%)&( zV#P10DT<`N_4m4ss&%z&RNRTpZD_fhe!B1SOj(t6m!6gU>Fj3Un$?XdpG`xlaObeU z|Kpi%__gb!~%UeU?elEZy5&pgQ($F!_siN2didHTbYXjYj z*H^aAV}WISbU_OH*RLb{)HwTcjAOa!*ZbP8`+AuZU&60DP-Tr7u$oX(o4AH- z`so7mJItTf9k40rm^R2z+war~f5C0;pUl4c&1T8Jug$FX8&vg>)W*FkXFBp@#0q$7 zUAP^N0u;>p?_PFxs$ZT%%BLnFNNxPkaO#;jPJD!f-$MnX`9iuKJLaNm(ev!P^?>~N zCk*HK*iD+fyim7wu1ej=1`0848aR?$!a!#BjdDdE#8T3k>X!$$xTWvX~b;EIK?ZgN)f^r>rRe8D|n zF)iJ0>$Pwbt0!SR^)siJwS!tpL>?z34NOC+!(^4fOIO>G(go?oi}NUG$uyr@&&-Ct z1NKI}adbn}YmUu*V!2_G8;h09RJHCOer~Mo1r1$;bg#Rp7#>paGv3l{kB(+5)6B&y ze#R^h-2(;BFFmc5V&P`iW;lGnQu<{%^k!|vh5U$8msMEau5q9x$$=arF*s1**fuCG zCzN<|VZI|Q>6@TrzESTxJ!v?O2+iVl(p3Y9gC=#)h z-0$u-*9;GyV0|J9iw2b7iA`z&TUz4r#8Qr}!M5nYS(F(}&`RaZTa;bN)D&on)MnPY zy=&{#kyo|Eo0WHh12;IAYEQ9d*{^-{n^=f#<9%mbq%~|JA;bzCl*T6P9drq^NOzf; zQHXtNrz}WzQ72iyXE8pRlqqZkVHBwyKChN5I}59s5HQ5{eC*g*-wi2@_I#T8mQGhe zNM?(c#%G>N-3Xi2#Sj_B+eNnRqhxERt;2|A%BF>T5=$3aMyplWXQ z9TTgc)8}hcAWubxx@E{#Yj-H2TnlQonjD6KW{qU$Rhv@OF>o88UMQN~UiWrgAfq9s z>uCdhXp{V237#?uhX&RY+P#>j6>Ua9kZaA7oU&&G@5jEDbyRMYjY~nu4)jSo)vPB& z$aypX@0mEh^U(3mFf{M|2D||%TP0c3ALl=qSGm@tt-O7#bu6SmlcA>Ow-1nZz~Ft#Vff zsN)@?tI!n(J@*E8^hO98L z-#KP_>6dL*k`+7X07|K^{te7fnsZ>>>xx;_L4Q$p=J3FRhK-p;KnsBW=~-9lQ;ZTE zRa|G;=bW+;23h(^alPK}9M;_G)@FMJGI2zyWgFWyF8#?P#yyE(Yjdmja?ICkj^r|=UU_9&lpXT_3#b$e@jhsOS=PBo5bprnO zi-D1y6g&DL?HIK;?`4}&4~8Bf`(!Iw1h9?nZ= zvVjiMQ|uz3|ukclK?oB7!bZ=Z}QVHq~XRAi9Cy?XZhlk3DsHwKY8ib857SdEfP zelSKuGjY$MKTGx}A7JLqjy-q2dRGiABo#O2TI;m2UY1|g=DH}0=Y4%i@eqhMKW1_b zfXVN>nyMjnQJY=u@*z@A)C5C$-zkNwaca9oS`+814qSD3Udjjx6;Q?*<60AqhJee~ zz)|WAtiQy-SL-5zgO{;)+JjcKNu>caJkf*&bW!WuR#?Z#OI`o)&N|=1Z_{F?nc?ty z4hAG_5_d0ux{aL%4(xixPEG?aH}&l3u(IOfR)b&2MHE%c%;a9(6C+46$Gmnz8Eb}8 zckG23LxFKpqo|IJZmScj-mhp&FTSH8X3qy~Sf`t?I7rX*cJDCEQPX)%!1EZpR(Biv#Vrw3Q%xyuQyzUY2-F|>>rm#uv2f{trMP}KEF(|;R*=%t;t*g;eLGLKg&tjuSGlrIos{IarO<*Cu!W< zC5VGb$6z@3ium$4u>G0Gd57n0x5o?c-q-uz^g99LbLjut?ruNq;jf79oK2;dkGT+m z0D2XBy9xJZvTH6)dePqUos@Ay)4ahtxAny7$zlH~_g#}P99}M2vN4vihTTjF;?oM; zJ{a&l5MT6$wyLwh%c{>Eppf-Z3{A1e>vm(>iC%M@8T#ov=+e__cuPd-BE{0ZlvZl+g z1~PnRM&2bqK<6>XV89DD} zl)$pq1H3$Cb)$t&w9y78x)JjbOmll=y)3W%M0?KZ(c~Sk!LCGPMr0cuc`y)WKAg$2 z$PZZQ-1WEFmdXo=UktgcT`aktsG*TqR+M-LNcOR*e5$0AIWw58a;N#iib;KG2izDp z>Uj}7XCc#*oej(HTC!(uYSw$Ul^JRbGKRVZedpu4P3cK4Gs)j-D<)`Qd(C%FO1pA2 z)s2L@3j$VER`Sv~ZSv`_aqX|2@`N6oqpfV%$Du+`kemj6<=jMtm6f25LTyYaJv)!9Ntih1wU=GSDq=e_U7*__#lo&1Qnip;hpo2j zxqTIa>vcW$kX!!8UKgYMfFvM47>k0RsaTPu`K4iY{q`Q0|1zt*9yID2rhER8rK6H* z_S-~tEH>L_vWm6d!l#-go{tj4`kyWhX0);1q@EBc$6Ltu@OE4Z)moCAPv7vVM#vNd z;0N?PB3M&zsJTa_15Oqc#!IvzHWqen6t@x56k&}9{Dg&-;jE}#+z3F0@iaCsT1oMtNk?UPvno+c2Yn;?EVZ;ie_8nx1Ig}r5cd3B*6YB%JC1NHI}_uQ5r zpF%AO550asg(<|(Mlt3$X%{oZp}}_V)MX6)hRZ(sZ~QF6mq(@@x(|&X{C?+n&7N9n z^aZ!)UbZr!0VVOaQfBg^0y%&@9NCG6pvvP&H6tHPnzKR)9lnydbSJnFXlTXnQ!y$r za+NBd_bkj+>{2jX+Qwd1&5~v}VB98<;WAYhZxVXPR}M;C-91e1SzT})+l|q?Rh)~T zJ6^ecF!@P+rB7LQp{Tpz+TDvXu{YQTyJwlv(TBdSi0*K0z!T{elA$-jiziiNLx}xJ zP%$jx#b!8-A2u6yzh~=I95?ciUqV_TuV%zk1&J8s#EwvhL6QkF`L%Y11$j4EZ(x?! z)|WPv(Ip|ycReyQ0P?tA(lO{jD?S+I(YpyBWoxmsJpruGVp>jd{ z>88|%K}7&Yvs)iDRXpBw?`Gu$-e@J(zLDxyVFj0Mq0B4Km;W#l9N+DnHq{+;`@6tB^L*DiO}ekTl*AhBuAY2dK%3U=9Gvc^j^Z0JxrBVL!d!|>0U=h< zp>i?13>_E06n53U%@UGQZ=jFP1We+I^9tCaTdv$+Q5|mf)FLc2aMq1PjEXWo(|qH0 zfvcAO4!j_KR7D*GBh~8rNhgl{U6su5WJ&wVW)i;{ZV&v1Wcuzua1?)DGHb=qIe`f zrVdXeQDV<beDg^}8w#u}oBu@>O?Zznv$mV5GgR zS2tkOtJcn0je+qO*2-8^Cx|+#LivdaS>o(vkLbr;VT9<%i~0v51K7T_@4L@Pxt*^h ztRU>~7A=KHR&EF*H0=`y?8I%Y01yUzU{HE4Q7F`ocvhx6WXeB4P;TR)!pQ!i9D55?c5soIl?=E;^$OAEwhQ%=5|=Y9)Ycb2w_Awq+iG!M zu0z^sRdrp?i+GhZIG2sDPHTfpUXs_m-b_M}Q9)Aj2yPy9l-u-=KXbDbmYV__6)^Y_ zJT!aFNT=a^qhE?mvqH*o>(#VTe*Lkc+_DRUIaXFrjMWY|a?;Km%9eY%#GZ>DLoQW9 zp*=M6s~c&C2bWd{$w^%%LV9OahsemP3~}+4co^VYF|X;@9|yDotN~v}OJgLqw zyApNV<0l`Ggv3AwaSZ0mBT1m42BRrMEq4X-++y0Nv4N&LXywB#QjNcKn)f19dP$gX0Wvz)?>8#IWU(caw?R=}!ZU${(dznxM_$W^U!wykuOa1Rt!*%T6{ zqXiW2!ullI_BzBc>&<3J?7BtqM~@VtjFR^St-tJwEAv~@v7=$1k}MQ4bTvQis8O*I!J<8tXPB~hfR=9$yfs>g~(%FpC(*MKWo5v-c{rlt1 zG)*&=HC9-;)wpD$W}0YjHI4h80-^$1?t)A1x#iSMmKc~An7EaS3J3-YhU=86si~<5 zid*KsVC7m`_M?06_c6}>&UEkh`@7%!yT9-K@K50T9M0*y&--xB>-AiGKq2_3yKGtE zl$uYmGutbN*4^)Akz*Lp<>u62bLT=oNM7!|9f937a;caFHgC(4>!h$H%)Slj3$)zS;z5)^>T}bI~F-oOG>&puaS>#xSVjHMI z_=%pX^fPtcK1XuPp1!Um0d52^^wdDccDBYTxzklXX_#?y11njc**b6y7zPDz+(k(^ zWWlMTBT40rWf7pYZ-=Oq1u0C-SP8>&KpOH)z;s+(4fHY)WK~IHr&{#CYKX0m5IuKr zzm%~{b_m-*zpKt2rp-&uCB%pFAS1MX^-7@Yc#wC*X>f-XtF2Q;nbiO~o&-cAT5YfD8B}Ca- zDb-vomY35;>i#hHDsOO@`ugP9OOq`I5Y%hHzs^!gLbv^$8y@th{bgIySzGFV*237* z?=5*ZGcn10OTjJau>b2DvY1s*!2rSvg>la8+LI9H`K*)-8h*K0nW@5r;l%ra@(^+_+&fSW| zPGe&oM=QuOKAL$;V7-h2$xb+|Y1+6Aqd$_8SAIP82d-62nlx;*i@(h$4hH$eLt>&l zuw!~E#k>kYrS%n5zF0HBw{3UfwZzT0o}iqxYi^w2L!nPzALz6Lpv=?(5g)2i1|>d$ zyk4zHh2nsNUCoLy`NiM^Bw*aODH+_9kl3<>OqF_4(P)SD=I+%G6r6@XFnh!rIq#@0 zf$>$j8-r-ujsj;@pL{%6C0%dZ8)nz?^rT!M+bt+7x1ZoVsjKe0wqs%yXqwdK=#d65 zkvkY_inR*xP2vaXxeLyHh!14nMV0)OlKB4gF$--5MtGL^3nV zMoF92C(xohpuNZO=FOEh_g`%feDP*1wDlpKaPhIgZ4MDD0%WaANI#CC(lIc#G=}N? z*t%B3ZUysv>(tpfdpm<9QS~E#&T!BgY@m?q&RA2+=^)yeON3TA*KznO70ytuYJgH& zsyIVT z;M%-!3&pq-85D6u){2L439+^fQLQ_D>=D!~lqbl!mdYP0U9GZoLIunmaR328Ml7DP zOh1I0jNGIVZc)U;qvAS>FhtGk>D0{s_H;f&mLs}CuVQUDqOJuWq*Eq(zloGH&eu9X zIWUu8AC?$tTqQ3Tv7@qbGq2zcP%M{sH;>hPVn9f?aU^`V>G)A8tpppZ$$Tc>R{yX! zcsQ;ydgi^Ff6&0*ne@R^YR0Uow04_|6;m=hn2k-ydJPzCA~b=*0=M=;dezIP23u zClK0aJ{LDXNJn=u9O$&}$ui~fn(Vwq2VE)7=&Pim!1{TlS5mu~KR59W6maju0TzZ@ zN2k6Ae+11}yJb2qTGph~hYAFJ47)bjhQKrQsPkdvPD-F7#$6$YRPsTFs63UVJQ`j> zWs_iJ_h}npMvQ-<-uK(~?>L2SO?_@Z5?5oAze+U8@?LO@-)U@ZO}jDVR*S{Gb=a=z zY~7sT2zGD)sO|R|e>P%YvSONs$vnHo$*^cu+u1<>uz)#D4@YEoIbN-RY=0cg9SAun z##kTPg_^Yzreg9*&TX<-j|Bk;3OKiFjQ6=bnwXTr_O9Grym!5oMfFo7=N9a*Y*7?! zBBo5KG_kZ=ad6ltJ})o!PQ3&g)V6E$=^zMf{DV$WLNG%xun+ z<_3G}N15PF$t~}H5F0DUZfRia`!6LmT2n4Ql7LMS16V`;8fq6@3a%L(UGGNRfP(Ta<~-c0W%Qe*ivdq84wy z^js#YrnzWs)R|@WSlHlwD=CXMWTg-b@_|C{%RSw+p1w5`8wb1H*?DH2*w&H!k_-Ri z_%DtEY_}ae1Bz-A=*2sCT~4|#Qb`xMp{7t(z&NbZ+g`_K%MK_e`v=o0g}4}n#ns#* z?%=(SD8@s9@uN+@pPD$YQxM0|YSTWOv$x%CbWTE`xG05Y#RR$s{lHaFO{W_go9Y0N zZxFm2cKk+`f1=E}M9rlm(ZkwSppf`(yZ7Hp0R5M-6#yKWN+KQNL7qR$#{xRz2C-+HL=fG%O{zlMEx@*V!mF>U(2hZ#r_(z;b+5BZwvP0L4c- zCa!3eLptpz99HXgm`$`(A0YoFTJ+EVH2Ub9{kp3;Sl<^Mku(&*23Hj^ihRcV#!zvI zVp}OEg>a}CdH{v|r1Iepw$}|v)|lk<#OrVJ@QtdX+^=Z4 z#DWPL05iRqX=w)8s~U(y@bx`fm`hL?2+@m_-m}k$ZDn`#hrS}OyRRbpBgy@U2wm#z z1Q$}ii_^oRUn)WuQpiD141NJMK%mOVEUl-&(ByiyCfzZLpwktKB#M=eB zo8-$?7xm(AR92U+L@ZrE6hElsfuF6l*uT#N*rF=l*5XhgTsSn(`lqAXdN{S%=7?Z8 zwB~J2%GDPCNN8@xt~!HWm#GU@2M-vqd%<8U9UbV2H7%5!&dBW3CiYRyZnFw+5d7<` zQ*{37?E@hE((&n3Ma(!+x>ER{qQzd&44LKmU1Sz!7lcdBPIBdVJX5H_(($HJeWGz_ zqjnbJkeb;r$=YC6f1tzQmV1t-SNcYNK2UL}D==qIFoRF5(g7JqD|>_@-muwit3Id4GG3UomHmTj5lpOo zFf?p&QfwfiEtb;NY{d0`s06(6{0y@CYn#^3XTU!SUYZW^{NN(;XbbiD_VXF=L2b%g zFLt6vWBlPQ^*^5hw-l8BqyB&OhW18Qd&;1Gjqt3Rlm|vR4TRjQ-CT22qhF~H?w>}9 zPCextu3K1Z!7pbbFuhRc<`#I1<3QP#QSeTTO^6Yby0t%TQ^Wx-{C66=f9Gt_L&k|I z(u}XL=q!L4Vs+5D)6BboNEbycp10fmBeq+gj)u)2oZX<7aPQP|Gn zTyI})GY$hEhu+OF1P>{*-l9wKn6aOx!e-~G3XoXPVA@e>YSXf*1^Zbx_EFbq5#1pf zIdf`0TAJ&_O?a|Tt(XNz%E$pUotP-9AE6zSySLD}Aa|jds;}scL*;)fsnhhkXTT)*LLa3>| z4*{}PyI6wb&yz_^xMYh)b>yYZUtwsKC{&JabnS8A|mqq=ecI`dX z34;6nwJ@&xfNB4DP6ebQ2o1MzaM#%aXp|w0ST*e%o?8e;S zAGxF52$o>1D0dUDRtEvXmA$*c;By}dB2TvGs(wlf6tL@G&5=KU++Ujd+M(>M$E3%2 z=o6|n>s;;Gn)ivBiD}JZ97gxw%CrA73fu^=d=O?Wo#NAqmlo$-^LCgX&^jv1tOYQ< zNOg^N>Fp?Nt)WIoqxWEy<9loNam3?vp!gz)t3(DTUv-~e^*#A}^pTWY4_DlkFU zb_EAPMOpKWOXJpmo%TN)Hy=+6^1D~-%Y` z-~;}HcbHvVkp;IbjV6qU)Lc4{OLGbgEZckY;1ktxF$o=c@!@EYnC!LZG>38WmKOnQ zjsA7Sdaa&ZIw|;RawC>tGHrP_aO%B#T=wV%znG4$N}v4`AM~c)%SH(eBXsC2gCf%4 zR1ed2d1QZ>rI59h&iFp2tdd*}kjpssV&kaC6l8tp*S{Z2+1o<9@B4jd{2ZPS7S`k& z82)NRBuG;G#tA7s+J$NP3Y8@4%@;pi4%UCFd6001cRQg;|Kt&=)BbgEs%E+uM4Jq? zYbEY{jK+~T&UN}PO9&Mm4ATjtQ1R$vN65mS*TAQd*@hjX$vlG;O}Hp>>M+M7 z3P&9PaW7qW>GCcVdEuA~aigEMS-mYFNaDsPcl!T&L-ort#};h4X6$2O2TSKxZ|1!JOXP|MHov>LfxJx&WaL1}zl zTG_=L%nPu|8cmQrpdQ)fHha7X<9pU(amHCKKf>Nwfl5vC`U5KRm+oDEz0iCGe73o~ zzBIAvvuPnKR$@`y=$Y%xc%SiJ_VSm0B)_mN`?7w^r5=rD!O5ua2%omS9}A*Hxw(re z=pXW1nMyhFRp*8=IY#UC^(WnX`YJtw*4*aERjI9UamF^Pz-l+E2Y&w3UYUmf;y12e z2MTu_vV~fJ+U>1gHAp-SF=T4W$bkKhBxDL_i>~)5C$)HZ?12?KtKCOc5peTV{cx9w z#N*BFP(*JyG{XOs(PFQ%PP~a{CJvn3t?Z;su>uOA^1E5d zk6G@#yazC0bJ*U=r{#O14a&vx8<@d(&NVihGm*i>Yi=swscvpb5w#_+AL#5a&pT<; z(@v#BpwF|>m`nQDeVa1eq$2?h+57+pgo6(zl#ne{Fu;W^Upj#cvMrdX02 zrV)}x?FeyZi!Q9o?%mcII)A-~yOf=jCH3qiyQloe%?DwOrUe~<6jhnYQ#_6n$?&gN z4X&|tFljTwW~Gwx^-z7VTluTVjQEqiND7o{8)Ta80D1SU*EJ>c z7PwxTa-$D1uZ)c|*D8w!U)Wdp%joS8y9>VWIp+e|b2a#M8?j|(RdrAjM*u%>x1;u6 zdA~XyY|Xc_vj8>9^&F(5@k+|vxya@08m?Zt)3q(f+y6-;5+172T|KGTwqa_uq4cOMH zx3G#rGjvw>T$E-Dz|rwgzn=pNxa1&e7iTTQe*#|oyO_x5X#F2Cjjb_}&zXV0KBN62 zP7G|BG+SaK7eD6({yO;bkA@ZpVUK?q(#YERZLLq`?QeUDLR1(cK_RlcOAai>N@F#( zD8`LW@o$GKc@}UZ%FZI*=RY9N)K?%yOJAq1(tmqpyz+aALwk-0_6Tk- zIaX4GaFs!!-S5$FW~W*T`AeH4u(Ougy>0ESGLcI+Mdu=;Ou`=s4zp=Lwy4f2Q0u#0 z12Qj*P#5vv9~X7ypjNzD3e+-?1^3X$w$6Pv#qVOerSsR!Jj&hzWrO&S`ti>OzWFXA z%1m01T6AIzS`wF$cRVaSdupKu*H*T?tizFxcQT;H-RKg9k3q?pLj~D<)3s7uh;3kU2Mk1q z+NFEEltyJqa%{@jL_;4Y#6e;KgWnTCe2OC<$d24?J6#X~*4t3KC#c+P)_#0nRl|_j z>fo8y zEu0|X_3ExIV7v5R0E^EMyyEUrhY>>YQGt4MuWQiqnnp_^tpT*^>cJ|Bwk_BGz*+B{ zS$?-1lG66Tdc{H6+x}){YD@3*1j+o|gR3dYIps%$c(2Ust}7kzKw9g{Nec^)^TAKb zDteBa2_4%cjG;l`@yJ#-^F0{u%(svcWGTYJ&F?3C%bC`Y@hkTTZL`l2n~k~}6qG?O zxKJ{8G&;r<2S4?*&CU?!Sk`0+v+oKt5hteSRz7VzQu+ve+a3O`MgSLnf=N-2DB~2& z0Z&XtT6mYv1kxj=6@V%rkw<$%u}0{5`s>5w1)5ZERqN6>S8)0vltwj*R#ww_S1@>j z00M;+&@hnV$_}xjP=K$GouH%wU&RxdkLbd&byF)h+Vv)6d zp83n{)`YK~mfJ+RIwn*)ISIhMV|r4;V6EPtCKXZ6#9evIgLN&g{k-PofqCfEr)}FV zi3~KYU4jH{X6cTj6*~H-5pBI7V;t!WLp_X2Q}H}~mp(bAX_E%d%IFt?^>4hqXaDG7 zW6InI>rQO{Xk4L>1Qlc8BE6=mXPB>JItyJF%y}&M{j{I1x0+I0chPaP_o0}m_Xj6= zKlQIq3jh4qZ~k;b!2c<-@r8O@so+%nmZq=$N#XIvpNwYzB~Qg?=`=aphY@N_A%{pww%4gbIxqsv<7tyCSat`460E^0=^WPw^I1wvc5OZl&Zn=wTyWcd zd2mTK>u5>wlLKG3a_q{_QMk>QDK<4)FX-Q3$<~R-=Lg>_S2pF81?NcC&a}V^yH6sH zhYZMnpE-IM@lK+x+y0QQY80g!G5gBK7E9x{9pp{7!b+dV!<13XxUqV3UAL@D0Xpf-<&;e6k!X$yd8MgF zqlZpDyZoWj8!me2y*6M>nz3&qe6xVZlVS|5za2!%Aip`0UOR+`aHa7p5pgm1=8C_0 zcRVz5AR{O5`X&7x&1V)Z=k=s9Iwa1Jth2SX=0`u%)EiFu-z$Z9PmJTx+ya6dN$&Np zNN&QT=iD7W`RjwNk5l0+Qf7F~^`u>HRB6i@>c}_*eK6W`A}}FPG_;$vW=QL+`K21Z z*17j^LbFE20E=oE$Z1A~thLCThX`Yo$kA%IOLM&DsY=PuA%r{J1y8nPyP3&I{;QiN zg0bj%j>NU?8uv!&VUKSv z#N$S6P@KNGw>7Or`AN+QkD!frtl$oYlc=MX+;b*3?nm<@ zuOjJp8m|wqZeKMDxF^Elrl1-udQfCK&qf)sP~`Q>)rl;^(lMsj92t`<(67tDjpjEC zo2RwiZcnt6xqRM00HwRvjondNj5>?*DX@%xkPgD&Tymt(kz*DoL`L|xW)Jdhw)b2D z+ez8kSi#Th93-6nSr|)^0~oRQYlD2$lnALN>SBR^@;?wxqD&{QRLR5M&y_^|Q_wdusk zh=?{@u138g_X4Er^g0{r)@ZEwW2CV#$Fl^bePrOMp9;FARj_g_!c=C>85tf+zjW#O z2`cNEPf0-%-m(}+LQQ+QDv^U=z7OksLDU%qY)2XvO>kX?w4!WC5@Cutr_KV()%W>!4~Oj>Kx^#@*QlAiyXIPM zIKQM1%z>$gYPax&yJE)ND%mUFv7&BUX!@oSS_jVUaT)57>EW*p)0Zy5JQkvFlic+C zyOgyN3sBJW8)6aR2lGBA(vzRI`GGEo1I2&udLg#c`oimLXxhh_m8rH5Z69!F#N(nb9xR`+IuPPt-J-y;i|5T*dYglAUwnAh@gDV$lZHg9wtj3=lcfIk30r&qz_dddp_4UDbzy8w`W4|R;f8+0==S5W^w41FiLZ(D|r^IoOoHdu8M9sIa-@f=) z1m~Z=FmwKmOMl)$B;I|qa=$!Frj(7kt$oGkPy*eib~e9-2d?a;5pgYnNlD+Ugu4l> zr$^ClWzI}72P%BLsd&}o;+F>YfA?`^NS_o;G@T8h;mR`6B#8u(AL^@gIE)Vgy0~;RB&?V*nl} zUXpuScIc=l=~+&)=`flLhKfanPqiGF)&0^v`j5Rv_%n9I=}+tRPyexPed*f{*i8Mf zE_|HsuJt`-365<$T7tok6K(fyL|rGvsJ@~E+Lsg*5CMr^j=OtHRv=a~ooO~(^8jCM z5n}o;C*<_^icu0^_xX7ff5#!UP*q0#d*z08WK-^pH=PZ2>W%t=rxa35Pf`VEgH9PA zDj>rZ!l1gW|I??XFWsg8ooin>eQo4+JaR7ziqecR2I28%8%y0= zSk{6n*YUXtSzBx@fiW8{sb3l$5t@FlHvmzr)pdABq&1v9u@?@$O5~9A`o_6Vbts)6 z_0l+$ck-=t>)vrb6W&IL6>V97^j?0)p^FOW@9jQ-9nn$Ol#Sg?olvdQC{8YvgZyXfYdh9y@TXEGWoOPK5}4{|)lC zZA6ZJTB;}ew#S+#Gl1|x%?tW|?({xO{TvWOwn&z5@~FqlP0%YcG9-r z-1J*&I22h+s1 zzR$2>`Jnzop*NHzX1hGD_Oc@m?>!Gq#Pr|ghz<@FN|CHvGmG(r(pfK`po1y<6$crf zD~1oQUY~#GxBJngVn)y8is5#x`k`Yj%5Ab6g*;S0!%2ulXD(O<6pS~6xwQUra%n{1 zw0UKg6cl@za?d$PP3H(yBl2W*_BcgeTL5qv(=390B)RWxH`p%a;F+Z>|-ccw~} zTH{brt&_ELGWRYhzJgzDAob4GIJors#_T`}lmbundIXfHPUo{ZLxTO*!mDT*;!CV2 zw=B_3K|dD3NWDlNJ=rsPqfMeNSRy&LC^rc+fFiP3SUKP8xO@Xlcyt{4RRj~P3qn^19Bx`^Euot;+nrZ2 zwW>Tn!2H4+uHZL`W19h1& z^;9TBZ4(2T{vd0858b-t{tt7^zg`qffxF}oQ zI!vYaV{J;iBqEu|=?hQ|n8=Nd_0PvsW|UrgNiqo2Jd}QG-hw-kT_e~49hm+3(jO^- zAAm(U+^{U7M9JxFe&>OSvgWtdIo*WYDE$u7E>|T_1x+Rt@pM%t`6WHSkSmt0q|FqF z-A0n%bnd~J{^F?QyPg7V6gh*;ucu*XffD_t}KH&RYYE>Q0>m*u}e|g64&_>OcT=`ILFh z1N8AY=(9;JW+fc}Xnh*?QBljPB+~BNOCAqP*bL2Y9V4-C1nyoHzYB##V@dh`p**GSw{(v`9?{D^dh*~A&Jcb)>yQcGFJ#dMq%1=xoT?h`4;T%X;Y}A| zUY3T{XLY$SJj*H4LmP)%v`fRi5$~=(DVK4V*uAu?N~zvyjK6AN9p|gz8Fy?xR>mIx zY!=5zIBLGj&%EO|v_UMZ06te$by$ONMM@ter$JsltUAvAeLA0Wu6!;Z4Xw$tUucpK zRfy2^?g&^0-wnToK1ryxf?~!GZJa#k;o#w4H>^s1`0nI##*tvLEs@QABK63{IAuZ) zn04F|XVKhOPIo$2dhF3_$&D$sCoJ1132!|sP97@FZznu-nNcdP>E(hSA$>p+Sg08f*r*Pc`bllo7s3%?g}`ZVr#^PPI?Vx#RoTMp5& zJ*znvn(m5F5!DpO*5E7A60&DJWpsOQ4bzFwX^IaTg62>Kb^Sk5BSD}l7TLQD=iXM1 zb5-FMgW)|QG=M%n;-jhFyDpDlWu0gPnQM968Ha{CDR(1$4XTolUrTY6Zokl%&15HA zWBQfC-Eg?$1yw}dlJLgrpx3eO(J6y84pdmJ*cr0sT?yAJjp7j?t8L-4_a>V);>O6R z#lZb`I}G@aGj&&vJciRJX#LA`36n!S>~ZG8tUj^Oo5st53Rxu|4GhCRVG zdv(dmAX|1NeIBQzm6c>h3)ZR+Py_rJ{HgU6?3hPq-X7Q}P$DUMt27M?UZ#gVbgu3zt z5oIUMy@0&+dVMk@|M?0Z6n}ln2mmd8vJ=8q0rKqqF@TYA9on-xlgCTm6-@f>F5Sspa zEBl}M*FVQKx19CGL|$<}&ITaV2ROwl&ouk??#6rdpSAF6r}w_?@`Pbfx8^3j$OSmY zTf-pVJh)ErnJ%l5sp_dp)lZ5p(sbxVcTJSPGX z2)!^=%!H5n>1H__;^7%?m3cWC@FA_0?(Po9Ve@2$-dsA9R9$VtpoSYJh*e`F*!$s9 z`ft%g#(}tSZux^nx}p-)-A3v5?7D+}LjJb*S*dfh#+!hi1@>$W!)EB_-iMBQa@^5q z|1lf3abO!#W5<)6=bPy+>FPL=8!-wbseaPJ;4CW2H|4rTkla#OLENWpg}lk-v>tY1 z-|W3o=O(Ce-eOLEgr?YrRi> zlz6HE5T%rs0uRo0UP{944G^lura>k331UT?Eoi+hXun3WqRkex-WIf7plgJb0WIIft$sqv_cSm}-S_dySRR3y7#E1%F!Q9!lA zNyg-@VT`iN)NtOV5A_X+&&Drq>CjeG;h)<%wWXh*C3^n$KSV~$dC9X=6-j|T$66V# z&{553HG-(ZF4tp3X0 z>I(H@EXzM{2PCvrpfyc*4-&&W6Marqm+RGfo+*?n)lf*+Zk;=FsVP70)+&eN%ylj@ zPwWL4*%FIPH|MWC%k4F}D0pX=hqx4VTfRY9h3T^GlTq)OBSvo^mAduC&X^Xo+%-)$ zVoh^x`=x(tp8l_0-})H(KnPxWu?aWDyiy4Zn<-tt3^vE)oc{5mj)dBE*w@0?HLmQyax+)s~1rA$d;e~q*-Mn z|GKW3o%E+|t1tb|p(ypg{JBqm`gAV@aea9XS>`;Nam1g6y>?*(sezEKhWl)H!<9YK z%VSC%hNbIoNX1-4ecJYDPt+rEFSVDre&Sv>dM@6E?-OT2y>EM$WXSvqo^|J6!GAZH zhk(>t))cu%Z9j5*EXv4Gj^lZyy-Fq_zuiJ&hlILn%boKFByW2q&SOnYj{m7M|L;Hi z`9_HWRk(zi)uU}6^giIs|NZ&{xFK0lWi{pPbWcSi$h!-{uwNf5eKwv-CFYSd*{T=Q zTjhIKqX;^f+&(NRnNK{58lN9#Xjn z#hl|~i?|oMTVSqxQhHi)2u4npYh}k3^ga&uN`^{?YSJ~Ml8~1NhKw7^Yx_lj3xhwF za@r0A12mG3z-24u6xX{DOwFGyfR%Vl@z&#}SN!3i+fj_U*!!JYLN&7Bt1|4O$w9pN z^M#ik9juw|ckd1MwwE*ki`@!SXZ@HzY`#LASTH~^s*hE39$Pp>a4)W@W`eVZSi2q( z8^u_ph)BC20|PUX>R_q)YACbaJYo@gXE*3q%pMh`7nw(Y(A_W-apHqcwiwIu-;Yt! zc-k$}1uo1L;JF7h-mQ`jvc;mavCPYdpm?n2hVw?06OfY4(H%Uw&`OzKxdUx|CyulmLzWjI z3Qq(-uhKnC`koRb6=y9BX=I(ihNO>WNO_-M`|_VsLxadcEJyEXU|WtYh+pjF)My1B zf5FLVFG0_YqMAEgpm;HeqD*)w{^(^iHa+ecbMP}i#3Pw+6RDTMxcGm(go3WXzYl_p=5vMlB$XK@;?i@xE-hlk4OsjhCBles|W;}3*rEh?GUpt z1>jQ7*l)FMc=QRK#>C8sD1?e!tHv3!P>l{D=;<%$u9KuK_$K4e?uu~ITq&QxblUh# zm|owG$^J(98#OLrvbiaq;(2D*h))yf`;tqpxd_S5-Dh>JWIPQ0!qhHBSS}M1Zo@Pm z4!l98-3ZLSYMUofr_CApX0e-BdZ)!sL;dZdNFnzKspZGCk`ii*v_L`sP=>PEvABU7 zx7&QiEB9o{R|#h}cAq^e$H`bH`*4@|t_!eT6t4t3H77UUv%n@@{Z}x{=1STF128SL z#{f8mMF)<_Jf~1Z84}mvFfgK39XAzE{BEKEla@n%@@j>Y?~RjMiq+N4S9Iei>@D6& zA%xNjHQYwD`VQwT2IjmYZWy^lb?!#LH(=hJfr8@P4ZU23(pr#IpM= zXR<;gSt&`aS9!+{s4z*27vb0fweP>zRCmQQt_NSH91)nPv~DZL9P3l38sy(}Ue;&c z?tKKxua@WQNkpf%pt-#E9r0|mWol^&n&MK?Rp9@l`IF%Re2c=;s$L#+ATPaYEy_no z; z;GVZ`4W$GGlu*RhTg8~%+#D?CM82n18k5pOM}zys=6$!4SH5a8+C63TlgE|d=7qkY zU-z}=LBU9k?iqaGKvuBL*CO;wGG%o}$!-C&GtX&Q)hm>BBat)G~g|Pydiw{H%cZ5An#*H~)~s{1-XQ|F)Ci zoSQ(Ze>j~rl*KB&S4)HsB{h2%-e-;gPtwg_KoFDh-8LXOO>1tj21@Jj0uoQHo(Z$Q z_s5d@#dlww9m;GU+xv91@=`kn(F`p0xhb7wULYj&C=yWeji0tfK;CM*WgggQ-ri+Q z{RO=mb$nom;A&bw`)a)^fbN_`RcMCYX*p^ZFQw>P-N*8kkhMSilNS^q>ZdtiA^I@qu0U*>j(RO+O}=7G%GHU<}7FnRm)*X z?}_asUW$tI@u^~|^oj|k5XWaNnL2w>=F4$aRZw|;eu1n2X#B{~Pde-Pdo#b%ipyP& z3f}it+Egl{`hAQ7G*EO|FfyVr1a*%5d_9e^Zh>oTh>}R{8jH|@!RN*rnT8BG zb5`dr+B9vvD8AdORcQ*Sp_Bm3(J&2v&mQc#V^uctE(r~{cXU8q$A~j07n$v02~l=d zW)Yr4KVH95gCG2~ZAA@!5Ok^z25O&ZpMIM5+&K$*6tJ>1q|2ck9GO5Ij_9DH2pM{uw(cAx*i?tX|6 zNXm2}Xlr?U>OzXI0e#IP;!A0Z#QjG83SQ~_g46XcO6UUWT5c_pv0!z7SSYWJe~L_j0=5tq_?`Y%mNf>}#0t<8eS^WzU5xqK+tob%@n!is@d>TT)mZV2}GdbqW60v>b zy;yy}gNE8PkIDD^x}M++dG?F(z=z{dJzts+jjc3~N0A`OND0HjqAXT4oM`6dHl9*} z$_2`+oQ^fZsq0_P4C!zD$N|O$U90pzR(alNRfrK%oaw67=08818J^N_C$vs@xjdaL znmW4cN~}X-L7wh&-=?xe{)m(|`|f-tyr^1i(RnG+O7H(fyc;LXihwJ!W6d-qz0 z@82z_*hClfyXMG4L+}DeGrZ~SKJ{W!5-wJ^R?*G$Xq`F{dhAW5fIdIxv;uI@pg;)0QEBb~-aBp*^>meO(DfXqD2XT?dA+fI zJ=NAT4t=Bv_&V~)n0kA&`tXI;02K9PfXsdDVs(}m8m>@hu^4UR6`OCEq5Sbuy#A$o zWO06g~zZehiDaJ2;En(5rWb#`l z0lu0;Y(qVxa+H1beb^qXST!i8-^|K~!|RwiX^)kBTgpBek78EA-rLA@^UTbBv=cv^ zf3qRAGj*OCkK)hC@w-67WHd_%bjw%;fWZ(j{DFO!;7CD&5pG>hl8X_K53)Opd~_#q zH^K?2VTd*^Y8!txyO?S)q*3QKPNn4+7f@4KkqSNP`z>sCt)h1=b4yB{#l)sJ6Gnj1 z7&|~@m0i}ul9zR!^G_FdT6owPn@y(SA=b?fj*bpW%=!viPKPD(fLuF09Evr+Hr9M4 zwTv0GryS6C(qe3mge>J$mlMwvaI{m8RwA;jSJ}736orH*khpAyeG6PLTWFt7wW{EXv4owrpm_Tg0fVNjSMUSY`$GVz?Jr?*R^<1)29 z6rEc)wKpX5f;ShmIC>eEi#p!mU?n!r)c!7$$JU8pnY_p*rGUknU;0`a{T)>gr}%Mp zxET$ovIc1dRoA0@AoJ+@>iQ$9WVJo@9og-fz?2Rv11SW z{8ftT;952{0r#BFPV9I^f2fEj4buaAA$Qs@Jj-*++1<|4XL3u!iWlaZqZDuZ^q(~* zjPWE*E^>w!9Gg+kW*9KDAa1)jO2NSBI4H)8!VILUEPx*!ECqdzu$yY8hWpF)D&~z^ zdjqT7M_Ynj+9eQ@aCC5*wyx6aM6Zbxf+#K8Xka_WETr2rpDR~fyj{47@>j34{j?4A zXp9%JmX)B4i}9DSk^pq;%fNP?nSrZg7-?mJ-Ig;X=IQkJkp&HMc_FwT)mPRxN2c9v zlo#hnk5Qy9xrJOR=B=4AY0A)r(0R=ekc4s>(KAI&79vP2&@`^uTQ=UMRH|A6)Np_) z49mK?(m6}4xp}&v!s&uRkNd3jtpa*xEl9h?P_B4Dq(Sc#8S`D!d?cA9OhuB6d>aleI}P*$Xv8{fWm;kjrqPMqy6%A=W!=~kA+4NJWC<>yKbDhu}Z{cy8{!G;TJMaD$?xTvQz)w>OlE{_Qj3a|Iv$g(Dk3Tq2Oni9uV2-d^LD!iFnQ+th~e zxV}Hm^;Mu`?YYeyZSJ8WpQ$^;T!2VJSIj~|_~f^8c9@7Dk$0$3#Ma}L)T&p*0WDJB z0b<3m*MMW6W3MAxw^7YWW5gO8=}NQn;o#)YK6Rgy_VpcSbhK=E6UX>#Y?`Rr($UaXfnqe=%?ApkR zc1sme)&JAobw)Lnu50F^j@^S8REjzR0trQ0q=@LyyMcrNp(q5wgn&{+nmEqrNDwf= z&_N6kAR)nkNeoqoPACc_kkE!Mgd%+e!JAq4u61A#rjy0#0RfS|pHIQG~$*z8Qa zcU@%^Ney+hPBuWoa5N~&nBQK^AwD;<2~bt?+^4l-q{PfRRxbiYrDCiii>IVw~QV_;DgBxOSB^Z7G%1pnH)-7 zGEKz?uSv(4$JSpvnloIyU`Pb5W*+KGOH_S<_jwY!P~qg6eUTtnIfhb2A4-kQQa(6emgX+y@0nnH!;J|sVL74Y;sclVb=+d-Mkf6azwDb6=%j6;NmHV z(1qDuQ@WPpHX}e}L-B7+*BxB#_*7jJE~34wp|62o9l_4dG=Ld6J-!*%9hb2DBRbxE zCKE(#9!}#2Qy!&Z1-VE)4s|7@b06Lk2UG|++#m~3ksqRk4)i^mXo1V=Tp z3BVdEJ7Xm`G-Bspm`JR~Yv{}9B=|ueuCB3V$%$U5WheMg4ETO7FS>mHPhsFgay04T zclvTQPo?keK9i$>`Sy~wltMte-xE>(dwvhRRB@{FaftKCsHD;hWa=C)2%os6PHzc` zv{6v=i8{kfK3GU4_kzW3#&P!Oi_FFUiNQOYXkw`h}HhU|o?&ZFT1( zN6!;8f|ld31F|}VkS@a)_Y~bkDUCCcmc0h{mW3{Ts~1WduU~oAxJm<|NTlepx&wfW zoL%N0t_B=tQ+*^Py!IWJAsCSx^WYh$zlmqv*dk(%W%r6Ru2%t*WNNJWv|DMa(6?RA zmRvKRg1F;dt0*D}=JamK-kp6)`XGQkANuj^M3j;;hn#(@ZhC>v>m4fDPb$tUB8E0U zqU0Cgyz!PBE=fz_c?wXNp95SWzCV0Q!YJZ`I0QE^$7)6JzH%_T(V_;vPb}A6n57qO4WdkTD0W1Gd3YjNWs|v;A<>tk57F7^CRXIK6S%LcL(I{Ev=9_`B}Ff zZ^oegjJ(JKI_90NDFo8J&J!jc0a&h?hwO6*cP%ue#Gw>@ z#$4XB1PyzLB^OhNZ&&w&$?^Z;rp3VwVawu=^8sPPYu1(%Kk*V=Z@Y|zI}yVP-%d*w zcSPG2p<%5Lxds_|dqkvUH)<8=1FPFg_)lV{Eyl|)L9?2cJWqUL_8?``<%5j|o?|=2 zHDH$)WV>fj?P!IbKkFt;m%Lv5(7ka!ZCyp}G26Jns#|b*6Y)umWB9B})TQ@Iq0ZVV zS;NTD@pp7I3gB@b?O3DB|*B>Od30922>HCh>%6uQc; z6IXOM12HwXzh^iG$X4)ix+*HmmFizzD{~aQQ%LEXnTc{=hEYwI%#JLvS_`mJE%M(8 z2~rkD29RnC{Pk?JbSNLBHRy%)^lQXX%dNcp3bT1@tW=vTaC#J&$RIx)vc&RA*GyD` zU)?~olh?f~ucjDq0&Reu5&1d8k|S*E5+5n+2cQVs`G>?Hr?>DYA~N&hW_=sLK-4Cv z%5_z3SSR^l$y4R3H^xdY9bJL*4h7FxUC^>b(q8>3;sa_ItfgJ1#aY@nSnHe~^*sa* zxiOM?sFd>3vA5H4Gpmc+#Ue@nSTW{EQMle7q1j3<%IfVa3S=0_Sn@`okwfK|N6JT2 zK6H^&TGa6AD`(r=MX?EB#}ARKhM741QYZEn3X@{EGyWLkl22pF3#m+u2K=gpiEZ<# z_~O>7(8hXEhD6qcr_~$`w*7O|&thVAzOD}pe|Xd7UWQJ>b;I4?1*|O0B9m#fGLiwx z|AQvExL1eHDvr>tb{{BuNKSuzmQC_NzPf2xgT_M*WPDQ+-2|zc)eg?|stuQ6>O$}m z+AXJ7A0jCzLPeTL)VR?CN^cRcB&i2QV@^kHH@E{!MIP*7SU?m}rN}@oYEcISV&N(-enD6M;V+zn~V9 z-!RW&li2xOhbU!V65$E6;vw!ad$}zUZ{8wvtT%L}GMIO}18ywI(9cgJZ0B%1o*=__ zqfv9PBa2icv+w1Q8sYwpD|y5FXYFY=z57M6(Gb}<-m8Pa!HR>?Q&$2W)ld$$kZIa} zdTMecCJud!F7OmapR-bN)-|={?Ez+I8m$g%iB# zQHJGQrIuQwB3o^cJ=ISnG&`*QIspj8X(eQDC7xYG;V{Hbo;&`7Ur$Pc&8;eQNm;E5 z%Uf!fNz$NZd{$c`&0zW|@Xf%q=kPRuo+lzb33D>kKRp{k7ICCZ*PJ|yQq|bg-^VTg znnLHbrz071ctJrS2C2=FpH>j5>w=%f?;A4>MU6YGl`5K<5XDX!ml%An*ezI)P2JhU zHzgdM+oyQJ)j}LJmO@+MQ&rJGDdSZHOx9@taN19$Qg0mTpS?Sw@hZHI!S|MgR5!>_@dUf(ykp)emi;)f$eTG8kcTVhh}bfPaUT4(=hYF6s_wj3 zCyj#l+;TRgl%wtJv-%|5wG-s*62{hqX2hwGfOC5z<2iDY;~`#(+Lh83u5PXO(Hj8y z$?4-=Y?ZJsD|VSQ_JCiuV}PKYeyzf#EUc`TIlRkQ_SVA8LF;;NCxwF#fPGITa}o&) z-ofE-rx)&it+8lSxCIO#QHKv#dQ!o29#0ICTKJGY@Dk$)$TDkeJh8~s%0m*K$!56s zOx8n_JXRV_?mMaNtlZO%tW$r<{3@)oSb17V29}1Djku=<*5m}YL+MoQ86Q7=FUd%l zC~#eS@uKX(G>?jm$i1^ax?N+)8e3(0%wY5wV8bwcq`5(_g`8{$%e+%15r=jSjlNl8 z`6&9mkwj53$FAJ%)`hCKY$iyZ#9x9>3T~kf+{5nM8HO>1@175zh}P9eNSwW9i7xh? z!65`nn}Ck-_?4osme(;?GUfPcqcmYcFKN$(_R^OgBh)(eh@FaV>gTRwu|%7g{ck#9 z_Q_^&X(L*6K)N&yMbT&NL6kB9&%y@7rexc-+V1ruS&Fp5sJeN~WaA*YAWoSwjhaNL zA$69%ZHcBYSbc-sy&iL1dN?olV93~+#G1uRKlDBQ(O}WHs1j;-gPbYNMuvt4`D%CV z$lwP>DHOTN$!9d+rjG=fhScECPFAX?w1Ic!x2dx`#Is-%$4E)}xs6rK2Q@h)Rcs<{ zgI=Jmzl^8pCdNN&gI5xrL)q<_ncI)W^t{JP=OdIPVUO4&9{{87B85iKi*;Glm=y%g z?DSoVI8#vl?ZP)XL*%Tg2iNiw(&wQY{#cZt)_qatcDtsA@nQ)PC_7Wr@7wC7dbsI8 z#Z$>8{ZkqC*H=!zba3#b2A8VHIM&cgQi{VN!Sy|UXEp> ziAm6R&B^ZQf++8T{P?HkFEad^WFj{8s{t`t?M07cN)`@n&x6RmpTvd?22%WEKjvjx z*@=LqapcP&Bok;DQ;}m`Q4#0S)qFL9JXOuv!bxMvweNrE zG!>x=9tLi*fO#o7AD*8)V5X)zH=$V8bl7ksM!Hah*EU)`tQ%9T3vJ)X$g1`zTjBHD zQ!jPJQUaXKaFaB9Yo1_?;Fxm%lh~jXji@{M)bX{AqlhsnSn4mow-TM0h8#HhBhamX zr!0)GCLn^q`X(TP3_P^RGfjHc0cAd1pqePs5m(L+-%_fkyx*(l^F89Mz?zSq$oH9~ zy|nMKqUm;3cX44H4qsrWJ&qfw&KfGpsW-8#Kaq*PF~9_U6670?(5!2b|s45#y|UT4F5IYDp+qQ5MicN?M2?<_6}Eir@I zqnqh>&%X5hM&yix%mE4A6~8*;2Ec38gAO4sLmollymfX2yTc2eCDK%ZX{t&!6STQ0Du#( z*q_8~Upl+Z0M#PLPL~!ekzI!!ATmIecV0)TCC%gkF6-xt zRq);j_lGol)R5I2)Wo7ruUkZd{+{%#_C2?Z(MV=?Lpz-iVZAI4fw!PxVfq(_=*u2P zqZ_9Xu7d-71D%sBmWZu7Df!dcu)X3v%Pz`9Oz`)8E>5+hM@D&*7n zoB~|CBwt61?zW~ILASg61&8zHKiLTXaCbYtkUaQ8%l_hTlJphbKi4?>7hR5g)Y2w> zq;>VyKH4(0!7JTMNL`nS$Gma2k<$T_D@s?=wLlVEH?;9&ppr34U!M^{wm+kn*lQs8 z9y$IYo25=}ey&Ph*vZ;ZJ@SOP(QoG~dI`7I$MR3~mK7{@G_`cMQ{K>D%(rsXa>fvs zf?vA%&rsAHYa;i?<@${0;}$EFYLtK>2^|Rw-joO+W8Q2H_$(pG>*t#$Hg-~ySCBe7 z45$vB*}oUO7gd1j`Kf+-yl=u;6Nw78pdfnUTg1kJF`W9b^W|UNvV&mQosUODb;3)q zB7*+L98f+(m29Ov2Xivv%b!9%nU6KeB2ThC6NK&}605*{u*rCZA2E(xh|}DWUc#|_ zUZgqH`I2oSG8t@M=ugnDP;!`^kT%nXl%NV7S9ofq)f0zMzDWmp#|rSna#89f1-a$j zuO-p0+pRyKT^{0D{H{-8>q-jaMgH&;QuNA>ccg)H@%4ZZh=+V-cRf>j7mw*O>TDrS zI}isvY1>rE2(X^_UkN$~f=KTuzpu7lwdU;lqqCnCL^sK}0k~xLfT0??_}03qTh*)k zxP_}4vZpAyMn#IIfGeFPz_3&1+4oSla|*aG0W(7Um5r(6P4lcK5ptZzfgb7R>ATZl zghhtzwn#B-*$X9tFIKfb|8-~VfgdpTgU6;FAD*W?`wegBAKp2Ca>K8HBZadw3(Mk$ zTij65(f8nKIi3{+f?=_H%C}_ixK# z`;<*y-ZffA zS^-`^%uzn1fW{PmO?+&j-;rdNPP&vnO0vy7I%0_0_Qn3v@@rn)Un|Og)*g0IcDN!$ zj+1j$XU*N~hpqT6^CX2P4UzEo@}t)~9uL%UEX>&vm0x; z_T9fTlf$KdopSSMDS;*$ELrz_ama*`6EVSJtOg?I7o{~rVS!j<{L+x@QuC~1-}Gt85X)nAipYtXzs znSMPlW^&oiw72yUny2IHITUDaM4R6Dpnr4*dcM!RjkgKLlSZg(2XzTuZ!I79box|Y z@{-j8hL{_@sc!BCMn!0_9?K|;iD~vmC!Kii)B_t1;t2ze;J~Oj)J(caQ?O$iJw$_= zGdxxx@IK1yM%%+*4gN4q`c8)^Kyp^Qb`bupNcHOara|S$R~?_k!aRO+M*NZe@h7$U zV#~m+K0A7I0hh&Ow;DY!g+0G2igj-uOp?4;dKw9!(Q2W6DzwWV6s*VvxL>-u9&Sd_EaiA>KaxA_`X>Yq!O1jZI3Aoh=nTi z+Vma_9N#7WBj5kVKqE!Aa;zfbZ7lPWy36Ky-LQDsVQc(@V+t{oNQ{93-Fou1q=9=C zp>=#ivnz``kepGd==96Gu@KyR0(p{11Qs$R?mXAaRA^mtt4MfCM-D_p>yc-pE~qHl zmCY7ky4rLm?*+Gq_o~Fqk}K5swrBa1n6-Y+8c3hb0hbK$y&*Q3=YaxF;|q^xkxX@1 zbVniGbi-1WIbGz>TR(7q$zoqYN^x5h#4s$bc1FX$I`&ezEx12xtjmYBS6HwEt*R>l z6$tb5itoAP2jD97<)P5=$wF``m|Z0p4}n2q&Wm)P+%_6u-V8-wbReMIod$p#q{5)R zu-4*URS__=Dx;BjT9g5#OEon$75`4YS&M9dAjLeH#ZE7SNF-KEAo;<9b06)c?jroG2)-&$uAx&-0KeO?aQ5-c-A+F&o|Jl-z#pUEZp zZmootkVHr!eSCj07avY_xw`qt~0as4h#KoxkGu`jXjxJEL98lj6(RFw<2POT*> zkE3OJ*4dmEBU&(d6LwMj;wpXg=_mrVUG`G+K>gxE%qZY?;V&tI+7g;^+vjDmLx>Y9 z+ltImAt-72^Rk#YuL&C)hoNk=j(x2Ato%ysi=Mx@_yfay-EaI+o7O9WOzf22-i%>$ v2Lj>J@v9!bzV00vk?G^ry#`iDTq`YVU;+*zi2O*HeeUOX^q*Qj^ojqU=p~BU literal 0 HcmV?d00001 diff --git a/dev-docs/add-rtd-submodule.md b/dev-docs/add-rtd-submodule.md new file mode 100644 index 0000000000..8ec06b6838 --- /dev/null +++ b/dev-docs/add-rtd-submodule.md @@ -0,0 +1,280 @@ +--- +layout: page_v2 +title: How to Add a Prebid.js RTD submodule +description: How to Add a Prebid.js RTD submodule +sidebarType: 1 +--- + +# How to Add a Real Time Data Submodule +{:.no_toc} + +Sub-modules interact with the Real-Time Data (RTD) core module to +add data to bid requests or add targeting values for the primary ad server. + + +* TOC +{:toc } + +## Overview +1. RTD module is a generic core module, allowing sub-modules to register and use it to modify bid request/response and set targeting data for the publisher’s ad server. +2. This is done using hooks (with optional auction delay) and events. +3. Publishers will decide which RTD sub-modules they want to use, and can set parameters like timeout, endpoints, etc. +4. Sub-module functions are invoked by the RTD core module. +5. As a rule, sub-modules should delay the auction as little as possible. + +## Architecture + +The RTD module using hooks and event listeners to genrate the flow for the data modificatios. +On each step it calls the submodules to retrive the data. +Here is the flow for how the RTD-core module interacts with its sub-modules: + +![Prebid RTD Architecture Diagram](/assets/images/prebid-rtd-architecture.jpg){: .pb-xlg-img :} + +The activities performed by the RTD-core module are on the left-hand side, while the functions +that can be provided by your RTD sub-module are on the right-hand side. Note that you don't need to implement all of the functions - you'll want to plan out your functionality and develop the appropriate functions. + +## Creating a Sub-Module + +Working with any Prebid project requires using Github. In general, we recommend the same basic workflow for any project: + +1. Fork the appropriate Prebid repository (e.g. [Prebid.js](https://github.com/prebid/Prebid.js)). +2. Create a branch in your fork for your proposed code change. (e.g. feature/exRtdSProvider) +3. Build and test your feature/bug fix in the branch. +4. Open a [pull request](https://help.github.com/en/desktop/contributing-to-projects/creating-a-pull-request) to the appropriate repository's master branch with a good description of the feature/bug fix. +5. If there's something that needs to change on the prebid.org website, follow the above steps for the [website repo](https://github.com/prebid/prebid.github.io). + +{: .alert.alert-warning :} +RTD sub-modules are subject to a number of specific technical rules. Please become familiar +with the [module rules](/dev-docs/module-rules.html) that apply globally and to Real Time Data modules in particular. + +### Step 1: Add a markdown file describing the sub-module + +Create a markdown file under `modules` with the name of the module suffixed with 'RtdProvider', e.g., `exRtdProvider.md` + +Example markdown file: +{% highlight text %} +# Overview + +Module Name: Ex Rtd Provider +Module Type: Rtd Provider +Maintainer: prebid@example.com + +# Description + +RTD provider for Example.com. Contact prebid@example.com for information. + +{% endhighlight %} + +### Step 2: Build the Module + +Now create a javascript file under `modules` with the name of the module suffixed with 'RtdProvider', e.g., `exRtdProvider.js` + +#### The Sub-Module object + +In order to let RTD-core know where to find the functions in your sub-module, create an object called `submoduleObj` that contains key values: + +{: .table .table-bordered .table-striped } +| param name | type | Scope | Description | Params | +| :------------ | :------------ | :------ | :------ | :------ | +| name | string | required | must match the name provided by the publisher in the on-page config | n/a | +| init | function | required | defines the function that does any auction-level initialization required | config, userConsent | +| getTargetingData | function | optional | defines a function that provides ad server targeting data to RTD-core | adUnitArray, config, userConsent | +| getBidRequestData | function | optional | defines a function that provides ad server targeting data to RTD-core | reqBidsConfigObj, callback, config, userConsent | +| onAuctionInitEvent | function | optional | listens to the AUCTION_INIT event and calls a sub-module function that lets it inspect and/or update the auction | auctionDetails, config, userConsent | +| onAuctionEndEvent | function |optional | listens to the AUCTION_END event and calls a sub-module function that lets it know when auction is done | auctionDetails, config, userConsent | +| onBidResponseEvent | function |optional | listens to the BID_RESPONSE event and calls a sub-module function that lets it know when a bid response has been collected | bidResponse, config, userConsent | + +For example: +{% highlight text %} +export const subModuleObj = { + name: 'ExampleRTDModule', + init: init, + getTargetingData: sendDataToModule +}; +{% endhighlight %} + +#### Register the submodule + +Register submodule to RTD-core: + +{% highlight text %} +submodule('realTimeData', subModuleObject); +{% endhighlight %} + +#### User Consent + +Several of the interfaces get a `userConsent` object. It's an object that carries these attributes: +- [gdpr](/dev-docs/modules/consentManagement.html#bidder-adapter-gdpr-integration) - GDPR +- [usp](/dev-docs/modules/consentManagementUsp.html#bidder-adapter-us-privacy-integration) - US Privacy (aka CCPA) +- [coppa](/dev-docs/publisher-api-reference.html#setConfig-coppa) - the Child Online Privacy Protection Act + +These are provided so you can do the right thing with respect to regulations. The only privacy requirement imposed by the RTD-core is that sub-modules make make use of the StorageManager instead of attempting to access cookies or localstorage directly. + +#### The init() function +1. This function receives module configuration and userConsent parameters +2. If the function returns `false`, the submodule will be ignored. + +See the [Building the Request](/dev-docs/bidder-adaptor.html#building-the-request) section of the Bid Adapter documentation for more details about GDPR and USP. + +#### getTargetingData + +This is the function that will allow RTD sub-modules to merge ad server targeting data into the auction. It's called at the AUCTION_END event for each auction. + +1. RTD-core will call this function with an array of adUnits, config, and userConsent as parameters +2. Your sub-module should respond with per-adslot data that should be set as key values on the ad server targeting in this format: +{% highlight text %} +{ + "slotA":{ + "p":0.56, // ad server targeting variable (e.g. p) for slotA is 0.56 + }, + "slotB":{ + "p":0.824, // ad server targeting variable (e.g. p) for slotB is 0.824 + } +} +{% endhighlight %} + +**Code Example** + +{% highlight text %} +/** @type {RtdSubmodule} */ +export const subModuleObj = { + name: 'ExampleRTDModule', + init: init, + getTargetingData: returnTargetingData +}; + +function init(config, userConsent) { + // do init stuff + if (initfailed) return false; + return true; +} + +function returnTargetingData(adUnits, config, userConsent) { + // do stuff + return data; +} + +submodule('realTimeData', subModuleObj); +{% endhighlight %} + +#### getBidRequestData + +This is the function that will allow RTD sub-modules to modify the AdUnit object for each auction. It's called as part of the requestBids hook. + +1. RTD-core will call this function with: + - reqBidsConfigObj: the object that's passed to [`pbjs.requestBids`](). Note that several auctions can happen concurrently, so the sub-module must be ready to support this. + - callback: lets RTD-core know which auction the sub-module is done with. + - config: the sub-module's config params provided by the publisher + - userConsent object (see above) +2. Your sub-module may update the reqBidsConfigObj and hit the callback. + +**Code Example** + +{% highlight text %} +/** @type {RtdSubmodule} */ +export const subModuleObj = { + name: 'ExampleRTDModule2', + init: init, + setBidRequestsData: alterBidRequests +}; + +function init(config, userConsent) { + // do init stuff + if (initfailed) return false; + return true; +} + +function alterBidRequests(reqBidsConfigObj, callback, config, userConsent) { + // do stuff + callback(); +} + +submodule('realTimeData', subModuleObj); +{% endhighlight %} + +#### beforeInit +1. Use this function to take action to make sure data will be served as soon as possible (AJAX calls, pixels, etc..) +2. This function is **not** invoked by the RTD module, and should be invoked at the bottom of the submodule. + +#### Using event listeners +1. The RTD-core module listens for 3 events - `AUCTION_INIT`, `AUCTION_END`, and `BID_RESPONSE`. +2. Each time one of the events fires, RTD-core will invoke the corresponding function on each sub-module, allowing the sub-module to make changes to the event object. +3. To use this on your sub-module, define the required functions as noted in the table above and the examples below. + +**Code Example** + +Here is a code example with both mandatory and optional functions: +{% highlight text %} +/** @type {RtdSubmodule} */ +export const subModuleObj = { + name: 'ExampleRTDModule3', + init: init, + onAuctionInitEvent: onAuctionInit, + onAuctionEndEvent: onAuctionEnd, + onBidResponseEvent: onBidResponse +}; + +function onAuctionInit(auctionDetails, config, userConsent) { + // inspect/update auction details +} + +function onAuctionEnd(auctionDetails, config, userConsent) { + // take note of auction end +} + +function onBidResponse(bidResponse, config, userConsent) { + //optionally update bidResponse +} + +function init(config, userConsent) { + // do init stuff + if (initfailed) return false; + return true; +} + +function beforeInit(){ + //take actions to get data as soon as possible + submodule('realTimeData', subModuleObj); +} + +beforeInit(); +{% endhighlight %} + + +### Step 3: Add unit tests + +1. Create a JS file under `test/spec/modules` with the name of the bidder suffixed with 'RtdProvider_spec', e.g., `exRtdProvider_spec.js` + +2. Write great unit tests. See the other `RtdProvider_spec.js` files for examples. + +### Step 4: Submit the code + +Once everything looks good, submit the code, tests, and markdown as a pull request to the [Prebid.js repo](https://github.com/prebid/Prebid.js). + +### Step 5: Website pull request + +1. Create a fork of the [website repo](https://github.com/prebid/prebid.github.io) and a branch for your new adapter. (e.g. feature/exRtdProvider) + +2. Create a new file for your RTD sub-module in dev-docs/modules/ExampleRtdProvider.md. Take a look at the other *RtdProvider.md files in that directory for the important header values. Specifically it requires the following: + + ``` + --- + layout: page_v2 + title: Example Module + description: Useful statement for what this does + page_type: module + module_type: rtd + module_code : example + enable_download : true + sidebarType : 1 + --- + + # Example Module + + [Useful publisher-facing documentation] + ``` +3. Submit the pull request to the prebid.github.io repo. + +### Step 6: Wait for Prebid volunteers to review + +We sometimes get pretty busy, so it can take a couple of weeks for the review process to complete, so while you're waiting, consider [joining Prebid.org](https://prebid.org/membership/) to help us out with code reviews. (!) diff --git a/dev-docs/modules/browsiRtdProvider.md b/dev-docs/modules/browsiRtdProvider.md index e400ef56f9..a41193b68b 100644 --- a/dev-docs/modules/browsiRtdProvider.md +++ b/dev-docs/modules/browsiRtdProvider.md @@ -1,9 +1,11 @@ --- layout: page_v2 title: Browsi Viewability Module +display_name: Browsi Viewability description: Browsi Real Time Viewability +page_type: module +module_type: rtd module_code : browsi -display_name : Browsi enable_download : true sidebarType : 1 --- @@ -55,7 +57,9 @@ Syntax details: {: .table .table-bordered .table-striped } | Name |Type | Description | Notes | | :------------ | :------------ | :------------ |:------------ | -| name | String | Real time data module name | Always 'browsi' | +| name | String | Real time data module name | Always 'browsi' | +| auctionDelay | Number | Max time in ms to delay the auction | Optional. Default to 0 | +| timeout | Number | timeout in ms (only if auctionDealy is 0) | Optional. Default to 1000 | | params | Object | | | | params.siteKey |String |Site key| | | params.pubKey |String |Publisher key| | @@ -64,6 +68,7 @@ Syntax details: + ## Output For each ad slot, the module returns expected viewability prediction in a JSON format. diff --git a/dev-docs/modules/index.md b/dev-docs/modules/index.md index dd5b4bf164..f236b85fe1 100644 --- a/dev-docs/modules/index.md +++ b/dev-docs/modules/index.md @@ -35,11 +35,32 @@ If you are looking for bidder adapter parameters, see [Bidders' Params]({{site.b | [**Google Ad Manager Express**](/dev-docs/modules/dfp_express.html) | A simplified installation mechanism for publishers that have Google Publisher Tag (GPT) ad calls in their pages. | | [**Supply Chain Object**](/dev-docs/modules/schain.html) | Validates and makes the Supply Object available to bidders | | [**User ID**](/dev-docs/modules/userId.html) | Sub-modules are available to support a range of identification approaches: Criteo RTUS, DigiTrust, ID5 Universal ID, IdentityLink, PubCommon ID, Unified ID and LiveIntent ID. | -| [**Browsi Viewability**]({{site.baseurl}}/dev-docs/modules/browsiRtdProvider.html) | Browsi provider for real time data module. | | [**Advanced Size Mapping**](/dev-docs/modules/sizeMappingV2.html) | Display Responsive AdUnits in demanding page environments. | | [**Price Floors Module**](/dev-docs/modules/floors.html) | Configure and enforce minimum bids. | | [**GPT Pre-Auction Module**](/dev-docs/modules/gpt-pre-auction.html) | Adds a PB Ad Slot and matching GAM ad unit name to each ad unit's first-party data before bid requests are sent to the adapters. | +## Real-Time Data Providers + +{% assign module_pages = site.pages | where: "page_type", "module" | where: "module_type", "rtd" %} + + + + + + + + + +{% for page in module_pages %} + {% if page.enable_download == false %}{% continue %}{% endif %} + + + + +{% endfor %} + +
ModuleDescription
{{page.title}}{{page.description}}
+ ## Video Modules {: .table .table-bordered .table-striped } diff --git a/download.md b/download.md index 030ddb1a4e..4ba2e7a5fe 100644 --- a/download.md +++ b/download.md @@ -496,9 +496,7 @@ Prebid.js is open source software that is offered for free as a convenience. Whi

Modules

{% for page in module_pages %} - {% if page.enable_download == false %} - {% continue %} - {% endif %} + {% if page.enable_download == false %}{% continue %}{% endif %}
From 33cea4386025047621e49f725c94946519d2877c Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 21 Oct 2020 18:48:37 -0400 Subject: [PATCH 037/149] pubprovided filename change (#2426) --- download.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/download.md b/download.md index 4ba2e7a5fe..3c8462b0a0 100644 --- a/download.md +++ b/download.md @@ -546,7 +546,7 @@ Prebid.js is open source software that is offered for free as a convenience. Whi
- +
From 76881f6953d066a2ef6e696a4f5939eb21467312 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 22 Oct 2020 19:47:25 -0400 Subject: [PATCH 038/149] PBS targeting FAQ (#2445) * PBS targeting FAQ * PBS winning bid FAQ --- faq/prebid-server-faq.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/faq/prebid-server-faq.md b/faq/prebid-server-faq.md index 326b22aa11..edb521be8f 100644 --- a/faq/prebid-server-faq.md +++ b/faq/prebid-server-faq.md @@ -106,3 +106,39 @@ If a bidder adapter supplies 'nurl' in the bidResponse object, there are two pat If a bidder adapter supplies 'nurl' in the bidResponse object instead of 'adm', this URL will be treated as the location of the VAST XML. + +## How does ad server targeting work in Prebid Server? + +For OpenRTB responses, Prebid Server is always in "send all bids" mode -- it will return the top bid on each requested imp from each bidder. + +It will return ad server targeting in seatbid.bid.ext.prebid.targeting depending on the input scenario: + +- if request.ext.prebid.includewinner:true and this bid was declared the "winner" by Prebid Server, then seatbid.bid.ext.prebid.targeting will contain hb_pb, hb_size, and hb_bidder. If the bid was cached, there will also be hb_uuid and/or hb_cache_id +- if request.ext.prebid.includebidderkeys:true, seatbid.bid.ext.prebid.targeting will contain hb_pb_BIDDER, hb_size_BIDDER, and hb_bidder_BIDDER. If the bid was cached, there will also be hb_uuid_BIDDER and/or hb_cache_id_BIDDER. + +The AMP endpoint is somewhat different because it doesn't receive the openrtb - just the targeting. PBS basically resolves the OpenRTB, and then merges all the seatbid.bid.ext.prebid.targeting sections. + +## How does Prebid Server determine the winner of a given impression? + +**Decision 1**: best bid from each bidder on each impression + +Prebid Server returns one bid from each bidder for each impression object. If there +are multiple bids from a given bidder for a given imp[], here how it chooses: + +- highest ranked Programmatic Guaranteed bid (PBS-Java only) +- highest CPM deal (only when the ext.targeting.preferdeals is specified) +- highest CPM +- random tiebreaker + +**Decision 2**: which bidder for each imp[] object gets the hb_pb, hb_size, and hb_bidder targeting values + +This is only done when ext.prebid.targeting is specified. +This is most important for AMP, but other clients (e.g. app) may rely on Prebid Server +choosing the "winner" header bid. That decision is made with the same process as the +first decision: + +- highest ranked Programmatic Guaranteed bid (PBS-Java only) +- highest CPM deal (only when the ext.targeting.preferdeals is specified) +- highest CPM +- random tiebreaker + From 11637179c4eee19b02c9d14b1318f8ee4bfaa90a Mon Sep 17 00:00:00 2001 From: OneTagDevOps <38786435+OneTagDevOps@users.noreply.github.com> Date: Fri, 23 Oct 2020 15:48:08 +0200 Subject: [PATCH 039/149] Onetag tcf2 support. (#2439) * OneTag bidder params * gdpr support onetag * Add support to CCPA * added strings around pubId param * Adds tcf2 support Co-authored-by: valentino Co-authored-by: bretg Co-authored-by: francesco --- dev-docs/bidders/onetag.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev-docs/bidders/onetag.md b/dev-docs/bidders/onetag.md index c4b951ce46..edf1e64a26 100644 --- a/dev-docs/bidders/onetag.md +++ b/dev-docs/bidders/onetag.md @@ -6,6 +6,8 @@ pbjs: true biddercode: onetag media_types: banner, video gdpr_supported: true +tcf2_supported: true +gvl_id: 241 usp_supported: true userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId --- From 813519d863063f1ef884462031bebe436cbc74be Mon Sep 17 00:00:00 2001 From: Mike Chowla Date: Fri, 23 Oct 2020 07:32:20 -0700 Subject: [PATCH 040/149] Fix pubProvidedId example (#2446) --- dev-docs/modules/userId.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index bb6c224f42..81b2c0f332 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -909,7 +909,7 @@ The PubProvided Id module allows publishers to set and pass a first party user i pbjs.setConfig({ userSync: { userIds: [{ - name: "publisherProvided", + name: "pubProvidedId", params: { eidsFunction: getIdsFn // any function that exists in the page } From 50a39d3337cd49533220d540a988628e476ebf32 Mon Sep 17 00:00:00 2001 From: Konstantin <73297044+kulakov-adtelligent@users.noreply.github.com> Date: Fri, 23 Oct 2020 17:34:02 +0300 Subject: [PATCH 041/149] Update the documentation of the Adtarget adapter (#2448) --- dev-docs/bidders/adtarget.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/adtarget.md b/dev-docs/bidders/adtarget.md index f4d0ae40d9..89eb584def 100644 --- a/dev-docs/bidders/adtarget.md +++ b/dev-docs/bidders/adtarget.md @@ -23,7 +23,7 @@ To use the Adtarget bidder you will need an aid from an exchange account on [htt {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |-------|----------|---------------------------------|----------|-----------| -| `aid` | required | The source ID from Adtarget platform. | `331133` | `integer` | +| `aid` | required | The source ID from Adtarget platform. | `529814` | `integer` | # Description @@ -63,7 +63,7 @@ Provides a solution for accessing Video demand and display demand from Adtarget bids: [{ bidder: 'adtarget', params: { - aid: 350975 + aid: 529814 } }] } From a45558fbc319d62c41360b211e72b755000dac36 Mon Sep 17 00:00:00 2001 From: Mansi Nahar Date: Mon, 26 Oct 2020 09:36:37 -0400 Subject: [PATCH 042/149] Update docs to reflect that native asset's ID field is optional (#2449) --- prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md index 0119d9e878..8ce287f697 100644 --- a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md +++ b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md @@ -352,7 +352,7 @@ for each Bidder by using the `/cookie_sync` endpoint, and calling the URLs that #### Native Request -For each native request, the `assets` object's `id` field must not be defined. Prebid Server will set this automatically, using the index of the asset in the array as the ID. +For each native request, the `assets` object's `id` field is optional and if not defined, Prebid Server will set this automatically, using the index of the asset in the array as the ID. #### Bidder Aliases From 3ff36f18b1bdc2cc081ec4ec4a28a5d8fd25f75d Mon Sep 17 00:00:00 2001 From: jdwieland8282 Date: Mon, 26 Oct 2020 15:55:13 -0600 Subject: [PATCH 043/149] Update userId.md (#2453) * Update userId.md adding enable sharedid example * fixed the params, wordsmithing Co-authored-by: bretg --- dev-docs/modules/userId.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index 81b2c0f332..6e3b3a3e5d 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -852,6 +852,17 @@ Add it to your Prebid.js package with: {: .alert.alert-info :} gulp build --modules=pubCommonIdSystem +#### PubCommon ID Configuration + +In addition to the parameters documented above in the Basic Configuration section the following PubCommon specific configuration is available: + +{: .table .table-bordered .table-striped } +| Param under userSync.userIds[] | Scope | Type | Description | Example | +| --- | --- | --- | --- | --- | +| params | Optional | Object | Details for PubCommon ID. | | +| params.enableSharedId | Optional | Boolean | Invokes [SharedID](/dev-docs/modules/userId.html#shared-id-user-id-submodule) as well as setting PubCommon ID. Defaults to `false` in Prebid.js 4.x. Will default to `true` in Prebid.js 5.0. | `true` | + + #### PubCommon ID Examples 1) Publisher supports PubCommonID and first party domain cookie storage @@ -888,9 +899,12 @@ pbjs.setConfig({ } },{ name: "pubCommonId", + params: { + enableSharedId: true // optionally enable Prebid sharedID + }, storage: { type: "cookie", - name: "_pubcid", // create a cookie with this name + name: "_pubcid", // create a cookie with this name expires: 180 } }], @@ -899,6 +913,10 @@ pbjs.setConfig({ }); {% endhighlight %} +{: .alert.alert-info :} +When enableSharedId is true, the browser will make an additional call to id.sharedid.org/usync. Calling to Shareid.org sets a user id in a 3rd party cookie under the sharedid.org domain. Anyone setting this additional identity should reference Sharedid.orgs optout policy at https://sharedid.org/. Prebid.js 5.0 will enable the enableSharedId option by default. + + ### PubProvided ID The PubProvided Id module allows publishers to set and pass a first party user id into the bid stream. This module has several unique characteristics: From fb7cc77003980ee3137766780376170ba7266a36 Mon Sep 17 00:00:00 2001 From: Konstantin <73297044+kulakov-adtelligent@users.noreply.github.com> Date: Tue, 27 Oct 2020 20:47:42 +0200 Subject: [PATCH 044/149] Add appaloosa doc (#2444) * add documentation for appaloosa adapter * add documentation for appaloosa adapter * add documentation for appaloosa adapter * add documentation for appaloosa adapter * update adtarget.md * fix --- dev-docs/bidders/appaloosa.md | 124 ++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 dev-docs/bidders/appaloosa.md diff --git a/dev-docs/bidders/appaloosa.md b/dev-docs/bidders/appaloosa.md new file mode 100644 index 0000000000..3992898f39 --- /dev/null +++ b/dev-docs/bidders/appaloosa.md @@ -0,0 +1,124 @@ +--- +layout: bidder +title: Appaloosa +description: Prebid Appaloosa Bidder Adapter +biddercode: appaloosa +aliasCode: adtelligent +media_types: video,banner +gdpr_supported: true +userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId +schain_supported: true +coppa_supported: true +usp_supported: true +tcf2_supported: true +safeframes_ok: true +prebid_member: true +pbjs: true +pbs: false +--- + +### Bid params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------|----------|---------------------------------|----------|-----------| +| `aid` | required | The source ID from Appaloosa. | `529814` | `integer` | + +### Description +Get access to multiple demand partners across Appaloosa AdExchange and maximize your yield with Appaloosa header bidding adapter. + +Appaloosa header bidding adapter connects with Appaloosa demand sources in order to fetch bids. +This adapter provides a solution for accessing Video demand and display demand. + +Appaloosa now supports adpod. + +### Test Parameters +``` + var adUnits = [ + + // Video instream adUnit + { + code: 'test-div', + mediaTypes: { + video: { + context: 'instream', + playerSize: [640, 480] + } + }, + bids: [{ + bidder: 'appaloosa', + params: { + aid: 472386 + } + }] + }, + + // Video outstream adUnit + { + code: 'test-div', + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 480] + } + }, + bids: [{ + bidder: 'appaloosa', + params: { + aid: 472386 + } + }] + }, + + // Video ADPOD adUnit + { + code: 'test-div', + sizes: [[640, 480]], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480] + } + }, + bids: [{ + bidder: 'appaloosa', + params: { + aid: 472386 + } + }] + }, + + // Banner adUnit + { + code: 'test-div', + mediaTypes:{ + banner:{ + sizes: [[300, 250]] + } + } + bids: [{ + bidder: 'appaloosa', + params: { + aid: 529814 + } + }] + } + ]; +``` + +### Additional Configuration + +It is possible to configure requests to be split into chunks so as to have fewer bid requests in a single http request +(default value is 10). + +``` + pbjs.setBidderConfig({ + config: { + appaloosa: { + chunkSize: 1 // makes 1 http request per 1 adunit configured + } + } + }); +``` + +Appaloosa is an aliased bidder for Adtelligent \ No newline at end of file From 87d840ff5f1f8985785af4b45d0558f94faf6788 Mon Sep 17 00:00:00 2001 From: John Rosendahl Date: Tue, 27 Oct 2020 12:48:15 -0600 Subject: [PATCH 045/149] Sovrn: updated docs (#2407) * updated docs * remove identityLink --- dev-docs/bidders/sovrn.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/sovrn.md b/dev-docs/bidders/sovrn.md index 45d6a7041f..4f93125bf1 100644 --- a/dev-docs/bidders/sovrn.md +++ b/dev-docs/bidders/sovrn.md @@ -6,10 +6,12 @@ pbjs: true pbs: true biddercode: sovrn gdpr_supported: true +tcf2_supported: true usp_supported: true -userIds: unifiedId +userIds: britepoolId, criteo, id5Id, liveIntentId, netId, parrableId, pubCommonId, sharedId, unifiedId prebid_member: true schain_supported: true +gvl_id: 13 --- ### Bid Params From 9ff3c14b4c98c6cceee95be8feef383e6d8bf843 Mon Sep 17 00:00:00 2001 From: AcuityAdsIntegrations <72594990+AcuityAdsIntegrations@users.noreply.github.com> Date: Tue, 27 Oct 2020 20:56:05 +0200 Subject: [PATCH 046/149] init AcuityAdsAdapter documentation (#2433) * init AcuityAdsAdapter documentation * remove prebid js options Co-authored-by: Kushneryk Pavlo --- dev-docs/bidders/acuityads.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 dev-docs/bidders/acuityads.md diff --git a/dev-docs/bidders/acuityads.md b/dev-docs/bidders/acuityads.md new file mode 100644 index 0000000000..ba49994b7f --- /dev/null +++ b/dev-docs/bidders/acuityads.md @@ -0,0 +1,29 @@ +--- +layout: bidder +title: AcuityAds +description: Prebid AcuityAds Bidder Adaptor +biddercode: acuityads +gdpr_supported: true +tcf2_supported: true +usp_supported: true +coppa_supported: true +schain_supported: true +userId: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId +media_types: banner, video, native +safeframes_ok: true +bidder_supports_deals: true +pbjs: false +pbs: true +--- + +### Note: + +The Example Bidding adapter requires setup before beginning. Please contact us at rafi.babler@acuityads.com + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|-----------------------|-----------|-----------| +| `host` | required | Region id | `'ep1'` | `string` | +| `accountid` | required | Endpoint id | `'hash'` | `string` | From 73043e7855878739144470fec5984fcd0167f8ac Mon Sep 17 00:00:00 2001 From: Vladimir Fedoseev Date: Wed, 28 Oct 2020 21:23:51 +0300 Subject: [PATCH 047/149] Add Reconciliation RTD Module docs (#2395) * Add Reconciliation RTD Module docs * Fix Reconciliation RTD Module docs * Add Reconciliation RTD Module contact info --- dev-docs/modules/reconciliationRtdProvider.md | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 dev-docs/modules/reconciliationRtdProvider.md diff --git a/dev-docs/modules/reconciliationRtdProvider.md b/dev-docs/modules/reconciliationRtdProvider.md new file mode 100644 index 0000000000..ddf6c4ee87 --- /dev/null +++ b/dev-docs/modules/reconciliationRtdProvider.md @@ -0,0 +1,86 @@ +--- +layout: page_v2 +title: Reconciliation SDK Module +description: Reconciliation Real Time Data Module +page_type: module +module_type: rtd +module_code: reconciliation +display_name: Reconciliation +enable_download: true +sidebarType: 1 +--- + +# Reconciliation SDK Module +{:.no_toc} + +* TOC +{:toc} + +## Overview + +The purpose of Reconciliation Real Time Data Provider is to allow publishers to collect supply chain structure information and vendor-specific impression IDs from ad creative suppliers. It reports the data to the Reconciliation Service, allowing publishers, advertisers and other supply chain participants to match and reconcile ad server, SSP, DSP and verification system log file records. +Reconciliation SDK was created as part of TAG DLT initiative ([https://www.tagtoday.net/pressreleases/dlt_9_7_2020](https://www.tagtoday.net/pressreleases/dlt_9_7_2020)). +TAG recently led a twelve-month, cross-industry pilot in the UK that evaluated the feasibility and benefits of using Distributed Ledger Technology (DLT) to increase trust and transparency in digital advertising. + +More information: https://www.tagtoday.net/brand-safety#dltnetwork +Contact us: consultation@tagtoday.net + +Implementation works like this: + +1) Build the Reconciliation module into the Prebid.js package with: + +``` +gulp build --modules=reconciliationRtdProvider&... +``` + +2) Use `setConfig` to pass parameters to module + +## Configuration + +This module is configured as part of the `realTimeData.dataProviders` object: + +``` + pbjs.setConfig({ + "realTimeData": { + dataProviders:[{ + name: "reconciliation", + params: { + publisherMemberId: "test_prebid_publisher", + allowAccess: true, //optional - false by default + } + }] + } + }); +``` + +Syntax details: + +{: .table .table-bordered .table-striped } +| Name |Type | Description | Notes | +| :------------ | :------------ | :------------ |:------------ | +| name | String | Real time data module name | Always 'reconciliation' | +| params | Object | | | +| params.publisherMemberId |String |Unique Publisher ID| | +| params.allowAccess |Boolean |Share AdUnit IDs with advertiser Reconciliation Tags| Optional. Default to `false`| + + + +## Output + +For each ad slot, the module returns custom targeting values used to match impressions (publisher-adserver-advertiser). +The module also tracks AdUnit initialization and impressions ('impression' message is sent by the Reconciliation Tag in ad markup). + +Custom targetings example: +``` +{ + "slotA":{ + "RSDK_AUID": "/slotA-Unit", + "RSDK_ADID": "b5bbc103-00e9-499d-9637-bdba05b65427" + }, + "slotB":{ + "RSDK_AUID": "/slotB-Unit", + "RSDK_ADID": "325da95e-e37d-45fa-a46f-8ff91168b121" + } +} +``` + From 89916ca3fb5c405d1995e4f262348be531c8e85b Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Wed, 28 Oct 2020 18:06:22 -0400 Subject: [PATCH 048/149] [AD-963] Add documentation for JW Player RTD Provider (#2427) * adds docs for JW Player RTD Provider * moves auctionDelay to rtd * explains fileds required for async reqs * updates docs for fpd * making syntax consistent * reverts bid interface * added transition for bid adapters Co-authored-by: karimJWP Co-authored-by: bretg --- dev-docs/modules/jwplayerRtdProvider.md | 146 ++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 dev-docs/modules/jwplayerRtdProvider.md diff --git a/dev-docs/modules/jwplayerRtdProvider.md b/dev-docs/modules/jwplayerRtdProvider.md new file mode 100644 index 0000000000..bb34f2b6c1 --- /dev/null +++ b/dev-docs/modules/jwplayerRtdProvider.md @@ -0,0 +1,146 @@ +--- +layout: page_v2 +title: JW Player Real Time Data Provider +display_name: JW Player video ad targeting +description: makes JW Player's video ad targeting information accessible to Bid Adapters. +page_type: module +module_type: rtd +module_code : jwplayer +enable_download : true +sidebarType : 1 +--- + +# JW Player RTD Provider +{:.no_toc} + +* TOC +{:toc} + +## Overview + +The purpose of this Real Time Data Provider is to allow publishers to target against their JW Player media without +being forced to integrate with the Player Bidding product. This prebid module makes JW Player's video ad targeting information accessible +to Bid Adapters. + +## Implementation for Publishers: + +1) Compile the JW Player RTD Provider into your Prebid build: + +`gulp build --modules=jwplayerRtdProvider` + +2) Publishers must register JW Player as a Real Time Data provider by using `setConfig` to load a Prebid Config containing a `realTimeData.dataProviders` array: + +```javascript +pbjs.setConfig({ + ..., + realTimeData: { + auctionDelay: 100, + dataProviders: [{ + name: "jwplayer", + waitForIt: true, + params: { + mediaIDs: ['abc', 'def', 'ghi', 'jkl'] + } + }] + } +}); +``` + +3) Optionally, if you would like to prefetch the targeting information for certain media, you must include the media IDs in `params.mediaIDs`, as displayed above. You must also set `waitForIt` to `true` and make sure that a value is set to `realTimeData.auctionDelay`. + +`waitForIt` is required to ensure the auction waits for the prefetching of the relvant targeting information to complete. It signals to Prebid that you allow the module to delay the auction if necessary. +Setting an `auctionDelay` in the `realTimeData` object is required to ensure the auction waits for prefetching to complete. The `auctionDelay` is the max time in ms that the auction will wait for the requested targeting information. + +**Note:** Though prefetch is optional, we highly recommend enabling it to ensure that the targeting information is available before bids are requested. + +**Config Syntax details:** + +{: .table .table-bordered .table-striped } +| Name |Type | Description | Notes | +| :------------ | :------------ | :------------ |:------------ | +| name | String | Real time data module name | Always 'jwplayer' | +| waitForIt | Boolean | Required to ensure that the auction is delayed until prefetch is complete | Optional. Defaults to false | +| params | Object | | | +| params.mediaIDs | Array of Strings | Media Ids for prefetching | Optional | + +4) Include the content's media ID and/or the player's ID in the matching AdUnit's `fpd.context.data.jwTargeting` before calling `addAdUnits`: + +```javascript + const adUnit = { + code: '/19968336/prebid_native_example_1', + ..., + fpd: { + context: { + data: { + jwTargeting: { + // Note: the following Ids are placeholders and should be replaced with your Ids. + playerID: 'abcd', + mediaID: '1234' + } + } + } + } + }; + + pbjs.que.push(function() { + pbjs.addAdUnits([adUnit]); + pbjs.requestBids({...}); + }); +``` +**Note**: You may also include `jwTargeting` information in the prebid config's `fpd.context.data`. Information provided in the adUnit will always supersede the information in the config; use the config to set fallback information or information that applies to all adUnits. + +**AdUnit Syntax details:** + +{: .table .table-bordered .table-striped } +| Name |Type | Description | Notes | +| :------------ | :------------ | :------------ |:------------ | +| fpd.context.data.jwTargeting | Object | | | +| fpd.context.data.jwTargeting.mediaID | String | Media Id of the content associated to the Ad Unit | Optional but highly recommended | +| fpd.context.data.jwTargeting.playerID | String | Id of the JW Player instance which will render the content associated to the Ad Unit | Optional but recommended | + +## Implementation for Bid Adapters: + +This section contains guidelines for bid adapters that are working with JW Player to utilize the additional targeting. + +Those bidders should implement the `buildRequests` function. When it is called, the `bidRequests` param will be an array of bids. +Each bidRequest for which targeting information was found will conform to the following object structure: + +```json +{ + adUnitCode: 'xyz', + bidId: 'abc', + ..., + jwTargeting: { + segments: ['123', '456'], + content: { + id: 'jw_abc123' + } + } +} +``` + +Read the bidRequest.jwTargeting object and pass the values to your endpoint as appropriate. + +**BidRequest Syntax details:** + +{: .table .table-bordered .table-striped } +| Name |Type | Description | Notes | +| :------------ | :------------ | :------------ |:------------ | +| jwTargeting | Object | | | +| jwTargeting.segments | Array of Strings | jwpseg targeting segments | | +| jwTargeting.content | Object | | | +| jwTargeting.content.id | String | Unique identifier for the specific media asset | | + +## Example + +To view an example: + +- in the Prebid repo, run in your cli: + +`gulp serve --modules=jwplayerRtdProvider` + +- in your browser, navigate to: + +`http://localhost:9999/integrationExamples/gpt/jwplayerRtdProvider_example.html` + +**Note:** the mediaIds in the example are placeholder values; replace them with your existing IDs. From b98a0876ca4533ebf7e17eb4c459f4d2c11a4cfe Mon Sep 17 00:00:00 2001 From: Samuel Adu Date: Thu, 29 Oct 2020 14:31:26 +0000 Subject: [PATCH 049/149] Verizon Media user id module documentation (#2368) * Updates to Verizon Media documentation * Add Verizon Media module name to list of options in basic configuration section * Copy update * Remove previously shifed docs for a different provider. * Addressing PR feedback * Add documentation for pixelId parameter * Addressing PR feedback Co-authored-by: slimkrazy --- dev-docs/modules/userId.md | 66 +++++++++++++++++++++++++++++++++++--- download.md | 3 ++ 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index 6e3b3a3e5d..8c03a70047 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -58,7 +58,7 @@ of sub-objects. The table below has the options that are common across ID system {: .table .table-bordered .table-striped } | Param under userSync.userIds[] | Scope | Type | Description | Example | | --- | --- | --- | --- | --- | -| name | Required | String | May be: `"britepoolId"`, `"criteo"`, `"fabrickId"`, `"haloId"`, `"id5id"`, `identityLink`, `"idx"`, `"intentIqId"`, `"liveIntentId"`, `"lotamePanoramaId"`, `"merkleId"`, `"netId"`, `"parrableId"`, `"quantcastId"`, `"pubCommonId"`, `"pubProvidedId"`, `"sharedId"`, `"unifiedId"`, `"zeotapIdPlus"` | `"unifiedId"` | +| name | Required | String | May be: `"britepoolId"`, `"criteo"`, `"fabrickId"`, `"haloId"`, `"id5id"`, `identityLink`, `"idx"`, `"intentIqId"`, `"liveIntentId"`, `"lotamePanoramaId"`, `"merkleId"`, `"netId"`, `"parrableId"`, `"quantcastId"`, `"pubCommonId"`, `"pubProvidedId"`, `"sharedId"`, `"unifiedId"`, `"verizonMediaId"`, `"zeotapIdPlus"` | `"unifiedId"` | | params | Based on User ID sub-module | Object | | | | storage | Optional | Object | The publisher can specify some kind of local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. This is not needed when `value` is specified or the ID system is managing its own storage | | | storage.type | Required | String | Must be either `"cookie"` or `"html5"`. This is where the results of the user ID will be stored. | `"cookie"` | @@ -1169,6 +1169,58 @@ pbjs.setConfig({ }); {% endhighlight %} +### Verizon Media ID + +Verizon Media's ID is a person based ID and doesn't depend on 3rd party cookies. + +Verizon Media's ID is designed to enable ad tech platforms to recognize and match users consistently across the open web. The Verizon Media ID is built on top of Verizon Media's robust and proprietary ID Graph, delivering a higher find rate of audiences on publishers' sites user targeting that respects privacy. + +The Verizon Media ID honors privacy choices from our own [Privacy Dashboard](https://www.verizonmedia.com/policies/us/en/verizonmedia/privacy/dashboard/index.html), as well as global privacy acts. + +Please reach out to VerizonMedia-UIDsupport@verizonmedia.com for assistance with setup. + +Add Verizon Media ID to your Prebid.js package with: + +{: .alert.alert-info :} +gulp build --modules=userId,verizonMediaIdSystem + + +#### Verizon Media ID configuration + +{: .table .table-bordered .table-striped } +| Param under userSync.userIds[] | Scope | Type | Description | Example | +| --- | --- | --- | --- | --- | +| name | Required | String | The name of this module. | `'verizonMediaId'` | +| params | Required | Object | Container of all module params. || +| params.pixelId | Required | Number | The Verizon Media supplied publisher specific pixel Id | `8976` | +| params.he | Required | String | The SHA-256 hashed user email address |`'ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4'`| +| storage | Required | Object | This object defines where and for how long the results of the call to get a user ID will be stored. | | +| storage.type | Required | String | This parameter defines where the resolved user ID will be stored (either `'cookie'` or `'html5'` localstorage).| `'cookie'` | +| storage.name | Required | String | The name of the cookie or html5 localstorage where the resolved user ID will be stored. | `'vmuid'` | +| storage.expires | Recommended | Integer | How long (in days) the user ID information will be stored. The recommended value is `1` | `1` | + +#### Verizon Media ID examples + +``` +pbjs.setConfig({ + userSync: { + userIds: [{ + name: "verizonMediaId", + params: { + pixelId: 8976, + he: "ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4" + }, + storage: { + type: "cookie", + name: "vmuid", + expires: 1 + } + }] + } +}) +``` + + ## Adapters Supporting the User ID Sub-Modules {% assign bidder_pages = site.pages | where: "layout", "bidder" %} @@ -1208,6 +1260,7 @@ Bidders that want to support the User ID module in Prebid.js, need to update the | Quantcast ID | n/a | bidRequest.userId.quantcastId | `"1111"` | | Shared ID | SharedId | bidRequest.userId.sharedid | `{"id":"01EAJWWNEPN3CYMM5N8M5VXY22","third":"01EAJWWNEPN3CYMM5N8M5VXY22"}` | | Unified ID | Trade Desk | bidRequest.userId.tdid | `"1111"` | +| Verizon Media ID | Verizon Media | bidRequest.userId.vmuid | `"72d04af6e07c2eb93e9c584a131f48b6a9b963bcb2736d624e987ff8cf36d472"` | For example, the adapter code might do something like: @@ -1297,8 +1350,7 @@ Bidders that want to support the User ID module in Prebid Server, need to update "third": "01EAJWWNEPN3CYMM5N8M5VXY22" } }] - }, - { + },{ "source": "pub.com", // Publisher must configure their domain here "uids": [{ "id": "01EAJWWNEPN3CYMM5N8M5VXY22", @@ -1307,7 +1359,13 @@ Bidders that want to support the User ID module in Prebid Server, need to update "stype": "dmp" //currently supported values (dmp,ppuid,other) } }] - }] + },{ + "source": "verizonmedia.com", + "uids": [{ + "id": "61cef5656fb05f16d53938069f1684df4b2257e27" + }] + } + ] } } } diff --git a/download.md b/download.md index 3c8462b0a0..9bd7f4f81b 100644 --- a/download.md +++ b/download.md @@ -558,6 +558,9 @@ Prebid.js is open source software that is offered for free as a convenience. Whi
+ +
+
From 2093edda0aa7e38f7cb3e981dab3ab3869f9e631 Mon Sep 17 00:00:00 2001 From: Scott Menzer Date: Thu, 29 Oct 2020 16:59:10 +0100 Subject: [PATCH 050/149] ID5 requires html5 storage with id5id name (#2435) * update id5 docs to require html5 storage * add estimated prebid version and adjust some of the text * the code to require local storage will be released in 4.14.0 not 4.13.0 --- dev-docs/modules/userId.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index 8c03a70047..f987e95189 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -65,7 +65,7 @@ of sub-objects. The table below has the options that are common across ID system | storage.name | Required | String | The name of the cookie or html5 local storage where the user ID will be stored. | `"_unifiedId"` | | storage.expires | Strongly Recommended | Integer | How long (in days) the user ID information will be stored. If this parameter isn't specified, session cookies are used in cookie-mode, and local storage mode will create new IDs on every page. | `365` | | storage.refreshInSeconds | Optional | Integer | The amount of time (in seconds) the user ID should be cached in storage before calling the provider again to retrieve a potentially updated value for their user ID. If set, this value should equate to a time period less than the number of days defined in `storage.expires`. By default the ID will not be refreshed until it expires. -| value | Optional | Object | Used only if the page has a separate mechanism for storing a User ID. The value is an object containing the values to be sent to the adapters. | `{"tdid": "1111", "pubcid": {2222}, "IDP": "IDP-2233", "id5id": "ID5-12345" }` | +| value | Optional | Object | Used only if the page has a separate mechanism for storing a User ID. The value is an object containing the values to be sent to the adapters. | `{"tdid": "1111", "pubcid": {2222}, "IDP": "IDP-2233", "id5id": {"uid": "ID5-12345"}}` | ## User ID Sub-Modules @@ -324,6 +324,9 @@ The following configuration parameters are available: #### ID5 Universal ID Examples +{: .alert.alert-warning :} +**ATTENTION:** As of Prebid.js v4.14.0, ID5 requires `storage.type` to be `"html5"` and `storage.name` to be `"id5id"`. Using other values will display a warning today, but in an upcoming release, it will prevent the ID5 module from loading. This change is to ensure the ID5 module in Prebid.js interoperates properly with the [ID5 API](https://github.com/id5io/id5-api.js) and to reduce the size of publishers' first-party cookies that are sent to their web servers. If you have any questions, please reach out to us at [prebid@id5.io](mailto:prebid@id5.io). + 1) Publisher wants to retrieve the ID5 Universal ID through Prebid.js {% highlight javascript %} @@ -333,16 +336,16 @@ pbjs.setConfig({ name: "id5Id", params: { partner: 173, // change to the Partner Number you received from ID5 - pd: "MT1iNTBjY..." // optional, see param table above for a link to how to generate this string + pd: "MT1iNTBjY..." // optional, see table above for a link to how to generate this }, storage: { - type: "cookie", - name: "id5id.1st", // create a cookie with this name - expires: 90, // cookie lasts for 90 days + type: "html5", // "html5" is the required storage type + name: "id5id", // "id5id" is the required storage name + expires: 90, // storage lasts for 90 days refreshInSeconds: 8*3600 // refresh ID every 8 hours to ensure it's fresh } }], - auctionDelay: 50 // 50ms maximum auction delay + auctionDelay: 50 // 50ms maximum auction delay, applies to all userId modules } }); {% endhighlight %} @@ -985,7 +988,7 @@ In either case, bid adapters will receive the eid values after consent is valida Add it to your Prebid.js package with: -{: .alert.alert-info :} +{: .alert.alert-info :} gulp build --modules=pubProvidedId @@ -1042,7 +1045,7 @@ The Shared ID User Module generates a UUID that can be utilized to improve user #### Building Prebid with Shared Id Support Add it to your Prebid.js package with: -{: .alert.alert-info :} +{: .alert.alert-info :} ex: $ gulp build --modules=sharedIdSystem #### Prebid Params From 88b04367fdeb7a6ea6d6374707c15a0816127557 Mon Sep 17 00:00:00 2001 From: TheMediaGrid <44166371+TheMediaGrid@users.noreply.github.com> Date: Fri, 30 Oct 2020 02:44:36 +0300 Subject: [PATCH 051/149] Update doc for TheMediaGrid Bid Adapter (#2413) * Added doc file for Grid Bid Adapter * update doc for TheMediaGrid Bid Adapter * Added video support in Grid doc file * removing unnecessary front matter * Update doc file for TheMediaGrid Bid Adapter * Added doc file for TheMediaGridNM Bid Adapter * Update doc file for TheMediaGrid Bid Adapter * Update doc file for The Media Grid Bid Adapter * Update THeMediaGrid doc to support TCF 2.0 * Update doc for TheMediaGrid Bid Adapter * Update doc file for TheMediaGrid Bid Adapter Co-authored-by: bretg --- dev-docs/bidders/grid.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/grid.md b/dev-docs/bidders/grid.md index 75410c602b..bc90535d51 100644 --- a/dev-docs/bidders/grid.md +++ b/dev-docs/bidders/grid.md @@ -9,7 +9,7 @@ media_types: banner, video gdpr_supported: true usp_supported: true schain_supported: true -userIds: id5Id, unifiedId, liveIntentId, digitrust +userIds: id5Id, unifiedId, liveIntentId, criteo, identityLink, digitrust tcf2_supported: true --- @@ -21,4 +21,4 @@ tcf2_supported: true |----------------|----------|-------------------------------------------------------------------------------------------------------------|-------------------------------------------|-----------| | `uid` | required | Represents the MediaGrid bidder system Ad Slot ID associated with the respective div id from the site page. | `1` | `integer` | | `keywords` | optional | A set of key-value pairs applied to all ad slots on the page. Values can be empty. | `keywords: { topic: ['stress', 'fear'] }` | `object` | -| `useNewFormat` | optional | Indicates to use the new ad request format | `true` | `boolean` | +| `bidFloor` | optional | Floor of the impression opportunity. If present in the request overrides XML info. | `0.8` | `float` | \ No newline at end of file From 1731e8cf9392b708edf10a7ad7230035e4636d1d Mon Sep 17 00:00:00 2001 From: roygiladi <58809838+roygiladi@users.noreply.github.com> Date: Fri, 30 Oct 2020 01:45:18 +0200 Subject: [PATCH 052/149] add oolo analytics adapter docs (#2416) * Update download.md * Update analytics.md --- download.md | 8 ++++++++ overview/analytics.md | 1 + 2 files changed, 9 insertions(+) diff --git a/download.md b/download.md index 9bd7f4f81b..1c5c134907 100644 --- a/download.md +++ b/download.md @@ -331,6 +331,14 @@ Prebid.js is open source software that is offered for free as a convenience. Whi
+
+
+ +
+
+
Contact vendor| [Website](https://media.net) | | PrebidAnalytics by Roxot | [Paid]( http://prebidanalytics.roxot.com/) | [Website](http://prebidanalytics.roxot.com/) | From 8ae8deafa0baf0977c660521b426f71b7dae0c1a Mon Sep 17 00:00:00 2001 From: bretg Date: Fri, 30 Oct 2020 13:06:44 -0400 Subject: [PATCH 053/149] fixed missing pbjs flag (#2457) --- dev-docs/bidders/craft.md | 1 + dev-docs/bidders/doceree.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/craft.md b/dev-docs/bidders/craft.md index b3c740a8eb..857213225b 100644 --- a/dev-docs/bidders/craft.md +++ b/dev-docs/bidders/craft.md @@ -8,6 +8,7 @@ gdpr_supported: false coppa_supported: false usp_supported: false schain_supported: false +pbjs: true --- ### Bid Params diff --git a/dev-docs/bidders/doceree.md b/dev-docs/bidders/doceree.md index 9e5a62b4a4..a8dcee72b3 100644 --- a/dev-docs/bidders/doceree.md +++ b/dev-docs/bidders/doceree.md @@ -2,7 +2,7 @@ layout: bidder title: Doceree description: Prebid DivReach Bidder Adapter - +pbjs: true biddercode: doceree aliasCode: adbutler media_types: banner @@ -16,4 +16,4 @@ media_types: banner | `accountID` | required | Account ID | `'167283'` | `string` | | `zoneID` | required | Zone ID | `'445501'` | `string` | | `domain` | required | Serving Domain | `'adbserver.doceree.com'` | `string` | -| `extra` | optional | Extra Params | `{tuid: "abcd-1234"}` | `object` | \ No newline at end of file +| `extra` | optional | Extra Params | `{tuid: "abcd-1234"}` | `object` | From 48e2f650e446db353961eca3944466986941b987 Mon Sep 17 00:00:00 2001 From: bretg Date: Mon, 2 Nov 2020 15:58:36 -0500 Subject: [PATCH 054/149] fixing native table (#2460) --- dev-docs/publisher-api-reference.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/publisher-api-reference.md b/dev-docs/publisher-api-reference.md index 4d63511e46..260a7e962c 100644 --- a/dev-docs/publisher-api-reference.md +++ b/dev-docs/publisher-api-reference.md @@ -2119,6 +2119,7 @@ To accomplish this, Prebid does the following: * New targeting replaces original targeting before targeting is flattened. The targeting key names and the associated prefix value filtered by `allowTargetingKeys`: + {: .table .table-bordered .table-striped } | Name | Value | |------------+------------| From 63f18419ea80e87ca405143c41a9ad558574064a Mon Sep 17 00:00:00 2001 From: redaguermas Date: Tue, 3 Nov 2020 11:57:20 -0800 Subject: [PATCH 055/149] Nobid: Support tcf2 and pbs (#2452) * Adde support for CCPA * Added support for TCF2.0 and Prebid server. * Added note about the parameter to ignore for Prebid Server. * Removed all and added the 3 IDs, criteo, unifiedId, id5Id, we tested. Co-authored-by: Reda Guermas --- dev-docs/bidders/nobidBidAdapter.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/nobidBidAdapter.md b/dev-docs/bidders/nobidBidAdapter.md index 245f99075b..ed95d1aad9 100644 --- a/dev-docs/bidders/nobidBidAdapter.md +++ b/dev-docs/bidders/nobidBidAdapter.md @@ -4,12 +4,16 @@ title: Nobid description: Prebid Nobid Bidder Adaptor biddercode: nobid pbjs: true +pbs: true media_types: banner, video gdpr_supported: true +tcf2_supported: true +gvl_id: 816 usp_supported: true schain_supported: true coppa_supported: true -tcf2_supported: true +userId: criteo, unifiedId, id5Id +safeframes_ok: true --- ### Bid Params @@ -19,7 +23,7 @@ tcf2_supported: true |---------------|----------|-------------|---------|----------| | `siteId` | required | siteId is provided by your NoBid account manager(s) | | `integer` | | `placementId` | optional | placementId is provided by your NoBid account manager(s). This parameter allows to report on a specific ad unit | | `integer` | -| `video`| optional | Object containing video targeting parameters. See [Video Object](#nobid-video-object) for details. | `video: { playback_method: ['auto_play_sound_off'] }` | `object`| +| `video`| optional | Object containing video targeting parameters. Note that this parameter is not used in Prebid Server. See [Video Object](#nobid-video-object) for details. | `video: { playback_method: ['auto_play_sound_off'] }` | `object`| ### Note From 759013c22955f485a5cf6057e04eb3f60efebc55 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Tue, 3 Nov 2020 13:41:31 -0800 Subject: [PATCH 056/149] Update PubCommon ID doc to include missing params and sharedid support (#2417) --- dev-docs/modules/userId.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index f987e95189..e94c77e36f 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -862,7 +862,11 @@ In addition to the parameters documented above in the Basic Configuration sectio {: .table .table-bordered .table-striped } | Param under userSync.userIds[] | Scope | Type | Description | Example | | --- | --- | --- | --- | --- | -| params | Optional | Object | Details for PubCommon ID. | | +| name | Required | String | The name of this module. | `'pubCommonId'` | +| params | Optional | Object | Customized parameters | | +| params.create | Optional | Boolean | For publisher server support only. If true, the publisher's server will create the PubCommon ID cookie. Default is true. | `true` | +| params.pixelUrl | Optional | String | For publisher server support only. This is a URL of a pixel for updating cookies' expiration times. Fired after a new ID has been created or an existing ID is being extended. No default. | `'https://example.com/ping'` +| params.extend | Optional | Boolean | If true, the expiration time of the stored IDs will be refreshed during each page load. Default is false. | `false` | | params.enableSharedId | Optional | Boolean | Invokes [SharedID](/dev-docs/modules/userId.html#shared-id-user-id-submodule) as well as setting PubCommon ID. Defaults to `false` in Prebid.js 4.x. Will default to `true` in Prebid.js 5.0. | `true` | From 432f22ef74839059f0a43063d352ea4fbaa29aef Mon Sep 17 00:00:00 2001 From: smartclip-adtech <65160328+smartclip-adtech@users.noreply.github.com> Date: Tue, 3 Nov 2020 22:43:44 +0100 Subject: [PATCH 057/149] Smartx BidAdapter - removed userIds and schain support (#2459) * initial commit * adjustments * adjustments * adjustments * typo, further adjustments * removed userIds and schain support Co-authored-by: Gino --- dev-docs/bidders/smartx.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/smartx.md b/dev-docs/bidders/smartx.md index 6f7eee5c46..56b9e0b465 100644 --- a/dev-docs/bidders/smartx.md +++ b/dev-docs/bidders/smartx.md @@ -6,9 +6,9 @@ biddercode: smartx media_types: no-display, video gdpr_supported: true tcf2_supported: true -userIds: id5Id, pubCommonId +userIds: none prebid_member: true -schain_supported: true +schain_supported: false usp_supported: true safeframes_ok: false pbjs: true From f6046c80614aee18342cd89cee97fc1ea06d6f79 Mon Sep 17 00:00:00 2001 From: Samuel Adu Date: Tue, 3 Nov 2020 21:47:25 +0000 Subject: [PATCH 058/149] Feature/aol bidder vmuid updates (#2463) * Updates to Verizon Media documentation * Add Verizon Media module name to list of options in basic configuration section * Copy update * Remove previously shifed docs for a different provider. * Addressing PR feedback * Add documentation for pixelId parameter * Addressing PR feedback * Document that AOL bidder has VMUID support. Co-authored-by: slimkrazy --- dev-docs/bidders/aol.md | 3 +++ dev-docs/modules/userId.md | 16 ++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/dev-docs/bidders/aol.md b/dev-docs/bidders/aol.md index 7a58c1418d..3d6b745ffc 100644 --- a/dev-docs/bidders/aol.md +++ b/dev-docs/bidders/aol.md @@ -6,7 +6,10 @@ pbjs: true biddercode: aol gdpr_supported: true usp_supported: true +tcf2_supported: true gvl_id: 25 +userIds: verizonMediaId + --- ### Note: diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index e94c77e36f..b87ad3cde9 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -1176,23 +1176,23 @@ pbjs.setConfig({ }); {% endhighlight %} -### Verizon Media ID +### Verizon Media's Unified ID -Verizon Media's ID is a person based ID and doesn't depend on 3rd party cookies. +Verizon Media's Unified ID is a person based ID and doesn't depend on 3rd party cookies. -Verizon Media's ID is designed to enable ad tech platforms to recognize and match users consistently across the open web. The Verizon Media ID is built on top of Verizon Media's robust and proprietary ID Graph, delivering a higher find rate of audiences on publishers' sites user targeting that respects privacy. +Verizon Media's Unified ID is designed to enable ad tech platforms to recognize and match users consistently across the open web. Verizon Media's Unified ID is built on top of Verizon Media's robust and proprietary ID Graph, delivering a higher find rate of audiences on publishers' sites user targeting that respects privacy. -The Verizon Media ID honors privacy choices from our own [Privacy Dashboard](https://www.verizonmedia.com/policies/us/en/verizonmedia/privacy/dashboard/index.html), as well as global privacy acts. +Verizon Media's Unified ID honors privacy choices from our own [Privacy Dashboard](https://www.verizonmedia.com/policies/us/en/verizonmedia/privacy/dashboard/index.html), as well as global privacy acts. Please reach out to VerizonMedia-UIDsupport@verizonmedia.com for assistance with setup. -Add Verizon Media ID to your Prebid.js package with: +Add support for Verizon Media's Unified ID to your Prebid.js package with: {: .alert.alert-info :} gulp build --modules=userId,verizonMediaIdSystem -#### Verizon Media ID configuration +#### Verizon Media's Unified ID configuration {: .table .table-bordered .table-striped } | Param under userSync.userIds[] | Scope | Type | Description | Example | @@ -1206,7 +1206,7 @@ gulp build --modules=userId,verizonMediaIdSystem | storage.name | Required | String | The name of the cookie or html5 localstorage where the resolved user ID will be stored. | `'vmuid'` | | storage.expires | Recommended | Integer | How long (in days) the user ID information will be stored. The recommended value is `1` | `1` | -#### Verizon Media ID examples +#### Verizon Media's Unified ID examples ``` pbjs.setConfig({ @@ -1267,7 +1267,7 @@ Bidders that want to support the User ID module in Prebid.js, need to update the | Quantcast ID | n/a | bidRequest.userId.quantcastId | `"1111"` | | Shared ID | SharedId | bidRequest.userId.sharedid | `{"id":"01EAJWWNEPN3CYMM5N8M5VXY22","third":"01EAJWWNEPN3CYMM5N8M5VXY22"}` | | Unified ID | Trade Desk | bidRequest.userId.tdid | `"1111"` | -| Verizon Media ID | Verizon Media | bidRequest.userId.vmuid | `"72d04af6e07c2eb93e9c584a131f48b6a9b963bcb2736d624e987ff8cf36d472"` | +| Verizon Media's Unified ID | Verizon Media | bidRequest.userId.vmuid | `"72d04af6e07c2eb93e9c584a131f48b6a9b963bcb2736d624e987ff8cf36d472"` | For example, the adapter code might do something like: From 7e7c36e7c801b1a286abd290195120ef222c9f1a Mon Sep 17 00:00:00 2001 From: Rahul Shandilya <67756716+c3p-0@users.noreply.github.com> Date: Wed, 4 Nov 2020 03:17:53 +0530 Subject: [PATCH 059/149] medianet doc update (#2464) --- dev-docs/bidders/medianet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/medianet.md b/dev-docs/bidders/medianet.md index aae788d2ba..4bc48cd24b 100644 --- a/dev-docs/bidders/medianet.md +++ b/dev-docs/bidders/medianet.md @@ -53,7 +53,7 @@ var videoAdUnit = { code: 'video1', mediaTypes: { video: { - context: "outstream", + context: "instream", playerSize: [640, 480] } }, From 261414810eaf344609e09a5a08191d20f69d83db Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 3 Nov 2020 17:51:07 -0500 Subject: [PATCH 060/149] AdOps overview: adding safeframe section (#2466) * AdOps overview: adding safeframe section * wordsmithing --- adops/before-you-start.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/adops/before-you-start.md b/adops/before-you-start.md index 34957c3e6a..6388405a29 100644 --- a/adops/before-you-start.md +++ b/adops/before-you-start.md @@ -100,6 +100,23 @@ For instructions on setting up pre-bid with one set of line items for each bidde {% include alerts/alert_tip.html content=successNote %} +## Safeframes + +[SafeFrames are defined by the IAB](https://www.iab.com/guidelines/safeframe/) as a "managed API-enabled iframe that opens a line of communication between the publisher page and the iframe-contained ad creative." + +When setting up line items in your ad server, you'll need to consider whether to make the creatives safeframes or not. In general, for standard banner and native, safeframes are a good idea. Certain special mediatypes cannot use safeframes. + +### Bidders known to be incompatible with safeframes + +{% assign bidder_pages = site.pages | where: "layout", "bidder" | where: "safeframes_ok", false %} +
    +{% for page in bidder_pages %} +
  • {{ page.title }}
  • +{% endfor %} +
+ +There may be others, please check with bidders directly if you have questions about their support. + ## Work together with your dev team Implementing header bidding requires much more collaboration with your dev team than normal Ad Ops setup. For example: From 34e9c9d18ad3e3a658473ac26a71bfa4160eef6f Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 4 Nov 2020 08:57:07 -0500 Subject: [PATCH 061/149] adding RTD conventions (#2467) --- dev-docs/add-rtd-submodule.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dev-docs/add-rtd-submodule.md b/dev-docs/add-rtd-submodule.md index 8ec06b6838..42625fc4fa 100644 --- a/dev-docs/add-rtd-submodule.md +++ b/dev-docs/add-rtd-submodule.md @@ -166,7 +166,9 @@ This is the function that will allow RTD sub-modules to modify the AdUnit object - callback: lets RTD-core know which auction the sub-module is done with. - config: the sub-module's config params provided by the publisher - userConsent object (see above) -2. Your sub-module may update the reqBidsConfigObj and hit the callback. +2. Your sub-module may update the reqBidsConfigObj and hit the callback. When you update the bidRequest, you must follow one of these conventions: + - Use [First Party Data](/features/firstPartyData.html) conventions, setting AdUnit.fpd.context.data.ATTRIBUTES or AdUnit.fpd.user.data.ATTRIBUTES + - Place your data in bidRequest.realTimeData.RTDPROVIDERCODE.ATTRIBUTES **Code Example** @@ -186,6 +188,7 @@ function init(config, userConsent) { function alterBidRequests(reqBidsConfigObj, callback, config, userConsent) { // do stuff + // put data in AdUnit.fpd.* or realTimeData.RTDPROVIDERCODE.* callback(); } From 2d34301978035c15db7bb5b15ec5d75656d79625 Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 4 Nov 2020 10:08:57 -0500 Subject: [PATCH 062/149] ConsentManagement -- updated defaultGdprScope flag (#2468) --- dev-docs/modules/consentManagement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/modules/consentManagement.md b/dev-docs/modules/consentManagement.md index b95e62f309..31cd13c25c 100644 --- a/dev-docs/modules/consentManagement.md +++ b/dev-docs/modules/consentManagement.md @@ -74,7 +74,7 @@ but we recommend migrating to the new config structure as soon as possible. | gdpr | `Object` | | | | gdpr.cmpApi | `string` | The CMP interface that is in use. Supported values are **'iab'** or **'static'**. Static allows integrations where IAB-formatted consent strings are provided in a non-standard way. Default is `'iab'`. | `'iab'` | | gdpr.timeout | `integer` | Length of time (in milliseconds) to allow the CMP to obtain the GDPR consent string. Default is `10000`. | `10000` | -| gdpr.defaultGdprScope | `boolean` | (TCF v2.0 only) Defines what the `gdprApplies` flag should be when the CMP doesn't respond in time. | `true` | +| gdpr.defaultGdprScope | `boolean` | Defines what the `gdprApplies` flag should be when the CMP doesn't respond in time or the static data doesn't supply. | `true` | | gdpr.allowAuctionWithoutConsent | `boolean` | (TCF v1.1 only) Determines what will happen if obtaining consent information from the CMP fails; either allow the auction to proceed (`true`) or cancel the auction (`false`). Default is `true` | `true` | | gdpr.consentData | `Object` | An object representing the GDPR consent data being passed directly; only used when cmpApi is 'static'. Default is `undefined`. | | | gdpr.consentData.getTCData.tcString | `string` | (TCF v2.0 only) Base64url-encoded TCF v2.0 string with segments. | | From b75ba114abca6236db6d185c2909251cb4214f2b Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 4 Nov 2020 17:24:21 -0500 Subject: [PATCH 063/149] Real Time Data: updating overview, refining instructions (#2469) --- dev-docs/add-rtd-submodule.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/dev-docs/add-rtd-submodule.md b/dev-docs/add-rtd-submodule.md index 42625fc4fa..da085f8187 100644 --- a/dev-docs/add-rtd-submodule.md +++ b/dev-docs/add-rtd-submodule.md @@ -16,16 +16,17 @@ add data to bid requests or add targeting values for the primary ad server. {:toc } ## Overview -1. RTD module is a generic core module, allowing sub-modules to register and use it to modify bid request/response and set targeting data for the publisher’s ad server. -2. This is done using hooks (with optional auction delay) and events. -3. Publishers will decide which RTD sub-modules they want to use, and can set parameters like timeout, endpoints, etc. -4. Sub-module functions are invoked by the RTD core module. -5. As a rule, sub-modules should delay the auction as little as possible. +The point of the Real Time Data (RTD) infrastructure is to make configuration consistent for publishers. Rather than having dozens of different modules with disparate config approaches, being a Real-Time Data sub-module means plugging into a framework +for publishers to control how sub-modules behave. For example, publishers can define how long the auction can be delayed and give some +sub-modules priority over others. + +The RTD infrustruture is a generic module, not useful by itself. Instead, it allows sub-modules to register and modify bid request/response and/or set targeting data for the publisher’s ad server. + +Publishers will decide which RTD sub-modules they want to use, and can set parameters like timeout, endpoints, etc. They will set limits on how long sub-modules are allowed to delay the auction, which will most likely be in the tens of milliseconds. ## Architecture -The RTD module using hooks and event listeners to genrate the flow for the data modificatios. -On each step it calls the submodules to retrive the data. +The RTD-core infrastructure uses hooks and event listeners to call the appropriate sub-modules to retrieve the data. Here is the flow for how the RTD-core module interacts with its sub-modules: ![Prebid RTD Architecture Diagram](/assets/images/prebid-rtd-architecture.jpg){: .pb-xlg-img :} @@ -35,6 +36,11 @@ that can be provided by your RTD sub-module are on the right-hand side. Note tha ## Creating a Sub-Module +When you create a Real-Time Data sub-module, you will be operating under the umbrella of the Real-Time Data core module. Here are the services core provides: +- your sub-module will be initialized as soon as pbjs.setConfig({realTimeData}) is called. If you can initialize at the time of code load, that can be done at the bottom of your javascript file. +- whenever any of your functions is called, it will be passed the config params provided by the publisher. As a result, you should not call getConfig(). +- your functions will also be passed all available privacy information. As a result, you do not need to query to get GDPR, US Privacy, or any other consent parameters. + Working with any Prebid project requires using Github. In general, we recommend the same basic workflow for any project: 1. Fork the appropriate Prebid repository (e.g. [Prebid.js](https://github.com/prebid/Prebid.js)). From 37033338231f49d525f821deef98b243a9cc4b59 Mon Sep 17 00:00:00 2001 From: Viacheslav Chimishuk Date: Thu, 5 Nov 2020 19:04:14 +0200 Subject: [PATCH 064/149] Add client parameter documentation. (#2422) --- dev-docs/bidders/adoppler.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/adoppler.md b/dev-docs/bidders/adoppler.md index 15fcf99fb2..ed306762b6 100644 --- a/dev-docs/bidders/adoppler.md +++ b/dev-docs/bidders/adoppler.md @@ -12,3 +12,4 @@ biddercode: adoppler | Name | Scope | Description | Example | Type | |------------|----------|------------------------|---------|----------| | adunit | required | AdUnit to bid against | 'test' | string | +| client | optional | Client name | 'ads' | string | From b617ebd1a9afe55e8cb4a629b91e778f50cfbc98 Mon Sep 17 00:00:00 2001 From: Nick Jacob Date: Thu, 5 Nov 2020 17:19:39 -0500 Subject: [PATCH 065/149] indicate prebid server adapter and gvl ID (#2437) The PBS adapter was updated to align with PBJS. We're all good. --- dev-docs/bidders/amx-rtb.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev-docs/bidders/amx-rtb.md b/dev-docs/bidders/amx-rtb.md index 15ed4082e2..b0e1716a52 100644 --- a/dev-docs/bidders/amx-rtb.md +++ b/dev-docs/bidders/amx-rtb.md @@ -13,6 +13,8 @@ biddercode: amx safeframes_ok: true media_types: banner, video pbjs: true +pbs: true +gvl_id: 737 --- ### Bid Params From e954222185c65bb6d6a719af3598455ed9deec83 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 5 Nov 2020 16:28:47 -0600 Subject: [PATCH 066/149] Add support for Publisher Common ID Module in Sharethrough bid adapter documentation (#2432) - Related feature PR [here](placeholder) Story: [#175125639](https://www.pivotaltracker.com/story/show/175125639) --- dev-docs/bidders/sharethrough.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/sharethrough.md b/dev-docs/bidders/sharethrough.md index da77260c49..9c7293b22a 100644 --- a/dev-docs/bidders/sharethrough.md +++ b/dev-docs/bidders/sharethrough.md @@ -8,7 +8,7 @@ media_types : native schain_supported: true tcf2_supported : true title : Sharethrough -userIds : unifiedId +userIds : pubCommonId, unifiedId usp_supported : true pbjs : true pbs : true From 4c14bfaa121bba9b5274fed5b077e45fe95e61af Mon Sep 17 00:00:00 2001 From: Jozef Bartek <31618107+jbartek25@users.noreply.github.com> Date: Thu, 5 Nov 2020 23:32:38 +0100 Subject: [PATCH 067/149] Adding supported user id types (#2471) --- dev-docs/bidders/improvedigital.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/improvedigital.md b/dev-docs/bidders/improvedigital.md index 530c48e7c4..baf43d571e 100644 --- a/dev-docs/bidders/improvedigital.md +++ b/dev-docs/bidders/improvedigital.md @@ -6,6 +6,7 @@ biddercode: improvedigital pbjs: true pbs: true gdpr_supported: true +userIds: criteo, id5Id usp_supported: true media_types: banner, native, video schain_supported: true From 1fc085e9538705a5533a93d20a867f87a8fe4dfc Mon Sep 17 00:00:00 2001 From: Brandon Ling <51931757+blingster7@users.noreply.github.com> Date: Thu, 5 Nov 2020 17:33:13 -0500 Subject: [PATCH 068/149] [Triplelift] Avoid versions 4.3-4.14 (#2473) Video bug fixes in effect starting 4.15: https://github.com/prebid/Prebid.js/releases/tag/4.15.0 --- dev-docs/bidders/triplelift.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/triplelift.md b/dev-docs/bidders/triplelift.md index ee1b7a2072..f7639c5e0c 100644 --- a/dev-docs/bidders/triplelift.md +++ b/dev-docs/bidders/triplelift.md @@ -11,7 +11,7 @@ biddercode: triplelift userIds: criteo, identityLink, unifiedId pbjs: true pbs: true -pbjs_version_notes: avoid 4.3 - 4.12 +pbjs_version_notes: avoid 4.3 - 4.14 --- ### Bid Params From 54d3ed31ae6df08e440e3834141a95a2eca7857c Mon Sep 17 00:00:00 2001 From: Mike Sperone Date: Thu, 5 Nov 2020 16:34:44 -0600 Subject: [PATCH 069/149] include a renderer for a specific mediaType (#2343) * add documentation noting that you can include the renderer for a specific mediaType * Show mediaType renderer is preferred. Documentation now states that applying the renderer property to the mediaType property ('video' in this page) is preferred to applying it on the adUnit level. The example code also shows this. Also refers to the pull request where this change was made. --- dev-docs/show-outstream-video-ads.md | 59 +++++++++++++--------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/dev-docs/show-outstream-video-ads.md b/dev-docs/show-outstream-video-ads.md index 450a8cc999..e7021607ee 100644 --- a/dev-docs/show-outstream-video-ads.md +++ b/dev-docs/show-outstream-video-ads.md @@ -3,8 +3,6 @@ layout: page_v2 title: Show Outstream Video Ads description: Show Outstream Video Ads with Prebid.js pid: 10 -top_nav_section: dev_docs -nav_section: prebid-video sidebarType: 4 --- @@ -67,52 +65,51 @@ To display an outstream video, two things are needed: Prebid.js will select the `renderer` used to display the outstream video in the following way: -1. If a `renderer` is associated with the Prebid adUnit, it will be used to display any outstream demand associated with that adUnit. Below, we will provide an example of an adUnit with an associated `renderer`. If that renderer is specified as backup only, it will only be used when no other renderer is found. -2. If no `renderer` is specified on the Prebid adUnit, Prebid will invoke the renderer associated with the winning (or selected) demand partner video bid. Choosing a backup only renderer allows publishers to access demand with or without an attached renderer. +1. If a `renderer` is associated with the Prebid adUnit's video mediaType, it will be used to display any outstream demand associated with that adUnit with a mediaType of "video". (This is the preferred method.) +2. If a `renderer` is associated with the Prebid adUnit, it will be used to display any outstream demand associated with that adUnit. Below, we will provide an example of an adUnit with an associated `renderer`. This is legacy, and number 1 is the preferred way. +3. If no `renderer` is specified on the Prebid adUnit, Prebid will invoke the renderer associated with the winning (or selected) demand partner video bid. {: .alert.alert-warning :} At this time, since not all demand partners return a renderer with their video bid responses, we recommend that publishers associate a `renderer` with their Prebid video adUnits, if possible. By doing so, any Prebid adapter that supports video will be able to provide demand for a given outstream slot. -Renderers are associated with adUnits through the `adUnit.renderer` object. This object contains three fields: +Renderers are associated with adUnits in two ways. +Primarily through the `adUnit.renderer` object. But also, especially for multiFormat adUnits, through the specified mediaType `adUnit.mediaTypes.video.renderer`. +This object contains these fields: 1. `url` -- Points to a file containing the renderer script. 2. `render` -- A function that tells Prebid.js how to invoke the renderer script. 3. `backupOnly` -- Optional field, if set to true, buyer or adapter renderer will be preferred + +In a multiFormat adUnit, you might want the renderer to only apply to only one of the mediaTypes. You can do this by defining the renderer on the media type itself. {% highlight js %} pbjs.addAdUnit({ code: 'video1', + // This renderer would apply to all prebid creatives... + renderer: { + url: 'example.com/publishersCustomRenderer.js', + render: function(bid) { renderAdUnit(...) } + }, mediaTypes: { video: { context: 'outstream', - playerSize: [640, 480] - } - }, - renderer: { - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - backupOnly: true, // prefer demand renderer - render: function (bid) { - adResponse = { - ad: { - video: { - content: bid.vastXml, - player_height: bid.playerHeight, - player_width: bid.playerWidth - } - } + playerSize: [640, 480], + // but a renderer passed in here would apply only to this mediaType. + // This renderer would override the above renderer if it exists. + renderer: { + url: 'example.com/videoRenderer.js', + render: function (bid) { renderVideo(...) } } - // push to render queue because ANOutstreamVideo may not be loaded yet. - bid.renderer.push(() => { - ANOutstreamVideo.renderAd({ - targetId: bid.adUnitCode, // target div id to render video. - adResponse: adResponse - }); - }); - } - } + }, + display: { + // With the renderer property excluded here, the display bids would + // use the renderer defined on the adUnit level. + ..., + }, + }, + ... }); - {% endhighlight %} Some demand partners that return a renderer with their video bid responses may support renderer configuration with the `adUnit.renderer.options` object. These configurations are bidder specific and may include options for skippability, player size, and ad text, for example. An example renderer configuration follows: @@ -137,7 +134,7 @@ pbjs.addAdUnit({ {% endhighlight %} -For more technical information about renderers, see [the pull request adding the 'Renderer' type](https://github.com/prebid/Prebid.js/pull/1082) +For more technical information about renderers, see [the pull request originally adding the 'Renderer' type](https://github.com/prebid/Prebid.js/pull/1082) and [the pull request allowing the 'renderer' type in the mediaType](https://github.com/prebid/Prebid.js/pull/5760). ## Step 2: Show ads in the page body From 510f4b3ecb93c24cebf7ed45f1b16a6a1b1c64be Mon Sep 17 00:00:00 2001 From: Nicholas Colletti <34142758+ncolletti@users.noreply.github.com> Date: Thu, 5 Nov 2020 17:37:09 -0500 Subject: [PATCH 070/149] feature/auction-options (#2370) * feature/auction-timing * rename to auctionOptions * add logging troubleshooting snippet --- dev-docs/publisher-api-reference.md | 34 ++++-- troubleshooting/troubleshooting-guide.md | 129 ++++++++++++++++++++++- 2 files changed, 153 insertions(+), 10 deletions(-) diff --git a/dev-docs/publisher-api-reference.md b/dev-docs/publisher-api-reference.md index 260a7e962c..9ee820b12b 100644 --- a/dev-docs/publisher-api-reference.md +++ b/dev-docs/publisher-api-reference.md @@ -66,6 +66,7 @@ This page has documentation for the public API methods of Prebid.js. * [cache](#setConfig-vast-cache) * [instreamTracking](#setConfig-instream-tracking) - requires [Instream Tracking Module](/dev-docs/modules/instreamTracking.html) * [site](#setConfig-site) + * [auctionOptions](#setConfig-auctionOptions) * [Generic Configuration](#setConfig-Generic-Configuration) * [Troubleshooting your config](#setConfig-Troubleshooting-your-configuration) * [.setBidderConfig(options)](#module_pbjs.setBidderConfig) @@ -1209,7 +1210,7 @@ If a custom adServerTargeting function can return an empty value, this boolean f ### pbjs.getEvents() ⇒ `Array` The methods `onEvent` and `offEvent` are provided for you to register -a callback to handle a Prebid.js event. +a callback to handle a Prebid.js event. The `getEvents` method returns a copy of all emitted events. @@ -2086,19 +2087,19 @@ Specifically, Prebid will go through the following steps with this feature: * Collect all the available targeting keys that were generated naturally by the auction. The keys are grouped by each of the adUnits that participated in the auction. * Prioritize these groups of targeting keys based on the following factors: * Bids with deals are prioritized before bids without deals. - * Bids with higher CPM are ranked before lower CPM bids. + * Bids with higher CPM are ranked before lower CPM bids. **Note** - The sorting follows this order specifically, so a bid with a deal that had a $10 CPM would be sorted before a bid with no deal that had a $15 CPM. * Convert the keys for each group into the format that they are passed to the ad server (i.e., an encoded query string) and count the number of characters that are used. * If the count is below the running threshold set in the `setConfig` call, that set of targeting keys will be passed along. If the keys exceed the limit, then they are excluded. - If you want to review the particular details about which sets of keys are passed/rejected, you can find them in the Prebid console debug log. + If you want to review the particular details about which sets of keys are passed/rejected, you can find them in the Prebid console debug log. ##### Finding the right value Given the varying nature of how sites are set up for advertising and the varying mechanics and data-points needed by ad servers, providing a generic threshold setting is tricky. If you plan to enable this setting, it's recommended you review your own setup to determine the ideal value. The following steps provide some guidance on how to start this process: * Use Prebid to set up a test page that uses the typical setup for your site (in terms of the number of ad slots, etc.). -* Once it's working, look for the average number of characters Prebid uses for the auction targeting keys. +* Once it's working, look for the average number of characters Prebid uses for the auction targeting keys. * You can do this by enabling the Prebid debug mode, enabling this setting in your `setConfig` with a high value, and then opening the browser's console to review the Console Logs section. * Also in the browser console, find your ad server's ad URL in the Network tab and review the details of the request to obtain information about the query data (specifically the number of characters used). * You can copy the data to another tool to count the number of characters that are present. @@ -2446,9 +2447,9 @@ video player can retrieve them when it's ready. Players don't obtain the VAST XM the JavaScript DOM in Prebid.js, but rather expect to be given a URL where it can be retrieved. There are two different flows possible with Prebid.js around VAST XML caching: -- Server-side caching: +- Server-side caching: Some video bidders (e.g. Rubicon Project) always cache the VAST XML on their servers as part of the bid. They provide a 'videoCacheKey', which is used in conjunction with the VAST URL in the ad server to retrieve the correct VAST XML when needed. In this case, Prebid.js has nothing else to do. -- Client-side caching: +- Client-side caching: Video bidders that don't cache on their servers return the entire VAST XML body. In this scenario, Prebid.js needs to copy the VAST XML to a publisher-defined cache location on the network. In this scenario, Prebid.js POSTs the VAST XML to the named Prebid Cache URL. It then sets the 'videoCacheKey' to the key that's returned in the response. For client-side caching, set the Prebid Cache URL as shown here (substituting the correct URL for the one shown here): @@ -2532,6 +2533,27 @@ pbjs.setConfig({ }); {% endhighlight %} + + +#### Auction Options + +The `auctionOptions` object passed to `pbjs.setConfig` provides a method to specify bidders that the Prebid auction will no longer wait for before determing the auction has completed. This may be helpful if you find there are a number of low performing and/or high timeout bidders in your page's rotation. + +{: .table .table-bordered .table-striped } +| Field | Scope | Type | Description | +|----------+---------+--------+---------------------------------------------------------------------------------------| +| `secondaryBidders` | Required | Array of Strings | The bidders that will be removed from determining when an Auction has completed. | + +Example config: + +{% highlight js %} +pbjs.setConfig({ + 'auctionOptions': { + 'secondaryBidders': ['doNotWaitForMe'] + } +}); +{% endhighlight %} + #### Generic setConfig Configuration diff --git a/troubleshooting/troubleshooting-guide.md b/troubleshooting/troubleshooting-guide.md index 8e3eac1799..07e879a014 100644 --- a/troubleshooting/troubleshooting-guide.md +++ b/troubleshooting/troubleshooting-guide.md @@ -50,7 +50,7 @@ This will add two types of messages to your browser’s developer console: ## Verify your config In your browser Console tab, insert `pbjs.getConfig()` in the command line. Check for basic setup in the output, including: - - selected timeout, + - selected timeout, - selected priceGranularity. ![Verfiy your config](/assets/images/troubleshooting/pbjs-check-config.png "Verfiy your config"){: height="70%" width="70%" :} @@ -96,7 +96,7 @@ You can review what ad units have been configured for Prebid by opening your bro ![Check ad units](/assets/images/troubleshooting/pbjs-check-adunits.png){: height="70%" width="70%" :} -**Expanded view of bid responses** +**Expanded view of bid responses** ![Check ad units](/assets/images/troubleshooting/pbjs-list-bidders.png){: height="50%" width="50%" :} @@ -385,11 +385,11 @@ If you're using DFP, you can verify this by using the [Google Publisher Console] To make sure your ad server is set up correctly, answer the following questions: -+ **How many ads have been fetched for an ad unit?** Ideally, only 1 ad will be requested on page load. If not, check for unnecessary extra calls to the ad server in your page's source code. ++ **How many ads have been fetched for an ad unit?** Ideally, only 1 ad will be requested on page load. If not, check for unnecessary extra calls to the ad server in your page's source code. ![Google Publisher Console Ad fetch count](/assets/images/overview/prebid-troubleshooting-guide/ad-server-1.png "Google Publisher Console Ad fetch count"){: .pb-sm-img :} -+ **Are the key-values being set in the ad server?** If not, review your page's source code to ensure that the Prebid auction completes **before** sending the key-value targeting to the ad server. ++ **Are the key-values being set in the ad server?** If not, review your page's source code to ensure that the Prebid auction completes **before** sending the key-value targeting to the ad server. ![DFP Delivery Troubleshooting](/assets/images/overview/prebid-troubleshooting-guide/ad-server-2.png "DFP Delivery Troubleshooting"){: .pb-lg-img :} @@ -434,6 +434,127 @@ The following parameters in the `bidResponse` object are common across all bidde | `height` | Integer | Height of the bid creative in pixels | `250` | | `adTag` | String | Creative's payload in HTML | `""` | +
+ +## Configure Auction Options with Logging + +The below snippet can be added to your page to better understand the Auction when including secondary bidders. This will help visualize when and if secondary bidders return with bids in time or outside of the auction. + +```javascript +pbjs.que.push(function() { + pbjs.addAdUnits(adUnits); + pbjs.aliasBidder('appnexus', 'waitForMe'); + pbjs.aliasBidder('rubicon', 'doNotWaitForMe'); + pbjs.setConfig({ + 'auctionOptions': { + 'secondaryBidders': ['doNotWaitForMe'] + } + }) + auctionOptionsLogging(); // include for logging + pbjs.requestBids({ + bidsBackHandler: sendAdserverRequest, + timeout: PREBID_TIMEOUT + }); +}); + +// must run before requestBids is invoked +function auctionOptionsLogging() { + pbjs.onEvent('auctionInit', auction => { + console.log(`Auction Options: Auction Start at ${auction.timestamp} - ${auction.auctionId}`); + }) + + pbjs.onEvent('bidRequested', bidderRequest => { + console.log(`Auction Options: Bid Requested from ${bidderRequest.bidderCode} at ${bidderRequest.start} - ${bidderRequest.auctionId}`); + }) + + pbjs.onEvent('bidResponse', bid => { + console.log(`Auction Options: Bid Response from ${bid.bidderCode} at ${Date.now()} in ${bid.responseTimestamp - bid.requestTimestamp}ms - ${bid.auctionId}`); + }) + + pbjs.onEvent('noBid', bid => { + console.log(`Auction Options: No Bid from ${bid.bidder} - ${bid.auctionId}`); + }) + + pbjs.onEvent('bidderDone', bidderRequest => { + console.log(`Auction Options: Bidder ${bidderRequest.bidderCode} Done in ${Date.now() - bidderRequest.start}ms - ${bidderRequest.auctionId}`); + }) + + pbjs.onEvent('bidTimeout', timedOutBidders => { + let auctionId = timedOutBidders.length > 0 ? timedOutBidders[0].auctionId : 0 + console.log(`Auction Options: Auction End! Timed Out! Bidders: ${Array.from(new Set(timedOutBidders.map(each => each.bidder))).join(',')} - ${auctionId}`); + }) + + pbjs.onEvent('auctionEnd', auction => { + let auctionId = auction.bidderRequests.length > 0 ? auction.bidderRequests[0].auctionId : 0 + let auctionStart = auction.bidderRequests.length > 0 ? auction.bidderRequests[0].auctionStart : 0 + console.log(`Auction Options: Auction End! After ${Date.now() - auctionStart}ms - ${auctionId}`); + auctionOptionsLog(auctionId) + }) + + function auctionOptionsLog(auctionId) { + let winners = pbjs.getAllWinningBids(); + let output = []; + let auctionTime = pbjs.getConfig('bidderTimeout'); + const config = pbjs.getConfig('auctionOptions'); + + populateData(); + displayData(); + + function populateData() { + function forEach(responses, cb) { + Object.keys(responses).forEach(function (adUnitCode) { + var response = responses[adUnitCode]; + response.bids.forEach(function (bid) { + cb(adUnitCode, bid); + }); + }); + } + + forEach(pbjs.getBidResponses(), function (code, bid) { + output.push({ + "Auction Options": auctionId, + bid: bid, + adunit: code, + adId: bid.adId, + bidder: bid.bidder, + secondary: !config.secondaryBidders.includes(bid.bidder), + time: bid.timeToRespond, + auctionTimeout: auctionTime, + cpm: bid.cpm, + msg: bid.statusMessage, + rendered: !!winners.find(function (winner) { + return winner.adId == bid.adId; + }) + }); + }); + + + forEach(pbjs.getNoBids && pbjs.getNoBids() || {}, function (code, bid) { + output.push({ + "Auction Options": auctionId, + msg: "no bid", + adunit: code, + adId: bid.bidId, + bidder: bid.bidder, + secondary: !config.secondaryBidders.includes(bid.bidder), + }); + }); + } + + function displayData() { + if (output.length) { + if (console.table) { + console.table(output); + } else { + for (var j = 0; j < output.length; j++) { + console.log(output[j]); + } + } + } + } + } +} +``` ## Related Topics From 2cdca28c4de477f3b568a615b9779b826e6964d9 Mon Sep 17 00:00:00 2001 From: Krushmedia <71434282+Krushmedia@users.noreply.github.com> Date: Fri, 6 Nov 2020 00:40:18 +0200 Subject: [PATCH 071/149] adding krushmedia pbjs adapter (#2403) * Krushmedia docs * Update krushmedia.md * Adding pbjs adapter Co-authored-by: bretg --- dev-docs/bidders/krushmedia.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/krushmedia.md b/dev-docs/bidders/krushmedia.md index b4b5645313..90b4734ed9 100644 --- a/dev-docs/bidders/krushmedia.md +++ b/dev-docs/bidders/krushmedia.md @@ -7,7 +7,7 @@ usp_supported: true schain_supported: true media_types: banner, video, native gdpr: true -pbjs: false +pbjs: true pbs: true --- From 3c01dea3642244d0861ac3f3c93de9b6e0d17338 Mon Sep 17 00:00:00 2001 From: John Salis Date: Thu, 5 Nov 2020 17:43:23 -0500 Subject: [PATCH 072/149] add video params to beachfront doc (#2412) Co-authored-by: John Salis --- dev-docs/bidders/beachfront.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev-docs/bidders/beachfront.md b/dev-docs/bidders/beachfront.md index 31e867ff22..98df223d20 100644 --- a/dev-docs/bidders/beachfront.md +++ b/dev-docs/bidders/beachfront.md @@ -44,6 +44,9 @@ For further information, please contact adops@beachfront.com. | `playbackmethod` | optional | Playback method supported by the publisher.
`1`: Auto-play sound on
`2`: Auto-play sound off
`3`: Click-to-play
`4`: Mouse-over | `1` | `integer` | | `maxduration` | optional | Maximum video ad duration in seconds. | `30` | `integer` | | `placement` | optional | Placement type for the impression.
`1`: In-Stream
`2`: In-Banner
`3`: In-Article
`4`: In-Feed
`5`: Interstitial/Slider/Floating | `1` | `integer` | +| `skip` | optional | Indicates if the player will allow the video to be skipped. | `1` | `integer` | +| `skipmin` | optional | Videos of total duration greater than this number of seconds can be skippable. | `15` | `integer` | +| `skipafter` | optional | Number of seconds a video must play before skipping is enabled. | `5` | `integer` |
From 02aa46c6c463b4dab5a21f6362c55addcba6ea32 Mon Sep 17 00:00:00 2001 From: Aparna Rao Date: Thu, 5 Nov 2020 17:46:20 -0500 Subject: [PATCH 073/149] 33Across: Updated for bidder support of video (#2441) * Add publisher usage docs for 33Across * Added 33Across to partners list * Clarified example pubID * Reinstated changes that got lost during rebase * 33across adapter is GDPR compliant * update docs * added usp support * We support Schain! * Update for video support * fixes to video params * fixed context * fixed instream params * fix for multi-format * Fixed Ad Unit titles * protocols is required * typo fix * Added required bidder param * removed duplicate video params * formatting edits Co-authored-by: Gleb Glushtsov Co-authored-by: Gleb Glushtsov Co-authored-by: Aparna Hegde Co-authored-by: Aparna Hegde --- dev-docs/bidders/33across.md | 139 ++++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/33across.md b/dev-docs/bidders/33across.md index 68e6affa55..39f60ac1eb 100644 --- a/dev-docs/bidders/33across.md +++ b/dev-docs/bidders/33across.md @@ -5,6 +5,7 @@ description: Prebid 33Across Bidder Adapter pbjs: true pbs: true biddercode: 33across +media_types: banner, video gdpr_supported: true schain_supported: true usp_supported: true @@ -17,4 +18,140 @@ usp_supported: true | Name | Scope | Description | Example | Type | |-------------|----------|--------------------------------------------------------------------------------------------------------------------------------|------------|----------| | `siteId` | required | Publisher GUID from 33Across | `'examplePub123'` | `string` | -| `productId` | required | 33Across Product ID that the Publisher has registered for (use `'siab'` for standard supply and `'inview'` for renderer) | `'siab'` | `string` | +| `productId` | required | 33Across Product ID that the Publisher has registered for (use `'siab'` for Banner or Outstream Video , `'inview'` for Adhesion, `'instream'` for Instream Video) | `'siab'` | `string` | + +### Ad Unit Setup for Banner +```javascript +var adUnits = [ +{ + code: '33across-hb-ad-123456-1', // ad slot HTML element ID + mediaTypes: { + banner: { + sizes: [ + [300, 250], + [728, 90] + ] + } + } + bids: [{ + bidder: '33across', + params: { + siteId: 'examplePub123', // required + productId: 'siab|inview' // required + } + }] +} +``` + +### Ad Unit Setup for Outstream Video +```javascript +var adUnits = [ +{ + code: '33across-hb-ad-123456-1', // ad slot HTML element ID + mediaTypes: { + video: { // We recommend setting the following video params + // in Ad Unit rather than bidder params as per Prebid 4.0 recommendation. + playerSize: [300, 250], // required + context: 'outstream', // required + mimes: ['video/mp4','video/x-flv'], // required + protocols: [ 2, 3 ], // required, set at least 1 value in array + placement: 2, // optional, defaults to 2 when context = outstream + api: [ 1, 2 ], // optional + skip: 0, // optional + minduration: 5, // optional + maxduration: 30, // optional + playbackmethod: [1,3], // optional + battr: [ 13, 14 ], // optional + linearity: 1, // optional + minbitrate: 10, // optional + maxbitrate: 10 // optional + } + }, + bids: [{ + bidder: '33across', + params: { + siteId: 'examplePub123', // required + productId: 'siab' // required + } + }], + ... +} +``` + +### Ad Unit Setup for Instream Video +```javascript +var adUnits = [ +{ + code: '33across-hb-ad-123456-1', // ad slot HTML element ID + mediaTypes: { + video: { // We recommend setting the following video params + // in Ad Unit rather than bidder params as per Prebid 4.0 recommendation. + playerSize: [300, 250], // required + context: 'instream', // required + mimes: ['video/mp4','video/x-flv'], // required + protocols: [ 2, 3 ], // required, set at least 1 value in array + placement: 1, // optional, defaults to 1 when context = instream + startdelay: 0, // optional, defaults to 0 when context = instream + api: [ 1, 2 ], // optional + skip: 0, // optional + minduration: 5, // optional + maxduration: 30, // optional + playbackmethod: [1,3], // optional + battr: [ 13, 14 ], // optional + linearity: 1, // optional + minbitrate: 10, // optional + maxbitrate: 10 // optional + } + }, + bids: [{ + bidder: '33across', + params: { + siteId: 'examplePub123', // required + productId: 'instream' // required + } + }], + ... +} +``` + +### Ad Unit Setup for Multi-format: Banner, Video (Outstream) +```javascript +var adUnits = [ +{ + code: '33across-hb-ad-123456-1', // ad slot HTML element ID + mediaTypes: { + banner: { + sizes: [ + [300, 250], + [728, 90] + ] + }, + video: { // We recommend setting the following video params + // in Ad Unit rather than bidder params as per Prebid 4.0 recommendation. + playerSize: [300, 250], // required + context: 'outstream', // required + mimes: ['video/mp4','video/x-flv'], // required + protocols: [ 2, 3 ], // required, set at least 1 value in array + placement: 2, // optional, defaults to 2 when context = outstream + api: [ 1, 2 ], // optional + skip: 0, // optional + minduration: 5, // optional + maxduration: 30, // optional + playbackmethod: [1,3], // optional + battr: [ 13, 14 ], // optional + linearity: 1, // optional + minbitrate: 10, // optional + maxbitrate: 10 // optional + } + }, + bids: [{ + bidder: '33across', + params: { + siteId: 'examplePub123', // required + productId: 'siab' // required + } + }], + ... +} +``` + From b02a322875f6784e1855dcf434a2816faa824ceb Mon Sep 17 00:00:00 2001 From: thuyhq <61451682+thuyhq@users.noreply.github.com> Date: Fri, 6 Nov 2020 05:46:48 +0700 Subject: [PATCH 074/149] Add apacdex bid adapter docs & edit valueimpression, quantumdex docs (#2447) --- dev-docs/bidders/apacdex.md | 20 ++++++++++++++++++++ dev-docs/bidders/quantumdex.md | 1 + dev-docs/bidders/valueimpression.md | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 dev-docs/bidders/apacdex.md diff --git a/dev-docs/bidders/apacdex.md b/dev-docs/bidders/apacdex.md new file mode 100644 index 0000000000..2a3550d2ff --- /dev/null +++ b/dev-docs/bidders/apacdex.md @@ -0,0 +1,20 @@ +--- +layout: bidder +title: Apacdex +description: Prebid APAC Digital Exchange Bidder Adapter +pbjs: true +biddercode: apacdex +media_types: banner, video +gdpr_supported: true +tcf2_supported: true +schain_supported: true +usp_supported: true +--- + + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------------|----------|--------------------------------------------------------------------------------------------------------------------------------|------------|----------| +| `siteId` | required | Publisher site ID from Apacdex | `'apacdex1234'` | `string` | diff --git a/dev-docs/bidders/quantumdex.md b/dev-docs/bidders/quantumdex.md index 4e8ae33dac..01e828a9c8 100644 --- a/dev-docs/bidders/quantumdex.md +++ b/dev-docs/bidders/quantumdex.md @@ -4,6 +4,7 @@ title: Quantumdex description: Prebid Quantum Digital Exchange Bidder Adapter pbjs: true biddercode: quantumdex +aliasCode: apacdex media_types: banner, video gdpr_supported: true tcf2_supported: true diff --git a/dev-docs/bidders/valueimpression.md b/dev-docs/bidders/valueimpression.md index b8b8d25e11..77580ada76 100644 --- a/dev-docs/bidders/valueimpression.md +++ b/dev-docs/bidders/valueimpression.md @@ -4,7 +4,7 @@ title: Valueimpression description: Prebid Valueimpression Bidder Adapter pbjs: true biddercode: valueimpression -aliasCode: quantumdex +aliasCode: apacdex media_types: banner, video gdpr_supported: true tcf2_supported: true From 0dc1852b79f8cc0dc78f3bb58642a6bc95e45d7a Mon Sep 17 00:00:00 2001 From: ix-certification Date: Thu, 5 Nov 2020 17:47:42 -0500 Subject: [PATCH 075/149] Adding detect missing sizes feature toggle (#2455) * adding detectMissingSizes feature toggle * cfg example update Co-authored-by: Ix-Prebid-Support --- dev-docs/bidders/indexExchange.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dev-docs/bidders/indexExchange.md b/dev-docs/bidders/indexExchange.md index 5ed73f868a..7b4b30f128 100644 --- a/dev-docs/bidders/indexExchange.md +++ b/dev-docs/bidders/indexExchange.md @@ -305,6 +305,27 @@ pbjs.setConfig({ }); ``` +#### The **detectMissingSizes** feature +With a recent update, the IX bid adapter bids on all banner sizes available in an ad unit, if IX is configured for at least one banner size in that ad unit. This default behavior if not required, can be turned off by using the `detectMissingSizes` flag. +``` +pbjs.setConfig({ + ix: { + detectMissingSizes: false + } + }); +``` +OR +``` +pbjs.setBidderConfig({ + bidders: ["ix"], + config: { + ix: { + detectMissingSizes: false + } + } + }); +``` + ### 2. Include `ixBidAdapter` in your build process When running the build command, include `ixBidAdapter` as a module, as well as `dfpAdServerVideo` if you require video support. From fdd2e1f0bdeb9126872bb4c48cd9d078eae808ed Mon Sep 17 00:00:00 2001 From: Stephan Brosinski Date: Thu, 5 Nov 2020 23:48:22 +0100 Subject: [PATCH 076/149] Smaato: Docs for adding userIds (#2462) --- dev-docs/bidders/smaato.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev-docs/bidders/smaato.md b/dev-docs/bidders/smaato.md index eb1ad9b442..791b2532fe 100644 --- a/dev-docs/bidders/smaato.md +++ b/dev-docs/bidders/smaato.md @@ -8,8 +8,10 @@ tcf2_supported: true usp_supported: true coppa_supported: true media_types: banner, video +userIds: criteo, pubCommonId, unifiedId pbjs: true pbs: true +prebid_member: true --- ### Table of Contents From 15bc7555c9ebfefebd4b03ee099d684edd06035b Mon Sep 17 00:00:00 2001 From: matthieularere-msq <63732822+matthieularere-msq@users.noreply.github.com> Date: Thu, 5 Nov 2020 23:56:54 +0100 Subject: [PATCH 077/149] MediaSquare: updated media_types + add glv_id (#2396) --- dev-docs/bidders/mediasquare.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/mediasquare.md b/dev-docs/bidders/mediasquare.md index 386f1a6519..41e621033e 100644 --- a/dev-docs/bidders/mediasquare.md +++ b/dev-docs/bidders/mediasquare.md @@ -9,7 +9,8 @@ tcf2_supported: true usp_supported: true schain_supported: true userIds: id5Id -media_types: banner +media_types: banner, video, native +glv_id: 791 --- From 6a0233cf69d6779fd8186c36dd81f40657b4b237 Mon Sep 17 00:00:00 2001 From: bretg Date: Mon, 9 Nov 2020 15:16:33 -0500 Subject: [PATCH 078/149] Added mediaType to the new PBS bidder doc (#2483) --- prebid-server/developers/add-new-bidder-go.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/prebid-server/developers/add-new-bidder-go.md b/prebid-server/developers/add-new-bidder-go.md index 4f35c310c8..d6ca2a0ecd 100644 --- a/prebid-server/developers/add-new-bidder-go.md +++ b/prebid-server/developers/add-new-bidder-go.md @@ -77,16 +77,17 @@ provide additional metadata in their bid response: "prebid": { "meta": { "networkId": NETWORK_ID, - "networkName": NETWORK_NAME + "networkName": NETWORK_NAME, "agencyId": AGENCY_ID, "agencyName": AGENCY_NAME, "advertiserId": ADVERTISER_ID, "advertiserName": ADVERTISER_NAME, - "advertiserDomains": [ARRAY_OF_ADVERTISER_DOMAINS] + "advertiserDomains": [ARRAY_OF_ADVERTISER_DOMAINS], "brandId": BRAND_ID, "brandName": BRAND_NAME, "primaryCatId": IAB_CATEGORY, "secondaryCatIds": [ARRAY_OF_IAB_CATEGORIES], + "mediaType": MEDIATYPE } } } @@ -99,6 +100,7 @@ Notes: - `advertiserDomains` is the same as the OpenRTB 2.5 `bid.adomain` field but replicated here for downstream convenience - See the [Prebid.js Bidder Adapter](/dev-docs/bidder-adaptor.html) page for details about the requested values for each field. +- The following fields are going to be enforced in an upcoming version of Prebid.js: advertiserDomains and mediaType. {: .alert.alert-info :} Please provide as much information as possible in the meta object. Publishers use this data for tracking down bad creatives and ad blocking. The advertiserDomains field is particularly useful. Some of these fields may become required in a future release. From 6a3d5450015297a65dcba3742942a67e37d3daba Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 10 Nov 2020 09:24:30 -0500 Subject: [PATCH 079/149] RTD: changed bidrequest attribute (#2486) --- dev-docs/add-rtd-submodule.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-docs/add-rtd-submodule.md b/dev-docs/add-rtd-submodule.md index da085f8187..d441e8176e 100644 --- a/dev-docs/add-rtd-submodule.md +++ b/dev-docs/add-rtd-submodule.md @@ -174,7 +174,7 @@ This is the function that will allow RTD sub-modules to modify the AdUnit object - userConsent object (see above) 2. Your sub-module may update the reqBidsConfigObj and hit the callback. When you update the bidRequest, you must follow one of these conventions: - Use [First Party Data](/features/firstPartyData.html) conventions, setting AdUnit.fpd.context.data.ATTRIBUTES or AdUnit.fpd.user.data.ATTRIBUTES - - Place your data in bidRequest.realTimeData.RTDPROVIDERCODE.ATTRIBUTES + - Place your data in bidRequest.rtd.RTDPROVIDERCODE.ATTRIBUTES **Code Example** @@ -194,7 +194,7 @@ function init(config, userConsent) { function alterBidRequests(reqBidsConfigObj, callback, config, userConsent) { // do stuff - // put data in AdUnit.fpd.* or realTimeData.RTDPROVIDERCODE.* + // put data in AdUnit.fpd.* or rtd.RTDPROVIDERCODE.* callback(); } From e8075efe06fb47c97673c4f2956d4b9dd5675a94 Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 10 Nov 2020 14:46:03 -0500 Subject: [PATCH 080/149] FPD: fleshing out example data (#2489) --- features/firstPartyData.md | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/features/firstPartyData.md b/features/firstPartyData.md index c1786fbfa2..06b4d06b26 100644 --- a/features/firstPartyData.md +++ b/features/firstPartyData.md @@ -51,16 +51,25 @@ to first party data that might be useful in ad targeting: pbjs.setConfig({ fpd: { context: { - keywords: "power tools", // keywords is a standard OpenRTB field - search: "drill", // same with search and content + name: "example", + domain: "page.example.com", + cat: ["IAB2"], + sectioncat: ["IAB2-2"], + pagecat: ["IAB2-2"], + page: "https://page.example.com/here.html", + ref: "https://ref.example.com", + keywords: "power tools, drills", + search: "drill", content: { userrating: 4 }, - data: { + data: { // fields that aren't part of openrtb 2.5 pageType: "article", - category: "tools" + category: "repair" } }, user: { - keywords: "a,b", // keywords is a standard OpenRTB field + yob: 1985, + gender: "m", + keywords: "a,b", data: { registered: true, interests: ["cars"] @@ -88,9 +97,11 @@ pbjs.addAdUnits({ } }, fpd: { - context: { + context: { pbAdSlot: "homepage-top-rect", - adUnitSpecificContextAttribute: "123" + data: { + adUnitSpecificAttribute: "123" + } } }, ... From fe2224c69c42aaf46b5b08c28a88c2b171b2d3e2 Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 10 Nov 2020 17:59:12 -0500 Subject: [PATCH 081/149] rubicon: add more user IDs (#2487) * rubicon: add more user IDs * Update rubicon.md adding a few additional user id sub adapters * Update rubicon.md missed quantcastId Co-authored-by: jdwieland8282 --- dev-docs/bidders/rubicon.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/rubicon.md b/dev-docs/bidders/rubicon.md index 4fd9c38560..a884694b82 100644 --- a/dev-docs/bidders/rubicon.md +++ b/dev-docs/bidders/rubicon.md @@ -9,7 +9,7 @@ usp_supported: true coppa_supported: true schain_supported: true media_types: video -userIds: identityLink, liveIntentId, sharedId, pubCommonId, pubProvidedId, unifiedId +userIds: britepoolId, criteo, fabrickId, haloId, id5Id, identityLink, intentiqId, idx, liveIntentId, lotamePanoramaId, netId, parrableId, pubCommonId, pubProvidedId, quantcastId, sharedId, unifiedId, verizonMediaId, zeotapIdPlus prebid_member: true safeframes_ok: true bidder_supports_deals: true From 1124ae2ec8d0fc91a2f8a5de7b4a57be442e5769 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 12 Nov 2020 11:24:48 -0500 Subject: [PATCH 082/149] added RTD external code exception (#2490) --- dev-docs/module-rules.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev-docs/module-rules.md b/dev-docs/module-rules.md index b009e446cc..cbcacd12c1 100644 --- a/dev-docs/module-rules.md +++ b/dev-docs/module-rules.md @@ -104,7 +104,8 @@ The use of the terms "must" and "should" in this document is deliberate. Howeve ### Real Time Data Module Rules -1. All global rules apply. +1. All global rules apply with one exception: + - A Real-Time Data module may load external code if it requires publisher registration and there's a prominent disclosure on the module documentation. The idea is that a publisher will not include the module if they don't approve of the external code, and since they've registered for the service, they must approve. The text of the disclosure may differ if the vendor allows Prebid to do regular reviews of a strictly versioned proprietary library. 1. Real Time Data (RTD) modules must not bid. That functionality is reserved for bid adapters. 1. RTD modules must not supply privacy-sensitive user information (including IDs) into the auction. That functionality is reserved for User ID modules. 1. RTD modules should make data available in a cross-bidder way when possible. For example, passing data through existing mechanisms like First Party Data. From eb23fbbe7ae6ed5401c220f86bbaa180fdccfdc4 Mon Sep 17 00:00:00 2001 From: rimaburder-index <55195208+rimaburder-index@users.noreply.github.com> Date: Thu, 12 Nov 2020 13:53:49 -0500 Subject: [PATCH 083/149] updated the text in like 309 (#2477) updated the text in like 309 --- dev-docs/bidders/indexExchange.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/indexExchange.md b/dev-docs/bidders/indexExchange.md index 7b4b30f128..6c3dfef6dd 100644 --- a/dev-docs/bidders/indexExchange.md +++ b/dev-docs/bidders/indexExchange.md @@ -306,7 +306,7 @@ pbjs.setConfig({ ``` #### The **detectMissingSizes** feature -With a recent update, the IX bid adapter bids on all banner sizes available in an ad unit, if IX is configured for at least one banner size in that ad unit. This default behavior if not required, can be turned off by using the `detectMissingSizes` flag. +By default, the IX bidding adapter bids on all banner sizes available in the ad unit when configured to at least one banner size. If you want the IX bidding adapter to only bid on the banner size it’s configured to, switch off this feature using `detectMissingSizes`. ``` pbjs.setConfig({ ix: { From 22106bdb829eeaefef873e7d1aa84f2ea693ad86 Mon Sep 17 00:00:00 2001 From: Olivier Date: Thu, 12 Nov 2020 19:54:45 +0100 Subject: [PATCH 084/149] Adagio: add user id types (#2478) --- dev-docs/bidders/adagio.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/adagio.md b/dev-docs/bidders/adagio.md index 287604e16f..fc1b503f58 100644 --- a/dev-docs/bidders/adagio.md +++ b/dev-docs/bidders/adagio.md @@ -5,6 +5,7 @@ description: Prebid Adagio Bidder Adaptor pbjs: true biddercode: adagio media_types: banner +userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, pubProvidedId, sharedId, unifiedId gdpr_supported: true usp_supported: true coppa_supported: true From d8031d56fdd542361f5f5ea8d3bb46a8b59afdc9 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 12 Nov 2020 14:30:20 -0500 Subject: [PATCH 085/149] Rubicon: refine first party data parameters (#2461) --- dev-docs/bidders/rubicon.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-docs/bidders/rubicon.md b/dev-docs/bidders/rubicon.md index a884694b82..e9b532b03f 100644 --- a/dev-docs/bidders/rubicon.md +++ b/dev-docs/bidders/rubicon.md @@ -31,13 +31,13 @@ For both Prebid.js and Prebid Server, the Rubicon Project adapter requires setup | `siteId` | required | The site ID | `'13945'` | `string` | | `zoneId` | required | The zone ID | `'23948'` | `string` | | `sizes` | optional | Array of Rubicon Project size IDs. If not specified, the system will try to convert from the AdUnit's mediaTypes.banner.sizes. | `[15]` | `Array` | -| `keywords` | optional | Array of page-specific keywords. May be referenced in Rubicon Project reports. | `['travel', 'tourism']` | `Array` | -| `inventory` | optional | An object defining arbitrary key-value pairs concerning the page for use in targeting. The values must be arrays. | `{"rating":["5-star"], "prodtype":["tech","mobile"]}` | `object` | -| `visitor` | optional | An object defining arbitrary key-value pairs concerning the visitor for use in targeting. The values must be arrays. | `{"ucat":["new"], "search":["iphone"]}` | `object` | | `position` | optional | Set the page position. Valid values are "atf" and "btf". | `'atf'` | `string` | | `userId` | optional | Site-specific user ID may be reflected back in creatives for analysis. Note that userId needs to be the same for all slots. | `'12345abc'` | `string` | | `floor` | optional | Sets the global floor -- no bids will be made under this value. | `0.50` | `float` | | `latLong` | optional | Sets the latitude and longitude for the visitor (avail since PBJS 1.10) | `[40.7608, 111.8910]` | `Array` | +| `inventory` | optional | Please consider using the [First Party Data feature](/features/firstPartyData.html), e.g. AdUnit.fpd.context.data.ATTR. This parameter allows the definition of an object defining arbitrary key-value pairs concerning the page for use in targeting. The values must be arrays. | `{"rating":["5-star"], "prodtype":["tech","mobile"]}` | `object` | +| `visitor` | optional | Please consider using the [First Party Data feature](/features/firstPartyData.html), e.g. AdUnit.fpd.user.data.ATTR. This parameter allows the definition of an object defining arbitrary key-value pairs concerning the visitor for use in targeting. The values must be arrays. | `{"ucat":["new"], "search":["iphone"]}` | `object` | +| `keywords` | optional | Deprecated - please use the [First Party Data feature](/features/firstPartyData.html), e.g. AdUnit.fpd.context.data.keywords. This is a legacy parameter that only works for client-side display. To get video or server-side reporting, please use First Party data or the inventory/visitor parameters. | `['travel', 'tourism']` | `Array` | | `video` | required for video | Video targeting parameters. See the [video section below](#rubicon-video). | `{"language": "en"}` | `object` | From 129eba469febe56f9d42fbae6b0a4d8fe0f8245b Mon Sep 17 00:00:00 2001 From: Bryan Szekely <49168870+bszekely1@users.noreply.github.com> Date: Thu, 12 Nov 2020 15:21:54 -0500 Subject: [PATCH 086/149] PBSDK: added clarity on insterstitial ad units (#2493) --- .../pbm-bannerinterstitialadunit-android.md | 6 ++---- .../ios/pbm-bannerinterstitialadunit-ios.md | 18 ++++++++---------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/prebid-mobile/pbm-api/android/pbm-bannerinterstitialadunit-android.md b/prebid-mobile/pbm-api/android/pbm-bannerinterstitialadunit-android.md index c9a2a1b02a..35bbb34ff7 100755 --- a/prebid-mobile/pbm-api/android/pbm-bannerinterstitialadunit-android.md +++ b/prebid-mobile/pbm-api/android/pbm-bannerinterstitialadunit-android.md @@ -21,11 +21,9 @@ Use the `InterstitialAdUnit` object to create and configure an interstitial ad u Create a new Interstitial Ad Unit associated with a Prebid Server configuration ID. -As of version 1.2+, Prebid SDK has extended the functionality of Interstitial ad monetization by using a smart ad size selection process. App developers can speicify a minimun width and minimum height percentage an ad can occupy of a devices real state, with Prebid Server (PBS) deriving a limited set of ad sizes (max 10) as eligible for the auction. +As of version 1.2+, Prebid SDK has extended the functionality of Interstitial ad monetization by using a smart ad size selection process to monetize sizes smaller than full screen ads. App developers can speicify a minimun width and minimum height percentage an ad can occupy of a devices real state, with Prebid Server (PBS) deriving a limited set of ad sizes (max 10) as eligible for the auction. -PBS will take the AdUnit's size (width and height) as the max size for the interstitial as size. If that size is 1x1, it will look up the device's size and use that as the max size. If the wdith and height are not present, it will also use the device size as the max size. (1x1 support so that you don't have to omit size as a parameter to use the device size). - -PBS with interstitial support will come preconfigured with a list of common ad sizes, preferentially organized by weighing the larger and more common sizes first. No guarantees to the ordering will be made. PBS will generate a list of ad sizes, selecting the first 10 sizes that fall within the imp's max size and minimum percentage size. All the interstitial parameters will still be passed to the bidders, allowing them to use their own size matching algorithms if they prefer. +PBS will take the AdUnit's size (width and height) as the max size for the interstitial as size, generating a list of ad sizes, selecting the first 10 sizes that fall within the imp's max size and minimum percentage size. All the interstitial parameters will still be passed to the bidders, allowing them to use their own size matching algorithms if they prefer. Prebid Server will send the eligible size list to each bidder to solicit a bid. For a full description of the Prebid Server logic, please refer to the [Prebid Server PR 797](https://github.com/prebid/prebid-server/pull/797/files). diff --git a/prebid-mobile/pbm-api/ios/pbm-bannerinterstitialadunit-ios.md b/prebid-mobile/pbm-api/ios/pbm-bannerinterstitialadunit-ios.md index ba006ef6dc..428d549eec 100755 --- a/prebid-mobile/pbm-api/ios/pbm-bannerinterstitialadunit-ios.md +++ b/prebid-mobile/pbm-api/ios/pbm-bannerinterstitialadunit-ios.md @@ -18,11 +18,9 @@ Create a new Interstitial Ad Unit associated with a Prebid Server configuration See [AdUnit]({{site.baseurl}}/prebid-mobile/pbm-api/ios/pbm-adunit-ios.html) for additional parameters and methods. -As of version 1.2+, Prebid SDK has extended the functionality of Interstitial ad monetization by using a smart ad size selection process. App developers can speicify a minimun width and minimum height percentage an ad can occupy of a devices real state, with Prebid Server (PBS) deriving a limited set of ad sizes (max 10) as eligible for the auction. +As of version 1.2+, Prebid SDK has extended the functionality of Interstitial ad monetization by using a smart ad size selection process to monetize sizes smaller than full screen ads. App developers can speicify a minimun width and minimum height percentage an ad can occupy of a devices real state, with Prebid Server (PBS) deriving a limited set of ad sizes (max 10) as eligible for the auction. -PBS will take the AdUnit's size (width and height) as the max size for the interstitial as size. If that size is 1x1, it will look up the device's size and use that as the max size. If the wdith and height are not present, it will also use the device size as the max size. (1x1 support so that you don't have to omit size as a parameter to use the device size). - -PBS with interstitial support will come preconfigured with a list of common ad sizes, preferentially organized by weighing the larger and more common sizes first. No guarantees to the ordering will be made. PBS will generate a list of ad sizes, selecting the first 10 sizes that fall within the imp's max size and minimum percentage size. All the interstitial parameters will still be passed to the bidders, allowing them to use their own size matching algorithms if they prefer. +PBS will take the AdUnit's size (width and height) as the max size for the interstitial as size, generating a list of ad sizes, selecting the first 10 sizes that fall within the imp's max size and minimum percentage size. All the interstitial parameters will still be passed to the bidders, allowing them to use their own size matching algorithms if they prefer. Prebid Server will send the eligible size list to each bidder to solicit a bid. For a full description of the Prebid Server logic, please refer to the [Prebid Server PR 797](https://github.com/prebid/prebid-server/pull/797/files). @@ -60,15 +58,15 @@ Array of integers or a predefined constant representing the supported [OpenRTB 2 **Create an InterstitialAdUnit** -``` -let bannerUnit = BannerAdUnit(configId: "6ace8c7d-88c0-4623-8117-75bc3f0a2e45", size: CGSize(width: 300, height: 250)) ``` -**Add additional ad sizes** - +let adUnit = InterstitialAdUnit(configId: "6ace8c7d-88c0-4623-8117-75bc3f0a2e45") ``` -bannerUnit.addAdditionalSizes(sizes: CGSize(width: 320, height: 50)) + +With optional minWidthPerc and minHeightPerc parameters. +``` +let adUnit = InterstitialAdUnit(configId: "6ace8c7d-88c0-4623-8117-75bc3f0a2e45", minWidthPerc: 50, minHeightPerc: 70) ``` -Once a BannerAdUnit is created use Google Mobile Ads or MoPub to retrieve and display creatives. + ** Define any appropriate API Frameworks ** From fe42accb2279c0dbc6cfe5e62f7c8921a68dd02e Mon Sep 17 00:00:00 2001 From: bretg Date: Fri, 13 Nov 2020 08:30:23 -0500 Subject: [PATCH 087/149] AppNexus: added PBS use_pmt_rule flag (#2481) --- dev-docs/bidders/appnexus.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/appnexus.md b/dev-docs/bidders/appnexus.md index 528673ed2d..714ae5d172 100644 --- a/dev-docs/bidders/appnexus.md +++ b/dev-docs/bidders/appnexus.md @@ -45,7 +45,7 @@ All AppNexus placements included in a single call to `requestBids` must belong t | `frameworks` | optional | Array of integers listing API frameworks for Banner supported by the publisher. | `integer` | | `user` | optional | Object that specifies information about an external user. See [User Object](#appnexus-user-object) for details. | `user: { age: 25, gender: 0, dnt: true}` | `object` | | `allowSmallerSizes` | optional | If `true`, ads smaller than the values in your ad unit's `sizes` array will be allowed to serve. Defaults to `false`. | `true` | `boolean` | -| `usePaymentRule` | optional | If `true`, Appnexus will return net price to Prebid.js after publisher payment rules have been applied. | `true` | `boolean` | +| `usePaymentRule` (PBJS) or `use_pmt_rule` (PBS) | optional | If `true`, Appnexus will return net price to Prebid.js after publisher payment rules have been applied. | `true` | `boolean` | | `keywords` | optional | A set of key-value pairs applied to all ad slots on the page. Mapped to [buy-side segment targeting](https://monetize.xandr.com/docs/segment-targeting) (login required). Values can be empty. See [Passing Keys Without Values](#appnexus-no-value) below for examples. Note that to use keyword with the Prebid Server adapter, that feature must be enabled for your account by an AppNexus account manager. | `keywords: { genre: ['rock', 'pop'] }` | `object` | | `video` | optional | Object containing video targeting parameters. See [Video Object](#appnexus-video-object) for details. | `video: { playback_method: ['auto_play_sound_off'] }` | `object` | | `app` | optional | Object containing mobile app parameters. See the [App Object](#appnexus-app-object) for details. | `app : { id: 'app-id'}` | `object` | From 0cff4559842b68f7e5aa8874de471c70bb451068 Mon Sep 17 00:00:00 2001 From: jdwieland8282 Date: Fri, 13 Nov 2020 10:18:18 -0700 Subject: [PATCH 088/149] Create Id-Library.md (#2429) * Create Id-Library.md Adding documentation for the Id Library module * fixing typos and configuration example * Update index.md adding reference to modules/index.html * Update Id-Library.md fixing typos * added image to PR, renamed file * fixing module link to new filename * refining algorithm desc * Update idLibrary.md * Update idLibrary.md * Update idLibrary.md removing unnecessary graphic * wordsmithing * Update idLibrary.md Adding instructions on how to disable the full scan * added fullscan to the config table Co-authored-by: bretg --- dev-docs/modules/idLibrary.md | 94 +++++++++++++++++++++++++++++++++++ dev-docs/modules/index.md | 1 + 2 files changed, 95 insertions(+) create mode 100644 dev-docs/modules/idLibrary.md diff --git a/dev-docs/modules/idLibrary.md b/dev-docs/modules/idLibrary.md new file mode 100644 index 0000000000..ea9bb9ea91 --- /dev/null +++ b/dev-docs/modules/idLibrary.md @@ -0,0 +1,94 @@ +--- +layout: page_v2 +page_type: module +title: ID Library +description: ID Graphing Adapter +module_code : currency +display_name : ID Library +enable_download : true +sidebarType : 1 +Maintainer: eng-dmp@magnite.com + +--- + + +# ID Library +{:.no_toc} + +The ID Library module gathers and generates a map of identities present on the page. The primary usecase for this adapter is for Publishers who have included multiple UserId subadapters in their prebid.js implementation, and want to store the resulting user ids serverside for modeling or graphing purposes. The ID Library module, anchors the response of `refreshUserIds()` to a presistant identifier (md5 encrypted) and returns an map of uids. This map of uids comes in the form of a POST message in JSON format and must be output to a publisher configured endpoint. + +The module attempts to extract a persistant identifier in the following ways: + +1. From a publisher defined target element +2. Searches for HTML input (text/email) element +3. Searches entire document for email using regex + +To get started, add the module to your Prebid.js wrapper. From the command line: + +{: .alert.alert-info :} +gulp build --modules=idLibrary + + +## Application Flow + +In the idLibrary module, the persistant id is fetched from the page and synced with the user ids as follows: + +1. Check for a valid 'idLibrary' configuration +1. If the configuration defines `target`, get the HTML element with the named id + 1. If a valid ID entry (e.g. email) exists in the target element, we're good, go on to step 5. + 1. Otherwise if no valid value is found, add a listener on the element + 1. Once the listener finds a valid value, go on to step 5. +1. Else, scan the values of all text and email input elements on the page. If one of them has a valid persistent ID value, we found it. Go on to step 5. +1. Else, scan the whole body tag for a valid persistent ID value. If one is found go on to step 5. +1. If a valid persistent ID value has been found, then MD5 hash it, combine it with user IDs from the user ID module and POST to the specified endpoint. + + +## Configuration: + +{: .table .table-bordered .table-striped } +| Param | Required | Description | +| --- | --- | --- | +| url | yes | The url endpoint is used to post the MD5 hasheds| +| target | no | Contains the element id from which the presistant value is to be read.| +| debounce | no | Time in milliseconds the module will wait before searching for the presistant value and user ids| +| fullscan | no | Allows the publisher to turn off the full page scan | + +Please note, A full scan (Step 4 above) of the body element is configured on by default but can be disabled by setting `"fullscan: false"` + +## Example + +```javascript + pbjs.setConfig({ + idLibrary:{ + url: 'url', + target: 'username', + debounce: 250 + } +}); +``` + +### Post data format + +After the data is collected, it will be POSTed to the configured URL in this format: + +```json +{ + "hid": "MD5 hash", + "uids": "user ids array" +} +``` + +```json +{ + "hid":"5dd72a98c8146bafa84313fc15eb27c2", + "uids": + { + "id5id":"ID5-ZHMOQ7afBOa_gZxzTSelo5KFcVwCQgM7d-BUkWtjAA", + "sharedid": + { + "id":"01EE77EKRHXEZVJYMSQVRJ9536", + "third":"01EE77EKRHXEZVJYMSQVRJ9536" + } + } +} +``` diff --git a/dev-docs/modules/index.md b/dev-docs/modules/index.md index f236b85fe1..21083cd7ac 100644 --- a/dev-docs/modules/index.md +++ b/dev-docs/modules/index.md @@ -38,6 +38,7 @@ If you are looking for bidder adapter parameters, see [Bidders' Params]({{site.b | [**Advanced Size Mapping**](/dev-docs/modules/sizeMappingV2.html) | Display Responsive AdUnits in demanding page environments. | | [**Price Floors Module**](/dev-docs/modules/floors.html) | Configure and enforce minimum bids. | | [**GPT Pre-Auction Module**](/dev-docs/modules/gpt-pre-auction.html) | Adds a PB Ad Slot and matching GAM ad unit name to each ad unit's first-party data before bid requests are sent to the adapters. | +| [**ID Library**](/dev-docs/modules/idLibrary.html) | Retrieve user ids deployed on your site, and return them to a configurable endpoint for ID Graphing | ## Real-Time Data Providers From 55cb5cccbc777782c30410d573a84ea4e9b19955 Mon Sep 17 00:00:00 2001 From: bretg Date: Fri, 13 Nov 2020 17:00:01 -0500 Subject: [PATCH 089/149] PBS features: added per-account SRID (#2500) --- prebid-server/features/pbs-feature-idx.md | 1 + 1 file changed, 1 insertion(+) diff --git a/prebid-server/features/pbs-feature-idx.md b/prebid-server/features/pbs-feature-idx.md index 7e830f9850..0d4e5ef323 100644 --- a/prebid-server/features/pbs-feature-idx.md +++ b/prebid-server/features/pbs-feature-idx.md @@ -34,6 +34,7 @@ title: Prebid Server | Features | Cache | VAST core | Accepts the ext.prebid.cache.vastxml parameter, storing VAST responses in PBC. | | | | Cache | Winning-only flag | Accepts a 'ext.prebid.cache.winningonly' parameter on the request. If true, instead of caching all bids and VAST, only the winning bid or VAST is stored. | | | | [Stored Requests](/prebid-server/features/pbs-storedreqs.html) | Core | Accepts a stored request ID in the OpenRTB, looks it up against a local data store, and merges with the OpenRTB request record. | | | +| Stored Requests | Unique Per Account | If an account ID is provided, PBS can distinguish between otherwise identical SRIDs. | | | | Stored Responses | Stored Responses | Accepts a stored response ID in the OpenRTB, looks it up against a local data store, and merges with the OpenRTB response record. | | | | First Party Data | Core | Accepts core first party data attributes and supports ext.prebid.data.bidders. | | | | First Party Data | Bidder-specific data | Accepts bidder-specific first party data attributes. | | | From 36fbc9aba7c4c9d755ee3248ca4f3cd93f831ddf Mon Sep 17 00:00:00 2001 From: Dan Bogdan <43830380+EMXDigital@users.noreply.github.com> Date: Fri, 13 Nov 2020 17:11:27 -0500 Subject: [PATCH 090/149] EMXDigital Adapter Updates (#2475) * adding video to supported mediatypes * Adding tcfv2, ccpa and schain support * removing bidder_support_deals Co-authored-by: Rakesh Balakrishnan --- dev-docs/bidders/emx_digital.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/emx_digital.md b/dev-docs/bidders/emx_digital.md index ab62e373e9..19b1d08da3 100644 --- a/dev-docs/bidders/emx_digital.md +++ b/dev-docs/bidders/emx_digital.md @@ -5,10 +5,12 @@ description: Prebid EMX Digital Bidder Adaptor pbjs: true pbs: true biddercode: emx_digital -bidder_supports_deals: false media_types: banner, video gdpr_supported: true gvl_id: 183 +tcf2_supported: true +usp_supported: true +schain_supported: true --- ### Registration From b0b17dcef15e5fef84dc060cf3df559556624a9c Mon Sep 17 00:00:00 2001 From: bretg Date: Mon, 16 Nov 2020 12:53:59 -0500 Subject: [PATCH 091/149] consentManagement: defaultGdprScope defaults to false (#2505) --- dev-docs/modules/consentManagement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/modules/consentManagement.md b/dev-docs/modules/consentManagement.md index 31cd13c25c..5e4d5ea4ae 100644 --- a/dev-docs/modules/consentManagement.md +++ b/dev-docs/modules/consentManagement.md @@ -74,7 +74,7 @@ but we recommend migrating to the new config structure as soon as possible. | gdpr | `Object` | | | | gdpr.cmpApi | `string` | The CMP interface that is in use. Supported values are **'iab'** or **'static'**. Static allows integrations where IAB-formatted consent strings are provided in a non-standard way. Default is `'iab'`. | `'iab'` | | gdpr.timeout | `integer` | Length of time (in milliseconds) to allow the CMP to obtain the GDPR consent string. Default is `10000`. | `10000` | -| gdpr.defaultGdprScope | `boolean` | Defines what the `gdprApplies` flag should be when the CMP doesn't respond in time or the static data doesn't supply. | `true` | +| gdpr.defaultGdprScope | `boolean` | Defines what the `gdprApplies` flag should be when the CMP doesn't respond in time or the static data doesn't supply. Defaults to `false`. | `true` | | gdpr.allowAuctionWithoutConsent | `boolean` | (TCF v1.1 only) Determines what will happen if obtaining consent information from the CMP fails; either allow the auction to proceed (`true`) or cancel the auction (`false`). Default is `true` | `true` | | gdpr.consentData | `Object` | An object representing the GDPR consent data being passed directly; only used when cmpApi is 'static'. Default is `undefined`. | | | gdpr.consentData.getTCData.tcString | `string` | (TCF v2.0 only) Base64url-encoded TCF v2.0 string with segments. | | From 2de9b88c0501d3ae75d1527d9fef01e0f95180cc Mon Sep 17 00:00:00 2001 From: MartianTribe Date: Tue, 17 Nov 2020 12:28:46 -0500 Subject: [PATCH 092/149] iOS instream example (#2508) * iOS instream example * Updated code sample Co-authored-by: Steve Suranie --- _data/sidebar.yml | 9 + pbm-video-instream | 8 + .../pbm-api/ios/pbm-video-instream-ios.md | 202 ++++++++++++++++++ .../ios/pbm-videooutstreamadunit-ios.md | 30 ++- 4 files changed, 232 insertions(+), 17 deletions(-) create mode 100644 pbm-video-instream create mode 100644 prebid-mobile/pbm-api/ios/pbm-video-instream-ios.md diff --git a/_data/sidebar.yml b/_data/sidebar.yml index 4e7b4bf487..0bb8de3f38 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -746,6 +746,15 @@ isSectionHeader: 0 sectionTitle: subgroup: 1 + +- sbSecId: 2 + title: Video Instream Ad Unit + link: /prebid-mobile/pbm-api/ios/pbm-video-instream-ios.html + isHeader: 0 + isSectionHeader: 0 + sectionTitle: + subgroup: 1 + - sbSecId: 2 title: Video interstitial Ad Unit link: /prebid-mobile/pbm-api/ios/pbm-videointerstitialadunit-ios.html diff --git a/pbm-video-instream b/pbm-video-instream new file mode 100644 index 0000000000..5ffd313825 --- /dev/null +++ b/pbm-video-instream @@ -0,0 +1,8 @@ +--- +layout: page_v2 +title: VideoAdUnit AdUnit:Instream +description: VideoAdUnit AdUnit:Instream +top_nav_section: prebid-mobile +nav_section: prebid-mobile +sidebarType: 2 +--- diff --git a/prebid-mobile/pbm-api/ios/pbm-video-instream-ios.md b/prebid-mobile/pbm-api/ios/pbm-video-instream-ios.md new file mode 100644 index 0000000000..c2591172de --- /dev/null +++ b/prebid-mobile/pbm-api/ios/pbm-video-instream-ios.md @@ -0,0 +1,202 @@ +--- +layout: page_v2 +title: VideoAdUnit AdUnit:Instream +description: VideoAdUnit AdUnit:Instream +top_nav_section: prebid-mobile +nav_section: prebid-mobile +sidebarType: 2 +--- + +# VideoAdUnit AdUnit:Instream +{: .notoc} + +This page describes how to implement a `VideoAdUnit` for the display of instream videos. + +The VideoAdUnit is a subclass of the [AdUnit]({{site.baseurl}}/prebid-mobile/pbm-api/ios/pbm-adunit-ios.html) class. Use the VideoAdUnit object to create and configure a video instream ad unit in your app. + +Video instream is only supported with Google Ad Manager. +{: .alert .alert-info} + +- TOC + {:toc} + +## VideoAdUnit + + Create a new Video Instream Ad Unit associated with a Prebid Server configuration ID and a video size. + + See [AdUnit]({{site.baseurl}}/prebid-mobile/pbm-api/ios/pbm-adunit-ios.html) for additional parameters and methods. + + `VideoAdUnit(configId: String, size: CGSize(width: Int, height: Int))` + + **Parameters** + + `configId(String)`: Prebid Server configuration ID. + + `size(CGSize)`: Width and height of the video ad unit. + +### CGSize + + Size of video ad unit. + + **Parameters** + + `width`: Width of video ad unit in DIPs. + + `height`: Height of video ad unit in DIPs. + +### Parameters + + `placement`: [int] or [enum]: OpenRTB placement + + `api`: [int] or [enum]: OpenRTB api frameworks + + `maxBitrate`: int: OpenRTB maxBirate + + `minBitrate`: int: OpenRTB minBitrate + + `maxDuration`:int: OpenRTB maxDuration + + `minDuration`: int: OpenRTB minDuration + + `mimes`: [string]: OpenRTB mime types + + `playbackMethod`: [int]: OpenRTB playbackMethod + + `protocols`: [int] or [enum]: OpenRTB Protocols + +#### api + Array of integers or enum representing the supported OpenRTB 2.5 Frameworks: + - 1 or Signals.Api.VPAID_1 : VPAID 1.0 + - 2 or Signals.Api.VPAID_2 : VPAID 2.0 + - 3 or Signals.Api.MRAID_1 : MRAID-1 + - 4 or Signals.Api.ORMMA : ORMMA + - 5 or Signals.Api.MARAID_2 : MRAID-2 + - 6 or Signals.Api.MARAID_3 : MRAID-3 + +#### maxBitrate + Integer representing the OpenRTB 2.5 maximum bit rate in Kbps. + +#### minBitrate + Integer representing the OpenRTB 2.5 minimum bit rate in Kbps. + +#### maxDuration + Integer representing the OpenRTB 2.5 maximum video ad duration in seconds. + +#### minDuration + Integer representing the OpenRTB 2.5 minimum video ad duration in seconds. + +#### mimes + Array of strings representing the supported OpenRTB 2.5 content MIME types (e.g., “video/x-ms-wmv”, “video/mp4”). + +#### playbackMethod + Array of OpenRTB 2.5 playback methods. If none are specified, any method may be used. Only one method is typically used in practice. It is strongly advised to use only the first element of the array. + - 1 or Signals.PlaybackMethod.AutoPlaySoundOn : Initiates on Page Load with Sound On + - 2 or Signals.PlaybackMethod.AutoPlaySoundOff : Initiates on Page Load with Sound Off by Default + - 3 or Signals.PlaybackMethod.ClickToPlay : Initiates on Click with Sound On + - 4 or Signals.PlaybackMethod.MouseOver : Initiates on Mouse-Over with Sound On + - 5 or Signals.PlaybackMethod.EnterSoundOn : Initiates on Entering Viewport with Sound On + - 6 or Signals.PlaybackMethod.EnterSoundOff: Initiates on Entering Viewport with Sound Off by Default + +#### protocols + Array or enum of OpenRTB 2.5 supported Protocols. Values can be one of: + - 1 or Signals.Protocols.VAST_1_0 : VAST 1.0 + - 2 or Signals.Protocols.VAST_2_0 : VAST 2.0 + - 3 or Signals.Protocols.VAST_3_0 : VAST 3.0 + - 4 or Signals.Protocols.VAST_1_0_Wrapper : VAST 1.0 Wrapper + - 5 or Signals.Protocols.VAST_2_0_Wrapper : VAST 2.0 Wrapper + - 6 or Signals.Protocols.VAST_3_0_Wrapper : VAST 3.0 Wrapper + - 7 or Signals.Protocols.VAST_4_0 : VAST 4.0 + - 8 or Signals.Protocols.VAST_4_0_Wrapper : VAST 4.0 Wrapper + +See our documentation on [AdUnit](/prebid-mobile/pbm-api/ios/pbm-adunit-ios.html) for more details. + +### Helper to Construct Google IMA adServer URL + +This utility method takes the adUnit Id of the publisher along with the adSlot sizes & Prebid custom keywords to construct the IMA adServer URL that the publisher can use to make the request. + +```public func constructAdTagURLForIMAWithPrebidKeys (adUnitID:String, adSlotSizes:[IMAAdSlotSize], customKeywords: [String:String]) throws -> String``` + +### Example + +
+
+
+var adUnit: VideoAdUnit!
+
+var adsLoader: IMAAdsLoader!
+var adsManager: IMAAdsManager!
+
+
+//setup PB Video
+let adUnit = VideoAdUnit(configId: "1001-1")
+
+//video parameters
+parameters.mimes = ["video/mp4"]
+parameters.protocols = [2,3,7]    // or alternative enum values [Protocols.VAST_2_0, Protocols.VAST_3_0]
+parameters.playbackMethod = [1]   // or alternative enum value [PlaybackMethod.AutoPlaySoundOn]
+parameters.api = [1,2]            // or alternative enum values [Api.VPAID_1, Api.VPAID_2]
+parameters.maxBitrate = 1500
+parameters.minBitrate = 300
+parameters.maxDuration = 30
+parameters.minDuration = 5
+
+adUnit.parameters = parameters
+
+//setup IMA Video
+adsLoader = IMAAdsLoader(settings: nil)
+adsLoader.delegate = self
+adUnit.fetchDemand { (ResultCode, prebidKeys: [String : String]?) in
+    print("prebid keys")
+    if(ResultCode == .prebidDemandFetchSuccess){
+        do {
+                     let adServerTag:String = try IMAUtils.shared.constructAdTagURLForIMAWithPrebidKeys(adUnitID: "your_ad_unit",  
+                    adSlotSizes: [.Size640x480,.Size400x300], customKeywords: prebidKeys!)
+                    let adDisplayContainer = IMAAdDisplayContainer(adContainer: self.appInstreamView)
+                    // Create an ad request with our ad tag, display container, and optional user context.
+                    let request = IMAAdsRequest(adTagUrl: adServerTag, adDisplayContainer: adDisplayContainer, contentPlayhead: nil, userContext: nil)
+                    self.adsLoader.requestAds(with: request)
+                }catch {
+                    print (error)
+                }
+    } else {
+                print ("Error constructing IMA Tag")
+            }
+    }
+}
+
+
+//adsLoader delegate
+    func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) {
+        // Grab the instance of the IMAAdsManager and set ourselves as the delegate.
+        adsManager = adsLoadedData.adsManager
+        adsManager.delegate = self
+
+
+        // Create ads rendering settings and tell the SDK to use the in-app browser.
+        let adsRenderingSettings = IMAAdsRenderingSettings()
+        adsRenderingSettings.webOpenerPresentingController = self
+
+
+        // Initialize the ads manager.
+        adsManager.initialize(with: adsRenderingSettings)
+    }
+
+    func adsLoader(_ loader: IMAAdsLoader!, failedWith adErrorData: IMAAdLoadingErrorData!) {
+        print("Error loading ads: \(adErrorData.adError.message ?? "nil")")
+    }
+
+    //adsManager delegate
+    func adsManager(_ adsManager: IMAAdsManager!, didReceive event: IMAAdEvent!) {
+        if event.type == IMAAdEventType.LOADED {
+          // When the SDK notifies us that ads have been loaded, play them.
+          adsManager.start()
+        }
+    }
+
+    func adsManager(_ adsManager: IMAAdsManager!, didReceive error: IMAAdError!) {
+        print("AdsManager error: \(error.message ?? "nil")")
+    }
+
+
+
+
diff --git a/prebid-mobile/pbm-api/ios/pbm-videooutstreamadunit-ios.md b/prebid-mobile/pbm-api/ios/pbm-videooutstreamadunit-ios.md index d33a6bd6fd..f5379e6be3 100755 --- a/prebid-mobile/pbm-api/ios/pbm-videooutstreamadunit-ios.md +++ b/prebid-mobile/pbm-api/ios/pbm-videooutstreamadunit-ios.md @@ -1,15 +1,17 @@ --- layout: page_v2 -title: VideoAdUnit AdUnit -description: VideoAdUnit AdUnit +title: VideoAdUnit AdUnit:Outstream +description: VideoAdUnit AdUnit:Outstream top_nav_section: prebid-mobile nav_section: prebid-mobile sidebarType: 2 --- -# VideoAdUnit: AdUnit +# Outstream VideoAdUnit: AdUnit {: .notoc} +This page describes how to implement a `VideoAdUnit` for the display of outstream videos. + The VideoAdUnit is a subclass of the [AdUnit]({{site.baseurl}}/prebid-mobile/pbm-api/ios/pbm-adunit-ios.html) class. Use the VideoAdUnit object to create and configure a video outstream ad unit in your app. Video Outstream is only supported with Google Ad Manager. @@ -18,11 +20,9 @@ Video Outstream is only supported with Google Ad Manager. - TOC {:toc} +## VideoAdUnit - - -Create a new Video Outstream Ad Unit associated with a Prebid Server configuration ID and a video size. - +Create a new Video Outstream Ad Unit associated with a Prebid Server configuration ID and a video size. See [AdUnit]({{site.baseurl}}/prebid-mobile/pbm-api/ios/pbm-adunit-ios.html) for additional parameters and methods. @@ -36,11 +36,7 @@ See [AdUnit]({{site.baseurl}}/prebid-mobile/pbm-api/ios/pbm-adunit-ios.html) for `type:Enum`: OpenRTB Placement Type. This field is being deprecated in favor of parameters.type - - - - -## CGSize +### CGSize Size of video ad unit. @@ -51,7 +47,7 @@ Size of video ad unit. `height`: Height of video ad unit in DIPs. -## type +### type {% capture deprecate %} VideoAdUnit type will be deprecated in future releases. Use parameters.placement below for future usage of type. @@ -65,9 +61,9 @@ OpenRTB Placement Type represented as an enumeration of values: * inFeed is transformed into OpenRTB value 4 to bid adapters -## Paramaters +### Paramaters -Parameters is a sub class of videoAdUnit.Create new Parameters class to define the parameters of the video ad unit. Parameters contain the OpenRTB video attributes. +Parameters is a sub class of videoAdUnit. Create new Parameters class to define the parameters of the video ad unit. Parameters contain the OpenRTB video attributes. **Parameters** @@ -115,7 +111,7 @@ Array of integers or enum representing the supported [OpenRTB 2.5](https://www.i #### maxBitrate -Integer representing the [OpenRTB 2.5](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) maximum bit rate in Kbps. +Integer representing the [OpenRTB 2.5](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) maximum bit rate in Kbps. #### minBitrate @@ -152,7 +148,7 @@ Array of [OpenRTB 2.5](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-AP #### protocols -Array or enum of [OpenRTB 2.5](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) supported Protocols. Values can be one of: +Array or enum of [OpenRTB 2.5](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) supported Protocols. Values can be one of: * `1` or `Signals.Protocols.VAST_1_0` : VAST 1.0 * `2` or `Signals.Protocols.VAST_2_0` : VAST 2.0 From 1e2caa945bf80c3ef948bb23b3d85121759f949b Mon Sep 17 00:00:00 2001 From: Jurij Sinickij Date: Tue, 17 Nov 2020 19:55:09 +0200 Subject: [PATCH 093/149] adform server bidder supports video (#2488) --- dev-docs/bidders/{adformPbjs.md => adform.md} | 4 +- dev-docs/bidders/adformPbs.md | 48 ------------------- 2 files changed, 2 insertions(+), 50 deletions(-) rename dev-docs/bidders/{adformPbjs.md => adform.md} (97%) delete mode 100644 dev-docs/bidders/adformPbs.md diff --git a/dev-docs/bidders/adformPbjs.md b/dev-docs/bidders/adform.md similarity index 97% rename from dev-docs/bidders/adformPbjs.md rename to dev-docs/bidders/adform.md index a27591e5f6..7aefb1e764 100644 --- a/dev-docs/bidders/adformPbjs.md +++ b/dev-docs/bidders/adform.md @@ -1,7 +1,7 @@ --- layout: bidder title: Adform -description: Prebid.js Adform Bidder Adaptor +description: Prebid Adform Bidder Adaptor biddercode: adform media_types: banner, video gdpr_supported: true @@ -9,7 +9,7 @@ usp_supported: true tcf2_supported: true prebid_member: true pbjs: true -pbs: false +pbs: true userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, sharedId, unifiedId gvl_id: 50 --- diff --git a/dev-docs/bidders/adformPbs.md b/dev-docs/bidders/adformPbs.md deleted file mode 100644 index cdb6b81922..0000000000 --- a/dev-docs/bidders/adformPbs.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -layout: bidder -title: Adform -description: Prebid Server Adform Bidder Adaptor -biddercode: adform -media_types: banner -gdpr_supported: true -usp_supported: true -tcf2_supported: true -prebid_member: true -pbjs: false -pbs: true -userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, sharedId, unifiedId -gvl_id: 50 ---- - - -### Bid Params - -{: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|-------------|----------|-----------------------------------------------|----------------------------|-----------| -| `mid` | required | | `12345` | `integer` | -| `adxDomain` | optional | The Adform domain | `'adx.adform.net'` | `string` | -| `priceType` | optional | An expected price type (net or gross) of bids | `'net'` | `string` | -| `mkv` | optional | Comma-separated key-value pairs | `'city:NY'` | `string` | -| `mkw` | optional | Comma-separated keywords | `'news,sport'` | `string` | -| `minp` | optional | Minimum CPM price | `2.55` | `number` | -| `cdims` | optional | Comma-separated creative dimentions | `'300x250'` | `string` | -| `url` | optional | Custom targeting URL | `'https://some.app/?home'` | `string` | - -Note: Spaces are not allowed between comma-separated list values. For example: -``` -// valid params -{ - mid: 12345, - mkv: 'city:NY,city:London', - mkv: 'news,sport', - cdims: '300x250,250x300' -} -// invalid params -{ - mid: 12345, - mkv: 'city:NY, city:London', - mkv: 'news, sport', - cdims: '300x250, 250x300' -} -``` From 9f5a3a8652564c137c89cb22262bd97bf26f8b10 Mon Sep 17 00:00:00 2001 From: Yevhenii Melnyk Date: Tue, 17 Nov 2020 19:03:44 +0100 Subject: [PATCH 094/149] LiveIntent id module. Add an "emailHash" param (#2497) * LiveIntent id module "emailHash" param * Add hash types into description --- dev-docs/modules/userId.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index b87ad3cde9..ba8e399b8a 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -617,6 +617,7 @@ The LiveIntent ID sub-module follows the standard Prebid.js initialization based | params.ajaxTimeout |Optional| Number |This configuration parameter defines the maximum duration of a call to the IdentityResolution endpoint. By default, 1000 milliseconds.|`1000`| | params.partner | Optional| String |The name of the partner whose data will be returned in the response.|`'prebid'`| | params.identifiersToResolve |Optional| Array[String] |Used to send additional identifiers in the request for LiveIntent to resolve against the LiveIntent ID.|`['my-id']`| +| params.emailHash |Optional| String |The hashed email address of a user. We can accept the hashes, which use the following hashing algorithms: md5, sha1, sha2.|`1a79a4d60de6718e8e5b326e338ae533`| | params.url | Optional| String |Use this to change the default endpoint URL if you can call the LiveIntent Identity Exchange within your own domain.|`'https://idx.my-domain.com'`| | params.liCollectConfig |Optional| Object |Container of all collector params.|| | params.liCollectConfig.fpiStorageStrategy |Optional| String |This parameter defines whether the first party identifiers that LiveConnect creates and updates are stored in a cookie jar, or in local storage. If nothing is set, default behaviour would be `cookie`. Allowed values: [`cookie`, `ls`, `none`]|`'cookie'`| From c2a70b1edf5c43f97dd3eacd7907b7453a96241c Mon Sep 17 00:00:00 2001 From: John Salis Date: Tue, 17 Nov 2020 13:04:55 -0500 Subject: [PATCH 095/149] add identityLink to supported userIds (#2499) Co-authored-by: John Salis --- dev-docs/bidders/beachfront.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/beachfront.md b/dev-docs/bidders/beachfront.md index 98df223d20..53cfac114a 100644 --- a/dev-docs/bidders/beachfront.md +++ b/dev-docs/bidders/beachfront.md @@ -6,7 +6,7 @@ biddercode: beachfront media_types: video gdpr_supported: true usp_supported: true -userIds: unifiedId +userIds: unifiedId, identityLink prebid_member: true pbjs: true pbs: true From 62e0aa7486893c902d2684595a17bae8a41fcca3 Mon Sep 17 00:00:00 2001 From: jdwieland8282 Date: Tue, 17 Nov 2020 12:22:43 -0700 Subject: [PATCH 096/149] Update sidebar.yml (#2509) * Update sidebar.yml adding ID Library to modules sidebar * Fixed sidebar YML, the ID entry had extra space on it. The entry had - sbSecId and needed to just be - sbSecId Co-authored-by: Steve --- _data/sidebar.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/_data/sidebar.yml b/_data/sidebar.yml index 0bb8de3f38..bbd4d63a34 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -521,6 +521,15 @@ sectionTitle: subgroup: 5 +- sbSecId: 1 + title: ID Library + link: /dev-docs/modules/idLibrary.html + isLastSubSectionItem: 0 + isHeader: 0 + isSectionHeader: 0 + sectionTitle: + subgroup: 5 + - sbSecId: 1 title: External Interfaces link: From 1782ae1b4f77bff47738768439473f8e633c81c9 Mon Sep 17 00:00:00 2001 From: Ben Anderson Date: Tue, 17 Nov 2020 14:23:41 -0500 Subject: [PATCH 097/149] neustar fabrick email address update (#2513) Co-authored-by: Anderson, Ben --- dev-docs/modules/userId.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index ba8e399b8a..c7cd9d2d9d 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -164,7 +164,7 @@ gulp build --modules=fabrickIdSystem #### Fabrick Registration -Please reach out to [integrations@team.neustar](mailto:integrations@team.neustar) to request your `apiKey`. +Please reach out to [FabrickIntegrations@team.neustar](mailto:FabrickIntegrations@team.neustar) to request your `apiKey`. #### Fabrick Configuration From d42e58de8052aa7193c0f718af5415f05f4f3689 Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 17 Nov 2020 15:03:25 -0500 Subject: [PATCH 098/149] code of conduct update (#2514) --- _posts/2019-01-08-updated-website.md | 2 +- assets/images/code-of-conduct-diagram.png | Bin 0 -> 31271 bytes overview/community-code-of-conduct.md | 113 ------------------- wrapper_code_of_conduct.md | 127 ++++++++++++++-------- 4 files changed, 81 insertions(+), 161 deletions(-) create mode 100644 assets/images/code-of-conduct-diagram.png delete mode 100644 overview/community-code-of-conduct.md diff --git a/_posts/2019-01-08-updated-website.md b/_posts/2019-01-08-updated-website.md index f3cd3d0ba0..16eb9b21ce 100644 --- a/_posts/2019-01-08-updated-website.md +++ b/_posts/2019-01-08-updated-website.md @@ -21,7 +21,7 @@ permalink: /blog/updated-website - **New Content**: - [Prebid Server docs](/prebid-server/prebid-server-overview.html) - [Product Management Committees](/overview/prebid-management-committees.html) - - [Community Code of Conduct](/overview/community-code-of-conduct.html) + - [Community Code of Conduct](https://prebid.org/code-of-conduct/#community) - [Prebid Members and Partners](/partners/partners.html) - [Prebid Members providing Managed Services](https://prebid.org/product-suite/managed-services/) - [Format index page](/formats/formats.html) diff --git a/assets/images/code-of-conduct-diagram.png b/assets/images/code-of-conduct-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..e8bb0fa0f3fb41ba1210f18c741106ead0f64291 GIT binary patch literal 31271 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 dvx}aPlEPy$-iDh|J%211Dyt+@DP(Text in the section above based on the Django Code of Conduct) - -## Prebid Conduct Reporting Guide - -If you believe someone is violating the code of conduct we ask that you report it to Prebid.org by emailing conduct@prebid.org. All reports will be kept confidential. In some cases we may determine that a public statement will need to be made. If that's the case, the identities of all victims and reporters will remain confidential unless those individuals instruct us otherwise. -If you believe anyone is in physical danger, please notify appropriate law enforcement first. If you are unsure what law enforcement agency is appropriate, please include this in your report and we will attempt to notify them. - -We encourage you to report an incident even if you are unsure whether it is a violation, or whether the space where it happened is covered by this Code of Conduct. We would much rather have a few extra reports where we decide to take no action than miss a report of an actual violation. We do not look negatively on you if we find the incident is not a violation. And knowing about incidents that are not violations, or happen outside our spaces, can also help us to improve the Code of Conduct and the processes surrounding it. - -In your report please include: - -+ Your contact info (so we can get in touch with you if we need to follow up). -+ Names (real, nicknames, or pseudonyms) of any individuals involved. If there were other witnesses besides you, please try to include them as well. -+ When and where the incident occurred. Please be as specific as possible. -+ Your account of what occurred. If there is a publicly available record (e.g. a mailing list archive or a public IRC logger) please include a link. -+ Any extra context you believe existed for the incident. -+ Whether you believe this incident is ongoing. -+ Any other information you believe we should have. - -### What happens after you file a report? - -You will receive an email from Prebid.org acknowledging receipt. We promise to acknowledge receipt within one business day. - -The working group will meet to review the incident and determine: - -+ What happened. -+ Whether this event constitutes a Code of Conduct violation. -+ Who the bad actor was. -+ Whether this is an ongoing situation, or if there is a threat to anyone's physical safety. - -If the incident is determined to be ongoing or a threat to physical safety, the working groups' immediate priority will be to protect everyone involved. This means we may delay an "official" response until we believe that the situation has ended and that everyone is physically safe. -Once the working group has a complete account of the events we will make a decision as to how to respond. Responses may include: - -+ Nothing (if we determine no violation occurred). -+ A technical fix, if appropriate. -+ A private reprimand from the working group to the individual(s) involved. -+ A public reprimand. -+ An imposed vacation (i.e. asking someone to "take a week off" from a mailing list or Slack). -+ A permanent or temporary ban from some or all Prebid spaces (mailing lists, Slack, etc.) -+ A request for a public or private apology. - -We'll respond within one week to the person who filed the report with either a resolution or an explanation of why the situation is not yet resolved. - -Once we've determined our final action, we'll contact the original reporter with an update. - -Finally, the working group will make a report on the situation to the Prebid.org Board. The Board may choose to release a public report of the incident. - -### Reconsideration - -Any of the parties directly involved or affected can request reconsideration of the committee’s decision. To make such a request, contact the Prebid.org Board at board@prebid.org with your request and motivation and the board will review the case. - -(Text in the section above based on the Django Code of Conduct Reporting Guide) - -## Further Reading - -+ [Header Bidding Wrapper Code of Conduct](/wrapper_code_of_conduct.html) -+ [About Prebid.org](/overview/what-is-prebid-org.html) diff --git a/wrapper_code_of_conduct.md b/wrapper_code_of_conduct.md index 608521d72b..392acd03b7 100644 --- a/wrapper_code_of_conduct.md +++ b/wrapper_code_of_conduct.md @@ -5,56 +5,89 @@ description: Full text of the Prebid.org Header Bidding Wrapper Code of Conduct sidebarType: 0 --- - - -# Prebid.org Header Bidding Wrapper Code of Conduct +# Prebid.org Header Bidding Code of Conduct {:.no_toc} -This Wrapper Code of Conduct establishes the principles by which we believe header bidding wrappers should operate. +Nov 17, 2020 + +In order to encourage the development of quality products while maintaining a healthy open source community, Prebid.org members and contributors are expected to abide by technical guidelines based on the core values of the organization. * TOC {:toc} -## Definitions - -* _Wrapper_: any technology layer that facilitates bids from demand partners being passed into the decisioning layer. -* _Demand partner_: any party that is willing to provide a price to be paid to the publisher for a given impression, and is integrated into the wrapper. -* _Publisher_: the party who is integrating the wrapper into their page. -* _Decisioning layer_: the technology that decides the final winning bid. - -## Auction Logic - -* The wrapper must not modify bids from demand partners, except to: - * Apply a modification that changes the bid from gross to net or; - * Apply a modification that changes the bid from one currency to another. -* The wrapper must provide equal opportunity for all demand partners to bid, either by requesting bids simultaneously or by randomizing the order in which they are called. -* The wrapper must send all demand returned within the publisher-configured timeout to the decisioning layer. -* The decisioning layer must make the final choice of what bid wins. -* The wrapper must provide a mechanism to validate that submitted bid responses were sent to the decisioning layer. -* The wrapper must provide a mechanism or process for publishers and demand partners to validate fairness of the wrapper. -* The wrapper must not favor any demand partner in any way, including any demand that is provided by a bidder that is also hosting the wrapper. - -## Data and Transparency - -* The wrapper must segregate demand data so there is no opportunity for demand partners to have access to other bids. -* The wrapper must pass all available bid request information to each demand partner. -* The wrapper must not collect and store publisher or demand partner information except in the process of passing information to demand partners, validating wrapper mechanics, providing aggregated reporting to publishers, or troubleshooting and diagnosing implementations. - * This includes bid stream information, user information, and publisher first party data. - * For any bidder-level data aggregated for any of the approved purposes, the wrapper must disclose to the bidder in question the use cases. -* The wrapper must not record, use, or sell publisher or demand partner data without permission from the publisher and the demand partner. -* The wrapper must be able to provide mechanical data relating to each auction: who was called, who responded on time, and who responded late. -* If the wrapper charges fees, the fee structure should be disclosed to all parties involved in the setup. - -## User Experience - -* The wrapper must make a best effort to minimize the impact on the user's web browsing experience. -* The wrapper must not allow any demand partners to have any blocking or synchronous steps in the process of eliciting a bid. -* Publishers must set timeout periods, and the timeouts should be consistent across all demand partners within a given auction. -* The wrapper must reject any bid responses received after the conclusion of the timeout period. -* The wrapper must send bids to the decisioning layer as soon as all demand partners have responded or the timeout has been reached. - -## Further Reading - -+ [Project Principles]({{site.baseurl}}/principles.html) -+ [Getting Started]({{site.baseurl}}/overview/getting-started.html) -+ [Prebid.org Community Code of Conduct](https://prebid.org/code-of-conduct/) +## Prebid.org Core Values + +The main objective of Prebid.org is to make great header bidding technology available for web publishers and mobile app developers. We believe great technology is: + +- **Efficient** - Products offered by Prebid.org should not burden a user device, the network, or a company server. +- **Secure** - Prebid.org software should not open doors to security risks, including electronic attack, denial of service, fraud, or data leakage. +- **Transparent** - Our products are built in the open with community review. Changes to Prebid software and modules must be open to inspection before and after release. +- **Fair** - The Prebid.org platform doesn’t favor any one entity over another. No entity can be favored over another in technical ordering or status as a default value. No entity can gain information about another entity without approval. +- **Collaborative** - Human interactions in Prebid.org public forums and events must be courteous. +- **Privacy Sensitive** - Our products are built for publishers to support users’ privacy concerns and comply with industry standards. + +## Auction Principles + +The guidelines in this section apply to open source software written for the Prebid.org platform, or plugins designed to integrate into the Prebid.org platform. + +**Definitions:** + +- **Publisher**: the party who is integrating the header bidding technology into their page, app, video service, etc. They may integrate Prebid software on their own or through an approved agent. +- **Publisher Agent**: a party who helps a Publisher integrate or install Prebid software. +- **Auction Layer**: the part of the system that facilitates bids from demand partners being passed into the decisioning layer. +- **Demand Partner**: any party that is willing to provide a price to be paid to the Publisher for a given impression, and is integrated into header bidding. +- **Decisioning Layer**: the part of the system that decides the final winning bid. + +![Conduct](/assets/images/code-of-conduct-diagram.png){:class="pb-lg-img"} + +### Auction Logic + +1. The Auction Layer must not modify bids from Demand Partners unless specifically instructed to do so by configuration. For example, a Publisher might instruct the Auction Layer to: + 1. Apply a modification that changes the bid from gross to net or; + 1. Apply a modification that changes the bid from one currency to another; + 1. Account for a consistent discrepancy; + 1. Account for managed service fees; + 1. Drop bids that do not meet the floor requirement +1. The Auction Layer must provide equal opportunity for all Demand Partners to bid, either by randomizing the order in which they are called, or by requesting bids in the order specified by the publisher. + 1. Publisher configuration may override which bidders take part in each auction. + 1. This also specifically covers any situation where a Publisher Agent is also a Demand Partner or a Demand Partner is hosting the Auction Layer. +1. The Auction Layer must send all demand returned within the configured timeout period to the Decisioning Layer. +1. The Decisioning Layer must make the final choice of which bid wins unless configured to do otherwise. +1. The Decisioning Layer can be determined by the Publisher, e.g. It could be an ad server or the same software that implements the Auction Layer, or a proxy server. If decisioning is done in Prebid software, it must conform to all other rules in this section. +1. The Auction Layer should provide a mechanism or process for Publishers and Demand Partners to validate auction mechanics, including: + 1. Confirmation that bid requests were sent to Demand Partners + 1. Confirmation that bid responses were sent to the Decisioning Layer + 1. Confirmation that the correct bid values were sent to the Decisioning Layer + 1. Bid timing information such as which Demand Partners met the timeout period + +### Data and Transparency + +1. The Auction Layer must segregate demand data so there is no opportunity for Demand Partners to have access to other bids or bidder data. +1. The Auction Layer must pass available bid request information to each configured demand partner, subject to Publisher configuration and privacy regulation controls. +1. The Auction Layer must not collect and store Publisher or Demand Partner information (such as bid stream information, user information, and Publisher first party data) except in the following cases: + 1. Passing information to Demand Partners or Analytics Adapters + 1. Validating header bidding mechanics + 1. Troubleshooting and diagnosing implementations +1. The Auction Layer must not record, use, or sell Publisher or Demand Partner data except in accordance with the instructions of the Publisher and the Demand Partner. +1. The Prebid ecosystem will endeavor to support industry standard privacy regulations, including allowing Publishers to transmit notice, consent, and opt-out state. +1. Analytics Adapters must not utilize header bidding auction data outside of any agreement they reached with the Publisher. + +### User Experience + +1. The system should minimize the impact on the user’s web browsing experience. +1. Users, Publishers and Advertisers deserve a reliable ad serving environment. Prebid software should facilitate data that helps determine if an impression is fraudulent or undisplayable for any reason. +1. Publishers should be able to utilize Prebid software while adhering to their privacy policies. + +1. Adapter Conduct + +Prebid software supports different types of ‘plugin’ modules, including for example bid adapters, analytics adapters, user ID modules, real-time-data modules, and others. + +1. Adapters of all types must follow all of the above guidelines and specific technical rules defined by the relevant Prebid committee. + 1. Prebid.js and Prebid Server technical rules are defined by Prebid Module Rules. +1. As technical rules may change over time, Prebid committees are empowered to force adapters to change specific behaviors as part of major milestone releases. The committees should strive to give the adapter community ample opportunity to weigh in on specific guidelines and ample time to make changes. + +## Information and Resources + +- [Prebid.org Community Code of Conduct](https://prebid.org/code-of-conduct/#community) +- [Prebid.org Member Companies](https://prebid.org/membership/member-directory/) +- [Prebid Module Rules](/dev-docs/module-rules.html) From 729a91a16a515bcea83b88273b4f99417d3be4ad Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 17 Nov 2020 15:23:22 -0500 Subject: [PATCH 099/149] code of conduct formatting (#2515) --- wrapper_code_of_conduct.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrapper_code_of_conduct.md b/wrapper_code_of_conduct.md index 392acd03b7..28a23408f7 100644 --- a/wrapper_code_of_conduct.md +++ b/wrapper_code_of_conduct.md @@ -78,7 +78,7 @@ The guidelines in this section apply to open source software written for the Pre 1. Users, Publishers and Advertisers deserve a reliable ad serving environment. Prebid software should facilitate data that helps determine if an impression is fraudulent or undisplayable for any reason. 1. Publishers should be able to utilize Prebid software while adhering to their privacy policies. -1. Adapter Conduct +### Adapter Conduct Prebid software supports different types of ‘plugin’ modules, including for example bid adapters, analytics adapters, user ID modules, real-time-data modules, and others. From dc71bc3995ac5a209f529aa211ade008a2416934 Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 17 Nov 2020 17:12:43 -0500 Subject: [PATCH 100/149] Dev page (#2516) * developers index page readability * missing colon --- developers.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/developers.md b/developers.md index 5b7c7064c5..8126bf86cf 100644 --- a/developers.md +++ b/developers.md @@ -15,25 +15,25 @@ sidebarType: 0 Key links for publisher developers. -### Prebid.js - integrating display and video ads in standard web pages. +**Prebid.js** - integrating display and video ads in standard web pages: -+ [What is Prebid.js]({{site.baseurl}}/prebid/prebidjs.html) -+ [Getting Started with Prebid.js]({{site.baseurl}}/dev-docs/getting-started.html) -+ [Publisher API Reference]({{site.baseurl}}/dev-docs/publisher-api-reference.html) -+ [Download a Prebid.js package]({{site.baseurl}}/download.html) -+ [Troubleshooting Guide]({{site.baseurl}}/dev-docs/prebid-troubleshooting-guide.html) ++ [What is Prebid.js](/prebid/prebidjs.html) ++ [Getting Started with Prebid.js](/dev-docs/getting-started.html) ++ [Publisher API Reference](/dev-docs/publisher-api-reference.html) ++ [Download a Prebid.js package](/download.html) ++ [Troubleshooting Guide](/dev-docs/prebid-troubleshooting-guide.html) -### Prebid for AMP - integrating display ads into AMP pages +**Prebid for AMP** - integrating display ads into AMP pages: -+ [How Prebid on AMP works]({{site.baseurl}}/dev-docs/how-prebid-on-amp-works.html) -+ [Prebid AMP Implementation Guide]({{site.baseurl}}/dev-docs/show-prebid-ads-on-amp-pages.html) -+ [Prebid Server AMP endpoint documentation]({{site.baseurl}}/prebid-server/endpoints/openrtb2/pbs-endpoint-amp.html) ++ [How Prebid on AMP works](/dev-docs/how-prebid-on-amp-works.html) ++ [Prebid AMP Implementation Guide](/dev-docs/show-prebid-ads-on-amp-pages.html) ++ [Prebid Server AMP endpoint documentation](/prebid-server/endpoints/openrtb2/pbs-endpoint-amp.html) -### Prebid Mobile - integrating display, video, and native ads into iOS and Android apps +**Prebid Mobile** - integrating display, video, and native ads into iOS and Android apps: -+ [Getting started with Prebid Mobile]({{site.baseurl}}/prebid-mobile/prebid-mobile-pbs.html) -+ [Android code integration]({{site.baseurl}}/prebid-mobile/pbm-api/android/code-integration-android.html) -+ [iOS code integration]({{site.baseurl}}/prebid-mobile/pbm-api//ios/code-integration-ios.html) ++ [Getting started with Prebid Mobile](/prebid-mobile/prebid-mobile-pbs.html) ++ [Android code integration](/prebid-mobile/pbm-api/android/code-integration-android.html) ++ [iOS code integration](/prebid-mobile/pbm-api//ios/code-integration-ios.html) --- @@ -43,12 +43,12 @@ Key links for publisher developers. Key links for integrating into the Prebid ecosystem. -### Prebid.js - adding an adapter +**Prebid.js** - adding an adapter: -+ [How to add a bid adapter]({{site.baseurl}}/dev-docs/bidder-adaptor.html) -+ [How to add an analytics adapter]({{site.baseurl}}/dev-docs/integrate-with-the-prebid-analytics-api.html) ++ [How to add a bid adapter](/dev-docs/bidder-adaptor.html) ++ [How to add an analytics adapter](/dev-docs/integrate-with-the-prebid-analytics-api.html) + [Open source repository](https://github.com/prebid/Prebid.js) -### Prebid Server - adding an adapter +**Prebid Server** - adding an adapter: -+ [Adding a new bid adapter]({{site.baseurl}}/prebid-server/developers/add-new-bidder-go.html) ++ [Adding a new bid adapter](/prebid-server/developers/add-new-bidder-go.html) From 274333033718843b8a981bccff60c761587aa639 Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 17 Nov 2020 17:19:36 -0500 Subject: [PATCH 101/149] removing browsi from sidenav (#2517) --- _data/sidebar.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/_data/sidebar.yml b/_data/sidebar.yml index bbd4d63a34..3ede205974 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -503,15 +503,6 @@ sectionTitle: subgroup: 5 -- sbSecId: 1 - title: Browsi Viewability Module - link: /dev-docs/modules/browsiRtdProvider.html - isLastSubSectionItem: 1 - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - - sbSecId: 1 title: GPT Pre-Auction Module link: /dev-docs/modules/gpt-pre-auction.html From 1c6d6da683f84f9ff943c523c7d4f2efb1523528 Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 17 Nov 2020 17:29:00 -0500 Subject: [PATCH 102/149] tidying modules in sidenav --- _data/sidebar.yml | 130 +++----------------------------------- dev-docs/modules/index.md | 5 +- 2 files changed, 10 insertions(+), 125 deletions(-) diff --git a/_data/sidebar.yml b/_data/sidebar.yml index 3ede205974..8f3407d469 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -376,146 +376,32 @@ subgroup: 5 - sbSecId: 1 - title: Currency - link: /dev-docs/modules/currency.html + title: General Modules + link: /dev-docs/modules/index.html#general-modules isHeader: 0 isSectionHeader: 0 sectionTitle: subgroup: 5 - sbSecId: 1 - title: Google Ad Manager Express - link: /dev-docs/modules/dfp_express.html + title: Real Time Data Providers + link: /dev-docs/modules/index.html#real-time-data-providers isHeader: 0 isSectionHeader: 0 sectionTitle: subgroup: 5 - sbSecId: 1 - title: Consent Management - GDPR - link: /dev-docs/modules/consentManagement.html + title: Video Modules + link: /dev-docs/modules/index.html#video-modules isHeader: 0 isSectionHeader: 0 sectionTitle: subgroup: 5 - sbSecId: 1 - title: GDPR Enforcement - link: /dev-docs/modules/gdprEnforcement.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: Consent Management - US Privacy (CCPA) - link: /dev-docs/modules/consentManagementUsp.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: Floors Module - link: /dev-docs/modules/floors.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: Supply Chain Object - link: /dev-docs/modules/schain.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: User ID - link: /dev-docs/modules/userId.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: Server To Server Testing - link: /dev-docs/modules/s2sTesting.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: Advanced Size Mapping - link: /dev-docs/modules/sizeMappingV2.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: Google Ad Manager Video - link: /dev-docs/modules/dfp_video.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: Instream Video Ads Tracking - link: /dev-docs/modules/instreamTracking.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: Freewheel Module - link: /dev-docs/modules/freewheel.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: Ad Pod Module - link: /dev-docs/modules/adpod.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: Category Translation - link: /dev-docs/modules/categoryTranslation.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: Konduit Accelerate Module - link: /dev-docs/modules/konduit.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: GPT Pre-Auction Module - link: /dev-docs/modules/gpt-pre-auction.html - isLastSubSectionItem: 1 - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 5 - -- sbSecId: 1 - title: ID Library - link: /dev-docs/modules/idLibrary.html - isLastSubSectionItem: 0 + title: Testing and Debug Modules + link: /dev-docs/modules/index.html#testing-and-debug-modules isHeader: 0 isSectionHeader: 0 sectionTitle: diff --git a/dev-docs/modules/index.md b/dev-docs/modules/index.md index 21083cd7ac..2587c30823 100644 --- a/dev-docs/modules/index.md +++ b/dev-docs/modules/index.md @@ -91,6 +91,5 @@ If you are looking for bidder adapter parameters, see [Bidders' Params]({{site.b ## Further Reading + [Source code of all modules](https://github.com/prebid/Prebid.js/tree/master/modules) -+ [Bidders' Params]({{site.baseurl}}/dev-docs/bidders.html) - - ++ [Bidders' Params](/dev-docs/bidders.html) ++ [How to add a Real Time Data Submodule](/dev-docs/add-rtd-submodule.html) From 72e51cf9947e5f2c5c4aafb22227c8785b9053b0 Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 18 Nov 2020 10:37:27 -0500 Subject: [PATCH 103/149] pbs-java repo move (#2520) --- faq/prebid-server-faq.md | 8 ++++---- overview/prebid-management-committees.md | 4 ++-- prebid-mobile/prebid-mobile-pbs.md | 2 +- prebid-server/developers/add-new-bidder-java.md | 8 ++++---- prebid-server/developers/code-reviews.md | 2 +- prebid-server/developers/installing-java.md | 8 ++++---- .../developers/pbs-build-an-analytics-adapter.md | 4 ++-- prebid-server/features/pbs-privacy.md | 2 +- prebid-server/versions/pbs-versions-java.md | 2 +- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/faq/prebid-server-faq.md b/faq/prebid-server-faq.md index edb521be8f..d6cb5b366b 100644 --- a/faq/prebid-server-faq.md +++ b/faq/prebid-server-faq.md @@ -17,8 +17,8 @@ This page has answers to some frequently asked questions about Prebid Server. If Nope. The only approval process is a code review. There are separate instructions for: -- [Prebid Server - Go](https://github.com/prebid/prebid-server/blob/master/docs/developers/add-new-bidder.md) -- [Prebid Server - Java](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/developers/add-new-bidder.md) +- [Prebid Server - Go](/prebid-server/developers/add-new-bidder-go.html) +- [Prebid Server - Java](/prebid-server/developers/add-new-bidder-java.html) As for [membership](https://prebid.org/membership/) in Prebid.org, that's entirely optional -- we'd be happy to have you join and participate in the various committees, but it's not necessary for contributing code as a community member. @@ -35,10 +35,10 @@ The original version of Prebid Server was the Go-Lang version. Rubicon Project ported it to Java because they had more Java talent than Go. + [Prebid Server - Go](https://github.com/prebid/prebid-server) -+ [Prebid Server - Java](https://github.com/rubicon-project/prebid-server-java) ++ [Prebid Server - Java](https://github.com/prebid/prebid-server-java) Both versions are live in production, and they are kept identical in external APIs -and reasonably close in functionality. See [https://github.com/rubicon-project/prebid-server-java/blob/master/docs/differenceBetweenPBSGo-and-Java.md](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/differenceBetweenPBSGo-and-Java.md) for the list of differences. +and reasonably close in functionality. See the [Prebid Server feature list](/prebid-server/features/pbs-feature-idx.html) for the list of differences. For demand partners, we recommend building new bid adapters in Go - the team will port it to Java for you within a couple of months. diff --git a/overview/prebid-management-committees.md b/overview/prebid-management-committees.md index 170c5974c5..daedc6563a 100644 --- a/overview/prebid-management-committees.md +++ b/overview/prebid-management-committees.md @@ -65,8 +65,8 @@ GitHub Repositories: + https://github.com/prebid/prebid-server + https://github.com/prebid/prebid-cache -+ https://github.com/rubicon-project/prebid-server-java -+ https://github.com/rubicon-project/prebid-cache-java ++ https://github.com/prebid/prebid-server-java ++ https://github.com/prebid/prebid-cache-java ## Prebid Tools diff --git a/prebid-mobile/prebid-mobile-pbs.md b/prebid-mobile/prebid-mobile-pbs.md index 2d1c97708e..64cf7dd104 100644 --- a/prebid-mobile/prebid-mobile-pbs.md +++ b/prebid-mobile/prebid-mobile-pbs.md @@ -31,7 +31,7 @@ Before you begin using Prebid Mobile in your apps, you need to prepare your end- ### Implement Your Own Prebid Server Host -Prebid Server is an open source project. This allows you to host your own implementation of Prebid Server, though it's not as easy as downloading Prebid.js, because it needs to be hosted. The source code is available under the [Prebid organization on GitHub](https://github.com/prebid/prebid-server). There's also a [Java version of Prebid Server](https://github.com/rubicon-project/prebid-server-java). +Prebid Server is an open source project. This allows you to host your own implementation of Prebid Server, though it's not as easy as downloading Prebid.js, because it needs to be hosted. The source code is available under the [Prebid organization on GitHub](https://github.com/prebid/prebid-server). There's also a [Java version of Prebid Server](https://github.com/prebid/prebid-server-java). See the [Prebid Server docs on GitHub](https://github.com/prebid/prebid-server/tree/master/docs/developers) for more information on setting up your own server host. diff --git a/prebid-server/developers/add-new-bidder-java.md b/prebid-server/developers/add-new-bidder-java.md index 5a4d296f70..f1b135904b 100644 --- a/prebid-server/developers/add-new-bidder-java.md +++ b/prebid-server/developers/add-new-bidder-java.md @@ -18,7 +18,7 @@ Publishers can correct for gross-price bids by setting [Bid Adjustments](/prebid ## Choose a Bidder Name -This name must be unique. Existing BidderNames can be found [here](https://github.com/rubicon-project/prebid-server-java/tree/master/src/main/java/org/prebid/server/bidder). +This name must be unique. Existing BidderNames can be found [here](https://github.com/prebid/prebid-server-java/tree/master/src/main/java/org/prebid/server/bidder). Throughout the rest of this document, substitute `{bidder}` with the name you've chosen. @@ -50,7 +50,7 @@ Prebid Server bid adapters must follow all required conventions defined in the [ ### Generic OpenRTB Bidder There's an option to implement a bidder by using a pre-existing template. -OpenrtbBidder(https://github.com/rubicon-project/prebid-server-java/blob/master/src/main/java/org/prebid/server/bidder/OpenrtbBidder.java) is an abstract class that +OpenrtbBidder(https://github.com/prebid/prebid-server-java/blob/master/src/main/java/org/prebid/server/bidder/OpenrtbBidder.java) is an abstract class that implements Bidder interface and provides a default implementation of its methods. This class provides a fixed algorithm with number of certain access points(so called hook-methods) that @@ -195,7 +195,7 @@ We expect to see at least 90% code coverage on each bidder. ### Manual Tests -[Configure](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/config.md), [build](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/build.md) and [start](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/run.md) your server. +[Configure](https://github.com/prebid/prebid-server-java/blob/master/docs/config.md), [build](https://github.com/prebid/prebid-server-java/blob/master/docs/build.md) and [start](https://github.com/prebid/prebid-server-java/blob/master/docs/run.md) your server. Then `POST` an OpenRTB Request to `http://localhost:8000/openrtb2/auction`. @@ -214,4 +214,4 @@ There are two documents required before we’ll accept your pull request: ## Contribute -Finally, [Contribute](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/contributing.md) your Bidder to the project. +Finally, [Contribute](https://github.com/prebid/prebid-server-java/blob/master/docs/contributing.md) your Bidder to the project. diff --git a/prebid-server/developers/code-reviews.md b/prebid-server/developers/code-reviews.md index 10202d468a..737779afbe 100644 --- a/prebid-server/developers/code-reviews.md +++ b/prebid-server/developers/code-reviews.md @@ -9,7 +9,7 @@ title: Prebid Server | Developers | Code Reviews ## Standards Anyone is free to review and comment on any [open pull requests](https://github.com/prebid/prebid-server/pulls). -for either [PBS-Go](https://github.com/prebid/prebid-server/pulls) or [PBS-Java](https://github.com/rubicon-project/prebid-server-java/pulls) +for either [PBS-Go](https://github.com/prebid/prebid-server/pulls) or [PBS-Java](https://github.com/prebid/prebid-server-java/pulls) All pull requests must be reviewed and approved by at least one core member before merge. diff --git a/prebid-server/developers/installing-java.md b/prebid-server/developers/installing-java.md index c061e34204..d34bb1a7d4 100644 --- a/prebid-server/developers/installing-java.md +++ b/prebid-server/developers/installing-java.md @@ -15,17 +15,17 @@ We use [Maven](https://maven.apache.org) and attempt to introduce minimal depend ## Getting Started To start the Prebid Server you need to do the following steps: -- Build all-in-one JAR file from sources as described in the [build documentation](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/build.md). +- Build all-in-one JAR file from sources as described in the [build documentation](https://github.com/prebid/prebid-server-java/blob/master/docs/build.md). - Check minimal needed configuration file `sample/prebid-config.yaml`. - Also, check the Data Cache settings file `sample/sample-app-settings.yaml`. -For more information how to configure the server follow the [config documentation](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/config.md). +For more information how to configure the server follow the [config documentation](https://github.com/prebid/prebid-server-java/blob/master/docs/config.md). - Run your server with: ``` java -jar target/prebid-server.jar --spring.config.additional-location=sample/prebid-config.yaml ``` -For more information how to start the server follow the [run documentation](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/run.md). +For more information how to start the server follow the [run documentation](https://github.com/prebid/prebid-server-java/blob/master/docs/run.md). - To verify everything is OK go to `http://localhost:8080/status` and check response status is `200 OK`. -More detailed project documentation can be found [here](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/TOC.md). +More project documentation can be found [here](/prebid-server/versions/pbs-versions-java.html). diff --git a/prebid-server/developers/pbs-build-an-analytics-adapter.md b/prebid-server/developers/pbs-build-an-analytics-adapter.md index 364b486b58..bb76a0b8e1 100644 --- a/prebid-server/developers/pbs-build-an-analytics-adapter.md +++ b/prebid-server/developers/pbs-build-an-analytics-adapter.md @@ -51,7 +51,7 @@ Prebid Server will then write sample log messages to the file you provided. ## Adding an Analytics Adapter in PBS-Java 1. Define config params -Analytics modules are enabled through the [Configuration](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/config.md). +Analytics modules are enabled through the [Configuration](https://github.com/prebid/prebid-server-java/blob/master/docs/config.md). 2. Implement your module Your new module org.prebid.server.analytics.{module}AnalyticsReporter needs to implement the org.prebid.server.analytics.AnalyticsReporter interface. @@ -62,7 +62,7 @@ In order to make Prebid Server aware of the new analytics module it needs to be ### Example {:.no_toc} -The [log module](https://github.com/rubicon-project/prebid-server-java/blob/master/src/main/java/org/prebid/server/analytics/LogAnalyticsReporter.java) is provided as an example. This module will write dummy messages to a log. +The [log module](https://github.com/prebid/prebid-server-java/blob/master/src/main/java/org/prebid/server/analytics/LogAnalyticsReporter.java) is provided as an example. This module will write dummy messages to a log. It can be configured with: diff --git a/prebid-server/features/pbs-privacy.md b/prebid-server/features/pbs-privacy.md index dd31507d47..dd3b7099fb 100644 --- a/prebid-server/features/pbs-privacy.md +++ b/prebid-server/features/pbs-privacy.md @@ -42,7 +42,7 @@ the request to the adapters: - Removes the request.device.ifa attribute - Rounds the request.device.geo. {lat,lon} to two decimal places -Full details are available [here](https://github.com/rubicon-project/prebid-server-java/blob/master/docs/developers/PrebidServerJava_GDPR_Requirements.pdf). +Full details are available [here](https://docs.google.com/document/d/1g0zAYc_EfqyilKD8N2qQ47uz0hdahY-t8vfb-vxZL5w/edit). ### TCF 2.0 diff --git a/prebid-server/versions/pbs-versions-java.md b/prebid-server/versions/pbs-versions-java.md index 4fa6ad51fc..d024930727 100644 --- a/prebid-server/versions/pbs-versions-java.md +++ b/prebid-server/versions/pbs-versions-java.md @@ -34,7 +34,7 @@ PBS-Java look over the [feature list](/prebid-server/features/pbs-feature-idx.ht The repositories are currently in the Rubicon-Project GitHub organization, but will soon move to the Prebid org. -- [Prebid Server - Java](https://github.com/rubicon-project/prebid-server-java) +- [Prebid Server - Java](https://github.com/prebid/prebid-server-java) - [Prebid Cache Server - Java](https://github.com/prebid/prebid-cache-java) ## Installation From f38a2cb68603067994062fac97a4167ce3b49259 Mon Sep 17 00:00:00 2001 From: Bryan Szekely <49168870+bszekely1@users.noreply.github.com> Date: Wed, 18 Nov 2020 15:44:35 -0500 Subject: [PATCH 104/149] Floors Support in Bidder param page (#2522) * floors: added feature support for bidders * floors: added feature support for all supported bidders --- dev-docs/bidders.md | 1 + dev-docs/bidders/33across.md | 1 + dev-docs/bidders/connectad.md | 1 + dev-docs/bidders/criteo.md | 1 + dev-docs/bidders/districtmdmx.md | 1 + dev-docs/bidders/grid.md | 1 + dev-docs/bidders/gumgum.md | 1 + dev-docs/bidders/openx.md | 1 + dev-docs/bidders/pubmatic.md | 1 + dev-docs/bidders/rubicon.md | 1 + dev-docs/bidders/triplelift.md | 1 + 11 files changed, 11 insertions(+) diff --git a/dev-docs/bidders.md b/dev-docs/bidders.md index dfa96bd249..871c676bb2 100644 --- a/dev-docs/bidders.md +++ b/dev-docs/bidders.md @@ -51,6 +51,7 @@ You can also download the full CSV | **Safeframes OK** | {% if page.safeframes_ok == false %}no{% elsif page.safeframes_ok == true %}yes{% else %}check with bidder{% endif %} | **USP/CCPA Support** | {% if page.usp_supported == true %}yes{% else %}no{% endif %} | | **Supports Deals** | {% if page.bidder_supports_deals == false %}no{% elsif page.bidder_supports_deals == true %}yes{% else %}check with bidder{% endif %} | **Prebid.js Adapter** | yes | | **IAB GVL ID** | {% if page.gvl_id %}{{page.gvl_id}}{% else %}check with bidder{% endif %} | **Prebid Server Adapter** | {% if page.pbs == true %}yes{% else %}no{% endif %} | +| **Floors Module Support** | {% if page.getFloor == true %}yes{% else %}no{% endif %} |

"Send All Bids" Ad Server Keys

diff --git a/dev-docs/bidders/33across.md b/dev-docs/bidders/33across.md index 39f60ac1eb..59fc018670 100644 --- a/dev-docs/bidders/33across.md +++ b/dev-docs/bidders/33across.md @@ -7,6 +7,7 @@ pbs: true biddercode: 33across media_types: banner, video gdpr_supported: true +getFloor: true schain_supported: true usp_supported: true --- diff --git a/dev-docs/bidders/connectad.md b/dev-docs/bidders/connectad.md index cdb2d17e8b..8288dc2839 100644 --- a/dev-docs/bidders/connectad.md +++ b/dev-docs/bidders/connectad.md @@ -12,6 +12,7 @@ userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrable prebid_member: true safeframes_ok: true tcf2_supported: true +getFloor: true pbjs: true pbs: true gvl_id: 138 diff --git a/dev-docs/bidders/criteo.md b/dev-docs/bidders/criteo.md index 522df88c38..bc5e01e588 100644 --- a/dev-docs/bidders/criteo.md +++ b/dev-docs/bidders/criteo.md @@ -9,6 +9,7 @@ gdpr_supported: true usp_supported: true prebid_member: true tcf2_supported: true +getFloor: true gvl_id: 91 --- ### Note diff --git a/dev-docs/bidders/districtmdmx.md b/dev-docs/bidders/districtmdmx.md index 76ef040615..6af35635eb 100644 --- a/dev-docs/bidders/districtmdmx.md +++ b/dev-docs/bidders/districtmdmx.md @@ -6,6 +6,7 @@ pbjs: true biddercode: districtmDMX gdpr_supported: true schain_supported: true +getFloor: true usp_supported: true coppa_supported: true userIds: britepoolId, criteo, id5Id, identityLink, intentiq, liveIntentId, netId, parrableId, pubCommonId, unifiedId diff --git a/dev-docs/bidders/grid.md b/dev-docs/bidders/grid.md index bc90535d51..b3387c0f58 100644 --- a/dev-docs/bidders/grid.md +++ b/dev-docs/bidders/grid.md @@ -9,6 +9,7 @@ media_types: banner, video gdpr_supported: true usp_supported: true schain_supported: true +getFloor: true userIds: id5Id, unifiedId, liveIntentId, criteo, identityLink, digitrust tcf2_supported: true --- diff --git a/dev-docs/bidders/gumgum.md b/dev-docs/bidders/gumgum.md index 4fa35521f5..9906bc858f 100644 --- a/dev-docs/bidders/gumgum.md +++ b/dev-docs/bidders/gumgum.md @@ -7,6 +7,7 @@ pbs: true biddercode: gumgum media_types: banner, video schain_supported: true +getFloor: true userIds: unifiedId gdpr_supported: true usp_supported: true diff --git a/dev-docs/bidders/openx.md b/dev-docs/bidders/openx.md index d0cc3bc5ee..4d52acbe32 100644 --- a/dev-docs/bidders/openx.md +++ b/dev-docs/bidders/openx.md @@ -10,6 +10,7 @@ schain_supported: true gdpr_supported: true usp_supported: true coppa_supported: true +getFloor: true userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId prebid_member: true tcf2_supported: true diff --git a/dev-docs/bidders/pubmatic.md b/dev-docs/bidders/pubmatic.md index 33cdc6ec8b..ec439ec38a 100644 --- a/dev-docs/bidders/pubmatic.md +++ b/dev-docs/bidders/pubmatic.md @@ -8,6 +8,7 @@ gdpr_supported: true usp_supported: true coppa_supported: true schain_supported: true +getFloor: true userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId prebid_member: true safeframes_ok: true diff --git a/dev-docs/bidders/rubicon.md b/dev-docs/bidders/rubicon.md index e9b532b03f..c27549c3cb 100644 --- a/dev-docs/bidders/rubicon.md +++ b/dev-docs/bidders/rubicon.md @@ -8,6 +8,7 @@ tcf2_supported: true usp_supported: true coppa_supported: true schain_supported: true +getFloor: true media_types: video userIds: britepoolId, criteo, fabrickId, haloId, id5Id, identityLink, intentiqId, idx, liveIntentId, lotamePanoramaId, netId, parrableId, pubCommonId, pubProvidedId, quantcastId, sharedId, unifiedId, verizonMediaId, zeotapIdPlus prebid_member: true diff --git a/dev-docs/bidders/triplelift.md b/dev-docs/bidders/triplelift.md index f7639c5e0c..e4eedb63e0 100644 --- a/dev-docs/bidders/triplelift.md +++ b/dev-docs/bidders/triplelift.md @@ -6,6 +6,7 @@ gdpr_supported: true tcf2_supported: true usp_supported: true schain_supported: true +getFloor: true coppa_supported: true biddercode: triplelift userIds: criteo, identityLink, unifiedId From fa30e4875e22b65f09dc2c3c2da5cf137b059566 Mon Sep 17 00:00:00 2001 From: Daniel Lawrence Date: Wed, 18 Nov 2020 12:50:13 -0800 Subject: [PATCH 105/149] updating to reflect a switch to offline-agreements in the interim (#2518) --- dev-docs/bidders/inmobi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/inmobi.md b/dev-docs/bidders/inmobi.md index 6c6a6ce60f..aa35cd4f72 100644 --- a/dev-docs/bidders/inmobi.md +++ b/dev-docs/bidders/inmobi.md @@ -5,7 +5,7 @@ description: InMobi Bidder Adapter biddercode: inmobi gdpr_supported: true tcf2_supported: true -usp_supported: true +usp_supported: false gvl_id: 333 coppa_supported: true media_types: banner, video From bc7c5958dd5069ee5ff4b9b4538118a0d2879516 Mon Sep 17 00:00:00 2001 From: JonGoSonobi Date: Wed, 18 Nov 2020 15:50:51 -0500 Subject: [PATCH 106/149] added tcf2_supported for sonobi (#2519) --- dev-docs/bidders/sonobi.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/sonobi.md b/dev-docs/bidders/sonobi.md index 6aa0616ff4..6d0643895c 100644 --- a/dev-docs/bidders/sonobi.md +++ b/dev-docs/bidders/sonobi.md @@ -8,6 +8,7 @@ gdpr_supported: true userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId pbjs: true pbs: true +tcf2_supported: true --- ### Note: From c56257719833ad3910a93cb8f99b7089a9cfc848 Mon Sep 17 00:00:00 2001 From: Alexey Elymanov Date: Thu, 19 Nov 2020 19:20:12 +0300 Subject: [PATCH 107/149] between adapter doc update: schain support (#2434) * between docs * gitignore * between adapter docs fix * between docs update: gdpr support * between docs update: tcf2 support Co-authored-by: Alexey Elymanov --- dev-docs/bidders/between.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/between.md b/dev-docs/bidders/between.md index 72e2d906b4..fd6480ca5d 100644 --- a/dev-docs/bidders/between.md +++ b/dev-docs/bidders/between.md @@ -5,7 +5,9 @@ description: Prebid Between Bidder Adaptor pbjs: true pbs: true biddercode: between -media_types: banner +schain_supported: true +gdpr_supported: true +tcf2_supported: true --- ### Bid Params @@ -15,3 +17,4 @@ media_types: banner |---------------|----------|-------------|---------|----------| | `host` | required | between host url prefix | `eu` | `string` | + From 92ddd3304c494c5959606f86fa8bfbd95ed12482 Mon Sep 17 00:00:00 2001 From: Salomon Rada Date: Thu, 19 Nov 2020 18:21:09 +0200 Subject: [PATCH 108/149] Add new bid adaptor alias (#2450) --- dev-docs/bidders/MobfoxX.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 dev-docs/bidders/MobfoxX.md diff --git a/dev-docs/bidders/MobfoxX.md b/dev-docs/bidders/MobfoxX.md new file mode 100644 index 0000000000..df027b7c28 --- /dev/null +++ b/dev-docs/bidders/MobfoxX.md @@ -0,0 +1,20 @@ +--- +layout: bidder +title: Mobfox X +description: Mobfox X Bidder Adaptor +biddercode: MobfoxX +pbjs: true +media_types: banner, video +gdpr_supported: true +schain_supported: true +usp_supported: true +userIds: id5Id, unifiedId +aliasCode: gamoshi +--- + +### Bid params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------------------|----------|---------------------------------------------------------------|----------------------|----------| +| `supplyPartnerId` | required | ID of the supply partner | `'12345'` | `string` | From 85459903c30616cfa1fc207d8dfa303c2a9f5cf0 Mon Sep 17 00:00:00 2001 From: lunamedia <73552749+lunamedia@users.noreply.github.com> Date: Thu, 19 Nov 2020 18:21:44 +0200 Subject: [PATCH 109/149] initial (#2454) Co-authored-by: Aiholkin --- dev-docs/bidders/lunamediahb.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 dev-docs/bidders/lunamediahb.md diff --git a/dev-docs/bidders/lunamediahb.md b/dev-docs/bidders/lunamediahb.md new file mode 100644 index 0000000000..532de24c7d --- /dev/null +++ b/dev-docs/bidders/lunamediahb.md @@ -0,0 +1,19 @@ +--- +layout: bidder +title: LunamediaHB +description: Prebid Lunamedia Bidder Adapter +biddercode: lunamediahb +usp_supported: true +schain_supported: true +media_types: banner, video, native +gdpr: true +pbjs: true +pbs: false +--- + +### Prebid.Server Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|----------------|----------|----------------------------------------------------------|------------|-----------| +| `placementId` | required | Placement Id will be generated on Lunamedia Platform. | `'0'` | `string` | \ No newline at end of file From 0a05cee86bbc1ba45dd0a02f46a7eedf16bffbd9 Mon Sep 17 00:00:00 2001 From: silvermob <73727464+silvermob@users.noreply.github.com> Date: Thu, 19 Nov 2020 23:22:17 +0700 Subject: [PATCH 110/149] SilverMob bidder (#2458) Co-authored-by: Anton Nikityuk --- dev-docs/bidders/silvermob.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 dev-docs/bidders/silvermob.md diff --git a/dev-docs/bidders/silvermob.md b/dev-docs/bidders/silvermob.md new file mode 100644 index 0000000000..eb8f2b155a --- /dev/null +++ b/dev-docs/bidders/silvermob.md @@ -0,0 +1,23 @@ +--- +layout: bidder +title: SilverMob +description: SilverMob Bidder Adapter +biddercode: silvermob +gdpr_supported: true/false +media_types: banner, video, native +pbjs: false +pbs: true +prebid_member: false +--- + +### Note: + +The SilverMob Bidding adapter requires setup before beginning. Please contact us at partners@silvermob.com + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|-----------------------|-----------|-----------| +| `zoneid` | required | Placement id | `'3011'` | `string` | +| `host` | required | Data center location | `'us'` | `string` | \ No newline at end of file From 9c46f4678a5d4915490330eab896eae85eb12da3 Mon Sep 17 00:00:00 2001 From: pro-nsk <32703851+pro-nsk@users.noreply.github.com> Date: Thu, 19 Nov 2020 23:25:01 +0700 Subject: [PATCH 111/149] Update documentation for Qwarry bid adapter (#2476) * Qwarry adapter description * fix * add pbjs: true * add quotes to example string parameter * add pos parameter to qwarry bid adapter Co-authored-by: Alexander Kascheev --- dev-docs/bidders/qwarry.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dev-docs/bidders/qwarry.md b/dev-docs/bidders/qwarry.md index 424448bf0f..228684eccb 100644 --- a/dev-docs/bidders/qwarry.md +++ b/dev-docs/bidders/qwarry.md @@ -12,6 +12,7 @@ pbjs: true ### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|-------------|----------|------------------------------------------|----------------------------------------|----------| -| `zoneToken` | required | The ID issued by Qwarry to the publisher | `'8a80d8e9-0cf9-4329-8486-6f5bbcd8a61a'` | `string` | +| Name | Scope | Description | Example | Type | +|-------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------|-----------| +| `zoneToken` | required | The ID issued by Qwarry to the publisher | `'8a80d8e9-0cf9-4329-8486-6f5bbcd8a61a'` | `string` | +| `pos` | optional | Specify the position of the ad as a relative measure of visibility or prominence. Allowed values: Above the fold: `1`; Below the fold: `3`; Middle of the fold: `7`; | `0` | `integer` | \ No newline at end of file From 28592d4735096787a5f4ed8574cd77c046fdd422 Mon Sep 17 00:00:00 2001 From: SmartyAdsSSP <41569976+SmartyAdsSSP@users.noreply.github.com> Date: Thu, 19 Nov 2020 18:26:06 +0200 Subject: [PATCH 112/149] update SmartyAds apater docs for prebid.js and prebid-server (#2480) --- dev-docs/bidders/smartyads.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dev-docs/bidders/smartyads.md b/dev-docs/bidders/smartyads.md index ba70abfa42..fa9328221b 100644 --- a/dev-docs/bidders/smartyads.md +++ b/dev-docs/bidders/smartyads.md @@ -25,6 +25,7 @@ The Example Bidding adapter requires setup before beginning. Please contact us a {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |---------------|----------|-----------------------|-----------|-----------| -| `host` | required | Region id | `'ns1'` | `string` | -| `sourceid` | required | Partner id | `'smartyads'` | `string` | -| `accountid` | required | Endpoint id | `'hash'` | `string` | +| `placementId` | required (for prebid.js) | placement Id | `'0'` | `string` | +| `host` | required (for prebid-server) | Region id | `'ns1'` | `string` | +| `sourceid` | required (for prebid-server) | Partner id | `'smartyads'` | `string` | +| `accountid` | required (for prebid-server) | Endpoint id | `'hash'` | `string` | From dd45296a8c7a756d89c048f7656faf514eb501e5 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Thu, 19 Nov 2020 11:28:02 -0500 Subject: [PATCH 113/149] [AD-1023] JW Player - Set targeting info to bid.rtd (#2485) * updates for rtd support * improves overview Co-authored-by: karimJWP --- dev-docs/modules/jwplayerRtdProvider.md | 27 ++++++++++++++----------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/dev-docs/modules/jwplayerRtdProvider.md b/dev-docs/modules/jwplayerRtdProvider.md index bb34f2b6c1..bf881ef326 100644 --- a/dev-docs/modules/jwplayerRtdProvider.md +++ b/dev-docs/modules/jwplayerRtdProvider.md @@ -18,9 +18,8 @@ sidebarType : 1 ## Overview -The purpose of this Real Time Data Provider is to allow publishers to target against their JW Player media without -being forced to integrate with the Player Bidding product. This prebid module makes JW Player's video ad targeting information accessible -to Bid Adapters. +The JW Player RTD module passes contextual and performance based information about individual video impression opportunities to bid adapters in order to increase monetization. +To use this module, you'll need to work with [JW Player](https://www.jwplayer.com/video-monetization/) to get an account and discuss the best integration path. ## Implementation for Publishers: @@ -110,11 +109,15 @@ Each bidRequest for which targeting information was found will conform to the fo adUnitCode: 'xyz', bidId: 'abc', ..., - jwTargeting: { - segments: ['123', '456'], - content: { - id: 'jw_abc123' - } + rtd: { + jwplayer: { + targeting: { + segments: ['123', '456'], + content: { + id: 'jw_abc123' + } + } + } } } ``` @@ -126,10 +129,10 @@ Read the bidRequest.jwTargeting object and pass the values to your endpoint as a {: .table .table-bordered .table-striped } | Name |Type | Description | Notes | | :------------ | :------------ | :------------ |:------------ | -| jwTargeting | Object | | | -| jwTargeting.segments | Array of Strings | jwpseg targeting segments | | -| jwTargeting.content | Object | | | -| jwTargeting.content.id | String | Unique identifier for the specific media asset | | +| rtd.jwplayer.targeting | Object | | | +| rtd.jwplayer.targeting.segments | Array of Strings | jwpseg targeting segments | | +| rtd.jwplayer.targeting.content | Object | | | +| rtd.jwplayer.targeting.content.id | String | Unique identifier for the specific media asset | | ## Example From 2d764f44f67dfe800d7fc3baa9d04a2ffb32795e Mon Sep 17 00:00:00 2001 From: Omer Koren Date: Thu, 19 Nov 2020 18:38:51 +0200 Subject: [PATCH 114/149] Change placementId to be mandatory in undertone bidder docs (#2503) --- dev-docs/bidders/undertone.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/undertone.md b/dev-docs/bidders/undertone.md index a4257053e6..975fff723b 100644 --- a/dev-docs/bidders/undertone.md +++ b/dev-docs/bidders/undertone.md @@ -17,7 +17,7 @@ pbjs: true {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |---------------|----------|-------------------------------------------|------------|-----------| -| `placementId` | optional | Your placement ID (provided by undertone) | `"13as14d0"` | `string` | +| `placementId` | required | Your placement ID (provided by undertone) | `"13as14d0"` | `string` | | `publisherId` | required | publisher ID (provided by undertone) | `12345` | `integer` | From 207bc54d5f764be04fcf7eff1f8dbf76bd9b8a3e Mon Sep 17 00:00:00 2001 From: SmartyAdman <59048845+SmartyAdman@users.noreply.github.com> Date: Thu, 19 Nov 2020 18:39:34 +0200 Subject: [PATCH 115/149] add usp consent support (#2510) * Add adman dev doc * Change params Params required by new adapter setup * Edit docs Fix naming, use quotes around example * adding quotes to string param * Update adman.md * tcf2_supported: true * Update adman.md add usp support Co-authored-by: minoru katogi Co-authored-by: ADman Media Co-authored-by: bretg --- dev-docs/bidders/adman.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/adman.md b/dev-docs/bidders/adman.md index f576a97602..27d8454e43 100644 --- a/dev-docs/bidders/adman.md +++ b/dev-docs/bidders/adman.md @@ -6,6 +6,7 @@ pbjs: true pbs: true biddercode: adman gdpr_supported: true +usp_supported: true media_types: banner, video tcf2_supported: true --- From 5feeb2ef6829605474da5b55b3524e2dcc8565e4 Mon Sep 17 00:00:00 2001 From: Anthony Lauzon Date: Thu, 19 Nov 2020 11:45:37 -0500 Subject: [PATCH 116/149] Add Audigent RTD provider Docs (#2369) * add audigent rtd provider docs * update audigent rtd provider docs * remove section * doc update * update audigent docs * update docs * update audigent docs * add parameter description dtable * fix name * add default specification * documentation update * requestParams object type * header size in markdown * brand halo module * formatting --- dev-docs/modules/haloRtdProvider.md | 197 ++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 dev-docs/modules/haloRtdProvider.md diff --git a/dev-docs/modules/haloRtdProvider.md b/dev-docs/modules/haloRtdProvider.md new file mode 100644 index 0000000000..0390422c91 --- /dev/null +++ b/dev-docs/modules/haloRtdProvider.md @@ -0,0 +1,197 @@ +--- +layout: page_v2 +title: Audigent Halo Real-time Data Module +description: Audigent Halo RTD Segment Module +display_name: Audigent Halo Segmentation +module_code : halo +module_type : rtd +enable_download : true +sidebarType : 1 +--- + +# Audigent Halo RTD Segmentation Module +{:.no_toc} + +* TOC +{:toc} + +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 quality user segmentation that can be +attached to bid request objects destined for different SSPs in order to optimize +targeting and increase publisher revenue. Audigent maintains a large database +of first-party Tradedesk Unified ID, Audigent Halo ID and other id provider +mappings to various third-party segment types that are utilizable across +different SSPs. With this module, these segments can be retrieved and supplied +to the SSP in real-time during the bid request cycle. + +## Publisher Usage + +Compile the Halo RTD module into your Prebid build: + +`gulp build --modules=userId,unifiedIdSystem,rtdModule,haloRtdProvider,appnexusBidAdapter` + +Add the Audigent Halo RTD provider to your Prebid config. For any adapters +that you would like to retrieve segments for, add a mapping in the 'mapSegments' +parameter. In this example we will configure publisher 1234 to retrieve +appnexus segments from Audigent. See the "Parameter Descriptions" below for +more detailed information of the configuration parameters. Currently, +OpenRTB compatible fpd data will be added for any bid adapter in the +"mapSegments" objects. Automated bid augmentation exists for some bidders. +Please work with your Audigent Prebid support team (prebid@audigent.com) on +which version of Prebid.js supports which bidders automatically. + +``` +pbjs.setConfig( + ... + realTimeData: { + auctionDelay: auctionDelay, + dataProviders: [ + { + name: "halo", + waitForIt: true, + params: { + mapSegments: { + appnexus: true, + }, + segmentCache: false, + requestParams: { + publisherId: 1234 + } + } + } + ] + } + ... +} +``` + +## Overriding & Adding Segment Mappers +As indicated above, it is possible to provide your own bid augmentation +functions. This is useful if you know a bid adapter's API supports segment +fields which aren't specifically being added to request objects in the Prebid +bid adapter. You can also override segment mappers by passing a function +instead of a boolean to the Halo RTD segment module. This might be useful +if you'd like to use custom logic to determine which segments are sent +to a specific backend. + +Please see the following example, which provides a function to modify bids for +a bid adapter called adBuzz and overrides the appnexus segment mapper. + +``` +pbjs.setConfig( + ... + realTimeData: { + auctionDelay: auctionDelay, + dataProviders: [ + { + name: "halo", + waitForIt: true, + params: { + mapSegments: { + // adding an adBuzz segment mapper + adBuzz: function(bid, segments) { + bid.params.adBuzzCustomSegments = []; + for (var i = 0; i < segments.length; i++) { + bid.params.adBuzzCustomSegments.push(segments[i].id); + } + }, + // overriding the appnexus segment mapper to exclude certain segments + appnexus: function(bid, segments) { + for (var i = 0; i < segments.length; i++) { + if (segments[i].id != 'exclude_segment') { + bid.params.user.segments.push(segments[i].id); + } + } + } + }, + segmentCache: false, + requestParams: { + publisherId: 1234 + } + } + } + ] + } + ... +} +``` + +**Config Syntax details:** + +{: .table .table-bordered .table-striped } +| Name |Type | Description | Notes | +| :------------ | :------------ | :------------ |:------------ | +| name | String | Real time data module name | Always 'halo' | +| waitForIt | Boolean | Required to ensure that the auction is delayed until prefetch is complete | Optional. Defaults to false | +| params | Object | | | +| params.mapSegments | Boolean | Dictionary of bidders you would like to supply Audigent segments for. Maps to boolean values, but also allows functions for custom mapping logic. The function signature is (bid, segments) => {}. | Required | +| params.segmentCache | Boolean | This parameter tells the Halo RTD module to attempt reading segments from a local storage cache instead of always requesting them from the Audigent server. | Optional. Defaults to false. | +| params.requestParams | Object | Publisher partner specific configuration options, such as optional publisher id and other segment query related metadata to be submitted to Audigent's backend with each request. Contact prebid@audigent.com for more information. | Optional | + +## Overriding & Adding Segment Mappers +As indicated above, it is possible to provide your own bid augmentation +functions. This is useful if you know a bid adapter's API supports segment +fields which aren't specifically being added to request objects in the Prebid +bid adapter. You can also override segment mappers by passing a function +instead of a boolean to the Halo RTD segment module. This might be useful +if you'd like to use custom logic to determine which segments are sent +to a specific backend. + +Please see the following example, which provides a function to modify bids for +a bid adapter called adBuzz and overrides the appnexus segment mapper. + +``` +pbjs.setConfig( + ... + realTimeData: { + auctionDelay: auctionDelay, + dataProviders: [ + { + name: "halo", + waitForIt: true, + params: { + mapSegments: { + // adding an adBuzz segment mapper + adBuzz: function(bid, segments) { + bid.params.adBuzzCustomSegments = []; + for (var i = 0; i < segments.length; i++) { + bid.params.adBuzzCustomSegments.push(segments[i].id); + } + }, + // overriding the appnexus segment mapper to exclude certain segments + appnexus: function(bid, segments) { + for (var i = 0; i < segments.length; i++) { + if (segments[i].id != 'exclude_segment') { + bid.params.user.segments.push(segments[i].id); + } + } + } + }, + segmentCache: false, + requestParams: { + publisherId: 1234 + } + } + } + ] + } + ... +} +``` + +## Testing + +To view an example of available segments returned by Audigent's backends: + +`gulp serve --modules=userId,unifiedIdSystem,rtdModule,haloRtdProvider,appnexusBidAdapter` + +and then point your browser at: + +`http://localhost:9999/integrationExamples/gpt/haloRtdProvider_example.html` + + + + From b18a88690f916da662accec8171f8664ce8ce4ff Mon Sep 17 00:00:00 2001 From: omerBrowsi <54346241+omerBrowsi@users.noreply.github.com> Date: Thu, 19 Nov 2020 18:49:18 +0200 Subject: [PATCH 117/149] auction delay and timeout params (#1690) * auction delay and timeout * removing common RTD params from params table Co-authored-by: bretg --- dev-docs/modules/browsiRtdProvider.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev-docs/modules/browsiRtdProvider.md b/dev-docs/modules/browsiRtdProvider.md index a41193b68b..6503cca338 100644 --- a/dev-docs/modules/browsiRtdProvider.md +++ b/dev-docs/modules/browsiRtdProvider.md @@ -58,8 +58,6 @@ Syntax details: | Name |Type | Description | Notes | | :------------ | :------------ | :------------ |:------------ | | name | String | Real time data module name | Always 'browsi' | -| auctionDelay | Number | Max time in ms to delay the auction | Optional. Default to 0 | -| timeout | Number | timeout in ms (only if auctionDealy is 0) | Optional. Default to 1000 | | params | Object | | | | params.siteKey |String |Site key| | | params.pubKey |String |Publisher key| | From 2df1dc5dc7f408794394c80b2093fef981812f7e Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Thu, 19 Nov 2020 12:17:54 -0500 Subject: [PATCH 118/149] Update criteo.md (#2524) Clarify floors supprt --- dev-docs/bidders/criteo.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/criteo.md b/dev-docs/bidders/criteo.md index bc5e01e588..d2c41a3ac9 100644 --- a/dev-docs/bidders/criteo.md +++ b/dev-docs/bidders/criteo.md @@ -9,7 +9,7 @@ gdpr_supported: true usp_supported: true prebid_member: true tcf2_supported: true -getFloor: true +getFloor: false* gvl_id: 91 --- ### Note @@ -17,6 +17,8 @@ gvl_id: 91 For Native Ads, in order to avoid further decoding issues of special characters, the assets need to be sent as placeholders. That means, `sendId: true` becomes mandatory for all fields receiving URLs, notably: `icon`, `image`, `clickUrl`, `privacyLink`, `privacyIcon`. +*Criteo currently only supports getFloor if floors are in Euros and if the publisher is enabling the Criteo Publisher Tag external js call. + See [Sending Asset Placeholders]({{site.baseurl}}/dev-docs/show-native-ads.html#sending-asset-placeholders). ### Bid Params From 9d53fed3ee8944fe4dcf59786fb0cf3c0aa7c81d Mon Sep 17 00:00:00 2001 From: Anthony Lauzon Date: Fri, 20 Nov 2020 09:20:24 -0500 Subject: [PATCH 119/149] Add page_type param, remove duplicate section in Audigent Halo RTD docs (#2526) * add audigent rtd provider docs * update audigent rtd provider docs * remove section * doc update * update audigent docs * update docs * update audigent docs * add parameter description dtable * fix name * add default specification * documentation update * requestParams object type * header size in markdown * brand halo module * formatting * add page type, remove duplicate section --- dev-docs/modules/haloRtdProvider.md | 60 +++-------------------------- 1 file changed, 5 insertions(+), 55 deletions(-) diff --git a/dev-docs/modules/haloRtdProvider.md b/dev-docs/modules/haloRtdProvider.md index 0390422c91..aac1bb4602 100644 --- a/dev-docs/modules/haloRtdProvider.md +++ b/dev-docs/modules/haloRtdProvider.md @@ -1,10 +1,11 @@ --- layout: page_v2 -title: Audigent Halo Real-time Data Module -description: Audigent Halo RTD Segment Module -display_name: Audigent Halo Segmentation +title: Audigent Halo Real Time Data Provider +display_name: Audigent Halo Real-time Segmentation Module +description: Audigent Halo Real-time Segmentation Module +page_type: module +module_type: rtd module_code : halo -module_type : rtd enable_download : true sidebarType : 1 --- @@ -68,57 +69,6 @@ pbjs.setConfig( } ``` -## Overriding & Adding Segment Mappers -As indicated above, it is possible to provide your own bid augmentation -functions. This is useful if you know a bid adapter's API supports segment -fields which aren't specifically being added to request objects in the Prebid -bid adapter. You can also override segment mappers by passing a function -instead of a boolean to the Halo RTD segment module. This might be useful -if you'd like to use custom logic to determine which segments are sent -to a specific backend. - -Please see the following example, which provides a function to modify bids for -a bid adapter called adBuzz and overrides the appnexus segment mapper. - -``` -pbjs.setConfig( - ... - realTimeData: { - auctionDelay: auctionDelay, - dataProviders: [ - { - name: "halo", - waitForIt: true, - params: { - mapSegments: { - // adding an adBuzz segment mapper - adBuzz: function(bid, segments) { - bid.params.adBuzzCustomSegments = []; - for (var i = 0; i < segments.length; i++) { - bid.params.adBuzzCustomSegments.push(segments[i].id); - } - }, - // overriding the appnexus segment mapper to exclude certain segments - appnexus: function(bid, segments) { - for (var i = 0; i < segments.length; i++) { - if (segments[i].id != 'exclude_segment') { - bid.params.user.segments.push(segments[i].id); - } - } - } - }, - segmentCache: false, - requestParams: { - publisherId: 1234 - } - } - } - ] - } - ... -} -``` - **Config Syntax details:** {: .table .table-bordered .table-striped } From 84e5fb2de8158a2789469a112d7786841490f815 Mon Sep 17 00:00:00 2001 From: r-schweitzer <50628828+r-schweitzer@users.noreply.github.com> Date: Fri, 20 Nov 2020 16:11:22 +0100 Subject: [PATCH 120/149] Feature: getNoBidsForAdUnitCode (#2498) * added getNoBidsForAdUnitCode * added request params to docs * adjusted getNoBids doc to say it returns an object --- dev-docs/publisher-api-reference.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/dev-docs/publisher-api-reference.md b/dev-docs/publisher-api-reference.md index 9ee820b12b..c3e11a92a2 100644 --- a/dev-docs/publisher-api-reference.md +++ b/dev-docs/publisher-api-reference.md @@ -29,6 +29,7 @@ This page has documentation for the public API methods of Prebid.js. * [.getAllWinningBids()](#module_pbjs.getAllWinningBids) * [.getAllPrebidWinningBids()](#module_pbjs.getAllPrebidWinningBids) * [.getNoBids()](#module_pbjs.getNoBids) + * [.getNoBidsForAdUnitCode(adUnitCode)](#module_pbjs.getNoBidsForAdUnitCode) * [.setTargetingForGPTAsync([codeArr], customSlotMatching)](#module_pbjs.setTargetingForGPTAsync) * [.setTargetingForAst()](#module_pbjs.setTargetingForAst) * [.renderAd(doc, id)](#module_pbjs.renderAd) @@ -574,7 +575,7 @@ pbjs.refreshUserIds({ submoduleNames: ['britepoolId'] }, () => console.log("Done
-### pbjs.getNoBids() ⇒ `Array` +### pbjs.getNoBids() ⇒ `Object` Use this method to get all of the bid requests that resulted in a NO_BID. These are bid requests that were sent to a bidder but, for whatever reason, the bidder decided not to bid on. Used by debugging snippet in [Tips for Troubleshooting](/dev-docs/troubleshooting-tips.html). @@ -582,6 +583,25 @@ Use this method to get all of the bid requests that resulted in a NO_BID. These
+ + +### pbjs.getNoBidsForAdUnitCode(adUnitCode) ⇒ `Object` + +Returns bid requests that resulted in a NO_BID for the specified adUnitCode. See full documentation at [pbjs.getNoBids()](#module_pbjs.getNoBids). + +**Kind**: static method of [pbjs](#module_pbjs) + +**Returns**: `Object` - NO_BID bidResponse object + +**Request Params:** + +{: .table .table-bordered .table-striped } +| Param | Scope | Type | Description | +| --- | --- | --- | --- | +| adUnitCode | Required | `String` | adUnitCode | + +
+ ### pbjs.setTargetingForGPTAsync([codeArr], customSlotMatching) From 34bcdeda5fba612ea4f3458cf7b796822f23442f Mon Sep 17 00:00:00 2001 From: Kylian Deau Date: Wed, 25 Nov 2020 16:43:33 +0100 Subject: [PATCH 121/149] Teads Bidder documentation update (#2527) --- dev-docs/bidders/teads.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev-docs/bidders/teads.md b/dev-docs/bidders/teads.md index 851278f9cc..adab71c25e 100644 --- a/dev-docs/bidders/teads.md +++ b/dev-docs/bidders/teads.md @@ -9,6 +9,8 @@ tcf2_supported: true usp_supported: true schain_supported: true media_types: banner, video +gvl_id: 132 +bidder_supports_deals: true --- ### Note: From dc60501cb40184d3bd6682d5929a72c0a6fcbcea Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 25 Nov 2020 10:44:29 -0500 Subject: [PATCH 122/149] Update the name of the lotamePanoramaIdSystem module to be accurate (#2529) --- dev-docs/modules/userId.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index c7cd9d2d9d..dae26041d4 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -708,7 +708,7 @@ The Lotame privacy policy is at [https://www.lotame.com/about-lotame/privacy/](h Add it to your Prebid.js package with: {: .alert.alert-info :} -gulp build --modules=lotamePanoramaId +gulp build --modules=lotamePanoramaIdSystem #### Lotame Panorama ID Configuration From 48ccf4a128f9b2b576fd5835c699effd89e3337a Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 25 Nov 2020 10:47:22 -0500 Subject: [PATCH 123/149] module index: removing example user id names (#2535) --- dev-docs/modules/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/modules/index.md b/dev-docs/modules/index.md index 2587c30823..8e69f088bc 100644 --- a/dev-docs/modules/index.md +++ b/dev-docs/modules/index.md @@ -34,7 +34,7 @@ If you are looking for bidder adapter parameters, see [Bidders' Params]({{site.b | **ConsentManagement** | Collecting and passing consent information in support of privacy regulations:{::nomarkdown}{:/} See [CMP Best Practices.](/dev-docs/cmp-best-practices.html) | | [**Google Ad Manager Express**](/dev-docs/modules/dfp_express.html) | A simplified installation mechanism for publishers that have Google Publisher Tag (GPT) ad calls in their pages. | | [**Supply Chain Object**](/dev-docs/modules/schain.html) | Validates and makes the Supply Object available to bidders | -| [**User ID**](/dev-docs/modules/userId.html) | Sub-modules are available to support a range of identification approaches: Criteo RTUS, DigiTrust, ID5 Universal ID, IdentityLink, PubCommon ID, Unified ID and LiveIntent ID. | +| [**User ID**](/dev-docs/modules/userId.html) | Sub-modules are available to support a range of identification approaches. | | [**Advanced Size Mapping**](/dev-docs/modules/sizeMappingV2.html) | Display Responsive AdUnits in demanding page environments. | | [**Price Floors Module**](/dev-docs/modules/floors.html) | Configure and enforce minimum bids. | | [**GPT Pre-Auction Module**](/dev-docs/modules/gpt-pre-auction.html) | Adds a PB Ad Slot and matching GAM ad unit name to each ad unit's first-party data before bid requests are sent to the adapters. | From f12ee99a98a82cda630f2e7569572b651d8fa3aa Mon Sep 17 00:00:00 2001 From: Omer Koren Date: Wed, 25 Nov 2020 17:50:01 +0200 Subject: [PATCH 124/149] Update undertone.md (#2531) --- dev-docs/bidders/undertone.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/undertone.md b/dev-docs/bidders/undertone.md index 975fff723b..94d743d670 100644 --- a/dev-docs/bidders/undertone.md +++ b/dev-docs/bidders/undertone.md @@ -30,6 +30,7 @@ pbjs: true | `maxDuration` | optional | Maximum video ad duration in seconds. | `30` | `integer` | | `skippable` | optional | Skippability of the inventory. Possible values: `true` - only skippable inventory is allowed, `false` - skippable inventory is not allowed, null/missing - all inventory is allowed (default value). | `true` | `boolean` | +Supported from version 3.27.0 and above ### Configuration From fab4d001336f9402b55acc462b256c5bab9b18fd Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 1 Dec 2020 10:47:58 -0500 Subject: [PATCH 125/149] rtd module FPD interface (#2541) --- dev-docs/add-rtd-submodule.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dev-docs/add-rtd-submodule.md b/dev-docs/add-rtd-submodule.md index d441e8176e..75394f8b99 100644 --- a/dev-docs/add-rtd-submodule.md +++ b/dev-docs/add-rtd-submodule.md @@ -172,9 +172,12 @@ This is the function that will allow RTD sub-modules to modify the AdUnit object - callback: lets RTD-core know which auction the sub-module is done with. - config: the sub-module's config params provided by the publisher - userConsent object (see above) -2. Your sub-module may update the reqBidsConfigObj and hit the callback. When you update the bidRequest, you must follow one of these conventions: - - Use [First Party Data](/features/firstPartyData.html) conventions, setting AdUnit.fpd.context.data.ATTRIBUTES or AdUnit.fpd.user.data.ATTRIBUTES - - Place your data in bidRequest.rtd.RTDPROVIDERCODE.ATTRIBUTES +2. Your sub-module may update the reqBidsConfigObj and hit the callback. To inject data into the bid requests, you should follow one of these conventions: + - Recommended: use one of these [First Party Data](/features/firstPartyData.html) conventions: + - For AdUnit-specific first party data, set AdUnit.fpd.context.data.ATTRIBUTES + - For global first party data, call 'pbjs.[getConfig](/dev-docs/publisher-api-reference.html#module_pbjs.getConfig)({fpd.context})' or 'pbjs.getConfig({fpd.user})', merge in the new global data, and update with `pbjs.[setConfig](/dev-docs/publisher-api-reference.html#module_pbjs.setConfig)()'. + - If the data is not meant to go to all bidders, the module should use 'pbjs.[setBidderConfig](/dev-docs/publisher-api-reference.html#module_pbjs.setBidderConfig)()' and support a parameter to allow the publisher to define which bidders are to receive the data. + - Not recommended: Place your data in bidRequest.rtd.RTDPROVIDERCODE.ATTRIBUTES and then get individual adapters to specifically read that location. Note that this method won't pass data to Prebid Server adapters. **Code Example** From 862e66d4ae79a7f55aa48ba0eada6c2da7032da2 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Tue, 1 Dec 2020 11:55:35 -0500 Subject: [PATCH 126/149] Rewrite PBS-Go New Adapter Doc (#2495) --- prebid-server/developers/add-new-bidder-go.md | 1256 +++++++++++++++-- 1 file changed, 1112 insertions(+), 144 deletions(-) diff --git a/prebid-server/developers/add-new-bidder-go.md b/prebid-server/developers/add-new-bidder-go.md index d6ca2a0ecd..98d66ab9e0 100644 --- a/prebid-server/developers/add-new-bidder-go.md +++ b/prebid-server/developers/add-new-bidder-go.md @@ -8,229 +8,1167 @@ title: Prebid Server | Developers | Adding a New Bidder # Prebid Server - Adding a New Bidder in Go {: .no_toc} +Thank you for contributing a bid adapter to the open source Prebid Server project. Each new adapter gives publishers more options for monetizing their inventory and strengthens the header bidding community. + +This document guides you through the process of developing a new bid adapter for your bidding server. We encourage you to look at [existing bid adapters](https://github.com/prebid/prebid-server/tree/master/adapters) for working examples and practical guidance. You can also ask us questions by [submitting a GitHub issue](https://github.com/prebid/prebid-server/issues/new). + +{% capture alertNote %} +There are two implementations of Prebid Server, [PBS-Go](https://github.com/prebid/prebid-server) and [PBS-Java](https://github.com/prebid/prebid-server-java). We recommend you build new adapters for PBS-Go and allow us to port it to PBS-Java within a couple of months. If you'd like to build both yourself, please also follow these [instructions for building an adapter in PBS-Java](/prebid-server/developers/add-new-bidder-java.html). +{% endcapture %} + * TOC {:toc } -This document describes how to add a new bid adapter to the Go version of Prebid Server. Our recommendation is to build new adapters in Go because we port them to Java within a couple of months. But if you'd like to build them yourself in both, there are [instructions for building an adapter in PBS-Java](/prebid-server/developers/add-new-bidder-java.html). +## Overview + +Bid adapters are responsible for translating an [OpenRTB 2.5 Bid Request](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf#page=13) to your bidding server's protocol and mapping your server's response to an [OpenRTB 2.5 Bid Response](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf#page=32). -**NOTE**: To make everyone's lives easier, Bidders are expected to make net-price bids (e.g. "If this ad wins, what will the publisher make?"), not gross-price bids. -Publishers can correct for gross-price bids by setting [Bid Adjustments](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#bid-adjustments) to account for fees. +An OpenRTB 2.5 Bid Request contains one or more Impressions, each representing a single ad placement. An Impression may define multiple sizes and/or multiple ad formats. If your bidding server limits requests to a single ad placement, size, or format, then your adapter will need to split the Impression into multiple calls and merge the responses. -## Choose a Bidder Name +## Plan Your Bid Adapter -This name must be unique. Existing BidderNames can be found [here](https://github.com/prebid/prebid-server/blob/master/openrtb_ext/bidders.go). +### Choose A Name + +You will need to choose a unique name for your bid adapter. Names should be written in lower case and may not contain special characters or emoji. If you already have a Prebid.js bid adapter, we encourage you to use the same name with the same bidder parameters. You may not name your adapter `general`, `context`, or `prebid` as those have special meaning in various contexts. Existing bid adapter names are [maintained here](https://github.com/prebid/prebid-server/blob/master/openrtb_ext/bidders.go#L29). + +We ask that the first 6 letters of the name you choose be unique among the existing bid adapters. This consideration helps with generating targeting keys for use by some ad exchanges, such as Google Ad Manager. There's no need to manually check, as this constraint is enforced by the [`TestBidderUniquenessGatekeeping`](https://github.com/prebid/prebid-server/blob/master/openrtb_ext/bidders_test.go#L70) test. Throughout the rest of this document, substitute `{bidder}` with the name you've chosen. -## Define Your Bidder Params +### Respect The Rules -Bidders may define their own APIs for Publishers to pass custom values subject to these guidelines: +We are proud to run the Prebid Server project as a transparent and trustworthy header bidding solution. You are expected to follow our community's [code of conduct](https://docs.prebid.org/wrapper_code_of_conduct.html) and [module rules](https://docs.prebid.org/dev-docs/module-rules.html) when creating your adapter and when interacting with others through issues and code reviews. -- Don't duplicate values already present in the [OpenRTB 2.5 spec](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf). -- Don't add bidder-specific parameters that already have Prebid conventions: first party data, floors, schain, video params, referrer, COPPA. +Please take the time to read our rules in full. Below is a summary of some of the rules which apply to your Prebid Server bid adapter: + - Adapters must not modify bids from demand partners, except to either change the bid from gross to net or from one currency to another. + - Adapters must use the functions provided by the core framework for all external communication. Initiation of any form of network connection outside of what is provided by the core framework is strictly prohibited. No exceptions will be made for this rule. + - Adapters must support the creation of multiple concurrent instances. This means adapters may not mutate global or package scoped variables. + - Bidding server endpoints should prefer secure HTTPS to protect user privacy and should allow keep alive connections (preferably with HTTP/2 support) to increase host performance. + - Adapters must include maintainer information with a group email address for Prebid.org to contact for ongoing support and maintenance. + - Adapters must annotate the bid response with the proper media type, ideally based on the response from the bidding server. -Publishers will send values for these parameters in `request.imp[i].ext.{bidder}` of -[the Auction endpoint](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html). Prebid Server will preprocess these so that -your bidder will access them at `request.imp[i].ext.bidder`--regardless of what your `{bidder}` name is. +{: .alert.alert-warning :} +Failure to follow the rules will lead to delays in approving your adapter for inclusion in Prebid Server. If you'd like to discuss an exception to a rule, please make your request by [submitting a GitHub issue](https://github.com/prebid/prebid-server/issues/new). -## Implement Your Bidder +### Ongoing Support and Maintenance -Bidder implementations are scattered throughout several files. +You are expected to provide support and maintenance for the code you contribute to Prebid Server as part of your bid adapter. We ask that you proactively update your adapter when your bidding server introduces new features or breaking changes. -- `adapters/{bidder}/{bidder}.go`: contains an implementation of [the Bidder interface](https://github.com/prebid/prebid-server/blob/master/adapters/bidder.go). -- `openrtb_ext/imp_{bidder}.go`: contract classes for your Bidder's params. -- `usersync/usersyncers/{bidder}.go`: A [Usersyncer](https://github.com/prebid/prebid-server/blob/master/usersync/usersync.go) which returns cookie sync info for your bidder. -- `usersync/usersyncers/{bidder}_test.go`: Unit tests for your Usersyncer -- `static/bidder-params/{bidder}.json`: A [draft-4 json-schema](https://spacetelescope.github.io/understanding-json-schema/) which [validates your Bidder's params](https://www.jsonschemavalidator.net/). -- `static/bidder-info/{bidder}.yaml`: contains metadata (e.g. contact email, platform & media type support) about the adapter. Note that email cannot be a single individual – we need robust maintainer contact info read by multiple people like "support@example.com". +Occasionally, we'll introduce changes to the core framework as part of our ongoing maintenance and enhancement of the project. If this causes a compilation error or a performance impact to your adapter, we will update the affected portion of your bid adapter code and provide full unit test coverage of our changes. We will notify you via email if this happens and give you at least one week to review the PR and provide comments. Please understand that we will not wait for your explicit approval for these kinds of changes unless you respond to our email or comment on the PR. -Bidder implementations may assume that any params have already been validated against the defined json-schema. +Please be attentive in reading and responding to emails and [GitHub issues](https://github.com/prebid/prebid-server/issues) from publishers, hosts, and Prebid.org project maintainers. If we receive complaints about your bid adapter and you do not respond to our communications, we may disable your adapter by default or remove it from the project entirely. -{: .alert.alert-warning :} -Prebid Server bid adapters must follow all required conventions defined in the [Module Rules](/dev-docs/module-rules.html). Not doing so could lead to delays in approving your adapter for inclusion in Prebid Server. If you'd like to apply for an exception to one of the rules, make your request in a new [Prebid Server issue](https://github.com/prebid/prebid-server/issues). +## Create Your Adapter -### Bid Request Standards +Prebid Server bid adapters consist of several components: bidder info, bidder parameters, adapter code, user sync code, registration with the core framework, and default configuration values. This chapter will guide you though each component. -Prebid clients ([Prebid.js](/use-cases/pbs-pbjs.html), [Prebid SDK](/use-cases/pbs-sdk.html), and [AMP](/use-cases/pbs-amp.html)) pass a number of parameters -that bid adapters should take into account: +Please refer to [existing bid adapters](https://github.com/prebid/prebid-server/tree/master/adapters) for working examples and practical guidance, but understand that our adapter interfaces and coding style evolve over time. Please prefer the examples in this document over differences you may find in code. -- Currency: The publisher's desired bid currency is in the OpenRTB `cur` field. If your bid is in a different currency, you must set the bid currency in the response. -- Bid Floor: `imp[].bidfloor` and `imp[].bidfloorcur` - please make use of this value before responding with a bid. -- First Party Data: bidders should look in these locations for first party data: `imp[].ext.context.data.*`, `site.ext.data.*`, `app.ext.data.*`, and `user.ext.data.*`. -- Supply Chain: `source.ext.schain` -- GDPR: `regs.ext.gdpr` and `user.ext.consent` -- CCPA: `regs.ext.us_privacy` -- COPPA: `regs.coppa` -- Test: Bidders should be aware that the OpenRTB `test` flag indicates non-production traffic. +Our project is written in the [Go programming language](https://golang.org/). We understand not everyone has prior experience writing Go code. Please try your best and we'll respectfully steer you in the right direction during the review process. -### Bid Response Metadata +{: .alert.alert-info :} +Please do not ignore errors from method calls made in your bid adapter code. Even if it's seemingly impossible for an error to occur, such as from `json.Marshal`, it's still possible under the high throughput multi-threaded nature of Prebid Server. + +### Bidder Info + +Let's begin with your adapter's bidder information YAML file. This file is required and contains your maintainer email address, specifies the ad formats your adapter will accept, and allows you to opt-in to video impression tracking. + +Create a file with the path `static/bidder-info/{bidder}.yaml` and begin with the following template: + +```yaml +maintainer: + email: prebid-maintainer@example.com +modifyingVastXmlAllowed: false +capabilities: + app: + mediaTypes: + - banner + - video + - audio + - native + site: + mediaTypes: + - banner + - video + - audio + - native +``` -In addition to the standard OpenRTB2.5 response fields, Prebid encourages bidders to -provide additional metadata in their bid response: +Modify this template for your bid adapter: +- Change the maintainer email address to a group distribution list on your ad server's domain. A distribution list is preferred over an individual mailbox to allow for robustness, as roles and team members naturally change. +- Change the `modifyingVastXmlAllowed` value to `true` if you'd like to opt-in for [video impression tracking](https://github.com/prebid/prebid-server/issues/1015), or remove this line entirely if your adapter doesn't support VAST video ads. +- Remove the `capabilities` (app/site) and `mediaTypes` (banner/video/audio/native) combinations which your adapter does not support. + +
+ Example: Website with banner ads only. + + ```yaml + maintainer: + email: foo@foo.com + capabilities: + site: + mediaTypes: + - banner + ``` +
+ +
+ Example: Website or app with banner or video ads and video impression tracking. + + ```yaml + maintainer: + email: foo@foo.com + modifyingVastXmlAllowed: true + capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video + ``` +
+

+ +### Bidder Parameters + +Your bid adapter might require extra information from the publisher to make a request to your bidding server. The bidder parameters JSON Schema codifies this information to allow Prebid Server to verify requests and to provide an API for third party configuration systems. + +Publishers will provide extra information using an OpenRTB 2.5 Bid Request Extension, preferably at `request.imp[].ext.prebid.bidder.{bidder}` but also supported at `request.imp[].ext.{bidder}`. Prebid Server will validate the publisher information based on your schema and relocate the data to `request.imp[].ext.bidder`, regardless of your bidder name or the publisher's choice of location. + +We request that you do not duplicate information that is already present in the [OpenRTB 2.5 Bid Request specification](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf#page=13) or is already part of an established Prebid convention. For example, your bidder parameters should not include first party data, bid floors, schain, video parameters, referrer information, or privacy consent including COPPA, CCPA, and GDPR TCF. For video parameters in particular, you must prefer the OpenRTB 2.5 Bid Request standard of `request.imp[].video`. -{% highlight js %} +{: .alert.alert-warning :} +You may not use an endpoint domain as a bidder parameter. Prebid Server is not an open proxy. If absolutely necessary, you may specify a portion of the domain as a parameter to support geo regions or account specific servers. However, this is discouraged and may degrade the performance of your adapter since the server needs to maintain more outgoing connections. Host companies may choose to disable your adapter if it uses a dynamically configured domain. + +Create a file with the path `static/bidder-params/{bidder}.json` using [JSON Schema](https://spacetelescope.github.io/understanding-json-schema/) to define your bidder parameters. Prebid Server requires this file for every adapter, even if yours doesn't require bidder parameters (see the 'no parameters' example at the end of this section). + +Let's start with this example which defines one required `placementId` string parameter: + +```json { - "seatbid": [{ - "bid": [{ - ... - "ext": { - "prebid": { - "meta": { - "networkId": NETWORK_ID, - "networkName": NETWORK_NAME, - "agencyId": AGENCY_ID, - "agencyName": AGENCY_NAME, - "advertiserId": ADVERTISER_ID, - "advertiserName": ADVERTISER_NAME, - "advertiserDomains": [ARRAY_OF_ADVERTISER_DOMAINS], - "brandId": BRAND_ID, - "brandName": BRAND_NAME, - "primaryCatId": IAB_CATEGORY, - "secondaryCatIds": [ARRAY_OF_IAB_CATEGORIES], - "mediaType": MEDIATYPE - } - } + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Foo Adapter Params", + "description": "A schema which validates params accepted by the Foo adapter", + "type": "object", + + "properties": { + "placementId": { + "type": "string", + "description": "Placement ID" + } + }, + + "required": ["placementId"] +} +``` +We encourage you to utilize the full features of [JSON Schema](https://spacetelescope.github.io/understanding-json-schema/) to narrowly define your bidder parameter data types. If you copy and paste these examples, please remember to change the `title` and `description` to refer to your bidder name instead of our fictional `Foo` example. + +When choosing your parameter names, please consider aligning with the OpenRTB 2.5 standards by using lower case letters without camel casing or special characters. + +In addition to the examples listed below, please refer to [existing bidder parameter files](https://github.com/prebid/prebid-server/tree/master/static/bidder-params) for guidance. + +
+ Example: No parameters. + + ```json + { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Foo Adapter Params", + "description": "A schema which validates params accepted by the Foo adapter", + "type": "object", + + "properties": {} + } + ``` +
+ +
+ Example: Required integer placement id. + + ```json + { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Foo Adapter Params", + "description": "A schema which validates params accepted by the Foo adapter", + "type": "object", + + "properties": { + "placementId": { + "type": "integer", + "minimum": 1, + "description": "Placement ID" } - }] - }] + }, + + "required": ["placementId"] + } + ``` +
+ +
+ Example: Required access token and an optional hexadecimal account. + + ```json + { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Foo Adapter Params", + "description": "A schema which validates params accepted by the Foo adapter", + "type": "object", + + "properties": { + "token": { + "type": "string", + "description": "Token" + }, + "account": { + "type": "string", + "description": "Account", + "pattern": "^([a-fA-F\\d]+)$" + } + }, + + "required": ["token"] + } + ``` +
+ +
+ Example: Required access token or secret. + + ```json + { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Foo Adapter Params", + "description": "A schema which validates params accepted by the Foo adapter", + "type": "object", + + "properties": { + "token": { + "type": "string", + "description": "Token" + }, + "secret": { + "secret": "string", + "description": "Secret" + } + }, + + "oneOf": [ + { "required": ["token"] }, + { "required": ["secret"] } + ] + } + ``` +
+

+ +### Bidder Parameters Code + +{: .alert.alert-info :} +You can skip this step if your adapter has no bidder parameters. + +You also need to represent your bidder parameters in code. The core framework uses the JSON Schema file for validation, but your adapter code needs a data structure to support unmarshalling / deserialization. These data structures are organized in a shared path using a standard naming convention, which also serves as documentation of all adapter parameters. + +Create a file with the path `openrtb_ext/imp_{bidder}.go` containing an exported (must start with an upper case letter) data structure named `ImpExt{Bidder}`. All required and optional bidder parameters from the JSON Schema should be represented as fields. + +For example, this is what the bidder parameter code looks like for the example we used in the previous section: + +```go +package openrtb_ext + +type ImpExtFoo struct { + PlacementID string `json:"placementId"` } -{% endhighlight %} +``` + +Please follow [Go's standard naming convention](https://golang.org/doc/effective_go.html) for the field names (particularly for acronyms) and use `json` attributes to specify the JSON name, matching exactly what you defined in the bidder parameters JSON Schema. -Notes: +### Adapter Code -- `advertiserDomains` is the same as the OpenRTB 2.5 `bid.adomain` field but replicated here for downstream convenience -- See the [Prebid.js Bidder Adapter](/dev-docs/bidder-adaptor.html) page for details about the requested values for each field. -- The following fields are going to be enforced in an upcoming version of Prebid.js: advertiserDomains and mediaType. +Now it's time to write the bulk of your bid adapter code. + +Each adapter has its own directory (a 'package' in Go parlance) for all code and tests associated with translating an OpenRTB 2.5 Bid Request to your bidding server's protocol and mapping your server's response to an OpenRTB 2.5 Bid Response. The use of separate packages provide each adapter with its own naming scope to avoid conflicts and the freedom to organize files as you best see fit (although we make suggestions in this guide). + +Create a file with the path `adapters/{bidder}/{bidder}.go`. Your bid adapter code will need to implement and export: +- The `adapters.Builder` method to create a new instance of the adapter based on the host configuration. +- The `adapters.Bidder` interface consisting of the `MakeRequests` method to create outgoing requests to your bidding server and the `MakeBids` method to create bid responses. + +{: .alert.alert-warning :} +Go has only two kinds of access modifiers, exported and private, which are scoped at the package level. The access modifier is encoded into the name of the type or method. Names starting with an upper case letter are exported whereas names starting with a lower case letter are private. Please only export the three required methods and keep everything else private. + +Here is a reference implementation for a bidding server which uses the OpenRTB 2.5 protocol: + +```go +package foo + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/mxmCherry/openrtb" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Foo adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + requestJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + } + + return []*adapters.RequestData{requestData}, nil +} + +func (a *adapter) MakeBids(request *openrtb.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if responseData.StatusCode == http.StatusNoContent { + return nil, nil + } + + if responseData.StatusCode == http.StatusBadRequest { + err := &errortypes.BadInput{ + Message: "Unexpected status code: 400. Bad request from publisher. Run with request.debug = 1 for more info.", + } + return nil, []error{err} + } + + if responseData.StatusCode != http.StatusOK { + err := &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info.", responseData.StatusCode), + } + return nil, []error{err} + } + + var response openrtb.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + for _, seatBid := range response.SeatBid { + for _, bid := range seatBid.Bid { + b := &adapters.TypedBid{ + Bid: &bid, + BidType: getMediaTypeForBid(bid), + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + return bidResponse, nil +} +``` + +#### Builder + +The `Builder` method is responsible for validating the adapter configuration, performing any necessary pre-processing steps (such as macro parsing), and storing the configuration values in a new instance of the `adapter` struct. + +This method may be called multiple times if the host has configured aliases of your adapter. On the other hand, it will never be called if your bid adapter is disabled by the host. Please be aware the same instance of the adapter will be used to process all bid requests for each bidder or alias. To ensure thread safety, all runtime state must be stored in the `adapter` instance and the adapter may not mutate any global or package scoped variables. + +The first argument, `bidderName`, is the name of the bidder being built. This may be the bidder name you've chosen or it may be an alias. Most adapters ignore the `bidderName`, but its provided by the core framework for situations where the adapter might need to do something special for aliases. + +The second argument, `config`, is all configuration values set for your adapter. However, not all of this information is intended for use by the `Builder` method. The only two fields relevant here are `config.Endpoint` and `config.ExtraAdapterInfo`: +- `config.Endpoint` is the base url of your bidding server and may be interpreted as either a literal address or as a templated macro to support dynamic domains or dynamic paths. +- `config.ExtraAdapterInfo` may be used for any other values your adapter may need, such as an application token or publisher allow/deny list. You may interpret this string however you like, although JSON is a common choice. + +The `Builder` method is expected to return an error if either the `config.Endpoint` or the `config.ExtraAdapterInfo` values are invalid or cannot be parsed. Errors will be surfaced to the host during application startup as a fatal error. + +
+ Example: Builder using endpoint macros. + + ```go + type adapter struct { + endpointTemplate template.Template + } + + // Builder builds a new instance of the Foo adapter for the given bidder with the given config. + func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpointTemplate: *template, + } + return bidder, nil + } + ``` +
+ +
+ Example: Builder using extra adapter info. + + ```go + type extraInfo struct { + token string + } + + // Builder builds a new instance of the Foo adapter for the given bidder with the given config. + func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) { + info, err := parseExtraInfo(config.ExtraAdapterInfo) + if err != nil { + return nil, err + } + + bidder := &adapter{ + endpoint: config.Endpoint, + token: info.token, + } + return bidder, nil + } + + func parseExtraInfo(v string) (extraInfo, error) { + if len(v) == 0 { + return buildDefaultExtraInfo(), nil + } + + var info extraInfo + if err := json.Unmarshal([]byte(v), &info); err != nil { + return nil, fmt.Errorf("invalid extra info: %v", err) + } + + return info, nil + } + + func buildDefaultExtraInfo() extraInfo { + return extraInfo{ + token: "all your base are belong to us", + } + } + ``` +
+

+ +#### MakeRequests + +The `MakeRequests` method is responsible for returning none, one, or many HTTP requests to be sent to your bidding server. Bid adapters are forbidden from directly initiating any form of network communication and must entirely rely upon the core framework. This allows the core framework to optimize outgoing connections using a managed pool and record networking metrics. The return type `adapters.RequestData` allows your adapter to specify the HTTP method, url, body, and headers. + +This method is called once by the core framework for bid requests which have at least one valid Impression for your adapter. Impressions not configured for your adapter will be removed and are not accessible. + +The first argument, `request`, is the OpenRTB 2.5 Bid Request object. Extension information is stored as `json.RawMessage` byte arrays and must be unmarshalled and/or marshalled to be read and/or mutated. It is *critical* to understand that the `request` object contains pointers to shared memory. If your adapter needs to alter any data referenced by a pointer then you *must* first make a shallow copy. The only exception is for `request.Imp` and its elements, as these are already shallow copies. The exact same instance of the `request` object is also passed to the `MakeBids` method, so please be careful when mutating. It's safe to assume that `request.Imp[]` always contains at least one elements and that the `request.Imp[].ext.bidder` was successfully validated by your bidder parameter JSON Schema. + +
+ Example: Mutating banner shared memory (make a copy). + + ```go + // Populate the top level width and height of a banner request if it's not set by the publisher. + + if request.Imp[i].W == nil && request.Imp[i].H == nil && len(request.Imp[i].Format) > 0 { + bannerCopy := *request.Imp[i].Banner + bannerCopy.W = &(request.Imp[i].Banner.Format[0].W) + bannerCopy.H = &(request.Imp[i].Banner.Format[0].H) + request.Imp[i].Banner = &bannerCopy + } + ``` +
+

+ +The second argument, `requestInfo`, is for extra information and helper methods provided by the core framework. For now, this just includes `requestInfo.PbsEntryPoint` which is commonly used to determine if the request is for AMP or Long Form Video Ad Pods. This object will be expanded in the future to also include currency conversion and extension unmarshalling helper methods. + +The `MakeRequests` method is expected to return a slice (similar to a C# `List`) of `adapters.RequestData` objects representing the HTTP calls to be sent to your bidding server and a slice of type `error` for any issues encountered creating them. If there are no HTTP calls or if there are no errors, please return `nil` for both return values. Neither slices may contain `nil` elements. {: .alert.alert-info :} -Please provide as much information as possible in the meta object. Publishers use this data for tracking down bad creatives and ad blocking. The advertiserDomains field is particularly useful. Some of these fields may become required in a future release. +HTTP calls to your bidding server will automatically prefer GZIP compression. You should not specify it yourself using headers. You don't have to worry about decompressing the response in `MakeBids` either, as that will be taken care of automatically. + +An Impression may define multiple sizes and/or multiple ad formats. If your bidding server limits requests to a single ad placement, size, or format, then your adapter will need to split the Impression into multiple calls and merge the responses. + +
+ Example: Impression splitting. + + ```go + func (a *adapter) MakeRequests(request *openrtb.BidRequest, requestInfo *adapters.ExtraRequestInfo) (*adapters.RequestData, []error) { + var requests []*adapters.RequestData + var errors []error + + requestCopy := *request + for _, imp := range request.Imp { + requestCopy.Imp = []openrtb.Imp{imp} + + requestJSON, err := json.Marshal(request) + if err != nil { + errors = append(errors, err) + continue + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + } + requests = append(requests, requestData) + } + return requests, errors + } + ``` +
+

+ +If your bidding server supports multiple currencies, please be sure to pass it the `request.cur` field. If your bidding server only ever bids in a single currency, such as USD or EUR, that's fine. Prebid Server will convert your bid to the request currency if you include it in the bid response, otherwise we assume USD and conversion will not occur correctly. + +Please ensure you forward the bid floor (`request.imp[].bidfloor`) and bid floor currency (`request.imp[].bidfloorcur`) values to your bidding server for enforcement. You'll soon have access to currency conversion helper methods if your endpoint only supports floors in a single currency. + +There are a several values of a bid that publishers expect to be populated. Some are defined by the OpenRTB 2.5 specification and some are defined by Prebid conventions. + +| Parameter | Definer | Description | Path | +| - | - | - | - | +| CCPA | OpenRTB | The publisher is specifying the California Consumer Privacy Act consent string | `request.regs.ext.us_privacy` | +| COPPA | OpenRTB |The publisher is specifying the Children's Online Privacy Protection flag. | `request.regs.coppa` | +| Currency | OpenRTB |The publisher is specifying the desired bid currency. The Prebid Server default is `"USD"`. | `request.cur` | +| [Debug](https://github.com/prebid/prebid-server/issues/745) | Prebid | The publisher is requesting verbose debugging information from Prebid Server | `request.ext.prebid.debug` | +| [First Party Data](https://docs.prebid.org/prebid-server/features/pbs-fpd.html) | Prebid | The publisher may provide first party data (ex: keywords). | `request.imp[].ext.context.data.*`, `request.app.ext.data.*`, `request.site.ext.data.*`, `request.user.ext.data.*` | +| GDPR | OpenRTB |The publisher is specifying the European General Data Protection Regulation flag and TCF consent string | `request.regs.ext.gdpr`, `request.user.ext.consent`| +| Site or App | OpenRTB |The publisher will provide either the site or app (not both) representing the client's device. | `request.site`, `request.app` | +| Supply Chain | OpenRTB |The publisher's declaration of all parties who are selling or reselling the bid request. | `request.source.ext.schain` | +| Test | OpenRTB | The publisher is sending non-production traffic which also enabled verbose debugging information from Prebid Server. | `request.test` | +| Video Parameters | OpenRTB | The publisher is specifying video ad requirements or preferences. | `request.imp[].video` | -### BidResponse Requirements +{: .alert.alert-warning :} +For simplicity, adapters are expected to make net-price bids (e.g. "If this ad wins, what will the publisher make?"), not gross-price bids. Publishers can correct for gross-price bids by setting [Bid Adjustments](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#bid-adjustments) to account for fees. -**Note**: In order to be part of the auction, all bids must include: +#### Response -- An ID -- An ImpID which matches one of the `Imp[i].ID`s from the incoming `BidRequest` -- A positive `Bid.Price` -- A `Bid.CrID` which uniquely identifies the Creative in the bid. +The `MakeBids` method is responsible for parsing the bidding server's response and mapping it to the OpenRTB 2.5 Bid Response object model. -Bids which don't satisfy these standards will be filtered out before Prebid Server responds. +This method is called for each response received from your bidding server within the bidding window (`request.tmax`). If there are no requests or if all requests time out, the `MakeBids` method will not be called. -## Long-Form Video Support -If long-form video will be supported ensure the bidder has the following: +{: .alert.alert-info :} +It's *imperative* to include all required information in the response for your bid to be accepted. Please avoid common mistakes, such as not specifying the bid currency and not detecting the media type from the bidding server response. -{: .table .table-bordered .table-striped } -|Field |Type |Description -|----------------|-------------------------------|-----------------------------| -|bid.bidVideo.PrimaryCategory | string | The category for the bid. This should be able to be translated to Primary ad server format| -|TypedBid.bid.Cat | []string | The category for the bid. Should be an array with length 1 containing the value in IAB format| -|TypedBid.BidVideo.Duration | int | Ad duration in seconds| -|TypedBid.bid.Price | float | Bid price| +The first argument, `request`, is the exact same OpenRTB 2.5 Bid Request object provided to (and potentially mutated by) the `MakeRequests` method. The information in the `request` may be useful as part of detecting the media type. + +The second argument, `requestData`, is the exact same `adapters.RequestData` object returned by the `MakeRequests` method. It's rare for adapters to make use of this information, but it's provided for potential edge cases. + +The third argument, `responseData`, is the HTTP response received from your bidding server and contains the status code, body, and headers. If your bidding server replies with a GZIP encoded body, it will be automatically decompressed. + +The `MakeBids` method is expected to return an `adapters.BidderResponse` object with one or more bids mapped from your bidding server's response. This may be as simple as decorating an OpenRTB 2.5 Bid Response with a some Prebid Server metadata, such as the media type, or more complicated mapping logic depending on your server's response format. + +Please review the entire [OpenRTB 2.5 Bid Response](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf#page=32) documentation to fully understand the response object model and expectations. We've summarized some common fields below. Data which is listed as required is enforced by the core framework and cannot be omitted. + +| Path | Scope | Description | +| - | - | - | +| `.Currency` | Required | [3-letter ISO 4217 code](https://www.iso.org/iso-4217-currency-codes.html) defining the currency of the bid. Defaults to USD. | +| `.Bids[].BidType` | Required | Prebid Server defined value which identifies the media type as either `banner`, `video`, `audio`, or `native`. Should be mapped from the bidding server response. | +| `.Bids[].Bid.ADomain` | Optional | Advertiser domain for block list checking. | +| `.Bids[].Bid.AdM` | Optional | Ad markup to serve the creative if the bid wins. May be HTML, Native, or VAST/VMAP formats. | +| `.Bids[].Bid.CrID` | Required | Unique id of the creative. | +| `.Bids[].Bid.ID` | Required | Bidder generated id to assist with logging/tracking. | +| `.Bids[].Bid.ImpID` | Required | Id of the corresponding bid request Impression. Prebid Server validates this id is actually found in the bid request. | +| `.Bids[].Bid.Price` | Required | Net price CPM of the bid, not gross price. Publishers can correct for gross price bids by setting Bid Adjustments to account for fees. We recommend the most granular price a bidder can provide. | +| `.Bids[].Bid.W` | Optional | Width of the creative in pixels. | +| `.Bids[].Bid.H` | Optional | Height of the creative in pixels. | +| `.Bids[].Bid.Ext` | Optional | Embedded JSON containing Prebid metadata (see below) or custom information. | + +If you'd like to support Long Form Video Ad Pods, then you'll need to provide the followings information: + +| Path | Description | +| - | - | +| `.Bids[].BidVideo.PrimaryCategory` | Category for the bid. Should be able to be translated to the primary ad server format. | +| `.Bids[].Bid.Cat` | Category for the bid. Should be able to be translated to the primary ad server format. | +| `.Bids[].BidVideo.Duration` | Length of the video in integer seconds. | +| `.Bids[].DealPriority` | Deal tier integer value. Defaults to 0. | {% capture alertNote %} -`bid.bidVideo.PrimaryCategory` or `TypedBid.bid.Cat` should be specified. +Either `.Bids[].BidVideo.PrimaryCategory` or `.Bids[].Bid.Cat` should be provided. {% endcapture %} -{% include alerts/alert_note.html content=alertNote %} -To learn more about IAB categories, refer site provided by adtagmacros.com: [IAB categories](https://adtagmacros.com/list-of-iab-categories-for-advertisement/) +Prebid has historically struggled with sharing granular bid response data with publishers, analytics, and reporting systems. To address this, we've introduced a standard object model. We encourage adapters to provide as much information as possible in the bid response. + +{: .alert.alert-danger :} +Bid metadata will be *required* in a coming Prebid.js release, specifically for AdvertiserDomains and MediaType. We recommend making sure your adapter sets these values or Prebid.js may throw out the bid. + +| Path | Description | +| - | - | +| `.NetworkID` | Bidder-specific network/DSP id. | +| `.NetworkName` | Bidder-specific network/DSP name. | +| `.AgencyID` | Bidder-specific agency id. | +| `.AgencyName` | Bidder-specific agency name | +| `.AdvertiserID` | Bidder-specific advertiser id | +| `.AdvertiserName` | Bidder-specific advertiser name. | +| `.AdvertiserDomains` | Advertiser domains for the landing page(s). Should match `.Bids[].Bid.ADomain`. +| `.BrandID` | Bidder-specific brand id for advertisers with multiple brands. | +| `.BrandName` | Bidder-specific brand name. | +| `.PrimaryCategoryID` | Primary IAB category id. | +| `.SecondaryCategoryIDs` | Secondary IAB category ids. | +| `.MediaType` | Either `banner`, `audio`, `video`, or `native`. Should match `.Bids[].BidType`. | + + + +
+ Example: Setting metadata. + + ```go + func (a *adapter) MakeBids(request *openrtb.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + ... + for _, seatBid := range response.SeatBid { + for _, bid := range seatBid.Bid { + b := &adapters.TypedBid{ + Bid: &bid, + BidType: getMediaTypeForBid(bid), + } -## Test Your Bidder + if meta, err := buildMeta(b); err != nil { + errs = append(errs, metaErr) + } else { + b.Bid.Ext = meta + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + ... + } + + func buildMeta(bid *adapters.TypedBid) (json.RawMessage, error) { + metaExt := openrtb_ext.ExtBidPrebid { + Meta: &openrtb_ext.ExtBidPrebidMeta { + NetworkID: 1, + NetworkName: "Some Network Name", + AgencyID: 2, + AgencyName: "Some Agency Name", + AdvertiserID: 3, + AdvertiserName: "Some Advertiser Name", + AdvertiserDomains: bid.ADomain, + BrandID: 4, + BrandName: "Some Brand Name", + PrimaryCategoryID: "IAB-1", + SecondaryCategoryIDs: []string{"IAB-2", "IAB-3"}, + MediaType: b.BidType, + } + } + return json.Marshal(meta) + } + ``` +
+

-### Automated Tests +### Create A User Syncer (Optional) -Bidder tests live in two files: +Prebid Server offers a federated [user sync solution](https://docs.prebid.org/prebid-server/developers/pbs-cookie-sync.html) to store user ids in a single cookie within the host's domain. If your bidding server supports the protocol, you may add support with a relatively small amount of code. -- `adapters/{bidder}/{bidder}_test.go`: contains unit tests for your Bidder implementation. -- `adapters/{bidder}/params_test.go`: contains unit tests for your Bidder's JSON Schema params. +Create a file with the path `adatpers/{bidder}/usersync.go` using the following template: -Since most Bidders communicate through HTTP using JSON bodies, you should -use the [JSON-test utilities](https://github.com/prebid/prebid-server/blob/master/adapters/adapterstest/test_json.go). -This comes with several benefits, which are described in the source code docs. +```go +package {bidder} -If your HTTP requests don't use JSON, you'll need to write your tests in the code. -We expect to see at least 90% code coverage on each Bidder. +import ( + "text/template" + + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/usersync" +) -Bidders should also define an `adapters/{bidder}/{bidder}test/params/race/{mediaType}.json` file for any supported -Media Types (banner, video, audio, or native). These files should contain a JSON object with all the bidder params -(required & optional) which are expected in supporting that video type. This will be used in automated tests which -check for race conditions across Bidders. +func NewSyncer(template *template.Template) usersync.Usersyncer { + return adapters.NewSyncer("{bidder}", 0, template, adapters.SyncTypeRedirect) +} +``` + +The heavy lifting is handled by the `adapters.NewSyncer` method. You just need to provide a few arguments: + +1. `familyName`: Name used for storing your user sync id within the federated cookie. Please keep this the same as your bidder name. +1. `vendorID`: ID for your bidding server as registered with the [GDPR Global Vendor List (GVL)](https://iabeurope.eu/vendor-list-tcf-v2-0/). Leave this as `0` if you are not registered with IAB Europe. +1. `urlTemplate`: Pass through the `template` argument. +1. `syncType`: Type of user sync supported by your bidding server. The valid options are `SyncTypeRedirect` and `SyncTypeIframe`. + +### Register With The Core + +Prebid Server does not use reflection or any other automagic technology to recognize your new bid adapter. You must manually register it with the core framework. It's just a few lines of code. + +{% capture alertNote %} +You will need to add an `import` statement for your bid adapter package in these files. Modern code editors such as Visual Studio Code and JetBrain's GoLand will do that for you. +{% endcapture %} + +Edit the file `openrtb_ext/bidders.go` to add your bidder name constant and include it alphabetically in the `CoreBidderNames` list: + +```go +// Names of core bidders. These names *must* match the bidder code in Prebid.js if an adapter also exists in that +// project. You may *not* use the name 'general' as that is reserved for general error messages nor 'context' as +// that is reserved for first party data. +// +// Please keep this list alphabetized to minimize merge conflicts. +const ( + ... + Bidder{Bidder} BidderName = "{bidder}" + ... +) +``` + +```go +// CoreBidderNames returns a slice of all core bidders. +func CoreBidderNames() []BidderName { + return []BidderName{ + ... + Bidder{Bidder}, + ... + } +} +``` + +Edit the file `exchange/adapter_builders.go` to register your builder method: + +```go +func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { + return map[openrtb_ext.BidderName]adapters.Builder{ + ... + openrtb_ext.Bidder{Bidder}: {bidder}.Builder, + ... + } +} +``` + +If you have a user syncer, edit the file `usersync/usersyncers/syncer.go` to include it in the syncer map. + +```go +func NewSyncerMap(cfg *config.Configuration) map[openrtb_ext.BidderName]usersync.Usersyncer { + syncers := make(map[openrtb_ext.BidderName]usersync.Usersyncer, len(cfg.Adapters)) + ... + insertIntoMap(cfg, syncers, openrtb_ext.Bidder{Bidder}, {bidder}.NewSyncer) + ... +} +``` -### Manual Tests +### Set Adapter Defaults -Build and start your server: +Finally, you need to provide default settings for your bid adapter. You can decide if you'd like your bid adapter to be enabled out of the box, and if so, you'll need to provide a default endpoint and default extra adapter info if applicable. If your bid adapter requires host specific information to function properly, such as a security token or host account, then it's best to leave the adapter disabled. + +{: .alert.alert-warning :} +The default endpoint should not be specific to any particular host, such as Xandr/AppNexus. We may ask you about suspicious looking ids during the review process. Please reach out to individual hosts if you need to set specialized configuration. + +#### Enabled By Default + +Edit the file `config/config.go` to register your default endpoint within the `SetupViper` method. If your bid adapter makes use of extra adapter info and you'd like to provide a good default value, you can do that here too. + +```go +func SetupViper(v *viper.Viper, filename string) { + ... + v.SetDefault("adapters.{bidder}.endpoint", "https://your.url/any/path") + v.SetDefault("adapters.{bidder}.extra_info", `{"your": "extra info"}`) + ... +} +``` + +#### Disabled By Default + +Edit the file `config/config.go` to register your default endpoint within the `SetupViper` method. You may still provide a default endpoint or extra adapter info. + +```go +func SetupViper(v *viper.Viper, filename string) { + ... + v.SetDefault("adapters.{bidder}.disabled", "true") + ... +} +``` + +### Set User Syncer Defaults + +If you implemented a user syncer, you'll need to provide a default endpoint. Edit the file `config/config.go` to alphabetically register your user syncer in the `setDerivedDefaults` method: + +```go +func (cfg *Configuration) setDerivedDefaults() { + ... + setDefaultUsersync(cfg.Adapters, openrtb_ext.Bidder{Bidder}, "https://your.url/sync?r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3D{bidder}%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BUUID%5D") + ... +} +``` + +If you don't have a good default, please add a comment instead. + +```go +func (cfg *Configuration) setDerivedDefaults() { + ... + // openrtb_ext.Bidder{Bidder} doesn't have a good default. + ... +} +``` + + +Yes, you're right. That url value is quite complicated. You can find further details in our [user sync documentation](https://docs.prebid.org/prebid-server/developers/pbs-cookie-sync.html). + +The user sync endpoint is composed of two main parts, the url of your user syncer and a redirect url back to Prebid Server. The url of your user syncer is responsible for reading the user id from the client's cookie and redirecting to Prebid Server with a user id macro resolved. + +The url of your user syncer can make use of the following privacy policy macros which will be resolved by Prebid Server before sending the url to your server: +- `{{.USPrivacy}}`: Client's CCPA consent string. +- `{{.GDPR}}`: Client's GDPR TCF enforcement flag. +- `{{.GDPRConsent}}`: Client's GDPR TCF consent string. + +
+ Example: Bidding server url with no macros. + + ```go + "https://your.url/sync?r=" + ``` +
+ +
+ Example: Bidding server url with CCPA privacy consent. + + ```go + "https://your.url/sync?usp={{.USPrivacy}}&r=" + ``` +
+

+ +The redirect url for Prebid Server must follow this format: +``` +{host}/setuid?bidder={bidder}&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&uid=[UUID] +``` + +- `{host}` is a placeholder for the Prebid Server host url. In code, you would use `url.QueryEscape(externalURL)`. +- `{bidder}` is a placeholder for the name of your bid adapter. +- `[UUID]` is a macro defined by your user sync server which will be replaced with the user's id. + +The final value of the redirect url is encoded for safe use within a query string: + +``` +{host}%2Fsetuid%3Fbidder%3D{bidder}%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BUUID%5D +``` + +## Test Your Adapter + +This chapter will guide you through the creation of automated unit tests to cover your bid adapter code, bidder parameters JSON Schema, and user sync code. We use GitHub Action Workflows to ensure the code you submit passes validation. You can run the same validation locally with this command: ```bash -go build . -./prebid-server +./validate.sh --nofmt --cov --race 10 +``` + +### Adapter Code Tests + +Bid requests and server responses can be quite verbose. To avoid large blobs of text embedded within test code, we've created a framework for bid adapters which use a JSON body and/or a url. If your bidding server uses another payload format, such as XML, you're on your own. + +We strive for as much test coverage as possible, but recognize that some code paths are impractical to simulate and rarely occur. You do not need to test the error conditions for `json.Marshal` calls, for template parse errors within `MakeRequests` or `MakeBids`, or for `url.Parse` calls. Following this guidance usually results in a coverage rate of around 90% - 95%, although we don't enforce a specific threshold. + +To use the test framework, create a file with the path `adapters/{bidder}/{bidder}_test.go` with the following template: + +```go +package {bidder} + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.Bidder{Bidder}, config.Adapter{ + Endpoint: "http://whatever.url"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "{bidder}test", bidder) +} +``` + +You should use an obviously fake endpoint for your tests. There is no reason to use a real endpoint value. Please also note the `_test.go` file suffix is a required Go idiom enforced by Go tools. The Go test runner will look in these files for tests and the Go compiler will exclude this code from production binaries. + +Each test case should be written in its own JSON file with a succinct, yet descriptive, name of what's being tested. The files should be located in either `adapters/{bidder}/{bidder}test/exemplary/` for straight forward "happy path" tests or `adapters/{bidder}/{bidder}test/supplemental` for tests which produce errors or cover more complicated scenarios. We expect to see 'exemplary' tests for each supported media type. + +The format of a JSON test is as follows: +```json +{ + "mockBidRequest": { + «OpenRTB 2.5 Bid Request» + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "«Bidding Server Endpoint»", + "headers": { + "«Name»": ["«Value»"], + }, + "body": { + «Bidding Server Request Body» + } + }, + "mockResponse": { + "status": «Mock HTTP Status Code (e.g. 200)», + "headers": { + "«Name»": ["«Value»"], + }, + "body": { + «Bidding Server Response Body» + }, + }, + }], + "expectedBidResponses": [{ + "bids": [{ + «Prebid Server Bid Response» + }] + }], + "expectedMakeRequestsErrors": [{ + "value": "«Value»", + "comparison": "«literal or regex»" + }], + "expectedMakeBidsErrors": [{ + "value": "«Value»", + "comparison": "«literal or regex»" + }] +} ``` -Then `POST` an OpenRTB Request to `https://localhost:8000/openrtb2/auction`. +The `mockBidRequest`, `httpCalls`, and `expectedBidResponses` fields are required. The `expectedMakeRequestsErrors` and `expectedMakeBidsErrors` may be omitted if there are no expected errors. We provide a `literal` and `regex` mode for testing error values. We often use the `regex` mode to handle error messages produced by the core Go framework which changed between recent releases. -If at least one `request.imp[i].ext.{bidder}` is defined in your Request, -then your bidder should be called. +To make everyone's life easier, please use a JSON 'prettifier' to apply standard formatting to your test files. We recommend the use of Visual Studio Code's [Beautify](https://marketplace.visualstudio.com/items?itemName=HookyQR.beautify) extension. -To test user syncs, [save a UID](/prebid-server/endpoints/pbs-endpoint-setuid.html) using the FamilyName of your Usersyncer. -The next time you use `/openrtb2/auction`, the OpenRTB request sent to your Bidder should have -`BidRequest.User.BuyerUID` with the value you saved. +### Builder Tests -## Automated Tests +The `TestJsonSamples` tests provide adequate test coverage of your bid adapter's `Builder` method if it remains simple. If you've added custom logic, macro support, or make use of extra adapter info, you'll need additional tests. -This project uses [TravisCI](https://travis-ci.org/) to make sure that every PR passes automated tests. -To reproduce these tests locally, use: +If your adapter supports template parsing, we recommend adding this failure test to the `adapters/{bidder}/{bidder}_test.go` file: +```go +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.Bidder{Bidder}, config.Adapter{ + Endpoint: "{{Malformed}}"}) + + assert.Error(t, buildErr) +} ``` -./validate --nofmt --cov + +If your adapter supports extra adapter info, we recommend adding these tests to the `adapters/{bidder}/{bidder}_test.go` file. You should customize the `TestEmptyConfig` test to assert your adapter's default extra info values. + +```go +func TestBadConfig(t *testing.T) { + _, buildErr := Builder(openrtb_ext.Bidder{Bidder}, config.Adapter{ + Endpoint: `http://it.doesnt.matter/bid`, + ExtraAdapterInfo: `{foo:42}`, + }) + + assert.Error(t, buildErr) +} + +func TestEmptyConfig(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.Bidder{Bidder}, config.Adapter{ + Endpoint: `http://it.doesnt.matter/bid`, + ExtraAdapterInfo: ``, + }) + + bidder{Bidder} := bidder.(*adapter) + + assert.NoError(t, buildErr) + assert.Empty(t, bidder{Bidder}.extraInfo.SomeInfo) +} ``` -### Writing Tests +### Adapter Race Condition Tests -Tests for `some-file.go` should be placed in the file `some-file_test.go` in the same package. -For more info on how to write tests in Go, see [the Go docs](https://golang.org/pkg/testing/). +You must define race condition tests for each media type supported by your bid adapter. We don't expect bid adapters to run concurrent code. Rather, these tests attempt to verify that your bid adapter doesn't modify shared memory. We use Go's [race detector](https://golang.org/doc/articles/race_detector.html) which is a great line of defense, but it may produce false negatives. It will not produce false positives, so please investigate further if these tests ever fail. -### Adapter Tests +Create a file with the path `adapters/{bidder}/{bidder}test/params/race/{mediaType}.json` for each `banner`, `video`, `audio`, and `native` media type supported by your adapter. Include all required and optional bidder parameters defined by your JSON Schema. -If your adapter makes HTTP calls using standard JSON, you should use the -[RunJSONBidderTest](https://github.com/prebid/prebid-server/blob/master/adapters/adapterstest/test_json.go#L50) function. +Here's an example file using the same example JSON Schema from other chapters: +```json +{ + "placementId": "Some Placement" +} +``` -This will be much more thorough, convenient, maintainable, and reusable than writing standard Go tests -for your adapter. +### Bidder Parameter Tests + +The bidder parameter JSON Schema files are considered a form of code and must be tested. Create a file with the path `adapters/{bidder}/params_test.go` using the following template: + +```go +package {bidder} + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.Bidder{Bidder}, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} -### Concurrency Tests +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.Bidder{Bidder}, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} -Code which creates new goroutines should include tests which thoroughly exercise its concurrent behavior. -The names of functions which test concurrency should start with `TestRace`. For example `TestRaceAuction` or `TestRaceCurrency`. +var validParams = []string{ + `{"placementId": ""}`, + `{"placementId": "Some Placement ID}`, +} + +var invalidParams = []string{ + `{"placementId": 42}`, +} +``` +Please include tests for required fields, optional fields, conditional fields such as `oneOf`, regex filters, and data type mismatches. For example, if the field is defined as a string please include one invalid case for the wrong data type such as an integer in this example. + +You don't have to go crazy with combinatorials. We're looking for just enough test cases to build confidence. + +### User Syncer Tests + +{: .alert.alert-info :} +Please skip to the end of this section if your adapter doesn't define a user syncer. + +We ask that you include a user syncer test to verify the basic mechanics of macro substitution. The `syncURL` should be the same value used in the `setDefaultUsersync` call with the `url.QueryEscape(externalURL)` code replaced with a simple hardcoded value such as `"host"`. Please keep the privacy policy values simple, as we're only testing substitution. + +Create a file with the path `adapters/{bidder}/usersync_test.go` using the following template: + +```go +package {bidder} + +import ( + "testing" + "text/template" + + "github.com/prebid/prebid-server/privacy" + "github.com/prebid/prebid-server/privacy/ccpa" + "github.com/prebid/prebid-server/privacy/gdpr" + "github.com/stretchr/testify/assert" +) + +func TestSyncer(t *testing.T) { + syncURL := "" + syncURLTemplate := template.Must( + template.New("sync-template").Parse(syncURL), + ) + + syncer := NewSyncer(syncURLTemplate) + syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{ + GDPR: gdpr.Policy{ + Signal: "A", + Consent: "B", + }, + CCPA: ccpa.Policy{ + Consent: "C", + }, + }) + + assert.NoError(t, err) + assert.Equal(t, "", syncInfo.URL) + assert.Equal(t, "redirect", syncInfo.Type) + assert.Equal(t, 0, syncer.GDPRVendorID()) +} +``` + +If you *DON'T* have a user syncer, edit the file `usersync/usersyncers/syncer_test.go` to exclude your bid adapter from user sync tests: -The `./validate.sh` script will run these using the [Race Detector](https://golang.org/doc/articles/race_detector.html). +```go +adaptersWithoutSyncers := map[openrtb_ext.BidderName]bool{ + ... + openrtb_ext.Bidder{Bidder}: true, + ... +} +``` + +### Manual End To End Tests + +We'll verify your adapter works correctly on a technical level during the code review, but you'll need to perform separate end-to-end testing: + +1. Build the project and start your server: + ```bash + go build . + ./prebid-server + ``` + +1. POST an OpenRTB 2.5 Bid Request with at least one Impression defined for your bid adapter with a supported media type. This is an example template for a banner ad. + ```bash + curl --request POST \ + --url 'https://localhost:8000/openrtb2/auction' \ + --header 'Content-Type: application/json' \ + --data '{ + "id": "some-request-id", + "test": 1, + "site": { + "page": "prebid.org" + }, + "imp": [{ + "id": "some-impression-id", + "banner": { + "format": [{ + "w": 600, + "h": 500 + }, { + "w": 300, + "h": 600 + }] + }, + "ext": { + "prebid": { + "bidder": { + "{bidder}": { + + } + } + } + } + }], + "tmax": 1000 + }' + ``` + +If your bid adapters defines a user syncer, please perform end-to-end testing of the user sync process: -## Add your Bidder to the Server +1. [Save a User ID](https://docs.prebid.org/prebid-server/endpoints/pbs-endpoint-setuid.html) using the `familyName` of your user syncer. This is likely the same as your bidder name. -- Add a new [BidderName constant](https://github.com/prebid/prebid-server/blob/master/openrtb_ext/bidders.go) for your `{bidder}`. -- Update the [newAdapterMap function](https://github.com/prebid/prebid-server/blob/master/exchange/adapter_map.go) to make your Bidder available in auctions. -- Update the [newSyncerMap function](https://github.com/prebid/prebid-server/blob/master/usersync/usersync.go) to make your Bidder available for user syncs. +1. Run a test auction (see the curl example above) and verify in the debug response that the outgoing `request.ext.debug.httpcalls` calls includes the User ID you saved in step 1. -## Document Your Adapter +It may be a bit tricky to track down the root cause of user sync errors. If you get stuck, please [submit a GitHub issue](https://github.com/prebid/prebid-server/issues/new) and we'll provide guidance. -There are two documents required before we'll accept your pull request: +## User Documentation -1. Repo metadata - create a new file https://github.com/prebid/prebid-server/blob/master/static/bidder-info/BIDDERCODE.yaml based on one of the other ones there. Note that you must provide an email that's not a single individual -- we need robust maintainer contact info read by multiple people like "support@example.com". -1. User documentation - required to appear in the [Prebid Server adapters page](/dev-docs/pbs-bidders.html). - 1. If you already have a Prebid.js bid adapter, update your bidders existing file in https://github.com/prebid/prebid.github.io/tree/master/dev-docs/modules to add the `pbs: true` variable in the header section. - 1. If you don't have a Prebid.js bid adapter, create a new file in https://github.com/prebid/prebid.github.io/tree/master/dev-docs/modules based on the example below. +Human readable documentation for bid adapters is required in the separate [prebid.github.io](https://github.com/prebid/prebid.github.io) repository. We will not merge your bid adapter until you've at least opened a documentation PR and comment with a link to it. + +1. If you already have a Prebid.js bid adapter, update your existing bidder file in https://github.com/prebid/prebid.github.io/tree/master/dev-docs/modules to add the `pbs: true` variable in the header section. If your Prebid Server bidding parameters are different from your Prebid.js parameters, please include the differences in this document for publishers to be aware. +1. If you don't have a Prebid.js bid adapter, create a new file in https://github.com/prebid/prebid.github.io/tree/master/dev-docs/modules using this template: ``` --- layout: bidder -title: example -description: Prebid example Bidder Adapter -biddercode: example +title: {bidder} +description: Prebid {Bidder} Bidder Adapter +biddercode: {bidder} gdpr_supported: true/false tcf2_supported: true/false gvl_id: 111 usp_supported: true/false coppa_supported: true/false schain_supported: true/false -userId: (list of supported vendors) -media_types: banner, video, native +userId: +media_types: banner, video, audio, native safeframes_ok: true/false bidder_supports_deals: true/false pbjs: true/false @@ -245,9 +1183,9 @@ The Example Bidding adapter requires setup before beginning. Please contact us a ### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|---------------|----------|-----------------------|-----------|-----------| -| `placement` | required | Placement id | `'11111'` | `string` | +| Name | Scope | Description | Example | Type | +|---------------|----------|--------------|-----------|----------| +| `placementId` | required | Placement ID | `'11111'` | `string` | ``` Notes on the metadata fields: - Add `pbs: true`. If you also have a [Prebid.js bid adapter](/dev-docs/bidder-adaptor.html), add `pbjs: true`. Default is false for both. @@ -263,6 +1201,36 @@ Notes on the metadata fields: - If your bidder supports deals, set `bidder_supports_deals: true`. No default value. - If you're a member of Prebid.org, add `prebid_member: true`. Default is false. + +## File Checklist + +- Bidder Info + - `static/bidder-info/{bidder}.yaml` +- Bidder Parameters + - `static/bidder-params/{bidder}.json` + - `openrtb_ext/imp_{bidder}.go` + - `adapters/{bidder}/params_test.go` +- Adapter Code + - `adapters/{bidder}/{bidder}.go` + - `adapters/{bidder}/{bidder}_test.go` + - `adapters/{bidder}/{bidder}test/exemplary/*.json` + - `adapters/{bidder}/{bidder}test/supplemental/*.json` + - `adapters/{bidder}/{bidder}test/params/race/{mediaType}.json` +- User Syncer - If You Have One + - `adapters/{bidder}/usersync.go` + - `adapters/{bidder}/usersync_test.go` + - `usersync/usersyncers/syncer.go` +- User Syncer - If You Don't + - `usersync/usersyncers/syncer_test.go` +- Register With The Core + - `openrtb_ext/bidders.go` + - `exchange/adapter_builders.go` +- Defaults + - `config/config.go` + ## Contribute -Finally, [Contribute](https://github.com/prebid/prebid-server/blob/master/docs/developers/contributing.md) your Bidder to the project. +Whew! You're almost done. Thank you for taking the time to develop a Prebid Server bid adapter. When you're ready, [contribute](https://github.com/prebid/prebid-server/blob/master/docs/developers/contributing.md) your new bid adapter by opening a PR to the [PBS-Go GitHub repository](https://github.com/prebid/prebid-server) with the name "New Adapter: {Bidder}". + +{: .alert.alert-warning :} +You don't need to ask permission or open a GitHub issue before submitting an adapter. From 2e3fb4d42acbca9a98d8dda65c831ba3fa50783b Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Tue, 1 Dec 2020 12:31:12 -0800 Subject: [PATCH 127/149] updated list of PubMatic supported user id modules (#2543) --- dev-docs/bidders/pubmatic.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/pubmatic.md b/dev-docs/bidders/pubmatic.md index ec439ec38a..14a0a9bf39 100644 --- a/dev-docs/bidders/pubmatic.md +++ b/dev-docs/bidders/pubmatic.md @@ -9,7 +9,7 @@ usp_supported: true coppa_supported: true schain_supported: true getFloor: true -userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId +userIds: britepoolId, criteo, fabrickId, haloId, id5Id, identityLink, intentiqId, idx, liveIntentId, lotamePanoramaId, netId, parrableId, pubCommonId, quantcastId, sharedId, unifiedId, verizonMediaId, zeotapIdPlus prebid_member: true safeframes_ok: true tcf2_supported: true From 15bac18bed64c6ad637f411d8718833373dd08d9 Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 1 Dec 2020 16:39:45 -0500 Subject: [PATCH 128/149] PBS Go docs escaping {{}} (#2544) --- prebid-server/developers/add-new-bidder-go.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/prebid-server/developers/add-new-bidder-go.md b/prebid-server/developers/add-new-bidder-go.md index 98d66ab9e0..08fbe3693e 100644 --- a/prebid-server/developers/add-new-bidder-go.md +++ b/prebid-server/developers/add-new-bidder-go.md @@ -786,7 +786,7 @@ If you implemented a user syncer, you'll need to provide a default endpoint. Edi ```go func (cfg *Configuration) setDerivedDefaults() { ... - setDefaultUsersync(cfg.Adapters, openrtb_ext.Bidder{Bidder}, "https://your.url/sync?r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3D{bidder}%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BUUID%5D") + setDefaultUsersync(cfg.Adapters, openrtb_ext.Bidder{Bidder}, "https://your.url/sync?r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3D{bidder}%26gdpr%3D{%raw%}{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}{%endraw%}%26uid%3D%5BUUID%5D") ... } ``` @@ -807,9 +807,9 @@ Yes, you're right. That url value is quite complicated. You can find further det The user sync endpoint is composed of two main parts, the url of your user syncer and a redirect url back to Prebid Server. The url of your user syncer is responsible for reading the user id from the client's cookie and redirecting to Prebid Server with a user id macro resolved. The url of your user syncer can make use of the following privacy policy macros which will be resolved by Prebid Server before sending the url to your server: -- `{{.USPrivacy}}`: Client's CCPA consent string. -- `{{.GDPR}}`: Client's GDPR TCF enforcement flag. -- `{{.GDPRConsent}}`: Client's GDPR TCF consent string. +- `{%raw%}{{.USPrivacy}}{%endraw%}`: Client's CCPA consent string. +- `{%raw%}{{.GDPR}}{%endraw%}`: Client's GDPR TCF enforcement flag. +- `{%raw%}{{.GDPRConsent}}{%endraw%}`: Client's GDPR TCF consent string.
Example: Bidding server url with no macros. @@ -823,14 +823,14 @@ The url of your user syncer can make use of the following privacy policy macros Example: Bidding server url with CCPA privacy consent. ```go - "https://your.url/sync?usp={{.USPrivacy}}&r=" + "https://your.url/sync?usp={%raw%}{{.USPrivacy}}{%endraw%}&r=" ```

The redirect url for Prebid Server must follow this format: ``` -{host}/setuid?bidder={bidder}&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&uid=[UUID] +{host}/setuid?bidder={bidder}&gdpr={%raw%}{{.GDPR}}&gdpr_consent={{.GDPRConsent}}{%endraw%}&uid=[UUID] ``` - `{host}` is a placeholder for the Prebid Server host url. In code, you would use `url.QueryEscape(externalURL)`. @@ -840,7 +840,7 @@ The redirect url for Prebid Server must follow this format: The final value of the redirect url is encoded for safe use within a query string: ``` -{host}%2Fsetuid%3Fbidder%3D{bidder}%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BUUID%5D +{host}%2Fsetuid%3Fbidder%3D{bidder}%26gdpr%3D{%raw%}{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}{%endraw%}%26uid%3D%5BUUID%5D ``` ## Test Your Adapter @@ -941,7 +941,7 @@ If your adapter supports template parsing, we recommend adding this failure test ```go func TestEndpointTemplateMalformed(t *testing.T) { _, buildErr := Builder(openrtb_ext.Bidder{Bidder}, config.Adapter{ - Endpoint: "{{Malformed}}"}) + Endpoint: "{%raw%}{{Malformed}}{%endraw%}"}) assert.Error(t, buildErr) } From 08afec62a3db2a2436020b23d389b5c072f759c5 Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 2 Dec 2020 09:35:31 -0500 Subject: [PATCH 129/149] adding videonow bidder code (#2547) --- dev-docs/bidders/videonow.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/videonow.md b/dev-docs/bidders/videonow.md index 4d22e4c26e..11eab677fd 100644 --- a/dev-docs/bidders/videonow.md +++ b/dev-docs/bidders/videonow.md @@ -2,6 +2,7 @@ layout: bidder title: videonow description: Prebid Videonow Bidder Adaptor +biddercode: videonow pbjs: true media_types: banner --- From f3c47b3dd2b8f9a39f783a6a88914fe700df75a2 Mon Sep 17 00:00:00 2001 From: Sourabh Gandhe Date: Thu, 3 Dec 2020 20:35:35 +0530 Subject: [PATCH 130/149] DeepIntent: PBS docs added (#2523) Co-authored-by: Sourabh Gandhe --- dev-docs/bidders/deepintent.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev-docs/bidders/deepintent.md b/dev-docs/bidders/deepintent.md index faad684365..161a520e44 100644 --- a/dev-docs/bidders/deepintent.md +++ b/dev-docs/bidders/deepintent.md @@ -3,6 +3,7 @@ layout: bidder title: Deepintent description: Prebid Deepintent Bidder Adaptor pbjs: true +pbs: true biddercode: deepintent media_types: banner gdpr_supported: true @@ -20,6 +21,8 @@ usp_supported: true | `user` | optional | user params according to IAB standards | `'{"gender":"F"}''`| `object` | | `pos` | optional | ad position as per IAB standards | `1` | `number` | + + ### Configuration Deepintent recommends the UserSync configuration below. Without it, the Deepintent adapter will not able to perform user syncs, which lowers match rate and reduces monetization. From 3950c4ca1209ea49181efa47dda66b047e0ee01a Mon Sep 17 00:00:00 2001 From: Denis Logachov Date: Thu, 3 Dec 2020 20:07:21 +0200 Subject: [PATCH 131/149] Update andbeyond adaptor documentation (#2538) --- dev-docs/bidders/andbeyond.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/dev-docs/bidders/andbeyond.md b/dev-docs/bidders/andbeyond.md index d32c64179d..66964793fc 100644 --- a/dev-docs/bidders/andbeyond.md +++ b/dev-docs/bidders/andbeyond.md @@ -1,9 +1,15 @@ --- layout: bidder -title: andbeyond -description: Prebid andbeyond Bidder Adaptor +title: Andbeyond Media +description: Andbeyond Media pbjs: true +pbs: true biddercode: andbeyond +media_types: banner, native, video +gdpr_supported: true +usp_supported: true +schain_supported: true +aliasCode : adkernel --- ### Note: @@ -15,5 +21,5 @@ The andbeyond Bidding adaptor requires setup and approval before beginning. Plea {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |----------|----------|-----------------------|---------------------------|----------| -| `host` | required | Ad network's RTB host | `'cpm.metaadserving.com'` | `string` | -| `zoneId` | required | RTB zone id | `'30164'` | `string` | +| `host` | required | Our Host | `'cpm.andbeyond.media'` | `string` | +| `zoneId` | required | Example RTB zone id | `'12345'` | `string` | From 34da73d91abfca2f37e50300ac86b580f5c0b330 Mon Sep 17 00:00:00 2001 From: mwehr-zeta <70167335+mwehr-zeta@users.noreply.github.com> Date: Thu, 3 Dec 2020 13:32:01 -0500 Subject: [PATCH 132/149] submit docs for the new Zeta Global bidder adapter (#2409) * submit docs for the new Zeta Global bidder adapter * remove flag for server adapter * update biddercode value to match adapter code * update to include additional required values * update to docs --- dev-docs/bidders/zetaGlobal.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 dev-docs/bidders/zetaGlobal.md diff --git a/dev-docs/bidders/zetaGlobal.md b/dev-docs/bidders/zetaGlobal.md new file mode 100644 index 0000000000..1191270a93 --- /dev/null +++ b/dev-docs/bidders/zetaGlobal.md @@ -0,0 +1,26 @@ +--- +layout: bidder +title: Zeta Global +description: Zeta Global Prebid Bidder Adapter +pbjs: true +biddercode: zeta_global +bidder_supports_deals: false +media_types: banner +gdpr_supported: true +tcf2_supported: true +gvl_id: 469 +--- + +### Registration + +To use this bidder you will need a valid definerId. For further information, please contact jzirbel@disqus.com. + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------------|----------|---------------------------------------------------------------------------------------------------------------------|-----------|-----------| +| `ip` | required | The client IP | `0.0.0.0` | `string` | +| `buyeruid` | required | Zeta's user id | `12345` | `string` | +| `definerId` | required | The Definer ID from Zeta Global | `12345` | `string` | +| `test` | optional | Flag which will induce a sample bid response when true; only set to true for testing purposes (1 = true, 0 = false) | `1` | `integer` | From f81c7d3da395e420ce8772711974e980ea61835a Mon Sep 17 00:00:00 2001 From: pnh-pubx <73683023+pnh-pubx@users.noreply.github.com> Date: Fri, 4 Dec 2020 00:06:37 +0530 Subject: [PATCH 133/149] Add PubXAi analytics adapter docs (#2470) Co-authored-by: Phaneendra Hegde --- download.md | 8 ++++++++ overview/analytics.md | 1 + 2 files changed, 9 insertions(+) diff --git a/download.md b/download.md index 1c5c134907..ef7802aa3c 100644 --- a/download.md +++ b/download.md @@ -371,6 +371,14 @@ Prebid.js is open source software that is offered for free as a convenience. Whi
+
+
+ +
+
+