{"action":"created","comment":{"url":"https://api.github.com/repos/apache/cordova-lib/pulls/comments/54785237","id":54785237,"diff_hunk":"@@ -512,3 +543,219 @@ function versionString(version) {\n \n     return null;\n }\n+\n+/**\n+ * Gets the version of a plugin that should be fetched for a given project based\n+ * on the plugin's engine information from NPM and the platforms/plugins installed\n+ * in the project. The cordovaDependencies object in the package.json's engines\n+ * entry takes the form of an object that maps plugin versions to a series of\n+ * constraints and semver ranges. For example:\n+ *\n+ *     { plugin-version: { constraint: semver-range, ...}, ...}\n+ *\n+ * Constraint can be a plugin, platform, or cordova version. Plugin-version\n+ * can be either a single version (e.g. 3.0.0) or an upper bound (e.g. <3.0.0)\n+ *\n+ * @param {string}  projectRoot     The path to the root directory of the project\n+ * @param {object}  pluginInfo      The NPM info of the plugin be fetched (e.g. the\n+ *                                  result of calling `registry.info()`)\n+ * @param {string}  cordovaVersion  The semver version of cordova-lib\n+ *\n+ * @return {Promise}                A promise that will resolve to either a string\n+ *                                  if there is a version of the plugin that this\n+ *                                  project satisfies or null if there is not\n+ */\n+function getFetchVersion(projectRoot, pluginInfo, cordovaVersion) {\n+    // Figure out the project requirements\n+    if (pluginInfo.engines && pluginInfo.engines.cordovaDependencies) {\n+        var pluginList = getInstalledPlugins(projectRoot);\n+        var pluginMap = {};\n+\n+        pluginList.forEach(function(plugin) {\n+            pluginMap[plugin.id] = plugin.version;\n+        });\n+\n+        return cordova_util.getInstalledPlatformsWithVersions(projectRoot)\n+        .then(function(platformVersions) {\n+            return determinePluginVersionToFetch(\n+                pluginInfo.versions,\n+                pluginInfo.engines.cordovaDependencies,\n+                pluginMap,\n+                platformVersions,\n+                cordovaVersion);\n+        });\n+    } else {\n+        // If we have no engine, we want to fall back to the default behavior\n+        events.emit('verbose', 'No plugin engine info found or not using registry, falling back to latest or pinned version');\n+        return Q(null);\n+    }\n+}\n+\n+function findVersion(versions, version) {\n+    var cleanedVersion = semver.clean(version);\n+    for(var i = 0; i < versions.length; i++) {\n+        if(semver.clean(versions[i]) === cleanedVersion) {\n+            return versions[i];\n+        }\n+    }\n+    return null;\n+}\n+\n+/*\n+ * The engine entry maps plugin versions to constraints like so:\n+ *  {\n+ *      '1.0.0' : { 'cordova': '<5.0.0' },\n+ *      '<2.0.0': {\n+ *          'cordova': '>=5.0.0',\n+ *          'cordova-ios': '~5.0.0',\n+ *          'cordova-plugin-camera': '~5.0.0'\n+ *      },\n+ *      '3.0.0' : { 'cordova-ios': '>5.0.0' }\n+ *  }\n+ *\n+ * See cordova-spec/plugin_fetch.spec.js for test cases and examples\n+ */\n+function determinePluginVersionToFetch(allVersions, engine, pluginMap, platformMap, cordovaVersion) {\n+    // Filters out pre-release versions\n+    var latest = semver.maxSatisfying(allVersions, '>=0.0.0');\n+\n+    var versions = [];\n+    var upperBound = null;\n+    var upperBoundRange = null;\n+\n+    for(var version in engine) {\n+        if(semver.valid(semver.clean(version)) && !semver.gt(version, latest)) {\n+            versions.push(version);\n+        } else {\n+            // Check if this is an upperbound; validRange() handles whitespace\n+            var cleanedRange = semver.validRange(version);\n+            if(cleanedRange && UPPER_BOUND_REGEX.exec(cleanedRange)) {\n+                // We only care about the highest upper bound that our project does not support\n+                if(getFailedRequirements(engine[version], pluginMap, platformMap, cordovaVersion).length !== 0) {\n+                    var maxMatchingUpperBound = cleanedRange.substring(1);\n+                    if (maxMatchingUpperBound && (!upperBound || semver.gt(maxMatchingUpperBound, upperBound))) {\n+                        upperBound = maxMatchingUpperBound;\n+                        upperBoundRange = version;\n+                    }\n+                }\n+            }\n+        }\n+    }\n+\n+    // Handle the lower end of versions by giving them a satisfied engine\n+    if(!findVersion(versions, '0.0.0')) {\n+        versions.push('0.0.0');\n+        engine['0.0.0'] = {};\n+    }\n+\n+    // Add an entry after the upper bound to handle the versions above the\n+    // upper bound but below the next entry. For example: 0.0.0, <1.0.0, 2.0.0\n+    // needs a 1.0.0 entry that has the same engine as 0.0.0\n+    if(upperBound && !findVersion(versions, upperBound) && !semver.gt(upperBound, latest)) {\n+        versions.push(upperBound);\n+        var below = semver.maxSatisfying(versions, upperBoundRange);\n+\n+        // Get the original entry without trimmed whitespace\n+        below = below ? findVersion(versions, below) : null;\n+        engine[upperBound] = below ? engine[below] : {};\n+    }\n+\n+    // Sort in descending order; we want to start at latest and work back\n+    versions.sort(semver.rcompare);\n+\n+    for(var i = 0; i < versions.length; i++) {\n+        if(upperBound && semver.lt(versions[i], upperBound)) {\n+            // Because we sorted in desc. order, if the upper bound we found\n+            // applies to this version (and thus the ones below) we can just\n+            // quit\n+            break;\n+        }\n+\n+        var range = i? ('>=' + versions[i] + ' <' + versions[i-1]) : ('>=' + versions[i]);\n+        var maxMatchingVersion = semver.maxSatisfying(allVersions, range);\n+\n+        if (maxMatchingVersion && getFailedRequirements(engine[versions[i]], pluginMap, platformMap, cordovaVersion).length === 0) {\n+\n+            // Because we sorted in descending order, we can stop searching once\n+            // we hit a satisfied constraint\n+            if (maxMatchingVersion !== latest) {\n+                var failedReqs = getFailedRequirements(engine[versions[0]], pluginMap, platformMap, cordovaVersion);\n+\n+                // Warn the user that we are not fetching latest\n+                listUnmetRequirements(failedReqs);\n+                events.emit('warn', 'Fetching highest version of plugin that this project supports: ' + maxMatchingVersion + ' (latest is ' + latest + ')');\n+            }\n+            return maxMatchingVersion;\n+        }\n+    }\n+\n+    // No version of the plugin is satisfied. In this case, we fall back to\n+    // fetching latest or pinned versions, but also output a warning\n+    var latestFailedReqs = versions.length > 0 ? getFailedRequirements(engine[versions[0]], pluginMap, platformMap, cordovaVersion) : [];\n+\n+    // If the upper bound is greater than latest, we need to combine its engine\n+    // requirements with latest to print out in the warning\n+    if(upperBound && semver.satisfies(latest, upperBoundRange)) {\n+        var upperFailedReqs = getFailedRequirements(engine[upperBoundRange], pluginMap, platformMap, cordovaVersion);\n+        upperFailedReqs.forEach(function(failedReq) {\n+            for(var i = 0; i < latestFailedReqs.length; i++) {\n+                if(latestFailedReqs[i].dependency === failedReq.dependency) {\n+                    // Not going to overcomplicate things and actually merge the ranges\n+                    latestFailedReqs[i].required = latestFailedReqs[i].required + ' AND ' + failedReq.required;\n+                    return;\n+                }\n+            }\n+\n+            // There is no req to merge it with\n+            latestFailedReqs.push(failedReq);\n+        });\n+    }\n+\n+    listUnmetRequirements(latestFailedReqs);\n+    events.emit('warn', 'Current project does not satisfy the engine requirements specified by any version of this plugin. Fetching latest or pinned version of plugin anyway (may be incompatible)');\n+\n+    // No constraints were satisfied\n+    return null;\n+}\n+\n+\n+function getFailedRequirements(reqs, pluginMap, platformMap, cordovaVersion) {\n+    var failed = [];\n+\n+    for (var req in reqs) {\n+        if(reqs.hasOwnProperty(req) && typeof req === 'string' && semver.validRange(reqs[req])) {\n+            var badInstalledVersion = null;\n+            var trimmedReq = req.trim();\n+\n+            if(pluginMap[trimmedReq] && !semver.satisfies(pluginMap[trimmedReq], reqs[req])) {\n+                badInstalledVersion = pluginMap[req];\n+            } else if(trimmedReq === 'cordova' && !semver.satisfies(cordovaVersion, reqs[req])) {\n+                badInstalledVersion = cordovaVersion;\n+            } else if(trimmedReq.indexOf('cordova-') === 0) {\n+                // Might be a platform constraint\n+                var platform = trimmedReq.substring(8);\n+                if(platformMap[platform] && !semver.satisfies(platformMap[platform], reqs[req])) {\n+                    badInstalledVersion = platformMap[platform];\n+                }\n+            }\n+\n+            if(badInstalledVersion) {\n+                failed.push({\n+                    dependency: trimmedReq,\n+                    installed: badInstalledVersion.trim(),\n+                    required: reqs[req].trim()\n+                });\n+            }\n+        }\n+    }\n+\n+    return failed;\n+}\n+\n+function listUnmetRequirements(failedRequirments) {\n+    events.emit('warn', 'Unmet project requirements for latest version of plugin:');","path":"cordova-lib/src/cordova/plugin.js","position":352,"original_position":352,"commit_id":"557b747b3b826e640ebfce301939f83ecfc562e7","original_commit_id":"557b747b3b826e640ebfce301939f83ecfc562e7","user":{"login":"riknoll","id":13754588,"avatar_url":"https://avatars.githubusercontent.com/u/13754588?v=3","gravatar_id":"","url":"https://api.github.com/users/riknoll","html_url":"https://github.com/riknoll","followers_url":"https://api.github.com/users/riknoll/followers","following_url":"https://api.github.com/users/riknoll/following{/other_user}","gists_url":"https://api.github.com/users/riknoll/gists{/gist_id}","starred_url":"https://api.github.com/users/riknoll/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/riknoll/subscriptions","organizations_url":"https://api.github.com/users/riknoll/orgs","repos_url":"https://api.github.com/users/riknoll/repos","events_url":"https://api.github.com/users/riknoll/events{/privacy}","received_events_url":"https://api.github.com/users/riknoll/received_events","type":"User","site_admin":false},"body":"After looking into this, dependent plugins are not subject to any version selection code because of how cordova-lib is written. Latest will always be fetched  (pinned versions won't be taken into account either). Plugins restored with `cordova prepare` are, so we should indeed print out the id in the message. The dependent plugin thing is bad, but I'm going to leave that as a separate issue since it is not a regression. For now, plugin authors should be advised to give versions for their plugin dependencies. ","created_at":"2016-03-02T20:25:56Z","updated_at":"2016-03-02T20:25:56Z","html_url":"https://github.com/apache/cordova-lib/pull/363#discussion_r54785237","pull_request_url":"https://api.github.com/repos/apache/cordova-lib/pulls/363","_links":{"self":{"href":"https://api.github.com/repos/apache/cordova-lib/pulls/comments/54785237"},"html":{"href":"https://github.com/apache/cordova-lib/pull/363#discussion_r54785237"},"pull_request":{"href":"https://api.github.com/repos/apache/cordova-lib/pulls/363"}}},"pull_request":{"url":"https://api.github.com/repos/apache/cordova-lib/pulls/363","id":56961766,"html_url":"https://github.com/apache/cordova-lib/pull/363","diff_url":"https://github.com/apache/cordova-lib/pull/363.diff","patch_url":"https://github.com/apache/cordova-lib/pull/363.patch","issue_url":"https://api.github.com/repos/apache/cordova-lib/issues/363","number":363,"state":"open","locked":false,"title":"New plugin version selection implementation","user":{"login":"riknoll","id":13754588,"avatar_url":"https://avatars.githubusercontent.com/u/13754588?v=3","gravatar_id":"","url":"https://api.github.com/users/riknoll","html_url":"https://github.com/riknoll","followers_url":"https://api.github.com/users/riknoll/followers","following_url":"https://api.github.com/users/riknoll/following{/other_user}","gists_url":"https://api.github.com/users/riknoll/gists{/gist_id}","starred_url":"https://api.github.com/users/riknoll/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/riknoll/subscriptions","organizations_url":"https://api.github.com/users/riknoll/orgs","repos_url":"https://api.github.com/users/riknoll/repos","events_url":"https://api.github.com/users/riknoll/events{/privacy}","received_events_url":"https://api.github.com/users/riknoll/received_events","type":"User","site_admin":false},"body":"@stevengill @dblotsky please review. This is an implementation for the plugin version selection scheme that Dmitry and I proposed in [this discuss PR](https://github.com/cordova/cordova-discuss/pull/30). I'd appreciate some feedback! I have some docs written up for this too, I'm just holding off on that PR just yet.","created_at":"2016-01-23T00:55:03Z","updated_at":"2016-03-02T20:25:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d967b8e18149cdada295a343f2c1b27f613566c0","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/apache/cordova-lib/pulls/363/commits","review_comments_url":"https://api.github.com/repos/apache/cordova-lib/pulls/363/comments","review_comment_url":"https://api.github.com/repos/apache/cordova-lib/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/cordova-lib/issues/363/comments","statuses_url":"https://api.github.com/repos/apache/cordova-lib/statuses/557b747b3b826e640ebfce301939f83ecfc562e7","head":{"label":"MSOpenTech:plugin-fetching-proposal","ref":"plugin-fetching-proposal","sha":"557b747b3b826e640ebfce301939f83ecfc562e7","user":{"login":"MSOpenTech","id":1638184,"avatar_url":"https://avatars.githubusercontent.com/u/1638184?v=3","gravatar_id":"","url":"https://api.github.com/users/MSOpenTech","html_url":"https://github.com/MSOpenTech","followers_url":"https://api.github.com/users/MSOpenTech/followers","following_url":"https://api.github.com/users/MSOpenTech/following{/other_user}","gists_url":"https://api.github.com/users/MSOpenTech/gists{/gist_id}","starred_url":"https://api.github.com/users/MSOpenTech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MSOpenTech/subscriptions","organizations_url":"https://api.github.com/users/MSOpenTech/orgs","repos_url":"https://api.github.com/users/MSOpenTech/repos","events_url":"https://api.github.com/users/MSOpenTech/events{/privacy}","received_events_url":"https://api.github.com/users/MSOpenTech/received_events","type":"Organization","site_admin":false},"repo":{"id":19624574,"name":"cordova-lib","full_name":"MSOpenTech/cordova-lib","owner":{"login":"MSOpenTech","id":1638184,"avatar_url":"https://avatars.githubusercontent.com/u/1638184?v=3","gravatar_id":"","url":"https://api.github.com/users/MSOpenTech","html_url":"https://github.com/MSOpenTech","followers_url":"https://api.github.com/users/MSOpenTech/followers","following_url":"https://api.github.com/users/MSOpenTech/following{/other_user}","gists_url":"https://api.github.com/users/MSOpenTech/gists{/gist_id}","starred_url":"https://api.github.com/users/MSOpenTech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MSOpenTech/subscriptions","organizations_url":"https://api.github.com/users/MSOpenTech/orgs","repos_url":"https://api.github.com/users/MSOpenTech/repos","events_url":"https://api.github.com/users/MSOpenTech/events{/privacy}","received_events_url":"https://api.github.com/users/MSOpenTech/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/MSOpenTech/cordova-lib","description":"Mirror of Apache Cordova","fork":true,"url":"https://api.github.com/repos/MSOpenTech/cordova-lib","forks_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/forks","keys_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/keys{/key_id}","collaborators_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/teams","hooks_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/hooks","issue_events_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/issues/events{/number}","events_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/events","assignees_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/assignees{/user}","branches_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/branches{/branch}","tags_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/tags","blobs_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/git/refs{/sha}","trees_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/git/trees{/sha}","statuses_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/statuses/{sha}","languages_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/languages","stargazers_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/stargazers","contributors_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/contributors","subscribers_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/subscribers","subscription_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/subscription","commits_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/commits{/sha}","git_commits_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/git/commits{/sha}","comments_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/comments{/number}","issue_comment_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/issues/comments{/number}","contents_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/contents/{+path}","compare_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/compare/{base}...{head}","merges_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/merges","archive_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/downloads","issues_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/issues{/number}","pulls_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/pulls{/number}","milestones_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/milestones{/number}","notifications_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/labels{/name}","releases_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/releases{/id}","deployments_url":"https://api.github.com/repos/MSOpenTech/cordova-lib/deployments","created_at":"2014-05-09T20:30:32Z","updated_at":"2015-05-06T08:16:48Z","pushed_at":"2016-03-02T01:00:03Z","git_url":"git://github.com/MSOpenTech/cordova-lib.git","ssh_url":"git@github.com:MSOpenTech/cordova-lib.git","clone_url":"https://github.com/MSOpenTech/cordova-lib.git","svn_url":"https://github.com/MSOpenTech/cordova-lib","homepage":null,"size":43911,"stargazers_count":6,"watchers_count":6,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":0,"forks":4,"open_issues":0,"watchers":6,"default_branch":"master"}},"base":{"label":"apache:master","ref":"master","sha":"3cef0823d7553b4885c12501609a976510f83f96","user":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"repo":{"id":19524397,"name":"cordova-lib","full_name":"apache/cordova-lib","owner":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/apache/cordova-lib","description":"Mirror of Apache Cordova","fork":false,"url":"https://api.github.com/repos/apache/cordova-lib","forks_url":"https://api.github.com/repos/apache/cordova-lib/forks","keys_url":"https://api.github.com/repos/apache/cordova-lib/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/cordova-lib/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/cordova-lib/teams","hooks_url":"https://api.github.com/repos/apache/cordova-lib/hooks","issue_events_url":"https://api.github.com/repos/apache/cordova-lib/issues/events{/number}","events_url":"https://api.github.com/repos/apache/cordova-lib/events","assignees_url":"https://api.github.com/repos/apache/cordova-lib/assignees{/user}","branches_url":"https://api.github.com/repos/apache/cordova-lib/branches{/branch}","tags_url":"https://api.github.com/repos/apache/cordova-lib/tags","blobs_url":"https://api.github.com/repos/apache/cordova-lib/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/cordova-lib/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/cordova-lib/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/cordova-lib/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/cordova-lib/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/cordova-lib/languages","stargazers_url":"https://api.github.com/repos/apache/cordova-lib/stargazers","contributors_url":"https://api.github.com/repos/apache/cordova-lib/contributors","subscribers_url":"https://api.github.com/repos/apache/cordova-lib/subscribers","subscription_url":"https://api.github.com/repos/apache/cordova-lib/subscription","commits_url":"https://api.github.com/repos/apache/cordova-lib/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/cordova-lib/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/cordova-lib/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/cordova-lib/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/cordova-lib/contents/{+path}","compare_url":"https://api.github.com/repos/apache/cordova-lib/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/cordova-lib/merges","archive_url":"https://api.github.com/repos/apache/cordova-lib/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/cordova-lib/downloads","issues_url":"https://api.github.com/repos/apache/cordova-lib/issues{/number}","pulls_url":"https://api.github.com/repos/apache/cordova-lib/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/cordova-lib/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/cordova-lib/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/cordova-lib/labels{/name}","releases_url":"https://api.github.com/repos/apache/cordova-lib/releases{/id}","deployments_url":"https://api.github.com/repos/apache/cordova-lib/deployments","created_at":"2014-05-07T07:00:06Z","updated_at":"2016-02-19T12:39:05Z","pushed_at":"2016-03-02T01:00:03Z","git_url":"git://github.com/apache/cordova-lib.git","ssh_url":"git@github.com:apache/cordova-lib.git","clone_url":"https://github.com/apache/cordova-lib.git","svn_url":"https://github.com/apache/cordova-lib","homepage":null,"size":45250,"stargazers_count":116,"watchers_count":116,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":188,"mirror_url":"git://git.apache.org/cordova-lib.git","open_issues_count":20,"forks":188,"open_issues":20,"watchers":116,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/cordova-lib/pulls/363"},"html":{"href":"https://github.com/apache/cordova-lib/pull/363"},"issue":{"href":"https://api.github.com/repos/apache/cordova-lib/issues/363"},"comments":{"href":"https://api.github.com/repos/apache/cordova-lib/issues/363/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/cordova-lib/pulls/363/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/cordova-lib/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/cordova-lib/pulls/363/commits"},"statuses":{"href":"https://api.github.com/repos/apache/cordova-lib/statuses/557b747b3b826e640ebfce301939f83ecfc562e7"}}}}