{"action":"created","comment":{"url":"https://api.github.com/repos/aframevr/aframe/pulls/comments/92327474","pull_request_review_id":12839987,"id":92327474,"diff_hunk":"@@ -0,0 +1,259 @@\n+var registerComponent = require('../core/component').registerComponent;\n+var bind = require('../utils/bind');\n+var isControllerPresent = require('../utils/tracked-controls').isControllerPresent;\n+\n+var TOUCH_CONTROLLER_MODEL_BASE_URL = 'https://cdn.aframe.io/controllers/oculus/oculus-touch-controller-';\n+var TOUCH_CONTROLLER_MODEL_OBJ_URL_L = TOUCH_CONTROLLER_MODEL_BASE_URL + 'left.obj';\n+var TOUCH_CONTROLLER_MODEL_OBJ_MTL_L = TOUCH_CONTROLLER_MODEL_BASE_URL + 'left.mtl';\n+var TOUCH_CONTROLLER_MODEL_OBJ_URL_R = TOUCH_CONTROLLER_MODEL_BASE_URL + 'right.obj';\n+var TOUCH_CONTROLLER_MODEL_OBJ_MTL_R = TOUCH_CONTROLLER_MODEL_BASE_URL + 'right.mtl';\n+\n+var GAMEPAD_ID_PREFIX = 'Oculus Touch';\n+\n+var FAKE_TOUCH_THRESHOLD = 0.00001;\n+\n+/**\n+ * Oculus Touch Controls Component\n+ * Interfaces with Oculus Touch controllers and maps Gamepad events to\n+ * common controller buttons: trackpad, trigger, grip, menu and system\n+ * It loads a controller model and highlights the pressed buttons\n+ */\n+module.exports.Component = registerComponent('oculus-touch-controls', {\n+  schema: {\n+    hand: {default: 'left'},\n+    buttonColor: { default: '#FAFAFA' },  // Off-white.\n+    buttonHighlightColor: {default: '#22D1EE'},  // Light blue.\n+    model: {default: true},\n+    rotationOffset: {default: 0} // no default offset; -999 is sentinel value to auto-determine based on hand\n+  },\n+\n+  // buttonId\n+  // 0 - thumbstick\n+  // 1 - trigger ( intensity value from 0.5 to 1 )\n+  // 2 - grip\n+  // 3 - menu ( dispatch but better for menu options )\n+  // 4 - system ( never dispatched on this layer )\n+  mapping: {\n+    'left': {\n+      axis0: 'thumbstick',\n+      axis1: 'thumbstick',\n+      button0: 'thumbstick',\n+      button1: 'trigger',\n+      button2: 'grip',\n+      button3: 'X',\n+      button4: ['Y', 'menu'],\n+      button5: 'surface'\n+    },\n+    'right': {\n+      axis0: 'thumbstick',\n+      axis1: 'thumbstick',\n+      button0: 'thumbstick',\n+      button1: 'trigger',\n+      button2: 'grip',\n+      button3: 'A',\n+      button4: ['B', 'menu'],\n+      button5: 'surface'\n+    }\n+  },\n+\n+  bindMethods: function () {\n+    this.onModelLoaded = bind(this.onModelLoaded, this);\n+    this.onControllersUpdate = bind(this.onControllersUpdate, this);\n+    this.checkIfControllerPresent = bind(this.checkIfControllerPresent, this);\n+    this.removeControllersUpdateListener = bind(this.removeControllersUpdateListener, this);\n+    this.onGamepadConnected = bind(this.onGamepadConnected, this);\n+    this.onGamepadDisconnected = bind(this.onGamepadDisconnected, this);\n+  },\n+\n+  init: function () {\n+    var self = this;\n+    this.animationActive = 'pointing';\n+    this.onButtonChanged = bind(this.onButtonChanged, this);\n+    this.onButtonDown = function (evt) { self.onButtonEvent(evt.detail.id, 'down'); };\n+    this.onButtonUp = function (evt) { self.onButtonEvent(evt.detail.id, 'up'); };\n+    this.onButtonTouchStart = function (evt) { self.onButtonEvent(evt.detail.id, 'touchstart'); };\n+    this.onButtonTouchEnd = function (evt) { self.onButtonEvent(evt.detail.id, 'touchend'); };\n+    this.controllerPresent = false;\n+    this.everGotGamepadEvent = false;\n+    this.lastControllerCheck = 0;\n+    this.previousButtonValues = {};\n+    this.bindMethods();\n+  },\n+\n+  addEventListeners: function () {\n+    var el = this.el;\n+    el.addEventListener('buttonchanged', this.onButtonChanged);\n+    el.addEventListener('buttondown', this.onButtonDown);\n+    el.addEventListener('buttonup', this.onButtonUp);\n+    el.addEventListener('touchstart', this.onButtonTouchStart);\n+    el.addEventListener('touchend', this.onButtonTouchEnd);\n+    el.addEventListener('model-loaded', this.onModelLoaded);\n+  },\n+\n+  removeEventListeners: function () {\n+    var el = this.el;\n+    el.removeEventListener('buttonchanged', this.onButtonChanged);\n+    el.removeEventListener('buttondown', this.onButtonDown);\n+    el.removeEventListener('buttonup', this.onButtonUp);\n+    el.removeEventListener('touchstart', this.onButtonTouchStart);\n+    el.removeEventListener('touchend', this.onButtonTouchEnd);\n+    el.removeEventListener('model-loaded', this.onModelLoaded);\n+  },\n+\n+  checkIfControllerPresent: function () {\n+    var data = this.data;\n+    var isPresent = isControllerPresent(GAMEPAD_ID_PREFIX, { hand: data.hand });\n+    if (isPresent === this.controllerPresent) { return; }\n+    this.controllerPresent = isPresent;\n+    if (isPresent) {\n+      this.injectTrackedControls(); // inject track-controls\n+      this.addEventListeners();\n+    } else {\n+      this.removeEventListeners();\n+    }\n+  },\n+\n+  onGamepadConnected: function (evt) {\n+    this.everGotGamepadEvent = true;\n+    this.removeControllersUpdateListener();\n+    this.checkIfControllerPresent();\n+  },\n+\n+  onGamepadDisconnected: function (evt) {\n+    this.everGotGamepadEvent = true;\n+    this.removeControllersUpdateListener();\n+    this.checkIfControllerPresent();\n+  },\n+\n+  play: function () {\n+    this.checkIfControllerPresent();\n+    window.addEventListener('gamepadconnected', this.onGamepadConnected, false);\n+    window.addEventListener('gamepaddisconnected', this.onGamepadDisconnected, false);\n+    this.addControllersUpdateListener();\n+  },\n+\n+  pause: function () {\n+    window.removeEventListener('gamepadconnected', this.onGamepadConnected, false);\n+    window.removeEventListener('gamepaddisconnected', this.onGamepadDisconnected, false);\n+    this.removeControllersUpdateListener();\n+    this.removeEventListeners();\n+  },\n+\n+  updateModel: function () {\n+    var objUrl, mtlUrl;\n+    if (!this.data.model) { return; }\n+    if (this.data.hand === 'right') {\n+      objUrl = 'url(' + TOUCH_CONTROLLER_MODEL_OBJ_URL_R + ')';\n+      mtlUrl = 'url(' + TOUCH_CONTROLLER_MODEL_OBJ_MTL_R + ')';\n+    } else {\n+      objUrl = 'url(' + TOUCH_CONTROLLER_MODEL_OBJ_URL_L + ')';\n+      mtlUrl = 'url(' + TOUCH_CONTROLLER_MODEL_OBJ_MTL_L + ')';\n+    }\n+    this.el.setAttribute('obj-model', {obj: objUrl, mtl: mtlUrl});\n+  },\n+\n+  injectTrackedControls: function () {\n+    var el = this.el;\n+    var data = this.data;\n+    var isRightHand = data.hand === 'right';\n+\n+    // since each hand is named differently, avoid enumeration\n+    el.setAttribute('tracked-controls', {\n+      id: isRightHand ? 'Oculus Touch (Right)' : 'Oculus Touch (Left)',\n+      controller: 0,\n+      rotationOffset: data.rotationOffset !== -999 ? data.rotationOffset : isRightHand ? -90 : 90\n+    });\n+\n+    this.updateModel();\n+  },\n+\n+  addControllersUpdateListener: function () {\n+    this.el.sceneEl.addEventListener('controllersupdate', this.onControllersUpdate, false);\n+  },\n+\n+  removeControllersUpdateListener: function () {\n+    this.el.sceneEl.removeEventListener('controllersupdate', this.onControllersUpdate, false);\n+  },\n+\n+  onControllersUpdate: function () {\n+    if (!this.everGotGamepadEvent) { this.checkIfControllerPresent(); }\n+  },\n+\n+  onButtonChanged: function (evt) {\n+    var button = this.mapping[this.data.hand]['button' + evt.detail.id];\n+    var buttonMeshes = this.buttonMeshes;\n+    var value;\n+    // at the moment, if trigger or grip,\n+    // touch events aren't happening (touched is stuck true);\n+    // synthesize touch events from very low values\n+    if (button === 'trigger' || button === 'grip') {\n+      var lastValue = this.previousButtonValues[button];\n+      var lastFakeTouch = false;\n+      if (lastValue) { lastFakeTouch = (lastValue >= FAKE_TOUCH_THRESHOLD); }\n+      var thisValue = evt.detail.state.value;\n+      var thisFakeTouch = false;\n+      if (thisValue) { thisFakeTouch = (thisValue >= FAKE_TOUCH_THRESHOLD); }\n+      this.previousButtonValues[button] = thisValue;\n+      if (thisFakeTouch !== lastFakeTouch) {\n+        if (thisFakeTouch) {\n+          this.onButtonTouchStart(evt);\n+        } else {\n+          this.onButtonTouchEnd(evt);\n+        }\n+      }\n+    }\n+    if (typeof button === 'undefined' || typeof buttonMeshes === 'undefined') { return; }\n+    if (button !== 'trigger' || !buttonMeshes || !buttonMeshes.trigger) { return; }\n+    value = evt.detail.state.value;\n+    buttonMeshes.trigger.rotation.x = -value * (Math.PI / 12);\n+  },\n+\n+  onModelLoaded: function (evt) {\n+    var controllerObject3D = evt.detail.model;\n+    var buttonMeshes;\n+    if (!this.data.model) { return; }\n+\n+    var leftHand = this.data.hand === 'left';\n+    buttonMeshes = this.buttonMeshes = {};\n+\n+    buttonMeshes.grip = controllerObject3D.getObjectByName(leftHand ? 'grip tooche1 group3' : 'grip tooche group4');\n+    buttonMeshes.thumbstick = controllerObject3D.getObjectByName(leftHand ? 'tooche1 group3 control_surface group2 thumb_stick' : 'tooche group4 control_surface group2 thumb_stick');\n+    buttonMeshes.trigger = controllerObject3D.getObjectByName(leftHand ? 'tooche1 group3 trigger' : 'tooche group4 trigger');\n+    buttonMeshes['X'] = controllerObject3D.getObjectByName('tooche1 group3 control_surface group2 button2');\n+    buttonMeshes['A'] = controllerObject3D.getObjectByName('tooche group4 control_surface group2 button2');\n+    buttonMeshes['Y'] = controllerObject3D.getObjectByName('tooche1 group3 control_surface group2 button3');\n+    buttonMeshes['B'] = controllerObject3D.getObjectByName('tooche group4 control_surface group2 button3');\n+    buttonMeshes.surface = controllerObject3D.getObjectByName(leftHand ? 'tooche1 group3 face control_surface group2' : 'tooche group4 face control_surface group2');\n+\n+    // Offset pivot point\n+    controllerObject3D.position.set(0, -0.015, 0.04);\n+  },\n+\n+  onButtonEvent: function (id, evtName) {\n+    var buttonName = this.mapping[this.data.hand]['button' + id];\n+    var i;\n+    if (Array.isArray(buttonName)) {\n+      for (i = 0; i < buttonName.length; i++) {\n+        this.el.emit(buttonName[i] + evtName);\n+      }\n+    } else {\n+      this.el.emit(buttonName + evtName);\n+    }\n+    if (Array.isArray(buttonName)) {","path":"src/components/oculus-touch-controls.js","position":242,"original_position":242,"commit_id":"92e394e1346bf4ba42367b93ab265651975863c3","original_commit_id":"92e394e1346bf4ba42367b93ab265651975863c3","user":{"login":"dmarcos","id":39342,"avatar_url":"https://avatars.githubusercontent.com/u/39342?v=3","gravatar_id":"","url":"https://api.github.com/users/dmarcos","html_url":"https://github.com/dmarcos","followers_url":"https://api.github.com/users/dmarcos/followers","following_url":"https://api.github.com/users/dmarcos/following{/other_user}","gists_url":"https://api.github.com/users/dmarcos/gists{/gist_id}","starred_url":"https://api.github.com/users/dmarcos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmarcos/subscriptions","organizations_url":"https://api.github.com/users/dmarcos/orgs","repos_url":"https://api.github.com/users/dmarcos/repos","events_url":"https://api.github.com/users/dmarcos/events{/privacy}","received_events_url":"https://api.github.com/users/dmarcos/received_events","type":"User","site_admin":false},"body":"Can we move this to an `updateModel` method?","created_at":"2016-12-14T06:06:09Z","updated_at":"2016-12-14T06:12:11Z","html_url":"https://github.com/aframevr/aframe/pull/2132#discussion_r92327474","pull_request_url":"https://api.github.com/repos/aframevr/aframe/pulls/2132","_links":{"self":{"href":"https://api.github.com/repos/aframevr/aframe/pulls/comments/92327474"},"html":{"href":"https://github.com/aframevr/aframe/pull/2132#discussion_r92327474"},"pull_request":{"href":"https://api.github.com/repos/aframevr/aframe/pulls/2132"}}},"pull_request":{"url":"https://api.github.com/repos/aframevr/aframe/pulls/2132","id":95053762,"html_url":"https://github.com/aframevr/aframe/pull/2132","diff_url":"https://github.com/aframevr/aframe/pull/2132.diff","patch_url":"https://github.com/aframevr/aframe/pull/2132.patch","issue_url":"https://api.github.com/repos/aframevr/aframe/issues/2132","number":2132,"state":"open","locked":false,"title":"Refactor hand controls","user":{"login":"machenmusik","id":2080738,"avatar_url":"https://avatars.githubusercontent.com/u/2080738?v=3","gravatar_id":"","url":"https://api.github.com/users/machenmusik","html_url":"https://github.com/machenmusik","followers_url":"https://api.github.com/users/machenmusik/followers","following_url":"https://api.github.com/users/machenmusik/following{/other_user}","gists_url":"https://api.github.com/users/machenmusik/gists{/gist_id}","starred_url":"https://api.github.com/users/machenmusik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/machenmusik/subscriptions","organizations_url":"https://api.github.com/users/machenmusik/orgs","repos_url":"https://api.github.com/users/machenmusik/repos","events_url":"https://api.github.com/users/machenmusik/events{/privacy}","received_events_url":"https://api.github.com/users/machenmusik/received_events","type":"User","site_admin":false},"body":"refactor hand-controls per discussion on https://github.com/aframevr/aframe/pull/2124","created_at":"2016-11-23T18:05:35Z","updated_at":"2016-12-14T06:12:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"877b40b682658396eaeeca014386988d20958edf","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/aframevr/aframe/pulls/2132/commits","review_comments_url":"https://api.github.com/repos/aframevr/aframe/pulls/2132/comments","review_comment_url":"https://api.github.com/repos/aframevr/aframe/pulls/comments{/number}","comments_url":"https://api.github.com/repos/aframevr/aframe/issues/2132/comments","statuses_url":"https://api.github.com/repos/aframevr/aframe/statuses/92e394e1346bf4ba42367b93ab265651975863c3","head":{"label":"chenzlabs:refactor-hand-controls","ref":"refactor-hand-controls","sha":"92e394e1346bf4ba42367b93ab265651975863c3","user":{"login":"chenzlabs","id":11540216,"avatar_url":"https://avatars.githubusercontent.com/u/11540216?v=3","gravatar_id":"","url":"https://api.github.com/users/chenzlabs","html_url":"https://github.com/chenzlabs","followers_url":"https://api.github.com/users/chenzlabs/followers","following_url":"https://api.github.com/users/chenzlabs/following{/other_user}","gists_url":"https://api.github.com/users/chenzlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/chenzlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chenzlabs/subscriptions","organizations_url":"https://api.github.com/users/chenzlabs/orgs","repos_url":"https://api.github.com/users/chenzlabs/repos","events_url":"https://api.github.com/users/chenzlabs/events{/privacy}","received_events_url":"https://api.github.com/users/chenzlabs/received_events","type":"Organization","site_admin":false},"repo":{"id":74418613,"name":"aframe","full_name":"chenzlabs/aframe","owner":{"login":"chenzlabs","id":11540216,"avatar_url":"https://avatars.githubusercontent.com/u/11540216?v=3","gravatar_id":"","url":"https://api.github.com/users/chenzlabs","html_url":"https://github.com/chenzlabs","followers_url":"https://api.github.com/users/chenzlabs/followers","following_url":"https://api.github.com/users/chenzlabs/following{/other_user}","gists_url":"https://api.github.com/users/chenzlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/chenzlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chenzlabs/subscriptions","organizations_url":"https://api.github.com/users/chenzlabs/orgs","repos_url":"https://api.github.com/users/chenzlabs/repos","events_url":"https://api.github.com/users/chenzlabs/events{/privacy}","received_events_url":"https://api.github.com/users/chenzlabs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/chenzlabs/aframe","description":"A web framework for building virtual reality experiences.","fork":true,"url":"https://api.github.com/repos/chenzlabs/aframe","forks_url":"https://api.github.com/repos/chenzlabs/aframe/forks","keys_url":"https://api.github.com/repos/chenzlabs/aframe/keys{/key_id}","collaborators_url":"https://api.github.com/repos/chenzlabs/aframe/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/chenzlabs/aframe/teams","hooks_url":"https://api.github.com/repos/chenzlabs/aframe/hooks","issue_events_url":"https://api.github.com/repos/chenzlabs/aframe/issues/events{/number}","events_url":"https://api.github.com/repos/chenzlabs/aframe/events","assignees_url":"https://api.github.com/repos/chenzlabs/aframe/assignees{/user}","branches_url":"https://api.github.com/repos/chenzlabs/aframe/branches{/branch}","tags_url":"https://api.github.com/repos/chenzlabs/aframe/tags","blobs_url":"https://api.github.com/repos/chenzlabs/aframe/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/chenzlabs/aframe/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/chenzlabs/aframe/git/refs{/sha}","trees_url":"https://api.github.com/repos/chenzlabs/aframe/git/trees{/sha}","statuses_url":"https://api.github.com/repos/chenzlabs/aframe/statuses/{sha}","languages_url":"https://api.github.com/repos/chenzlabs/aframe/languages","stargazers_url":"https://api.github.com/repos/chenzlabs/aframe/stargazers","contributors_url":"https://api.github.com/repos/chenzlabs/aframe/contributors","subscribers_url":"https://api.github.com/repos/chenzlabs/aframe/subscribers","subscription_url":"https://api.github.com/repos/chenzlabs/aframe/subscription","commits_url":"https://api.github.com/repos/chenzlabs/aframe/commits{/sha}","git_commits_url":"https://api.github.com/repos/chenzlabs/aframe/git/commits{/sha}","comments_url":"https://api.github.com/repos/chenzlabs/aframe/comments{/number}","issue_comment_url":"https://api.github.com/repos/chenzlabs/aframe/issues/comments{/number}","contents_url":"https://api.github.com/repos/chenzlabs/aframe/contents/{+path}","compare_url":"https://api.github.com/repos/chenzlabs/aframe/compare/{base}...{head}","merges_url":"https://api.github.com/repos/chenzlabs/aframe/merges","archive_url":"https://api.github.com/repos/chenzlabs/aframe/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/chenzlabs/aframe/downloads","issues_url":"https://api.github.com/repos/chenzlabs/aframe/issues{/number}","pulls_url":"https://api.github.com/repos/chenzlabs/aframe/pulls{/number}","milestones_url":"https://api.github.com/repos/chenzlabs/aframe/milestones{/number}","notifications_url":"https://api.github.com/repos/chenzlabs/aframe/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/chenzlabs/aframe/labels{/name}","releases_url":"https://api.github.com/repos/chenzlabs/aframe/releases{/id}","deployments_url":"https://api.github.com/repos/chenzlabs/aframe/deployments","created_at":"2016-11-22T00:35:28Z","updated_at":"2016-11-22T00:35:29Z","pushed_at":"2016-12-14T05:04:15Z","git_url":"git://github.com/chenzlabs/aframe.git","ssh_url":"git@github.com:chenzlabs/aframe.git","clone_url":"https://github.com/chenzlabs/aframe.git","svn_url":"https://github.com/chenzlabs/aframe","homepage":"https://aframe.io/","size":144814,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"aframevr:master","ref":"master","sha":"e19a72396f6df69b9bb11a33d9906ac8bdd0c48c","user":{"login":"aframevr","id":16024092,"avatar_url":"https://avatars.githubusercontent.com/u/16024092?v=3","gravatar_id":"","url":"https://api.github.com/users/aframevr","html_url":"https://github.com/aframevr","followers_url":"https://api.github.com/users/aframevr/followers","following_url":"https://api.github.com/users/aframevr/following{/other_user}","gists_url":"https://api.github.com/users/aframevr/gists{/gist_id}","starred_url":"https://api.github.com/users/aframevr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aframevr/subscriptions","organizations_url":"https://api.github.com/users/aframevr/orgs","repos_url":"https://api.github.com/users/aframevr/repos","events_url":"https://api.github.com/users/aframevr/events{/privacy}","received_events_url":"https://api.github.com/users/aframevr/received_events","type":"Organization","site_admin":false},"repo":{"id":42488903,"name":"aframe","full_name":"aframevr/aframe","owner":{"login":"aframevr","id":16024092,"avatar_url":"https://avatars.githubusercontent.com/u/16024092?v=3","gravatar_id":"","url":"https://api.github.com/users/aframevr","html_url":"https://github.com/aframevr","followers_url":"https://api.github.com/users/aframevr/followers","following_url":"https://api.github.com/users/aframevr/following{/other_user}","gists_url":"https://api.github.com/users/aframevr/gists{/gist_id}","starred_url":"https://api.github.com/users/aframevr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aframevr/subscriptions","organizations_url":"https://api.github.com/users/aframevr/orgs","repos_url":"https://api.github.com/users/aframevr/repos","events_url":"https://api.github.com/users/aframevr/events{/privacy}","received_events_url":"https://api.github.com/users/aframevr/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/aframevr/aframe","description":"A web framework for building virtual reality experiences.","fork":false,"url":"https://api.github.com/repos/aframevr/aframe","forks_url":"https://api.github.com/repos/aframevr/aframe/forks","keys_url":"https://api.github.com/repos/aframevr/aframe/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aframevr/aframe/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aframevr/aframe/teams","hooks_url":"https://api.github.com/repos/aframevr/aframe/hooks","issue_events_url":"https://api.github.com/repos/aframevr/aframe/issues/events{/number}","events_url":"https://api.github.com/repos/aframevr/aframe/events","assignees_url":"https://api.github.com/repos/aframevr/aframe/assignees{/user}","branches_url":"https://api.github.com/repos/aframevr/aframe/branches{/branch}","tags_url":"https://api.github.com/repos/aframevr/aframe/tags","blobs_url":"https://api.github.com/repos/aframevr/aframe/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aframevr/aframe/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aframevr/aframe/git/refs{/sha}","trees_url":"https://api.github.com/repos/aframevr/aframe/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aframevr/aframe/statuses/{sha}","languages_url":"https://api.github.com/repos/aframevr/aframe/languages","stargazers_url":"https://api.github.com/repos/aframevr/aframe/stargazers","contributors_url":"https://api.github.com/repos/aframevr/aframe/contributors","subscribers_url":"https://api.github.com/repos/aframevr/aframe/subscribers","subscription_url":"https://api.github.com/repos/aframevr/aframe/subscription","commits_url":"https://api.github.com/repos/aframevr/aframe/commits{/sha}","git_commits_url":"https://api.github.com/repos/aframevr/aframe/git/commits{/sha}","comments_url":"https://api.github.com/repos/aframevr/aframe/comments{/number}","issue_comment_url":"https://api.github.com/repos/aframevr/aframe/issues/comments{/number}","contents_url":"https://api.github.com/repos/aframevr/aframe/contents/{+path}","compare_url":"https://api.github.com/repos/aframevr/aframe/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aframevr/aframe/merges","archive_url":"https://api.github.com/repos/aframevr/aframe/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aframevr/aframe/downloads","issues_url":"https://api.github.com/repos/aframevr/aframe/issues{/number}","pulls_url":"https://api.github.com/repos/aframevr/aframe/pulls{/number}","milestones_url":"https://api.github.com/repos/aframevr/aframe/milestones{/number}","notifications_url":"https://api.github.com/repos/aframevr/aframe/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aframevr/aframe/labels{/name}","releases_url":"https://api.github.com/repos/aframevr/aframe/releases{/id}","deployments_url":"https://api.github.com/repos/aframevr/aframe/deployments","created_at":"2015-09-15T02:04:40Z","updated_at":"2016-12-14T06:07:07Z","pushed_at":"2016-12-14T05:00:44Z","git_url":"git://github.com/aframevr/aframe.git","ssh_url":"git@github.com:aframevr/aframe.git","clone_url":"https://github.com/aframevr/aframe.git","svn_url":"https://github.com/aframevr/aframe","homepage":"https://aframe.io/","size":139783,"stargazers_count":4171,"watchers_count":4171,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":831,"mirror_url":null,"open_issues_count":230,"forks":831,"open_issues":230,"watchers":4171,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/aframevr/aframe/pulls/2132"},"html":{"href":"https://github.com/aframevr/aframe/pull/2132"},"issue":{"href":"https://api.github.com/repos/aframevr/aframe/issues/2132"},"comments":{"href":"https://api.github.com/repos/aframevr/aframe/issues/2132/comments"},"review_comments":{"href":"https://api.github.com/repos/aframevr/aframe/pulls/2132/comments"},"review_comment":{"href":"https://api.github.com/repos/aframevr/aframe/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/aframevr/aframe/pulls/2132/commits"},"statuses":{"href":"https://api.github.com/repos/aframevr/aframe/statuses/92e394e1346bf4ba42367b93ab265651975863c3"}}}}
{"actor":{"display_login":"dmarcos"}}