{"action":"created","comment":{"url":"https://api.github.com/repos/mapsme/omim/pulls/comments/89673497","pull_request_review_id":10216893,"id":89673497,"diff_hunk":"@@ -77,16 +119,154 @@ class IndexGraph final\n   {\n     uint32_t const jointsSize = ReadPrimitiveFromSource<uint32_t>(src);\n     m_roadIndex.Deserialize(src);\n-    m_jointIndex.Build(m_roadIndex, jointsSize);\n+    Build(jointsSize);\n+  }\n+\n+  Joint::Id GetJointIdForTesting(RoadPoint const & ftp) const\n+  {\n+    return m_roadIndex.GetJointId(ftp);\n+  }\n+\n+  /// \\brief Disable all edges between |from| and |to| if they are different and adjacent.\n+  /// \\note Despit the fact that |from| and |to| could be connected with several edges\n+  /// it's a rare case. In most cases |from| and |to| are connected with only one edge\n+  /// if they are adjacent.\n+  /// \\note The method doesn't affect routing if |from| and |to| are not adjacent or\n+  /// if one of them is equal to Joint::kInvalidId.\n+  void DisableEdge(Joint::Id from, Joint::Id to)\n+  {\n+    m_blockedEdges.insert(DirectedEdge(from, to));\n   }\n+  /// \\brief Adding a fake oneway feature with a loose end starting from joint |from|.\n+  /// Geometry for the feature points is taken from |geometrySource|.\n+  /// If |geometrySource| contains more than two points the feature is created\n+  /// with intermediate (not joint) point(s).\n+  /// \\returns feature id which was added.\n+  uint32_t AddFakeLooseEndFeature(Joint::Id from, vector<RoadPoint> const & geometrySource);\n+\n+  /// \\brief Connects joint |from| and |to| with a fake oneway feature. Geometry for the feature\n+  /// points is taken from |geometrySource|. If |geometrySource| contains more than\n+  /// two points the feature is created with intermediate (not joint) point(s).\n+  /// \\returns feature id which was added.\n+  uint32_t AddFakeFeature(Joint::Id from, Joint::Id to, vector<RoadPoint> const & geometrySource);\n+\n+  /// \\brief Adds restriction to navigation graph which says that it's prohibited to go from\n+  /// |restrictionPoint.m_from| to |restrictionPoint.m_to|.\n+  /// \\note |from| and |to| could be only begining or ending feature points and they has to belong\n+  /// to\n+  /// the same junction with |jointId|. That means features |from| and |to| has to be adjacent.\n+  /// \\note This method could be called only after |m_roadIndex| have been loaded with the help of\n+  /// Deserialize() or Import().\n+  void ApplyRestrictionNo(RestrictionPoint const & restrictionPoint);\n+\n+  /// \\brief Adds restriction to navigation graph which says that from feature\n+  /// |restrictionPoint.m_from| it's permitted only\n+  /// to go to feature |restrictionPoint.m_to|. All other ways starting form\n+  /// |restrictionPoint.m_form| is prohibited.\n+  /// \\note All notes which are valid for ApplyRestrictionNo() is valid for ApplyRestrictionOnly().\n+  void ApplyRestrictionOnly(RestrictionPoint const & restrictionPoint);\n+\n+  void ApplyRestrictionOnlyRealFeatures(RestrictionPoint const & restrictionPoint);\n+  void ApplyRestrictionNoRealFeatures(RestrictionPoint const & restrictionPoint);\n+\n+  /// \\brief Add restrictions in |restrictions| to |m_ftPointIndex|.\n+  void ApplyRestrictions(RestrictionVec const & restrictions);\n+\n+  /// \\brief Fills |singleFeaturePath| with points from point |from| to point |to|\n+  /// \\note |from| and |to| has to belong the same feature.\n+  /// \\note The order on points in items of |connectionPaths| is from |from| to |to|.\n+  void GetSingleFeaturePaths(RoadPoint from, RoadPoint to, vector<RoadPoint> & singleFeaturePath);\n+\n+  /// \\brief  Fills |connectionPaths| with all path from joint |from| to joint |to|.\n+  /// If |from| and |to| don't belong to the same feature |connectionPaths| an exception\n+  /// |RootException| with be raised.\n+  /// If |from| and |to| belong to only one feature |connectionPaths| will have one item.\n+  /// It's most common case.\n+  /// If |from| and |to| could be connected by several feature |connectionPaths|\n+  /// will have several items.\n+  /// \\note The order on points in items of |connectionPaths| is from |from| to |to|.\n+  void GetConnectionPaths(Joint::Id from, Joint::Id to,\n+                          vector<vector<RoadPoint>> & connectionPaths);\n+\n+  /// \\brief Fills |shortestConnectionPath| with shortest path from joint |from| to joint |to|.\n+  /// \\note The order on points in |shortestConnectionPath| is from |from| to |to|.\n+  /// \\note In most cases the method doesn't load geometry to find the shortest path\n+  /// because there's only one path between |from| and |to|.\n+  /// \\note if |shortestConnectionPath| could be filled after call of the method\n+  /// an exception of type |RootException| is raised. It could happend,\n+  /// for example, if |from| and |to| are connected with a pedestrian road\n+  /// but a car route is looked for.\n+  void GetShortestConnectionPath(Joint::Id from, Joint::Id to,\n+                                 vector<RoadPoint> & shortestConnectionPath);\n+\n+  /// \\brief Fills |featureConnectionPath| with a path from |from| to |to| of points of |featureId|.\n+  void GetFeatureConnectionPath(Joint::Id from, Joint::Id to, uint32_t featureId,\n+                                vector<RoadPoint> & featureConnectionPath);\n+\n+  void GetOutgoingGeomEdges(vector<JointEdge> const & outgoingEdges, Joint::Id center,\n+                            vector<JointEdgeGeom> & outgoingGeomEdges);\n+\n+  void CreateFakeFeatureGeometry(vector<RoadPoint> const & geometrySource, RoadGeometry & geometry);\n+\n+  /// \\returns RoadGeometry by a real or fake featureId.\n+  RoadGeometry const & GetRoad(uint32_t featureId);\n+\n+  bool IsFakeFeature(uint32_t featureId) const { return featureId >= kStartFakeFeatureIds; }\n+\n+  static uint32_t const kStartFakeFeatureIds = 1024 * 1024 * 1024;\n \n private:\n-  void GetNeighboringEdge(RoadGeometry const & road, RoadPoint const & rp, bool forward,\n-                          vector<JointEdge> & edges) const;\n+  void GetNeighboringEdge(RoadGeometry const & road, RoadPoint const & rp, bool forward, bool outgoing,\n+                          bool graphWithoutRestrictions, vector<JointEdge> & edges) const;\n+  void Build(uint32_t jointNumber);\n+\n+  double GetSpeed(RoadPoint ftp);\n+\n+  /// \\brief Finds neghboring of |centerId| joint on feature id of |center|\n+  /// which is contained in |edges| and fills |oneStepAside| with it.\n+  /// \\note If oneStepAside is empty no neghboring nodes were found.\n+  /// \\note Taking into account the way of setting restrictions almost always |oneStepAside|\n+  /// will contain one or zero items. Besides the it it's posible to draw map\n+  /// the (wrong) way |oneStepAside| will contain any number of items.\n+  void FindOneStepAsideRoadPoint(RoadPoint const & center, Joint::Id centerId,\n+                                 vector<JointEdge> const & edges,\n+                                 vector<Joint::Id> & oneStepAside) const;\n+\n+  bool ApplyRestrictionPrepareData(RestrictionPoint const & restrictionPoint,\n+                                   vector<JointEdge> & ingoingEdges,\n+                                   vector<JointEdge> & outgoingEdges,\n+                                   Joint::Id & fromFirstOneStepAside,\n+                                   Joint::Id & toFirstOneStepAside);\n \n   Geometry m_geometry;\n   shared_ptr<EdgeEstimator> m_estimator;\n   RoadIndex m_roadIndex;\n   JointIndex m_jointIndex;\n+\n+  set<DirectedEdge> m_blockedEdges;\n+  uint32_t m_nextFakeFeatureId = kStartFakeFeatureIds;\n+  // Mapping from fake feature id to fake feature geometry.\n+  map<uint32_t, RoadGeometry> m_fakeFeatureGeometry;\n+  // Adding restrictions leads to disabling some edges and adding others.\n+  // According to graph trasformation implemented in ApplyRestrictionNo() and\n+  // ApplyRestrictionOnly() every |DirectedEdge| could (a pair of joints):\n+  // * disappears at all (it's added in |m_blockedEdges| in that case)\n+  // * be transformed to another DirectedEdge. If so the mapping\n+  //   is kept in |m_movedCrossings|.\n+  // * be copied to another DirectedEdge. If so the mapping\n+  //   form a directedEdge1 to (directedEdge1, directedEdge2) is kept in |m_edgeMapping|.\n+  // See ApplyRestriction* method for a detailed comments.\n+  //\n+  // If it's necessary to apply a restriction with some RestrictionPoint with a real features id\n+  // it's needed to perform the followig steps:\n+  // * Any restriction(RestrictionPoint) composed of two edge(DirectedEdge). So it's necessary\n+  //   to check if there's one of the edge in |m_edgeMapping|.\n+  // * Neither of them there's in |m_edgeMapping| the restriction should be applied to the graph\n+  //   as is.\n+  // * If the first of them there's in |m_edgeMapping| all leaves of the first edge\n+  //   in the forest |m_edgeMapping| should be found for it. And all restriction\n+  //   starting from the leaves edge and finishing the second edge of the RestrictionPoint\n+  //   should be applied.\n+  map<DirectedEdge, vector<DirectedEdge>> m_edgeMapping;","path":"routing/index_graph.hpp","position":244,"original_position":244,"commit_id":"c92da42c632dd19cd2cd6a3f0e7f6ddb7df6fbab","original_commit_id":"c92da42c632dd19cd2cd6a3f0e7f6ddb7df6fbab","user":{"login":"dobriy-eeh","id":19839790,"avatar_url":"https://avatars.githubusercontent.com/u/19839790?v=3","gravatar_id":"","url":"https://api.github.com/users/dobriy-eeh","html_url":"https://github.com/dobriy-eeh","followers_url":"https://api.github.com/users/dobriy-eeh/followers","following_url":"https://api.github.com/users/dobriy-eeh/following{/other_user}","gists_url":"https://api.github.com/users/dobriy-eeh/gists{/gist_id}","starred_url":"https://api.github.com/users/dobriy-eeh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dobriy-eeh/subscriptions","organizations_url":"https://api.github.com/users/dobriy-eeh/orgs","repos_url":"https://api.github.com/users/dobriy-eeh/repos","events_url":"https://api.github.com/users/dobriy-eeh/events{/privacy}","received_events_url":"https://api.github.com/users/dobriy-eeh/received_events","type":"User","site_admin":false},"body":"IndexGraph сильно разросся.\r\nМожет выделить новые данные и часть новых методов в отдельный класс? RestrictionIndex, RestrictionsGraph или что-то типа того?","created_at":"2016-11-26T15:55:24Z","updated_at":"2016-11-26T15:55:24Z","html_url":"https://github.com/mapsme/omim/pull/4817#discussion_r89673497","pull_request_url":"https://api.github.com/repos/mapsme/omim/pulls/4817","_links":{"self":{"href":"https://api.github.com/repos/mapsme/omim/pulls/comments/89673497"},"html":{"href":"https://github.com/mapsme/omim/pull/4817#discussion_r89673497"},"pull_request":{"href":"https://api.github.com/repos/mapsme/omim/pulls/4817"}}},"pull_request":{"url":"https://api.github.com/repos/mapsme/omim/pulls/4817","id":95372509,"html_url":"https://github.com/mapsme/omim/pull/4817","diff_url":"https://github.com/mapsme/omim/pull/4817.diff","patch_url":"https://github.com/mapsme/omim/pull/4817.patch","issue_url":"https://api.github.com/repos/mapsme/omim/issues/4817","number":4817,"state":"open","locked":false,"title":"[routing] Applying restrictions on index graph","user":{"login":"bykoianko","id":1768114,"avatar_url":"https://avatars.githubusercontent.com/u/1768114?v=3","gravatar_id":"","url":"https://api.github.com/users/bykoianko","html_url":"https://github.com/bykoianko","followers_url":"https://api.github.com/users/bykoianko/followers","following_url":"https://api.github.com/users/bykoianko/following{/other_user}","gists_url":"https://api.github.com/users/bykoianko/gists{/gist_id}","starred_url":"https://api.github.com/users/bykoianko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bykoianko/subscriptions","organizations_url":"https://api.github.com/users/bykoianko/orgs","repos_url":"https://api.github.com/users/bykoianko/repos","events_url":"https://api.github.com/users/bykoianko/events{/privacy}","received_events_url":"https://api.github.com/users/bykoianko/received_events","type":"User","site_admin":false},"body":"Данный PR реализовывает наложение restriction на index graph. В не тривильных случаях это одно из двух преобразований графа: \r\nRestriction type Only\r\n```\r\n  // It's possible to move only from one segment to another in case of any number of ingoing and\r\n  // outgoing edges.\r\n  // The idea is to tranform the navigation graph for every non-degenerate case as it's shown below.\r\n  // At the picture below a restriction for permission moving only from 6 to O to 3 is shown.\r\n  // So to implement it it's necessary to remove (disable) an edge 6-O and add feature (edge) 4-N-3.\r\n  // Adding N is important for a route recovery stage. (The geometry of O will be copied to N.)\r\n  //\r\n  // 1       2       3                     1       2       3\r\n  // *       *       *                     *       *       *\r\n  //  ↖     ^     ↗                        ↖     ^     ↗^\r\n  //    ↖   |   ↗                            ↖   |   ↗  |\r\n  //      ↖ | ↗                                ↖ | ↗    |\r\n  //         *  O             ==>                  *  O    * N\r\n  //      ↗ ^ ↖                                 ↗^       ^\r\n  //    ↗   |   ↖                             ↗  |       |\r\n  //  ↗     |     ↖                         ↗    |       |\r\n  // *       *       *                     *       *       *\r\n  // 4       5       6                     4       5       6\r\n  //\r\n  // In case of this transformation the following edge mapping happens:\r\n  // 6-O -> 6-N\r\n  // O-3 -> O-3; N-3\r\n```\r\n\r\nRestriction type No\r\n```\r\n  // Prohibition of moving from one segment to another in case of any number of ingoing and outgoing\r\n  // edges.\r\n  // The idea is to transform the navigation graph for every non-degenerate case as it's shown below.\r\n  // At the picture below a restriction for prohibition moving from 4 to O to 3 is shown.\r\n  // So to implement it it's necessary to remove (disable) an edge 4-O and add features (edges)\r\n  // 4-N-1 and N-2.\r\n  //\r\n  // 1       2       3                     1       2       3\r\n  // *       *       *                     *       *       *\r\n  //  ↖     ^     ↗                       ^↖   ↗^     ↗\r\n  //    ↖   |   ↗                         |  ↖   |   ↗\r\n  //      ↖ | ↗                           |↗   ↖| ↗\r\n  //         *  O             ==>        N *       *  O\r\n  //      ↗ ^ ↖                           ^       ^ ↖\r\n  //    ↗   |   ↖                         |       |   ↖\r\n  //  ↗     |     ↖                       |       |     ↖\r\n  // *       *       *                     *       *       *\r\n  // 4       5       6                     4       5       6\r\n  //\r\n  // In case of this transformation the following edge mapping happens:\r\n  // 4-O -> 4-N\r\n  // O-1 -> O-1; N-1\r\n  // O-2 -> 0-2; N-2\r\n```\r\n\r\nВ данном PR я планирую еще доделать наложение пересекающихся рестрикшинов (входная дуга одного совпадает с выходной дугой другого). И добавить тестов.\r\n\r\nНо это сильно не повлияет на уже написанный код. Прошу всех заинтересованных коллег приступать к ревью.\r\n\r\n@ygorshenin @mpimenov @dobriy-eeh PTAL\r\n","created_at":"2016-11-26T14:06:55Z","updated_at":"2016-11-26T15:55:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"63ba0d63e0c4622ef9840e19c31a6bf7e4f2d4b1","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/mapsme/omim/pulls/4817/commits","review_comments_url":"https://api.github.com/repos/mapsme/omim/pulls/4817/comments","review_comment_url":"https://api.github.com/repos/mapsme/omim/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mapsme/omim/issues/4817/comments","statuses_url":"https://api.github.com/repos/mapsme/omim/statuses/c92da42c632dd19cd2cd6a3f0e7f6ddb7df6fbab","head":{"label":"mapsme:master-applying-restrictions","ref":"master-applying-restrictions","sha":"c92da42c632dd19cd2cd6a3f0e7f6ddb7df6fbab","user":{"login":"mapsme","id":14185141,"avatar_url":"https://avatars.githubusercontent.com/u/14185141?v=3","gravatar_id":"","url":"https://api.github.com/users/mapsme","html_url":"https://github.com/mapsme","followers_url":"https://api.github.com/users/mapsme/followers","following_url":"https://api.github.com/users/mapsme/following{/other_user}","gists_url":"https://api.github.com/users/mapsme/gists{/gist_id}","starred_url":"https://api.github.com/users/mapsme/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mapsme/subscriptions","organizations_url":"https://api.github.com/users/mapsme/orgs","repos_url":"https://api.github.com/users/mapsme/repos","events_url":"https://api.github.com/users/mapsme/events{/privacy}","received_events_url":"https://api.github.com/users/mapsme/received_events","type":"Organization","site_admin":false},"repo":{"id":42798033,"name":"omim","full_name":"mapsme/omim","owner":{"login":"mapsme","id":14185141,"avatar_url":"https://avatars.githubusercontent.com/u/14185141?v=3","gravatar_id":"","url":"https://api.github.com/users/mapsme","html_url":"https://github.com/mapsme","followers_url":"https://api.github.com/users/mapsme/followers","following_url":"https://api.github.com/users/mapsme/following{/other_user}","gists_url":"https://api.github.com/users/mapsme/gists{/gist_id}","starred_url":"https://api.github.com/users/mapsme/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mapsme/subscriptions","organizations_url":"https://api.github.com/users/mapsme/orgs","repos_url":"https://api.github.com/users/mapsme/repos","events_url":"https://api.github.com/users/mapsme/events{/privacy}","received_events_url":"https://api.github.com/users/mapsme/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mapsme/omim","description":"MAPS.ME - Offline OpenStreetMap maps for iOS/Android/Mac/Linux/Windows","fork":false,"url":"https://api.github.com/repos/mapsme/omim","forks_url":"https://api.github.com/repos/mapsme/omim/forks","keys_url":"https://api.github.com/repos/mapsme/omim/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mapsme/omim/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mapsme/omim/teams","hooks_url":"https://api.github.com/repos/mapsme/omim/hooks","issue_events_url":"https://api.github.com/repos/mapsme/omim/issues/events{/number}","events_url":"https://api.github.com/repos/mapsme/omim/events","assignees_url":"https://api.github.com/repos/mapsme/omim/assignees{/user}","branches_url":"https://api.github.com/repos/mapsme/omim/branches{/branch}","tags_url":"https://api.github.com/repos/mapsme/omim/tags","blobs_url":"https://api.github.com/repos/mapsme/omim/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mapsme/omim/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mapsme/omim/git/refs{/sha}","trees_url":"https://api.github.com/repos/mapsme/omim/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mapsme/omim/statuses/{sha}","languages_url":"https://api.github.com/repos/mapsme/omim/languages","stargazers_url":"https://api.github.com/repos/mapsme/omim/stargazers","contributors_url":"https://api.github.com/repos/mapsme/omim/contributors","subscribers_url":"https://api.github.com/repos/mapsme/omim/subscribers","subscription_url":"https://api.github.com/repos/mapsme/omim/subscription","commits_url":"https://api.github.com/repos/mapsme/omim/commits{/sha}","git_commits_url":"https://api.github.com/repos/mapsme/omim/git/commits{/sha}","comments_url":"https://api.github.com/repos/mapsme/omim/comments{/number}","issue_comment_url":"https://api.github.com/repos/mapsme/omim/issues/comments{/number}","contents_url":"https://api.github.com/repos/mapsme/omim/contents/{+path}","compare_url":"https://api.github.com/repos/mapsme/omim/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mapsme/omim/merges","archive_url":"https://api.github.com/repos/mapsme/omim/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mapsme/omim/downloads","issues_url":"https://api.github.com/repos/mapsme/omim/issues{/number}","pulls_url":"https://api.github.com/repos/mapsme/omim/pulls{/number}","milestones_url":"https://api.github.com/repos/mapsme/omim/milestones{/number}","notifications_url":"https://api.github.com/repos/mapsme/omim/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mapsme/omim/labels{/name}","releases_url":"https://api.github.com/repos/mapsme/omim/releases{/id}","deployments_url":"https://api.github.com/repos/mapsme/omim/deployments","created_at":"2015-09-20T02:57:13Z","updated_at":"2016-11-25T15:16:33Z","pushed_at":"2016-11-26T14:06:55Z","git_url":"git://github.com/mapsme/omim.git","ssh_url":"git@github.com:mapsme/omim.git","clone_url":"https://github.com/mapsme/omim.git","svn_url":"https://github.com/mapsme/omim","homepage":null,"size":2901840,"stargazers_count":2048,"watchers_count":2048,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":407,"mirror_url":null,"open_issues_count":364,"forks":407,"open_issues":364,"watchers":2048,"default_branch":"master"}},"base":{"label":"mapsme:master","ref":"master","sha":"3b1d1a5cbc6c8f9e2a05deba218f1347af4e66d6","user":{"login":"mapsme","id":14185141,"avatar_url":"https://avatars.githubusercontent.com/u/14185141?v=3","gravatar_id":"","url":"https://api.github.com/users/mapsme","html_url":"https://github.com/mapsme","followers_url":"https://api.github.com/users/mapsme/followers","following_url":"https://api.github.com/users/mapsme/following{/other_user}","gists_url":"https://api.github.com/users/mapsme/gists{/gist_id}","starred_url":"https://api.github.com/users/mapsme/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mapsme/subscriptions","organizations_url":"https://api.github.com/users/mapsme/orgs","repos_url":"https://api.github.com/users/mapsme/repos","events_url":"https://api.github.com/users/mapsme/events{/privacy}","received_events_url":"https://api.github.com/users/mapsme/received_events","type":"Organization","site_admin":false},"repo":{"id":42798033,"name":"omim","full_name":"mapsme/omim","owner":{"login":"mapsme","id":14185141,"avatar_url":"https://avatars.githubusercontent.com/u/14185141?v=3","gravatar_id":"","url":"https://api.github.com/users/mapsme","html_url":"https://github.com/mapsme","followers_url":"https://api.github.com/users/mapsme/followers","following_url":"https://api.github.com/users/mapsme/following{/other_user}","gists_url":"https://api.github.com/users/mapsme/gists{/gist_id}","starred_url":"https://api.github.com/users/mapsme/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mapsme/subscriptions","organizations_url":"https://api.github.com/users/mapsme/orgs","repos_url":"https://api.github.com/users/mapsme/repos","events_url":"https://api.github.com/users/mapsme/events{/privacy}","received_events_url":"https://api.github.com/users/mapsme/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mapsme/omim","description":"MAPS.ME - Offline OpenStreetMap maps for iOS/Android/Mac/Linux/Windows","fork":false,"url":"https://api.github.com/repos/mapsme/omim","forks_url":"https://api.github.com/repos/mapsme/omim/forks","keys_url":"https://api.github.com/repos/mapsme/omim/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mapsme/omim/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mapsme/omim/teams","hooks_url":"https://api.github.com/repos/mapsme/omim/hooks","issue_events_url":"https://api.github.com/repos/mapsme/omim/issues/events{/number}","events_url":"https://api.github.com/repos/mapsme/omim/events","assignees_url":"https://api.github.com/repos/mapsme/omim/assignees{/user}","branches_url":"https://api.github.com/repos/mapsme/omim/branches{/branch}","tags_url":"https://api.github.com/repos/mapsme/omim/tags","blobs_url":"https://api.github.com/repos/mapsme/omim/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mapsme/omim/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mapsme/omim/git/refs{/sha}","trees_url":"https://api.github.com/repos/mapsme/omim/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mapsme/omim/statuses/{sha}","languages_url":"https://api.github.com/repos/mapsme/omim/languages","stargazers_url":"https://api.github.com/repos/mapsme/omim/stargazers","contributors_url":"https://api.github.com/repos/mapsme/omim/contributors","subscribers_url":"https://api.github.com/repos/mapsme/omim/subscribers","subscription_url":"https://api.github.com/repos/mapsme/omim/subscription","commits_url":"https://api.github.com/repos/mapsme/omim/commits{/sha}","git_commits_url":"https://api.github.com/repos/mapsme/omim/git/commits{/sha}","comments_url":"https://api.github.com/repos/mapsme/omim/comments{/number}","issue_comment_url":"https://api.github.com/repos/mapsme/omim/issues/comments{/number}","contents_url":"https://api.github.com/repos/mapsme/omim/contents/{+path}","compare_url":"https://api.github.com/repos/mapsme/omim/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mapsme/omim/merges","archive_url":"https://api.github.com/repos/mapsme/omim/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mapsme/omim/downloads","issues_url":"https://api.github.com/repos/mapsme/omim/issues{/number}","pulls_url":"https://api.github.com/repos/mapsme/omim/pulls{/number}","milestones_url":"https://api.github.com/repos/mapsme/omim/milestones{/number}","notifications_url":"https://api.github.com/repos/mapsme/omim/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mapsme/omim/labels{/name}","releases_url":"https://api.github.com/repos/mapsme/omim/releases{/id}","deployments_url":"https://api.github.com/repos/mapsme/omim/deployments","created_at":"2015-09-20T02:57:13Z","updated_at":"2016-11-25T15:16:33Z","pushed_at":"2016-11-26T14:06:55Z","git_url":"git://github.com/mapsme/omim.git","ssh_url":"git@github.com:mapsme/omim.git","clone_url":"https://github.com/mapsme/omim.git","svn_url":"https://github.com/mapsme/omim","homepage":null,"size":2901840,"stargazers_count":2048,"watchers_count":2048,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":407,"mirror_url":null,"open_issues_count":364,"forks":407,"open_issues":364,"watchers":2048,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mapsme/omim/pulls/4817"},"html":{"href":"https://github.com/mapsme/omim/pull/4817"},"issue":{"href":"https://api.github.com/repos/mapsme/omim/issues/4817"},"comments":{"href":"https://api.github.com/repos/mapsme/omim/issues/4817/comments"},"review_comments":{"href":"https://api.github.com/repos/mapsme/omim/pulls/4817/comments"},"review_comment":{"href":"https://api.github.com/repos/mapsme/omim/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mapsme/omim/pulls/4817/commits"},"statuses":{"href":"https://api.github.com/repos/mapsme/omim/statuses/c92da42c632dd19cd2cd6a3f0e7f6ddb7df6fbab"}}}}
{"actor":{"display_login":"dobriy-eeh"}}