{"action":"created","comment":{"url":"https://api.github.com/repos/google/blockly/pulls/comments/61662195","id":61662195,"diff_hunk":"@@ -0,0 +1,234 @@\n+/**\n+ * Blockly Demos: AccessibleBlockly\n+ *\n+ * Copyright 2016 Google Inc.\n+ * https://developers.google.com/blockly/\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+/**\n+ * @fileoverview Angular2 Component that details how Blockly.Block's are rendered in the workspace in AccessibleBlockly. Also handles any interactions with the blocks.\n+ * @author madeeha@google.com (Madeeha Ghori)\n+ */\n+var blocklyApp = blocklyApp || {};\n+\n+blocklyApp.TreeView = ng.core\n+  .Component({\n+    selector: 'tree-view',\n+    template: `\n+<li #parentList aria-selected=false role='treeitem' class='blocklyHasChildren' [attr.aria-level]='level' id='{{setId(parentList)}}'>\n+  {{checkParentList(parentList)}}\n+  <label #blockSummary id='blockly-{{block.id}}'>{{block.toString()}}</label>\n+  {{setLabelledBy(parentList, concatStringWithSpaces('blockly-block-summary', blockSummary.id))}}\n+  <ol role='group'  [attr.aria-level]='level+1'>\n+    <li #listItem id='{{treeService.createId(listItem)}}' role='treeitem' aria-selected=false [attr.aria-level]='level+1'>\n+      {{setLabelledBy(listItem, concatStringWithSpaces('blockly-block-menu', blockSummary.id))}}\n+      <label #label id='{{treeService.createId(label)}}'>block action list </label>\n+      <ol role='group'  [attr.aria-level]='level+2'>\n+        <li #cutListItem id='{{treeService.createId(cutListItem)}}' role='treeitem' aria-selected=false [attr.aria-level]='level+2'>\n+          <button #cutButton id='{{treeService.createId(cutButton)}}' (click)='sharedClipboardService.cut(block)'>cut block</button>\n+          {{setLabelledBy(cutListItem, concatStringWithSpaces(cutButton.id, 'blockly-button'))}}\n+        </li>\n+        <li #copyListItem id='{{treeService.createId(copyListItem)}}' role='treeitem' aria-selected=false [attr.aria-level]='level+2'>\n+          <button #copyButton id='{{treeService.createId(copyButton)}}' (click)='sharedClipboardService.copy(block)'>copy block</button>\n+          {{setLabelledBy(copyListItem, concatStringWithSpaces(copyButton.id, 'blockly-button'))}}\n+        </li>\n+        <li #pasteBelow id='{{treeService.createId(pasteBelow)}}' role='treeitem' aria-selected=false [attr.aria-level]='level+2'>\n+          <button #pasteBelowButton id='{{treeService.createId(pasteBelowButton)}}' (click)='sharedClipboardService.paste(block.nextConnection)' disabled='{{hasNoNextConnection(block)}}' disabled='{{notCompatibleWithClipboard(block.nextConnection)}}'>paste below</button>\n+          {{setLabelledBy(pasteBelow, concatStringWithSpaces(pasteBelowButton.id, 'blockly-button', (hasNoNextConnection(block)||notCompatibleWithClipboard(block.nextConnection))))}}\n+        </li>\n+        <li #pasteAbove id='{{treeService.createId(pasteAbove)}}' role='treeitem' aria-selected=false [attr.aria-level]='level+2'>\n+          <button #pasteAboveButton id='{{treeService.createId(pasteAboveButton)}}' (click)='sharedClipboardService.paste(block.previousConnection)' disabled='{{hasNoPreviousConnection(block)}}' disabled='{{notCompatibleWithClipboard(block.previousConnection)}}'>paste above</button>\n+          {{setLabelledBy(pasteAbove, concatStringWithSpaces(pasteAboveButton.id, 'blockly-button', (hasNoPreviousConnection(block)||notCompatibleWithClipboard(block.previousConnection))))}}\n+        </li>\n+        <li #markBelow id='{{treeService.createId(markBelow)}}' role='treeitem' aria-selected=false [attr.aria-level]='level+2'>\n+          <button #markBelowButton id='{{treeService.createId(markBelowButton)}}' (click)='sharedClipboardService.markConnection(block.nextConnection)' disabled='{{hasNoNextConnection(block)}}'>mark spot below</button>\n+          {{setLabelledBy(markBelow, concatStringWithSpaces(markBelowButton.id, 'blockly-button', hasNoNextConnection(block)))}}\n+        </li>\n+        <li #markAbove id='{{treeService.createId(markAbove)}}' role='treeitem' aria-selected=false [attr.aria-level]='level+2'>\n+          <button #markAboveButton id='{{treeService.createId(markAboveButton)}}' (click)='sharedClipboardService.markConnection(block.previousConnection)' disabled='{{hasNoPreviousConnection(block)}}'>mark spot above</button>\n+          {{setLabelledBy(markAbove, concatStringWithSpaces(markAboveButton.id, 'blockly-button', hasNoPreviousConnection(block)))}}\n+        </li>\n+        <li #sendToSelected id='{{treeService.createId(sendToSelected)}}' role='treeitem' aria-selected=false [attr.aria-level]='level+2'>\n+          <button #sendToSelectedButton id='{{treeService.createId(sendToSelectedButton)}}' (click)='sendToSelected(block)' disabled='{{notCompatibleWithMarkedBlock(block)}}'>move to marked spot</button>\n+          {{setLabelledBy(sendToSelected, concatStringWithSpaces(sendToSelectedButton.id, 'blockly-button', notCompatibleWithMarkedBlock(block)))}}\n+        </li>\n+        <li #delete id='{{treeService.createId(delete)}}' role='treeitem' aria-selected=false [attr.aria-level]='level+2'>\n+          <button #deleteButton id='{{treeService.createId(deleteButton)}}' (click)='block.dispose(true)'>delete button</button>\n+        </li>\n+      </ol>\n+      {{addClass(listItem, 'blocklyHasChildren')}}\n+    </li>\n+    <div *ngFor='#inputBlock of block.inputList'>\n+      <field-view *ngFor='#field of getInfo(inputBlock)' [field]='field'></field-view>\n+      <tree-view *ngIf='inputBlock.connection && inputBlock.connection.targetBlock()' [block]='inputBlock.connection.targetBlock()' [isTopBlock]='false' [level]='level'></tree-view>\n+      <li #inputList [attr.aria-level]='level+1' id='{{treeService.createId(inputList)}}' *ngIf='inputBlock.connection && !inputBlock.connection.targetBlock()' (keydown)='treeService.keyHandler($event, tree)'>\n+        {{inputType(inputBlock.connection)}} {{valueOrStatement(inputBlock)}} needed:\n+        <select aria-label='insert input menu' (change)='inputMenuSelected(inputBlock.connection, $event)'>\n+          <option value='NO_ACTION' selected>select an action</option>\n+          <option value='MARK_SPOT'>mark this spot</option>\n+          <option value='PASTE' disabled='{{notCompatibleWithClipboard(inputBlock.connection)}}'>paste</option>\n+        </select>\n+      </li>\n+    </div>\n+  </ol>\n+</li>\n+  <tree-view *ngIf= 'block.nextConnection && block.nextConnection.targetBlock()' [block]='block.nextConnection.targetBlock()' [isTopBlock]='false' [level]='level'></tree-view>\n+\n+    `,\n+    directives: [ng.core.forwardRef(\n+        function() { return blocklyApp.TreeView; }), blocklyApp.FieldView],\n+    inputs: ['block', 'isTopBlock', 'topBlockIndex', 'level', 'parentId'],\n+  })\n+  .Class({\n+    constructor: [blocklyApp.ClipboardService, blocklyApp.TreeService, function(_service, _service2) {\n+      this.infoBlocks = {};\n+      this.nextBlock = {};\n+      this.sharedClipboardService = _service;\n+      this.treeService = _service2;\n+    }],\n+    setLabelledBy: function(item,string){\n+      if (!item.getAttribute('aria-labelledby')) {\n+        item.setAttribute('aria-labelledby', string);\n+      }\n+    },\n+    concatStringWithSpaces: function(){\n+      var string = arguments[0];\n+      for (i = 1; i < arguments.length; i++) {\n+        string = string + ' ' + arguments[i];\n+      }\n+      return string;\n+    },\n+    hasNoPreviousConnection: function(block){\n+      if (!block.previousConnection){\n+        return 'blockly-disabled';\n+      } else {\n+        return undefined;\n+      }\n+    },\n+    hasNoNextConnection: function(block){\n+      if (!block.nextConnection){\n+        return 'blockly-disabled';\n+      } else {\n+        return undefined;\n+      }\n+    },\n+    checkParentList: function(parentList) {\n+      console.log('setting parent list');\n+      var tree = parentList;\n+      while (tree && !tree.id.match(/^blockly-workspace-tree\\d+$/)) {\n+        tree = tree.parentNode;\n+      }\n+      if (tree && tree.getAttribute('aria-activedescendant') == parentList.id){\n+        this.treeService.updateSelectedNode(parentList, tree, false);\n+      }\n+    },\n+    addClass: function(node, classText) {\n+      //ensure that node doesn't have class already in it\n+      var classList = node.className;\n+      classList = classList.split(' ');\n+      var canAdd = true;\n+      for (var i=0; i<classList.length; i++){\n+        if (classList[i] == classText) {\n+          canAdd = false;\n+        }\n+      }\n+      //add class if it doesn't\n+      if (canAdd) {\n+        if (classList.length == 0) {\n+          node.className += classText;\n+        } else {\n+          node.className += (' ' + classText);\n+        }\n+      }\n+    },\n+    setId: function(block){\n+      if (this.isTopBlock){\n+        return this.parentId+'-node0';\n+      }\n+      return this.treeService.createId(block);\n+    },\n+    getInfo: function(block) {\n+      //List all inputs\n+      if (this.infoBlocks[block.id]) {\n+        //TODO(madeeha): is there a situation in which overwriting often unnecessarily is a problem?\n+        this.infoBlocks[block.id].length = 0;\n+      } else {\n+        this.infoBlocks[block.id] = [];\n+      }\n+\n+      var blockInfoList = this.infoBlocks[block.id];\n+\n+      for (var j = 0, field; field = block.fieldRow[j]; j++) {\n+        blockInfoList.push(field);\n+      }\n+\n+      return this.infoBlocks[block.id];\n+    },\n+    inputType: function(connection) {\n+      if (connection.check_) {\n+        return connection.check_.join(', ').toUpperCase();\n+      } else {\n+        return 'any';\n+      }\n+    },\n+    sendToSelected: function(block){\n+      if (this.sharedClipboardService) {\n+        this.sharedClipboardService.pasteToMarkedConnection(block);\n+        block.dispose(true);\n+        alert('block sent to marked spot');\n+      }\n+    },\n+    inputMenuSelected: function(connection, event) {\n+      switch (event.target.value) {\n+        case 'MARK_SPOT':\n+          this.sharedClipboardService.markConnection(connection);\n+          console.log('marked spot');\n+          break;\n+        case 'PASTE':\n+          this.sharedClipboardService.paste(connection);\n+          break;\n+      }\n+      event.target.selectedIndex = 0;\n+    },\n+    notCompatibleWithClipboard: function(connection) {","path":"accessible/workspace_treeview.component.js","position":205,"original_position":205,"commit_id":"0170fbef91cbcc4b84912dc614970256564e8e68","original_commit_id":"0170fbef91cbcc4b84912dc614970256564e8e68","user":{"login":"seanlip","id":10575562,"avatar_url":"https://avatars.githubusercontent.com/u/10575562?v=3","gravatar_id":"","url":"https://api.github.com/users/seanlip","html_url":"https://github.com/seanlip","followers_url":"https://api.github.com/users/seanlip/followers","following_url":"https://api.github.com/users/seanlip/following{/other_user}","gists_url":"https://api.github.com/users/seanlip/gists{/gist_id}","starred_url":"https://api.github.com/users/seanlip/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/seanlip/subscriptions","organizations_url":"https://api.github.com/users/seanlip/orgs","repos_url":"https://api.github.com/users/seanlip/repos","events_url":"https://api.github.com/users/seanlip/events{/privacy}","received_events_url":"https://api.github.com/users/seanlip/received_events","type":"User","site_admin":false},"body":"Also (just making a guess based on the other stuff you wrote), it sounds like you want the name of this function to be something like getLabelForClipboardButton or something like that? What I mean is that the function name should reflect what you're actually doing/returning.","created_at":"2016-04-30T01:19:13Z","updated_at":"2016-04-30T01:19:13Z","html_url":"https://github.com/google/blockly/pull/354#discussion_r61662195","pull_request_url":"https://api.github.com/repos/google/blockly/pulls/354","_links":{"self":{"href":"https://api.github.com/repos/google/blockly/pulls/comments/61662195"},"html":{"href":"https://github.com/google/blockly/pull/354#discussion_r61662195"},"pull_request":{"href":"https://api.github.com/repos/google/blockly/pulls/354"}}},"pull_request":{"url":"https://api.github.com/repos/google/blockly/pulls/354","id":68438554,"html_url":"https://github.com/google/blockly/pull/354","diff_url":"https://github.com/google/blockly/pull/354.diff","patch_url":"https://github.com/google/blockly/pull/354.patch","issue_url":"https://api.github.com/repos/google/blockly/issues/354","number":354,"state":"open","locked":false,"title":"AccessibleBlockly","user":{"login":"madCode","id":2229305,"avatar_url":"https://avatars.githubusercontent.com/u/2229305?v=3","gravatar_id":"","url":"https://api.github.com/users/madCode","html_url":"https://github.com/madCode","followers_url":"https://api.github.com/users/madCode/followers","following_url":"https://api.github.com/users/madCode/following{/other_user}","gists_url":"https://api.github.com/users/madCode/gists{/gist_id}","starred_url":"https://api.github.com/users/madCode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/madCode/subscriptions","organizations_url":"https://api.github.com/users/madCode/orgs","repos_url":"https://api.github.com/users/madCode/repos","events_url":"https://api.github.com/users/madCode/events{/privacy}","received_events_url":"https://api.github.com/users/madCode/received_events","type":"User","site_admin":false},"body":"AccessibleBlockly is an alternative web UI for developers that is supports keyboard navigation. If the user is blind, AccessibleBlockly is best experienced in conjunction with NVDA or Jaws on Firefox on Windows.","created_at":"2016-04-29T21:45:54Z","updated_at":"2016-04-30T01:19:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"32d43a40667c980ce8c1258027a3a6a72f04008b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/google/blockly/pulls/354/commits","review_comments_url":"https://api.github.com/repos/google/blockly/pulls/354/comments","review_comment_url":"https://api.github.com/repos/google/blockly/pulls/comments{/number}","comments_url":"https://api.github.com/repos/google/blockly/issues/354/comments","statuses_url":"https://api.github.com/repos/google/blockly/statuses/0170fbef91cbcc4b84912dc614970256564e8e68","head":{"label":"madCode:rebase-blind","ref":"rebase-blind","sha":"0170fbef91cbcc4b84912dc614970256564e8e68","user":{"login":"madCode","id":2229305,"avatar_url":"https://avatars.githubusercontent.com/u/2229305?v=3","gravatar_id":"","url":"https://api.github.com/users/madCode","html_url":"https://github.com/madCode","followers_url":"https://api.github.com/users/madCode/followers","following_url":"https://api.github.com/users/madCode/following{/other_user}","gists_url":"https://api.github.com/users/madCode/gists{/gist_id}","starred_url":"https://api.github.com/users/madCode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/madCode/subscriptions","organizations_url":"https://api.github.com/users/madCode/orgs","repos_url":"https://api.github.com/users/madCode/repos","events_url":"https://api.github.com/users/madCode/events{/privacy}","received_events_url":"https://api.github.com/users/madCode/received_events","type":"User","site_admin":false},"repo":{"id":53075895,"name":"blockly","full_name":"madCode/blockly","owner":{"login":"madCode","id":2229305,"avatar_url":"https://avatars.githubusercontent.com/u/2229305?v=3","gravatar_id":"","url":"https://api.github.com/users/madCode","html_url":"https://github.com/madCode","followers_url":"https://api.github.com/users/madCode/followers","following_url":"https://api.github.com/users/madCode/following{/other_user}","gists_url":"https://api.github.com/users/madCode/gists{/gist_id}","starred_url":"https://api.github.com/users/madCode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/madCode/subscriptions","organizations_url":"https://api.github.com/users/madCode/orgs","repos_url":"https://api.github.com/users/madCode/repos","events_url":"https://api.github.com/users/madCode/events{/privacy}","received_events_url":"https://api.github.com/users/madCode/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/madCode/blockly","description":"The web-based visual programming editor.","fork":true,"url":"https://api.github.com/repos/madCode/blockly","forks_url":"https://api.github.com/repos/madCode/blockly/forks","keys_url":"https://api.github.com/repos/madCode/blockly/keys{/key_id}","collaborators_url":"https://api.github.com/repos/madCode/blockly/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/madCode/blockly/teams","hooks_url":"https://api.github.com/repos/madCode/blockly/hooks","issue_events_url":"https://api.github.com/repos/madCode/blockly/issues/events{/number}","events_url":"https://api.github.com/repos/madCode/blockly/events","assignees_url":"https://api.github.com/repos/madCode/blockly/assignees{/user}","branches_url":"https://api.github.com/repos/madCode/blockly/branches{/branch}","tags_url":"https://api.github.com/repos/madCode/blockly/tags","blobs_url":"https://api.github.com/repos/madCode/blockly/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/madCode/blockly/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/madCode/blockly/git/refs{/sha}","trees_url":"https://api.github.com/repos/madCode/blockly/git/trees{/sha}","statuses_url":"https://api.github.com/repos/madCode/blockly/statuses/{sha}","languages_url":"https://api.github.com/repos/madCode/blockly/languages","stargazers_url":"https://api.github.com/repos/madCode/blockly/stargazers","contributors_url":"https://api.github.com/repos/madCode/blockly/contributors","subscribers_url":"https://api.github.com/repos/madCode/blockly/subscribers","subscription_url":"https://api.github.com/repos/madCode/blockly/subscription","commits_url":"https://api.github.com/repos/madCode/blockly/commits{/sha}","git_commits_url":"https://api.github.com/repos/madCode/blockly/git/commits{/sha}","comments_url":"https://api.github.com/repos/madCode/blockly/comments{/number}","issue_comment_url":"https://api.github.com/repos/madCode/blockly/issues/comments{/number}","contents_url":"https://api.github.com/repos/madCode/blockly/contents/{+path}","compare_url":"https://api.github.com/repos/madCode/blockly/compare/{base}...{head}","merges_url":"https://api.github.com/repos/madCode/blockly/merges","archive_url":"https://api.github.com/repos/madCode/blockly/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/madCode/blockly/downloads","issues_url":"https://api.github.com/repos/madCode/blockly/issues{/number}","pulls_url":"https://api.github.com/repos/madCode/blockly/pulls{/number}","milestones_url":"https://api.github.com/repos/madCode/blockly/milestones{/number}","notifications_url":"https://api.github.com/repos/madCode/blockly/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/madCode/blockly/labels{/name}","releases_url":"https://api.github.com/repos/madCode/blockly/releases{/id}","deployments_url":"https://api.github.com/repos/madCode/blockly/deployments","created_at":"2016-03-03T19:09:31Z","updated_at":"2016-03-19T05:32:02Z","pushed_at":"2016-04-29T21:41:24Z","git_url":"git://github.com/madCode/blockly.git","ssh_url":"git@github.com:madCode/blockly.git","clone_url":"https://github.com/madCode/blockly.git","svn_url":"https://github.com/madCode/blockly","homepage":"https://developers.google.com/blockly/","size":73445,"stargazers_count":1,"watchers_count":1,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"google:develop","ref":"develop","sha":"6c0bf9f9662615cded68f1ae587042f20934694a","user":{"login":"google","id":1342004,"avatar_url":"https://avatars.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":13872231,"name":"blockly","full_name":"google/blockly","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars.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/blockly","description":"The web-based visual programming editor.","fork":false,"url":"https://api.github.com/repos/google/blockly","forks_url":"https://api.github.com/repos/google/blockly/forks","keys_url":"https://api.github.com/repos/google/blockly/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/blockly/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/blockly/teams","hooks_url":"https://api.github.com/repos/google/blockly/hooks","issue_events_url":"https://api.github.com/repos/google/blockly/issues/events{/number}","events_url":"https://api.github.com/repos/google/blockly/events","assignees_url":"https://api.github.com/repos/google/blockly/assignees{/user}","branches_url":"https://api.github.com/repos/google/blockly/branches{/branch}","tags_url":"https://api.github.com/repos/google/blockly/tags","blobs_url":"https://api.github.com/repos/google/blockly/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/blockly/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/blockly/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/blockly/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/blockly/statuses/{sha}","languages_url":"https://api.github.com/repos/google/blockly/languages","stargazers_url":"https://api.github.com/repos/google/blockly/stargazers","contributors_url":"https://api.github.com/repos/google/blockly/contributors","subscribers_url":"https://api.github.com/repos/google/blockly/subscribers","subscription_url":"https://api.github.com/repos/google/blockly/subscription","commits_url":"https://api.github.com/repos/google/blockly/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/blockly/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/blockly/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/blockly/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/blockly/contents/{+path}","compare_url":"https://api.github.com/repos/google/blockly/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/blockly/merges","archive_url":"https://api.github.com/repos/google/blockly/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/blockly/downloads","issues_url":"https://api.github.com/repos/google/blockly/issues{/number}","pulls_url":"https://api.github.com/repos/google/blockly/pulls{/number}","milestones_url":"https://api.github.com/repos/google/blockly/milestones{/number}","notifications_url":"https://api.github.com/repos/google/blockly/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/blockly/labels{/name}","releases_url":"https://api.github.com/repos/google/blockly/releases{/id}","deployments_url":"https://api.github.com/repos/google/blockly/deployments","created_at":"2013-10-25T21:13:33Z","updated_at":"2016-04-29T21:53:10Z","pushed_at":"2016-04-29T21:45:54Z","git_url":"git://github.com/google/blockly.git","ssh_url":"git@github.com:google/blockly.git","clone_url":"https://github.com/google/blockly.git","svn_url":"https://github.com/google/blockly","homepage":"https://developers.google.com/blockly/","size":97726,"stargazers_count":2238,"watchers_count":2238,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":728,"mirror_url":null,"open_issues_count":87,"forks":728,"open_issues":87,"watchers":2238,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/google/blockly/pulls/354"},"html":{"href":"https://github.com/google/blockly/pull/354"},"issue":{"href":"https://api.github.com/repos/google/blockly/issues/354"},"comments":{"href":"https://api.github.com/repos/google/blockly/issues/354/comments"},"review_comments":{"href":"https://api.github.com/repos/google/blockly/pulls/354/comments"},"review_comment":{"href":"https://api.github.com/repos/google/blockly/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/google/blockly/pulls/354/commits"},"statuses":{"href":"https://api.github.com/repos/google/blockly/statuses/0170fbef91cbcc4b84912dc614970256564e8e68"}}}}