{"action":"created","comment":{"url":"https://api.github.com/repos/highfidelity/hifi/pulls/comments/29601447","id":29601447,"diff_hunk":"@@ -0,0 +1,376 @@\n+//\n+//  UserInputMapper.cpp\n+//  interface/src/ui\n+//\n+//  Created by Sam Gateau on 4/27/15.\n+//  Copyright 2015 High Fidelity, Inc.\n+//\n+//  Distributed under the Apache License, Version 2.0.\n+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html\n+//\n+#include \"UserInputMapper.h\"\n+#include <algorithm>\n+\n+void KeyboardMouseDevice::update() {\n+    _axisStateMap.clear();\n+\n+    // For touch event, we need to check that the last event is not too long ago\n+    // Maybe it's a Qt issue, but the touch event sequence (begin, update, end) is not always called properly\n+    // The following is a workaround to detect that the touch sequence is over in case we didn;t see the end event\n+    if (_isTouching) {\n+        const auto TOUCH_EVENT_MAXIMUM_WAIT = 100; //ms\n+        auto currentTime = _clock.now();\n+        auto sinceLastTouch = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - _lastTouchTime);\n+        if (sinceLastTouch.count() > TOUCH_EVENT_MAXIMUM_WAIT) {\n+            _isTouching = false;\n+        }\n+    }\n+}\n+\n+void KeyboardMouseDevice::focusOutEvent(QFocusEvent* event) {\n+    _buttonPressedMap.clear();\n+};\n+\n+void KeyboardMouseDevice::keyPressEvent(QKeyEvent* event) {\n+    auto input = makeInput((Qt::Key) event->key());\n+    auto result = _buttonPressedMap.insert(input.getChannel());\n+    if (!result.second) {\n+        // key pressed again ? without catching the release event ?\n+    }\n+}\n+void KeyboardMouseDevice::keyReleaseEvent(QKeyEvent* event) {\n+    auto input = makeInput((Qt::Key) event->key());\n+    _buttonPressedMap.erase(input.getChannel());\n+}\n+\n+void KeyboardMouseDevice::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {\n+    auto input = makeInput((Qt::MouseButton) event->button());\n+    auto result = _buttonPressedMap.insert(input.getChannel());\n+    if (!result.second) {\n+        // key pressed again ? without catching the release event ?\n+    }\n+    _lastCursor = event->pos();\n+}\n+void KeyboardMouseDevice::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {\n+    auto input = makeInput((Qt::MouseButton) event->button());\n+    _buttonPressedMap.erase(input.getChannel());\n+}\n+void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {\n+    QPoint currentPos = event->pos();\n+    QPoint currentMove = currentPos - _lastCursor;\n+\n+    _axisStateMap[makeInput(MOUSE_AXIS_X_POS).getChannel()] = (currentMove.x() > 0 ? currentMove.x() : 0.0f);\n+    _axisStateMap[makeInput(MOUSE_AXIS_X_NEG).getChannel()] = (currentMove.x() < 0 ? -currentMove.x() : 0.0f);\n+     // Y mouse is inverted positive is pointing up the screen\n+    _axisStateMap[makeInput(MOUSE_AXIS_Y_POS).getChannel()] = (currentMove.y() < 0 ? -currentMove.y() : 0.0f);\n+    _axisStateMap[makeInput(MOUSE_AXIS_Y_NEG).getChannel()] = (currentMove.y() > 0 ? currentMove.y() : 0.0f);\n+\n+    _lastCursor = currentPos;\n+}\n+void KeyboardMouseDevice::wheelEvent(QWheelEvent* event) {\n+    auto currentMove = event->angleDelta() / 120.0f;\n+\n+    _axisStateMap[makeInput(MOUSE_AXIS_WHEEL_X_POS).getChannel()] = (currentMove.x() > 0 ? currentMove.x() : 0.0f);\n+    _axisStateMap[makeInput(MOUSE_AXIS_WHEEL_X_NEG).getChannel()] = (currentMove.x() < 0 ? -currentMove.x() : 0.0f);\n+    _axisStateMap[makeInput(MOUSE_AXIS_WHEEL_Y_POS).getChannel()] = (currentMove.y() > 0 ? currentMove.y() : 0.0f);\n+    _axisStateMap[makeInput(MOUSE_AXIS_WHEEL_Y_NEG).getChannel()] = (currentMove.y() < 0 ? -currentMove.y() : 0.0f);\n+}\n+\n+glm::vec2 KeyboardMouseDevice::evalAverageTouchPoints(const QList<QTouchEvent::TouchPoint>& points) const {\n+    glm::vec2 averagePoint(0.0f);\n+    if (points.count() > 0) {\n+        for (auto& point : points) {\n+            averagePoint += glm::vec2(point.pos().x(), point.pos().y()); \n+        }\n+        averagePoint /= (float)(points.count());\n+    }\n+    return averagePoint;\n+}\n+\n+\n+void KeyboardMouseDevice::touchBeginEvent(const QTouchEvent* event) {\n+    _isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed);\n+    _lastTouch = evalAverageTouchPoints(event->touchPoints());\n+    _lastTouchTime = _clock.now();\n+}\n+void KeyboardMouseDevice::touchEndEvent(const QTouchEvent* event) {\n+    _isTouching = false;\n+    _lastTouch = evalAverageTouchPoints(event->touchPoints());\n+    _lastTouchTime = _clock.now();\n+}\n+void KeyboardMouseDevice::touchUpdateEvent(const QTouchEvent* event) {\n+    auto currentPos = evalAverageTouchPoints(event->touchPoints());\n+    _lastTouchTime = _clock.now();\n+    \n+    if (!_isTouching) {\n+        _isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed);\n+    } else {\n+        auto currentMove = currentPos - _lastTouch;\n+    \n+        _axisStateMap[makeInput(TOUCH_AXIS_X_POS).getChannel()] = (currentMove.x > 0 ? currentMove.x : 0.0f);\n+        _axisStateMap[makeInput(TOUCH_AXIS_X_NEG).getChannel()] = (currentMove.x < 0 ? -currentMove.x : 0.0f);\n+        // Y mouse is inverted positive is pointing up the screen\n+        _axisStateMap[makeInput(TOUCH_AXIS_Y_POS).getChannel()] = (currentMove.y < 0 ? -currentMove.y : 0.0f);\n+        _axisStateMap[makeInput(TOUCH_AXIS_Y_NEG).getChannel()] = (currentMove.y > 0 ? currentMove.y : 0.0f);\n+    }\n+\n+    _lastTouch = currentPos;\n+}\n+\n+UserInputMapper::Input KeyboardMouseDevice::makeInput(Qt::Key code) {\n+    return UserInputMapper::Input(_deviceID, code & KEYBOARD_MASK, UserInputMapper::ChannelType::BUTTON);\n+}\n+UserInputMapper::Input KeyboardMouseDevice::makeInput(Qt::MouseButton code) {\n+    switch (code) {\n+        case Qt::LeftButton:\n+            return UserInputMapper::Input(_deviceID, MOUSE_BUTTON_LEFT, UserInputMapper::ChannelType::BUTTON);\n+        case Qt::RightButton:\n+            return UserInputMapper::Input(_deviceID, MOUSE_BUTTON_RIGHT, UserInputMapper::ChannelType::BUTTON);\n+        case Qt::MiddleButton:\n+            return UserInputMapper::Input(_deviceID, MOUSE_BUTTON_MIDDLE, UserInputMapper::ChannelType::BUTTON);\n+        default:\n+            return UserInputMapper::Input();\n+    };\n+}\n+UserInputMapper::Input KeyboardMouseDevice::makeInput(KeyboardMouseDevice::MouseAxisChannel axis) {\n+    return UserInputMapper::Input(_deviceID, axis, UserInputMapper::ChannelType::AXIS);\n+}\n+UserInputMapper::Input KeyboardMouseDevice::makeInput(KeyboardMouseDevice::TouchAxisChannel axis) {\n+    return UserInputMapper::Input(_deviceID, axis, UserInputMapper::ChannelType::AXIS);\n+}\n+UserInputMapper::Input KeyboardMouseDevice::makeInput(KeyboardMouseDevice::TouchButtonChannel button) {","path":"interface/src/ui/UserInputMapper.cpp","position":141,"original_position":141,"commit_id":"3921156978061ad3ed71de84403cab4206eeccc3","original_commit_id":"3921156978061ad3ed71de84403cab4206eeccc3","user":{"login":"birarda","id":724069,"avatar_url":"https://avatars.githubusercontent.com/u/724069?v=3","gravatar_id":"","url":"https://api.github.com/users/birarda","html_url":"https://github.com/birarda","followers_url":"https://api.github.com/users/birarda/followers","following_url":"https://api.github.com/users/birarda/following{/other_user}","gists_url":"https://api.github.com/users/birarda/gists{/gist_id}","starred_url":"https://api.github.com/users/birarda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/birarda/subscriptions","organizations_url":"https://api.github.com/users/birarda/orgs","repos_url":"https://api.github.com/users/birarda/repos","events_url":"https://api.github.com/users/birarda/events{/privacy}","received_events_url":"https://api.github.com/users/birarda/received_events","type":"User","site_admin":false},"body":"space here","created_at":"2015-05-04T17:00:47Z","updated_at":"2015-05-04T17:00:47Z","html_url":"https://github.com/highfidelity/hifi/pull/4753#discussion_r29601447","pull_request_url":"https://api.github.com/repos/highfidelity/hifi/pulls/4753","_links":{"self":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/comments/29601447"},"html":{"href":"https://github.com/highfidelity/hifi/pull/4753#discussion_r29601447"},"pull_request":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/4753"}}},"pull_request":{"url":"https://api.github.com/repos/highfidelity/hifi/pulls/4753","id":34620899,"html_url":"https://github.com/highfidelity/hifi/pull/4753","diff_url":"https://github.com/highfidelity/hifi/pull/4753.diff","patch_url":"https://github.com/highfidelity/hifi/pull/4753.patch","issue_url":"https://api.github.com/repos/highfidelity/hifi/issues/4753","number":4753,"state":"open","locked":false,"title":"Introducing UserInputMapper","user":{"login":"samcake","id":2230265,"avatar_url":"https://avatars.githubusercontent.com/u/2230265?v=3","gravatar_id":"","url":"https://api.github.com/users/samcake","html_url":"https://github.com/samcake","followers_url":"https://api.github.com/users/samcake/followers","following_url":"https://api.github.com/users/samcake/following{/other_user}","gists_url":"https://api.github.com/users/samcake/gists{/gist_id}","starred_url":"https://api.github.com/users/samcake/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samcake/subscriptions","organizations_url":"https://api.github.com/users/samcake/orgs","repos_url":"https://api.github.com/users/samcake/repos","events_url":"https://api.github.com/users/samcake/events{/privacy}","received_events_url":"https://api.github.com/users/samcake/received_events","type":"User","site_admin":false},"body":"- The class UserInputMapper is in charge of bindings keys and any device inputs identified with a unique Input to the actual few \"Actions\"\r\n\r\n- Replace all the code happening in Application::key*Event to control the _myAvatar driveKeys, instead it is happening in the Application::update right after the userINputMapper has been updated\r\n\r\n- For now the Actions of the UserInputMapper are hard coded, we ll need to change that soon and make the actions created at runtime","created_at":"2015-05-04T08:04:05Z","updated_at":"2015-05-04T17:00:47Z","closed_at":null,"merged_at":null,"merge_commit_sha":"aa1449d4f27dfd87b64c5e25d0e6b070c6c4fa52","assignee":{"login":"birarda","id":724069,"avatar_url":"https://avatars.githubusercontent.com/u/724069?v=3","gravatar_id":"","url":"https://api.github.com/users/birarda","html_url":"https://github.com/birarda","followers_url":"https://api.github.com/users/birarda/followers","following_url":"https://api.github.com/users/birarda/following{/other_user}","gists_url":"https://api.github.com/users/birarda/gists{/gist_id}","starred_url":"https://api.github.com/users/birarda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/birarda/subscriptions","organizations_url":"https://api.github.com/users/birarda/orgs","repos_url":"https://api.github.com/users/birarda/repos","events_url":"https://api.github.com/users/birarda/events{/privacy}","received_events_url":"https://api.github.com/users/birarda/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/highfidelity/hifi/pulls/4753/commits","review_comments_url":"https://api.github.com/repos/highfidelity/hifi/pulls/4753/comments","review_comment_url":"https://api.github.com/repos/highfidelity/hifi/pulls/comments{/number}","comments_url":"https://api.github.com/repos/highfidelity/hifi/issues/4753/comments","statuses_url":"https://api.github.com/repos/highfidelity/hifi/statuses/3921156978061ad3ed71de84403cab4206eeccc3","head":{"label":"samcake:orange","ref":"orange","sha":"3921156978061ad3ed71de84403cab4206eeccc3","user":{"login":"samcake","id":2230265,"avatar_url":"https://avatars.githubusercontent.com/u/2230265?v=3","gravatar_id":"","url":"https://api.github.com/users/samcake","html_url":"https://github.com/samcake","followers_url":"https://api.github.com/users/samcake/followers","following_url":"https://api.github.com/users/samcake/following{/other_user}","gists_url":"https://api.github.com/users/samcake/gists{/gist_id}","starred_url":"https://api.github.com/users/samcake/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samcake/subscriptions","organizations_url":"https://api.github.com/users/samcake/orgs","repos_url":"https://api.github.com/users/samcake/repos","events_url":"https://api.github.com/users/samcake/events{/privacy}","received_events_url":"https://api.github.com/users/samcake/received_events","type":"User","site_admin":false},"repo":{"id":24736064,"name":"hifi","full_name":"samcake/hifi","owner":{"login":"samcake","id":2230265,"avatar_url":"https://avatars.githubusercontent.com/u/2230265?v=3","gravatar_id":"","url":"https://api.github.com/users/samcake","html_url":"https://github.com/samcake","followers_url":"https://api.github.com/users/samcake/followers","following_url":"https://api.github.com/users/samcake/following{/other_user}","gists_url":"https://api.github.com/users/samcake/gists{/gist_id}","starred_url":"https://api.github.com/users/samcake/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samcake/subscriptions","organizations_url":"https://api.github.com/users/samcake/orgs","repos_url":"https://api.github.com/users/samcake/repos","events_url":"https://api.github.com/users/samcake/events{/privacy}","received_events_url":"https://api.github.com/users/samcake/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/samcake/hifi","description":"Open, decentralized virtual worlds using sensors to control avatars and dynamically assigned devices as servers.  San Francisco based startup, we are hiring: http://highfidelity.io/jobs  Contribute by reporting bugs & doing jobs on http://worklist.net","fork":true,"url":"https://api.github.com/repos/samcake/hifi","forks_url":"https://api.github.com/repos/samcake/hifi/forks","keys_url":"https://api.github.com/repos/samcake/hifi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/samcake/hifi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/samcake/hifi/teams","hooks_url":"https://api.github.com/repos/samcake/hifi/hooks","issue_events_url":"https://api.github.com/repos/samcake/hifi/issues/events{/number}","events_url":"https://api.github.com/repos/samcake/hifi/events","assignees_url":"https://api.github.com/repos/samcake/hifi/assignees{/user}","branches_url":"https://api.github.com/repos/samcake/hifi/branches{/branch}","tags_url":"https://api.github.com/repos/samcake/hifi/tags","blobs_url":"https://api.github.com/repos/samcake/hifi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/samcake/hifi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/samcake/hifi/git/refs{/sha}","trees_url":"https://api.github.com/repos/samcake/hifi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/samcake/hifi/statuses/{sha}","languages_url":"https://api.github.com/repos/samcake/hifi/languages","stargazers_url":"https://api.github.com/repos/samcake/hifi/stargazers","contributors_url":"https://api.github.com/repos/samcake/hifi/contributors","subscribers_url":"https://api.github.com/repos/samcake/hifi/subscribers","subscription_url":"https://api.github.com/repos/samcake/hifi/subscription","commits_url":"https://api.github.com/repos/samcake/hifi/commits{/sha}","git_commits_url":"https://api.github.com/repos/samcake/hifi/git/commits{/sha}","comments_url":"https://api.github.com/repos/samcake/hifi/comments{/number}","issue_comment_url":"https://api.github.com/repos/samcake/hifi/issues/comments{/number}","contents_url":"https://api.github.com/repos/samcake/hifi/contents/{+path}","compare_url":"https://api.github.com/repos/samcake/hifi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/samcake/hifi/merges","archive_url":"https://api.github.com/repos/samcake/hifi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/samcake/hifi/downloads","issues_url":"https://api.github.com/repos/samcake/hifi/issues{/number}","pulls_url":"https://api.github.com/repos/samcake/hifi/pulls{/number}","milestones_url":"https://api.github.com/repos/samcake/hifi/milestones{/number}","notifications_url":"https://api.github.com/repos/samcake/hifi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/samcake/hifi/labels{/name}","releases_url":"https://api.github.com/repos/samcake/hifi/releases{/id}","created_at":"2014-10-02T20:49:37Z","updated_at":"2015-04-02T23:12:49Z","pushed_at":"2015-05-04T08:09:38Z","git_url":"git://github.com/samcake/hifi.git","ssh_url":"git@github.com:samcake/hifi.git","clone_url":"https://github.com/samcake/hifi.git","svn_url":"https://github.com/samcake/hifi","homepage":"","size":154311,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"highfidelity:master","ref":"master","sha":"d7cc76e48bf6fec7ae4312176abf9397b6507561","user":{"login":"highfidelity","id":1565370,"avatar_url":"https://avatars.githubusercontent.com/u/1565370?v=3","gravatar_id":"","url":"https://api.github.com/users/highfidelity","html_url":"https://github.com/highfidelity","followers_url":"https://api.github.com/users/highfidelity/followers","following_url":"https://api.github.com/users/highfidelity/following{/other_user}","gists_url":"https://api.github.com/users/highfidelity/gists{/gist_id}","starred_url":"https://api.github.com/users/highfidelity/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/highfidelity/subscriptions","organizations_url":"https://api.github.com/users/highfidelity/orgs","repos_url":"https://api.github.com/users/highfidelity/repos","events_url":"https://api.github.com/users/highfidelity/events{/privacy}","received_events_url":"https://api.github.com/users/highfidelity/received_events","type":"Organization","site_admin":false},"repo":{"id":5372872,"name":"hifi","full_name":"highfidelity/hifi","owner":{"login":"highfidelity","id":1565370,"avatar_url":"https://avatars.githubusercontent.com/u/1565370?v=3","gravatar_id":"","url":"https://api.github.com/users/highfidelity","html_url":"https://github.com/highfidelity","followers_url":"https://api.github.com/users/highfidelity/followers","following_url":"https://api.github.com/users/highfidelity/following{/other_user}","gists_url":"https://api.github.com/users/highfidelity/gists{/gist_id}","starred_url":"https://api.github.com/users/highfidelity/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/highfidelity/subscriptions","organizations_url":"https://api.github.com/users/highfidelity/orgs","repos_url":"https://api.github.com/users/highfidelity/repos","events_url":"https://api.github.com/users/highfidelity/events{/privacy}","received_events_url":"https://api.github.com/users/highfidelity/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/highfidelity/hifi","description":"Open source software for shared virtual worlds using HMDs and dynamically assigned devices as servers.  San Francisco based startup, we are hiring: http://highfidelity.com/jobs  Documentation at http://docs.highfidelity.com  Contribute by reporting bugs & doing jobs on http://worklist.net","fork":false,"url":"https://api.github.com/repos/highfidelity/hifi","forks_url":"https://api.github.com/repos/highfidelity/hifi/forks","keys_url":"https://api.github.com/repos/highfidelity/hifi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/highfidelity/hifi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/highfidelity/hifi/teams","hooks_url":"https://api.github.com/repos/highfidelity/hifi/hooks","issue_events_url":"https://api.github.com/repos/highfidelity/hifi/issues/events{/number}","events_url":"https://api.github.com/repos/highfidelity/hifi/events","assignees_url":"https://api.github.com/repos/highfidelity/hifi/assignees{/user}","branches_url":"https://api.github.com/repos/highfidelity/hifi/branches{/branch}","tags_url":"https://api.github.com/repos/highfidelity/hifi/tags","blobs_url":"https://api.github.com/repos/highfidelity/hifi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/highfidelity/hifi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/highfidelity/hifi/git/refs{/sha}","trees_url":"https://api.github.com/repos/highfidelity/hifi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/highfidelity/hifi/statuses/{sha}","languages_url":"https://api.github.com/repos/highfidelity/hifi/languages","stargazers_url":"https://api.github.com/repos/highfidelity/hifi/stargazers","contributors_url":"https://api.github.com/repos/highfidelity/hifi/contributors","subscribers_url":"https://api.github.com/repos/highfidelity/hifi/subscribers","subscription_url":"https://api.github.com/repos/highfidelity/hifi/subscription","commits_url":"https://api.github.com/repos/highfidelity/hifi/commits{/sha}","git_commits_url":"https://api.github.com/repos/highfidelity/hifi/git/commits{/sha}","comments_url":"https://api.github.com/repos/highfidelity/hifi/comments{/number}","issue_comment_url":"https://api.github.com/repos/highfidelity/hifi/issues/comments{/number}","contents_url":"https://api.github.com/repos/highfidelity/hifi/contents/{+path}","compare_url":"https://api.github.com/repos/highfidelity/hifi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/highfidelity/hifi/merges","archive_url":"https://api.github.com/repos/highfidelity/hifi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/highfidelity/hifi/downloads","issues_url":"https://api.github.com/repos/highfidelity/hifi/issues{/number}","pulls_url":"https://api.github.com/repos/highfidelity/hifi/pulls{/number}","milestones_url":"https://api.github.com/repos/highfidelity/hifi/milestones{/number}","notifications_url":"https://api.github.com/repos/highfidelity/hifi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/highfidelity/hifi/labels{/name}","releases_url":"https://api.github.com/repos/highfidelity/hifi/releases{/id}","created_at":"2012-08-10T18:26:22Z","updated_at":"2015-05-04T16:46:26Z","pushed_at":"2015-05-04T16:55:36Z","git_url":"git://github.com/highfidelity/hifi.git","ssh_url":"git@github.com:highfidelity/hifi.git","clone_url":"https://github.com/highfidelity/hifi.git","svn_url":"https://github.com/highfidelity/hifi","homepage":"","size":207135,"stargazers_count":261,"watchers_count":261,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":149,"mirror_url":null,"open_issues_count":55,"forks":149,"open_issues":55,"watchers":261,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/4753"},"html":{"href":"https://github.com/highfidelity/hifi/pull/4753"},"issue":{"href":"https://api.github.com/repos/highfidelity/hifi/issues/4753"},"comments":{"href":"https://api.github.com/repos/highfidelity/hifi/issues/4753/comments"},"review_comments":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/4753/comments"},"review_comment":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/highfidelity/hifi/pulls/4753/commits"},"statuses":{"href":"https://api.github.com/repos/highfidelity/hifi/statuses/3921156978061ad3ed71de84403cab4206eeccc3"}}}}