diff --git a/.prettierignore b/.prettierignore
index 326da2e..46e39d6 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,4 +1,5 @@
.prettierrc
browser/dist
lib/dist
-demos/publishers
+demos/vanilla/nocookies/targeting/prebid*.js
+demos/vanilla/targeting/prebid*.js
diff --git a/Dockerfile b/Dockerfile
index 0bd80cd..631b25f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -54,6 +54,15 @@ COPY --from=build /build/demos/vanilla/identify.html ./vanilla/identify.html
COPY --from=build /build/demos/vanilla/profile.html ./vanilla/profile.html
COPY --from=build /build/demos/vanilla/witness.html ./vanilla/witness.html
COPY --from=build /build/demos/vanilla/authenticator.html ./vanilla/authenticator.html
+COPY --from=build /build/demos/vanilla/nocookies/targeting/gam360.html ./vanilla/nocookies/targeting/gam360.html
+COPY --from=build /build/demos/vanilla/nocookies/targeting/gam360-cached.html ./vanilla/nocookies/targeting/gam360-cached.html
+COPY --from=build /build/demos/vanilla/nocookies/targeting/prebid.html ./vanilla/nocookies/targeting/prebid.html
+COPY --from=build /build/demos/vanilla/nocookies/targeting/prebid-us-east-16.html ./vanilla/nocookies/targeting/prebid-us-east-16.html
+COPY --from=build /build/demos/vanilla/nocookies/targeting/prebid.js ./vanilla/nocookies/targeting/prebid.js
+COPY --from=build /build/demos/vanilla/nocookies/targeting/prebid-us-east-16.js ./vanilla/nocookies/targeting/prebid-us-east-16.js
+COPY --from=build /build/demos/vanilla/nocookies/identify.html ./vanilla/nocookies/identify.html
+COPY --from=build /build/demos/vanilla/nocookies/profile.html ./vanilla/nocookies/profile.html
+COPY --from=build /build/demos/vanilla/nocookies/witness.html ./vanilla/nocookies/witness.html
COPY --from=build /build/demos/react/dist/ ./react/dist/
COPY --from=build /build/demos/index.html ./index.html
COPY --from=build /build/demos/css/ ./css/
diff --git a/README.md b/README.md
index 113f67d..19cbe97 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@ JavaScript SDK for integrating with optable-sandbox from a web site or web appli
- [script tag](#script-tag)
- [Versioning](#versioning)
- [Domains and Cookies](#domains-and-cookies)
+ - [LocalStorage](#localstorage)
- [Using (npm module)](#using-npm-module)
- [Identify API](#identify-api)
- [Profile API](#profile-api)
@@ -74,6 +75,18 @@ For example, if your website runs at `www.customer.com` or `customer.com`, then
> :warning: **Optable Visitor ID Scope**: The _visitor ID_ configured by the Optable sandbox will be unique to a browser only within the top-level domain that the sandbox shares with the calling web site.
+### LocalStorage
+
+In cases where it is not practical or possible to configure your sandbox to run on the same effective top-level domain plus one (eTLD+1) as your website(s), then the default cookie-based transport that the SDK depends on will not work. Instead, a fallback cookie-less transport utilizing browser `LocalStorage` is recommended. To switch to the cookie-less transport, simply set the optional `cookies` parameter to `false` when creating your SDK instance. For example:
+
+```javascript
+import OptableSDK from "@optable/web-sdk";
+
+const sdk = new OptableSDK({ host: "sandbox.customer.com", site: "my-site", cookies: false });
+```
+
+Note that the default is `cookies: true` and will be inferred if you do not specify the `cookies` parameter at all.
+
## Using (npm module)
To configure an instance of `OptableSDK` integrating with an [Optable](https://optable.co/) sandbox running at hostname `sandbox.customer.com`, from a configured web site origin identified by slug `my-site`, you simply create an instance of the `OptableSDK` class exported by the `@optable/web-sdk` module:
diff --git a/demos/Makefile b/demos/Makefile
index 44a26cd..664dabb 100644
--- a/demos/Makefile
+++ b/demos/Makefile
@@ -12,7 +12,14 @@ html:
envsubst < ./vanilla/targeting/gam360-cached.html.tpl > ./vanilla/targeting/gam360-cached.html && \
envsubst < ./vanilla/targeting/prebid.html.tpl > ./vanilla/targeting/prebid.html && \
envsubst < ./vanilla/targeting/prebid-us-east-16.html.tpl > ./vanilla/targeting/prebid-us-east-16.html && \
- envsubst < ./vanilla/authenticator.html.tpl > ./vanilla/authenticator.html
+ envsubst < ./vanilla/authenticator.html.tpl > ./vanilla/authenticator.html && \
+ envsubst < ./vanilla/nocookies/identify.html.tpl > ./vanilla/nocookies/identify.html && \
+ envsubst < ./vanilla/nocookies/witness.html.tpl > ./vanilla/nocookies/witness.html && \
+ envsubst < ./vanilla/nocookies/profile.html.tpl > ./vanilla/nocookies/profile.html && \
+ envsubst < ./vanilla/nocookies/targeting/gam360.html.tpl > ./vanilla/nocookies/targeting/gam360.html && \
+ envsubst < ./vanilla/nocookies/targeting/gam360-cached.html.tpl > ./vanilla/nocookies/targeting/gam360-cached.html && \
+ envsubst < ./vanilla/nocookies/targeting/prebid.html.tpl > ./vanilla/nocookies/targeting/prebid.html && \
+ envsubst < ./vanilla/nocookies/targeting/prebid-us-east-16.html.tpl > ./vanilla/nocookies/targeting/prebid-us-east-16.html
.PHONY: react
react:
diff --git a/demos/index-nocookies.html b/demos/index-nocookies.html
new file mode 100644
index 0000000..1e73c4c
--- /dev/null
+++ b/demos/index-nocookies.html
@@ -0,0 +1,110 @@
+
+
+
+
+ Optable Web SDK Demos
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
👋 demo.optable.co (cookies=false)
+
+ To learn about optable-web-sdk integration on your web site or application, see the latest releases, or
+ report an issue, please check out the
+ web-sdk GitHub README. If you're looking for more
+ information on Optable itself, visit our company site.
+
+
+ In all examples below, the Optable demo environment is used. Data stored by the demo environment is
+ periodically deleted.
+
+
+ Note that the examples below initialize the OptableSDK with cookies=false, so all ID transport is done
+ using browser LocalStorage.
+ Generally, it is preferable to use secure first party HTTP-only cookies for transporting IDs from
+ OptableSDK. However, when the integrating website does not share the same top-level domain name with the
+ Optable Sandbox, then first party cookies are not reliable, and the LocalStorage method is suggested. To
+ enable it, simply initialize the OptableSDK object with the cookies option set to
+ false, and the SDK will do the rest.
+
+ Shows how to load and cache active cohorts in a visitor's browser. Separately, cached cohorts are
+ passed to Google Ad Manager (GAM) via the
+ Google Publisher Tag for
+ ad targeting.
+
Shows how to set visitor traits (e.g., age=45) and sync them to your sandbox.
+
+
+ // Set some traits on the current visitor:
+ optable.instance.profile({ gender: "F", age: 38, favColor: "blue" });
+
+ // Set some new traits and update some existing on the current visitor:
+ optable.instance.profile({ favColor: "green", firstName: "Mary", lastName: "Smith" });
+
+
Shows how to set visitor traits (e.g., age=45) and sync them to your sandbox.
+
+
+ // Set some traits on the current visitor:
+ optable.instance.profile({ gender: "F", age: 38, favColor: "blue" });
+
+ // Set some new traits and update some existing on the current visitor:
+ optable.instance.profile({ favColor: "green", firstName: "Mary", lastName: "Smith" });
+
+
+ Shows how to load and cache active cohorts in a visitor's browser. Separately, cached cohorts are passed to
+ Google Ad Manager (GAM) via the
+ Google Publisher Tag (GPT) for
+ ad targeting.
+
+
+ In this example, we use the targetingFromCache() API to retrieve any targeting data from
+ browser LocalStorage, in order to pass it to GPT via googletag.pubads().setTargeting(). We also
+ call the SDK targeting API which will fetch the latest targeting data from our sandbox and
+ cache it locally for later use. Since these two events happen asynchronously, it's possible that the
+ targeting data passed to GAM is slightly outdated. To ensure ad targeting accuracy, we recommend calling
+ targeting to update the local cache on every page load.
+
+
+ If you are comfortable with disabling initial load on GAM ads and always loading them explicitly with the
+ very latest targeting data, have a look at the
+ original targeting & GAM360 activation example instead.
+
+ Shows how to load and cache active cohorts in a visitor's browser. Separately, cached cohorts are passed to
+ Google Ad Manager (GAM) via the
+ Google Publisher Tag (GPT) for
+ ad targeting.
+
+
+ In this example, we use the targetingFromCache() API to retrieve any targeting data from
+ browser LocalStorage, in order to pass it to GPT via googletag.pubads().setTargeting(). We also
+ call the SDK targeting API which will fetch the latest targeting data from our sandbox and
+ cache it locally for later use. Since these two events happen asynchronously, it's possible that the
+ targeting data passed to GAM is slightly outdated. To ensure ad targeting accuracy, we recommend calling
+ targeting to update the local cache on every page load.
+
+
+ If you are comfortable with disabling initial load on GAM ads and always loading them explicitly with the
+ very latest targeting data, have a look at the
+ original targeting & GAM360 activation example instead.
+
+ Shows how to load active cohorts for a visitor and pass them to
+ Google Ad Manager (GAM) via the
+ Google Publisher Tag (GPT) for
+ ad targeting.
+
+
+ In this example, the call to the targeting API happens first and, on success or error, banner
+ ads are loaded from Optable's demo GAM account via googletag.pubads().refresh(). In order to
+ prevent ads loading until the asynchronous targeting call is done, we start by disabling
+ automatic ads loading with googletag.pubads().disableInitialLoad().
+
+
+ To see an alternate way of loading GAM ads with targeting data where disableInitialLoad() is
+ not required, check out the
+ cached targeting & GAM360 activation example
+ instead.
+
+ Shows how to load active cohorts for a visitor and pass them to
+ Google Ad Manager (GAM) via the
+ Google Publisher Tag (GPT) for
+ ad targeting.
+
+
+ In this example, the call to the targeting API happens first and, on success or error, banner
+ ads are loaded from Optable's demo GAM account via googletag.pubads().refresh(). In order to
+ prevent ads loading until the asynchronous targeting call is done, we start by disabling
+ automatic ads loading with googletag.pubads().disableInitialLoad().
+
+
+ To see an alternate way of loading GAM ads with targeting data where disableInitialLoad() is
+ not required, check out the
+ cached targeting & GAM360 activation example
+ instead.
+
+ Shows how to load active cohorts for a visitor and pass them to Prebid.js via
+ setConfig-fpd.
+ It's assumed in this example that your primary ad server is
+ Google Ad Manager (GAM) and that you are integrated with it
+ using the
+ Google Publisher Tag (GPT), so
+ we also pass matching active cohorts to GAM.
+
+
+ In this example, we use the targetingFromCache API to retrieve any targeting data from browser
+ LocalStorage, in order to pass it to both Prebid.js and GPT. We also call the SDK targeting API
+ which will fetch the latest targeting data from our sandbox and cache it locally for later use. Since these
+ two events happen asynchronously, it's possible that the targeting data passed to GAM is slightly outdated.
+ To ensure ad targeting accuracy, we recommend calling targeting to update the local cache on
+ every page load.
+
+ Shows how to load active cohorts for a visitor and pass them to Prebid.js via
+ setConfig-fpd.
+ It's assumed in this example that your primary ad server is
+ Google Ad Manager (GAM) and that you are integrated with it
+ using the
+ Google Publisher Tag (GPT), so
+ we also pass matching active cohorts to GAM.
+
+
+ In this example, we use the targetingFromCache API to retrieve any targeting data from browser
+ LocalStorage, in order to pass it to both Prebid.js and GPT. We also call the SDK targeting API
+ which will fetch the latest targeting data from our sandbox and cache it locally for later use. Since these
+ two events happen asynchronously, it's possible that the targeting data passed to GAM is slightly outdated.
+ To ensure ad targeting accuracy, we recommend calling targeting to update the local cache on
+ every page load.
+
+
+
+
+
+
+
diff --git a/demos/vanilla/nocookies/targeting/prebid-us-east-16.js b/demos/vanilla/nocookies/targeting/prebid-us-east-16.js
new file mode 100644
index 0000000..c8a6847
--- /dev/null
+++ b/demos/vanilla/nocookies/targeting/prebid-us-east-16.js
@@ -0,0 +1,5 @@
+/* prebid.js v4.18.0-pre
+Updated : 2020-11-26 */
+!function(u){var s=window.pbjsChunk;window.pbjsChunk=function(e,t,n){for(var r,i,o,a=0,c=[];a>t/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,e)},t.getBidIdParameter=function(e,t){if(t&&t[e])return t[e];return""},t.tryAppendQueryString=function(e,t,n){if(n)return e+t+"="+encodeURIComponent(n)+"&";return e},t.parseQueryStringParameters=function(e){var t="";for(var n in e)e.hasOwnProperty(n)&&(t+=n+"="+encodeURIComponent(e[n])+"&");return t=t.replace(/&$/,"")},t.transformAdServerTargetingObj=function(t){return t&&0';return n+=''},t.createTrackPixelIframeHtml=se,t.getValueString=de,t.uniques=fe,t.flatten=le,t.getBidRequest=function(n,e){return n?(e.some(function(e){var t=c()(e.bids,function(t){return["bidId","adId","bid_id"].some(function(e){return t[e]===n})});return t&&(r=t),t}),r):void 0;var r},t.getKeys=pe,t.getValue=ge,t.getKeyByValue=function(e,t){for(var n in e)if(e.hasOwnProperty(n)&&e[n]===t)return n},t.getBidderCodes=function(){return(0t[n]?-1:0}},t.parseQS=Ie,t.formatQS=Ce,t.parseUrl=function(e,t){var n=document.createElement("a");t&&"noDecodeWholeURL"in t&&t.noDecodeWholeURL?n.href=e:n.href=decodeURIComponent(e);var r=t&&"decodeSearchAsString"in t&&t.decodeSearchAsString;return{href:n.href,protocol:(n.protocol||"").replace(/:$/,""),hostname:n.hostname,port:+n.port,pathname:n.pathname.replace(/^(?!\/)/,"/"),search:r?n.search:k.parseQS(n.search||""),hash:(n.hash||"").replace(/^#/,""),host:n.host||window.location.host}},t.buildUrl=function(e){return(e.protocol||"http")+"://"+(e.host||e.hostname+(e.port?":".concat(e.port):""))+(e.pathname||"")+(e.search?"?".concat(k.formatQS(e.search||"")):"")+(e.hash?"#".concat(e.hash):"")},t.deepEqual=je,t.mergeDeep=we,t.cyrb53Hash=function(e){for(var t,n=1>>16,2246822507)^r(o^o>>>13,3266489909),(4294967296*(2097151&(o=r(o^o>>>16,2246822507)^r(i^i>>>13,3266489909)))+(i>>>0)).toString()};var r=n(3),i=n(159),o=n.n(i),a=n(10),c=n.n(a),u=n(12),s=n.n(u),d=n(160);n.d(t,"deepAccess",function(){return d.a});var f=n(161);function l(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var n=[],r=!0,i=!1,o=void 0;try{for(var a,c=e[Symbol.iterator]();!(r=(a=c.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){i=!0,o=e}finally{try{r||null==c.return||c.return()}finally{if(i)throw o}}return n}(e,t)||g(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(e){return function(e){if(Array.isArray(e))return b(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||g(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function g(e,t){if(e){if("string"==typeof e)return b(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?b(e,t):void 0}}function b(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n\n ')):""}function de(e,t,n){return null==t?n:Z(t)?t:te(t)?t.toString():void k.logWarn("Unsuported type for param: "+e+" required type: String")}function fe(e,t,n){return n.indexOf(e)===t}function le(e,t){return e.concat(t)}function pe(e){return Object.keys(e)}function ge(e,t){return e[t]}function be(){if(window.googletag&&X(window.googletag.pubads)&&X(window.googletag.pubads().getSlots))return!0}var ve=me("timeToRespond",function(e,t){return te.length)&&(t=e.length);for(var n=0,r=new Array(t);no.lastUpdated+24*r*60*60*1e3)&&Object(p.a)(t.url,{success:function(e){try{e=JSON.parse(e);var t={lastUpdated:Object(m.timestamp)(),mapping:e.mapping};I.setDataInLocalStorage(i,JSON.stringify(t))}catch(e){Object(m.logError)("Failed to parse ".concat(n," bidder translation mapping file"))}},error:function(){Object(m.logError)("Failed to load ".concat(n," bidder translation file"))}})}catch(e){Object(m.logError)("Failed to parse ".concat(n," bidder translation mapping file"))}}}),e.call(this,t)}function U(e,t,n){function r(e){return"Invalid bid from ".concat(t.bidderCode,". Ignoring bid: ").concat(e)}return e?t?(i=Object.keys(t),C.every(function(e){return l()(i,e)&&!l()([void 0,null],t[e])})?"native"!==t.mediaType||Object(o.f)(t,n)?"video"!==t.mediaType||Object(a.d)(t,n)?!("banner"===t.mediaType&&!function(e,t,n){if((t.width||0===parseInt(t.width,10))&&(t.height||0===parseInt(t.height,10)))return t.width=parseInt(t.width,10),t.height=parseInt(t.height,10),1;var r=Object(m.getBidderRequest)(n,t.bidderCode,e),i=r&&r.bids&&r.bids[0]&&r.bids[0].sizes,o=Object(m.parseSizesInput)(i);if(1===o.length){var a=A(o[0].split("x"),2),c=a[0],u=a[1];return t.width=parseInt(c,10),t.height=parseInt(u,10),1}}(e,t,n))||(Object(m.logError)(r("Banner bids require a width and height")),!1):(Object(m.logError)(r("Video bid does not have required vastUrl or renderer property")),!1):(Object(m.logError)(r("Native bid missing some required properties.")),!1):(Object(m.logError)(r("Bidder ".concat(t.bidderCode," is missing required params. Check http://prebid.org/dev-docs/bidder-adapter-1.html for list of params."))),!1)):(Object(m.logWarn)("Some adapter tried to add an undefined bid for ".concat(e,".")),!1):(Object(m.logWarn)("No adUnitCode was supplied to addBidResponse."),!1);var i}Object(b.a)("checkAdUnitSetup").before(B)},10:function(e,t,n){var r=n(97);e.exports=r},100:function(e,t,n){"use strict";var r={}.propertyIsEnumerable,i=Object.getOwnPropertyDescriptor,o=i&&!r.call({1:2},1);t.f=o?function(e){var t=i(this,e);return!!t&&t.enumerable}:r},101:function(e,t,n){function r(e,t){var n=c[a(e)];return n==s||n!=u&&("function"==typeof t?i(t):!!t)}var i=n(31),o=/#|\.prototype\./,a=r.normalize=function(e){return String(e).replace(o,".").toLowerCase()},c=r.data={},u=r.NATIVE="N",s=r.POLYFILL="P";e.exports=r},102:function(e,t,n){var r=n(26),i=n(103),o=n(20)("species");e.exports=function(e,t){var n;return i(e)&&("function"==typeof(n=e.constructor)&&(n===Array||i(n.prototype))||r(n)&&null===(n=n[o]))&&(n=void 0),new(void 0===n?Array:n)(0===t?0:t)}},103:function(e,t,n){var r=n(48);e.exports=Array.isArray||function(e){return"Array"==r(e)}},104:function(e,t,n){var r=n(25),i=n(32);e.exports=function(t,n){try{i(r,t,n)}catch(e){r[t]=n}return n}},105:function(e,t,n){var r=n(76);e.exports=r&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},106:function(e,t,n){n(107);var r=n(52);e.exports=r("Array","includes")},107:function(e,t,n){"use strict";var r=n(14),i=n(77).includes,o=n(51);r({target:"Array",proto:!0,forced:!n(60)("indexOf",{ACCESSORS:!0,1:0})},{includes:function(e,t){return i(this,e,1i;)a(r,n=t[i++])&&(~u(o,n)||o.push(n));return o}},12:function(e,t,n){var r=n(106);e.exports=r},120:function(e,t,n){var r=n(28);e.exports=r("document","documentElement")},121:function(e,t,n){var i=n(85);e.exports=function(e,t,n){for(var r in t)n&&n.unsafe&&e[r]?e[r]=t[r]:i(e,r,t[r],n);return e}},122:function(e,t,n){"use strict";function i(){return this}var o=n(86).IteratorPrototype,a=n(83),c=n(46),u=n(64),s=n(38);e.exports=function(e,t,n){var r=t+" Iterator";return e.prototype=a(o,{next:c(1,n)}),u(e,r,!1,!0),s[r]=i,e}},123:function(e,t,n){var r=n(31);e.exports=!r(function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype})},124:function(e,t,n){var i=n(15),o=n(125);e.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var n,r=!1,e={};try{(n=Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set).call(e,[]),r=e instanceof Array}catch(e){}return function(e,t){return i(e),o(t),r?n.call(e,t):e.__proto__=t,e}}():void 0)},125:function(e,t,n){var r=n(26);e.exports=function(e){if(!r(e)&&null!==e)throw TypeError("Can't set "+String(e)+" as a prototype");return e}},126:function(e,t,n){"use strict";var r=n(28),i=n(33),o=n(20),a=n(30),c=o("species");e.exports=function(e){var t=r(e),n=i.f;a&&t&&!t[c]&&n(t,c,{configurable:!0,get:function(){return this}})}},127:function(e,t){},128:function(e,t,n){function r(c){return function(e,t){var n,r,i=String(s(e)),o=u(t),a=i.length;return o<0||a<=o?c?"":void 0:(n=i.charCodeAt(o))<55296||56319e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=t.length?{value:e.target=void 0,done:!0}:"keys"==n?{value:r,done:!1}:"values"==n?{value:t[r],done:!1}:{value:[r,t[r]],done:!1}},"values"),o.Arguments=o.Array,i("keys"),i("values"),i("entries")},131:function(e,t){e.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},132:function(e,t,n){n(14)({target:"Set",stat:!0},{from:n(133)})},133:function(e,t,n){"use strict";var s=n(18),d=n(23),f=n(17);e.exports=function(e,t,n){var r,i,o,a,c=arguments.length,u=1>>0,o=0;if(t)n=t;else{for(;oi&&(r=!1)),!r}),r&&e.run(),r}function g(e,t){void 0===e[t]?e[t]=1:e[t]++}p(e)||(P.logWarn("queueing auction due to limited endpoint capacity"),K.push(e))}return{addBidReceived:function(e){f=f.concat(e)},addNoBid:function(e){l=l.concat(e)},executeCallback:O,callBids:function(){b=W,t=Date.now();var e=q.makeBidRequests(y,t,p,m,s);P.logInfo("Bids Requested for Auction with id: ".concat(p),e),e.length<1?(P.logWarn("No valid bid requests returned for auction"),T()):Y.call({dispatch:C,context:this},e)},addWinningBid:function(e){S=S.concat(e),q.callBidWonBidder(e.bidder,e,o)},setBidTargeting:function(e){q.callSetTargetingBidder(e.bidder,e)},getWinningBids:function(){return S},getTimeout:function(){return m},getAuctionId:function(){return p},getAuctionStatus:function(){return b},getAdUnits:function(){return y},getAdUnitCodes:function(){return d},getBidRequests:function(){return h},getBidsReceived:function(){return f},getNoBids:function(){return l}}},n.d(t,"c",function(){return J}),n.d(t,"e",function(){return Y}),t.g=d,t.d=$,n.d(t,"f",function(){return X}),n.d(t,"i",function(){return f}),n.d(t,"h",function(){return l}),t.j=p;var j=n(0),w=n(45),a=n(37),o=n(94),_=n(11),B=n(3),r=n(43),i=n(13),c=n(10),U=n.n(c),u=n(12),x=n.n(u),R=n(29),s=n(2);function k(e){return(k="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function D(){return(D=Object.assign||function(e){for(var t=1;te.getTimeout()+B.b.getConfig("timeoutBuffer")&&e.executeCallback(!0)}function $(e,t){var n=e.getBidRequests(),r=U()(n,function(e){return e.bidderCode===t.bidderCode});!function(t,e){var n;{var r;t.bidderCode&&(0e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=h.syncsPerBidder?a.logWarn('Number of user syncs exceeded for "'.concat(t,'"')):p.canBidderRegisterSync(e,t)?(g[e].push([t,n]),(r=v)[i=t]?r[i]+=1:r[i]=1,void(v=r)):a.logWarn('Bidder "'.concat(t,'" not permitted to register their "').concat(e,'" userSync pixels.')):a.logWarn("Bidder is required for registering sync"):a.logWarn('User sync type "'.concat(e,'" not supported'));var r,i},p.syncUsers=function(){var e=0e.length)&&(t=e.length);for(var n=0,r=new Array(t);nObject(S.timestamp)()},s=function(e){return e&&(e.status&&!O()([w.BID_STATUS.RENDERED],e.status)||!e.status)};function U(e,r,t){var i=2t.max?e:t},{max:0}),g=0,b=v()(e.buckets,function(e){if(n>p.max*r){var t=e.precision;void 0===t&&(t=y),i=(e.max*r).toFixed(t)}else{if(n<=e.max*r&&g*r<=n)return e.min=g,e;g=e.max}});return b&&(t=n,a=r,c=void 0!==(o=b).precision?o.precision:y,u=o.increment*a,s=o.min*a,d=Math.pow(10,c+2),f=(t*d-s*d)/(u*d),l=Math.floor(f)*u+s,i=(l=Number(l.toFixed(10))).toFixed(c)),i}function h(e){if(i.isEmpty(e)||!e.buckets||!Array.isArray(e.buckets))return!1;var t=!0;return e.buckets.forEach(function(e){e.max&&e.increment||(t=!1)}),t}},46:function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},47:function(e,t,n){var r=n(71),i=n(49);e.exports=function(e){return r(i(e))}},48:function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},49:function(e,t){e.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},5:function(e,t){e.exports={JSON_MAPPING:{PL_CODE:"code",PL_SIZE:"sizes",PL_BIDS:"bids",BD_BIDDER:"bidder",BD_ID:"paramsd",BD_PL_ID:"placementId",ADSERVER_TARGETING:"adserverTargeting",BD_SETTING_STANDARD:"standard"},DEBUG_MODE:"pbjs_debug",STATUS:{GOOD:1,NO_BID:2},CB:{TYPE:{ALL_BIDS_BACK:"allRequestedBidsBack",AD_UNIT_BIDS_BACK:"adUnitBidsBack",BID_WON:"bidWon",REQUEST_BIDS:"requestBids"}},EVENTS:{AUCTION_INIT:"auctionInit",AUCTION_END:"auctionEnd",BID_ADJUSTMENT:"bidAdjustment",BID_TIMEOUT:"bidTimeout",BID_REQUESTED:"bidRequested",BID_RESPONSE:"bidResponse",NO_BID:"noBid",BID_WON:"bidWon",BIDDER_DONE:"bidderDone",SET_TARGETING:"setTargeting",BEFORE_REQUEST_BIDS:"beforeRequestBids",REQUEST_BIDS:"requestBids",ADD_AD_UNITS:"addAdUnits",AD_RENDER_FAILED:"adRenderFailed",TCF2_ENFORCEMENT:"tcf2Enforcement",AUCTION_DEBUG:"auctionDebug"},AD_RENDER_FAILED_REASON:{PREVENT_WRITING_ON_MAIN_DOCUMENT:"preventWritingOnMainDocuemnt",NO_AD:"noAd",EXCEPTION:"exception",CANNOT_FIND_AD:"cannotFindAd",MISSING_DOC_OR_ADID:"missingDocOrAdid"},EVENT_ID_PATHS:{bidWon:"adUnitCode"},GRANULARITY_OPTIONS:{LOW:"low",MEDIUM:"medium",HIGH:"high",AUTO:"auto",DENSE:"dense",CUSTOM:"custom"},TARGETING_KEYS:{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"},NATIVE_KEYS:{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"},S2S:{SRC:"s2s",DEFAULT_ENDPOINT:"https://prebid.adnxs.com/pbs/v1/openrtb2/auction",SYNCED_BIDDERS_KEY:"pbjsSyncs"},BID_STATUS:{BID_TARGETING_SET:"targetingSet",RENDERED:"rendered",BID_REJECTED:"bidRejected"}}},50:function(e,t,n){var r=n(58),i=Math.min;e.exports=function(e){return 0"+e+""+g+">"}var o,a=n(15),c=n(117),u=n(84),s=n(53),d=n(120),f=n(73),l=n(65),p="prototype",g="script",b=l("IE_PROTO"),v=function(){try{o=document.domain&&new ActiveXObject("htmlfile")}catch(e){}var e,t;v=o?function(e){e.write(i("")),e.close();var t=e.parentWindow.Object;return e=null,t}(o):((t=f("iframe")).style.display="none",d.appendChild(t),t.src=String("javascript:"),(e=t.contentWindow.document).open(),e.write(i("document.F=Object")),e.close(),e.F);for(var n=u.length;n--;)delete v[p][u[n]];return v()};s[b]=!0,e.exports=Object.create||function(e,t){var n;return null!==e?(r[p]=a(e),n=new r,r[p]=null,n[b]=e):n=v(),void 0===t?n:c(n,t)}},84:function(e,t){e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},85:function(e,t,n){var i=n(32);e.exports=function(e,t,n,r){r&&r.enumerable?e[t]=n:i(e,t,n)}},86:function(e,t,n){"use strict";var r,i,o,a=n(87),c=n(32),u=n(27),s=n(20),d=n(16),f=s("iterator"),l=!1;[].keys&&("next"in(o=[].keys())?(i=a(a(o)))!==Object.prototype&&(r=i):l=!0),null==r&&(r={}),d||u(r,f)||c(r,f,function(){return this}),e.exports={IteratorPrototype:r,BUGGY_SAFARI_ITERATORS:l}},87:function(e,t,n){var r=n(27),i=n(57),o=n(65),a=n(123),c=o("IE_PROTO"),u=Object.prototype;e.exports=a?Object.getPrototypeOf:function(e){return e=i(e),r(e,c)?e[c]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?u:null}},88:function(e,t,n){"use strict";var i=n(128).charAt,r=n(54),o=n(66),a="String Iterator",c=r.set,u=r.getterFor(a);o(String,"String",function(e){c(this,{type:a,string:String(e),index:0})},function(){var e,t=u(this),n=t.string,r=t.index;return r>=n.length?{value:void 0,done:!0}:(e=i(n,r),t.index+=e.length,{value:e,done:!1})})},89:function(e,t,n){var r=n(15),i=n(61);e.exports=function(e){var t=i(e);if("function"!=typeof t)throw TypeError(String(e)+" is not iterable");return r(t.call(e))}},9:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n.d(t,"gdprDataHandler",function(){return R}),n.d(t,"uspDataHandler",function(){return k}),t.setS2STestingModule=function(e){I=e};var S=n(0),p=n(92),g=n(37),l=n(1),h=n(4),A=n(3),r=n(13),i=n(12),E=n.n(i),o=n(10),O=n.n(o),b=n(67),T=n(21);function m(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var n=[],r=!0,i=!1,o=void 0;try{for(var a,c=e[Symbol.iterator]();!(r=(a=c.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){i=!0,o=e}finally{try{r||null==c.return||c.return()}finally{if(i)throw o}}return n}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return a(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n"):"",'\n \n \n prebid.org wrapper\n \n ").concat(r,"\n \n \n \n ")),ttlseconds:Number(e.ttl)};return o.b.getConfig("cache.vasttrack")&&(i.bidder=e.bidder,i.bidid=e.requestId,a.isPlainObject(this)&&this.hasOwnProperty("auctionStart")&&(i.timestamp=this.auctionStart)),"string"==typeof e.customCacheKey&&""!==e.customCacheKey&&(i.key=e.customCacheKey),i}},97:function(e,t,n){n(98);var r=n(52);e.exports=r("Array","find")},98:function(e,t,n){"use strict";var r=n(14),i=n(56).find,o=n(51),a=n(60),c="find",u=!0,s=a(c);c in[]&&Array(1).find(function(){u=!1}),r({target:"Array",proto:!0,forced:u||!s},{find:function(e,t){return i(this,e,1e.length)&&(r=e.length);for(var t=0,n=new Array(r);t]*?src\s*=\s*['\"]([^'\"]*?)['\"][^>]*?>/,i=c(r.match(n),2),o=i[0],s=i[1];return r=r.replace(n,""),o&&s&&(e=""),r=r.replace("","".concat(e))),r}catch(e){if(!t)return r;var a="");return r=r.replace("","".concat(a))}}Object(n.registerBidder)(h)}},[396]);
+pbjs.processQueue();
diff --git a/demos/vanilla/nocookies/targeting/prebid.html b/demos/vanilla/nocookies/targeting/prebid.html
new file mode 100644
index 0000000..54e3721
--- /dev/null
+++ b/demos/vanilla/nocookies/targeting/prebid.html
@@ -0,0 +1,304 @@
+
+
+
+
+ Optable Web SDK Demos
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Example: targeting & Prebid.js activation
+
+ Shows how to load active cohorts for a visitor and pass them to Prebid.js via
+ setConfig-fpd.
+ It's assumed in this example that your primary ad server is
+ Google Ad Manager (GAM) and that you are integrated with it
+ using the
+ Google Publisher Tag (GPT), so
+ we also pass matching active cohorts to GAM.
+
+
+ In this example, we use the targetingFromCache API to retrieve any targeting data from browser
+ LocalStorage, in order to pass it to both Prebid.js and GPT. We also call the SDK targeting API
+ which will fetch the latest targeting data from our sandbox and cache it locally for later use. Since these
+ two events happen asynchronously, it's possible that the targeting data passed to GAM is slightly outdated.
+ To ensure ad targeting accuracy, we recommend calling targeting to update the local cache on
+ every page load.
+
+ Shows how to load active cohorts for a visitor and pass them to Prebid.js via
+ setConfig-fpd.
+ It's assumed in this example that your primary ad server is
+ Google Ad Manager (GAM) and that you are integrated with it
+ using the
+ Google Publisher Tag (GPT), so
+ we also pass matching active cohorts to GAM.
+
+
+ In this example, we use the targetingFromCache API to retrieve any targeting data from browser
+ LocalStorage, in order to pass it to both Prebid.js and GPT. We also call the SDK targeting API
+ which will fetch the latest targeting data from our sandbox and cache it locally for later use. Since these
+ two events happen asynchronously, it's possible that the targeting data passed to GAM is slightly outdated.
+ To ensure ad targeting accuracy, we recommend calling targeting to update the local cache on
+ every page load.
+