{"action":"created","comment":{"url":"https://api.github.com/repos/src-d/blog/pulls/comments/180716792","pull_request_review_id":111183793,"id":180716792,"diff_hunk":"@@ -0,0 +1,1355 @@\n+---\n+author: vadim\n+date: 2018-04-02\n+title: \"go-license-detector\"\n+image: /post/gld/wtfpl.png\n+description: \"Detecting the license of an open source projects is harder than it seems. We have created go-license-detector, a Go library and command line application to solve that task.\"\n+categories: [\"science\", \"technical\"]\n+---\n+\n+While working on [Public Git Archive](https://github.com/src-d/datasets/PublicGitArchive), we\n+thought that it would be handy to include the license of each project in the index file, so that\n+people could easily filter \"grey\" repositories without a clear license. Besides, we were\n+curious about the licenses distribution. GitHub already detects licenses by leveraging\n+[benbalter/licensee](https://github.com/benbalter/licensee) Ruby library and the easy solution was\n+to query GitHub API. However, we were not satisfied with\n+it's detection quality: many projects which actually contain the license file in a non-standard\n+format are missed, and some are misclassified. This is how\n+[go-license-detector](https://github.com/src-d/go-license-detector) was born.\n+\n+The goals were defined from the very beginning:\n+\n+1. Favor detection rate to the classification accuracy (target data mining instead of compliance).\n+2. Perform fast.\n+3. Detect as many licenses as possible on the [hand-collected dataset of 1,000 top-starred repositories\n+on GitHub](https://github.com/src-d/go-license-detector/blob/master/licensedb/dataset.zip).\n+4. Comply with SPDX [licenses list](https://github.com/spdx/license-list-data) and\n+[detection guidelines](https://spdx.org/spdx-license-list/matching-guidelines).\n+\n+(1) means that we should rather label a project with a bit inaccurate license than miss it's\n+license completely. The open source compliance departments will not be satisfied with this choice,\n+as they need the opposite: the missed projects are manually studied. (2) restricts from using a\n+scripting language such as Python or Ruby, and we chose Go for our implementation. (3) paves\n+the way to many technical tricks, hacks and heuristics and enables any hardcore and complex code.\n+(4) is the only way to obtain the database of 400 different licenses validated by professional\n+lawyers.\n+\n+The following table compares the current go-license-detector with GitHub's built-in license detector,\n+Google's licenseclassifier and Ben Boyter's `lc` on the\n+[reference 1k dataset](https://github.com/src-d/go-license-detector/blob/master/licensedb/dataset.zip):\n+\n+|Detector|Detection rate|Time to scan, sec|\n+|:-------|:----------------------------------------:|:-----------------------------------------|\n+|[go-license-detector](https://github.com/src-d/go-license-detector)| 99% \\\\(\\\\quad(\\\\frac{897}{902})\\\\) | 16 |\n+|[benbalter/licensee](https://github.com/benbalter/licensee)| 75% \\\\(\\\\quad(\\\\frac{673}{902})\\\\) | 111 |\n+|[google/licenseclassifier](https://github.com/google/licenseclassifier)| 76% \\\\(\\\\quad(\\\\frac{682}{902})\\\\) | 907 |\n+|[boyter/lc](https://github.com/boyter/lc)| 88% \\\\(\\\\quad(\\\\frac{797}{902})\\\\) | 548 |\n+\n+The total number of repositories in the dataset is 958, however, only 902 contain any pointer to\n+the license - we looked though each of them. The rest are mainly \"awesome lists\" and Chinese projects\n+and translations of the western books. We filed issues for the maintainers to clarify the license\n+[\\[1\\]](https://github.com/DrkSephy/es6-cheatsheet/issues/90)\n+[\\[2\\]](https://github.com/kdn251/interviews/issues/63)\n+[\\[3\\]](https://github.com/markerikson/react-redux-links/issues/87)\n+[\\[4\\]](https://github.com/CodeHubApp/CodeHub/issues/441)\n+[\\[5\\]](https://github.com/h4cc/awesome-elixir/issues/4400)\n+[\\[6\\]](https://github.com/fffaraz/awesome-cpp/issues/449).\n+Few added the license; some maintainers even demonstrated aggression.\n+We also encountered two licenses which were not included into SPDX and reported them:\n+[\\[1\\]](https://github.com/spdx/license-list-XML/issues/611)\n+[\\[2\\]](https://github.com/spdx/license-list-XML/issues/612).\n+\n+#### How we measured the time\n+\n+Hardware: Intel Core i7-7500U (2x2 threads), 2x8GB LPDDR3@1867MHz.\n+\n+```bash\n+$ cd $(go env GOPATH)/src/gopkg.in/src-d/go-license-detector.v2/licensedb\n+$ mkdir dataset && cd dataset\n+$ unzip ../dataset.zip\n+$ # src-d/go-license-detector\n+$ time license-detector * \\\n+  | grep -Pzo '\\n[-0-9a-zA-Z]+\\n\\tno license' | grep -Pa '\\tno ' | wc -l\n+$ # benbalter/licensee\n+$ time ls -1 | xargs -n1 -P4 licensee \\\n+  | grep -E \"^License: Other\" | wc -l\n+$ # google/licenseclassifier\n+$ time find -type f -print | xargs -n1 -P4 identify_license \\\n+  | cut -d/ -f2 | sort | uniq | wc -l\n+$ # boyter/lc\n+$ time lc . \\\n+  | grep -vE 'NOASSERTION|----|Directory' | cut -d\" \" -f1 | sort | uniq | wc -l\n+```\n+\n+## Algorithm\n+\n+We have implemented license detection based on the license and README files for now, and wish to\n+add fine-grained scanning of source code files in the future (do you want to help us?). Given the\n+stated license text, we compare it to the texts in the SPDX database and record the match. The naive\n+way of making the comparisons is to calculate the\n+[Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance)\n+between the query and each of the examples. This is not fast at all for the two reasons:\n+\n+1. The complexity is linear to the number of examples.\n+2. The complexity is linear to the size of the difference. Since we've always got very few matches,\n+the rest of the distances will be slow to calculate.\n+\n+These two reasons confidently render the naive approach unusable.\n+\n+The core of go-license-detector's detection mechanism is [Locality Sensitive Hashing](https://en.wikipedia.org/wiki/Locality-sensitive_hashing).\n+We treat each license as a TF-IDF-weighted bag-of-words - that is, as a set of words where every\n+word has a weight corresponding to the frequency in the license text (term frequency) and\n+throughout the whole database (document frequency). This is a proven approach for large scale\n+similarity detection which we used multiple times in the past. Although 400 items is clearly\n+not large scale at all, it still makes sense to employ LSH because of the O(1) complexity\n+guarantee. We saw that it works reasonably well in practice and introduces the minimal overhead,\n+say 20MB of memory for the hashes and the vocabulary. The hashing algorithm which we use is\n+[Weighted MinHash](http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36928.pdf)\n+- again, battle-tested in the past, e.g. in [Apollo](https://github.com/src-d/apollo) or\n+[bags deduplication](https://blog.sourced.tech/post/minhashcuda/).\n+We set 75% Jaccard similarity threshold and hash length 154\n+after careful tuning of the false positive vs. false negative vs. performance trade-off.\n+Since we discard the text structure by treating sequences as sets, we further calculate the Levenshtein\n+distance to the matched database records in order to determine the precise confidence value.\n+\n+We look at the README file if the analyzed project does not contain a license file. This happens\n+in more than 7% of the cases in the 1k dataset and x% in Public Git Archive (182,000 repositories).","path":"content/post/gld.md","position":116,"original_position":116,"commit_id":"f1c1f5b8d27ecdebc1f6f9610c3eda494f07d392","original_commit_id":"f1c1f5b8d27ecdebc1f6f9610c3eda494f07d392","user":{"login":"vmarkovtsev","id":2793551,"avatar_url":"https://avatars3.githubusercontent.com/u/2793551?v=4","gravatar_id":"","url":"https://api.github.com/users/vmarkovtsev","html_url":"https://github.com/vmarkovtsev","followers_url":"https://api.github.com/users/vmarkovtsev/followers","following_url":"https://api.github.com/users/vmarkovtsev/following{/other_user}","gists_url":"https://api.github.com/users/vmarkovtsev/gists{/gist_id}","starred_url":"https://api.github.com/users/vmarkovtsev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vmarkovtsev/subscriptions","organizations_url":"https://api.github.com/users/vmarkovtsev/orgs","repos_url":"https://api.github.com/users/vmarkovtsev/repos","events_url":"https://api.github.com/users/vmarkovtsev/events{/privacy}","received_events_url":"https://api.github.com/users/vmarkovtsev/received_events","type":"User","site_admin":false},"body":"Forgot to update!","created_at":"2018-04-11T11:13:37Z","updated_at":"2018-04-11T11:13:37Z","html_url":"https://github.com/src-d/blog/pull/195#discussion_r180716792","pull_request_url":"https://api.github.com/repos/src-d/blog/pulls/195","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/src-d/blog/pulls/comments/180716792"},"html":{"href":"https://github.com/src-d/blog/pull/195#discussion_r180716792"},"pull_request":{"href":"https://api.github.com/repos/src-d/blog/pulls/195"}},"in_reply_to_id":180232263},"pull_request":{"url":"https://api.github.com/repos/src-d/blog/pulls/195","id":178697696,"html_url":"https://github.com/src-d/blog/pull/195","diff_url":"https://github.com/src-d/blog/pull/195.diff","patch_url":"https://github.com/src-d/blog/pull/195.patch","issue_url":"https://api.github.com/repos/src-d/blog/issues/195","number":195,"state":"open","locked":false,"title":"[WIP] go-license-detector","user":{"login":"vmarkovtsev","id":2793551,"avatar_url":"https://avatars3.githubusercontent.com/u/2793551?v=4","gravatar_id":"","url":"https://api.github.com/users/vmarkovtsev","html_url":"https://github.com/vmarkovtsev","followers_url":"https://api.github.com/users/vmarkovtsev/followers","following_url":"https://api.github.com/users/vmarkovtsev/following{/other_user}","gists_url":"https://api.github.com/users/vmarkovtsev/gists{/gist_id}","starred_url":"https://api.github.com/users/vmarkovtsev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vmarkovtsev/subscriptions","organizations_url":"https://api.github.com/users/vmarkovtsev/orgs","repos_url":"https://api.github.com/users/vmarkovtsev/repos","events_url":"https://api.github.com/users/vmarkovtsev/events{/privacy}","received_events_url":"https://api.github.com/users/vmarkovtsev/received_events","type":"User","site_admin":false},"body":"TODO:\r\n\r\n- [x] Add logo\r\n- [ ] Add implementation flesh\r\n- [ ] Add funny observations skin\r\n- [x] Add PGA stats (friendly ping @eiso I believe in your super system)\r\n\r\nDeployed as ","created_at":"2018-03-31T19:52:18Z","updated_at":"2018-04-11T11:13:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"db2ab1c5d613216a7653eea9b5ccc545e21c197e","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/src-d/blog/pulls/195/commits","review_comments_url":"https://api.github.com/repos/src-d/blog/pulls/195/comments","review_comment_url":"https://api.github.com/repos/src-d/blog/pulls/comments{/number}","comments_url":"https://api.github.com/repos/src-d/blog/issues/195/comments","statuses_url":"https://api.github.com/repos/src-d/blog/statuses/f1c1f5b8d27ecdebc1f6f9610c3eda494f07d392","head":{"label":"vmarkovtsev:gld","ref":"gld","sha":"f1c1f5b8d27ecdebc1f6f9610c3eda494f07d392","user":{"login":"vmarkovtsev","id":2793551,"avatar_url":"https://avatars3.githubusercontent.com/u/2793551?v=4","gravatar_id":"","url":"https://api.github.com/users/vmarkovtsev","html_url":"https://github.com/vmarkovtsev","followers_url":"https://api.github.com/users/vmarkovtsev/followers","following_url":"https://api.github.com/users/vmarkovtsev/following{/other_user}","gists_url":"https://api.github.com/users/vmarkovtsev/gists{/gist_id}","starred_url":"https://api.github.com/users/vmarkovtsev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vmarkovtsev/subscriptions","organizations_url":"https://api.github.com/users/vmarkovtsev/orgs","repos_url":"https://api.github.com/users/vmarkovtsev/repos","events_url":"https://api.github.com/users/vmarkovtsev/events{/privacy}","received_events_url":"https://api.github.com/users/vmarkovtsev/received_events","type":"User","site_admin":false},"repo":{"id":60337212,"name":"blog","full_name":"vmarkovtsev/blog","owner":{"login":"vmarkovtsev","id":2793551,"avatar_url":"https://avatars3.githubusercontent.com/u/2793551?v=4","gravatar_id":"","url":"https://api.github.com/users/vmarkovtsev","html_url":"https://github.com/vmarkovtsev","followers_url":"https://api.github.com/users/vmarkovtsev/followers","following_url":"https://api.github.com/users/vmarkovtsev/following{/other_user}","gists_url":"https://api.github.com/users/vmarkovtsev/gists{/gist_id}","starred_url":"https://api.github.com/users/vmarkovtsev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vmarkovtsev/subscriptions","organizations_url":"https://api.github.com/users/vmarkovtsev/orgs","repos_url":"https://api.github.com/users/vmarkovtsev/repos","events_url":"https://api.github.com/users/vmarkovtsev/events{/privacy}","received_events_url":"https://api.github.com/users/vmarkovtsev/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/vmarkovtsev/blog","description":"auto-deployable static websites","fork":true,"url":"https://api.github.com/repos/vmarkovtsev/blog","forks_url":"https://api.github.com/repos/vmarkovtsev/blog/forks","keys_url":"https://api.github.com/repos/vmarkovtsev/blog/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vmarkovtsev/blog/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vmarkovtsev/blog/teams","hooks_url":"https://api.github.com/repos/vmarkovtsev/blog/hooks","issue_events_url":"https://api.github.com/repos/vmarkovtsev/blog/issues/events{/number}","events_url":"https://api.github.com/repos/vmarkovtsev/blog/events","assignees_url":"https://api.github.com/repos/vmarkovtsev/blog/assignees{/user}","branches_url":"https://api.github.com/repos/vmarkovtsev/blog/branches{/branch}","tags_url":"https://api.github.com/repos/vmarkovtsev/blog/tags","blobs_url":"https://api.github.com/repos/vmarkovtsev/blog/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vmarkovtsev/blog/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vmarkovtsev/blog/git/refs{/sha}","trees_url":"https://api.github.com/repos/vmarkovtsev/blog/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vmarkovtsev/blog/statuses/{sha}","languages_url":"https://api.github.com/repos/vmarkovtsev/blog/languages","stargazers_url":"https://api.github.com/repos/vmarkovtsev/blog/stargazers","contributors_url":"https://api.github.com/repos/vmarkovtsev/blog/contributors","subscribers_url":"https://api.github.com/repos/vmarkovtsev/blog/subscribers","subscription_url":"https://api.github.com/repos/vmarkovtsev/blog/subscription","commits_url":"https://api.github.com/repos/vmarkovtsev/blog/commits{/sha}","git_commits_url":"https://api.github.com/repos/vmarkovtsev/blog/git/commits{/sha}","comments_url":"https://api.github.com/repos/vmarkovtsev/blog/comments{/number}","issue_comment_url":"https://api.github.com/repos/vmarkovtsev/blog/issues/comments{/number}","contents_url":"https://api.github.com/repos/vmarkovtsev/blog/contents/{+path}","compare_url":"https://api.github.com/repos/vmarkovtsev/blog/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vmarkovtsev/blog/merges","archive_url":"https://api.github.com/repos/vmarkovtsev/blog/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vmarkovtsev/blog/downloads","issues_url":"https://api.github.com/repos/vmarkovtsev/blog/issues{/number}","pulls_url":"https://api.github.com/repos/vmarkovtsev/blog/pulls{/number}","milestones_url":"https://api.github.com/repos/vmarkovtsev/blog/milestones{/number}","notifications_url":"https://api.github.com/repos/vmarkovtsev/blog/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vmarkovtsev/blog/labels{/name}","releases_url":"https://api.github.com/repos/vmarkovtsev/blog/releases{/id}","deployments_url":"https://api.github.com/repos/vmarkovtsev/blog/deployments","created_at":"2016-06-03T09:45:55Z","updated_at":"2016-11-08T15:15:18Z","pushed_at":"2018-04-09T12:07:21Z","git_url":"git://github.com/vmarkovtsev/blog.git","ssh_url":"git@github.com:vmarkovtsev/blog.git","clone_url":"https://github.com/vmarkovtsev/blog.git","svn_url":"https://github.com/vmarkovtsev/blog","homepage":"http://mcuadros.github.io/autohugo","size":64132,"stargazers_count":0,"watchers_count":0,"language":"HTML","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"src-d:master","ref":"master","sha":"e53eb0c080619252d4acb619187df61f15e62935","user":{"login":"src-d","id":15128793,"avatar_url":"https://avatars2.githubusercontent.com/u/15128793?v=4","gravatar_id":"","url":"https://api.github.com/users/src-d","html_url":"https://github.com/src-d","followers_url":"https://api.github.com/users/src-d/followers","following_url":"https://api.github.com/users/src-d/following{/other_user}","gists_url":"https://api.github.com/users/src-d/gists{/gist_id}","starred_url":"https://api.github.com/users/src-d/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/src-d/subscriptions","organizations_url":"https://api.github.com/users/src-d/orgs","repos_url":"https://api.github.com/users/src-d/repos","events_url":"https://api.github.com/users/src-d/events{/privacy}","received_events_url":"https://api.github.com/users/src-d/received_events","type":"Organization","site_admin":false},"repo":{"id":44317537,"name":"blog","full_name":"src-d/blog","owner":{"login":"src-d","id":15128793,"avatar_url":"https://avatars2.githubusercontent.com/u/15128793?v=4","gravatar_id":"","url":"https://api.github.com/users/src-d","html_url":"https://github.com/src-d","followers_url":"https://api.github.com/users/src-d/followers","following_url":"https://api.github.com/users/src-d/following{/other_user}","gists_url":"https://api.github.com/users/src-d/gists{/gist_id}","starred_url":"https://api.github.com/users/src-d/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/src-d/subscriptions","organizations_url":"https://api.github.com/users/src-d/orgs","repos_url":"https://api.github.com/users/src-d/repos","events_url":"https://api.github.com/users/src-d/events{/privacy}","received_events_url":"https://api.github.com/users/src-d/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/src-d/blog","description":"source{d} blog","fork":false,"url":"https://api.github.com/repos/src-d/blog","forks_url":"https://api.github.com/repos/src-d/blog/forks","keys_url":"https://api.github.com/repos/src-d/blog/keys{/key_id}","collaborators_url":"https://api.github.com/repos/src-d/blog/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/src-d/blog/teams","hooks_url":"https://api.github.com/repos/src-d/blog/hooks","issue_events_url":"https://api.github.com/repos/src-d/blog/issues/events{/number}","events_url":"https://api.github.com/repos/src-d/blog/events","assignees_url":"https://api.github.com/repos/src-d/blog/assignees{/user}","branches_url":"https://api.github.com/repos/src-d/blog/branches{/branch}","tags_url":"https://api.github.com/repos/src-d/blog/tags","blobs_url":"https://api.github.com/repos/src-d/blog/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/src-d/blog/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/src-d/blog/git/refs{/sha}","trees_url":"https://api.github.com/repos/src-d/blog/git/trees{/sha}","statuses_url":"https://api.github.com/repos/src-d/blog/statuses/{sha}","languages_url":"https://api.github.com/repos/src-d/blog/languages","stargazers_url":"https://api.github.com/repos/src-d/blog/stargazers","contributors_url":"https://api.github.com/repos/src-d/blog/contributors","subscribers_url":"https://api.github.com/repos/src-d/blog/subscribers","subscription_url":"https://api.github.com/repos/src-d/blog/subscription","commits_url":"https://api.github.com/repos/src-d/blog/commits{/sha}","git_commits_url":"https://api.github.com/repos/src-d/blog/git/commits{/sha}","comments_url":"https://api.github.com/repos/src-d/blog/comments{/number}","issue_comment_url":"https://api.github.com/repos/src-d/blog/issues/comments{/number}","contents_url":"https://api.github.com/repos/src-d/blog/contents/{+path}","compare_url":"https://api.github.com/repos/src-d/blog/compare/{base}...{head}","merges_url":"https://api.github.com/repos/src-d/blog/merges","archive_url":"https://api.github.com/repos/src-d/blog/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/src-d/blog/downloads","issues_url":"https://api.github.com/repos/src-d/blog/issues{/number}","pulls_url":"https://api.github.com/repos/src-d/blog/pulls{/number}","milestones_url":"https://api.github.com/repos/src-d/blog/milestones{/number}","notifications_url":"https://api.github.com/repos/src-d/blog/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/src-d/blog/labels{/name}","releases_url":"https://api.github.com/repos/src-d/blog/releases{/id}","deployments_url":"https://api.github.com/repos/src-d/blog/deployments","created_at":"2015-10-15T12:58:09Z","updated_at":"2018-04-10T15:26:28Z","pushed_at":"2018-04-10T15:26:29Z","git_url":"git://github.com/src-d/blog.git","ssh_url":"git@github.com:src-d/blog.git","clone_url":"https://github.com/src-d/blog.git","svn_url":"https://github.com/src-d/blog","homepage":"https://blog.sourced.tech/","size":64254,"stargazers_count":17,"watchers_count":17,"language":"HTML","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":24,"mirror_url":null,"archived":false,"open_issues_count":18,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":24,"open_issues":18,"watchers":17,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/src-d/blog/pulls/195"},"html":{"href":"https://github.com/src-d/blog/pull/195"},"issue":{"href":"https://api.github.com/repos/src-d/blog/issues/195"},"comments":{"href":"https://api.github.com/repos/src-d/blog/issues/195/comments"},"review_comments":{"href":"https://api.github.com/repos/src-d/blog/pulls/195/comments"},"review_comment":{"href":"https://api.github.com/repos/src-d/blog/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/src-d/blog/pulls/195/commits"},"statuses":{"href":"https://api.github.com/repos/src-d/blog/statuses/f1c1f5b8d27ecdebc1f6f9610c3eda494f07d392"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"vmarkovtsev"}}