{"action":"created","comment":{"url":"https://api.github.com/repos/ampproject/amphtml/pulls/comments/119369591","pull_request_review_id":41243628,"id":119369591,"diff_hunk":"@@ -124,116 +128,151 @@ export function isReportingEnabled(ampElement) {\n }\n \n /**\n+ * Has side-effect of incrementing ifi counter on window.\n+ * @param {!../../../extensions/amp-a4a/0.1/amp-a4a.AmpA4A} a4a\n+ * @param {!Array<string>=} opt_experimentIds Any experiments IDs (in addition\n+ *     to those specified on the ad element) that should be included in the\n+ *     request.\n+ * @return {!Object<string,null|number|string>} block level parameters\n+ */\n+export function googleBlockParameters(a4a, opt_experimentIds) {\n+  const adElement = a4a.element;\n+  const win = a4a.win;\n+  win['ampAdGoogleIfiCounter'] = win['ampAdGoogleIfiCounter'] || 1;\n+  const slotRect = a4a.getPageLayoutBox();\n+  const iframeDepth = iframeNestingDepth(win);\n+  // Detect container types.\n+  const containerTypeSet = {};\n+  for (let el = adElement.parentElement, counter = 0;\n+      el && counter < 20; el = el.parentElement, counter++) {\n+    const tagName = el.tagName.toUpperCase();\n+    if (ValidAdContainerTypes[tagName]) {\n+      containerTypeSet[ValidAdContainerTypes[tagName]] = true;\n+    }\n+  }\n+  const pfx =\n+      (containerTypeSet[ValidAdContainerTypes['AMP-FX-FLYING-CARPET']]\n+       || containerTypeSet[ValidAdContainerTypes['AMP-STICKY-AD']])\n+      ? '1' : '0';\n+  let eids = adElement.getAttribute('data-experiment-id');\n+  if (opt_experimentIds) {\n+    eids = mergeExperimentIds(opt_experimentIds, eids);\n+  }\n+  const containerTypeArray = Object.keys(containerTypeSet);\n+  return {\n+    'ifi': win['ampAdGoogleIfiCounter']++,\n+    'adf': domFingerprint(adElement),\n+    'nhd': iframeDepth,\n+    'eid': eids,\n+    'adx': slotRect.left,\n+    'ady': slotRect.top,\n+    'oid': '2',\n+    pfx,\n+    'rc': a4a.fromResumeCallback ? 1 : null,\n+    'act': containerTypeArray.length ? containerTypeArray.join() : null,\n+  };\n+}\n+\n+/**\n+ * @param {!Window} win\n+ * @param {string} type matching typing attribute.\n+ * @param {!function(!Element):string} groupFn\n+ * @return {!Promise<!Object<string,!Array<!Promise<!../../../src/base-element.BaseElement>>>>}\n+ */\n+export function groupAmpAdsByType(win, type, groupFn) {\n+  return resourcesForDoc(win.document).getMeasuredResources(win,\n+      r => r.element.tagName == 'AMP-AD' &&\n+        r.element.getAttribute('type') == type)\n+      .then(resources => {\n+        const result = {};\n+        resources.forEach(r => {\n+          const groupId = groupFn(r.element);\n+          (result[groupId] || (result[groupId] = [])).push(r.element.getImpl());\n+        });\n+        return result;\n+      });\n+}\n+\n+/**\n+ * @param {!Window} win\n+ * @param {!Node|!../../../src/service/ampdoc-impl.AmpDoc} doc\n+ * @param {number} startTime\n+ * @param {string=} output default is 'html'\n+ * @return {!Promise<!Object<string,null|number|string>>}\n+ */\n+export function googlePageParameters(win, doc, startTime, output = 'html') {\n+  const referrerPromise = viewerForDoc(doc).getReferrerUrl();\n+  return getClientAdCid(win, doc, 'AMP_ECID_GOOGLE')\n+    .then(clientId => referrerPromise.then(referrer => {\n+      const documentInfo = documentInfoForDoc(win.document);\n+        // Read by GPT for GA/GPT integration.\n+      win.gaGlobal = win.gaGlobal ||\n+        {cid: clientId, hid: documentInfo.pageViewId};\n+      const screen = win.screen;\n+      const viewport = viewportForDoc(win.document);\n+      const viewportRect = viewport.getRect();\n+      const viewportSize = viewport.getSize();\n+      return {\n+        'is_amp': AmpAdImplementation.AMP_AD_XHR_TO_IFRAME_OR_AMP,\n+        'amp_v': '$internalRuntimeVersion$',\n+        'd_imp': '1',\n+        'c': getCorrelator(win, clientId),\n+        'dt': startTime,\n+        output,\n+        'biw': viewportRect.width,\n+        'bih': viewportRect.height,\n+        'u_aw': screen ? screen.availWidth : null,\n+        'u_ah': screen ? screen.availHeight : null,\n+        'u_cd': screen ? screen.colorDepth : null,\n+        'u_w': screen ? screen.width : null,\n+        'u_h': screen ? screen.height : null,\n+        'u_tz': -new Date().getTimezoneOffset(),\n+        'u_his': getHistoryLength(win),\n+        'brdim': additionalDimensions(win, viewportSize),\n+        'isw': viewportSize.width,\n+        'ish': viewportSize.height,\n+        'art': isCanary(win) ? '2' : null,\n+        'url': documentInfo.canonicalUrl,\n+        'top': win != win.top ? topWindowUrlOrDomain(win) : null,\n+        'loc': win.location.href == documentInfo.canonicalUrl ?\n+          null : win.location.href,\n+        'ref': referrer,\n+      };\n+    }));\n+}\n+\n+/**\n  * @param {!../../../extensions/amp-a4a/0.1/amp-a4a.AmpA4A} a4a\n  * @param {string} baseUrl\n  * @param {number} startTime\n- * @param {!Array<!./url-builder.QueryParameterDef>} queryParams\n- * @param {!Array<!./url-builder.QueryParameterDef>} unboundedQueryParams\n- *     Parameters that will be put at the end of the URL, where they may be\n- *     elided for length reasons. Intended for parameters with potentially\n- *     long values, like URLs.\n+ * @param {!Object<string,null|number|string>} parameters\n  * @param {!Array<string>=} opt_experimentIds Any experiments IDs (in addition\n  *     to those specified on the ad element) that should be included in the\n  *     request.\n  * @return {!Promise<string>}\n  */\n export function googleAdUrl(\n-    a4a, baseUrl, startTime, queryParams, unboundedQueryParams,\n-    opt_experimentIds) {\n+    a4a, baseUrl, startTime, parameters, opt_experimentIds) {\n   // TODO: Maybe add checks in case these promises fail.\n-  /** @const {!Promise<string>} */\n-  const referrerPromise = viewerForDoc(a4a.getAmpDoc()).getReferrerUrl();\n-  return getAdCid(a4a).then(clientId => referrerPromise.then(referrer => {\n-    const adElement = a4a.element;\n-    window['ampAdGoogleIfiCounter'] = window['ampAdGoogleIfiCounter'] || 1;\n-    const slotNumber = window['ampAdGoogleIfiCounter']++;\n-    const win = a4a.win;\n-    const documentInfo = documentInfoForDoc(adElement);\n-      // Read by GPT for GA/GPT integration.\n-    win.gaGlobal = win.gaGlobal ||\n-      {cid: clientId, hid: documentInfo.pageViewId};\n-    const slotRect = a4a.getPageLayoutBox();\n-    const screen = win.screen;\n-    const viewport = a4a.getViewport();\n-    const viewportRect = viewport.getRect();\n-    const iframeDepth = iframeNestingDepth(win);\n-    const viewportSize = viewport.getSize();\n-    // Detect container types.\n-    const containerTypeSet = {};\n-    for (let el = adElement.parentElement, counter = 0;\n-        el && counter < 20; el = el.parentElement, counter++) {\n-      const tagName = el.tagName.toUpperCase();\n-      if (ValidAdContainerTypes[tagName]) {\n-        containerTypeSet[ValidAdContainerTypes[tagName]] = true;\n-      }\n-    }\n-    const pfx =\n-        (containerTypeSet[ValidAdContainerTypes['AMP-FX-FLYING-CARPET']]\n-         || containerTypeSet[ValidAdContainerTypes['AMP-STICKY-AD']])\n-        ? '1' : '0';\n-    queryParams.push({name: 'act', value:\n-      Object.keys(containerTypeSet).join()});\n-    if (isCanary(win)) {\n-      // The semantics here are:\n-      //   0: production branch (this is never actually sent)\n-      //   1: control branch (this is not yet supported, so is never sent)\n-      //   2: canary branch\n-      queryParams.push({name: 'art', value: '2'});\n-    }\n-    let eids = adElement.getAttribute('data-experiment-id');\n-    if (opt_experimentIds) {\n-      eids = mergeExperimentIds(opt_experimentIds, eids);\n-    }\n-    const allQueryParams = queryParams.concat(\n-      [\n-        {\n-          name: 'is_amp',\n-          value: AmpAdImplementation.AMP_AD_XHR_TO_IFRAME_OR_AMP,\n-        },\n-        {name: 'amp_v', value: '$internalRuntimeVersion$'},\n-        {name: 'd_imp', value: '1'},\n-        {name: 'dt', value: startTime},\n-        {name: 'ifi', value: slotNumber},\n-        {name: 'adf', value: domFingerprint(adElement)},\n-        {name: 'c', value: getCorrelator(win, clientId)},\n-        {name: 'output', value: 'html'},\n-        {name: 'nhd', value: iframeDepth},\n-        {name: 'iu', value: adElement.getAttribute('data-ad-slot')},\n-        {name: 'eid', value: eids},\n-        {name: 'biw', value: viewportRect.width},\n-        {name: 'bih', value: viewportRect.height},\n-        {name: 'adx', value: slotRect.left},\n-        {name: 'ady', value: slotRect.top},\n-        {name: 'u_aw', value: screen ? screen.availWidth : null},\n-        {name: 'u_ah', value: screen ? screen.availHeight : null},\n-        {name: 'u_cd', value: screen ? screen.colorDepth : null},\n-        {name: 'u_w', value: screen ? screen.width : null},\n-        {name: 'u_h', value: screen ? screen.height : null},\n-        {name: 'u_tz', value: -new Date().getTimezoneOffset()},\n-        {name: 'u_his', value: getHistoryLength(win)},\n-        {name: 'oid', value: '2'},\n-        {name: 'brdim', value: additionalDimensions(win, viewportSize)},\n-        {name: 'isw', value: viewportSize.width},\n-        {name: 'ish', value: viewportSize.height},\n-        {name: 'pfx', value: pfx},\n-        {name: 'rc', value: a4a.fromResumeCallback ? 1 : null},\n-      ],\n-      unboundedQueryParams,\n-      [\n-        {name: 'url', value: documentInfo.canonicalUrl},\n-        {name: 'top', value: iframeDepth ? topWindowUrlOrDomain(win) : null},\n-        {\n-          name: 'loc',\n-          value: win.location.href == documentInfo.canonicalUrl ?\n-            null : win.location.href,\n-        },\n-        {name: 'ref', value: referrer},\n-      ]\n-    );\n-    const url = buildUrl(baseUrl, allQueryParams, MAX_URL_LENGTH - 10,\n-                         {name: 'trunc', value: '1'});\n-    return url + '&dtd=' + elapsedTimeWithCeiling(Date.now(), startTime);\n-  }));\n+  const blockLevelParameters = googleBlockParameters(a4a, opt_experimentIds);\n+  return googlePageParameters(a4a.win, a4a.getAmpDoc(), startTime)\n+    .then(pageLevelParameters => {\n+      Object.assign(parameters, blockLevelParameters);\n+      Object.assign(parameters, pageLevelParameters);","path":"ads/google/a4a/utils.js","position":253,"original_position":253,"commit_id":"a136616722aeb6443f699b3ea2628fc2cdc462d0","original_commit_id":"a136616722aeb6443f699b3ea2628fc2cdc462d0","user":{"login":"keithwrightbos","id":1766447,"avatar_url":"https://avatars1.githubusercontent.com/u/1766447?v=3","gravatar_id":"","url":"https://api.github.com/users/keithwrightbos","html_url":"https://github.com/keithwrightbos","followers_url":"https://api.github.com/users/keithwrightbos/followers","following_url":"https://api.github.com/users/keithwrightbos/following{/other_user}","gists_url":"https://api.github.com/users/keithwrightbos/gists{/gist_id}","starred_url":"https://api.github.com/users/keithwrightbos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/keithwrightbos/subscriptions","organizations_url":"https://api.github.com/users/keithwrightbos/orgs","repos_url":"https://api.github.com/users/keithwrightbos/repos","events_url":"https://api.github.com/users/keithwrightbos/events{/privacy}","received_events_url":"https://api.github.com/users/keithwrightbos/received_events","type":"User","site_admin":false},"body":"Done","created_at":"2017-05-31T14:26:02Z","updated_at":"2017-05-31T14:26:02Z","html_url":"https://github.com/ampproject/amphtml/pull/9563#discussion_r119369591","pull_request_url":"https://api.github.com/repos/ampproject/amphtml/pulls/9563","_links":{"self":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/comments/119369591"},"html":{"href":"https://github.com/ampproject/amphtml/pull/9563#discussion_r119369591"},"pull_request":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/9563"}}},"pull_request":{"url":"https://api.github.com/repos/ampproject/amphtml/pulls/9563","id":122526787,"html_url":"https://github.com/ampproject/amphtml/pull/9563","diff_url":"https://github.com/ampproject/amphtml/pull/9563.diff","patch_url":"https://github.com/ampproject/amphtml/pull/9563.patch","issue_url":"https://api.github.com/repos/ampproject/amphtml/issues/9563","number":9563,"state":"open","locked":false,"title":"Add SRA support for Doubleclick Fast Fetch Traffic","user":{"login":"keithwrightbos","id":1766447,"avatar_url":"https://avatars1.githubusercontent.com/u/1766447?v=3","gravatar_id":"","url":"https://api.github.com/users/keithwrightbos","html_url":"https://github.com/keithwrightbos","followers_url":"https://api.github.com/users/keithwrightbos/followers","following_url":"https://api.github.com/users/keithwrightbos/following{/other_user}","gists_url":"https://api.github.com/users/keithwrightbos/gists{/gist_id}","starred_url":"https://api.github.com/users/keithwrightbos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/keithwrightbos/subscriptions","organizations_url":"https://api.github.com/users/keithwrightbos/orgs","repos_url":"https://api.github.com/users/keithwrightbos/repos","events_url":"https://api.github.com/users/keithwrightbos/events{/privacy}","received_events_url":"https://api.github.com/users/keithwrightbos/received_events","type":"User","site_admin":false},"body":"Still a WIP but contains the following:\r\n\r\n- If page url includes force_sra=true query parameter, doubleclick request will be sent via SRA\r\n- combines doubleclick amp-ad elements by network ID (sends separate SRA requests for different networks)\r\n- expect line delimited response format where odd lines are JSON formatted headers and event lines are the creative content\r\n- uses streaming fetch method so that blocks can be rendered without waiting for entire SRA response (renders each block as their pair of lines are retrieved) where possible (requires native fetch API) otherwise falls back to fetching entire response prior to processing.\r\n- in the event of error, slots are collapsed and frame get fallback method is disabled\r\n- resets global SRA fetch executor in unlayoutCallback allowing for resumeCallback initiated chain to refetch via SRA\r\n- separates parameters into block and page level.  Assumes that only block level parameters included in COMBINER global functions are required.  TODO: verify and implement exceptions (e.g. block fields within googleBlockParameters such as ifi, adf, and act).\r\n\r\nTODO:\r\n- test coverage update/addition\r\n- allow for selecting into SRA by publisher and/or experiment\r\n- update CSI metrics to properly capture SRA behavior\r\n- edge condition analysis/handling\r\n\r\ncc/ @ampproject/a4a \r\n","created_at":"2017-05-25T21:10:33Z","updated_at":"2017-05-31T14:26:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4ddcf7fc8ebaaf9d0eb19c2b61451b90c8a229ae","assignee":{"login":"keithwrightbos","id":1766447,"avatar_url":"https://avatars1.githubusercontent.com/u/1766447?v=3","gravatar_id":"","url":"https://api.github.com/users/keithwrightbos","html_url":"https://github.com/keithwrightbos","followers_url":"https://api.github.com/users/keithwrightbos/followers","following_url":"https://api.github.com/users/keithwrightbos/following{/other_user}","gists_url":"https://api.github.com/users/keithwrightbos/gists{/gist_id}","starred_url":"https://api.github.com/users/keithwrightbos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/keithwrightbos/subscriptions","organizations_url":"https://api.github.com/users/keithwrightbos/orgs","repos_url":"https://api.github.com/users/keithwrightbos/repos","events_url":"https://api.github.com/users/keithwrightbos/events{/privacy}","received_events_url":"https://api.github.com/users/keithwrightbos/received_events","type":"User","site_admin":false},"assignees":[{"login":"keithwrightbos","id":1766447,"avatar_url":"https://avatars1.githubusercontent.com/u/1766447?v=3","gravatar_id":"","url":"https://api.github.com/users/keithwrightbos","html_url":"https://github.com/keithwrightbos","followers_url":"https://api.github.com/users/keithwrightbos/followers","following_url":"https://api.github.com/users/keithwrightbos/following{/other_user}","gists_url":"https://api.github.com/users/keithwrightbos/gists{/gist_id}","starred_url":"https://api.github.com/users/keithwrightbos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/keithwrightbos/subscriptions","organizations_url":"https://api.github.com/users/keithwrightbos/orgs","repos_url":"https://api.github.com/users/keithwrightbos/repos","events_url":"https://api.github.com/users/keithwrightbos/events{/privacy}","received_events_url":"https://api.github.com/users/keithwrightbos/received_events","type":"User","site_admin":false}],"requested_reviewers":[{"login":"dvoytenko","id":726049,"avatar_url":"https://avatars3.githubusercontent.com/u/726049?v=3","gravatar_id":"","url":"https://api.github.com/users/dvoytenko","html_url":"https://github.com/dvoytenko","followers_url":"https://api.github.com/users/dvoytenko/followers","following_url":"https://api.github.com/users/dvoytenko/following{/other_user}","gists_url":"https://api.github.com/users/dvoytenko/gists{/gist_id}","starred_url":"https://api.github.com/users/dvoytenko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dvoytenko/subscriptions","organizations_url":"https://api.github.com/users/dvoytenko/orgs","repos_url":"https://api.github.com/users/dvoytenko/repos","events_url":"https://api.github.com/users/dvoytenko/events{/privacy}","received_events_url":"https://api.github.com/users/dvoytenko/received_events","type":"User","site_admin":false},{"login":"bradfrizzell","id":4276992,"avatar_url":"https://avatars2.githubusercontent.com/u/4276992?v=3","gravatar_id":"","url":"https://api.github.com/users/bradfrizzell","html_url":"https://github.com/bradfrizzell","followers_url":"https://api.github.com/users/bradfrizzell/followers","following_url":"https://api.github.com/users/bradfrizzell/following{/other_user}","gists_url":"https://api.github.com/users/bradfrizzell/gists{/gist_id}","starred_url":"https://api.github.com/users/bradfrizzell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bradfrizzell/subscriptions","organizations_url":"https://api.github.com/users/bradfrizzell/orgs","repos_url":"https://api.github.com/users/bradfrizzell/repos","events_url":"https://api.github.com/users/bradfrizzell/events{/privacy}","received_events_url":"https://api.github.com/users/bradfrizzell/received_events","type":"User","site_admin":false},{"login":"glevitzky","id":20518281,"avatar_url":"https://avatars2.githubusercontent.com/u/20518281?v=3","gravatar_id":"","url":"https://api.github.com/users/glevitzky","html_url":"https://github.com/glevitzky","followers_url":"https://api.github.com/users/glevitzky/followers","following_url":"https://api.github.com/users/glevitzky/following{/other_user}","gists_url":"https://api.github.com/users/glevitzky/gists{/gist_id}","starred_url":"https://api.github.com/users/glevitzky/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/glevitzky/subscriptions","organizations_url":"https://api.github.com/users/glevitzky/orgs","repos_url":"https://api.github.com/users/glevitzky/repos","events_url":"https://api.github.com/users/glevitzky/events{/privacy}","received_events_url":"https://api.github.com/users/glevitzky/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/ampproject/amphtml/pulls/9563/commits","review_comments_url":"https://api.github.com/repos/ampproject/amphtml/pulls/9563/comments","review_comment_url":"https://api.github.com/repos/ampproject/amphtml/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ampproject/amphtml/issues/9563/comments","statuses_url":"https://api.github.com/repos/ampproject/amphtml/statuses/a136616722aeb6443f699b3ea2628fc2cdc462d0","head":{"label":"google:dbclk_sra","ref":"dbclk_sra","sha":"a136616722aeb6443f699b3ea2628fc2cdc462d0","user":{"login":"google","id":1342004,"avatar_url":"https://avatars2.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":51965089,"name":"amphtml","full_name":"google/amphtml","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars2.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/amphtml","description":"AMP HTML source code, samples, and documentation.  See below for more info.","fork":true,"url":"https://api.github.com/repos/google/amphtml","forks_url":"https://api.github.com/repos/google/amphtml/forks","keys_url":"https://api.github.com/repos/google/amphtml/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/amphtml/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/amphtml/teams","hooks_url":"https://api.github.com/repos/google/amphtml/hooks","issue_events_url":"https://api.github.com/repos/google/amphtml/issues/events{/number}","events_url":"https://api.github.com/repos/google/amphtml/events","assignees_url":"https://api.github.com/repos/google/amphtml/assignees{/user}","branches_url":"https://api.github.com/repos/google/amphtml/branches{/branch}","tags_url":"https://api.github.com/repos/google/amphtml/tags","blobs_url":"https://api.github.com/repos/google/amphtml/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/amphtml/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/amphtml/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/amphtml/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/amphtml/statuses/{sha}","languages_url":"https://api.github.com/repos/google/amphtml/languages","stargazers_url":"https://api.github.com/repos/google/amphtml/stargazers","contributors_url":"https://api.github.com/repos/google/amphtml/contributors","subscribers_url":"https://api.github.com/repos/google/amphtml/subscribers","subscription_url":"https://api.github.com/repos/google/amphtml/subscription","commits_url":"https://api.github.com/repos/google/amphtml/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/amphtml/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/amphtml/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/amphtml/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/amphtml/contents/{+path}","compare_url":"https://api.github.com/repos/google/amphtml/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/amphtml/merges","archive_url":"https://api.github.com/repos/google/amphtml/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/amphtml/downloads","issues_url":"https://api.github.com/repos/google/amphtml/issues{/number}","pulls_url":"https://api.github.com/repos/google/amphtml/pulls{/number}","milestones_url":"https://api.github.com/repos/google/amphtml/milestones{/number}","notifications_url":"https://api.github.com/repos/google/amphtml/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/amphtml/labels{/name}","releases_url":"https://api.github.com/repos/google/amphtml/releases{/id}","deployments_url":"https://api.github.com/repos/google/amphtml/deployments","created_at":"2016-02-18T00:04:16Z","updated_at":"2017-05-30T17:33:57Z","pushed_at":"2017-05-31T13:43:48Z","git_url":"git://github.com/google/amphtml.git","ssh_url":"git@github.com:google/amphtml.git","clone_url":"https://github.com/google/amphtml.git","svn_url":"https://github.com/google/amphtml","homepage":"https://ampproject.org","size":254573,"stargazers_count":98,"watchers_count":98,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":25,"mirror_url":null,"open_issues_count":0,"forks":25,"open_issues":0,"watchers":98,"default_branch":"master"}},"base":{"label":"ampproject:master","ref":"master","sha":"45944892ba2c25d2d6b2abdc7a997e3197d19cc2","user":{"login":"ampproject","id":14114390,"avatar_url":"https://avatars0.githubusercontent.com/u/14114390?v=3","gravatar_id":"","url":"https://api.github.com/users/ampproject","html_url":"https://github.com/ampproject","followers_url":"https://api.github.com/users/ampproject/followers","following_url":"https://api.github.com/users/ampproject/following{/other_user}","gists_url":"https://api.github.com/users/ampproject/gists{/gist_id}","starred_url":"https://api.github.com/users/ampproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ampproject/subscriptions","organizations_url":"https://api.github.com/users/ampproject/orgs","repos_url":"https://api.github.com/users/ampproject/repos","events_url":"https://api.github.com/users/ampproject/events{/privacy}","received_events_url":"https://api.github.com/users/ampproject/received_events","type":"Organization","site_admin":false},"repo":{"id":41766002,"name":"amphtml","full_name":"ampproject/amphtml","owner":{"login":"ampproject","id":14114390,"avatar_url":"https://avatars0.githubusercontent.com/u/14114390?v=3","gravatar_id":"","url":"https://api.github.com/users/ampproject","html_url":"https://github.com/ampproject","followers_url":"https://api.github.com/users/ampproject/followers","following_url":"https://api.github.com/users/ampproject/following{/other_user}","gists_url":"https://api.github.com/users/ampproject/gists{/gist_id}","starred_url":"https://api.github.com/users/ampproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ampproject/subscriptions","organizations_url":"https://api.github.com/users/ampproject/orgs","repos_url":"https://api.github.com/users/ampproject/repos","events_url":"https://api.github.com/users/ampproject/events{/privacy}","received_events_url":"https://api.github.com/users/ampproject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ampproject/amphtml","description":"AMP HTML source code, samples, and documentation.  See below for more info.","fork":false,"url":"https://api.github.com/repos/ampproject/amphtml","forks_url":"https://api.github.com/repos/ampproject/amphtml/forks","keys_url":"https://api.github.com/repos/ampproject/amphtml/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ampproject/amphtml/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ampproject/amphtml/teams","hooks_url":"https://api.github.com/repos/ampproject/amphtml/hooks","issue_events_url":"https://api.github.com/repos/ampproject/amphtml/issues/events{/number}","events_url":"https://api.github.com/repos/ampproject/amphtml/events","assignees_url":"https://api.github.com/repos/ampproject/amphtml/assignees{/user}","branches_url":"https://api.github.com/repos/ampproject/amphtml/branches{/branch}","tags_url":"https://api.github.com/repos/ampproject/amphtml/tags","blobs_url":"https://api.github.com/repos/ampproject/amphtml/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ampproject/amphtml/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ampproject/amphtml/git/refs{/sha}","trees_url":"https://api.github.com/repos/ampproject/amphtml/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ampproject/amphtml/statuses/{sha}","languages_url":"https://api.github.com/repos/ampproject/amphtml/languages","stargazers_url":"https://api.github.com/repos/ampproject/amphtml/stargazers","contributors_url":"https://api.github.com/repos/ampproject/amphtml/contributors","subscribers_url":"https://api.github.com/repos/ampproject/amphtml/subscribers","subscription_url":"https://api.github.com/repos/ampproject/amphtml/subscription","commits_url":"https://api.github.com/repos/ampproject/amphtml/commits{/sha}","git_commits_url":"https://api.github.com/repos/ampproject/amphtml/git/commits{/sha}","comments_url":"https://api.github.com/repos/ampproject/amphtml/comments{/number}","issue_comment_url":"https://api.github.com/repos/ampproject/amphtml/issues/comments{/number}","contents_url":"https://api.github.com/repos/ampproject/amphtml/contents/{+path}","compare_url":"https://api.github.com/repos/ampproject/amphtml/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ampproject/amphtml/merges","archive_url":"https://api.github.com/repos/ampproject/amphtml/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ampproject/amphtml/downloads","issues_url":"https://api.github.com/repos/ampproject/amphtml/issues{/number}","pulls_url":"https://api.github.com/repos/ampproject/amphtml/pulls{/number}","milestones_url":"https://api.github.com/repos/ampproject/amphtml/milestones{/number}","notifications_url":"https://api.github.com/repos/ampproject/amphtml/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ampproject/amphtml/labels{/name}","releases_url":"https://api.github.com/repos/ampproject/amphtml/releases{/id}","deployments_url":"https://api.github.com/repos/ampproject/amphtml/deployments","created_at":"2015-09-01T22:10:53Z","updated_at":"2017-05-31T14:15:05Z","pushed_at":"2017-05-31T13:37:55Z","git_url":"git://github.com/ampproject/amphtml.git","ssh_url":"git@github.com:ampproject/amphtml.git","clone_url":"https://github.com/ampproject/amphtml.git","svn_url":"https://github.com/ampproject/amphtml","homepage":"https://www.ampproject.org","size":253885,"stargazers_count":10131,"watchers_count":10131,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":1751,"mirror_url":null,"open_issues_count":853,"forks":1751,"open_issues":853,"watchers":10131,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/9563"},"html":{"href":"https://github.com/ampproject/amphtml/pull/9563"},"issue":{"href":"https://api.github.com/repos/ampproject/amphtml/issues/9563"},"comments":{"href":"https://api.github.com/repos/ampproject/amphtml/issues/9563/comments"},"review_comments":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/9563/comments"},"review_comment":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ampproject/amphtml/pulls/9563/commits"},"statuses":{"href":"https://api.github.com/repos/ampproject/amphtml/statuses/a136616722aeb6443f699b3ea2628fc2cdc462d0"}}}}
{"actor":{"display_login":"keithwrightbos"}}