{"action":"created","comment":{"url":"https://api.github.com/repos/Marfeel/amphtml/pulls/comments/207245997","pull_request_review_id":142818058,"id":207245997,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwNzI0NTk5Nw==","diff_hunk":"@@ -0,0 +1,1701 @@\n+/**\n+ * Copyright 2016 The AMP HTML Authors. All Rights Reserved.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *      http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS-IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+// Because AdSense and DoubleClick are both operated by Google and their A4A\n+// implementations share some behavior in common, part of the logic for this\n+// implementation is located in the ads/google/a4a directory rather than here.\n+// Most other ad networks will want to put their A4A code entirely in the\n+// extensions/amp-ad-network-${NETWORK_NAME}-impl directory.\n+\n+import '../../amp-a4a/0.1/real-time-config-manager';\n+import {\n+  AmpA4A,\n+  DEFAULT_SAFEFRAME_VERSION,\n+  RENDERING_TYPE_HEADER,\n+  XORIGIN_MODE,\n+  assignAdUrlToError,\n+} from '../../amp-a4a/0.1/amp-a4a';\n+import {\n+  AmpAnalyticsConfigDef,\n+  QQID_HEADER,\n+  ValidAdContainerTypes,\n+  addCsiSignalsToAmpAnalyticsConfig,\n+  extractAmpAnalyticsConfig,\n+  getCsiAmpAnalyticsConfig,\n+  getCsiAmpAnalyticsVariables,\n+  getEnclosingContainerTypes,\n+  getIdentityToken,\n+  googleAdUrl,\n+  googleBlockParameters,\n+  googlePageParameters,\n+  groupAmpAdsByType,\n+  isCdnProxy,\n+  isReportingEnabled,\n+  maybeAppendErrorParameter,\n+  truncAndTimeUrl,\n+} from '../../../ads/google/a4a/utils';\n+import {CONSENT_POLICY_STATE} from '../../../src/consent-state';\n+import {Deferred} from '../../../src/utils/promise';\n+import {Layout, isLayoutSizeDefined} from '../../../src/layout';\n+import {Navigation} from '../../../src/service/navigation';\n+import {RTC_VENDORS} from '../../amp-a4a/0.1/callout-vendors';\n+import {\n+  RefreshManager, // eslint-disable-line no-unused-vars\n+  getRefreshManager,\n+} from '../../amp-a4a/0.1/refresh-manager';\n+import {SafeframeHostApi} from './safeframe-host';\n+import {Services} from '../../../src/services';\n+import {createElementWithAttributes, removeElement} from '../../../src/dom';\n+import {deepMerge, dict} from '../../../src/utils/object';\n+import {dev, user} from '../../../src/log';\n+import {domFingerprintPlain} from '../../../src/utils/dom-fingerprint';\n+import {\n+  extractUrlExperimentId,\n+} from '../../../ads/google/a4a/traffic-experiments';\n+import {getMode} from '../../../src/mode';\n+import {getMultiSizeDimensions} from '../../../ads/google/utils';\n+import {getOrCreateAdCid} from '../../../src/ad-cid';\n+import {\n+  googleLifecycleReporterFactory,\n+  setGoogleLifecycleVarsFromHeaders,\n+} from '../../../ads/google/a4a/google-data-reporter';\n+import {\n+  incrementLoadingAds,\n+  is3pThrottled,\n+  waitFor3pThrottle,\n+} from '../../amp-ad/0.1/concurrent-load';\n+import {insertAnalyticsElement} from '../../../src/extension-analytics';\n+import {isCancellation} from '../../../src/error';\n+import {\n+  isInManualExperiment,\n+} from '../../../ads/google/a4a/traffic-experiments';\n+import {isObject} from '../../../src/types';\n+import {isSecureUrlDeprecated, parseQueryString} from '../../../src/url';\n+import {\n+  lineDelimitedStreamer,\n+  metaJsonCreativeGrouper,\n+} from '../../../ads/google/a4a/line-delimited-response-handler';\n+import {setStyles} from '../../../src/style';\n+import {stringHash32} from '../../../src/string';\n+import {tryParseJson} from '../../../src/json';\n+import {tryResolve} from '../../../src/utils/promise';\n+import {utf8Encode} from '../../../src/utils/bytes';\n+\n+/** @type {string} */\n+const TAG = 'amp-ad-network-matrioshka-impl';\n+\n+/** @const {string} */\n+const DOUBLECLICK_BASE_URL =\n+    'https://securepubads.g.doubleclick.net/gampad/ads';\n+\n+/** @const {string} */\n+const RTC_SUCCESS = '2';\n+\n+/** @const @enum{string} */\n+const DOUBLECLICK_EXPERIMENT_FEATURE = {\n+  DELAYED_REQUEST_CONTROL: '21060728',\n+  DELAYED_REQUEST: '21060729',\n+  SRA_CONTROL: '117152666',\n+  SRA: '117152667',\n+};\n+\n+/**\n+ * @const {string}\n+ * @visibleForTesting\n+ */\n+export const TFCD = 'tagForChildDirectedTreatment';\n+\n+/** @private {?Promise} */\n+let sraRequests = null;\n+\n+/** @typedef {{\n+      adUrl: !Promise<string>,\n+      lineItemId: string,\n+      creativeId: string,\n+      slotId: string,\n+      slotIndex: string,\n+    }} */\n+let TroubleshootDataDef;\n+\n+/** @private {?JsonObject} */\n+let windowLocationQueryParameters;\n+\n+\n+/**\n+ * @typedef\n+ * {({width: number, height: number}|../../../src/layout-rect.LayoutRectDef)}\n+ */\n+let LayoutRectOrDimsDef;\n+\n+/* eslint-disable jsdoc/require-param */\n+/**\n+ * Array of functions used to combine block level request parameters for SRA\n+ * request.\n+ * @private @const {!Array<!function(!Array<AmpAdNetworkMatrioshkaImpl>):?Object<string,string>>}\n+ */\n+const BLOCK_SRA_COMBINERS_ = [\n+  instances => {\n+    const uniqueIuNames = {};\n+    let uniqueIuNamesCount = 0;\n+    const prevIusEncoded = [];\n+    instances.forEach(instance => {\n+      const iu = dev().assert(instance.element.getAttribute('data-slot'));\n+      const componentNames = (iu || '').split('/');\n+      const encodedNames = [];\n+      for (let i = 0; i < componentNames.length; i++) {\n+        if (componentNames[i] == '') {\n+          continue;\n+        }\n+        let index = uniqueIuNames[componentNames[i]];\n+        if (index == undefined) {\n+          uniqueIuNames[componentNames[i]] = (index = uniqueIuNamesCount++);\n+        }\n+        encodedNames.push(index);\n+      }\n+      prevIusEncoded.push(encodedNames.join('/'));\n+    });\n+    return {\n+      'iu_parts': Object.keys(uniqueIuNames).join(),\n+      'enc_prev_ius': prevIusEncoded.join(),\n+    };\n+  },\n+  // Although declared at a block-level, this is actually page level so\n+  // return true if ANY indicate cookie opt out.\n+  instances => getFirstInstanceValue_(instances, instance => {\n+    return instance.jsonTargeting_ &&\n+        instance.jsonTargeting_['cookieOptOut'] ? {'co': '1'} : null;\n+  }),\n+  instances => {\n+    return {'adks': instances.map(instance => instance.adKey_).join()};\n+  },\n+  instances => {\n+    return {'prev_iu_szs': instances.map(instance =>\n+      instance.parameterSize_).join()};\n+  },\n+  // Although declared at a block-level, this is actually page level so\n+  // return true if ANY indicate TFCD.\n+  instances => getFirstInstanceValue_(instances, instance => {\n+    return instance.jsonTargeting_ && instance.jsonTargeting_[TFCD] ?\n+      {'tfcd': instance.jsonTargeting_[TFCD]} : null;\n+  }),\n+  // Although declared at a block-level, this is actually page level so\n+  // return true if ANY indicate manual experiment.\n+  instances => getFirstInstanceValue_(instances, instance => {\n+    return isInManualExperiment(instance.element) ? {'adtest': 'on'} : null;\n+  }),\n+  instances => {\n+    const scps = [];\n+    instances.forEach(instance => {\n+      if (!instance.jsonTargeting_) {\n+        return;\n+      }\n+      scps.push(serializeTargeting_(\n+          instance.jsonTargeting_['targeting'] || null,\n+          instance.jsonTargeting_['categoryExclusions'] || null));\n+    });\n+    return scps.length ? {'prev_scp': scps.join('|')} : null;\n+  },\n+  instances => {\n+    const eids = {};\n+    instances.forEach(instance => {\n+      instance.experimentIds.forEach(eid => eids[eid] = 1);\n+      const deid = /(?:#|,)deid=(\\d+)/i.exec(instance.win.location.hash);\n+      if (deid) {\n+        eids[deid[1]] = 1;\n+      }\n+    });\n+    return Object.keys(eids).length ? {'eid': Object.keys(eids).join()} : null;\n+  },\n+  instances => getFirstInstanceValue_(instances,\n+      instance => instance.buildIdentityParams_()),\n+  instances => {\n+    let safeframeForced = false;\n+    const forceSafeframes = [];\n+    instances.forEach(instance => {\n+      safeframeForced = safeframeForced || instance.forceSafeframe_;\n+      forceSafeframes.push(Number(instance.forceSafeframe_));\n+    });\n+    return safeframeForced ? {'fsfs': forceSafeframes.join(',')} : null;\n+  },\n+  instances => ({'adxs':\n+    instances.map(instance => instance.getPageLayoutBox().left).join()}),\n+  instances => ({'adys':\n+    instances.map(instance => instance.getPageLayoutBox().top).join()}),\n+  instances => {\n+    let hasAmpContainer = false;\n+    const result = [];\n+    instances.forEach(instance => {\n+      const containers = getEnclosingContainerTypes(instance.element);\n+      result.push(containers.join());\n+      hasAmpContainer = hasAmpContainer || !!containers.length;\n+    });\n+    return hasAmpContainer ? {'acts': result.join('|')} : null;\n+  },\n+];\n+/* eslint-enable jsdoc/require-param */\n+\n+/** @final */\n+export class AmpAdNetworkMatrioshkaImpl extends AmpA4A {\n+\n+  /**\n+   * @param {!Element} element\n+   */\n+  constructor(element) {\n+    super(element);\n+\n+    /**\n+     * @type\n+     * {!../../../ads/google/a4a/performance.GoogleAdLifecycleReporter}\n+     */\n+    this.lifecycleReporter_ = this.lifecycleReporter_ ||\n+        this.initLifecycleReporter();\n+\n+    /**\n+     * Config to generate amp-analytics element for active view reporting.\n+     * @type {?JsonObject}\n+     * @private\n+     */\n+    this.ampAnalyticsConfig_ = null;\n+\n+    /** @private {!../../../src/service/extensions-impl.Extensions} */\n+    this.extensions_ = Services.extensionsFor(this.win);\n+\n+    /** @private {?string} */\n+    this.qqid_ = null;\n+\n+    /** @private {?LayoutRectOrDimsDef} */\n+    this.initialSize_ = null;\n+\n+    /** @private {?string} */\n+    this.parameterSize_ = null;\n+\n+    /** @private {?{width: number, height: number}} */\n+    this.returnedSize_ = null;\n+\n+    /** @private {?Element} */\n+    this.ampAnalyticsElement_ = null;\n+\n+    /** @private {?Object<string,*>}*/\n+    this.jsonTargeting_ = null;\n+\n+    /** @private {number} */\n+    this.adKey_ = 0;\n+\n+    /** @protected {!Array<string>} */\n+    this.experimentIds = [];\n+\n+    /** @protected {boolean} */\n+    this.useSra = false;\n+\n+    /** @protected {!Deferred<?../../../src/service/xhr-impl.FetchResponse>} */\n+    this.sraDeferred = new Deferred();\n+\n+    /** @private {?RefreshManager} */\n+    this.refreshManager_ = null;\n+\n+    /** @private {number} */\n+    this.refreshCount_ = 0;\n+\n+    /** @private {number} */\n+    this.ifi_ = 0;\n+\n+    /** @private {boolean} */\n+    this.isFluidRequest_ = false;\n+\n+    /** @private {?string} */\n+    this.fluidImpressionUrl_ = null;\n+\n+    /** @private {?Promise<!../../../ads/google/a4a/utils.IdentityToken>} */\n+    this.identityTokenPromise_ = null;\n+\n+    /** @type {?../../../ads/google/a4a/utils.IdentityToken} */\n+    this.identityToken = null;\n+\n+    /** @private {!TroubleshootDataDef} */\n+    this.troubleshootData_ = /** @type {!TroubleshootDataDef} */ ({});\n+\n+    /**\n+     * @private {?boolean} whether preferential rendered AMP creative, null\n+     * indicates no creative render.\n+     */\n+    this.isAmpCreative_ = null;\n+\n+    /** @private {boolean} */\n+    this.isIdleRender_ = false;\n+\n+    /** @private {?./safeframe-host.SafeframeHostApi} */\n+    this.safeframeApi_ = null;\n+\n+    /** @private {boolean} whether safeframe forced via tag */\n+    this.forceSafeframe_ = false;\n+    if ('forceSafeframe' in this.element.dataset) {\n+      if (!/^(1|(true))$/i.test(this.element.dataset['forceSafeframe'])) {\n+        user().warn(TAG, 'Ignoring invalid data-force-safeframe attribute: ' +\n+            this.element.dataset['forceSafeframe']);\n+      } else {\n+        this.forceSafeframe_ = true;\n+      }\n+    }\n+\n+    /** @protected {?CONSENT_POLICY_STATE} */\n+    this.consentState = null;\n+  }\n+\n+  /** @override */\n+  idleRenderOutsideViewport() {\n+    // Disable if publisher has indicated a non-default loading strategy.\n+    if (this.element.getAttribute('data-loading-strategy')) {\n+      return false;\n+    }\n+    const expVal = this.postAdResponseExperimentFeatures['render-idle-vp'];\n+    let vpRange = parseInt(expVal, 10);\n+    if (expVal && isNaN(vpRange)) {\n+      // holdback branch sends non-numeric value.\n+      return false;\n+    }\n+    vpRange = vpRange || 12;\n+    this.isIdleRender_ = true;\n+    // NOTE(keithwrightbos): handle race condition where previous\n+    // idleRenderOutsideViewport marked slot as idle render despite never\n+    // being schedule due to being beyond viewport max offset.  If slot\n+    // comes within standard outside viewport range, then ensure throttling\n+    // will not be applied.\n+    this.getResource().whenWithinRenderOutsideViewport().then(\n+        () => this.isIdleRender_ = false);\n+    return vpRange;\n+  }\n+\n+  /** @override */\n+  isLayoutSupported(layout) {\n+    this.isFluidRequest_ = layout == Layout.FLUID;\n+    return this.isFluidRequest_ || isLayoutSizeDefined(layout);\n+  }\n+\n+  /** @override */\n+  isValidElement() {\n+    return this.isAmpAdElement();\n+  }\n+\n+  /** @override */\n+  delayAdRequestEnabled() {\n+    return this.experimentIds.includes(\n+        DOUBLECLICK_EXPERIMENT_FEATURE.DELAYED_REQUEST);\n+  }\n+\n+  /**\n+   * @param {?string} urlExperimentId\n+   * @visibleForTesting\n+   */\n+  setPageLevelExperiments(urlExperimentId) {\n+    if (!isCdnProxy(this.win)) {\n+      this.experimentIds.push('21060933');\n+    }\n+    const experimentId = {\n+      // Delay Request\n+      '3': DOUBLECLICK_EXPERIMENT_FEATURE.DELAYED_REQUEST_CONTROL,\n+      '4': DOUBLECLICK_EXPERIMENT_FEATURE.DELAYED_REQUEST,\n+      // SRA\n+      '7': DOUBLECLICK_EXPERIMENT_FEATURE.SRA_CONTROL,\n+      '8': DOUBLECLICK_EXPERIMENT_FEATURE.SRA,\n+    }[urlExperimentId];\n+    switch (experimentId) {\n+      case undefined:\n+        break;\n+      case DOUBLECLICK_EXPERIMENT_FEATURE.SRA_CONTROL:\n+      case DOUBLECLICK_EXPERIMENT_FEATURE.SRA:\n+        // For SRA experiments, do not include pages that are using refresh.\n+        if (this.win.document./*OK*/querySelector(\n+            'meta[name=amp-ad-enable-refresh], ' +\n+            'amp-ad[type=matrioshka][data-enable-refresh]')) {\n+          return;\n+        }\n+      default:\n+        dev().info(\n+            TAG,\n+            `url experiment selection ${urlExperimentId}: ${experimentId}.`);\n+        this.experimentIds.push(experimentId);\n+    }\n+  }\n+\n+  /** @private */\n+  maybeDeprecationWarn_() {\n+    const warnDeprecation = feature => user().warn(\n+        TAG, `${feature} is no longer supported for DoubleClick.` +\n+          'Please refer to ' +\n+          'https://github.com/ampproject/amphtml/issues/11834 ' +\n+          'for more information');\n+    const usdrd = 'useSameDomainRenderingUntilDeprecated';\n+    const hasUSDRD = usdrd in this.element.dataset ||\n+          (tryParseJson(this.element.getAttribute('json')) || {})[usdrd];\n+    if (hasUSDRD) {\n+      warnDeprecation(usdrd);\n+    }\n+    const useRemoteHtml =\n+      !!this.win.document.querySelector('meta[name=amp-3p-iframe-src]');\n+    if (useRemoteHtml) {\n+      warnDeprecation('remote.html');\n+    }\n+  }\n+\n+  /** @override */\n+  buildCallback() {\n+    super.buildCallback();\n+    this.maybeDeprecationWarn_();\n+    this.setPageLevelExperiments(\n+        extractUrlExperimentId(this.win, this.element));\n+    this.useSra = (getMode().localDev && /(\\?|&)force_sra=true(&|$)/.test(\n+        this.win.location.search)) ||\n+        !!this.win.document.querySelector(\n+            'meta[name=amp-ad-matrioshka-sra]') ||\n+        this.experimentIds.includes(DOUBLECLICK_EXPERIMENT_FEATURE.SRA);\n+    this.identityTokenPromise_ = Services.viewerForDoc(this.getAmpDoc())\n+        .whenFirstVisible()\n+        .then(() => getIdentityToken(this.win, this.getAmpDoc()));\n+    this.troubleshootData_.slotId = this.element.getAttribute('data-slot');\n+    this.troubleshootData_.slotIndex =\n+        this.element.getAttribute('data-amp-slot-index');\n+  }\n+\n+  /** @override */\n+  shouldPreferentialRenderWithoutCrypto() {\n+    dev().assert(!isCdnProxy(this.win));\n+    return true;\n+  }\n+\n+  /**\n+   * @param {?CONSENT_POLICY_STATE} consentState\n+   * @return {!Object<string,string|boolean|number>}\n+   * @visibleForTesting\n+   */\n+  getPageParameters(consentState) {\n+    return {\n+      'npa': consentState == CONSENT_POLICY_STATE.INSUFFICIENT ||\n+          consentState == CONSENT_POLICY_STATE.UNKNOWN ? 1 : null,\n+      'gdfp_req': '1',\n+      'sfv': DEFAULT_SAFEFRAME_VERSION,\n+      'u_sd': this.win.devicePixelRatio,\n+      'gct': this.getLocationQueryParameterValue('google_preview') || null,\n+    };\n+  }\n+\n+  /**\n+   * Constructs block-level url parameters with side effect of setting\n+   * size_, jsonTargeting_, and adKey_ fields.\n+   * @return {!Object<string,string|boolean|number>}\n+   */\n+  getBlockParameters_() {\n+    dev().assert(this.initialSize_);\n+    dev().assert(this.jsonTargeting_);\n+    const tfcd = this.jsonTargeting_ && this.jsonTargeting_[TFCD];\n+    this.win['ampAdGoogleIfiCounter'] = this.win['ampAdGoogleIfiCounter'] || 1;\n+    this.ifi_ = (this.isRefreshing && this.ifi_) ||\n+        this.win['ampAdGoogleIfiCounter']++;\n+    const pageLayoutBox = this.isSinglePageStoryAd ?\n+      this.element.getPageLayoutBox() : null;\n+    return Object.assign({\n+      'iu': this.element.getAttribute('data-slot'),\n+      'co': this.jsonTargeting_ &&\n+          this.jsonTargeting_['cookieOptOut'] ? '1' : null,\n+      'adk': this.adKey_,\n+      'sz': this.isSinglePageStoryAd ? '1x1' : this.parameterSize_,\n+      'output': 'html',\n+      'impl': 'ifr',\n+      'tfcd': tfcd == undefined ? null : tfcd,\n+      'adtest': isInManualExperiment(this.element) ? 'on' : null,\n+      'ifi': this.ifi_,\n+      'rc': this.refreshCount_ || null,\n+      'frc': Number(this.fromResumeCallback) || null,\n+      'fluid': this.isFluidRequest_ ? 'height' : null,\n+      'fsf': this.forceSafeframe_ ? '1' : null,\n+      'scp': serializeTargeting_(\n+          (this.jsonTargeting_ && this.jsonTargeting_['targeting']) || null,\n+          (this.jsonTargeting_ &&\n+            this.jsonTargeting_['categoryExclusions']) || null),\n+      'spsa': this.isSinglePageStoryAd ?\n+        `${pageLayoutBox.width}x${pageLayoutBox.height}` : null,\n+    }, googleBlockParameters(this));\n+  }\n+\n+  /**\n+   * Populate's block-level state for ad URL construction.\n+   * @param {?CONSENT_POLICY_STATE} consentState\n+   * @visibleForTesting\n+   */\n+  populateAdUrlState(consentState) {\n+    this.consentState = consentState;\n+    // Allow for pub to override height/width via override attribute.\n+    const width = Number(this.element.getAttribute('data-override-width')) ||\n+      Number(this.element.getAttribute('width'));\n+    const height = Number(this.element.getAttribute('data-override-height')) ||\n+      Number(this.element.getAttribute('height'));\n+    this.initialSize_ = this.isFluidRequest_ ? {width: 0, height: 0} :\n+      (width && height ?\n+        // width/height could be 'auto' in which case we fallback to measured.\n+        {width, height} : this.getIntersectionElementLayoutBox());\n+    this.jsonTargeting_ =\n+      tryParseJson(this.element.getAttribute('json')) || {};\n+    this.adKey_ = this.generateAdKey_(\n+        `${this.initialSize_.width}x${this.initialSize_.height}`);\n+    this.parameterSize_ = this.isFluidRequest_ ?\n+      '320x50' : `${this.initialSize_.width}x${this.initialSize_.height}`;\n+    const multiSizeDataStr = this.element.getAttribute('data-multi-size');\n+    if (multiSizeDataStr) {\n+      if (this.element.getAttribute('layout') == 'responsive') {\n+        // TODO(levitzky) Define the behavior and remove this warning.\n+        user().warn(TAG, 'Behavior of multi-size and responsive layout is ' +\n+            'currently not well defined. Proceed with caution.');\n+      }\n+      const multiSizeValidation = this.element\n+          .getAttribute('data-multi-size-validation') || 'true';\n+      // The following call will check all specified multi-size dimensions,\n+      // verify that they meet all requirements, and then return all the valid\n+      // dimensions in an array.\n+      const dimensions = getMultiSizeDimensions(\n+          multiSizeDataStr,\n+          this.initialSize_.width,\n+          this.initialSize_.height,\n+          multiSizeValidation == 'true',\n+          this.isFluidRequest_);\n+      if (dimensions.length) {\n+        this.parameterSize_ += '|' + dimensions\n+            .map(dimension => dimension.join('x'))\n+            .join('|');\n+      }\n+    }\n+  }\n+\n+  /** @override */\n+  getConsentPolicy() {\n+    // Ensure that build is not blocked by need for consent (delay will occur\n+    // prior to RTC & ad URL construction).\n+    return null;\n+  }\n+\n+  getThePrebidTargeting() {\n+    if (!!this.win.pbjs.getBidResponsesForAdUnitCode) {\n+      const targeting = this.win.pbjs\n+          .getAdserverTargetingForAdUnitCode(this.pbjsCode);\n+\n+      // this.win.pbjs.getBidResponsesForAdUnitCode(this.pbjsCode)\n+      //     .bids.forEach(b => {\n+      //       try {\n+      //           this.win.sessionStorage\n+      //               .setItem('mrf-prebid-' + b.adId, JSON.stringify(b));\n+      //       } catch(err) {\n+      //         user().warn(TAG, 'coudlnt set!!!!' + JSON.stringify(b));\n+      //         user().error(TAG, err);\n+      //       }\n+      //     });\n+        this.win.pbjs.setTargetingForGPTAsync(this.pbjsCode);\n+\n+\n+        return targeting || {};\n+    }\n+    user().error(TAG, 'NO getBidResponsesForAdUnitCode');\n+    return {};\n+  }\n+\n+  doThePrebidDance() {\n+    this.win.pbjs = this.win.pbjs || {};\n+    this.win.pbjs.que = this.win.pbjs.que || [];\n+    this.pbjsCode = '/22571134/crispr/starwarsnewsnet.com';\n+\n+    this.win.pbjs.bidderSettings = {","path":"extensions/amp-ad-network-matrioshka-impl/0.1/amp-ad-network-matrioshka-impl.js","position":616,"original_position":616,"commit_id":"482f4c97cdc0c2ee3e02d1c328904bdefdb53174","original_commit_id":"d0e9a680f2594961330469d6fcbadb0e4791e39f","user":{"login":"florevallatmrf","id":32760132,"node_id":"MDQ6VXNlcjMyNzYwMTMy","avatar_url":"https://avatars0.githubusercontent.com/u/32760132?v=4","gravatar_id":"","url":"https://api.github.com/users/florevallatmrf","html_url":"https://github.com/florevallatmrf","followers_url":"https://api.github.com/users/florevallatmrf/followers","following_url":"https://api.github.com/users/florevallatmrf/following{/other_user}","gists_url":"https://api.github.com/users/florevallatmrf/gists{/gist_id}","starred_url":"https://api.github.com/users/florevallatmrf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/florevallatmrf/subscriptions","organizations_url":"https://api.github.com/users/florevallatmrf/orgs","repos_url":"https://api.github.com/users/florevallatmrf/repos","events_url":"https://api.github.com/users/florevallatmrf/events{/privacy}","received_events_url":"https://api.github.com/users/florevallatmrf/received_events","type":"User","site_admin":false},"body":"this, and the bunch above, get set on every `amp-ad` rather than once at the beginning (which should be enough)\r\nIf we want that however, we need to put it in another module, because here everything gets called everytime.","created_at":"2018-08-02T14:24:52Z","updated_at":"2018-08-02T14:24:52Z","html_url":"https://github.com/Marfeel/amphtml/pull/45#discussion_r207245997","pull_request_url":"https://api.github.com/repos/Marfeel/amphtml/pulls/45","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/Marfeel/amphtml/pulls/comments/207245997"},"html":{"href":"https://github.com/Marfeel/amphtml/pull/45#discussion_r207245997"},"pull_request":{"href":"https://api.github.com/repos/Marfeel/amphtml/pulls/45"}}},"pull_request":{"url":"https://api.github.com/repos/Marfeel/amphtml/pulls/45","id":205749216,"node_id":"MDExOlB1bGxSZXF1ZXN0MjA1NzQ5MjE2","html_url":"https://github.com/Marfeel/amphtml/pull/45","diff_url":"https://github.com/Marfeel/amphtml/pull/45.diff","patch_url":"https://github.com/Marfeel/amphtml/pull/45.patch","issue_url":"https://api.github.com/repos/Marfeel/amphtml/issues/45","number":45,"state":"open","locked":false,"title":"Glu 643 prebid in amp - new adserver","user":{"login":"florevallatmrf","id":32760132,"node_id":"MDQ6VXNlcjMyNzYwMTMy","avatar_url":"https://avatars0.githubusercontent.com/u/32760132?v=4","gravatar_id":"","url":"https://api.github.com/users/florevallatmrf","html_url":"https://github.com/florevallatmrf","followers_url":"https://api.github.com/users/florevallatmrf/followers","following_url":"https://api.github.com/users/florevallatmrf/following{/other_user}","gists_url":"https://api.github.com/users/florevallatmrf/gists{/gist_id}","starred_url":"https://api.github.com/users/florevallatmrf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/florevallatmrf/subscriptions","organizations_url":"https://api.github.com/users/florevallatmrf/orgs","repos_url":"https://api.github.com/users/florevallatmrf/repos","events_url":"https://api.github.com/users/florevallatmrf/events{/privacy}","received_events_url":"https://api.github.com/users/florevallatmrf/received_events","type":"User","site_admin":false},"body":"* The `matrioshka` name can be changed for anything\r\n* the example is still just a copy of doubleclick\r\n* didn't write tests yet\r\n* see all my comments to know what to look at \r\n","created_at":"2018-08-02T14:12:40Z","updated_at":"2018-08-02T14:24:52Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6b8880610337a3a4b652442b1f537bbec2e81984","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/Marfeel/amphtml/pulls/45/commits","review_comments_url":"https://api.github.com/repos/Marfeel/amphtml/pulls/45/comments","review_comment_url":"https://api.github.com/repos/Marfeel/amphtml/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Marfeel/amphtml/issues/45/comments","statuses_url":"https://api.github.com/repos/Marfeel/amphtml/statuses/482f4c97cdc0c2ee3e02d1c328904bdefdb53174","head":{"label":"Marfeel:GLU-643-prebid-in-amp","ref":"GLU-643-prebid-in-amp","sha":"482f4c97cdc0c2ee3e02d1c328904bdefdb53174","user":{"login":"Marfeel","id":1053553,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwNTM1NTM=","avatar_url":"https://avatars3.githubusercontent.com/u/1053553?v=4","gravatar_id":"","url":"https://api.github.com/users/Marfeel","html_url":"https://github.com/Marfeel","followers_url":"https://api.github.com/users/Marfeel/followers","following_url":"https://api.github.com/users/Marfeel/following{/other_user}","gists_url":"https://api.github.com/users/Marfeel/gists{/gist_id}","starred_url":"https://api.github.com/users/Marfeel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Marfeel/subscriptions","organizations_url":"https://api.github.com/users/Marfeel/orgs","repos_url":"https://api.github.com/users/Marfeel/repos","events_url":"https://api.github.com/users/Marfeel/events{/privacy}","received_events_url":"https://api.github.com/users/Marfeel/received_events","type":"Organization","site_admin":false},"repo":{"id":79252850,"node_id":"MDEwOlJlcG9zaXRvcnk3OTI1Mjg1MA==","name":"amphtml","full_name":"Marfeel/amphtml","owner":{"login":"Marfeel","id":1053553,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwNTM1NTM=","avatar_url":"https://avatars3.githubusercontent.com/u/1053553?v=4","gravatar_id":"","url":"https://api.github.com/users/Marfeel","html_url":"https://github.com/Marfeel","followers_url":"https://api.github.com/users/Marfeel/followers","following_url":"https://api.github.com/users/Marfeel/following{/other_user}","gists_url":"https://api.github.com/users/Marfeel/gists{/gist_id}","starred_url":"https://api.github.com/users/Marfeel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Marfeel/subscriptions","organizations_url":"https://api.github.com/users/Marfeel/orgs","repos_url":"https://api.github.com/users/Marfeel/repos","events_url":"https://api.github.com/users/Marfeel/events{/privacy}","received_events_url":"https://api.github.com/users/Marfeel/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Marfeel/amphtml","description":"AMP HTML source code, samples, and documentation.  See below for more info.","fork":true,"url":"https://api.github.com/repos/Marfeel/amphtml","forks_url":"https://api.github.com/repos/Marfeel/amphtml/forks","keys_url":"https://api.github.com/repos/Marfeel/amphtml/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Marfeel/amphtml/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Marfeel/amphtml/teams","hooks_url":"https://api.github.com/repos/Marfeel/amphtml/hooks","issue_events_url":"https://api.github.com/repos/Marfeel/amphtml/issues/events{/number}","events_url":"https://api.github.com/repos/Marfeel/amphtml/events","assignees_url":"https://api.github.com/repos/Marfeel/amphtml/assignees{/user}","branches_url":"https://api.github.com/repos/Marfeel/amphtml/branches{/branch}","tags_url":"https://api.github.com/repos/Marfeel/amphtml/tags","blobs_url":"https://api.github.com/repos/Marfeel/amphtml/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Marfeel/amphtml/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Marfeel/amphtml/git/refs{/sha}","trees_url":"https://api.github.com/repos/Marfeel/amphtml/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Marfeel/amphtml/statuses/{sha}","languages_url":"https://api.github.com/repos/Marfeel/amphtml/languages","stargazers_url":"https://api.github.com/repos/Marfeel/amphtml/stargazers","contributors_url":"https://api.github.com/repos/Marfeel/amphtml/contributors","subscribers_url":"https://api.github.com/repos/Marfeel/amphtml/subscribers","subscription_url":"https://api.github.com/repos/Marfeel/amphtml/subscription","commits_url":"https://api.github.com/repos/Marfeel/amphtml/commits{/sha}","git_commits_url":"https://api.github.com/repos/Marfeel/amphtml/git/commits{/sha}","comments_url":"https://api.github.com/repos/Marfeel/amphtml/comments{/number}","issue_comment_url":"https://api.github.com/repos/Marfeel/amphtml/issues/comments{/number}","contents_url":"https://api.github.com/repos/Marfeel/amphtml/contents/{+path}","compare_url":"https://api.github.com/repos/Marfeel/amphtml/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Marfeel/amphtml/merges","archive_url":"https://api.github.com/repos/Marfeel/amphtml/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Marfeel/amphtml/downloads","issues_url":"https://api.github.com/repos/Marfeel/amphtml/issues{/number}","pulls_url":"https://api.github.com/repos/Marfeel/amphtml/pulls{/number}","milestones_url":"https://api.github.com/repos/Marfeel/amphtml/milestones{/number}","notifications_url":"https://api.github.com/repos/Marfeel/amphtml/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Marfeel/amphtml/labels{/name}","releases_url":"https://api.github.com/repos/Marfeel/amphtml/releases{/id}","deployments_url":"https://api.github.com/repos/Marfeel/amphtml/deployments","created_at":"2017-01-17T17:27:19Z","updated_at":"2018-06-18T09:06:40Z","pushed_at":"2018-08-02T14:16:25Z","git_url":"git://github.com/Marfeel/amphtml.git","ssh_url":"git@github.com:Marfeel/amphtml.git","clone_url":"https://github.com/Marfeel/amphtml.git","svn_url":"https://github.com/Marfeel/amphtml","homepage":"https://ampproject.org","size":493654,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":4,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":4,"watchers":0,"default_branch":"master"}},"base":{"label":"Marfeel:MarfeelK","ref":"MarfeelK","sha":"1a58e5ab3a45991dcf90ddaf929eb4d6eb1385e6","user":{"login":"Marfeel","id":1053553,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwNTM1NTM=","avatar_url":"https://avatars3.githubusercontent.com/u/1053553?v=4","gravatar_id":"","url":"https://api.github.com/users/Marfeel","html_url":"https://github.com/Marfeel","followers_url":"https://api.github.com/users/Marfeel/followers","following_url":"https://api.github.com/users/Marfeel/following{/other_user}","gists_url":"https://api.github.com/users/Marfeel/gists{/gist_id}","starred_url":"https://api.github.com/users/Marfeel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Marfeel/subscriptions","organizations_url":"https://api.github.com/users/Marfeel/orgs","repos_url":"https://api.github.com/users/Marfeel/repos","events_url":"https://api.github.com/users/Marfeel/events{/privacy}","received_events_url":"https://api.github.com/users/Marfeel/received_events","type":"Organization","site_admin":false},"repo":{"id":79252850,"node_id":"MDEwOlJlcG9zaXRvcnk3OTI1Mjg1MA==","name":"amphtml","full_name":"Marfeel/amphtml","owner":{"login":"Marfeel","id":1053553,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwNTM1NTM=","avatar_url":"https://avatars3.githubusercontent.com/u/1053553?v=4","gravatar_id":"","url":"https://api.github.com/users/Marfeel","html_url":"https://github.com/Marfeel","followers_url":"https://api.github.com/users/Marfeel/followers","following_url":"https://api.github.com/users/Marfeel/following{/other_user}","gists_url":"https://api.github.com/users/Marfeel/gists{/gist_id}","starred_url":"https://api.github.com/users/Marfeel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Marfeel/subscriptions","organizations_url":"https://api.github.com/users/Marfeel/orgs","repos_url":"https://api.github.com/users/Marfeel/repos","events_url":"https://api.github.com/users/Marfeel/events{/privacy}","received_events_url":"https://api.github.com/users/Marfeel/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Marfeel/amphtml","description":"AMP HTML source code, samples, and documentation.  See below for more info.","fork":true,"url":"https://api.github.com/repos/Marfeel/amphtml","forks_url":"https://api.github.com/repos/Marfeel/amphtml/forks","keys_url":"https://api.github.com/repos/Marfeel/amphtml/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Marfeel/amphtml/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Marfeel/amphtml/teams","hooks_url":"https://api.github.com/repos/Marfeel/amphtml/hooks","issue_events_url":"https://api.github.com/repos/Marfeel/amphtml/issues/events{/number}","events_url":"https://api.github.com/repos/Marfeel/amphtml/events","assignees_url":"https://api.github.com/repos/Marfeel/amphtml/assignees{/user}","branches_url":"https://api.github.com/repos/Marfeel/amphtml/branches{/branch}","tags_url":"https://api.github.com/repos/Marfeel/amphtml/tags","blobs_url":"https://api.github.com/repos/Marfeel/amphtml/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Marfeel/amphtml/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Marfeel/amphtml/git/refs{/sha}","trees_url":"https://api.github.com/repos/Marfeel/amphtml/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Marfeel/amphtml/statuses/{sha}","languages_url":"https://api.github.com/repos/Marfeel/amphtml/languages","stargazers_url":"https://api.github.com/repos/Marfeel/amphtml/stargazers","contributors_url":"https://api.github.com/repos/Marfeel/amphtml/contributors","subscribers_url":"https://api.github.com/repos/Marfeel/amphtml/subscribers","subscription_url":"https://api.github.com/repos/Marfeel/amphtml/subscription","commits_url":"https://api.github.com/repos/Marfeel/amphtml/commits{/sha}","git_commits_url":"https://api.github.com/repos/Marfeel/amphtml/git/commits{/sha}","comments_url":"https://api.github.com/repos/Marfeel/amphtml/comments{/number}","issue_comment_url":"https://api.github.com/repos/Marfeel/amphtml/issues/comments{/number}","contents_url":"https://api.github.com/repos/Marfeel/amphtml/contents/{+path}","compare_url":"https://api.github.com/repos/Marfeel/amphtml/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Marfeel/amphtml/merges","archive_url":"https://api.github.com/repos/Marfeel/amphtml/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Marfeel/amphtml/downloads","issues_url":"https://api.github.com/repos/Marfeel/amphtml/issues{/number}","pulls_url":"https://api.github.com/repos/Marfeel/amphtml/pulls{/number}","milestones_url":"https://api.github.com/repos/Marfeel/amphtml/milestones{/number}","notifications_url":"https://api.github.com/repos/Marfeel/amphtml/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Marfeel/amphtml/labels{/name}","releases_url":"https://api.github.com/repos/Marfeel/amphtml/releases{/id}","deployments_url":"https://api.github.com/repos/Marfeel/amphtml/deployments","created_at":"2017-01-17T17:27:19Z","updated_at":"2018-06-18T09:06:40Z","pushed_at":"2018-08-02T14:16:25Z","git_url":"git://github.com/Marfeel/amphtml.git","ssh_url":"git@github.com:Marfeel/amphtml.git","clone_url":"https://github.com/Marfeel/amphtml.git","svn_url":"https://github.com/Marfeel/amphtml","homepage":"https://ampproject.org","size":493654,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":4,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":4,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Marfeel/amphtml/pulls/45"},"html":{"href":"https://github.com/Marfeel/amphtml/pull/45"},"issue":{"href":"https://api.github.com/repos/Marfeel/amphtml/issues/45"},"comments":{"href":"https://api.github.com/repos/Marfeel/amphtml/issues/45/comments"},"review_comments":{"href":"https://api.github.com/repos/Marfeel/amphtml/pulls/45/comments"},"review_comment":{"href":"https://api.github.com/repos/Marfeel/amphtml/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Marfeel/amphtml/pulls/45/commits"},"statuses":{"href":"https://api.github.com/repos/Marfeel/amphtml/statuses/482f4c97cdc0c2ee3e02d1c328904bdefdb53174"}},"author_association":"NONE"}}
{"actor":{"display_login":"florevallatmrf"}}