diff --git a/.editorconfig b/.editorconfig index 1298c650015..28f1abd3add 100644 --- a/.editorconfig +++ b/.editorconfig @@ -24,7 +24,7 @@ indent_size = 2 [*.js] indent_style = space -indent_size = 4 +indent_size = 2 [Makefile] indent_style = tab diff --git a/.eslintrc b/.eslintrc index c7013f27854..4302886d752 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,27 +1,51 @@ root: true extends: + - eslint-config-airbnb-base - eslint:recommended parserOptions: - ecmaVersion: 2015 + ecmaVersion: 2020 env: browser: true - jquery: true es6: true + jquery: true + node: true globals: Clipboard: false CodeMirror: false - emojify: false - SimpleMDE: false - Vue: false Dropzone: false - u2fApi: false + emojify: false hljs: false + SimpleMDE: false + u2fApi: false + Vue: false rules: - no-unused-vars: [error, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, ignoreRestSiblings: true}] - prefer-const: [2, {destructuring: all}] + camelcase: [0] + comma-dangle: [2, only-multiline] + consistent-return: [0] + default-case: [0] + func-names: [0] + max-len: [0] + newline-per-chained-call: [0] + arrow-body-style: [0] + no-alert: [0] + no-continue: [0] + no-mixed-operators: [0] + no-multi-assign: [0] + no-new: [0] + no-param-reassign: [0] + no-plusplus: [0] + no-restricted-syntax: [0] + no-shadow: [0] + no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, ignoreRestSiblings: true}] + no-use-before-define: [0] no-var: [2] + one-var-declaration-per-line: [0] + one-var: [0] + prefer-const: [2, {destructuring: all}] + prefer-destructuring: [0] + radix: [2, as-needed] diff --git a/CHANGELOG.md b/CHANGELOG.md index a92a61b4975..92c3310f2ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,44 @@ This changelog goes through all the changes that have been made in each release without substantial changes to our git log; to see the highlights of what has been added to each release, please refer to the [blog](https://blog.gitea.io). -## [1.10.0-RC2](https://github.com/go-gitea/gitea/releases/tag/v1.10.0-rc2) - 2019-10-30 +## [1.10.0](https://github.com/go-gitea/gitea/releases/tag/v1.10.0) - 2019-11-13 * BREAKING * Fix deadline on update issue or PR via API (#8698) * Hide some user information via API if user doesn't have enough permission (#8655) (#8657) + * Remove legacy handling of drone token (#8191) + * Change repo search to use exact match for topic search. (#7941) + * Add pagination for admin api get orgs and fix only list public orgs bug (#7742) + * Implement the ability to change the ssh port to match what is in the gitea config (#7286) +* SECURITY + * Fix issue with user.fullname (#8903) + * Ignore mentions for users with no access (#8395) + * Be more strict with git arguments (#7715) + * Extract the username and password from the mirror url (#7651) + * reserve .well-known username (#7637) +* FEATURE + * Org/Members: display 2FA members states + optimize sql requests (#7621) + * SetDefaultBranch on pushing to empty repository (#7610) + * Adds side-by-side diff for images (#6784) + * API method to list all commits of a repository (#6408) + * Password Complexity Checks (#6230) + * Add option to initialize repository with labels (#6061) + * Add additional password hash algorithms (#6023) * BUGFIXES + * Allow to merge if file path contains " or \ (#8629) (#8771) + * On windows set core.longpaths true (#8776) (#8786) + * Fix 500 when edit hook (#8782) (#8789) + * Fix Checkbox at RepoSettings Protected Branch (#8799) (#8801) + * Fix SSH2 conditional in key parsing code (#8806) (#8810) + * Fix commit expand button to not go to commit link (#8745) (#8825) + * Fix new user form for non-local users (#8826) (#8828) + * Fix to close opened io resources as soon as not needed (#8839) (#8846) + * Fix edit content button on migrated issue content (#8877) (#8884) + * Fix require external registration password (#8885) (#8890) + * Fix password complexity check on registration (#8887) (#8888) + * Update Github Migration Tests (#8896) (#8938) (#8945) + * Enable punctuations ending mentions (#8889) (#8894) + * Add Close() method to gogitRepository (#8901) (#8956) + * Hotfix for review actions and notifications (#8965) * Expose db.SetMaxOpenConns and allow non MySQL dbs to set conn pool params (#8528) (#8618) * Fix milestone close timestamp (#8728) (#8730) * Fix 500 when getting user as unauthenticated user (#8653) (#8663) @@ -29,22 +62,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * Fix password complexity regex for special characters (#8524) * Prevent .code-view from overriding font on icon fonts (#8614) (#8627) * Allow more than 255 characters for tokens in external_login_user table (#8554) - -## [1.10.0-RC1](https://github.com/go-gitea/gitea/releases/tag/v1.10.0-rc1) - 2019-10-14 -* BREAKING - * Remove legacy handling of drone token (#8191) - * Change repo search to use exact match for topic search. (#7941) - * Add pagination for admin api get orgs and fix only list public orgs bug (#7742) - * Implement the ability to change the ssh port to match what is in the gitea config (#7286) -* FEATURE - * Org/Members: display 2FA members states + optimize sql requests (#7621) - * SetDefaultBranch on pushing to empty repository (#7610) - * Adds side-by-side diff for images (#6784) - * API method to list all commits of a repository (#6408) - * Password Complexity Checks (#6230) - * Add option to initialize repository with labels (#6061) - * Add additional password hash algorithms (#6023) -* BUGFIXES * Fix errors in create org UI regarding team access permission (#8506) * Fix bug on FindExternalUsersByProvider (#8504) * Create .ssh dir as necessary (#8486) @@ -244,10 +261,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * Support setting cookie domain (#6288) * Move migrating repository from frontend to backend (#6200) * Delete releases attachments if release is deleted (#6068) -* SECURITY - * Ignore mentions for users with no access (#8395) - * Be more strict with git arguments (#7715) - * reserve .well-known username (#7637) * TRANSLATION * Latvian translation for home page (#8468) * Add home template italian translation (#8352) @@ -276,7 +289,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * Fix global search result CSS, misc CSS tweaks (#7789) * Tweak label border CSS (#7739) * Fix create menu item widths (#7708) - * Extract the username and password from the mirror url (#7651) * [Branch View] Delete duplicate protection symbol (#7624) * [Branch View] Delete Table Header (#7622) * [Branch View] icons to buttons (#7602) @@ -289,6 +301,14 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * wiki - editor - add buttons 'inline code', 'empty checkbox', 'checked checkbox' (#7243) * Fix Statuses API only shows first 10 statuses: Add paging and extend API GetCommitStatuses (#7141) +## [1.9.6](https://github.com/go-gitea/gitea/releases/tag/v1.9.6) - 2019-11-13 +* BUGFIXES + * Allow to merge if file path contains " or \ (#8629) (#8772) + * Fix 500 when edit hook (#8782) (#8790) + * Fix issue with user.fullname (#8904) + * Update Github Migration Test (#8897) (#8946) + * Add Close() method to gogitRepository (#8901) (#8958) + ## [1.9.5](https://github.com/go-gitea/gitea/releases/tag/v1.9.5) - 2019-10-30 * BREAKING * Hide some user information via API if user doesn't have enough permission (#8655) (#8658) diff --git a/Makefile b/Makefile index 69eb088ba77..a87de5b6f9a 100644 --- a/Makefile +++ b/Makefile @@ -434,7 +434,8 @@ npm-update: npm-check .PHONY: js js: npm - npx eslint public/js + npx eslint web_src/js webpack.config.js + npx webpack .PHONY: css css: npm diff --git a/cmd/hook.go b/cmd/hook.go index f07568dd8b2..9f547362da9 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/private" + "code.gitea.io/gitea/modules/setting" "github.com/urfave/cli" ) @@ -55,7 +56,13 @@ var ( func runHookPreReceive(c *cli.Context) error { if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 { - return nil + if setting.OnlyAllowPushIfGiteaEnvironmentSet { + fail(`Rejecting changes as Gitea environment not set. +If you are pushing over SSH you must push with a key managed by +Gitea or set your environment appropriately.`, "") + } else { + return nil + } } setup("hooks/pre-receive.log") @@ -115,7 +122,13 @@ func runHookPreReceive(c *cli.Context) error { func runHookUpdate(c *cli.Context) error { if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 { - return nil + if setting.OnlyAllowPushIfGiteaEnvironmentSet { + fail(`Rejecting changes as Gitea environment not set. +If you are pushing over SSH you must push with a key managed by +Gitea or set your environment appropriately.`, "") + } else { + return nil + } } setup("hooks/update.log") @@ -125,7 +138,13 @@ func runHookUpdate(c *cli.Context) error { func runHookPostReceive(c *cli.Context) error { if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 { - return nil + if setting.OnlyAllowPushIfGiteaEnvironmentSet { + fail(`Rejecting changes as Gitea environment not set. +If you are pushing over SSH you must push with a key managed by +Gitea or set your environment appropriately.`, "") + } else { + return nil + } } setup("hooks/post-receive.log") diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index 5e26171d9e1..34c3ee9db54 100644 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -190,7 +190,7 @@ PROTOCOL = http DOMAIN = localhost ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/ ; when STATIC_URL_PREFIX is empty it will follow APP_URL -STATIC_URL_PREFIX = +STATIC_URL_PREFIX = ; The address to listen on. Either a IPv4/IPv6 address or the path to a unix socket. HTTP_ADDR = 0.0.0.0 HTTP_PORT = 3000 @@ -383,6 +383,8 @@ MIN_PASSWORD_LENGTH = 6 IMPORT_LOCAL_PATHS = false ; Set to true to prevent all users (including admin) from creating custom git hooks DISABLE_GIT_HOOKS = false +; Set to false to allow pushes to gitea repositories despite having an incomplete environment - NOT RECOMMENDED +ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET = true ;Comma separated list of character classes required to pass minimum complexity. ;If left empty or no valid values are specified, the default values ("lower,upper,digit,spec") will be used. ;Use "off" to disable checking. @@ -515,9 +517,9 @@ SKIP_TLS_VERIFY = false ; Number of history information in each page PAGING_NUM = 10 ; Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy -PROXY_URL = +PROXY_URL = ; Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts. -PROXY_HOSTS = +PROXY_HOSTS = [mailer] ENABLED = false diff --git a/docs/.gitignore b/docs/.gitignore index 55ec469a426..9cd1408bd24 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,3 +1,4 @@ public/ templates/swagger/v1_json.tmpl themes/ +resources/ diff --git a/docs/assets/js/search.js b/docs/assets/js/search.js new file mode 100644 index 00000000000..72d94c9ee20 --- /dev/null +++ b/docs/assets/js/search.js @@ -0,0 +1,176 @@ +function ready(fn) { + if (document.readyState != 'loading') { + fn(); + } else { + document.addEventListener('DOMContentLoaded', fn); + } +} + +ready(doSearch); + +const summaryInclude = 60; +const fuseOptions = { + shouldSort: true, + includeMatches: true, + matchAllTokens: true, + threshold: 0.0, // for parsing diacritics + tokenize: true, + location: 0, + distance: 100, + maxPatternLength: 32, + minMatchCharLength: 1, + keys: [{ + name: "title", + weight: 0.8 + }, + { + name: "contents", + weight: 0.5 + }, + { + name: "tags", + weight: 0.3 + }, + { + name: "categories", + weight: 0.3 + } + ] +}; + +function param(name) { + return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' '); +} + +let searchQuery = param("s"); + +function doSearch() { + if (searchQuery) { + document.getElementById("search-query").value = searchQuery; + executeSearch(searchQuery); + } else { + const para = document.createElement("P"); + para.innerText = "Please enter a word or phrase above"; + document.getElementById("search-results").appendChild(para); + } +} + +function getJSON(url, fn) { + const request = new XMLHttpRequest(); + request.open('GET', url, true); + request.onload = function () { + if (request.status >= 200 && request.status < 400) { + const data = JSON.parse(request.responseText); + fn(data); + } else { + console.log("Target reached on " + url + " with error " + request.status); + } + }; + request.onerror = function () { + console.log("Connection error " + request.status); + }; + request.send(); +} + +function executeSearch(searchQuery) { + getJSON("/" + document.LANG + "/index.json", function (data) { + const pages = data; + const fuse = new Fuse(pages, fuseOptions); + const result = fuse.search(searchQuery); + console.log({ + "matches": result + }); + document.getElementById("search-results").innerHTML = ""; + if (result.length > 0) { + populateResults(result); + } else { + const para = document.createElement("P"); + para.innerText = "No matches found"; + document.getElementById("search-results").appendChild(para); + } + }); +} + +function populateResults(result) { + result.forEach(function (value, key) { + const content = value.item.contents; + let snippet = ""; + const snippetHighlights = []; + if (fuseOptions.tokenize) { + snippetHighlights.push(searchQuery); + value.matches.forEach(function (mvalue) { + if (mvalue.key === "tags" || mvalue.key === "categories") { + snippetHighlights.push(mvalue.value); + } else if (mvalue.key === "contents") { + const ind = content.toLowerCase().indexOf(searchQuery.toLowerCase()); + const start = ind - summaryInclude > 0 ? ind - summaryInclude : 0; + const end = ind + searchQuery.length + summaryInclude < content.length ? ind + searchQuery.length + summaryInclude : content.length; + snippet += content.substring(start, end); + if (ind > -1) { + snippetHighlights.push(content.substring(ind, ind + searchQuery.length)) + } else { + snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1)); + } + } + }); + } + + if (snippet.length < 1) { + snippet += content.substring(0, summaryInclude * 2); + } + //pull template from hugo templarte definition + const templateDefinition = document.getElementById("search-result-template").innerHTML; + //replace values + const output = render(templateDefinition, { + key: key, + title: value.item.title, + link: value.item.permalink, + tags: value.item.tags, + categories: value.item.categories, + snippet: snippet + }); + document.getElementById("search-results").appendChild(htmlToElement(output)); + + snippetHighlights.forEach(function (snipvalue) { + new Mark(document.getElementById("summary-" + key)).mark(snipvalue); + }); + + }); +} + +function render(templateString, data) { + let conditionalMatches, copy; + const conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g; + //since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop + copy = templateString; + while ((conditionalMatches = conditionalPattern.exec(templateString)) !== null) { + if (data[conditionalMatches[1]]) { + //valid key, remove conditionals, leave content. + copy = copy.replace(conditionalMatches[0], conditionalMatches[2]); + } else { + //not valid, remove entire section + copy = copy.replace(conditionalMatches[0], ''); + } + } + templateString = copy; + //now any conditionals removed we can do simple substitution + let key, find, re; + for (key in data) { + find = '\\$\\{\\s*' + key + '\\s*\\}'; + re = new RegExp(find, 'g'); + templateString = templateString.replace(re, data[key]); + } + return templateString; +} + +/** + * By Mark Amery: https://stackoverflow.com/a/35385518 + * @param {String} HTML representing a single element + * @return {Element} + */ +function htmlToElement(html) { + const template = document.createElement('template'); + html = html.trim(); // Never return a text node of whitespace as the result + template.innerHTML = html; + return template.content.firstChild; +} diff --git a/docs/config.yaml b/docs/config.yaml index 23d12573374..ccdffeed81e 100644 --- a/docs/config.yaml +++ b/docs/config.yaml @@ -18,7 +18,13 @@ params: description: Git with a cup of tea author: The Gitea Authors website: https://docs.gitea.io - version: 1.9.5 + version: 1.10.0 + +outputs: + home: + - HTML + - RSS + - JSON menu: page: diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index e5236205fe2..ab353f9d5aa 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -244,6 +244,7 @@ relation to port exhaustion. authentication provided email. - `DISABLE_GIT_HOOKS`: **false**: Set to `true` to prevent all users (including admin) from creating custom git hooks. +- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to gitea repositories you should set the environment appropriately. - `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server. - `INTERNAL_TOKEN`: **\**: Secret used to validate communication within Gitea binary. - `INTERNAL_TOKEN_URI`: ****: Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`) @@ -306,6 +307,7 @@ relation to port exhaustion. - `AUTO_WATCH_ON_CHANGES`: **false**: Enable this to make users watch a repository after their first commit to it - `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private". - `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation. +- `ALLOW_ONLY_EXTERNAL_REGISTRATION`: **false** Set to true to force registration only using third-party services. ## Webhook (`webhook`) diff --git a/docs/content/doc/help.en-us.md b/docs/content/doc/help.en-us.md index 5ad1dd7f1ed..635cb8931e3 100644 --- a/docs/content/doc/help.en-us.md +++ b/docs/content/doc/help.en-us.md @@ -2,12 +2,12 @@ date: "2017-01-20T15:00:00+08:00" title: "Help" slug: "help" -weight: 50 +weight: 5 toc: false draft: false menu: sidebar: name: "Help" - weight: 50 + weight: 5 identifier: "help" --- diff --git a/docs/content/doc/help.fr-fr.md b/docs/content/doc/help.fr-fr.md new file mode 100644 index 00000000000..ab0cedccfc3 --- /dev/null +++ b/docs/content/doc/help.fr-fr.md @@ -0,0 +1,13 @@ +--- +date: "2017-01-20T15:00:00+08:00" +title: "Aide" +slug: "help" +weight: 5 +toc: false +draft: false +menu: + sidebar: + name: "Aide" + weight: 5 + identifier: "help" +--- diff --git a/docs/content/doc/help.zh-cn.md b/docs/content/doc/help.zh-cn.md index 6af7aa1719b..9465cd5464c 100644 --- a/docs/content/doc/help.zh-cn.md +++ b/docs/content/doc/help.zh-cn.md @@ -2,12 +2,12 @@ date: "2017-01-20T15:00:00+08:00" title: "帮助" slug: "help" -weight: 50 +weight: 5 toc: false draft: false menu: sidebar: name: "帮助" - weight: 50 + weight: 5 identifier: "help" --- diff --git a/docs/content/doc/help.zh-tw.md b/docs/content/doc/help.zh-tw.md new file mode 100644 index 00000000000..c9cd794d81d --- /dev/null +++ b/docs/content/doc/help.zh-tw.md @@ -0,0 +1,13 @@ +--- +date: "2017-01-20T15:00:00+08:00" +title: "救命" +slug: "help" +weight: 5 +toc: false +draft: false +menu: + sidebar: + name: "救命" + weight: 5 + identifier: "help" +--- diff --git a/docs/content/doc/help/search.en-us.md b/docs/content/doc/help/search.en-us.md new file mode 100644 index 00000000000..93c154bde2c --- /dev/null +++ b/docs/content/doc/help/search.en-us.md @@ -0,0 +1,25 @@ +--- +date: "2019-11-12T16:00:00+02:00" +title: "Search" +slug: "search" +weight: 4 +toc: true +draft: false +menu: + sidebar: + parent: "help" + name: "Search" + weight: 4 + identifier: "search" +sitemap: + priority : 0.1 +layout: "search" +--- + + +This file exists solely to respond to /search URL with the related `search` layout template. + +No content shown here is rendered, all content is based in the template layouts/doc/search.html + +Setting a very low sitemap priority will tell search engines this is not important content. + diff --git a/docs/content/doc/help/search.fr-fr.md b/docs/content/doc/help/search.fr-fr.md new file mode 100644 index 00000000000..3507e9efe86 --- /dev/null +++ b/docs/content/doc/help/search.fr-fr.md @@ -0,0 +1,25 @@ +--- +date: "2019-11-12T16:00:00+02:00" +title: "Chercher" +slug: "search" +weight: 4 +toc: true +draft: false +menu: + sidebar: + parent: "help" + name: "Chercher" + weight: 4 + identifier: "search" +sitemap: + priority : 0.1 +layout: "search" +--- + + +This file exists solely to respond to /search URL with the related `search` layout template. + +No content shown here is rendered, all content is based in the template layouts/doc/search.html + +Setting a very low sitemap priority will tell search engines this is not important content. + diff --git a/docs/content/doc/help/search.zh-cn.md b/docs/content/doc/help/search.zh-cn.md new file mode 100644 index 00000000000..a51860aacdb --- /dev/null +++ b/docs/content/doc/help/search.zh-cn.md @@ -0,0 +1,25 @@ +--- +date: "2019-11-12T16:00:00+02:00" +title: "搜索" +slug: "search" +weight: 4 +toc: true +draft: false +menu: + sidebar: + parent: "help" + name: "搜索" + weight: 4 + identifier: "search" +sitemap: + priority : 0.1 +layout: "search" +--- + + +This file exists solely to respond to /search URL with the related `search` layout template. + +No content shown here is rendered, all content is based in the template layouts/doc/search.html + +Setting a very low sitemap priority will tell search engines this is not important content. + diff --git a/docs/content/doc/help/search.zh-tw.md b/docs/content/doc/help/search.zh-tw.md new file mode 100644 index 00000000000..a51860aacdb --- /dev/null +++ b/docs/content/doc/help/search.zh-tw.md @@ -0,0 +1,25 @@ +--- +date: "2019-11-12T16:00:00+02:00" +title: "搜索" +slug: "search" +weight: 4 +toc: true +draft: false +menu: + sidebar: + parent: "help" + name: "搜索" + weight: 4 + identifier: "search" +sitemap: + priority : 0.1 +layout: "search" +--- + + +This file exists solely to respond to /search URL with the related `search` layout template. + +No content shown here is rendered, all content is based in the template layouts/doc/search.html + +Setting a very low sitemap priority will tell search engines this is not important content. + diff --git a/docs/content/doc/installation/windows-service.en-us.md b/docs/content/doc/installation/windows-service.en-us.md index 6a4b33cb3f0..8e3b63a1c83 100644 --- a/docs/content/doc/installation/windows-service.en-us.md +++ b/docs/content/doc/installation/windows-service.en-us.md @@ -40,7 +40,7 @@ To register Gitea as a Windows service, open a command prompt (cmd) as an Admini then run the following command: ``` -sc create gitea start= auto binPath= ""C:\gitea\gitea.exe" web --config "C:\gitea\custom\conf\app.ini"" +sc create gitea start= auto binPath= "\"C:\gitea\gitea.exe\" web --config \"C:\gitea\custom\conf\app.ini\"" ``` Do not forget to replace `C:\gitea` with the correct Gitea directory. diff --git a/docs/content/doc/installation/windows-service.fr-fr.md b/docs/content/doc/installation/windows-service.fr-fr.md index 66cc5fc6dd2..0a45bad20c9 100644 --- a/docs/content/doc/installation/windows-service.fr-fr.md +++ b/docs/content/doc/installation/windows-service.fr-fr.md @@ -18,7 +18,7 @@ menu: Pour activer le service Windows Gitea, ouvrez une `cmd` en tant qu'Administrateur puis utilisez la commande suivante : ``` -sc create gitea start= auto binPath= ""C:\gitea\gitea.exe" web --config "C:\gitea\custom\conf\app.ini"" +sc create gitea start= auto binPath= "\"C:\gitea\gitea.exe\" web --config \"C:\gitea\custom\conf\app.ini\"" ``` N'oubliez pas de remplacer `C:\gitea` par le chemin que vous avez utilisez pour votre installation. diff --git a/docs/content/doc/installation/windows-service.zh-cn.md b/docs/content/doc/installation/windows-service.zh-cn.md index 6f03f38b8ea..063c644de54 100644 --- a/docs/content/doc/installation/windows-service.zh-cn.md +++ b/docs/content/doc/installation/windows-service.zh-cn.md @@ -18,7 +18,7 @@ menu: 要注册为Windows服务,首先以Administrator身份运行 `cmd`,然后执行以下命令: ``` -sc create gitea start= auto binPath= ""C:\gitea\gitea.exe" web --config "C:\gitea\custom\conf\app.ini"" +sc create gitea start= auto binPath= "\"C:\gitea\gitea.exe\" web --config \"C:\gitea\custom\conf\app.ini\"" ``` 别忘了将 `C:\gitea` 替换成你的 Gitea 安装目录。 diff --git a/docs/content/doc/installation/windows-service.zh-tw.md b/docs/content/doc/installation/windows-service.zh-tw.md index 23dba7f8c9d..2ee886ff2ea 100644 --- a/docs/content/doc/installation/windows-service.zh-tw.md +++ b/docs/content/doc/installation/windows-service.zh-tw.md @@ -18,7 +18,7 @@ menu: 要註冊為 Windows 服務,首先要以管理者身份執行 `cmd`,跳出命令列視窗後執行底下指令: ``` -sc create gitea start= auto binPath= ""C:\gitea\gitea.exe" web --config "C:\gitea\custom\conf\app.ini"" +sc create gitea start= auto binPath= "\"C:\gitea\gitea.exe\" web --config \"C:\gitea\custom\conf\app.ini\"" ``` 別忘記將 `C:\gitea` 取代為您的 Gitea 安裝路徑。 diff --git a/docs/content/doc/installation/with-docker.en-us.md b/docs/content/doc/installation/with-docker.en-us.md index becbc254319..01914a9a2e1 100644 --- a/docs/content/doc/installation/with-docker.en-us.md +++ b/docs/content/doc/installation/with-docker.en-us.md @@ -51,6 +51,8 @@ services: - gitea volumes: - ./gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro ports: - "3000:3000" - "222:22" @@ -80,6 +82,8 @@ services: - gitea volumes: - ./gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro ports: - - "3000:3000" - - "222:22" @@ -115,6 +119,8 @@ services: - gitea volumes: - ./gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro ports: - "3000:3000" - "222:22" @@ -163,6 +169,8 @@ services: - gitea volumes: - ./gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro ports: - "3000:3000" - "222:22" @@ -209,6 +217,8 @@ services: volumes: - - ./gitea:/data + - gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro ports: - "3000:3000" - "222:22" @@ -306,6 +316,8 @@ UID/GID as the container values `USER_UID`/`USER_GID`. You should also create th - gitea volumes: - /var/lib/gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro ports: - "3000:3000" - "127.0.0.1:2222:22" diff --git a/docs/layouts/_default/index.json b/docs/layouts/_default/index.json new file mode 100644 index 00000000000..ae08324d8e7 --- /dev/null +++ b/docs/layouts/_default/index.json @@ -0,0 +1,5 @@ +{{- $.Scratch.Add "index" slice -}} +{{- range .Site.RegularPages -}} +{{- $.Scratch.Add "index" (dict "title" .Title "tags" .Params.tags "categories" .Params.categories "contents" .Plain "permalink" .Permalink) -}} +{{- end -}} +{{- $.Scratch.Get "index" | jsonify -}} diff --git a/docs/layouts/doc/search.html b/docs/layouts/doc/search.html new file mode 100644 index 00000000000..736fcaee106 --- /dev/null +++ b/docs/layouts/doc/search.html @@ -0,0 +1,44 @@ +{{ partial "header.html" . }} +{{ partial "navbar.html" . }} + +
+
+
+
+ {{ partial "menu" . }} +
+
+
+
+
+
+ +
+
+
+
+
+ + +
+
+
+
+
+ + + + +{{ $script := resources.Get "js/search.js" | minify | fingerprint -}} + +{{ partial "footer.html" . }} diff --git a/docs/static/_headers b/docs/static/_headers index a5de17226e9..b1f7453c5da 100644 --- a/docs/static/_headers +++ b/docs/static/_headers @@ -1,5 +1,5 @@ /* - Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' https://fonts.googleapis.com https://cdnjs.cloudflare.com; font-src 'self' data: https://cdnjs.cloudflare.com https://fonts.gstatic.com + Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; style-src 'self' https://fonts.googleapis.com https://cdnjs.cloudflare.com; font-src 'self' data: https://cdnjs.cloudflare.com https://fonts.gstatic.com X-Frame-Options: DENY X-Xss-Protection: 1; mode=block X-Content-Type-Options: nosniff diff --git a/go.mod b/go.mod index 87432f06892..2368a25bc13 100644 --- a/go.mod +++ b/go.mod @@ -80,7 +80,6 @@ require ( github.com/prometheus/client_golang v1.1.0 github.com/prometheus/procfs v0.0.4 // indirect github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect - github.com/russross/blackfriday v2.0.0+incompatible // indirect github.com/russross/blackfriday/v2 v2.0.1 github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect github.com/satori/go.uuid v1.2.0 diff --git a/go.sum b/go.sum index ddc0b2e4ebe..83b2152114d 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.30.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3 h1:0sMegbmn/8uTwpNkB0q9cLEpZ2W5a6kl+wtBQgPWBJQ= cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.0 h1:bALuGBSgE+BD4rxsopAYlqjcwqcQtye6pWG4bC3N/k0= cloud.google.com/go v0.45.0/go.mod h1:452BcPOeI9AZfbvDw0Tbo7D32wA+WX9WME8AZwMEDZU= @@ -67,7 +65,6 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -167,7 +164,6 @@ github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70t github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= -github.com/go-openapi/analysis v0.19.4 h1:1TjOzrWkj+9BrjnM1yPAICbaoC0FyfD49oVkTBrSSa0= github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= github.com/go-openapi/analysis v0.19.5 h1:8b2ZgKfKIUTVQpTb77MoRDIMEIwvDVw40o3aOXdfYzI= github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= @@ -179,39 +175,33 @@ github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNP github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.2 h1:rf5ArTHmIJxyV5Oiks+Su0mUens1+AjpkPoWr5xFRcI= github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= github.com/go-openapi/loads v0.19.3 h1:jwIoahqCmaA5OBoc/B+1+Mu2L0Gr8xYQnbeyQEo/7b0= github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= -github.com/go-openapi/runtime v0.19.4 h1:csnOgcgAiuGoM/Po7PEpKDoNulCcF3FGbSnbHfxgjMI= github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/runtime v0.19.5 h1:h4Zk7oTfB3ZYM2oMNliQvL+3BrDstTIX8lqP7yaYCuI= github.com/go-openapi/runtime v0.19.5/go.mod h1:WIH6IYPXOrtgTClTV8xzdrD20jBlrK25D0aQbdSlqp8= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.19.2 h1:SStNd1jRcYtfKCN7R0laGNs80WYYvn5CbBjM2sOmCrE= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= -github.com/go-openapi/strfmt v0.19.2 h1:clPGfBnJohokno0e+d7hs6Yocrzjlgz6EsQSDncCRnE= github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= github.com/go-openapi/strfmt v0.19.3 h1:eRfyY5SkaNJCAwmmMcADjY31ow9+N7MCLW7oRkbsINA= github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= @@ -221,7 +211,6 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= -github.com/go-openapi/validate v0.19.2 h1:ky5l57HjyVRrsJfd2+Ro5Z9PjGuKbsmftwyMtk8H7js= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.3 h1:PAH/2DylwWcIU1s0Y7k3yNmeAgWOcKrNE2Q7Ww/kCg4= github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= @@ -255,18 +244,15 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -288,7 +274,6 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -302,7 +287,6 @@ github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1 h1:LqbZZ9sNMWVjeXS4NN5 github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= -github.com/gorilla/sessions v1.1.1 h1:YMDmfaK68mUixINzY/XjscuJ47uXFWSSHzFbBQM0PrE= github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ= github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= @@ -385,7 +369,6 @@ github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= @@ -423,21 +406,15 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY= github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= -github.com/niklasfasching/go-org v0.1.6 h1:F521WcqRNl8OJumlgAnekZgERaTA2HpfOYYfVEKOeI8= -github.com/niklasfasching/go-org v0.1.6/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU= -github.com/niklasfasching/go-org v0.1.7 h1:t3V+3XnS/7BhKv/7SlMUa8FvAiq577/a1T3D7mLIRXE= -github.com/niklasfasching/go-org v0.1.7/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU= github.com/niklasfasching/go-org v0.1.8 h1:Kjvs6lP+LIILHhc9zIJ4Gu90a/pVY483if2Qmu8v4Fg= github.com/niklasfasching/go-org v0.1.8/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k= github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -466,7 +443,6 @@ github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -491,8 +467,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qq github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/russross/blackfriday v2.0.0+incompatible h1:cBXrhZNUf9C+La9/YpS+UHpUT8YD6Td9ZMSU9APFcsk= -github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI= @@ -503,8 +477,6 @@ github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA= github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc h1:3wIrJvFb3Pf6B/2mDBnN1G5IfUVev4X5apadQlWOczE= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0= @@ -517,7 +489,6 @@ github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= @@ -548,11 +519,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/syndtr/goleveldb v0.0.0-20190203031304-2f17a3356c66 h1:AwmkkZT+TucFotNCL+aNJ/0KCMsRtlXN9fs8uoOMSRk= github.com/syndtr/goleveldb v0.0.0-20190203031304-2f17a3356c66/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= @@ -594,7 +563,6 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.0 h1:aeOqSrhl9eDRAap/3T5pCfMBEBxZ0vuXBP+RMtp2KX8= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1 h1:Sq1fR+0c58RME5EoqKdjkiQAmPjmfHlZOoRI6fTUOcs= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -614,7 +582,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad h1:5E5raQxcv+6CZ11RrBYQe5WRbUIWpScjh0kvHZkZIrQ= golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -651,20 +618,13 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc= -golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 h1:N66aaryRB3Ax92gH0v3hp1QYZ3zWWCCUR/j8Ifh45Ss= -golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9 h1:DPz9iiH3YoKiKhX/ijjoZvT0VFwK2c6CWYWQ7Zyr8TU= golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -694,7 +654,6 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b h1:3S2h5FadpNr0zUUCVZjlKIEYF+KaX/OBplTGo89CYHI= @@ -738,9 +697,7 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.0 h1:Tfd7cKwKbFRsI8RMAD3oqqw7JPFRrvFlOsfbgVkjOOw= google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.4 h1:WiKh4+/eMB2HaY7QhCfW/R7MuRAoA8QMCSJA6jP5/fo= google.golang.org/appengine v1.6.4/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -764,7 +721,6 @@ gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 h1:nn6Zav2sOQHCFJHEspya8KqxhFwKci30UxHy3HXPTyQ= gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -776,7 +732,6 @@ gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkp gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg= -gopkg.in/ini.v1 v1.46.0 h1:VeDZbLYGaupuvIrsYCEOe/L/2Pcs5n7hdO1ZTjporag= gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.48.0 h1:URjZc+8ugRY5mL5uUeQH/a63JcHwdX9xZaWvmNWD7z8= gopkg.in/ini.v1 v1.48.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/integrations/git_helper_for_declarative_test.go b/integrations/git_helper_for_declarative_test.go index 294f0bc5fe6..5ac3348e77d 100644 --- a/integrations/git_helper_for_declarative_test.go +++ b/integrations/git_helper_for_declarative_test.go @@ -79,8 +79,10 @@ func allowLFSFilters() []string { return globalArgs } -func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL)) { - prepareTestEnv(t, 1) +func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL), prepare ...bool) { + if len(prepare) == 0 || prepare[0] { + prepareTestEnv(t, 1) + } s := http.Server{ Handler: mac, } diff --git a/integrations/gpg_git_test.go b/integrations/gpg_git_test.go index 12f0a138c75..cc06a5fdd22 100644 --- a/integrations/gpg_git_test.go +++ b/integrations/gpg_git_test.go @@ -23,14 +23,7 @@ import ( ) func TestGPGGit(t *testing.T) { - onGiteaRun(t, testGPGGit) -} - -func testGPGGit(t *testing.T, u *url.URL) { username := "user2" - baseAPITestContext := NewAPITestContext(t, username, "repo1") - - u.Path = baseAPITestContext.GitPath() // OK Set a new GPG home tmpDir, err := ioutil.TempDir("", "temp-gpg") @@ -65,130 +58,218 @@ func testGPGGit(t *testing.T, u *url.URL) { setting.Repository.Signing.SigningEmail = "gitea@fake.local" user := models.AssertExistsAndLoadBean(t, &models.User{Name: username}).(*models.User) - t.Run("Unsigned-Initial", func(t *testing.T) { - PrintCurrentTest(t) - setting.Repository.Signing.InitialCommit = []string{"never"} - testCtx := NewAPITestContext(t, username, "initial-unsigned") - t.Run("CreateRepository", doAPICreateRepository(testCtx, false)) - t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { - assert.NotNil(t, branch.Commit) - assert.NotNil(t, branch.Commit.Verification) - assert.False(t, branch.Commit.Verification.Verified) - assert.Empty(t, branch.Commit.Verification.Signature) - })) - setting.Repository.Signing.CRUDActions = []string{"never"} - t.Run("CreateCRUDFile-Never", crudActionCreateFile( - t, testCtx, user, "master", "never", "unsigned-never.txt", func(t *testing.T, response api.FileResponse) { - assert.False(t, response.Verification.Verified) + setting.Repository.Signing.InitialCommit = []string{"never"} + setting.Repository.Signing.CRUDActions = []string{"never"} + + baseAPITestContext := NewAPITestContext(t, username, "repo1") + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("Unsigned-Initial", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-unsigned") + t.Run("CreateRepository", doAPICreateRepository(testCtx, false)) + t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { + assert.NotNil(t, branch.Commit) + assert.NotNil(t, branch.Commit.Verification) + assert.False(t, branch.Commit.Verification.Verified) + assert.Empty(t, branch.Commit.Verification.Signature) })) - t.Run("CreateCRUDFile-Never", crudActionCreateFile( - t, testCtx, user, "never", "never2", "unsigned-never2.txt", func(t *testing.T, response api.FileResponse) { - assert.False(t, response.Verification.Verified) + t.Run("CreateCRUDFile-Never", crudActionCreateFile( + t, testCtx, user, "master", "never", "unsigned-never.txt", func(t *testing.T, response api.FileResponse) { + assert.False(t, response.Verification.Verified) + })) + t.Run("CreateCRUDFile-Never", crudActionCreateFile( + t, testCtx, user, "never", "never2", "unsigned-never2.txt", func(t *testing.T, response api.FileResponse) { + assert.False(t, response.Verification.Verified) + })) + }) + }, false) + setting.Repository.Signing.CRUDActions = []string{"parentsigned"} + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("Unsigned-Initial-CRUD-ParentSigned", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-unsigned") + t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile( + t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) { + assert.False(t, response.Verification.Verified) + })) + t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile( + t, testCtx, user, "parentsigned", "parentsigned2", "signed-parent2.txt", func(t *testing.T, response api.FileResponse) { + assert.False(t, response.Verification.Verified) + })) + }) + }, false) + setting.Repository.Signing.CRUDActions = []string{"never"} + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("Unsigned-Initial-CRUD-Never", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-unsigned") + t.Run("CreateCRUDFile-Never", crudActionCreateFile( + t, testCtx, user, "parentsigned", "parentsigned-never", "unsigned-never2.txt", func(t *testing.T, response api.FileResponse) { + assert.False(t, response.Verification.Verified) + })) + }) + }, false) + setting.Repository.Signing.CRUDActions = []string{"always"} + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("Unsigned-Initial-CRUD-Always", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-unsigned") + t.Run("CreateCRUDFile-Always", crudActionCreateFile( + t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) { + assert.True(t, response.Verification.Verified) + assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) + })) + t.Run("CreateCRUDFile-ParentSigned-always", crudActionCreateFile( + t, testCtx, user, "parentsigned", "parentsigned-always", "signed-parent2.txt", func(t *testing.T, response api.FileResponse) { + assert.True(t, response.Verification.Verified) + assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) + })) + }) + }, false) + setting.Repository.Signing.CRUDActions = []string{"parentsigned"} + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("Unsigned-Initial-CRUD-ParentSigned", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-unsigned") + t.Run("CreateCRUDFile-Always-ParentSigned", crudActionCreateFile( + t, testCtx, user, "always", "always-parentsigned", "signed-always-parentsigned.txt", func(t *testing.T, response api.FileResponse) { + assert.True(t, response.Verification.Verified) + assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) + })) + }) + }, false) + setting.Repository.Signing.InitialCommit = []string{"always"} + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("AlwaysSign-Initial", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-always") + t.Run("CreateRepository", doAPICreateRepository(testCtx, false)) + t.Run("CheckMasterBranchSigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { + assert.NotNil(t, branch.Commit) + assert.NotNil(t, branch.Commit.Verification) + assert.True(t, branch.Commit.Verification.Verified) + assert.Equal(t, "gitea@fake.local", branch.Commit.Verification.Signer.Email) })) - setting.Repository.Signing.CRUDActions = []string{"parentsigned"} - t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile( - t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) { - assert.False(t, response.Verification.Verified) + }) + }, false) + setting.Repository.Signing.CRUDActions = []string{"never"} + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("AlwaysSign-Initial-CRUD-Never", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-always") + t.Run("CreateCRUDFile-Never", crudActionCreateFile( + t, testCtx, user, "master", "never", "unsigned-never.txt", func(t *testing.T, response api.FileResponse) { + assert.False(t, response.Verification.Verified) + })) + }) + }, false) + setting.Repository.Signing.CRUDActions = []string{"parentsigned"} + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("AlwaysSign-Initial-CRUD-ParentSigned-On-Always", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-always") + t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile( + t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) { + assert.True(t, response.Verification.Verified) + assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) + })) + }) + }, false) + setting.Repository.Signing.CRUDActions = []string{"always"} + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("AlwaysSign-Initial-CRUD-Always", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-always") + t.Run("CreateCRUDFile-Always", crudActionCreateFile( + t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) { + assert.True(t, response.Verification.Verified) + assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) + })) + + }) + }, false) + var pr api.PullRequest + setting.Repository.Signing.Merges = []string{"commitssigned"} + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("UnsignedMerging", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-unsigned") + var err error + t.Run("CreatePullRequest", func(t *testing.T) { + pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "never2")(t) + assert.NoError(t, err) + }) + t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index)) + t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { + assert.NotNil(t, branch.Commit) + assert.NotNil(t, branch.Commit.Verification) + assert.False(t, branch.Commit.Verification.Verified) + assert.Empty(t, branch.Commit.Verification.Signature) })) - t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile( - t, testCtx, user, "parentsigned", "parentsigned2", "signed-parent2.txt", func(t *testing.T, response api.FileResponse) { - assert.False(t, response.Verification.Verified) + }) + }, false) + setting.Repository.Signing.Merges = []string{"basesigned"} + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("BaseSignedMerging", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-unsigned") + var err error + t.Run("CreatePullRequest", func(t *testing.T) { + pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "parentsigned2")(t) + assert.NoError(t, err) + }) + t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index)) + t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { + assert.NotNil(t, branch.Commit) + assert.NotNil(t, branch.Commit.Verification) + assert.False(t, branch.Commit.Verification.Verified) + assert.Empty(t, branch.Commit.Verification.Signature) })) - setting.Repository.Signing.CRUDActions = []string{"never"} - t.Run("CreateCRUDFile-Never", crudActionCreateFile( - t, testCtx, user, "parentsigned", "parentsigned-never", "unsigned-never2.txt", func(t *testing.T, response api.FileResponse) { - assert.False(t, response.Verification.Verified) - })) - setting.Repository.Signing.CRUDActions = []string{"always"} - t.Run("CreateCRUDFile-Always", crudActionCreateFile( - t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) { - assert.True(t, response.Verification.Verified) - assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) - })) - t.Run("CreateCRUDFile-ParentSigned-always", crudActionCreateFile( - t, testCtx, user, "parentsigned", "parentsigned-always", "signed-parent2.txt", func(t *testing.T, response api.FileResponse) { - assert.True(t, response.Verification.Verified) - assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) - })) - setting.Repository.Signing.CRUDActions = []string{"parentsigned"} - t.Run("CreateCRUDFile-Always-ParentSigned", crudActionCreateFile( - t, testCtx, user, "always", "always-parentsigned", "signed-always-parentsigned.txt", func(t *testing.T, response api.FileResponse) { - assert.True(t, response.Verification.Verified) - assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) - })) - }) - t.Run("AlwaysSign-Initial", func(t *testing.T) { - PrintCurrentTest(t) - setting.Repository.Signing.InitialCommit = []string{"always"} - testCtx := NewAPITestContext(t, username, "initial-always") - t.Run("CreateRepository", doAPICreateRepository(testCtx, false)) - t.Run("CheckMasterBranchSigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { - assert.NotNil(t, branch.Commit) - assert.NotNil(t, branch.Commit.Verification) - assert.True(t, branch.Commit.Verification.Verified) - assert.Equal(t, "gitea@fake.local", branch.Commit.Verification.Signer.Email) - })) - setting.Repository.Signing.CRUDActions = []string{"never"} - t.Run("CreateCRUDFile-Never", crudActionCreateFile( - t, testCtx, user, "master", "never", "unsigned-never.txt", func(t *testing.T, response api.FileResponse) { - assert.False(t, response.Verification.Verified) - })) - setting.Repository.Signing.CRUDActions = []string{"parentsigned"} - t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile( - t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) { - assert.True(t, response.Verification.Verified) - assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) - })) - setting.Repository.Signing.CRUDActions = []string{"always"} - t.Run("CreateCRUDFile-Always", crudActionCreateFile( - t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) { - assert.True(t, response.Verification.Verified) - assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) + }) + }, false) + setting.Repository.Signing.Merges = []string{"commitssigned"} + onGiteaRun(t, func(t *testing.T, u *url.URL) { + u.Path = baseAPITestContext.GitPath() + + t.Run("CommitsSignedMerging", func(t *testing.T) { + PrintCurrentTest(t) + testCtx := NewAPITestContext(t, username, "initial-unsigned") + var err error + t.Run("CreatePullRequest", func(t *testing.T) { + pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "always-parentsigned")(t) + assert.NoError(t, err) + }) + t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index)) + t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { + assert.NotNil(t, branch.Commit) + assert.NotNil(t, branch.Commit.Verification) + assert.True(t, branch.Commit.Verification.Verified) })) - }) - t.Run("UnsignedMerging", func(t *testing.T) { - PrintCurrentTest(t) - testCtx := NewAPITestContext(t, username, "initial-unsigned") - var pr api.PullRequest - var err error - t.Run("CreatePullRequest", func(t *testing.T) { - pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "never2")(t) - assert.NoError(t, err) }) - setting.Repository.Signing.Merges = []string{"commitssigned"} - t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index)) - t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { - assert.NotNil(t, branch.Commit) - assert.NotNil(t, branch.Commit.Verification) - assert.False(t, branch.Commit.Verification.Verified) - assert.Empty(t, branch.Commit.Verification.Signature) - })) - setting.Repository.Signing.Merges = []string{"basesigned"} - t.Run("CreatePullRequest", func(t *testing.T) { - pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "parentsigned2")(t) - assert.NoError(t, err) - }) - t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index)) - t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { - assert.NotNil(t, branch.Commit) - assert.NotNil(t, branch.Commit.Verification) - assert.False(t, branch.Commit.Verification.Verified) - assert.Empty(t, branch.Commit.Verification.Signature) - })) - setting.Repository.Signing.Merges = []string{"commitssigned"} - t.Run("CreatePullRequest", func(t *testing.T) { - pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "always-parentsigned")(t) - assert.NoError(t, err) - }) - t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index)) - t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { - assert.NotNil(t, branch.Commit) - assert.NotNil(t, branch.Commit.Verification) - assert.True(t, branch.Commit.Verification.Verified) - })) - - }) + }, false) } func crudActionCreateFile(t *testing.T, ctx APITestContext, user *models.User, from, to, path string, callback ...func(*testing.T, api.FileResponse)) func(*testing.T) { diff --git a/models/action.go b/models/action.go index ddb82e0f4c8..1e05a68c398 100644 --- a/models/action.go +++ b/models/action.go @@ -30,26 +30,28 @@ type ActionType int // Possible action types. const ( - ActionCreateRepo ActionType = iota + 1 // 1 - ActionRenameRepo // 2 - ActionStarRepo // 3 - ActionWatchRepo // 4 - ActionCommitRepo // 5 - ActionCreateIssue // 6 - ActionCreatePullRequest // 7 - ActionTransferRepo // 8 - ActionPushTag // 9 - ActionCommentIssue // 10 - ActionMergePullRequest // 11 - ActionCloseIssue // 12 - ActionReopenIssue // 13 - ActionClosePullRequest // 14 - ActionReopenPullRequest // 15 - ActionDeleteTag // 16 - ActionDeleteBranch // 17 - ActionMirrorSyncPush // 18 - ActionMirrorSyncCreate // 19 - ActionMirrorSyncDelete // 20 + ActionCreateRepo ActionType = iota + 1 // 1 + ActionRenameRepo // 2 + ActionStarRepo // 3 + ActionWatchRepo // 4 + ActionCommitRepo // 5 + ActionCreateIssue // 6 + ActionCreatePullRequest // 7 + ActionTransferRepo // 8 + ActionPushTag // 9 + ActionCommentIssue // 10 + ActionMergePullRequest // 11 + ActionCloseIssue // 12 + ActionReopenIssue // 13 + ActionClosePullRequest // 14 + ActionReopenPullRequest // 15 + ActionDeleteTag // 16 + ActionDeleteBranch // 17 + ActionMirrorSyncPush // 18 + ActionMirrorSyncCreate // 19 + ActionMirrorSyncDelete // 20 + ActionApprovePullRequest // 21 + ActionRejectPullRequest // 22 ) // Action represents user operation type and other information to @@ -520,52 +522,6 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit, bra return nil } -func transferRepoAction(e Engine, doer, oldOwner *User, repo *Repository) (err error) { - if err = notifyWatchers(e, &Action{ - ActUserID: doer.ID, - ActUser: doer, - OpType: ActionTransferRepo, - RepoID: repo.ID, - Repo: repo, - IsPrivate: repo.IsPrivate, - Content: path.Join(oldOwner.Name, repo.Name), - }); err != nil { - return fmt.Errorf("notifyWatchers: %v", err) - } - - // Remove watch for organization. - if oldOwner.IsOrganization() { - if err = watchRepo(e, oldOwner.ID, repo.ID, false); err != nil { - return fmt.Errorf("watchRepo [false]: %v", err) - } - } - - return nil -} - -// TransferRepoAction adds new action for transferring repository, -// the Owner field of repository is assumed to be new owner. -func TransferRepoAction(doer, oldOwner *User, repo *Repository) error { - return transferRepoAction(x, doer, oldOwner, repo) -} - -func mergePullRequestAction(e Engine, doer *User, repo *Repository, issue *Issue) error { - return notifyWatchers(e, &Action{ - ActUserID: doer.ID, - ActUser: doer, - OpType: ActionMergePullRequest, - Content: fmt.Sprintf("%d|%s", issue.Index, issue.Title), - RepoID: repo.ID, - Repo: repo, - IsPrivate: repo.IsPrivate, - }) -} - -// MergePullRequestAction adds new action for merging pull request. -func MergePullRequestAction(actUser *User, repo *Repository, pull *Issue) error { - return mergePullRequestAction(x, actUser, repo, pull) -} - // GetFeedsOptions options for retrieving feeds type GetFeedsOptions struct { RequestedUser *User diff --git a/models/action_test.go b/models/action_test.go index 5eb89aac212..e7766eac2f7 100644 --- a/models/action_test.go +++ b/models/action_test.go @@ -332,54 +332,6 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) { CheckConsistencyFor(t, &Action{}) } -func TestTransferRepoAction(t *testing.T) { - assert.NoError(t, PrepareTestDatabase()) - - user2 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) - user4 := AssertExistsAndLoadBean(t, &User{ID: 4}).(*User) - repo := AssertExistsAndLoadBean(t, &Repository{ID: 1, OwnerID: user2.ID}).(*Repository) - - repo.OwnerID = user4.ID - repo.Owner = user4 - - actionBean := &Action{ - OpType: ActionTransferRepo, - ActUserID: user2.ID, - ActUser: user2, - RepoID: repo.ID, - Repo: repo, - IsPrivate: repo.IsPrivate, - } - AssertNotExistsBean(t, actionBean) - assert.NoError(t, TransferRepoAction(user2, user2, repo)) - AssertExistsAndLoadBean(t, actionBean) - - _, err := x.ID(repo.ID).Cols("owner_id").Update(repo) - assert.NoError(t, err) - CheckConsistencyFor(t, &Action{}) -} - -func TestMergePullRequestAction(t *testing.T) { - assert.NoError(t, PrepareTestDatabase()) - user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) - repo := AssertExistsAndLoadBean(t, &Repository{ID: 1, OwnerID: user.ID}).(*Repository) - repo.Owner = user - issue := AssertExistsAndLoadBean(t, &Issue{ID: 3, RepoID: repo.ID}).(*Issue) - - actionBean := &Action{ - OpType: ActionMergePullRequest, - ActUserID: user.ID, - ActUser: user, - RepoID: repo.ID, - Repo: repo, - IsPrivate: repo.IsPrivate, - } - AssertNotExistsBean(t, actionBean) - assert.NoError(t, MergePullRequestAction(user, repo, issue)) - AssertExistsAndLoadBean(t, actionBean) - CheckConsistencyFor(t, &Action{}) -} - func TestGetFeeds(t *testing.T) { // test with an individual user assert.NoError(t, PrepareTestDatabase()) diff --git a/models/issue_comment.go b/models/issue_comment.go index 63f5f6b7788..c7e9e7cdfad 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -539,8 +539,10 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err return nil, err } - if err = sendCreateCommentAction(e, opts, comment); err != nil { - return nil, err + if !opts.NoAction { + if err = sendCreateCommentAction(e, opts, comment); err != nil { + return nil, err + } } if err = comment.addCrossReferences(e, opts.Doer); err != nil { @@ -816,6 +818,7 @@ type CreateCommentOptions struct { RefCommentID int64 RefAction references.XRefAction RefIsPull bool + NoAction bool } // CreateComment creates comment of issue or commit. diff --git a/models/login_source.go b/models/login_source.go index ce03c4154f6..b8441adcc4c 100644 --- a/models/login_source.go +++ b/models/login_source.go @@ -1,4 +1,5 @@ // Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. @@ -403,6 +404,19 @@ func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoR var isAttributeSSHPublicKeySet = len(strings.TrimSpace(source.LDAP().AttributeSSHPublicKey)) > 0 + // Update User admin flag if exist + if isExist, err := IsUserExist(0, sr.Username); err != nil { + return nil, err + } else if isExist && + !user.ProhibitLogin && len(source.LDAP().AdminFilter) > 0 && user.IsAdmin != sr.IsAdmin { + // Change existing admin flag only if AdminFilter option is set + user.IsAdmin = sr.IsAdmin + err = UpdateUserCols(user, "is_admin") + if err != nil { + return nil, err + } + } + if !autoRegister { if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(user, source, sr.SSHPublicKey) { return user, RewriteAllPublicKeys() diff --git a/models/repo.go b/models/repo.go index a340a391a13..851add409f3 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1792,8 +1792,13 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error if err = watchRepo(sess, doer.ID, repo.ID, true); err != nil { return fmt.Errorf("watchRepo: %v", err) - } else if err = transferRepoAction(sess, doer, owner, repo); err != nil { - return fmt.Errorf("transferRepoAction: %v", err) + } + + // Remove watch for organization. + if owner.IsOrganization() { + if err = watchRepo(sess, owner.ID, repo.ID, false); err != nil { + return fmt.Errorf("watchRepo [false]: %v", err) + } } // Rename remote repository to new path and delete local copy. @@ -1824,23 +1829,21 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error } // ChangeRepositoryName changes all corresponding setting from old repository name to new one. -func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error) { - oldRepoName = strings.ToLower(oldRepoName) +func ChangeRepositoryName(doer *User, repo *Repository, newRepoName string) (err error) { newRepoName = strings.ToLower(newRepoName) if err = IsUsableRepoName(newRepoName); err != nil { return err } - has, err := IsRepositoryExist(u, newRepoName) + if err := repo.GetOwner(); err != nil { + return err + } + + has, err := IsRepositoryExist(repo.Owner, newRepoName) if err != nil { return fmt.Errorf("IsRepositoryExist: %v", err) } else if has { - return ErrRepoAlreadyExist{u.Name, newRepoName} - } - - repo, err := GetRepositoryByName(u.ID, oldRepoName) - if err != nil { - return fmt.Errorf("GetRepositoryByName: %v", err) + return ErrRepoAlreadyExist{repo.Owner.Name, newRepoName} } // Change repository directory name. We must lock the local copy of the @@ -1849,14 +1852,14 @@ func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error) repoWorkingPool.CheckIn(com.ToStr(repo.ID)) defer repoWorkingPool.CheckOut(com.ToStr(repo.ID)) - newRepoPath := RepoPath(u.Name, newRepoName) + newRepoPath := RepoPath(repo.Owner.Name, newRepoName) if err = os.Rename(repo.RepoPath(), newRepoPath); err != nil { return fmt.Errorf("rename repository directory: %v", err) } wikiPath := repo.WikiPath() if com.IsExist(wikiPath) { - if err = os.Rename(wikiPath, WikiPath(u.Name, newRepoName)); err != nil { + if err = os.Rename(wikiPath, WikiPath(repo.Owner.Name, newRepoName)); err != nil { return fmt.Errorf("rename repository wiki: %v", err) } } @@ -1868,7 +1871,7 @@ func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error) } // If there was previously a redirect at this location, remove it. - if err = deleteRepoRedirect(sess, u.ID, newRepoName); err != nil { + if err = deleteRepoRedirect(sess, repo.OwnerID, newRepoName); err != nil { return fmt.Errorf("delete repo redirect: %v", err) } diff --git a/models/repo_test.go b/models/repo_test.go index bf10de8d99c..72a2959eb7e 100644 --- a/models/repo_test.go +++ b/models/repo_test.go @@ -15,7 +15,6 @@ import ( "code.gitea.io/gitea/modules/markup" "github.com/stretchr/testify/assert" - "github.com/unknwon/com" ) func TestRepo(t *testing.T) { @@ -142,29 +141,6 @@ func TestRepoAPIURL(t *testing.T) { assert.Equal(t, "https://try.gitea.io/api/v1/repos/user12/repo10", repo.APIURL()) } -func TestTransferOwnership(t *testing.T) { - assert.NoError(t, PrepareTestDatabase()) - - doer := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) - repo := AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository) - repo.Owner = AssertExistsAndLoadBean(t, &User{ID: repo.OwnerID}).(*User) - assert.NoError(t, TransferOwnership(doer, "user2", repo)) - - transferredRepo := AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository) - assert.EqualValues(t, 2, transferredRepo.OwnerID) - - assert.False(t, com.IsExist(RepoPath("user3", "repo3"))) - assert.True(t, com.IsExist(RepoPath("user2", "repo3"))) - AssertExistsAndLoadBean(t, &Action{ - OpType: ActionTransferRepo, - ActUserID: 2, - RepoID: 3, - Content: "user3/repo3", - }) - - CheckConsistencyFor(t, &Repository{}, &User{}, &Team{}) -} - func TestUploadAvatar(t *testing.T) { // Generate image diff --git a/models/repo_watch.go b/models/repo_watch.go index cb864fb46da..2de4f8b320d 100644 --- a/models/repo_watch.go +++ b/models/repo_watch.go @@ -216,6 +216,21 @@ func NotifyWatchers(act *Action) error { return notifyWatchers(x, act) } +// NotifyWatchersActions creates batch of actions for every watcher. +func NotifyWatchersActions(acts []*Action) error { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + for _, act := range acts { + if err := notifyWatchers(sess, act); err != nil { + return err + } + } + return sess.Commit() +} + func watchIfAuto(e Engine, userID, repoID int64, isWrite bool) error { if !isWrite || !setting.Service.AutoWatchOnChanges { return nil diff --git a/models/review.go b/models/review.go index 89a26d6fdb9..e1674e885d0 100644 --- a/models/review.go +++ b/models/review.go @@ -5,14 +5,12 @@ package models import ( - "fmt" + "strings" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" "xorm.io/builder" "xorm.io/core" - "xorm.io/xorm" ) // ReviewType defines the sort of feedback a review gives @@ -86,6 +84,11 @@ func (r *Review) loadReviewer(e Engine) (err error) { return } +// LoadReviewer loads reviewer +func (r *Review) LoadReviewer() error { + return r.loadReviewer(x) +} + func (r *Review) loadAttributes(e Engine) (err error) { if err = r.loadReviewer(e); err != nil { return @@ -101,54 +104,6 @@ func (r *Review) LoadAttributes() error { return r.loadAttributes(x) } -// Publish will send notifications / actions to participants for all code comments; parts are concurrent -func (r *Review) Publish() error { - return r.publish(x) -} - -func (r *Review) publish(e *xorm.Engine) error { - if r.Type == ReviewTypePending || r.Type == ReviewTypeUnknown { - return fmt.Errorf("review cannot be published if type is pending or unknown") - } - if r.Issue == nil { - if err := r.loadIssue(e); err != nil { - return err - } - } - if err := r.Issue.loadRepo(e); err != nil { - return err - } - if len(r.CodeComments) == 0 { - if err := r.loadCodeComments(e); err != nil { - return err - } - } - for _, lines := range r.CodeComments { - for _, comments := range lines { - for _, comment := range comments { - go func(en *xorm.Engine, review *Review, comm *Comment) { - sess := en.NewSession() - defer sess.Close() - opts := &CreateCommentOptions{ - Doer: comm.Poster, - Issue: review.Issue, - Repo: review.Issue.Repo, - Type: comm.Type, - Content: comm.Content, - } - if err := updateCommentInfos(sess, opts, comm); err != nil { - log.Warn("updateCommentInfos: %v", err) - } - if err := sendCreateCommentAction(sess, opts, comm); err != nil { - log.Warn("sendCreateCommentAction: %v", err) - } - }(e, r, comment) - } - } - } - return nil -} - func getReviewByID(e Engine, id int64) (*Review, error) { review := new(Review) if has, err := e.ID(id).Get(review); err != nil { @@ -271,12 +226,79 @@ func GetCurrentReview(reviewer *User, issue *Issue) (*Review, error) { return getCurrentReview(x, reviewer, issue) } -// UpdateReview will update all cols of the given review in db -func UpdateReview(r *Review) error { - if _, err := x.ID(r.ID).AllCols().Update(r); err != nil { - return err +// ContentEmptyErr represents an content empty error +type ContentEmptyErr struct { +} + +func (ContentEmptyErr) Error() string { + return "Review content is empty" +} + +// IsContentEmptyErr returns true if err is a ContentEmptyErr +func IsContentEmptyErr(err error) bool { + _, ok := err.(ContentEmptyErr) + return ok +} + +// SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist +func SubmitReview(doer *User, issue *Issue, reviewType ReviewType, content string) (*Review, *Comment, error) { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return nil, nil, err } - return nil + + review, err := getCurrentReview(sess, doer, issue) + if err != nil { + if !IsErrReviewNotExist(err) { + return nil, nil, err + } + + if reviewType != ReviewTypeApprove && len(strings.TrimSpace(content)) == 0 { + return nil, nil, ContentEmptyErr{} + } + + // No current review. Create a new one! + review, err = createReview(sess, CreateReviewOptions{ + Type: reviewType, + Issue: issue, + Reviewer: doer, + Content: content, + }) + if err != nil { + return nil, nil, err + } + } else { + if err := review.loadCodeComments(sess); err != nil { + return nil, nil, err + } + if reviewType != ReviewTypeApprove && len(review.CodeComments) == 0 && len(strings.TrimSpace(content)) == 0 { + return nil, nil, ContentEmptyErr{} + } + + review.Issue = issue + review.Content = content + review.Type = reviewType + if _, err := sess.ID(review.ID).Cols("content, type").Update(review); err != nil { + return nil, nil, err + } + } + + comm, err := createComment(sess, &CreateCommentOptions{ + Type: CommentTypeReview, + Doer: doer, + Content: review.Content, + Issue: issue, + Repo: issue.Repo, + ReviewID: review.ID, + NoAction: true, + }) + if err != nil || comm == nil { + return nil, nil, err + } + + comm.Review = review + return review, comm, sess.Commit() } // PullReviewersWithType represents the type used to display a review overview diff --git a/models/review_test.go b/models/review_test.go index f8e8086dca9..3e7563b4345 100644 --- a/models/review_test.go +++ b/models/review_test.go @@ -98,14 +98,6 @@ func TestCreateReview(t *testing.T) { AssertExistsAndLoadBean(t, &Review{Content: "New Review"}) } -func TestUpdateReview(t *testing.T) { - assert.NoError(t, PrepareTestDatabase()) - review := AssertExistsAndLoadBean(t, &Review{ID: 1}).(*Review) - review.Content = "Updated Review" - assert.NoError(t, UpdateReview(review)) - AssertExistsAndLoadBean(t, &Review{ID: 1, Content: "Updated Review"}) -} - func TestGetReviewersByPullID(t *testing.T) { assert.NoError(t, PrepareTestDatabase()) diff --git a/modules/git/blob.go b/modules/git/blob.go index 68147673a35..df88ac2ede9 100644 --- a/modules/git/blob.go +++ b/modules/git/blob.go @@ -6,6 +6,7 @@ package git import ( + "bytes" "encoding/base64" "io" "io/ioutil" @@ -50,6 +51,28 @@ func (b *Blob) GetBlobContent() (string, error) { return string(buf), nil } +// GetBlobLineCount gets line count of lob as raw text +func (b *Blob) GetBlobLineCount() (int, error) { + reader, err := b.DataAsync() + if err != nil { + return 0, err + } + defer reader.Close() + buf := make([]byte, 32*1024) + count := 0 + lineSep := []byte{'\n'} + for { + c, err := reader.Read(buf) + count += bytes.Count(buf[:c], lineSep) + switch { + case err == io.EOF: + return count, nil + case err != nil: + return count, err + } + } +} + // GetBlobContentBase64 Reads the content of the blob with a base64 encode and returns the encoded string func (b *Blob) GetBlobContentBase64() (string, error) { dataRc, err := b.DataAsync() diff --git a/modules/notification/action/action.go b/modules/notification/action/action.go index d481bd8c4dd..dd4dc0ae323 100644 --- a/modules/notification/action/action.go +++ b/modules/notification/action/action.go @@ -6,6 +6,8 @@ package action import ( "fmt" + "path" + "strings" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/log" @@ -76,7 +78,9 @@ func (a *actionNotifier) NotifyNewPullRequest(pull *models.PullRequest) { } } -func (a *actionNotifier) NotifyRenameRepository(doer *models.User, repo *models.Repository, oldName string) { +func (a *actionNotifier) NotifyRenameRepository(doer *models.User, repo *models.Repository, oldRepoName string) { + log.Trace("action.ChangeRepositoryName: %s/%s", doer.Name, repo.Name) + if err := models.NotifyWatchers(&models.Action{ ActUserID: doer.ID, ActUser: doer, @@ -84,11 +88,23 @@ func (a *actionNotifier) NotifyRenameRepository(doer *models.User, repo *models. RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, - Content: oldName, + Content: oldRepoName, }); err != nil { - log.Error("notify watchers: %v", err) - } else { - log.Trace("action.renameRepoAction: %s/%s", doer.Name, repo.Name) + log.Error("NotifyWatchers: %v", err) + } +} + +func (a *actionNotifier) NotifyTransferRepository(doer *models.User, repo *models.Repository, oldOwnerName string) { + if err := models.NotifyWatchers(&models.Action{ + ActUserID: doer.ID, + ActUser: doer, + OpType: models.ActionTransferRepo, + RepoID: repo.ID, + Repo: repo, + IsPrivate: repo.IsPrivate, + Content: path.Join(oldOwnerName, repo.Name), + }); err != nil { + log.Error("NotifyWatchers: %v", err) } } @@ -117,3 +133,61 @@ func (a *actionNotifier) NotifyForkRepository(doer *models.User, oldRepo, repo * log.Error("notify watchers '%d/%d': %v", doer.ID, repo.ID, err) } } + +func (a *actionNotifier) NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment) { + if err := review.LoadReviewer(); err != nil { + log.Error("LoadReviewer '%d/%d': %v", review.ID, review.ReviewerID, err) + return + } + if err := review.LoadCodeComments(); err != nil { + log.Error("LoadCodeComments '%d/%d': %v", review.Reviewer.ID, review.ID, err) + return + } + + var actions = make([]*models.Action, 0, 10) + for _, lines := range review.CodeComments { + for _, comments := range lines { + for _, comm := range comments { + actions = append(actions, &models.Action{ + ActUserID: review.Reviewer.ID, + ActUser: review.Reviewer, + Content: fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comm.Content, "\n")[0]), + OpType: models.ActionCommentIssue, + RepoID: review.Issue.RepoID, + Repo: review.Issue.Repo, + IsPrivate: review.Issue.Repo.IsPrivate, + Comment: comm, + CommentID: comm.ID, + }) + } + } + } + + if review.Type != models.ReviewTypeComment || strings.TrimSpace(comment.Content) != "" { + action := &models.Action{ + ActUserID: review.Reviewer.ID, + ActUser: review.Reviewer, + Content: fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comment.Content, "\n")[0]), + RepoID: review.Issue.RepoID, + Repo: review.Issue.Repo, + IsPrivate: review.Issue.Repo.IsPrivate, + Comment: comment, + CommentID: comment.ID, + } + + switch review.Type { + case models.ReviewTypeApprove: + action.OpType = models.ActionApprovePullRequest + case models.ReviewTypeReject: + action.OpType = models.ActionRejectPullRequest + default: + action.OpType = models.ActionCommentIssue + } + + actions = append(actions, action) + } + + if err := models.NotifyWatchersActions(actions); err != nil { + log.Error("notify watchers '%d/%d': %v", review.Reviewer.ID, review.Issue.RepoID, err) + } +} diff --git a/modules/notification/base/notifier.go b/modules/notification/base/notifier.go index 9510afc9786..1935c305576 100644 --- a/modules/notification/base/notifier.go +++ b/modules/notification/base/notifier.go @@ -17,7 +17,8 @@ type Notifier interface { NotifyMigrateRepository(doer *models.User, u *models.User, repo *models.Repository) NotifyDeleteRepository(doer *models.User, repo *models.Repository) NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository) - NotifyRenameRepository(doer *models.User, repo *models.Repository, oldName string) + NotifyRenameRepository(doer *models.User, repo *models.Repository, oldRepoName string) + NotifyTransferRepository(doer *models.User, repo *models.Repository, oldOwnerName string) NotifyNewIssue(*models.Issue) NotifyIssueChangeStatus(*models.User, *models.Issue, bool) diff --git a/modules/notification/base/null.go b/modules/notification/base/null.go index 2341b8d2a75..b9ecaed425e 100644 --- a/modules/notification/base/null.go +++ b/modules/notification/base/null.go @@ -58,18 +58,6 @@ func (*NullNotifier) NotifyUpdateComment(doer *models.User, c *models.Comment, o func (*NullNotifier) NotifyDeleteComment(doer *models.User, c *models.Comment) { } -// NotifyDeleteRepository places a place holder function -func (*NullNotifier) NotifyDeleteRepository(doer *models.User, repo *models.Repository) { -} - -// NotifyForkRepository places a place holder function -func (*NullNotifier) NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository) { -} - -// NotifyRenameRepository places a place holder function -func (*NullNotifier) NotifyRenameRepository(doer *models.User, repo *models.Repository, oldName string) { -} - // NotifyNewRelease places a place holder function func (*NullNotifier) NotifyNewRelease(rel *models.Release) { } @@ -111,6 +99,14 @@ func (*NullNotifier) NotifyIssueChangeLabels(doer *models.User, issue *models.Is func (*NullNotifier) NotifyCreateRepository(doer *models.User, u *models.User, repo *models.Repository) { } +// NotifyDeleteRepository places a place holder function +func (*NullNotifier) NotifyDeleteRepository(doer *models.User, repo *models.Repository) { +} + +// NotifyForkRepository places a place holder function +func (*NullNotifier) NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository) { +} + // NotifyMigrateRepository places a place holder function func (*NullNotifier) NotifyMigrateRepository(doer *models.User, u *models.User, repo *models.Repository) { } @@ -126,3 +122,11 @@ func (*NullNotifier) NotifyCreateRef(doer *models.User, repo *models.Repository, // NotifyDeleteRef notifies branch or tag deleteion to notifiers func (*NullNotifier) NotifyDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) { } + +// NotifyRenameRepository places a place holder function +func (*NullNotifier) NotifyRenameRepository(doer *models.User, repo *models.Repository, oldRepoName string) { +} + +// NotifyTransferRepository places a place holder function +func (*NullNotifier) NotifyTransferRepository(doer *models.User, repo *models.Repository, oldOwnerName string) { +} diff --git a/modules/notification/notification.go b/modules/notification/notification.go index fdfcc62ffe1..fa0b280e71d 100644 --- a/modules/notification/notification.go +++ b/modules/notification/notification.go @@ -101,27 +101,6 @@ func NotifyDeleteComment(doer *models.User, c *models.Comment) { } } -// NotifyDeleteRepository notifies delete repository to notifiers -func NotifyDeleteRepository(doer *models.User, repo *models.Repository) { - for _, notifier := range notifiers { - notifier.NotifyDeleteRepository(doer, repo) - } -} - -// NotifyForkRepository notifies fork repository to notifiers -func NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository) { - for _, notifier := range notifiers { - notifier.NotifyForkRepository(doer, oldRepo, repo) - } -} - -// NotifyRenameRepository notifies repository renamed -func NotifyRenameRepository(doer *models.User, repo *models.Repository, oldName string) { - for _, notifier := range notifiers { - notifier.NotifyRenameRepository(doer, repo, oldName) - } -} - // NotifyNewRelease notifies new release to notifiers func NotifyNewRelease(rel *models.Release) { for _, notifier := range notifiers { @@ -200,6 +179,34 @@ func NotifyMigrateRepository(doer *models.User, u *models.User, repo *models.Rep } } +// NotifyTransferRepository notifies create repository to notifiers +func NotifyTransferRepository(doer *models.User, repo *models.Repository, newOwnerName string) { + for _, notifier := range notifiers { + notifier.NotifyTransferRepository(doer, repo, newOwnerName) + } +} + +// NotifyDeleteRepository notifies delete repository to notifiers +func NotifyDeleteRepository(doer *models.User, repo *models.Repository) { + for _, notifier := range notifiers { + notifier.NotifyDeleteRepository(doer, repo) + } +} + +// NotifyForkRepository notifies fork repository to notifiers +func NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository) { + for _, notifier := range notifiers { + notifier.NotifyForkRepository(doer, oldRepo, repo) + } +} + +// NotifyRenameRepository notifies repository renamed +func NotifyRenameRepository(doer *models.User, repo *models.Repository, oldName string) { + for _, notifier := range notifiers { + notifier.NotifyRenameRepository(doer, repo, oldName) + } +} + // NotifyPushCommits notifies commits pushed to notifiers func NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { for _, notifier := range notifiers { diff --git a/modules/repofiles/diff_test.go b/modules/repofiles/diff_test.go index db2c7552c4f..4e1d5b13ebd 100644 --- a/modules/repofiles/diff_test.go +++ b/modules/repofiles/diff_test.go @@ -55,6 +55,15 @@ func TestGetDiffPreview(t *testing.T) { Type: 4, Content: "@@ -1,3 +1,4 @@", Comments: nil, + SectionInfo: &gitdiff.DiffLineSectionInfo{ + Path: "README.md", + LastLeftIdx: 0, + LastRightIdx: 0, + LeftIdx: 1, + RightIdx: 1, + LeftHunkSize: 3, + RightHunkSize: 4, + }, }, { LeftIdx: 1, diff --git a/modules/setting/setting.go b/modules/setting/setting.go index f3dd45d7bf9..c0b9b99e3cb 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -140,18 +140,19 @@ var ( } // Security settings - InstallLock bool - SecretKey string - LogInRememberDays int - CookieUserName string - CookieRememberName string - ReverseProxyAuthUser string - ReverseProxyAuthEmail string - MinPasswordLength int - ImportLocalPaths bool - DisableGitHooks bool - PasswordComplexity []string - PasswordHashAlgo string + InstallLock bool + SecretKey string + LogInRememberDays int + CookieUserName string + CookieRememberName string + ReverseProxyAuthUser string + ReverseProxyAuthEmail string + MinPasswordLength int + ImportLocalPaths bool + DisableGitHooks bool + OnlyAllowPushIfGiteaEnvironmentSet bool + PasswordComplexity []string + PasswordHashAlgo string // UI settings UI = struct { @@ -778,6 +779,7 @@ func NewContext() { MinPasswordLength = sec.Key("MIN_PASSWORD_LENGTH").MustInt(6) ImportLocalPaths = sec.Key("IMPORT_LOCAL_PATHS").MustBool(false) DisableGitHooks = sec.Key("DISABLE_GIT_HOOKS").MustBool(false) + OnlyAllowPushIfGiteaEnvironmentSet = sec.Key("ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET").MustBool(true) PasswordHashAlgo = sec.Key("PASSWORD_HASH_ALGO").MustString("pbkdf2") CSRFCookieHTTPOnly = sec.Key("CSRF_COOKIE_HTTP_ONLY").MustBool(true) diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 1347835b808..6aa429ee142 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -555,6 +555,10 @@ func ActionIcon(opType models.ActionType) string { return "issue-reopened" case models.ActionMirrorSyncPush, models.ActionMirrorSyncCreate, models.ActionMirrorSyncDelete: return "repo-clone" + case models.ActionApprovePullRequest: + return "eye" + case models.ActionRejectPullRequest: + return "x" default: return "invalid type" } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index e3e0dba9fec..883b9222f53 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -582,7 +582,7 @@ email_notifications.submit = Set Email Preference owner = Owner repo_name = Repository Name repo_name_helper = Good repository names use short, memorable and unique keywords. -repo_size = Repository Size +repo_size = Repository Size template = Template template_select = Select a template. template_helper = Make repository a template @@ -2000,6 +2000,8 @@ compare_commits_general = Compare commits mirror_sync_push = synced commits to %[3]s at %[4]s from mirror mirror_sync_create = synced new reference %[2]s to %[3]s from mirror mirror_sync_delete = synced and deleted reference %[2]s at %[3]s from mirror +approve_pull_request = `approved %s#%[2]s` +reject_pull_request = `suggested changes for %s#%[2]s` [tool] ago = %s ago diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index 48f91b7d3ea..18bf6ba9eca 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -581,6 +581,7 @@ email_notifications.submit=Atualizar preferências de e-mail owner=Proprietário repo_name=Nome do repositório repo_name_helper=Um bom nome de repositório é composto por palavras curtas, memorizáveis e únicas. +repo_size=Tamanho do repositório template=Modelo template_select=Selecione um modelo. template_helper=Tornar repositório um modelo @@ -1711,6 +1712,7 @@ users.auth_login_name=Nome de acesso da autenticação users.password_helper=Deixe a senha em branco para mantê-la inalterada. users.update_profile_success=A conta de usuário foi atualizada. users.edit_account=Editar a conta de usuário +users.max_repo_creation=Número máximo de repositórios users.max_repo_creation_desc=(Use -1 para usar o limite padrão global.) users.is_activated=Conta de usuário está ativada users.prohibit_login=Desabilitar acesso diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 2ad24114d67..f6a0742e381 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -68,6 +68,10 @@ pull_requests=合并请求 issues=工单管理 cancel=取消 +add=添加 +add_all=添加所有 +remove=移除 +remove_all=移除所有 write=撰写 preview=预览 @@ -577,6 +581,11 @@ email_notifications.submit=邮件通知设置 owner=拥有者 repo_name=仓库名称 repo_name_helper=好的存储库名称使用简短、深刻和独特的关键字。 +repo_size=仓库大小 +template=模板 +template_select=选择模板 +template_helper=设置仓库为模板仓库 +template_description=模板仓库让用户通过拷贝目录结构,文件和可选设置来生成仓库。 visibility=可见性 visibility_description=只有组织所有人或拥有权利的组织成员才能看到。 visibility_helper=将仓库设为私有 @@ -586,6 +595,9 @@ clone_helper=不知道如何克隆?查看= 1.0.0" } }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -1003,21 +2103,30 @@ "typedarray": "^0.0.6" } }, + "confusing-browser-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==" + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } } }, "copy-concurrently": { @@ -1040,6 +2149,24 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, + "core-js-compat": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.4.1.tgz", + "integrity": "sha512-YdeJI26gLc0CQJ9asLE5obEgBz2I0+CIgnoTbS2T0d5IPQw/OCgCIFR527RmpduxjrB3gSEHoGOCTq9sigOyfw==", + "dev": true, + "requires": { + "browserslist": "^4.7.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1076,6 +2203,43 @@ } } }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -1089,6 +2253,25 @@ "which": "^1.2.9" } }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -1099,9 +2282,9 @@ } }, "cyclist": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, "dashdash": { @@ -1165,6 +2348,14 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", @@ -1219,6 +2410,33 @@ "integrity": "sha512-DCvzSq2UiMsuLnj/9AL484ummEgLtZIcRS7YvtO38QnpX3vqh9nJ8P+zhu8Ja+SmLrBHO2iDbva20jq38qvBkQ==", "dev": true }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, "dir-glob": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", @@ -1238,9 +2456,9 @@ } }, "dom-serializer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", - "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", "dev": true, "requires": { "domelementtype": "^2.0.1", @@ -1261,6 +2479,12 @@ } } }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, "domelementtype": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", @@ -1319,15 +2543,36 @@ } }, "electron-to-chromium": { - "version": "1.3.249", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.249.tgz", - "integrity": "sha512-BSNKVkF67cfgwCOJD3/eyIFi001+8mRoazPJYZRpxxtabToCDCef1vhZMDjA6CPfAdgOI0QMOiGLELgJVYP76Q==", + "version": "1.3.306", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.306.tgz", + "integrity": "sha512-frDqXvrIROoYvikSKTIKbHbzO6M3/qC6kCIt/1FOa9kALe++c4VAJnwjSFvf1tYLEUsP2n9XZ4XSCyqc3l7A/A==", "dev": true }, + "elliptic": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz", + "integrity": "sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, "encoding": { @@ -1335,19 +2580,43 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "dev": true, + "optional": true, "requires": { "iconv-lite": "~0.4.13" } }, "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "requires": { "once": "^1.4.0" } }, + "enhanced-resolve": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, "entities": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", @@ -1365,7 +2634,6 @@ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", "dev": true, - "optional": true, "requires": { "prr": "~1.0.1" } @@ -1379,6 +2647,33 @@ "is-arrayish": "^0.2.1" } }, + "es-abstract": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", + "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -1401,9 +2696,9 @@ "dev": true }, "eslint": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", - "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.6.0.tgz", + "integrity": "sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -1413,9 +2708,9 @@ "debug": "^4.0.1", "doctrine": "^3.0.0", "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.2", + "eslint-utils": "^1.4.3", "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.1", + "espree": "^6.1.2", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", @@ -1425,7 +2720,7 @@ "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.4.1", + "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", @@ -1453,6 +2748,16 @@ } } }, + "eslint-config-airbnb-base": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz", + "integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==", + "requires": { + "confusing-browser-globals": "^1.0.7", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0" + } + }, "eslint-scope": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", @@ -1464,12 +2769,12 @@ } }, "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { @@ -1479,13 +2784,13 @@ "dev": true }, "espree": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", - "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", "dev": true, "requires": { - "acorn": "^7.0.0", - "acorn-jsx": "^5.0.2", + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", "eslint-visitor-keys": "^1.1.0" } }, @@ -1525,6 +2830,22 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", @@ -1599,6 +2920,15 @@ } } }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -1771,9 +3101,9 @@ "dev": true }, "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", + "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -1811,6 +3141,17 @@ } } }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -1820,6 +3161,18 @@ "locate-path": "^3.0.0" } }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", @@ -1902,6 +3255,15 @@ "universalify": "^0.1.0" } }, + "fs-minipass": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.0.0.tgz", + "integrity": "sha512-40Qz+LFXmd9tzYVnnBmZvFfvAADfUA14TXPK1s7IfElJTIZ97rA8w4Kin7Wt5JBrC3ShnnFJO/5vPjPEeJIq9A==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -2468,6 +3830,11 @@ } } }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", @@ -2512,9 +3879,9 @@ } }, "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -2526,9 +3893,9 @@ } }, "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2606,9 +3973,9 @@ } }, "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", "dev": true }, "graceful-readlink": { @@ -2635,12 +4002,25 @@ "har-schema": "^2.0.0" } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -2673,10 +4053,50 @@ } } }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, "hosted-git-info": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", - "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", "dev": true }, "html-tags": { @@ -2757,10 +4177,16 @@ "sshpk": "^1.7.0" } }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, "https-proxy-agent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", - "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "dev": true, "requires": { "agent-base": "^4.3.0", @@ -2796,6 +4222,12 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, "iferr": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", @@ -2825,9 +4257,9 @@ } }, "import-fresh": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", - "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -2857,6 +4289,16 @@ "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -2904,26 +4346,41 @@ "dev": true }, "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz", + "integrity": "sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==", "dev": true, "requires": { - "ansi-escapes": "^3.2.0", + "ansi-escapes": "^4.2.1", "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", + "cli-cursor": "^3.1.0", "cli-width": "^2.0.0", "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", "run-async": "^2.2.0", "rxjs": "^6.4.0", - "string-width": "^2.1.0", + "string-width": "^4.1.0", "strip-ansi": "^5.1.0", "through": "^2.3.6" } }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", @@ -2999,6 +4456,11 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -3019,6 +4481,11 @@ } } }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, "is-decimal": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.3.tgz", @@ -3063,9 +4530,9 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-glob": { @@ -3130,6 +4597,14 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "^1.0.1" + } + }, "is-regexp": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", @@ -3142,6 +4617,14 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "requires": { + "has-symbols": "^1.0.0" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -3167,6 +4650,12 @@ "integrity": "sha512-0wfcrFgOOOBdgRNT9H33xe6Zi6yhX/uoc4U8NBZGeQQB0ctU1dnlNTyL9JM2646bHDTpsDm1Brb3VPoCIMrd/A==", "dev": true }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -3192,6 +4681,12 @@ "dev": true, "optional": true }, + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3254,20 +4749,12 @@ "optional": true }, "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", "dev": true, "requires": { "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "jsonfile": { @@ -3299,9 +4786,9 @@ "dev": true }, "known-css-properties": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.14.0.tgz", - "integrity": "sha512-P+0a/gBzLgVlCnK8I7VcD0yuYJscmWn66wH9tlKsQnmVdg689tLEmziwB9PuazZYLkcm07fvWOKCJJqI55sD5Q==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.16.0.tgz", + "integrity": "sha512-0g5vDDPvNnQk7WM/aE92dTDxXJoOE0biiIcUb3qkn/F6h/ZQZPlZIbE2XSXH2vFPfphkgCxuR2vH6HHnobEOaQ==", "dev": true }, "lcid": { @@ -3328,6 +4815,15 @@ "promise": "^7.1.1", "request": "^2.83.0", "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } } }, "less-plugin-clean-css": { @@ -3375,6 +4871,34 @@ } } }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -3406,6 +4930,15 @@ "integrity": "sha512-9lz5IVdpwsKLMzQi0MQ+oD9EA0mIGcWYP7jXMTZVXP8D42PwuAk+M/HBFYQoxt1G5OR8m7aSIgb1UymfWGBWEw==", "dev": true }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -3425,25 +4958,44 @@ "yallist": "^3.0.2" } }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, "make-fetch-happen": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.0.tgz", - "integrity": "sha512-nFr/vpL1Jc60etMVKeaLOqfGjMMb3tAHFVJWxHOFCFS04Zmd7kGlMxo0l1tzfhoQje0/UPnd0X8OeGUiXXnfPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-6.0.0.tgz", + "integrity": "sha512-0c4s/5ktozfRWPvii/Bang+an/YCPzkTRFSzEC6uBMTUp02ZskNGgNFm0rmmMLYlFN5OvW7HruLIDSS2fjQjOA==", "dev": true, "requires": { "agentkeepalive": "^3.4.1", - "cacache": "^12.0.0", + "cacache": "^13.0.1", "http-cache-semantics": "^3.8.1", "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.1", "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "node-fetch-npm": "^2.0.2", + "minipass": "^3.0.0", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.1.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", "promise-retry": "^1.1.1", "socks-proxy-agent": "^4.0.0", - "ssri": "^6.0.0" + "ssri": "^7.0.1" } }, + "mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", + "dev": true + }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", @@ -3492,10 +5044,21 @@ "integrity": "sha512-pWB896KPGSGkp1XtyzRBftpTzwSOL0Gfk0wLvxt4f2mgzjY19o0LxJ3U25vNWTzsh7da+KTbuXQoQ3lOJZ8WHw==", "dev": true }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, "mdast-util-compact": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.3.tgz", - "integrity": "sha512-nRiU5GpNy62rZppDKbLwhhtw5DXoFMqw9UNZFmlPsNaQCZ//WLjGKUwWMdJrUH+Se7UvtO2gXtAMe0g/N+eI5w==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", + "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", "dev": true, "requires": { "unist-util-visit": "^1.1.0" @@ -3510,14 +5073,16 @@ "map-age-cleaner": "^0.1.1", "mimic-fn": "^2.0.0", "p-is-promise": "^2.0.0" - }, - "dependencies": { - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - } + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" } }, "meow": { @@ -3555,9 +5120,9 @@ } }, "merge2": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.4.tgz", - "integrity": "sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", "dev": true }, "micromatch": { @@ -3581,6 +5146,16 @@ "to-regex": "^3.0.2" } }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -3589,26 +5164,38 @@ "optional": true }, "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", "dev": true, "optional": true }, "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", "dev": true, "optional": true, "requires": { - "mime-db": "1.40.0" + "mime-db": "1.42.0" } }, "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", "dev": true }, "minimatch": { @@ -3621,9 +5208,9 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "minimist-options": { @@ -3636,6 +5223,90 @@ "is-plain-obj": "^1.1.0" } }, + "minipass": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", + "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-fetch": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.2.1.tgz", + "integrity": "sha512-ssHt0dkljEDaKmTgQ04DQgx2ag6G2gMPxA5hpcsoeTbfDgRf2fC2gNSRc6kISjD7ckCpHwwQvXxuTBK8402fXg==", + "dev": true, + "requires": { + "encoding": "^0.1.12", + "minipass": "^3.1.0", + "minipass-pipeline": "^1.2.2", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz", + "integrity": "sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", + "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -3682,6 +5353,14 @@ "dev": true, "requires": { "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } } }, "move-concurrently": { @@ -3705,9 +5384,9 @@ "dev": true }, "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, "nan": { @@ -3742,30 +5421,72 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "node-fetch-npm": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz", - "integrity": "sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw==", + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", "dev": true, "requires": { - "encoding": "^0.1.11", - "json-parse-better-errors": "^1.0.0", - "safe-buffer": "^5.1.1" + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } } }, "node-releases": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.29.tgz", - "integrity": "sha512-R5bDhzh6I+tpi/9i2hrrvGJ3yKPYzlVOORDkXhnZuwi5D3q1I5w4vYy24PJXTcLk9Q0kws9TO77T75bcK8/ysQ==", + "version": "1.1.40", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.40.tgz", + "integrity": "sha512-r4LPcC5b/bS8BdtWH1fbeK88ib/wg9aqmg6/s3ngNLn2Ewkn/8J6Iw3P9RTlfIAdSdvYvQl2thCY5Y+qTAQ2iQ==", "dev": true, "requires": { - "semver": "^5.3.0" + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "normalize-package-data": { @@ -3826,6 +5547,12 @@ "dev": true, "optional": true }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -3857,6 +5584,16 @@ } } }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -3866,6 +5603,28 @@ "isobject": "^3.0.0" } }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -3885,28 +5644,34 @@ } }, "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "mimic-fn": "^2.1.0" } }, "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", + "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "word-wrap": "~1.2.3" } }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", @@ -3960,19 +5725,34 @@ "p-limit": "^2.0.0" } }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "dev": true + }, "parallel-transform": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", - "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", "dev": true, "requires": { - "cyclist": "~0.2.2", + "cyclist": "^1.0.1", "inherits": "^2.0.3", "readable-stream": "^2.1.5" } @@ -3986,6 +5766,20 @@ "callsites": "^3.0.0" } }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, "parse-entities": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", @@ -4010,12 +5804,24 @@ "json-parse-better-errors": "^1.0.1" } }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", @@ -4063,6 +5869,19 @@ } } }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -4071,9 +5890,9 @@ "optional": true }, "picomatch": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", - "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", + "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==", "dev": true }, "pify": { @@ -4082,6 +5901,15 @@ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -4089,9 +5917,9 @@ "dev": true }, "postcss": { - "version": "7.0.17", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.17.tgz", - "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==", + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", + "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -4099,6 +5927,12 @@ "supports-color": "^6.1.0" }, "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -4211,13 +6045,13 @@ } }, "postcss-sass": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.3.5.tgz", - "integrity": "sha512-B5z2Kob4xBxFjcufFnhQ2HqJQ2y/Zs/ic5EZbCywCkxKd756Q40cIQ/veRDwSrw1BF6+4wUgmpm0sBASqVi65A==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.2.tgz", + "integrity": "sha512-hcRgnd91OQ6Ot9R90PE/khUDCJHG8Uxxd3F7Y0+9VHjBiJgNv7sK5FxyHMCBtoLmmkzVbSj3M3OlqUfLJpq0CQ==", "dev": true, "requires": { - "gonzales-pe": "^4.2.3", - "postcss": "^7.0.1" + "gonzales-pe": "^4.2.4", + "postcss": "^7.0.21" } }, "postcss-scss": { @@ -4264,6 +6098,18 @@ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", "dev": true }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -4306,15 +6152,28 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "psl": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", + "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==", "dev": true, "optional": true }, - "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==", + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, - "optional": true + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } }, "pump": { "version": "3.0.0", @@ -4362,12 +6221,43 @@ "dev": true, "optional": true }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, "quick-lru": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", "dev": true }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -4380,12 +6270,6 @@ "strip-json-comments": "~2.0.1" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -4490,14 +6374,6 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } } }, "readdirp": { @@ -4521,6 +6397,30 @@ "strip-indent": "^2.0.0" } }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-transform": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", + "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", + "dev": true, + "requires": { + "private": "^0.1.6" + } + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -4537,6 +6437,20 @@ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, + "regexpu-core": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + }, "registry-auth-token": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.0.0.tgz", @@ -4547,6 +6461,29 @@ "safe-buffer": "^5.0.1" } }, + "regjsgen": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", + "dev": true + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, "remark": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", @@ -4677,6 +6614,59 @@ "path-parse": "^1.0.6" } }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + } + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4690,12 +6680,12 @@ "dev": true }, "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "requires": { - "onetime": "^2.0.0", + "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, @@ -4720,6 +6710,16 @@ "glob": "^7.1.3" } }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, "run-async": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", @@ -4739,18 +6739,18 @@ } }, "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "dev": true, "requires": { "tslib": "^1.9.0" } }, "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "safe-regex": { @@ -4768,12 +6768,29 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, + "serialize-javascript": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", + "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", + "dev": true + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -4803,6 +6820,22 @@ } } }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -4839,12 +6872,20 @@ "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } } }, "smart-buffer": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz", - "integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", + "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", "dev": true }, "snapdragon": { @@ -4895,12 +6936,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true } } }, @@ -4976,13 +7011,13 @@ } }, "socks": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.2.tgz", - "integrity": "sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz", + "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==", "dev": true, "requires": { - "ip": "^1.1.5", - "smart-buffer": "4.0.2" + "ip": "1.1.5", + "smart-buffer": "^4.1.0" } }, "socks-proxy-agent": { @@ -5006,10 +7041,16 @@ } } }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "source-map-resolve": { @@ -5025,6 +7066,24 @@ "urix": "^0.1.0" } }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", @@ -5103,12 +7162,13 @@ } }, "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz", + "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==", "dev": true, "requires": { - "figgy-pudding": "^3.5.1" + "figgy-pudding": "^3.5.1", + "minipass": "^3.1.1" } }, "state-toggle": { @@ -5138,6 +7198,16 @@ } } }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, "stream-each": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", @@ -5148,6 +7218,19 @@ "stream-shift": "^1.0.0" } }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, "stream-shift": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", @@ -5155,26 +7238,45 @@ "dev": true }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" }, "dependencies": { "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.0" } } } }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -5182,14 +7284,6 @@ "dev": true, "requires": { "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } } }, "stringify-entities": { @@ -5252,9 +7346,9 @@ "dev": true }, "stylelint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-10.1.0.tgz", - "integrity": "sha512-OmlUXrgzEMLQYj1JPTpyZPR9G4bl0StidfHnGJEMpdiQ0JyTq0MPg1xkHk1/xVJ2rTPESyJCDWjG8Kbpoo7Kuw==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-11.1.1.tgz", + "integrity": "sha512-Vx6TAJsxG6qksiFvxQTKriQhp1CqUWdpTDITEkAjTR+l+8Af7qNlvrUDXfpuFJgXh/ayF8xdMSKE+SstcsPmMA==", "dev": true, "requires": { "autoprefixer": "^9.5.1", @@ -5272,29 +7366,28 @@ "ignore": "^5.0.6", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", - "known-css-properties": "^0.14.0", + "known-css-properties": "^0.16.0", "leven": "^3.1.0", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "log-symbols": "^3.0.0", "mathml-tag-names": "^2.1.0", "meow": "^5.0.0", "micromatch": "^4.0.0", "normalize-selector": "^0.2.0", - "pify": "^4.0.1", "postcss": "^7.0.14", "postcss-html": "^0.36.0", - "postcss-jsx": "^0.36.1", + "postcss-jsx": "^0.36.3", "postcss-less": "^3.1.4", "postcss-markdown": "^0.36.0", "postcss-media-query-parser": "^0.2.3", "postcss-reporter": "^6.0.1", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^4.0.1", - "postcss-sass": "^0.3.5", + "postcss-sass": "^0.4.1", "postcss-scss": "^2.0.0", "postcss-selector-parser": "^3.1.0", "postcss-syntax": "^0.36.2", - "postcss-value-parser": "^3.3.1", + "postcss-value-parser": "^4.0.2", "resolve-from": "^5.0.0", "signal-exit": "^3.0.2", "slash": "^3.0.0", @@ -5304,7 +7397,8 @@ "style-search": "^0.1.0", "sugarss": "^2.0.0", "svg-tags": "^1.0.0", - "table": "^5.2.3" + "table": "^5.2.3", + "v8-compile-cache": "^2.1.0" }, "dependencies": { "braces": { @@ -5316,12 +7410,6 @@ "fill-range": "^7.0.1" } }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -5343,12 +7431,6 @@ "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", "dev": true }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -5374,12 +7456,6 @@ "picomatch": "^2.0.5" } }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -5392,17 +7468,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "string-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", - "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^5.2.0" - } - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5415,18 +7480,18 @@ } }, "stylelint-config-recommended": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-2.2.0.tgz", - "integrity": "sha512-bZ+d4RiNEfmoR74KZtCKmsABdBJr4iXRiCso+6LtMJPw5rd/KnxUWTxht7TbafrTJK1YRjNgnN0iVZaJfc3xJA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-3.0.0.tgz", + "integrity": "sha512-F6yTRuc06xr1h5Qw/ykb2LuFynJ2IxkKfCMf+1xqPffkxh0S09Zc902XCffcsw/XMFq/OzQ1w54fLIDtmRNHnQ==", "dev": true }, "stylelint-config-standard": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-18.3.0.tgz", - "integrity": "sha512-Tdc/TFeddjjy64LvjPau9SsfVRexmTFqUhnMBrzz07J4p2dVQtmpncRF/o8yZn8ugA3Ut43E6o1GtjX80TFytw==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-19.0.0.tgz", + "integrity": "sha512-VvcODsL1PryzpYteWZo2YaA5vU/pWfjqBpOvmeA8iB2MteZ/ZhI1O4hnrWMidsS4vmEJpKtjdhLdfGJmmZm6Cg==", "dev": true, "requires": { - "stylelint-config-recommended": "^2.2.0" + "stylelint-config-recommended": "^3.0.0" } }, "sugarss": { @@ -5465,6 +7530,18 @@ "string-width": "^3.0.0" }, "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -5478,6 +7555,94 @@ } } }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "terser": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.0.tgz", + "integrity": "sha512-oDG16n2WKm27JO8h4y/w3iqBGAOSCtq7k8dRmrn4Wf9NouL0b2WpMHGChFGZq4nFAQy1FsNJrVQHfurXOSTmOA==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", + "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.7.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "cacache": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + } + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -5500,6 +7665,15 @@ "xtend": "~4.0.1" } }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -5509,6 +7683,12 @@ "os-tmpdir": "~1.0.2" } }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -5589,12 +7769,6 @@ "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", "dev": true }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, "trim-trailing-lines": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz", @@ -5613,6 +7787,12 @@ "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "dev": true }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -5639,6 +7819,12 @@ "prelude-ls": "~1.1.2" } }, + "type-fest": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", + "dev": true + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -5655,6 +7841,34 @@ "xtend": "^4.0.1" } }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", + "dev": true + }, "unified": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", @@ -5708,9 +7922,9 @@ } }, "unist-util-find-all-after": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.4.tgz", - "integrity": "sha512-CaxvMjTd+yF93BKLJvZnEfqdM7fgEACsIpQqz8vIj9CJnUb9VpyymFS3tg6TCtgrF7vfCJBF5jbT2Ox9CBRYRQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.5.tgz", + "integrity": "sha512-lWgIc3rrTMTlK1Y0hEuL+k+ApzFk78h+lsaa2gHf63Gp5Ww+mt11huDniuaoq1H+XMK2lIIjjPkncxXcDp3QDw==", "dev": true, "requires": { "unist-util-is": "^3.0.0" @@ -5723,19 +7937,22 @@ "dev": true }, "unist-util-remove-position": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.3.tgz", - "integrity": "sha512-CtszTlOjP2sBGYc2zcKA/CvNdTdEs3ozbiJ63IPBxh8iZg42SCCb8m04f8z2+V1aSk5a7BxbZKEdoDjadmBkWA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", "dev": true, "requires": { "unist-util-visit": "^1.1.0" } }, "unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", - "dev": true + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.2.tgz", + "integrity": "sha512-nK5n8OGhZ7ZgUwoUbL8uiVRwAbZyzBsB/Ddrlbu6jwwubFza4oe15KlyEaLNMXQW1svOQq4xesUeqA85YrIUQA==", + "dev": true, + "requires": { + "@types/unist": "^2.0.2" + } }, "unist-util-visit": { "version": "1.4.1", @@ -5802,21 +8019,21 @@ } }, "upath": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", - "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true }, "updates": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/updates/-/updates-8.5.3.tgz", - "integrity": "sha512-bREdpucNEtSULXu2PLfYmKnRD6E0lM16vbZNsgR39Ou7FqiUEyasA0o2Lrb3uHwZN3L2WhOjf+EjQl7NiOHhug==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/updates/-/updates-9.0.1.tgz", + "integrity": "sha512-uz2RvIYKH7DfjnZ1Km3L3w3qjaPhzPAwi4gHgDPT87YkymGk5bU7jIe12kOGtN3czGHLf6Z2ryZpsx2kETXaCQ==", "dev": true, "requires": { "chalk": "2.4.2", "find-up": "4.1.0", - "hosted-git-info": "3.0.0", - "make-fetch-happen": "5.0.0", + "hosted-git-info": "3.0.2", + "make-fetch-happen": "6.0.0", "minimist": "1.2.0", "rc": "1.2.8", "registry-auth-token": "4.0.0", @@ -5825,12 +8042,6 @@ "text-table": "0.2.0" }, "dependencies": { - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -5842,20 +8053,14 @@ } }, "hosted-git-info": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.0.tgz", - "integrity": "sha512-zYSx1cP4MLsvKtTg8DF/PI6e6FHZ3wcawcTGsrLU2TM+UfD4jmSrn2wdQT16TFbH3lO4PIdjLG0E+cuYDgFD9g==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.2.tgz", + "integrity": "sha512-ezZMWtHXm7Eb7Rq4Mwnx2vs79WUx2QmRg3+ZqeGroKzfDO+EprOcgRPYghsOP9JuYBfK18VojmRTGCg8Ma+ktw==", "dev": true, "requires": { "lru-cache": "^5.1.1" } }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -5865,12 +8070,6 @@ "p-locate": "^4.1.0" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", @@ -5920,12 +8119,47 @@ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -5980,26 +8214,259 @@ }, "dependencies": { "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", "dev": true + }, + "unist-util-stringify-position": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", + "dev": true + }, + "vfile-message": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", + "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "dev": true, + "requires": { + "unist-util-stringify-position": "^1.1.1" + } } } }, "vfile-location": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.5.tgz", - "integrity": "sha512-Pa1ey0OzYBkLPxPZI3d9E+S4BmvfVwNAAXrrqGbwTVXWaX2p9kM1zZ+n35UtVM06shmWKH4RPRN8KI80qE3wNQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", "dev": true }, "vfile-message": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", - "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.2.tgz", + "integrity": "sha512-gNV2Y2fDvDOOqq8bEe7cF3DXU6QgV4uA9zMR2P8tix11l1r7zju3zry3wZ8sx+BEfuO6WQ7z2QzfWTvqHQiwsA==", "dev": true, "requires": { - "unist-util-stringify-position": "^1.1.1" + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "webpack": { + "version": "4.41.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.2.tgz", + "integrity": "sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.1", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + }, + "webpack-cli": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.10.tgz", + "integrity": "sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg==", + "dev": true, + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" + }, + "dependencies": { + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "which": { @@ -6017,12 +8484,21 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -6104,9 +8580,9 @@ "dev": true }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "yargs": { @@ -6127,6 +8603,39 @@ "which-module": "^2.0.0", "y18n": "^3.2.1 || ^4.0.0", "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "yargs-parser": { diff --git a/package.json b/package.json index 376ae89b670..469b5a2ead3 100644 --- a/package.json +++ b/package.json @@ -5,14 +5,23 @@ "node": ">=8" }, "devDependencies": { - "autoprefixer": "9.6.1", - "eslint": "6.3.0", + "@babel/core": "7.7.2", + "@babel/preset-env": "7.7.1", + "autoprefixer": "9.7.1", + "babel-loader": "8.0.6", + "core-js": "3.4.1", + "eslint": "6.6.0", + "eslint-config-airbnb-base": "14.0.0", + "eslint-plugin-import": "2.18.2", "less": "3.10.3", "less-plugin-clean-css": "1.5.1", "postcss-cli": "6.1.3", - "stylelint": "10.1.0", - "stylelint-config-standard": "18.3.0", - "updates": "8.5.3" + "stylelint": "11.1.1", + "stylelint-config-standard": "19.0.0", + "terser-webpack-plugin": "2.2.1", + "updates": "9.0.1", + "webpack": "4.41.2", + "webpack-cli": "3.3.10" }, "browserslist": [ "> 1%", diff --git a/public/css/index.css b/public/css/index.css index 1a6032cf3e3..100870c1b24 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -73,7 +73,7 @@ a{cursor:pointer} .right.stackable.menu{margin-left:auto;display:flex;align-items:inherit;flex-direction:inherit} .ui.left{float:left} .ui.right{float:right} -.ui.button,.ui.menu .item{-webkit-user-select:auto;-moz-user-select:auto;-ms-user-select:auto;user-select:auto} +.ui.button,.ui.menu .item{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto} .ui.container.fluid.padded{padding:0 10px 0 10px} .ui.form .ui.button{font-weight:400} .ui.floating.label{z-index:10} @@ -233,14 +233,14 @@ i.icons .icon:first-child{margin-right:0} i.icon.centerlock{top:1.5em} .ui.label>.detail .icons{margin-right:.25em} .ui.label>.detail .icons .icon{margin-right:0} -.lines-num{vertical-align:top;text-align:right!important;color:#999;background:#f5f5f5;width:1%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} +.lines-num{vertical-align:top;text-align:right!important;color:#999;background:#f5f5f5;width:1%;-webkit-user-select:none;-ms-user-select:none;user-select:none} .lines-num span:before{content:attr(data-line-number);line-height:20px!important;padding:0 10px;cursor:pointer;display:block} .lines-code,.lines-num{padding:0!important} .lines-code .hljs,.lines-code ol,.lines-code pre,.lines-num .hljs,.lines-num ol,.lines-num pre{background-color:#fff;margin:0;padding:0!important} .lines-code .hljs li,.lines-code ol li,.lines-code pre li,.lines-num .hljs li,.lines-num ol li,.lines-num pre li{display:block;width:100%} .lines-code .hljs li:before,.lines-code ol li:before,.lines-code pre li:before,.lines-num .hljs li:before,.lines-num ol li:before,.lines-num pre li:before{content:' '} -.lines-commit{vertical-align:top;color:#999;padding:0!important;background:#f5f5f5;width:1%;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none} -.lines-commit .blame-info{width:350px;max-width:350px;display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:0 0 0 10px} +.lines-commit{vertical-align:top;color:#999;padding:0!important;background:#f5f5f5;width:1%;-ms-user-select:none;-webkit-user-select:none;user-select:none} +.lines-commit .blame-info{width:350px;max-width:350px;display:block;-webkit-user-select:none;-ms-user-select:none;user-select:none;padding:0 0 0 10px} .lines-commit .blame-info .blame-data{display:flex;font-family:-apple-system,BlinkMacSystemFont,system-ui,'Segoe UI',Roboto,Helvetica,Arial} .lines-commit .blame-info .blame-data .blame-message{flex-grow:2;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;line-height:20px} .lines-commit .blame-info .blame-data .blame-avatar,.lines-commit .blame-info .blame-data .blame-time{flex-shrink:0} @@ -333,7 +333,7 @@ i.icon.centerlock{top:1.5em} .repository.wiki.revisions .ui.container>.ui.stackable.grid>.header{margin-top:0} .repository.wiki.revisions .ui.container>.ui.stackable.grid>.header .sub.header{padding-left:52px;word-break:break-word} .file-revisions-btn{display:block;float:left;margin-bottom:2px!important;padding:11px!important;margin-right:10px!important} -.file-revisions-btn i{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} +.file-revisions-btn i{-webkit-touch-callout:none;-webkit-user-select:none;-ms-user-select:none;user-select:none} .home .logo{max-width:220px} @media only screen and (max-width:767px){.home .hero h1{font-size:3.5em} .home .hero h2{font-size:2em} @@ -687,7 +687,7 @@ i.icon.centerlock{top:1.5em} .repository .diff-box .header .file{flex:1;color:#888;word-break:break-all} .repository .diff-box .header .button{margin:-5px 0 -5px 12px;padding:8px 10px;flex:0 0 auto} .repository .diff-file-box .header{background-color:#f7f7f7} -.repository .diff-file-box .file-body.file-code .lines-num{text-align:right;color:#a6a6a6;background:#fafafa;width:1%;min-width:50px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top} +.repository .diff-file-box .file-body.file-code .lines-num{text-align:right;color:#a6a6a6;background:#fafafa;width:1%;min-width:50px;-webkit-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top} .repository .diff-file-box .file-body.file-code .lines-num span.fold{display:block;text-align:center} .repository .diff-file-box .file-body.file-code .lines-num-old{border-right:1px solid #ddd} .repository .diff-file-box .code-diff{font-size:12px} @@ -698,7 +698,7 @@ i.icon.centerlock{top:1.5em} .repository .diff-file-box .code-diff tbody tr .removed-code{background-color:#f99} .repository .diff-file-box .code-diff tbody tr .added-code{background-color:#9f9} .repository .diff-file-box .code-diff tbody tr [data-line-num]::before{content:attr(data-line-num);text-align:right} -.repository .diff-file-box .code-diff tbody tr .lines-type-marker{width:10px;min-width:10px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} +.repository .diff-file-box .code-diff tbody tr .lines-type-marker{width:10px;min-width:10px;-webkit-user-select:none;-ms-user-select:none;user-select:none} .repository .diff-file-box .code-diff tbody tr [data-type-marker]::before{content:attr(data-type-marker);text-align:right;display:inline-block} .repository .diff-file-box .code-diff-unified tbody tr.del-code td{background-color:#ffe0e0!important;border-color:#f1c0c0!important} .repository .diff-file-box .code-diff-unified tbody tr.add-code td{background-color:#d6fcd6!important;border-color:#c1e9c1!important} @@ -898,6 +898,7 @@ tbody.commit-list{vertical-align:baseline} .repo-buttons .disabled-repo-button a.button:hover{background:0 0!important;color:rgba(0,0,0,.6)!important;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset!important} .repo-buttons .ui.labeled.button>.label{border-left:0!important;margin:0!important} .tag-code,.tag-code td{background-color:#f0f0f0!important;border-color:#d3cfcf!important;padding-top:8px;padding-bottom:8px} +td.blob-excerpt{background-color:#fafafa} .issue-keyword{border-bottom:1px dotted #959da5;display:inline-block} .file-header{display:flex;justify-content:space-between;align-items:center;padding:8px 12px!important} .file-info{display:flex;align-items:center} @@ -1068,4 +1069,8 @@ tbody.commit-list{vertical-align:baseline} .comment-code-cloud .footer:after{clear:both;content:"";display:block} .comment-code-cloud button.comment-form-reply{margin:.5em .5em .5em 4.5em} .comment-code-cloud form.comment-form-reply{margin:0 0 0 4em} -.file-comment{font:12px 'SF Mono',Consolas,Menlo,'Liberation Mono',Monaco,'Lucida Console',monospace;color:rgba(0,0,0,.87)} \ No newline at end of file +.file-comment{font:12px 'SF Mono',Consolas,Menlo,'Liberation Mono',Monaco,'Lucida Console',monospace;color:rgba(0,0,0,.87)} +.ui.fold-code{margin-right:1em;padding-left:5px;cursor:pointer;width:22px;font-size:12px} +.ui.fold-code:hover{color:#428bca} +.ui.blob-excerpt{display:block;line-height:20px;font-size:16px;cursor:pointer} +.ui.blob-excerpt:hover{color:#428bca} \ No newline at end of file diff --git a/public/css/theme-arc-green.css b/public/css/theme-arc-green.css index 74a7c3ddc31..6b28d54925b 100644 --- a/public/css/theme-arc-green.css +++ b/public/css/theme-arc-green.css @@ -14,7 +14,7 @@ body{background:#383c4a;color:#9e9e9e} *{scrollbar-width:thin;scrollbar-color:#87ab63 rgba(255,255,255,.1)} ::-webkit-scrollbar{-webkit-appearance:none!important;width:10px!important;height:10px!important} ::-webkit-scrollbar-track{border-radius:0!important;background:rgba(255,255,255,.1)!important} -::-webkit-scrollbar-thumb{cursor:pointer!important;border-radius:5px!important;transition:color .2s ease!important;background:#87ab63!important} +::-webkit-scrollbar-thumb{cursor:pointer!important;border-radius:5px!important;-webkit-transition:color .2s ease!important;transition:color .2s ease!important;background:#87ab63!important} ::-webkit-scrollbar-thumb:window-inactive{background:#87ab63!important} ::-webkit-scrollbar-thumb:hover{background:#87ab63!important} a{color:#87ab63} diff --git a/public/js/draw.js b/public/js/draw.js deleted file mode 100644 index 643ff233c01..00000000000 --- a/public/js/draw.js +++ /dev/null @@ -1,15 +0,0 @@ -/* globals gitGraph */ - -$(document).ready(function () { - const graphList = []; - - if (!document.getElementById('graph-canvas')) { - return; - } - - $("#graph-raw-list li span.node-relation").each(function () { - graphList.push($(this).text()); - }) - - gitGraph(document.getElementById('graph-canvas'), graphList); -}) diff --git a/public/js/index.js b/public/js/index.js index af314183714..353a4fd19b9 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -1,3424 +1,2 @@ -/* globals wipPrefixes, issuesTribute, emojiTribute */ -/* exported timeAddManual, toggleStopwatch, cancelStopwatch, initHeatmap */ -/* exported toggleDeadlineForm, setDeadline, deleteDependencyModal, cancelCodeComment, onOAuthLoginClick */ -'use strict'; - -function htmlEncode(text) { - return jQuery('
').text(text).html() -} - -let csrf; -let suburl; -let previewFileModes; -let simpleMDEditor; -let codeMirrorEditor; - -// Disable Dropzone auto-discover because it's manually initialized -if (typeof(Dropzone) !== "undefined") { - Dropzone.autoDiscover = false; -} - -// Polyfill for IE9+ support (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) -if (!Array.from) { - Array.from = (function () { - const toStr = Object.prototype.toString; - const isCallable = function (fn) { - return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; - }; - const toInteger = function (value) { - const number = Number(value); - if (isNaN(number)) { return 0; } - if (number === 0 || !isFinite(number)) { return number; } - return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); - }; - const maxSafeInteger = Math.pow(2, 53) - 1; - const toLength = function (value) { - const len = toInteger(value); - return Math.min(Math.max(len, 0), maxSafeInteger); - }; - - // The length property of the from method is 1. - return function from(arrayLike/*, mapFn, thisArg */) { - // 1. Let C be the this value. - const C = this; - - // 2. Let items be ToObject(arrayLike). - const items = Object(arrayLike); - - // 3. ReturnIfAbrupt(items). - if (arrayLike == null) { - throw new TypeError("Array.from requires an array-like object - not null or undefined"); - } - - // 4. If mapfn is undefined, then let mapping be false. - const mapFn = arguments.length > 1 ? arguments[1] : void undefined; - let T; - if (typeof mapFn !== 'undefined') { - // 5. else - // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. - if (!isCallable(mapFn)) { - throw new TypeError('Array.from: when provided, the second argument must be a function'); - } - - // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. - if (arguments.length > 2) { - T = arguments[2]; - } - } - - // 10. Let lenValue be Get(items, "length"). - // 11. Let len be ToLength(lenValue). - const len = toLength(items.length); - - // 13. If IsConstructor(C) is true, then - // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len. - // 14. a. Else, Let A be ArrayCreate(len). - const A = isCallable(C) ? Object(new C(len)) : new Array(len); - - // 16. Let k be 0. - let k = 0; - // 17. Repeat, while k < len… (also steps a - h) - let kValue; - while (k < len) { - kValue = items[k]; - if (mapFn) { - A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); - } else { - A[k] = kValue; - } - k += 1; - } - // 18. Let putStatus be Put(A, "length", len, true). - A.length = len; - // 20. Return A. - return A; - }; - }()); -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign -if (typeof Object.assign != 'function') { - // Must be writable: true, enumerable: false, configurable: true - Object.defineProperty(Object, "assign", { - value: function assign(target, _varArgs) { // .length of function is 2 - 'use strict'; - if (target == null) { // TypeError if undefined or null - throw new TypeError('Cannot convert undefined or null to object'); - } - - const to = Object(target); - - for (let index = 1; index < arguments.length; index++) { - const nextSource = arguments[index]; - - if (nextSource != null) { // Skip over if undefined or null - for (const nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } - } - return to; - }, - writable: true, - configurable: true - }); -} - -function initCommentPreviewTab($form) { - const $tabMenu = $form.find('.tabular.menu'); - $tabMenu.find('.item').tab(); - $tabMenu.find('.item[data-tab="' + $tabMenu.data('preview') + '"]').click(function () { - const $this = $(this); - $.post($this.data('url'), { - "_csrf": csrf, - "mode": "gfm", - "context": $this.data('context'), - "text": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() - }, - function (data) { - const $previewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('preview') + '"]'); - $previewPanel.html(data); - emojify.run($previewPanel[0]); - $('pre code', $previewPanel[0]).each(function () { - hljs.highlightBlock(this); - }); - } - ); - }); - - buttonsClickOnEnter(); -} - -function initEditPreviewTab($form) { - const $tabMenu = $form.find('.tabular.menu'); - $tabMenu.find('.item').tab(); - const $previewTab = $tabMenu.find('.item[data-tab="' + $tabMenu.data('preview') + '"]'); - if ($previewTab.length) { - previewFileModes = $previewTab.data('preview-file-modes').split(','); - $previewTab.click(function () { - const $this = $(this); - $.post($this.data('url'), { - "_csrf": csrf, - "mode": "gfm", - "context": $this.data('context'), - "text": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() - }, - function (data) { - const $previewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('preview') + '"]'); - $previewPanel.html(data); - emojify.run($previewPanel[0]); - $('pre code', $previewPanel[0]).each(function () { - hljs.highlightBlock(this); - }); - } - ); - }); - } -} - -function initEditDiffTab($form) { - const $tabMenu = $form.find('.tabular.menu'); - $tabMenu.find('.item').tab(); - $tabMenu.find('.item[data-tab="' + $tabMenu.data('diff') + '"]').click(function () { - const $this = $(this); - $.post($this.data('url'), { - "_csrf": csrf, - "context": $this.data('context'), - "content": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() - }, - function (data) { - const $diffPreviewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('diff') + '"]'); - $diffPreviewPanel.html(data); - emojify.run($diffPreviewPanel[0]); - } - ); - }); -} - - -function initEditForm() { - if ($('.edit.form').length == 0) { - return; - } - - initEditPreviewTab($('.edit.form')); - initEditDiffTab($('.edit.form')); -} - -function initBranchSelector() { - const $selectBranch = $('.ui.select-branch') - const $branchMenu = $selectBranch.find('.reference-list-menu'); - $branchMenu.find('.item:not(.no-select)').click(function () { - const selectedValue = $(this).data('id'); - $($(this).data('id-selector')).val(selectedValue); - $selectBranch.find('.ui .branch-name').text(selectedValue); - }); - $selectBranch.find('.reference.column').click(function () { - $selectBranch.find('.scrolling.reference-list-menu').css('display', 'none'); - $selectBranch.find('.reference .text').removeClass('black'); - $($(this).data('target')).css('display', 'block'); - $(this).find('.text').addClass('black'); - return false; - }); -} - -function updateIssuesMeta(url, action, issueIds, elementId) { - return new Promise(function(resolve) { - $.ajax({ - type: "POST", - url: url, - data: { - "_csrf": csrf, - "action": action, - "issue_ids": issueIds, - "id": elementId - }, - success: resolve - }) - }) -} - -function initRepoStatusChecker() { - const migrating = $("#repo_migrating"); - $('#repo_migrating_failed').hide(); - if (migrating) { - const repo_name = migrating.attr('repo'); - if (typeof repo_name === 'undefined') { - return - } - $.ajax({ - type: "GET", - url: suburl +"/"+repo_name+"/status", - data: { - "_csrf": csrf, - }, - complete: function(xhr) { - if (xhr.status == 200) { - if (xhr.responseJSON) { - if (xhr.responseJSON["status"] == 0) { - location.reload(); - return - } - - setTimeout(function () { - initRepoStatusChecker() - }, 2000); - return - } - } - $('#repo_migrating_progress').hide(); - $('#repo_migrating_failed').show(); - } - }) - } -} - -function initReactionSelector(parent) { - let reactions = ''; - if (!parent) { - parent = $(document); - reactions = '.reactions > '; - } - - parent.find(reactions + 'a.label').popup({'position': 'bottom left', 'metadata': {'content': 'title', 'title': 'none'}}); - - parent.find('.select-reaction > .menu > .item, ' + reactions + 'a.label').on('click', function(e){ - const vm = this; - e.preventDefault(); - - if ($(this).hasClass('disabled')) return; - - const actionURL = $(this).hasClass('item') ? - $(this).closest('.select-reaction').data('action-url') : - $(this).data('action-url'); - const url = actionURL + '/' + ($(this).hasClass('blue') ? 'unreact' : 'react'); - $.ajax({ - type: 'POST', - url: url, - data: { - '_csrf': csrf, - 'content': $(this).data('content') - } - }).done(function(resp) { - if (resp && (resp.html || resp.empty)) { - const content = $(vm).closest('.content'); - let react = content.find('.segment.reactions'); - if (!resp.empty && react.length > 0) { - react.remove(); - } - if (!resp.empty) { - react = $('
'); - const attachments = content.find('.segment.bottom:first'); - if (attachments.length > 0) { - react.insertBefore(attachments); - } else { - react.appendTo(content); - } - react.html(resp.html); - const hasEmoji = react.find('.has-emoji'); - for (let i = 0; i < hasEmoji.length; i++) { - emojify.run(hasEmoji.get(i)); - } - react.find('.dropdown').dropdown(); - initReactionSelector(react); - } - } - }); - }); -} - -function insertAtCursor(field, value) { - if (field.selectionStart || field.selectionStart === 0) { - const startPos = field.selectionStart; - const endPos = field.selectionEnd; - field.value = field.value.substring(0, startPos) - + value - + field.value.substring(endPos, field.value.length); - field.selectionStart = startPos + value.length; - field.selectionEnd = startPos + value.length; - } else { - field.value += value; - } -} - -function replaceAndKeepCursor(field, oldval, newval) { - if (field.selectionStart || field.selectionStart === 0) { - const startPos = field.selectionStart; - const endPos = field.selectionEnd; - field.value = field.value.replace(oldval, newval); - field.selectionStart = startPos + newval.length - oldval.length; - field.selectionEnd = endPos + newval.length - oldval.length; - } else { - field.value = field.value.replace(oldval, newval); - } -} - -function retrieveImageFromClipboardAsBlob(pasteEvent, callback){ - if (!pasteEvent.clipboardData) { - return; - } - - const items = pasteEvent.clipboardData.items; - if (typeof(items) === "undefined") { - return; - } - - for (let i = 0; i < items.length; i++) { - if (items[i].type.indexOf("image") === -1) continue; - const blob = items[i].getAsFile(); - - if (typeof(callback) === "function") { - pasteEvent.preventDefault(); - pasteEvent.stopPropagation(); - callback(blob); - } - } -} - -function uploadFile(file, callback) { - const xhr = new XMLHttpRequest(); - - xhr.onload = function() { - if (xhr.status == 200) { - callback(xhr.responseText); - } - }; - - xhr.open("post", suburl + "/attachments", true); - xhr.setRequestHeader("X-Csrf-Token", csrf); - const formData = new FormData(); - formData.append('file', file, file.name); - xhr.send(formData); -} - -function reload() { - window.location.reload(); -} - -function initImagePaste(target) { - target.each(function() { - const field = this; - field.addEventListener('paste', function(event){ - retrieveImageFromClipboardAsBlob(event, function(img) { - const name = img.name.substr(0, img.name.lastIndexOf('.')); - insertAtCursor(field, '![' + name + ']()'); - uploadFile(img, function(res) { - const data = JSON.parse(res); - replaceAndKeepCursor(field, '![' + name + ']()', '![' + name + '](' + suburl + '/attachments/' + data.uuid + ')'); - const input = $('').val(data.uuid); - $('.files').append(input); - }); - }); - }, false); - }); -} - -function initCommentForm() { - if ($('.comment.form').length == 0) { - return - } - - initBranchSelector(); - initCommentPreviewTab($('.comment.form')); - initImagePaste($('.comment.form textarea')); - - // Listsubmit - function initListSubmits(selector, outerSelector) { - const $list = $('.ui.' + outerSelector + '.list'); - const $noSelect = $list.find('.no-select'); - const $listMenu = $('.' + selector + ' .menu'); - let hasLabelUpdateAction = $listMenu.data('action') == 'update'; - const labels = {}; - - $('.' + selector).dropdown('setting', 'onHide', function(){ - hasLabelUpdateAction = $listMenu.data('action') == 'update'; // Update the var - if (hasLabelUpdateAction) { - const promises = []; - Object.keys(labels).forEach(function(elementId) { - const label = labels[elementId]; - const promise = updateIssuesMeta( - label["update-url"], - label["action"], - label["issue-id"], - elementId - ); - promises.push(promise); - }); - Promise.all(promises).then(reload); - } - }); - - $listMenu.find('.item:not(.no-select)').click(function () { - - // we don't need the action attribute when updating assignees - if (selector == 'select-assignees-modify') { - - // UI magic. We need to do this here, otherwise it would destroy the functionality of - // adding/removing labels - if ($(this).hasClass('checked')) { - $(this).removeClass('checked'); - $(this).find('.octicon').removeClass('octicon-check'); - } else { - $(this).addClass('checked'); - $(this).find('.octicon').addClass('octicon-check'); - } - - updateIssuesMeta( - $listMenu.data('update-url'), - "", - $listMenu.data('issue-id'), - $(this).data('id') - ); - $listMenu.data('action', 'update'); // Update to reload the page when we updated items - return false; - } - - if ($(this).hasClass('checked')) { - $(this).removeClass('checked'); - $(this).find('.octicon').removeClass('octicon-check'); - if (hasLabelUpdateAction) { - if (!($(this).data('id') in labels)) { - labels[$(this).data('id')] = { - "update-url": $listMenu.data('update-url'), - "action": "detach", - "issue-id": $listMenu.data('issue-id'), - }; - } else { - delete labels[$(this).data('id')]; - } - } - } else { - $(this).addClass('checked'); - $(this).find('.octicon').addClass('octicon-check'); - if (hasLabelUpdateAction) { - if (!($(this).data('id') in labels)) { - labels[$(this).data('id')] = { - "update-url": $listMenu.data('update-url'), - "action": "attach", - "issue-id": $listMenu.data('issue-id'), - }; - } else { - delete labels[$(this).data('id')]; - } - } - } - - const listIds = []; - $(this).parent().find('.item').each(function () { - if ($(this).hasClass('checked')) { - listIds.push($(this).data('id')); - $($(this).data('id-selector')).removeClass('hide'); - } else { - $($(this).data('id-selector')).addClass('hide'); - } - }); - if (listIds.length == 0) { - $noSelect.removeClass('hide'); - } else { - $noSelect.addClass('hide'); - } - $($(this).parent().data('id')).val(listIds.join(",")); - return false; - }); - $listMenu.find('.no-select.item').click(function () { - if (hasLabelUpdateAction || selector == 'select-assignees-modify') { - updateIssuesMeta( - $listMenu.data('update-url'), - "clear", - $listMenu.data('issue-id'), - "" - ).then(reload); - } - - $(this).parent().find('.item').each(function () { - $(this).removeClass('checked'); - $(this).find('.octicon').removeClass('octicon-check'); - }); - - $list.find('.item').each(function () { - $(this).addClass('hide'); - }); - $noSelect.removeClass('hide'); - $($(this).parent().data('id')).val(''); - - }); - } - - // Init labels and assignees - initListSubmits('select-label', 'labels'); - initListSubmits('select-assignees', 'assignees'); - initListSubmits('select-assignees-modify', 'assignees'); - - function selectItem(select_id, input_id) { - const $menu = $(select_id + ' .menu'); - const $list = $('.ui' + select_id + '.list'); - const hasUpdateAction = $menu.data('action') == 'update'; - - $menu.find('.item:not(.no-select)').click(function () { - $(this).parent().find('.item').each(function () { - $(this).removeClass('selected active') - }); - - $(this).addClass('selected active'); - if (hasUpdateAction) { - updateIssuesMeta( - $menu.data('update-url'), - "", - $menu.data('issue-id'), - $(this).data('id') - ).then(reload); - } - switch (input_id) { - case '#milestone_id': - $list.find('.selected').html('
' + - htmlEncode($(this).text()) + ''); - break; - case '#assignee_id': - $list.find('.selected').html('' + - '' + - htmlEncode($(this).text()) + ''); - } - $('.ui' + select_id + '.list .no-select').addClass('hide'); - $(input_id).val($(this).data('id')); - }); - $menu.find('.no-select.item').click(function () { - $(this).parent().find('.item:not(.no-select)').each(function () { - $(this).removeClass('selected active') - }); - - if (hasUpdateAction) { - updateIssuesMeta( - $menu.data('update-url'), - "", - $menu.data('issue-id'), - $(this).data('id') - ).then(reload); - } - - $list.find('.selected').html(''); - $list.find('.no-select').removeClass('hide'); - $(input_id).val(''); - }); - } - - // Milestone and assignee - selectItem('.select-milestone', '#milestone_id'); - selectItem('.select-assignee', '#assignee_id'); -} - -function initInstall() { - if ($('.install').length == 0) { - return; - } - - if ($('#db_host').val()=="") { - $('#db_host').val("127.0.0.1:3306"); - $('#db_user').val("gitea"); - $('#db_name').val("gitea"); - } - - // Database type change detection. - $("#db_type").change(function () { - const sqliteDefault = 'data/gitea.db'; - const tidbDefault = 'data/gitea_tidb'; - - const dbType = $(this).val(); - if (dbType === "SQLite3") { - $('#sql_settings').hide(); - $('#pgsql_settings').hide(); - $('#mysql_settings').hide(); - $('#sqlite_settings').show(); - - if (dbType === "SQLite3" && $('#db_path').val() == tidbDefault) { - $('#db_path').val(sqliteDefault); - } - return; - } - - const dbDefaults = { - "MySQL": "127.0.0.1:3306", - "PostgreSQL": "127.0.0.1:5432", - "MSSQL": "127.0.0.1:1433" - }; - - $('#sqlite_settings').hide(); - $('#sql_settings').show(); - - $('#pgsql_settings').toggle(dbType === "PostgreSQL"); - $('#mysql_settings').toggle(dbType === "MySQL"); - $.each(dbDefaults, function(_type, defaultHost) { - if ($('#db_host').val() == defaultHost) { - $('#db_host').val(dbDefaults[dbType]); - return false; - } - }); - }); - - // TODO: better handling of exclusive relations. - $('#offline-mode input').change(function () { - if ($(this).is(':checked')) { - $('#disable-gravatar').checkbox('check'); - $('#federated-avatar-lookup').checkbox('uncheck'); - } - }); - $('#disable-gravatar input').change(function () { - if ($(this).is(':checked')) { - $('#federated-avatar-lookup').checkbox('uncheck'); - } else { - $('#offline-mode').checkbox('uncheck'); - } - }); - $('#federated-avatar-lookup input').change(function () { - if ($(this).is(':checked')) { - $('#disable-gravatar').checkbox('uncheck'); - $('#offline-mode').checkbox('uncheck'); - } - }); - $('#enable-openid-signin input').change(function () { - if ($(this).is(':checked')) { - if (!$('#disable-registration input').is(':checked')) { - $('#enable-openid-signup').checkbox('check'); - } - } else { - $('#enable-openid-signup').checkbox('uncheck'); - } - }); - $('#disable-registration input').change(function () { - if ($(this).is(':checked')) { - $('#enable-captcha').checkbox('uncheck'); - $('#enable-openid-signup').checkbox('uncheck'); - } else { - $('#enable-openid-signup').checkbox('check'); - } - }); - $('#enable-captcha input').change(function () { - if ($(this).is(':checked')) { - $('#disable-registration').checkbox('uncheck'); - } - }); -} - -function initRepository() { - if ($('.repository').length == 0) { - return; - } - - function initFilterSearchDropdown(selector) { - const $dropdown = $(selector); - $dropdown.dropdown({ - fullTextSearch: true, - selectOnKeydown: false, - onChange: function (_text, _value, $choice) { - if ($choice.data('url')) { - window.location.href = $choice.data('url'); - } - }, - message: {noResults: $dropdown.data('no-results')} - }); - } - - // File list and commits - if ($('.repository.file.list').length > 0 || - ('.repository.commits').length > 0) { - initFilterBranchTagDropdown('.choose.reference .dropdown'); - } - - // Wiki - if ($('.repository.wiki.view').length > 0) { - initFilterSearchDropdown('.choose.page .dropdown'); - } - - // Options - if ($('.repository.settings.options').length > 0) { - $('#repo_name').keyup(function () { - const $prompt = $('#repo-name-change-prompt'); - if ($(this).val().toString().toLowerCase() != $(this).data('name').toString().toLowerCase()) { - $prompt.show(); - } else { - $prompt.hide(); - } - }); - - // Enable or select internal/external wiki system and issue tracker. - $('.enable-system').change(function () { - if (this.checked) { - $($(this).data('target')).removeClass('disabled'); - if (!$(this).data('context')) $($(this).data('context')).addClass('disabled'); - } else { - $($(this).data('target')).addClass('disabled'); - if (!$(this).data('context')) $($(this).data('context')).removeClass('disabled'); - } - }); - $('.enable-system-radio').change(function () { - if (this.value == 'false') { - $($(this).data('target')).addClass('disabled'); - if (typeof $(this).data('context') !== 'undefined') $($(this).data('context')).removeClass('disabled'); - } else if (this.value == 'true') { - $($(this).data('target')).removeClass('disabled'); - if (typeof $(this).data('context') !== 'undefined') $($(this).data('context')).addClass('disabled'); - } - }); - } - - // Labels - if ($('.repository.labels').length > 0) { - // Create label - const $newLabelPanel = $('.new-label.segment'); - $('.new-label.button').click(function () { - $newLabelPanel.show(); - }); - $('.new-label.segment .cancel').click(function () { - $newLabelPanel.hide(); - }); - - $('.color-picker').each(function () { - $(this).minicolors(); - }); - $('.precolors .color').click(function () { - const color_hex = $(this).data('color-hex'); - $('.color-picker').val(color_hex); - $('.minicolors-swatch-color').css("background-color", color_hex); - }); - $('.edit-label-button').click(function () { - $('#label-modal-id').val($(this).data('id')); - $('.edit-label .new-label-input').val($(this).data('title')); - $('.edit-label .new-label-desc-input').val($(this).data('description')); - $('.edit-label .color-picker').val($(this).data('color')); - $('.minicolors-swatch-color').css("background-color", $(this).data('color')); - $('.edit-label.modal').modal({ - onApprove: function () { - $('.edit-label.form').submit(); - } - }).modal('show'); - return false; - }); - } - - // Milestones - if ($('.repository.new.milestone').length > 0) { - const $datepicker = $('.milestone.datepicker'); - $datepicker.datetimepicker({ - lang: $datepicker.data('lang'), - inline: true, - timepicker: false, - startDate: $datepicker.data('start-date'), - formatDate: 'Y-m-d', - onSelectDate: function (ct) { - $('#deadline').val(ct.dateFormat('Y-m-d')); - } - }); - $('#clear-date').click(function () { - $('#deadline').val(''); - return false; - }); - } - - // Issues - if ($('.repository.view.issue').length > 0) { - // Edit issue title - const $issueTitle = $('#issue-title'); - const $editInput = $('#edit-title-input input'); - const editTitleToggle = function () { - $issueTitle.toggle(); - $('.not-in-edit').toggle(); - $('#edit-title-input').toggle(); - $('.in-edit').toggle(); - $editInput.focus(); - return false; - }; - $('#edit-title').click(editTitleToggle); - $('#cancel-edit-title').click(editTitleToggle); - $('#save-edit-title').click(editTitleToggle).click(function () { - if ($editInput.val().length == 0 || - $editInput.val() == $issueTitle.text()) { - $editInput.val($issueTitle.text()); - return false; - } - - $.post($(this).data('update-url'), { - "_csrf": csrf, - "title": $editInput.val() - }, - function (data) { - $editInput.val(data.title); - $issueTitle.text(data.title); - reload(); - }); - return false; - }); - - // Edit issue or comment content - $('.edit-content').click(function () { - const $segment = $(this).parent().parent().parent().next(); - const $editContentZone = $segment.find('.edit-content-zone'); - const $renderContent = $segment.find('.render-content'); - const $rawContent = $segment.find('.raw-content'); - let $textarea; - - // Setup new form - if ($editContentZone.html().length == 0) { - $editContentZone.html($('#edit-content-form').html()); - $textarea = $editContentZone.find('textarea'); - issuesTribute.attach($textarea.get()); - emojiTribute.attach($textarea.get()); - - const $dropzone = $editContentZone.find('.dropzone'); - $dropzone.data("saved", false); - const $files = $editContentZone.find('.comment-files'); - if ($dropzone.length > 0) { - const filenameDict = {}; - $dropzone.dropzone({ - url: $dropzone.data('upload-url'), - headers: {"X-Csrf-Token": csrf}, - maxFiles: $dropzone.data('max-file'), - maxFilesize: $dropzone.data('max-size'), - acceptedFiles: ($dropzone.data('accepts') === '*/*') ? null : $dropzone.data('accepts'), - addRemoveLinks: true, - dictDefaultMessage: $dropzone.data('default-message'), - dictInvalidFileType: $dropzone.data('invalid-input-type'), - dictFileTooBig: $dropzone.data('file-too-big'), - dictRemoveFile: $dropzone.data('remove-file'), - init: function () { - this.on("success", function (file, data) { - filenameDict[file.name] = { - "uuid": data.uuid, - "submitted": false - } - const input = $('').val(data.uuid); - $files.append(input); - }); - this.on("removedfile", function (file) { - if (!(file.name in filenameDict)) { - return; - } - $('#' + filenameDict[file.name].uuid).remove(); - if ($dropzone.data('remove-url') && $dropzone.data('csrf') && !filenameDict[file.name].submitted) { - $.post($dropzone.data('remove-url'), { - file: filenameDict[file.name].uuid, - _csrf: $dropzone.data('csrf') - }); - } - }); - this.on("submit", function () { - $.each(filenameDict, function(name){ - filenameDict[name].submitted = true; - }); - }); - this.on("reload", function (){ - $.getJSON($editContentZone.data('attachment-url'), function(data){ - const drop = $dropzone.get(0).dropzone; - drop.removeAllFiles(true); - $files.empty(); - $.each(data, function(){ - const imgSrc = $dropzone.data('upload-url') + "/" + this.uuid; - drop.emit("addedfile", this); - drop.emit("thumbnail", this, imgSrc); - drop.emit("complete", this); - drop.files.push(this); - filenameDict[this.name] = { - "submitted": true, - "uuid": this.uuid - } - $dropzone.find("img[src='" + imgSrc + "']").css("max-width", "100%"); - const input = $('').val(this.uuid); - $files.append(input); - }); - }); - }); - } - }); - $dropzone.get(0).dropzone.emit("reload"); - } - // Give new write/preview data-tab name to distinguish from others - const $editContentForm = $editContentZone.find('.ui.comment.form'); - const $tabMenu = $editContentForm.find('.tabular.menu'); - $tabMenu.attr('data-write', $editContentZone.data('write')); - $tabMenu.attr('data-preview', $editContentZone.data('preview')); - $tabMenu.find('.write.item').attr('data-tab', $editContentZone.data('write')); - $tabMenu.find('.preview.item').attr('data-tab', $editContentZone.data('preview')); - $editContentForm.find('.write.segment').attr('data-tab', $editContentZone.data('write')); - $editContentForm.find('.preview.segment').attr('data-tab', $editContentZone.data('preview')); - - initCommentPreviewTab($editContentForm); - - $editContentZone.find('.cancel.button').click(function () { - $renderContent.show(); - $editContentZone.hide(); - $dropzone.get(0).dropzone.emit("reload"); - }); - $editContentZone.find('.save.button').click(function () { - $renderContent.show(); - $editContentZone.hide(); - const $attachments = $files.find("[name=files]").map(function(){ - return $(this).val(); - }).get(); - $.post($editContentZone.data('update-url'), { - "_csrf": csrf, - "content": $textarea.val(), - "context": $editContentZone.data('context'), - "files": $attachments - }, - function (data) { - if (data.length == 0) { - $renderContent.html($('#no-content').html()); - } else { - $renderContent.html(data.content); - emojify.run($renderContent[0]); - $('pre code', $renderContent[0]).each(function () { - hljs.highlightBlock(this); - }); - } - const $content = $segment.parent(); - if(!$content.find(".ui.small.images").length){ - if(data.attachments != ""){ - $content.append( - '
' + - '
' + - '
' + - '
' - ); - $content.find(".ui.small.images").html(data.attachments); - } - } else if (data.attachments == "") { - $content.find(".ui.small.images").parent().remove(); - } else { - $content.find(".ui.small.images").html(data.attachments); - } - $dropzone.get(0).dropzone.emit("submit"); - $dropzone.get(0).dropzone.emit("reload"); - }); - }); - } else { - $textarea = $segment.find('textarea'); - } - - // Show write/preview tab and copy raw content as needed - $editContentZone.show(); - $renderContent.hide(); - if ($textarea.val().length == 0) { - $textarea.val($rawContent.text()); - } - $textarea.focus(); - return false; - }); - - // Delete comment - $('.delete-comment').click(function () { - const $this = $(this); - if (confirm($this.data('locale'))) { - $.post($this.data('url'), { - "_csrf": csrf - }).success(function () { - $('#' + $this.data('comment-id')).remove(); - }); - } - return false; - }); - - // Change status - const $statusButton = $('#status-button'); - $('#comment-form .edit_area').keyup(function () { - if ($(this).val().length == 0) { - $statusButton.text($statusButton.data('status')) - } else { - $statusButton.text($statusButton.data('status-and-comment')) - } - }); - $statusButton.click(function () { - $('#status').val($statusButton.data('status-val')); - $('#comment-form').submit(); - }); - - // Pull Request merge button - const $mergeButton = $('.merge-button > button'); - $mergeButton.on('click', function(e) { - e.preventDefault(); - $('.' + $(this).data('do') + '-fields').show(); - $(this).parent().hide(); - }); - $('.merge-button > .dropdown').dropdown({ - onChange: function (_text, _value, $choice) { - if ($choice.data('do')) { - $mergeButton.find('.button-text').text($choice.text()); - $mergeButton.data('do', $choice.data('do')); - } - } - }); - $('.merge-cancel').on('click', function(e) { - e.preventDefault(); - $(this).closest('.form').hide(); - $mergeButton.parent().show(); - }); - - initReactionSelector(); - } - - // Diff - if ($('.repository.diff').length > 0) { - $('.diff-counter').each(function () { - const $item = $(this); - const addLine = $item.find('span[data-line].add').data("line"); - const delLine = $item.find('span[data-line].del').data("line"); - const addPercent = parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine)) * 100; - $item.find(".bar .add").css("width", addPercent + "%"); - }); - } - - // Quick start and repository home - $('#repo-clone-ssh').click(function () { - $('.clone-url').text($(this).data('link')); - $('#repo-clone-url').val($(this).data('link')); - $(this).addClass('blue'); - $('#repo-clone-https').removeClass('blue'); - localStorage.setItem('repo-clone-protocol', 'ssh'); - }); - $('#repo-clone-https').click(function () { - $('.clone-url').text($(this).data('link')); - $('#repo-clone-url').val($(this).data('link')); - $(this).addClass('blue'); - $('#repo-clone-ssh').removeClass('blue'); - localStorage.setItem('repo-clone-protocol', 'https'); - }); - $('#repo-clone-url').click(function () { - $(this).select(); - }); - - // Pull request - const $repoComparePull = $('.repository.compare.pull'); - if ($repoComparePull.length > 0) { - initFilterSearchDropdown('.choose.branch .dropdown'); - // show pull request form - $repoComparePull.find('button.show-form').on('click', function(e) { - e.preventDefault(); - $repoComparePull.find('.pullrequest-form').show(); - $(this).parent().hide(); - }); - } - - // Branches - if ($('.repository.settings.branches').length > 0) { - initFilterSearchDropdown('.protected-branches .dropdown'); - $('.enable-protection, .enable-whitelist').change(function () { - if (this.checked) { - $($(this).data('target')).removeClass('disabled'); - } else { - $($(this).data('target')).addClass('disabled'); - } - }); - } -} - -function initMigration() { - const toggleMigrations = function() { - const authUserName = $('#auth_username').val(); - const cloneAddr = $('#clone_addr').val(); - if (!$('#mirror').is(":checked") && (authUserName!=undefined && authUserName.length > 0) - && (cloneAddr!=undefined && (cloneAddr.startsWith("https://github.com") || cloneAddr.startsWith("http://github.com")))) { - $('#migrate_items').show(); - } else { - $('#migrate_items').hide(); - } - } - - toggleMigrations(); - - $('#clone_addr').on('input', toggleMigrations) - $('#auth_username').on('input', toggleMigrations) - $('#mirror').on('change', toggleMigrations) -} - -function initPullRequestReview() { - $('.show-outdated').on('click', function (e) { - e.preventDefault(); - const id = $(this).data('comment'); - $(this).addClass("hide"); - $("#code-comments-" + id).removeClass('hide'); - $("#code-preview-" + id).removeClass('hide'); - $("#hide-outdated-" + id).removeClass('hide'); - }); - - $('.hide-outdated').on('click', function (e) { - e.preventDefault(); - const id = $(this).data('comment'); - $(this).addClass("hide"); - $("#code-comments-" + id).addClass('hide'); - $("#code-preview-" + id).addClass('hide'); - $("#show-outdated-" + id).removeClass('hide'); - }); - - $('button.comment-form-reply').on('click', function (e) { - e.preventDefault(); - $(this).hide(); - const form = $(this).parent().find('.comment-form') - form.removeClass('hide'); - assingMenuAttributes(form.find('.menu')); - }); - // The following part is only for diff views - if ($('.repository.pull.diff').length == 0) { - return; - } - - $('.diff-detail-box.ui.sticky').sticky(); - - $('.btn-review').on('click', function(e) { - e.preventDefault(); - $(this).closest('.dropdown').find('.menu').toggle('visible'); - }).closest('.dropdown').find('.link.close').on('click', function(e) { - e.preventDefault(); - $(this).closest('.menu').toggle('visible'); - }); - - $('.code-view .lines-code,.code-view .lines-num') - .on('mouseenter', function() { - const parent = $(this).closest('td'); - $(this).closest('tr').addClass( - parent.hasClass('lines-num-old') || parent.hasClass('lines-code-old') - ? 'focus-lines-old' : 'focus-lines-new' - ); - }) - .on('mouseleave', function() { - $(this).closest('tr').removeClass('focus-lines-new focus-lines-old'); - }); - $('.add-code-comment').on('click', function(e) { - // https://github.com/go-gitea/gitea/issues/4745 - if ($(e.target).hasClass('btn-add-single')) { - return; - } - e.preventDefault(); - const isSplit = $(this).closest('.code-diff').hasClass('code-diff-split'); - const side = $(this).data('side'); - const idx = $(this).data('idx'); - const path = $(this).data('path'); - const form = $('#pull_review_add_comment').html(); - const tr = $(this).closest('tr'); - let ntr = tr.next(); - if (!ntr.hasClass('add-comment')) { - ntr = $('' - + (isSplit ? '' - : '') - + ''); - tr.after(ntr); - } - const td = ntr.find('.add-comment-' + side); - let commentCloud = td.find('.comment-code-cloud'); - if (commentCloud.length === 0) { - td.html(form); - commentCloud = td.find('.comment-code-cloud'); - assingMenuAttributes(commentCloud.find('.menu')); - - td.find("input[name='line']").val(idx); - td.find("input[name='side']").val(side === "left" ? "previous":"proposed"); - td.find("input[name='path']").val(path); - } - commentCloud.find('textarea').focus(); - }); -} - -function assingMenuAttributes(menu) { - const id = Math.floor(Math.random() * Math.floor(1000000)); - menu.attr('data-write', menu.attr('data-write') + id); - menu.attr('data-preview', menu.attr('data-preview') + id); - menu.find('.item').each(function() { - const tab = $(this).attr('data-tab') + id; - $(this).attr('data-tab', tab); - }); - menu.parent().find("*[data-tab='write']").attr('data-tab', 'write' + id); - menu.parent().find("*[data-tab='preview']").attr('data-tab', 'preview' + id); - initCommentPreviewTab(menu.parent(".form")); - return id; -} - -function initRepositoryCollaboration() { - // Change collaborator access mode - $('.access-mode.menu .item').click(function () { - const $menu = $(this).parent(); - $.post($menu.data('url'), { - "_csrf": csrf, - "uid": $menu.data('uid'), - "mode": $(this).data('value') - }) - }); -} - -function initTeamSettings() { - // Change team access mode - $('.organization.new.team input[name=permission]').change(function () { - const val = $('input[name=permission]:checked', '.organization.new.team').val() - if (val === 'admin') { - $('.organization.new.team .team-units').hide(); - } else { - $('.organization.new.team .team-units').show(); - } - }); -} - -function initWikiForm() { - const $editArea = $('.repository.wiki textarea#edit_area'); - if ($editArea.length > 0) { - const simplemde = new SimpleMDE({ - autoDownloadFontAwesome: false, - element: $editArea[0], - forceSync: true, - previewRender: function (plainText, preview) { // Async method - setTimeout(function () { - // FIXME: still send render request when return back to edit mode - $.post($editArea.data('url'), { - "_csrf": csrf, - "mode": "gfm", - "context": $editArea.data('context'), - "text": plainText - }, - function (data) { - preview.innerHTML = '
' + data + '
'; - emojify.run($('.editor-preview')[0]); - } - ); - }, 0); - - return "Loading..."; - }, - renderingConfig: { - singleLineBreaks: false - }, - indentWithTabs: false, - tabSize: 4, - spellChecker: false, - toolbar: ["bold", "italic", "strikethrough", "|", - "heading-1", "heading-2", "heading-3", "heading-bigger", "heading-smaller", "|", - { - name: "code-inline", - action: function(e){ - const cm = e.codemirror; - const selection = cm.getSelection(); - cm.replaceSelection("`" + selection + "`"); - if (!selection) { - const cursorPos = cm.getCursor(); - cm.setCursor(cursorPos.line, cursorPos.ch - 1); - } - cm.focus(); - }, - className: "fa fa-angle-right", - title: "Add Inline Code", - },"code", "quote", "|", { - name: "checkbox-empty", - action: function(e){ - const cm = e.codemirror; - cm.replaceSelection("\n- [ ] " + cm.getSelection()); - cm.focus(); - }, - className: "fa fa-square-o", - title: "Add Checkbox (empty)", - }, - { - name: "checkbox-checked", - action: function(e){ - const cm = e.codemirror; - cm.replaceSelection("\n- [x] " + cm.getSelection()); - cm.focus(); - }, - className: "fa fa-check-square-o", - title: "Add Checkbox (checked)", - }, "|", - "unordered-list", "ordered-list", "|", - "link", "image", "table", "horizontal-rule", "|", - "clean-block", "preview", "fullscreen"] - }) - $(simplemde.codemirror.getInputField()).addClass("js-quick-submit"); - } -} - -// For IE -String.prototype.endsWith = function (pattern) { - const d = this.length - pattern.length; - return d >= 0 && this.lastIndexOf(pattern) === d; -}; - -// Adding function to get the cursor position in a text field to jQuery object. -$.fn.getCursorPosition = function () { - const el = $(this).get(0); - let pos = 0; - if ('selectionStart' in el) { - pos = el.selectionStart; - } else if ('selection' in document) { - el.focus(); - const Sel = document.selection.createRange(); - const SelLength = document.selection.createRange().text.length; - Sel.moveStart('character', -el.value.length); - pos = Sel.text.length - SelLength; - } - return pos; -} - -function setSimpleMDE($editArea) { - if (codeMirrorEditor) { - codeMirrorEditor.toTextArea(); - codeMirrorEditor = null; - } - - if (simpleMDEditor) { - return true; - } - - simpleMDEditor = new SimpleMDE({ - autoDownloadFontAwesome: false, - element: $editArea[0], - forceSync: true, - renderingConfig: { - singleLineBreaks: false - }, - indentWithTabs: false, - tabSize: 4, - spellChecker: false, - previewRender: function (plainText, preview) { // Async method - setTimeout(function () { - // FIXME: still send render request when return back to edit mode - $.post($editArea.data('url'), { - "_csrf": csrf, - "mode": "gfm", - "context": $editArea.data('context'), - "text": plainText - }, - function (data) { - preview.innerHTML = '
' + data + '
'; - emojify.run($('.editor-preview')[0]); - } - ); - }, 0); - - return "Loading..."; - }, - toolbar: ["bold", "italic", "strikethrough", "|", - "heading-1", "heading-2", "heading-3", "heading-bigger", "heading-smaller", "|", - "code", "quote", "|", - "unordered-list", "ordered-list", "|", - "link", "image", "table", "horizontal-rule", "|", - "clean-block", "preview", "fullscreen", "side-by-side"] - }); - - return true; -} - -function setCodeMirror($editArea) { - if (simpleMDEditor) { - simpleMDEditor.toTextArea(); - simpleMDEditor = null; - } - - if (codeMirrorEditor) { - return true; - } - - codeMirrorEditor = CodeMirror.fromTextArea($editArea[0], { - lineNumbers: true - }); - codeMirrorEditor.on("change", function (cm, _change) { - $editArea.val(cm.getValue()); - }); - - return true; -} - -function initEditor() { - $('.js-quick-pull-choice-option').change(function () { - if ($(this).val() == 'commit-to-new-branch') { - $('.quick-pull-branch-name').show(); - $('.quick-pull-branch-name input').prop('required',true); - } else { - $('.quick-pull-branch-name').hide(); - $('.quick-pull-branch-name input').prop('required',false); - } - $('#commit-button').text($(this).attr('button_text')); - }); - - const $editFilename = $("#file-name"); - $editFilename.keyup(function (e) { - const $section = $('.breadcrumb span.section'); - const $divider = $('.breadcrumb div.divider'); - let value; - let parts; - - if (e.keyCode == 8) { - if ($(this).getCursorPosition() == 0) { - if ($section.length > 0) { - value = $section.last().find('a').text(); - $(this).val(value + $(this).val()); - $(this)[0].setSelectionRange(value.length, value.length); - $section.last().remove(); - $divider.last().remove(); - } - } - } - if (e.keyCode == 191) { - parts = $(this).val().split('/'); - for (let i = 0; i < parts.length; ++i) { - value = parts[i]; - if (i < parts.length - 1) { - if (value.length) { - $('' + value + '').insertBefore($(this)); - $('
/
').insertBefore($(this)); - } - } - else { - $(this).val(value); - } - $(this)[0].setSelectionRange(0, 0); - } - } - parts = []; - $('.breadcrumb span.section').each(function () { - const element = $(this); - if (element.find('a').length) { - parts.push(element.find('a').text()); - } else { - parts.push(element.text()); - } - }); - if ($(this).val()) - parts.push($(this).val()); - $('#tree_path').val(parts.join('/')); - }).trigger('keyup'); - - const $editArea = $('.repository.editor textarea#edit_area'); - if (!$editArea.length) - return; - - const markdownFileExts = $editArea.data("markdown-file-exts").split(","); - const lineWrapExtensions = $editArea.data("line-wrap-extensions").split(","); - - $editFilename.on("keyup", function () { - const val = $editFilename.val(); - let mode, spec, extension, extWithDot, dataUrl, apiCall; - - extension = extWithDot = ""; - const m = /.+\.([^.]+)$/.exec(val); - if (m) { - extension = m[1]; - extWithDot = "." + extension; - } - - const info = CodeMirror.findModeByExtension(extension); - const previewLink = $('a[data-tab=preview]'); - if (info) { - mode = info.mode; - spec = info.mime; - apiCall = mode; - } - else { - apiCall = extension - } - - if (previewLink.length && apiCall && previewFileModes && previewFileModes.length && previewFileModes.indexOf(apiCall) >= 0) { - dataUrl = previewLink.data('url'); - previewLink.data('url', dataUrl.replace(/(.*)\/.*/i, '$1/' + mode)); - previewLink.show(); - } - else { - previewLink.hide(); - } - - // If this file is a Markdown extensions, we will load that editor and return - if (markdownFileExts.indexOf(extWithDot) >= 0) { - if (setSimpleMDE($editArea)) { - return; - } - } - - // Else we are going to use CodeMirror - if (!codeMirrorEditor && !setCodeMirror($editArea)) { - return; - } - - if (mode) { - codeMirrorEditor.setOption("mode", spec); - CodeMirror.autoLoadMode(codeMirrorEditor, mode); - } - - if (lineWrapExtensions.indexOf(extWithDot) >= 0) { - codeMirrorEditor.setOption("lineWrapping", true); - } - else { - codeMirrorEditor.setOption("lineWrapping", false); - } - - // get the filename without any folder - let value = $editFilename.val(); - if (value.length === 0) { - return; - } - value = value.split('/'); - value = value[value.length - 1]; - - $.getJSON($editFilename.data('ec-url-prefix')+value, function(editorconfig) { - if (editorconfig.indent_style === 'tab') { - codeMirrorEditor.setOption("indentWithTabs", true); - codeMirrorEditor.setOption('extraKeys', {}); - } else { - codeMirrorEditor.setOption("indentWithTabs", false); - // required because CodeMirror doesn't seems to use spaces correctly for {"indentWithTabs": false}: - // - https://github.com/codemirror/CodeMirror/issues/988 - // - https://codemirror.net/doc/manual.html#keymaps - codeMirrorEditor.setOption('extraKeys', { - Tab: function(cm) { - const spaces = Array(parseInt(cm.getOption("indentUnit")) + 1).join(" "); - cm.replaceSelection(spaces); - } - }); - } - codeMirrorEditor.setOption("indentUnit", editorconfig.indent_size || 4); - codeMirrorEditor.setOption("tabSize", editorconfig.tab_width || 4); - }); - }).trigger('keyup'); - - // Using events from https://github.com/codedance/jquery.AreYouSure#advanced-usage - // to enable or disable the commit button - const $commitButton = $('#commit-button'); - const $editForm = $('.ui.edit.form'); - const dirtyFileClass = 'dirty-file'; - - // Disabling the button at the start - $commitButton.prop('disabled', true); - - // Registering a custom listener for the file path and the file content - $editForm.areYouSure({ - silent: true, - dirtyClass: dirtyFileClass, - fieldSelector: ':input:not(.commit-form-wrapper :input)', - change: function () { - const dirty = $(this).hasClass(dirtyFileClass); - $commitButton.prop('disabled', !dirty); - } - }); - - $commitButton.click(function (event) { - // A modal which asks if an empty file should be committed - if ($editArea.val().length === 0) { - $('#edit-empty-content-modal').modal({ - onApprove: function () { - $('.edit.form').submit(); - } - }).modal('show'); - event.preventDefault(); - } - }); -} - -function initOrganization() { - if ($('.organization').length == 0) { - return; - } - - // Options - if ($('.organization.settings.options').length > 0) { - $('#org_name').keyup(function () { - const $prompt = $('#org-name-change-prompt'); - if ($(this).val().toString().toLowerCase() != $(this).data('org-name').toString().toLowerCase()) { - $prompt.show(); - } else { - $prompt.hide(); - } - }); - } -} - -function initUserSettings() { - // Options - if ($('.user.settings.profile').length > 0) { - $('#username').keyup(function () { - const $prompt = $('#name-change-prompt'); - if ($(this).val().toString().toLowerCase() != $(this).data('name').toString().toLowerCase()) { - $prompt.show(); - } else { - $prompt.hide(); - } - }); - } -} - -function initWebhook() { - if ($('.new.webhook').length == 0) { - return; - } - - $('.events.checkbox input').change(function () { - if ($(this).is(':checked')) { - $('.events.fields').show(); - } - }); - $('.non-events.checkbox input').change(function () { - if ($(this).is(':checked')) { - $('.events.fields').hide(); - } - }); - - const updateContentType = function () { - const visible = $('#http_method').val() === 'POST'; - $('#content_type').parent().parent()[visible ? 'show' : 'hide'](); - }; - updateContentType(); - $('#http_method').change(function () { - updateContentType(); - }); - - // Test delivery - $('#test-delivery').click(function () { - const $this = $(this); - $this.addClass('loading disabled'); - $.post($this.data('link'), { - "_csrf": csrf - }).done( - setTimeout(function () { - window.location.href = $this.data('redirect'); - }, 5000) - ) - }); -} - -function initAdmin() { - if ($('.admin').length == 0) { - return; - } - - // New user - if ($('.admin.new.user').length > 0 || - $('.admin.edit.user').length > 0) { - $('#login_type').change(function () { - if ($(this).val().substring(0, 1) == '0') { - $('#login_name').removeAttr('required'); - $('.non-local').hide(); - $('.local').show(); - $('#user_name').focus(); - - if ($(this).data('password') == "required") { - $('#password').attr('required', 'required'); - } - - } else { - $('#login_name').attr('required', 'required'); - $('.non-local').show(); - $('.local').hide(); - $('#login_name').focus(); - - $('#password').removeAttr('required'); - } - }); - } - - function onSecurityProtocolChange() { - if ($('#security_protocol').val() > 0) { - $('.has-tls').show(); - } else { - $('.has-tls').hide(); - } - } - - function onUsePagedSearchChange() { - if ($('#use_paged_search').prop('checked')) { - $('.search-page-size').show() - .find('input').attr('required', 'required'); - } else { - $('.search-page-size').hide() - .find('input').removeAttr('required'); - } - } - - function onOAuth2Change() { - $('.open_id_connect_auto_discovery_url, .oauth2_use_custom_url').hide(); - $('.open_id_connect_auto_discovery_url input[required]').removeAttr('required'); - - const provider = $('#oauth2_provider').val(); - switch (provider) { - case 'github': - case 'gitlab': - case 'gitea': - $('.oauth2_use_custom_url').show(); - break; - case 'openidConnect': - $('.open_id_connect_auto_discovery_url input').attr('required', 'required'); - $('.open_id_connect_auto_discovery_url').show(); - break; - } - onOAuth2UseCustomURLChange(); - } - - function onOAuth2UseCustomURLChange() { - const provider = $('#oauth2_provider').val(); - $('.oauth2_use_custom_url_field').hide(); - $('.oauth2_use_custom_url_field input[required]').removeAttr('required'); - - if ($('#oauth2_use_custom_url').is(':checked')) { - if (!$('#oauth2_token_url').val()) { - $('#oauth2_token_url').val($('#' + provider + '_token_url').val()); - } - if (!$('#oauth2_auth_url').val()) { - $('#oauth2_auth_url').val($('#' + provider + '_auth_url').val()); - } - if (!$('#oauth2_profile_url').val()) { - $('#oauth2_profile_url').val($('#' + provider + '_profile_url').val()); - } - if (!$('#oauth2_email_url').val()) { - $('#oauth2_email_url').val($('#' + provider + '_email_url').val()); - } - switch (provider) { - case 'github': - $('.oauth2_token_url input, .oauth2_auth_url input, .oauth2_profile_url input, .oauth2_email_url input').attr('required', 'required'); - $('.oauth2_token_url, .oauth2_auth_url, .oauth2_profile_url, .oauth2_email_url').show(); - break; - case 'gitea': - case 'gitlab': - $('.oauth2_token_url input, .oauth2_auth_url input, .oauth2_profile_url input').attr('required', 'required'); - $('.oauth2_token_url, .oauth2_auth_url, .oauth2_profile_url').show(); - $('#oauth2_email_url').val(''); - break; - } - } - } - - // New authentication - if ($('.admin.new.authentication').length > 0) { - $('#auth_type').change(function () { - $('.ldap, .dldap, .smtp, .pam, .oauth2, .has-tls .search-page-size').hide(); - - $('.ldap input[required], .binddnrequired input[required], .dldap input[required], .smtp input[required], .pam input[required], .oauth2 input[required], .has-tls input[required]').removeAttr('required'); - $('.binddnrequired').removeClass("required"); - - const authType = $(this).val(); - switch (authType) { - case '2': // LDAP - $('.ldap').show(); - $('.binddnrequired input, .ldap div.required:not(.dldap) input').attr('required', 'required'); - $('.binddnrequired').addClass("required"); - break; - case '3': // SMTP - $('.smtp').show(); - $('.has-tls').show(); - $('.smtp div.required input, .has-tls').attr('required', 'required'); - break; - case '4': // PAM - $('.pam').show(); - $('.pam input').attr('required', 'required'); - break; - case '5': // LDAP - $('.dldap').show(); - $('.dldap div.required:not(.ldap) input').attr('required', 'required'); - break; - case '6': // OAuth2 - $('.oauth2').show(); - $('.oauth2 div.required:not(.oauth2_use_custom_url,.oauth2_use_custom_url_field,.open_id_connect_auto_discovery_url) input').attr('required', 'required'); - onOAuth2Change(); - break; - } - if (authType == '2' || authType == '5') { - onSecurityProtocolChange() - } - if (authType == '2') { - onUsePagedSearchChange(); - } - }); - $('#auth_type').change(); - $('#security_protocol').change(onSecurityProtocolChange); - $('#use_paged_search').change(onUsePagedSearchChange); - $('#oauth2_provider').change(onOAuth2Change); - $('#oauth2_use_custom_url').change(onOAuth2UseCustomURLChange); - } - // Edit authentication - if ($('.admin.edit.authentication').length > 0) { - const authType = $('#auth_type').val(); - if (authType == '2' || authType == '5') { - $('#security_protocol').change(onSecurityProtocolChange); - if (authType == '2') { - $('#use_paged_search').change(onUsePagedSearchChange); - } - } else if (authType == '6') { - $('#oauth2_provider').change(onOAuth2Change); - $('#oauth2_use_custom_url').change(onOAuth2UseCustomURLChange); - onOAuth2Change(); - } - } - - // Notice - if ($('.admin.notice')) { - const $detailModal = $('#detail-modal'); - - // Attach view detail modals - $('.view-detail').click(function () { - $detailModal.find('.content p').text($(this).data('content')); - $detailModal.modal('show'); - return false; - }); - - // Select actions - const $checkboxes = $('.select.table .ui.checkbox'); - $('.select.action').click(function () { - switch ($(this).data('action')) { - case 'select-all': - $checkboxes.checkbox('check'); - break; - case 'deselect-all': - $checkboxes.checkbox('uncheck'); - break; - case 'inverse': - $checkboxes.checkbox('toggle'); - break; - } - }); - $('#delete-selection').click(function () { - const $this = $(this); - $this.addClass("loading disabled"); - const ids = []; - $checkboxes.each(function () { - if ($(this).checkbox('is checked')) { - ids.push($(this).data('id')); - } - }); - $.post($this.data('link'), { - "_csrf": csrf, - "ids": ids - }).done(function () { - window.location.href = $this.data('redirect'); - }); - }); - } -} - -function buttonsClickOnEnter() { - $('.ui.button').keypress(function (e) { - if (e.keyCode == 13 || e.keyCode == 32) // enter key or space bar - $(this).click(); - }); -} - -function searchUsers() { - const $searchUserBox = $('#search-user-box'); - $searchUserBox.search({ - minCharacters: 2, - apiSettings: { - url: suburl + '/api/v1/users/search?q={query}', - onResponse: function(response) { - const items = []; - $.each(response.data, function (_i, item) { - let title = item.login; - if (item.full_name && item.full_name.length > 0) { - title += ' (' + htmlEncode(item.full_name) + ')'; - } - items.push({ - title: title, - image: item.avatar_url - }) - }); - - return { results: items } - } - }, - searchFields: ['login', 'full_name'], - showNoResults: false - }); -} - -function searchTeams() { - const $searchTeamBox = $('#search-team-box'); - $searchTeamBox.search({ - minCharacters: 2, - apiSettings: { - url: suburl + '/api/v1/orgs/' + $searchTeamBox.data('org') + '/teams/search?q={query}', - headers: {"X-Csrf-Token": csrf}, - onResponse: function(response) { - const items = []; - $.each(response.data, function (_i, item) { - const title = item.name + ' (' + item.permission + ' access)'; - items.push({ - title: title, - }) - }); - - return { results: items } - } - }, - searchFields: ['name', 'description'], - showNoResults: false - }); -} - -function searchRepositories() { - const $searchRepoBox = $('#search-repo-box'); - $searchRepoBox.search({ - minCharacters: 2, - apiSettings: { - url: suburl + '/api/v1/repos/search?q={query}&uid=' + $searchRepoBox.data('uid'), - onResponse: function(response) { - const items = []; - $.each(response.data, function (_i, item) { - items.push({ - title: item.full_name.split("/")[1], - description: item.full_name - }) - }); - - return { results: items } - } - }, - searchFields: ['full_name'], - showNoResults: false - }); -} - -function initCodeView() { - if ($('.code-view .linenums').length > 0) { - $(document).on('click', '.lines-num span', function (e) { - const $select = $(this); - const $list = $select.parent().siblings('.lines-code').find('ol.linenums > li'); - selectRange($list, $list.filter('[rel=' + $select.attr('id') + ']'), (e.shiftKey ? $list.filter('.active').eq(0) : null)); - deSelect(); - }); - - $(window).on('hashchange', function () { - let m = window.location.hash.match(/^#(L\d+)-(L\d+)$/); - const $list = $('.code-view ol.linenums > li'); - let $first; - if (m) { - $first = $list.filter('.' + m[1]); - selectRange($list, $first, $list.filter('.' + m[2])); - $("html, body").scrollTop($first.offset().top - 200); - return; - } - m = window.location.hash.match(/^#(L|n)(\d+)$/); - if (m) { - $first = $list.filter('.L' + m[2]); - selectRange($list, $first); - $("html, body").scrollTop($first.offset().top - 200); - } - }).trigger('hashchange'); - } -} - -function initU2FAuth() { - if($('#wait-for-key').length === 0) { - return - } - u2fApi.ensureSupport() - .then(function () { - $.getJSON(suburl + '/user/u2f/challenge').success(function(req) { - u2fApi.sign(req.appId, req.challenge, req.registeredKeys, 30) - .then(u2fSigned) - .catch(function (err) { - if(err === undefined) { - u2fError(1); - return - } - u2fError(err.metaData.code); - }); - }); - }).catch(function () { - // Fallback in case browser do not support U2F - window.location.href = suburl + "/user/two_factor" - }) -} -function u2fSigned(resp) { - $.ajax({ - url: suburl + '/user/u2f/sign', - type: "POST", - headers: {"X-Csrf-Token": csrf}, - data: JSON.stringify(resp), - contentType: "application/json; charset=utf-8", - }).done(function(res){ - window.location.replace(res); - }).fail(function () { - u2fError(1); - }); -} - -function u2fRegistered(resp) { - if (checkError(resp)) { - return; - } - $.ajax({ - url: suburl + '/user/settings/security/u2f/register', - type: "POST", - headers: {"X-Csrf-Token": csrf}, - data: JSON.stringify(resp), - contentType: "application/json; charset=utf-8", - success: function(){ - reload(); - }, - fail: function () { - u2fError(1); - } - }); -} - -function checkError(resp) { - if (!('errorCode' in resp)) { - return false; - } - if (resp.errorCode === 0) { - return false; - } - u2fError(resp.errorCode); - return true; -} - - -function u2fError(errorType) { - const u2fErrors = { - 'browser': $('#unsupported-browser'), - 1: $('#u2f-error-1'), - 2: $('#u2f-error-2'), - 3: $('#u2f-error-3'), - 4: $('#u2f-error-4'), - 5: $('.u2f-error-5') - }; - u2fErrors[errorType].removeClass('hide'); - for(const type in u2fErrors){ - if(type != errorType){ - u2fErrors[type].addClass('hide'); - } - } - $('#u2f-error').modal('show'); -} - -function initU2FRegister() { - $('#register-device').modal({allowMultiple: false}); - $('#u2f-error').modal({allowMultiple: false}); - $('#register-security-key').on('click', function(e) { - e.preventDefault(); - u2fApi.ensureSupport() - .then(u2fRegisterRequest) - .catch(function() { - u2fError('browser'); - }) - }) -} - -function u2fRegisterRequest() { - $.post(suburl + "/user/settings/security/u2f/request_register", { - "_csrf": csrf, - "name": $('#nickname').val() - }).success(function(req) { - $("#nickname").closest("div.field").removeClass("error"); - $('#register-device').modal('show'); - if(req.registeredKeys === null) { - req.registeredKeys = [] - } - u2fApi.register(req.appId, req.registerRequests, req.registeredKeys, 30) - .then(u2fRegistered) - .catch(function (reason) { - if(reason === undefined) { - u2fError(1); - return - } - u2fError(reason.metaData.code); - }); - }).fail(function(xhr) { - if(xhr.status === 409) { - $("#nickname").closest("div.field").addClass("error"); - } - }); -} - -function initWipTitle() { - $(".title_wip_desc > a").click(function (e) { - e.preventDefault(); - - const $issueTitle = $("#issue_title"); - $issueTitle.focus(); - const value = $issueTitle.val().trim().toUpperCase(); - - for (const i in wipPrefixes) { - if (value.startsWith(wipPrefixes[i].toUpperCase())) { - return; - } - } - - $issueTitle.val(wipPrefixes[0] + " " + $issueTitle.val()); - }); -} - -function initTemplateSearch() { - const $repoTemplate = $("#repo_template"); - const checkTemplate = function() { - const $templateUnits = $("#template_units"); - const $nonTemplate = $("#non_template"); - if ($repoTemplate.val() !== "") { - $templateUnits.show(); - $nonTemplate.hide(); - } else { - $templateUnits.hide(); - $nonTemplate.show(); - } - }; - $repoTemplate.change(checkTemplate); - checkTemplate(); - - const changeOwner = function() { - $("#repo_template_search") - .dropdown({ - apiSettings: { - url: suburl + '/api/v1/repos/search?q={query}&template=true&priority_owner_id=' + $("#uid").val(), - onResponse: function(response) { - const filteredResponse = {'success': true, 'results': []}; - filteredResponse.results.push({ - 'name': '', - 'value': '' - }); - // Parse the response from the api to work with our dropdown - $.each(response.data, function(_r, repo) { - filteredResponse.results.push({ - 'name' : htmlEncode(repo.full_name) , - 'value' : repo.id - }); - }); - return filteredResponse; - }, - cache: false, - }, - - fullTextSearch: true - }); - }; - $("#uid").change(changeOwner); - changeOwner(); -} - -$(document).ready(function () { - csrf = $('meta[name=_csrf]').attr("content"); - suburl = $('meta[name=_suburl]').attr("content"); - - // Show exact time - $('.time-since').each(function () { - $(this).addClass('poping up').attr('data-content', $(this).attr('title')).attr('data-variation', 'inverted tiny').attr('title', ''); - }); - - // Semantic UI modules. - $('.dropdown:not(.custom)').dropdown(); - $('.jump.dropdown').dropdown({ - action: 'hide', - onShow: function () { - $('.poping.up').popup('hide'); - } - }); - $('.slide.up.dropdown').dropdown({ - transition: 'slide up' - }); - $('.upward.dropdown').dropdown({ - direction: 'upward' - }); - $('.ui.accordion').accordion(); - $('.ui.checkbox').checkbox(); - $('.ui.progress').progress({ - showActivity: false - }); - $('.poping.up').popup(); - $('.top.menu .poping.up').popup({ - onShow: function () { - if ($('.top.menu .menu.transition').hasClass('visible')) { - return false; - } - } - }); - $('.tabular.menu .item').tab(); - $('.tabable.menu .item').tab(); - - $('.toggle.button').click(function () { - $($(this).data('target')).slideToggle(100); - }); - - // make table element clickable like a link - $('tr[data-href]').click(function() { - window.location = $(this).data('href'); - }); - - // Highlight JS - if (typeof hljs != 'undefined') { - const nodes = [].slice.call(document.querySelectorAll('pre code') || []); - for (let i = 0; i < nodes.length; i++) { - hljs.highlightBlock(nodes[i]); - } - } - - // Dropzone - const $dropzone = $('#dropzone'); - if ($dropzone.length > 0) { - const filenameDict = {}; - - new Dropzone("#dropzone", { - url: $dropzone.data('upload-url'), - headers: {"X-Csrf-Token": csrf}, - maxFiles: $dropzone.data('max-file'), - maxFilesize: $dropzone.data('max-size'), - acceptedFiles: ($dropzone.data('accepts') === '*/*') ? null : $dropzone.data('accepts'), - addRemoveLinks: true, - dictDefaultMessage: $dropzone.data('default-message'), - dictInvalidFileType: $dropzone.data('invalid-input-type'), - dictFileTooBig: $dropzone.data('file-too-big'), - dictRemoveFile: $dropzone.data('remove-file'), - init: function () { - this.on("success", function (file, data) { - filenameDict[file.name] = data.uuid; - const input = $('').val(data.uuid); - $('.files').append(input); - }); - this.on("removedfile", function (file) { - if (file.name in filenameDict) { - $('#' + filenameDict[file.name]).remove(); - } - if ($dropzone.data('remove-url') && $dropzone.data('csrf')) { - $.post($dropzone.data('remove-url'), { - file: filenameDict[file.name], - _csrf: $dropzone.data('csrf') - }); - } - }) - }, - }); - } - - // Emojify - emojify.setConfig({ - img_dir: suburl + '/vendor/plugins/emojify/images', - ignore_emoticons: true - }); - const hasEmoji = document.getElementsByClassName('has-emoji'); - for (let i = 0; i < hasEmoji.length; i++) { - emojify.run(hasEmoji[i]); - for (let j = 0; j < hasEmoji[i].childNodes.length; j++) { - if (hasEmoji[i].childNodes[j].nodeName === "A") { - emojify.run(hasEmoji[i].childNodes[j]) - } - } - } - - // Clipboard JS - const clipboard = new Clipboard('.clipboard'); - clipboard.on('success', function (e) { - e.clearSelection(); - - $('#' + e.trigger.getAttribute('id')).popup('destroy'); - e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-success')) - $('#' + e.trigger.getAttribute('id')).popup('show'); - e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original')) - }); - - clipboard.on('error', function (e) { - $('#' + e.trigger.getAttribute('id')).popup('destroy'); - e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-error')) - $('#' + e.trigger.getAttribute('id')).popup('show'); - e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original')) - }); - - // Helpers. - $('.delete-button').click(showDeletePopup); - $('.add-all-button').click(showAddAllPopup); - - $('.delete-branch-button').click(showDeletePopup); - - $('.undo-button').click(function() { - const $this = $(this); - $.post($this.data('url'), { - "_csrf": csrf, - "id": $this.data("id") - }).done(function(data) { - window.location.href = data.redirect; - }); - }); - $('.show-panel.button').click(function () { - $($(this).data('panel')).show(); - }); - $('.show-modal.button').click(function () { - $($(this).data('modal')).modal('show'); - }); - $('.delete-post.button').click(function () { - const $this = $(this); - $.post($this.data('request-url'), { - "_csrf": csrf - }).done(function () { - window.location.href = $this.data('done-url'); - }); - }); - - // Set anchor. - $('.markdown').each(function () { - const headers = {}; - $(this).find('h1, h2, h3, h4, h5, h6').each(function () { - let node = $(this); - const val = encodeURIComponent(node.text().toLowerCase().replace(/[^\u00C0-\u1FFF\u2C00-\uD7FF\w\- ]/g, '').replace(/[ ]/g, '-')); - let name = val; - if (headers[val] > 0) { - name = val + '-' + headers[val]; - } - if (headers[val] == undefined) { - headers[val] = 1; - } else { - headers[val] += 1; - } - node = node.wrap('
'); - node.append(''); - }); - }); - - $('.issue-checkbox').click(function() { - const numChecked = $('.issue-checkbox').children('input:checked').length; - if (numChecked > 0) { - $('#issue-filters').addClass("hide"); - $('#issue-actions').removeClass("hide"); - } else { - $('#issue-filters').removeClass("hide"); - $('#issue-actions').addClass("hide"); - } - }); - - $('.issue-action').click(function () { - let action = this.dataset.action; - let elementId = this.dataset.elementId; - const issueIDs = $('.issue-checkbox').children('input:checked').map(function() { - return this.dataset.issueId; - }).get().join(); - const url = this.dataset.url; - if (elementId === '0' && url.substr(-9) === '/assignee'){ - elementId = ''; - action = 'clear'; - } - updateIssuesMeta(url, action, issueIDs, elementId).then(function() { - // NOTICE: This reset of checkbox state targets Firefox caching behaviour, as the checkboxes stay checked after reload - if (action === "close" || action === "open" ){ - //uncheck all checkboxes - $('.issue-checkbox input[type="checkbox"]').each(function(_,e){ e.checked = false; }); - } - reload(); - }); - }); - - // NOTICE: This event trigger targets Firefox caching behaviour, as the checkboxes stay checked after reload - // trigger ckecked event, if checkboxes are checked on load - $('.issue-checkbox input[type="checkbox"]:checked').first().each(function(_,e) { - e.checked = false; - $(e).click(); - }); - - buttonsClickOnEnter(); - searchUsers(); - searchTeams(); - searchRepositories(); - - initCommentForm(); - initInstall(); - initRepository(); - initMigration(); - initWikiForm(); - initEditForm(); - initEditor(); - initOrganization(); - initWebhook(); - initAdmin(); - initCodeView(); - initVueApp(); - initTeamSettings(); - initCtrlEnterSubmit(); - initNavbarContentToggle(); - initTopicbar(); - initU2FAuth(); - initU2FRegister(); - initIssueList(); - initWipTitle(); - initPullRequestReview(); - initRepoStatusChecker(); - initTemplateSearch(); - - // Repo clone url. - if ($('#repo-clone-url').length > 0) { - switch (localStorage.getItem('repo-clone-protocol')) { - case 'ssh': - if ($('#repo-clone-ssh').click().length === 0) { - $('#repo-clone-https').click(); - } - break; - default: - $('#repo-clone-https').click(); - break; - } - } - - const routes = { - 'div.user.settings': initUserSettings, - 'div.repository.settings.collaboration': initRepositoryCollaboration - }; - - let selector; - for (selector in routes) { - if ($(selector).length > 0) { - routes[selector](); - break; - } - } - - const $cloneAddr = $('#clone_addr'); - $cloneAddr.change(function() { - const $repoName = $('#repo_name'); - if ($cloneAddr.val().length > 0 && $repoName.val().length === 0) { // Only modify if repo_name input is blank - $repoName.val($cloneAddr.val().match(/^(.*\/)?((.+?)(\.git)?)$/)[3]); - } - }); -}); - -function changeHash(hash) { - if (history.pushState) { - history.pushState(null, null, hash); - } - else { - location.hash = hash; - } -} - -function deSelect() { - if (window.getSelection) { - window.getSelection().removeAllRanges(); - } else { - document.selection.empty(); - } -} - -function selectRange($list, $select, $from) { - $list.removeClass('active'); - if ($from) { - let a = parseInt($select.attr('rel').substr(1)); - let b = parseInt($from.attr('rel').substr(1)); - let c; - if (a != b) { - if (a > b) { - c = a; - a = b; - b = c; - } - const classes = []; - for (let i = a; i <= b; i++) { - classes.push('.L' + i); - } - $list.filter(classes.join(',')).addClass('active'); - changeHash('#L' + a + '-' + 'L' + b); - return - } - } - $select.addClass('active'); - changeHash('#' + $select.attr('rel')); -} - -$(function () { - // Warn users that try to leave a page after entering data into a form. - // Except on sign-in pages, and for forms marked as 'ignore-dirty'. - if ($('.user.signin').length === 0) { - $('form:not(.ignore-dirty)').areYouSure(); - } - - // Parse SSH Key - $("#ssh-key-content").on('change paste keyup',function(){ - const arrays = $(this).val().split(" "); - const $title = $("#ssh-key-title") - if ($title.val() === "" && arrays.length === 3 && arrays[2] !== "") { - $title.val(arrays[2]); - } - }); -}); - -function showDeletePopup() { - const $this = $(this); - let filter = ""; - if ($this.attr("id")) { - filter += "#" + $this.attr("id") - } - - const dialog = $('.delete.modal' + filter); - dialog.find('.name').text($this.data('name')); - - dialog.modal({ - closable: false, - onApprove: function() { - if ($this.data('type') == "form") { - $($this.data('form')).submit(); - return; - } - - $.post($this.data('url'), { - "_csrf": csrf, - "id": $this.data("id") - }).done(function(data) { - window.location.href = data.redirect; - }); - } - }).modal('show'); - return false; -} - -function showAddAllPopup() { - const $this = $(this); - let filter = ""; - if ($this.attr("id")) { - filter += "#" + $this.attr("id") - } - - const dialog = $('.addall.modal' + filter); - dialog.find('.name').text($this.data('name')); - - dialog.modal({ - closable: false, - onApprove: function() { - if ($this.data('type') == "form") { - $($this.data('form')).submit(); - return; - } - - $.post($this.data('url'), { - "_csrf": csrf, - "id": $this.data("id") - }).done(function(data) { - window.location.href = data.redirect; - }); - } - }).modal('show'); - return false; -} - -function initVueComponents(){ - const vueDelimeters = ['${', '}']; - - Vue.component('repo-search', { - delimiters: vueDelimeters, - - props: { - searchLimit: { - type: Number, - default: 10 - }, - suburl: { - type: String, - required: true - }, - uid: { - type: Number, - required: true - }, - organizations: { - type: Array, - default: [] - }, - isOrganization: { - type: Boolean, - default: true - }, - canCreateOrganization: { - type: Boolean, - default: false - }, - organizationsTotalCount: { - type: Number, - default: 0 - }, - moreReposLink: { - type: String, - default: '' - } - }, - - data: function() { - return { - tab: 'repos', - repos: [], - reposTotalCount: 0, - reposFilter: 'all', - searchQuery: '', - isLoading: false, - repoTypes: { - 'all': { - count: 0, - searchMode: '', - }, - 'forks': { - count: 0, - searchMode: 'fork', - }, - 'mirrors': { - count: 0, - searchMode: 'mirror', - }, - 'sources': { - count: 0, - searchMode: 'source', - }, - 'collaborative': { - count: 0, - searchMode: 'collaborative', - }, - } - } - }, - - computed: { - showMoreReposLink: function() { - return this.repos.length > 0 && this.repos.length < this.repoTypes[this.reposFilter].count; - }, - searchURL: function() { - return this.suburl + '/api/v1/repos/search?sort=updated&order=desc&uid=' + this.uid + '&q=' + this.searchQuery - + '&limit=' + this.searchLimit + '&mode=' + this.repoTypes[this.reposFilter].searchMode - + (this.reposFilter !== 'all' ? '&exclusive=1' : ''); - }, - repoTypeCount: function() { - return this.repoTypes[this.reposFilter].count; - } - }, - - mounted: function() { - this.searchRepos(this.reposFilter); - - const self = this; - Vue.nextTick(function() { - self.$refs.search.focus(); - }); - }, - - methods: { - changeTab: function(t) { - this.tab = t; - }, - - changeReposFilter: function(filter) { - this.reposFilter = filter; - this.repos = []; - this.repoTypes[filter].count = 0; - this.searchRepos(filter); - }, - - showRepo: function(repo, filter) { - switch (filter) { - case 'sources': - return repo.owner.id == this.uid && !repo.mirror && !repo.fork; - case 'forks': - return repo.owner.id == this.uid && !repo.mirror && repo.fork; - case 'mirrors': - return repo.mirror; - case 'collaborative': - return repo.owner.id != this.uid && !repo.mirror; - default: - return true; - } - }, - - searchRepos: function(reposFilter) { - const self = this; - - this.isLoading = true; - - const searchedMode = this.repoTypes[reposFilter].searchMode; - const searchedURL = this.searchURL; - const searchedQuery = this.searchQuery; - - $.getJSON(searchedURL, function(result, _textStatus, request) { - if (searchedURL == self.searchURL) { - self.repos = result.data; - const count = request.getResponseHeader('X-Total-Count'); - if (searchedQuery === '' && searchedMode === '') { - self.reposTotalCount = count; - } - self.repoTypes[reposFilter].count = count; - } - }).always(function() { - if (searchedURL == self.searchURL) { - self.isLoading = false; - } - }); - }, - - repoClass: function(repo) { - if (repo.fork) { - return 'octicon octicon-repo-forked'; - } else if (repo.mirror) { - return 'octicon octicon-repo-clone'; - } else if (repo.private) { - return 'octicon octicon-lock'; - } else { - return 'octicon octicon-repo'; - } - } - } - }) -} - -function initCtrlEnterSubmit() { - $(".js-quick-submit").keydown(function(e) { - if (((e.ctrlKey && !e.altKey) || e.metaKey) && (e.keyCode == 13 || e.keyCode == 10)) { - $(this).closest("form").submit(); - } - }); -} - -function initVueApp() { - const el = document.getElementById('app'); - if (!el) { - return; - } - - initVueComponents(); - - new Vue({ - delimiters: ['${', '}'], - el: el, - - data: { - searchLimit: document.querySelector('meta[name=_search_limit]').content, - suburl: document.querySelector('meta[name=_suburl]').content, - uid: document.querySelector('meta[name=_context_uid]').content, - }, - }); -} - -function timeAddManual() { - $('.mini.modal') - .modal({ - duration: 200, - onApprove: function() { - $('#add_time_manual_form').submit(); - } - }).modal('show') - ; -} - -function toggleStopwatch() { - $("#toggle_stopwatch_form").submit(); -} -function cancelStopwatch() { - $("#cancel_stopwatch_form").submit(); -} - -function initHeatmap(appElementId, heatmapUser, locale) { - const el = document.getElementById(appElementId); - if (!el) { - return; - } - - locale = locale || {}; - - locale.contributions = locale.contributions || 'contributions'; - locale.no_contributions = locale.no_contributions || 'No contributions'; - - const vueDelimeters = ['${', '}']; - - Vue.component('activity-heatmap', { - delimiters: vueDelimeters, - - props: { - user: { - type: String, - required: true - }, - suburl: { - type: String, - required: true - }, - locale: { - type: Object, - required: true - } - }, - - data: function () { - return { - isLoading: true, - colorRange: [], - endDate: null, - values: [], - totalContributions: 0, - }; - }, - - mounted: function() { - this.colorRange = [ - this.getColor(0), - this.getColor(1), - this.getColor(2), - this.getColor(3), - this.getColor(4), - this.getColor(5) - ]; - this.endDate = new Date(); - this.loadHeatmap(this.user); - }, - - methods: { - loadHeatmap: function(userName) { - const self = this; - $.get(this.suburl + '/api/v1/users/' + userName + '/heatmap', function(chartRawData) { - const chartData = []; - for (let i = 0; i < chartRawData.length; i++) { - self.totalContributions += chartRawData[i].contributions; - chartData[i] = { date: new Date(chartRawData[i].timestamp * 1000), count: chartRawData[i].contributions }; - } - self.values = chartData; - self.isLoading = false; - }); - }, - - getColor: function(idx) { - const el = document.createElement('div'); - el.className = 'heatmap-color-' + idx; - document.body.appendChild(el); - - const color = getComputedStyle(el).backgroundColor; - - document.body.removeChild(el); - - return color; - } - }, - - template: '

total contributions in the last 12 months

' - }); - - new Vue({ - delimiters: vueDelimeters, - el: el, - - data: { - suburl: document.querySelector('meta[name=_suburl]').content, - heatmapUser: heatmapUser, - locale: locale - }, - }); -} - -function initFilterBranchTagDropdown(selector) { - $(selector).each(function() { - const $dropdown = $(this); - const $data = $dropdown.find('.data'); - const data = { - items: [], - mode: $data.data('mode'), - searchTerm: '', - noResults: '', - canCreateBranch: false, - menuVisible: false, - active: 0 - }; - $data.find('.item').each(function() { - data.items.push({ - name: $(this).text(), - url: $(this).data('url'), - branch: $(this).hasClass('branch'), - tag: $(this).hasClass('tag'), - selected: $(this).hasClass('selected') - }); - }); - $data.remove(); - new Vue({ - delimiters: ['${', '}'], - el: this, - data: data, - - beforeMount: function () { - const vm = this; - - this.noResults = vm.$el.getAttribute('data-no-results'); - this.canCreateBranch = vm.$el.getAttribute('data-can-create-branch') === 'true'; - - document.body.addEventListener('click', function(event) { - if (vm.$el.contains(event.target)) { - return; - } - if (vm.menuVisible) { - Vue.set(vm, 'menuVisible', false); - } - }); - }, - - watch: { - menuVisible: function(visible) { - if (visible) { - this.focusSearchField(); - } - } - }, - - computed: { - filteredItems: function() { - const vm = this; - - const items = vm.items.filter(function (item) { - return ((vm.mode === 'branches' && item.branch) - || (vm.mode === 'tags' && item.tag)) - && (!vm.searchTerm - || item.name.toLowerCase().indexOf(vm.searchTerm.toLowerCase()) >= 0); - }); - - vm.active = (items.length === 0 && vm.showCreateNewBranch ? 0 : -1); - - return items; - }, - showNoResults: function() { - return this.filteredItems.length === 0 - && !this.showCreateNewBranch; - }, - showCreateNewBranch: function() { - const vm = this; - if (!this.canCreateBranch || !vm.searchTerm || vm.mode === 'tags') { - return false; - } - - return vm.items.filter(function (item) { - return item.name.toLowerCase() === vm.searchTerm.toLowerCase() - }).length === 0; - } - }, - - methods: { - selectItem: function(item) { - const prev = this.getSelected(); - if (prev !== null) { - prev.selected = false; - } - item.selected = true; - window.location.href = item.url; - }, - createNewBranch: function() { - if (!this.showCreateNewBranch) { - return; - } - this.$refs.newBranchForm.submit(); - }, - focusSearchField: function() { - const vm = this; - Vue.nextTick(function() { - vm.$refs.searchField.focus(); - }); - }, - getSelected: function() { - for (let i = 0, j = this.items.length; i < j; ++i) { - if (this.items[i].selected) - return this.items[i]; - } - return null; - }, - getSelectedIndexInFiltered: function() { - for (let i = 0, j = this.filteredItems.length; i < j; ++i) { - if (this.filteredItems[i].selected) - return i; - } - return -1; - }, - scrollToActive: function() { - let el = this.$refs['listItem' + this.active]; - if (!el || el.length === 0) { - return; - } - if (Array.isArray(el)) { - el = el[0]; - } - - const cont = this.$refs.scrollContainer; - - if (el.offsetTop < cont.scrollTop) { - cont.scrollTop = el.offsetTop; - } - else if (el.offsetTop + el.clientHeight > cont.scrollTop + cont.clientHeight) { - cont.scrollTop = el.offsetTop + el.clientHeight - cont.clientHeight; - } - }, - keydown: function(event) { - const vm = this; - if (event.keyCode === 40) { - // arrow down - event.preventDefault(); - - if (vm.active === -1) { - vm.active = vm.getSelectedIndexInFiltered(); - } - - if (vm.active + (vm.showCreateNewBranch ? 0 : 1) >= vm.filteredItems.length) { - return; - } - vm.active++; - vm.scrollToActive(); - } - if (event.keyCode === 38) { - // arrow up - event.preventDefault(); - - if (vm.active === -1) { - vm.active = vm.getSelectedIndexInFiltered(); - } - - if (vm.active <= 0) { - return; - } - vm.active--; - vm.scrollToActive(); - } - if (event.keyCode == 13) { - // enter - event.preventDefault(); - - if (vm.active >= vm.filteredItems.length) { - vm.createNewBranch(); - } else if (vm.active >= 0) { - vm.selectItem(vm.filteredItems[vm.active]); - } - } - if (event.keyCode == 27) { - // escape - event.preventDefault(); - vm.menuVisible = false; - } - } - } - }); - }); -} - -$(".commit-button").click(function(e) { - e.preventDefault(); - $(this).parent().find('.commit-body').toggle(); -}); - -function initNavbarContentToggle() { - const content = $('#navbar'); - const toggle = $('#navbar-expand-toggle'); - let isExpanded = false; - toggle.click(function() { - isExpanded = !isExpanded; - if (isExpanded) { - content.addClass('shown'); - toggle.addClass('active'); - } - else { - content.removeClass('shown'); - toggle.removeClass('active'); - } - }); -} - -function initTopicbar() { - const mgrBtn = $("#manage_topic"); - const editDiv = $("#topic_edit"); - const viewDiv = $("#repo-topics"); - const saveBtn = $("#save_topic"); - const topicDropdown = $('#topic_edit .dropdown'); - const topicForm = $('#topic_edit.ui.form'); - const topicPrompts = getPrompts(); - - mgrBtn.click(function() { - viewDiv.hide(); - editDiv.css('display', ''); // show Semantic UI Grid - }); - - function getPrompts() { - const hidePrompt = $("div.hide#validate_prompt"), - prompts = { - countPrompt: hidePrompt.children('#count_prompt').text(), - formatPrompt: hidePrompt.children('#format_prompt').text() - }; - hidePrompt.remove(); - return prompts; - } - - saveBtn.click(function() { - const topics = $("input[name=topics]").val(); - - $.post(saveBtn.data('link'), { - "_csrf": csrf, - "topics": topics - }, function(_data, _textStatus, xhr){ - if (xhr.responseJSON.status === 'ok') { - viewDiv.children(".topic").remove(); - if (topics.length) { - const topicArray = topics.split(","); - - const last = viewDiv.children("a").last(); - for (let i=0; i < topicArray.length; i++) { - $('
'+topicArray[i]+'
').insertBefore(last) - } - } - editDiv.css('display', 'none'); - viewDiv.show(); - } - }).fail(function(xhr){ - if (xhr.status === 422) { - if (xhr.responseJSON.invalidTopics.length > 0) { - topicPrompts.formatPrompt = xhr.responseJSON.message; - - const invalidTopics = xhr.responseJSON.invalidTopics, - topicLables = topicDropdown.children('a.ui.label'); - - topics.split(',').forEach(function(value, index) { - for (let i=0; i < invalidTopics.length; i++) { - if (invalidTopics[i] === value) { - topicLables.eq(index).removeClass("green").addClass("red"); - } - } - }); - } else { - topicPrompts.countPrompt = xhr.responseJSON.message; - } - } - }).always(function() { - topicForm.form('validate form'); - }); - }); - - topicDropdown.dropdown({ - allowAdditions: true, - forceSelection: false, - fields: { name: "description", value: "data-value" }, - saveRemoteData: false, - label: { - transition : 'horizontal flip', - duration : 200, - variation : false, - blue : true, - basic: true, - }, - className: { - label: 'ui small label' - }, - apiSettings: { - url: suburl + '/api/v1/topics/search?q={query}', - throttle: 500, - cache: false, - onResponse: function(res) { - const formattedResponse = { - success: false, - results: [], - }; - const stripTags = function (text) { - return text.replace(/<[^>]*>?/gm, ""); - }; - - const query = stripTags(this.urlData.query.trim()); - let found_query = false; - const current_topics = []; - topicDropdown.find('div.label.visible.topic,a.label.visible').each(function(_,e){ current_topics.push(e.dataset.value); }); - - if (res.topics) { - let found = false; - for (let i=0;i < res.topics.length;i++) { - // skip currently added tags - if (current_topics.indexOf(res.topics[i].topic_name) != -1){ - continue; - } - - if (res.topics[i].topic_name.toLowerCase() === query.toLowerCase()){ - found_query = true; - } - formattedResponse.results.push({"description": res.topics[i].topic_name, "data-value": res.topics[i].topic_name}); - found = true; - } - formattedResponse.success = found; - } - - if (query.length > 0 && !found_query){ - formattedResponse.success = true; - formattedResponse.results.unshift({"description": query, "data-value": query}); - } else if (query.length > 0 && found_query) { - formattedResponse.results.sort(function(a, b){ - if (a.description.toLowerCase() === query.toLowerCase()) return -1; - if (b.description.toLowerCase() === query.toLowerCase()) return 1; - if (a.description > b.description) return -1; - if (a.description < b.description) return 1; - return 0; - }); - } - - - return formattedResponse; - }, - }, - onLabelCreate: function(value) { - value = value.toLowerCase().trim(); - this.attr("data-value", value).contents().first().replaceWith(value); - return $(this); - }, - onAdd: function(addedValue, _addedText, $addedChoice) { - addedValue = addedValue.toLowerCase().trim(); - $($addedChoice).attr('data-value', addedValue); - $($addedChoice).attr('data-text', addedValue); - } - }); - - $.fn.form.settings.rules.validateTopic = function(_values, regExp) { - const topics = topicDropdown.children('a.ui.label'), - status = topics.length === 0 || topics.last().attr("data-value").match(regExp); - if (!status) { - topics.last().removeClass("green").addClass("red"); - } - return status && topicDropdown.children('a.ui.label.red').length === 0; - }; - - topicForm.form({ - on: 'change', - inline : true, - fields: { - topics: { - identifier: 'topics', - rules: [ - { - type: 'validateTopic', - value: /^[a-z0-9][a-z0-9-]{1,35}$/, - prompt: topicPrompts.formatPrompt - }, - { - type: 'maxCount[25]', - prompt: topicPrompts.countPrompt - } - ] - }, - } - }); -} -function toggleDeadlineForm() { - $('#deadlineForm').fadeToggle(150); -} - -function setDeadline() { - const deadline = $('#deadlineDate').val(); - updateDeadline(deadline); -} - -function updateDeadline(deadlineString) { - $('#deadline-err-invalid-date').hide(); - $('#deadline-loader').addClass('loading'); - - let realDeadline = null; - if (deadlineString !== '') { - - const newDate = Date.parse(deadlineString) - - if (isNaN(newDate)) { - $('#deadline-loader').removeClass('loading'); - $('#deadline-err-invalid-date').show(); - return false; - } - realDeadline = new Date(newDate); - } - - $.ajax($('#update-issue-deadline-form').attr('action') + '/deadline', { - data: JSON.stringify({ - 'due_date': realDeadline, - }), - headers: { - 'X-Csrf-Token': csrf, - 'X-Remote': true, - }, - contentType: 'application/json', - type: 'POST', - success: function () { - reload(); - }, - error: function () { - $('#deadline-loader').removeClass('loading'); - $('#deadline-err-invalid-date').show(); - } - }); -} - -function deleteDependencyModal(id, type) { - $('.remove-dependency') - .modal({ - closable: false, - duration: 200, - onApprove: function () { - $('#removeDependencyID').val(id); - $('#dependencyType').val(type); - $('#removeDependencyForm').submit(); - } - }).modal('show') - ; -} - -function initIssueList() { - const repolink = $('#repolink').val(); - const repoId = $('#repoId').val(); - const crossRepoSearch = $('#crossRepoSearch').val(); - let issueSearchUrl = suburl + '/api/v1/repos/' + repolink + '/issues?q={query}'; - if (crossRepoSearch === 'true') { - issueSearchUrl = suburl + '/api/v1/repos/issues/search?q={query}&priority_repo_id=' + repoId; - } - $('#new-dependency-drop-list') - .dropdown({ - apiSettings: { - url: issueSearchUrl, - onResponse: function(response) { - const filteredResponse = {'success': true, 'results': []}; - const currIssueId = $('#new-dependency-drop-list').data('issue-id'); - // Parse the response from the api to work with our dropdown - $.each(response, function(_i, issue) { - // Don't list current issue in the dependency list. - if(issue.id === currIssueId) { - return; - } - filteredResponse.results.push({ - 'name' : '#' + issue.number + ' ' + htmlEncode(issue.title) + - '
' + htmlEncode(issue.repository.full_name) + '
', - 'value' : issue.id - }); - }); - return filteredResponse; - }, - cache: false, - }, - - fullTextSearch: true - }); - - $(".menu a.label-filter-item").each(function() { - $(this).click(function(e) { - if (e.altKey) { - e.preventDefault(); - - const href = $(this).attr("href"); - const id = $(this).data("label-id"); - - const regStr = "labels=(-?[0-9]+%2c)*(" + id + ")(%2c-?[0-9]+)*&"; - const newStr = "labels=$1-$2$3&"; - - window.location = href.replace(new RegExp(regStr), newStr); - } - }); - }); - - $(".menu .ui.dropdown.label-filter").keydown(function(e) { - if (e.altKey && e.keyCode == 13) { - const selectedItems = $(".menu .ui.dropdown.label-filter .menu .item.selected"); - - if (selectedItems.length > 0) { - const item = $(selectedItems[0]); - - const href = item.attr("href"); - const id = item.data("label-id"); - - const regStr = "labels=(-?[0-9]+%2c)*(" + id + ")(%2c-?[0-9]+)*&"; - const newStr = "labels=$1-$2$3&"; - - window.location = href.replace(new RegExp(regStr), newStr); - } - } - }); -} -function cancelCodeComment(btn) { - const form = $(btn).closest("form"); - if(form.length > 0 && form.hasClass('comment-form')) { - form.addClass('hide'); - form.parent().find('button.comment-form-reply').show(); - } else { - form.closest('.comment-code-cloud').remove() - } -} -function onOAuthLoginClick() { - const oauthLoader = $('#oauth2-login-loader'); - const oauthNav = $('#oauth2-login-navigator'); - - oauthNav.hide(); - oauthLoader.removeClass('disabled'); - - setTimeout(function(){ - // recover previous content to let user try again - // usually redirection will be performed before this action - oauthLoader.addClass('disabled'); - oauthNav.show(); - },5000); -} +!function(e){var t={};function a(i){if(t[i])return t[i].exports;var n=t[i]={i:i,l:!1,exports:{}};return e[i].call(n.exports,n,n.exports,a),n.l=!0,n.exports}a.m=e,a.c=t,a.d=function(e,t,i){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(a.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)a.d(i,n,function(t){return e[t]}.bind(null,n));return i},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=0)}([function(e,t,a){a(1),e.exports=a(2)},function(e,t){function a(e){return jQuery("
").text(e).html()}var i,n,o,r,s;function c(e){var t=e.find(".tabular.menu");t.find(".item").tab(),t.find('.item[data-tab="'.concat(t.data("preview"),'"]')).click((function(){var a=$(this);$.post(a.data("url"),{_csrf:i,mode:"gfm",context:a.data("context"),text:e.find('.tab.segment[data-tab="'.concat(t.data("write"),'"] textarea')).val()},(function(a){var i=e.find('.tab.segment[data-tab="'.concat(t.data("preview"),'"]'));i.html(a),emojify.run(i[0]),$("pre code",i[0]).each((function(){hljs.highlightBlock(this)}))}))})),w()}function l(){var e,t;0!==$(".edit.form").length&&(!function(e){var t=e.find(".tabular.menu");t.find(".item").tab();var a=t.find('.item[data-tab="'.concat(t.data("preview"),'"]'));a.length&&(o=a.data("preview-file-modes").split(","),a.click((function(){var a=$(this);$.post(a.data("url"),{_csrf:i,mode:"gfm",context:a.data("context"),text:e.find('.tab.segment[data-tab="'.concat(t.data("write"),'"] textarea')).val()},(function(a){var i=e.find('.tab.segment[data-tab="'.concat(t.data("preview"),'"]'));i.html(a),emojify.run(i[0]),$("pre code",i[0]).each((function(){hljs.highlightBlock(this)}))}))})))}($(".edit.form")),e=$(".edit.form"),(t=e.find(".tabular.menu")).find(".item").tab(),t.find('.item[data-tab="'.concat(t.data("diff"),'"]')).click((function(){var a=$(this);$.post(a.data("url"),{_csrf:i,context:a.data("context"),content:e.find('.tab.segment[data-tab="'.concat(t.data("write"),'"] textarea')).val()},(function(a){var i=e.find('.tab.segment[data-tab="'.concat(t.data("diff"),'"]'));i.html(a),emojify.run(i[0])}))})))}function d(e,t,a,n){return new Promise((function(o){$.ajax({type:"POST",url:e,data:{_csrf:i,action:t,issue_ids:a,id:n},success:o})}))}function u(){window.location.reload()}function h(e){e.each((function(){var e=this;e.addEventListener("paste",(function(t){!function(e,t){if(e.clipboardData){var a=e.clipboardData.items;if(void 0!==a)for(var i=0;i')).val(i.uuid);$(".files").append(o)}))}))}),!1)}))}function f(){var e;0!==$(".comment.form").length&&((e=$(".ui.select-branch")).find(".reference-list-menu").find(".item:not(.no-select)").click((function(){var t=$(this).data("id");$($(this).data("id-selector")).val(t),e.find(".ui .branch-name").text(t)})),e.find(".reference.column").click((function(){return e.find(".scrolling.reference-list-menu").css("display","none"),e.find(".reference .text").removeClass("black"),$($(this).data("target")).css("display","block"),$(this).find(".text").addClass("black"),!1})),c($(".comment.form")),h($(".comment.form textarea")),t("select-label","labels"),t("select-assignees","assignees"),t("select-assignees-modify","assignees"),i(".select-milestone","#milestone_id"),i(".select-assignee","#assignee_id"));function t(e,t){var a=$(".ui.".concat(t,".list")),i=a.find(".no-select"),n=$(".".concat(e," .menu")),o="update"===n.data("action"),r={};$(".".concat(e)).dropdown("setting","onHide",(function(){if(o="update"===n.data("action")){var e=[];Object.keys(r).forEach((function(t){var a=r[t],i=d(a["update-url"],a.action,a["issue-id"],t);e.push(i)})),Promise.all(e).then(u)}})),n.find(".item:not(.no-select)").click((function(){if("select-assignees-modify"===e)return $(this).hasClass("checked")?($(this).removeClass("checked"),$(this).find(".octicon").removeClass("octicon-check")):($(this).addClass("checked"),$(this).find(".octicon").addClass("octicon-check")),d(n.data("update-url"),"",n.data("issue-id"),$(this).data("id")),n.data("action","update"),!1;$(this).hasClass("checked")?($(this).removeClass("checked"),$(this).find(".octicon").removeClass("octicon-check"),o&&($(this).data("id")in r?delete r[$(this).data("id")]:r[$(this).data("id")]={"update-url":n.data("update-url"),action:"detach","issue-id":n.data("issue-id")})):($(this).addClass("checked"),$(this).find(".octicon").addClass("octicon-check"),o&&($(this).data("id")in r?delete r[$(this).data("id")]:r[$(this).data("id")]={"update-url":n.data("update-url"),action:"attach","issue-id":n.data("issue-id")}));var t=[];return $(this).parent().find(".item").each((function(){$(this).hasClass("checked")?(t.push($(this).data("id")),$($(this).data("id-selector")).removeClass("hide")):$($(this).data("id-selector")).addClass("hide")})),0===t.length?i.removeClass("hide"):i.addClass("hide"),$($(this).parent().data("id")).val(t.join(",")),!1})),n.find(".no-select.item").click((function(){(o||"select-assignees-modify"===e)&&d(n.data("update-url"),"clear",n.data("issue-id"),"").then(u),$(this).parent().find(".item").each((function(){$(this).removeClass("checked"),$(this).find(".octicon").removeClass("octicon-check")})),a.find(".item").each((function(){$(this).addClass("hide")})),i.removeClass("hide"),$($(this).parent().data("id")).val("")}))}function i(e,t){var i=$("".concat(e," .menu")),n=$(".ui".concat(e,".list")),o="update"===i.data("action");i.find(".item:not(.no-select)").click((function(){switch($(this).parent().find(".item").each((function(){$(this).removeClass("selected active")})),$(this).addClass("selected active"),o&&d(i.data("update-url"),"",i.data("issue-id"),$(this).data("id")).then(u),t){case"#milestone_id":n.find(".selected").html('')).val(t.uuid);s.append(a)})),this.on("removedfile",(function(e){e.name in l&&($("#".concat(l[e.name].uuid)).remove(),r.data("remove-url")&&r.data("csrf")&&!l[e.name].submitted&&$.post(r.data("remove-url"),{file:l[e.name].uuid,_csrf:r.data("csrf")}))})),this.on("submit",(function(){$.each(l,(function(e){l[e].submitted=!0}))})),this.on("reload",(function(){$.getJSON(a.data("attachment-url"),(function(e){var t=r.get(0).dropzone;t.removeAllFiles(!0),s.empty(),$.each(e,(function(){var e="".concat(r.data("upload-url"),"/").concat(this.uuid);t.emit("addedfile",this),t.emit("thumbnail",this,e),t.emit("complete",this),t.files.push(this),l[this.name]={submitted:!0,uuid:this.uuid},r.find("img[src='".concat(e,"']")).css("max-width","100%");var a=$('')).val(this.uuid);s.append(a)}))}))}))}}),r.get(0).dropzone.emit("reload")}var d=a.find(".ui.comment.form"),u=d.find(".tabular.menu");u.attr("data-write",a.data("write")),u.attr("data-preview",a.data("preview")),u.find(".write.item").attr("data-tab",a.data("write")),u.find(".preview.item").attr("data-tab",a.data("preview")),d.find(".write.segment").attr("data-tab",a.data("write")),d.find(".preview.segment").attr("data-tab",a.data("preview")),c(d),a.find(".cancel.button").click((function(){n.show(),a.hide(),r.get(0).dropzone.emit("reload")})),a.find(".save.button").click((function(){n.show(),a.hide();var o=s.find("[name=files]").map((function(){return $(this).val()})).get();$.post(a.data("update-url"),{_csrf:i,content:e.val(),context:a.data("context"),files:o},(function(e){0===e.length?n.html($("#no-content").html()):(n.html(e.content),emojify.run(n[0]),$("pre code",n[0]).each((function(){hljs.highlightBlock(this)})));var a=t.parent();a.find(".ui.small.images").length?""===e.attachments?a.find(".ui.small.images").parent().remove():a.find(".ui.small.images").html(e.attachments):""!==e.attachments&&(a.append('
'),a.find(".ui.small.images").html(e.attachments)),r.get(0).dropzone.emit("submit"),r.get(0).dropzone.emit("reload")}))}))}else e=t.find("textarea");return a.show(),n.hide(),0===e.val().length&&e.val(o.text()),e.focus(),!1})),$(".delete-comment").click((function(){var e=$(this);return window.confirm(e.data("locale"))&&$.post(e.data("url"),{_csrf:i}).success((function(){$("#".concat(e.data("comment-id"))).remove()})),!1}));var r=$("#status-button");$("#comment-form .edit_area").keyup((function(){0===$(this).val().length?r.text(r.data("status")):r.text(r.data("status-and-comment"))})),r.click((function(){$("#status").val(r.data("status-val")),$("#comment-form").submit()}));var s=$(".merge-button > button");s.on("click",(function(e){e.preventDefault(),$(".".concat($(this).data("do"),"-fields")).show(),$(this).parent().hide()})),$(".merge-button > .dropdown").dropdown({onChange:function(e,t,a){a.data("do")&&(s.find(".button-text").text(a.text()),s.data("do",a.data("do")))}}),$(".merge-cancel").on("click",(function(e){e.preventDefault(),$(this).closest(".form").hide(),s.parent().show()})),function e(t){var a="";t||(t=$(document),a=".reactions > "),t.find("".concat(a,"a.label")).popup({position:"bottom left",metadata:{content:"title",title:"none"}}),t.find(".select-reaction > .menu > .item, ".concat(a,"a.label")).on("click",(function(t){var a=this;if(t.preventDefault(),!$(this).hasClass("disabled")){var n=$(this).hasClass("item")?$(this).closest(".select-reaction").data("action-url"):$(this).data("action-url"),o="".concat(n,"/").concat($(this).hasClass("blue")?"unreact":"react");$.ajax({type:"POST",url:o,data:{_csrf:i,content:$(this).data("content")}}).done((function(t){if(t&&(t.html||t.empty)){var i=$(a).closest(".content"),n=i.find(".segment.reactions");if(!t.empty&&n.length>0&&n.remove(),!t.empty){n=$('
');var o=i.find(".segment.bottom:first");o.length>0?n.insertBefore(o):n.appendTo(i),n.html(t.html);for(var r=n.find(".has-emoji"),s=0;s0&&$(".diff-counter").each((function(){var e=$(this),t=e.find("span[data-line].add").data("line"),a=e.find("span[data-line].del").data("line"),i=parseFloat(t)/(parseFloat(t)+parseFloat(a))*100;e.find(".bar .add").css("width","".concat(i,"%"))})),$("#repo-clone-ssh").click((function(){$(".clone-url").text($(this).data("link")),$("#repo-clone-url").val($(this).data("link")),$(this).addClass("blue"),$("#repo-clone-https").removeClass("blue"),localStorage.setItem("repo-clone-protocol","ssh")})),$("#repo-clone-https").click((function(){$(".clone-url").text($(this).data("link")),$("#repo-clone-url").val($(this).data("link")),$(this).addClass("blue"),$("#repo-clone-ssh").removeClass("blue"),localStorage.setItem("repo-clone-protocol","https")})),$("#repo-clone-url").click((function(){$(this).select()}));var l=$(".repository.compare.pull");l.length>0&&(d(".choose.branch .dropdown"),l.find("button.show-form").on("click",(function(e){e.preventDefault(),l.find(".pullrequest-form").show(),$(this).parent().hide()}))),$(".repository.settings.branches").length>0&&(d(".protected-branches .dropdown"),$(".enable-protection, .enable-whitelist").change((function(){this.checked?$($(this).data("target")).removeClass("disabled"):$($(this).data("target")).addClass("disabled")})))}function d(e){var t=$(e);t.dropdown({fullTextSearch:!0,selectOnKeydown:!1,onChange:function(e,t,a){a.data("url")&&(window.location.href=a.data("url"))},message:{noResults:t.data("no-results")}})}}function m(e){var t=Math.floor(Math.random()*Math.floor(1e6));return e.attr("data-write",e.attr("data-write")+t),e.attr("data-preview",e.attr("data-preview")+t),e.find(".item").each((function(){var e=$(this).attr("data-tab")+t;$(this).attr("data-tab",e)})),e.parent().find("*[data-tab='write']").attr("data-tab","write".concat(t)),e.parent().find("*[data-tab='preview']").attr("data-tab","preview".concat(t)),c(e.parent(".form")),t}function v(){$(".access-mode.menu .item").click((function(){var e=$(this).parent();$.post(e.data("url"),{_csrf:i,uid:e.data("uid"),mode:$(this).data("value")})}))}function g(){$(".js-quick-pull-choice-option").change((function(){"commit-to-new-branch"===$(this).val()?($(".quick-pull-branch-name").show(),$(".quick-pull-branch-name input").prop("required",!0)):($(".quick-pull-branch-name").hide(),$(".quick-pull-branch-name input").prop("required",!1)),$("#commit-button").text($(this).attr("button_text"))}));var e=$("#file-name");e.keyup((function(e){var t,a,i=$(".breadcrumb span.section"),n=$(".breadcrumb div.divider");if(8===e.keyCode&&0===$(this).getCursorPosition()&&i.length>0&&(t=i.last().find("a").text(),$(this).val(t+$(this).val()),$(this)[0].setSelectionRange(t.length,t.length),i.last().remove(),n.last().remove()),191===e.keyCode){a=$(this).val().split("/");for(var o=0;o
'.concat(t,"")).insertBefore($(this)),$('
/
').insertBefore($(this))):$(this).val(t),$(this)[0].setSelectionRange(0,0)}a=[],$(".breadcrumb span.section").each((function(){var e=$(this);e.find("a").length?a.push(e.find("a").text()):a.push(e.text())})),$(this).val()&&a.push($(this).val()),$("#tree_path").val(a.join("/"))})).trigger("keyup");var t=$(".repository.editor textarea#edit_area");if(t.length){var a=t.data("markdown-file-exts").split(","),n=t.data("line-wrap-extensions").split(",");e.on("keyup",(function(){var c,l,d,u,h,f,p=e.val();d=u="";var m=/.+\.([^.]+)$/.exec(p);m&&(d=m[1],u=".".concat(d));var v=CodeMirror.findModeByExtension(d),g=$("a[data-tab=preview]");if(v?(c=v.mode,l=v.mime,f=c):f=d,g.length&&f&&o&&o.length&&o.indexOf(f)>=0?(h=g.data("url"),g.data("url",h.replace(/(.*)\/.*/i,"$1/".concat(c))),g.show()):g.hide(),!(a.indexOf(u)>=0&&function(e){return s&&(s.toTextArea(),s=null),!!r||(r=new SimpleMDE({autoDownloadFontAwesome:!1,element:e[0],forceSync:!0,renderingConfig:{singleLineBreaks:!1},indentWithTabs:!1,tabSize:4,spellChecker:!1,previewRender:function(t,a){return setTimeout((function(){$.post(e.data("url"),{_csrf:i,mode:"gfm",context:e.data("context"),text:t},(function(e){a.innerHTML='
'.concat(e,"
"),emojify.run($(".editor-preview")[0])}))}),0),"Loading..."},toolbar:["bold","italic","strikethrough","|","heading-1","heading-2","heading-3","heading-bigger","heading-smaller","|","code","quote","|","unordered-list","ordered-list","|","link","image","table","horizontal-rule","|","clean-block","preview","fullscreen","side-by-side"]}),!0)}(t))&&(s||function(e){return r&&(r.toTextArea(),r=null),!!s||((s=CodeMirror.fromTextArea(e[0],{lineNumbers:!0})).on("change",(function(t,a){e.val(t.getValue())})),!0)}(t))){c&&(s.setOption("mode",l),CodeMirror.autoLoadMode(s,c)),n.indexOf(u)>=0?s.setOption("lineWrapping",!0):s.setOption("lineWrapping",!1);var b=e.val();0!==b.length&&(b=(b=b.split("/"))[b.length-1],$.getJSON(e.data("ec-url-prefix")+b,(function(e){"tab"===e.indent_style?(s.setOption("indentWithTabs",!0),s.setOption("extraKeys",{})):(s.setOption("indentWithTabs",!1),s.setOption("extraKeys",{Tab:function(e){var t=Array(parseInt(e.getOption("indentUnit"))+1).join(" ");e.replaceSelection(t)}})),s.setOption("indentUnit",e.indent_size||4),s.setOption("tabSize",e.tab_width||4)})))}})).trigger("keyup");var c=$("#commit-button"),l=$(".ui.edit.form");c.prop("disabled",!0),l.areYouSure({silent:!0,dirtyClass:"dirty-file",fieldSelector:":input:not(.commit-form-wrapper :input)",change:function(){var e=$(this).hasClass("dirty-file");c.prop("disabled",!e)}}),c.click((function(e){0===t.val().length&&($("#edit-empty-content-modal").modal({onApprove:function(){$(".edit.form").submit()}}).modal("show"),e.preventDefault())}))}}function b(){$(".user.settings.profile").length>0&&$("#username").keyup((function(){var e=$("#name-change-prompt");$(this).val().toString().toLowerCase()!==$(this).data("name").toString().toLowerCase()?e.show():e.hide()}))}function w(){$(".ui.button").keypress((function(e){13!==e.keyCode&&32!==e.keyCode||$(this).click()}))}function k(){$(".code-view .linenums").length>0&&($(document).on("click",".lines-num span",(function(e){var t=$(this),a=t.parent().siblings(".lines-code").find("ol.linenums > li");q(a,a.filter("[rel=".concat(t.attr("id"),"]")),e.shiftKey?a.filter(".active").eq(0):null),window.getSelection?window.getSelection().removeAllRanges():document.selection.empty()})),$(window).on("hashchange",(function(){var e,t=window.location.hash.match(/^#(L\d+)-(L\d+)$/),a=$(".code-view ol.linenums > li");if(t)return e=a.filter(".".concat(t[1])),q(a,e,a.filter(".".concat(t[2]))),void $("html, body").scrollTop(e.offset().top-200);(t=window.location.hash.match(/^#(L|n)(\d+)$/))&&(e=a.filter(".L".concat(t[2])),q(a,e),$("html, body").scrollTop(e.offset().top-200))})).trigger("hashchange")),$(".ui.fold-code").on("click",(function(e){var t=$(e.target);t.hasClass("fa-chevron-down")?$(e.target).parent().next().slideUp("fast",(function(){t.removeClass("fa-chevron-down").addClass("fa-chevron-right")})):$(e.target).parent().next().slideDown("fast",(function(){t.removeClass("fa-chevron-right").addClass("fa-chevron-down")}))})),$(".ui.blob-excerpt").on("click",(function(e){!function e(t){var a=$(t.target),i=a.parent().parent();$.get("".concat(a.data("url"),"?").concat(a.data("query"),"&anchor=").concat(a.data("anchor")),(function(t){i.replaceWith(t),$('[data-anchor="'.concat(a.data("anchor"),'"]')).on("click",(function(t){e(t)}))}))}(e)}))}function _(e){$.ajax({url:"".concat(n,"/user/u2f/sign"),type:"POST",headers:{"X-Csrf-Token":i},data:JSON.stringify(e),contentType:"application/json; charset=utf-8"}).done((function(e){window.location.replace(e)})).fail((function(){C(1)}))}function y(e){(function(e){if(!("errorCode"in e))return!1;if(0===e.errorCode)return!1;return C(e.errorCode),!0})(e)||$.ajax({url:"".concat(n,"/user/settings/security/u2f/register"),type:"POST",headers:{"X-Csrf-Token":i},data:JSON.stringify(e),contentType:"application/json; charset=utf-8",success:function(){u()},fail:function(){C(1)}})}function C(e){var t={browser:$("#unsupported-browser"),1:$("#u2f-error-1"),2:$("#u2f-error-2"),3:$("#u2f-error-3"),4:$("#u2f-error-4"),5:$(".u2f-error-5")};t[e].removeClass("hide"),Object.keys(t).forEach((function(a){a!==e&&t[a].addClass("hide")})),$("#u2f-error").modal("show")}function x(){$.post("".concat(n,"/user/settings/security/u2f/request_register"),{_csrf:i,name:$("#nickname").val()}).success((function(e){$("#nickname").closest("div.field").removeClass("error"),$("#register-device").modal("show"),null===e.registeredKeys&&(e.registeredKeys=[]),u2fApi.register(e.appId,e.registerRequests,e.registeredKeys,30).then(y).catch((function(e){C(void 0!==e?e.metaData.code:1)}))})).fail((function(e){409===e.status&&$("#nickname").closest("div.field").addClass("error")}))}function S(e){window.history.pushState?window.history.pushState(null,null,e):window.location.hash=e}function q(e,t,a){if(e.removeClass("active"),a){var i,n=parseInt(t.attr("rel").substr(1)),o=parseInt(a.attr("rel").substr(1));if(n!==o){n>o&&(i=n,n=o,o=i);for(var r=[],s=n;s<=o;s++)r.push(".L".concat(s));return e.filter(r.join(",")).addClass("active"),void S("#L".concat(n,"-L").concat(o))}}t.addClass("active"),S("#".concat(t.attr("rel")))}function T(){var e=$(this),t="";e.attr("id")&&(t+="#".concat(e.attr("id")));var a=$(".delete.modal".concat(t));return a.find(".name").text(e.data("name")),a.modal({closable:!1,onApprove:function(){"form"!==e.data("type")?$.post(e.data("url"),{_csrf:i,id:e.data("id")}).done((function(e){window.location.href=e.redirect})):$(e.data("form")).submit()}}).modal("show"),!1}function L(){var e=$(this),t="";e.attr("id")&&(t+="#".concat(e.attr("id")));var a=$(".addall.modal".concat(t));return a.find(".name").text(e.data("name")),a.modal({closable:!1,onApprove:function(){"form"!==e.data("type")?$.post(e.data("url"),{_csrf:i,id:e.data("id")}).done((function(e){window.location.href=e.redirect})):$(e.data("form")).submit()}}).modal("show"),!1}"undefined"!=typeof Dropzone&&(Dropzone.autoDiscover=!1),$.fn.getCursorPosition=function(){var e=$(this).get(0),t=0;if("selectionStart"in e)t=e.selectionStart;else if("selection"in document){e.focus();var a=document.selection.createRange(),i=document.selection.createRange().text.length;a.moveStart("character",-e.value.length),t=a.text.length-i}return t},$(document).ready((function(){if(i=$("meta[name=_csrf]").attr("content"),n=$("meta[name=_suburl]").attr("content"),$(".time-since").each((function(){$(this).addClass("poping up").attr("data-content",$(this).attr("title")).attr("data-variation","inverted tiny").attr("title","")})),$(".dropdown:not(.custom)").dropdown(),$(".jump.dropdown").dropdown({action:"hide",onShow:function(){$(".poping.up").popup("hide")}}),$(".slide.up.dropdown").dropdown({transition:"slide up"}),$(".upward.dropdown").dropdown({direction:"upward"}),$(".ui.accordion").accordion(),$(".ui.checkbox").checkbox(),$(".ui.progress").progress({showActivity:!1}),$(".poping.up").popup(),$(".top.menu .poping.up").popup({onShow:function(){if($(".top.menu .menu.transition").hasClass("visible"))return!1}}),$(".tabular.menu .item").tab(),$(".tabable.menu .item").tab(),$(".toggle.button").click((function(){$($(this).data("target")).slideToggle(100)})),$("tr[data-href]").click((function(){window.location=$(this).data("href")})),"undefined"!=typeof hljs)for(var e=[].slice.call(document.querySelectorAll("pre code")||[]),t=0;t0){var r={};new Dropzone("#dropzone",{url:o.data("upload-url"),headers:{"X-Csrf-Token":i},maxFiles:o.data("max-file"),maxFilesize:o.data("max-size"),acceptedFiles:"*/*"===o.data("accepts")?null:o.data("accepts"),addRemoveLinks:!0,dictDefaultMessage:o.data("default-message"),dictInvalidFileType:o.data("invalid-input-type"),dictFileTooBig:o.data("file-too-big"),dictRemoveFile:o.data("remove-file"),init:function(){this.on("success",(function(e,t){r[e.name]=t.uuid;var a=$('')).val(t.uuid);$(".files").append(a)})),this.on("removedfile",(function(e){e.name in r&&$("#".concat(r[e.name])).remove(),o.data("remove-url")&&o.data("csrf")&&$.post(o.data("remove-url"),{file:r[e.name],_csrf:o.data("csrf")})}))}})}emojify.setConfig({img_dir:"".concat(n,"/vendor/plugins/emojify/images"),ignore_emoticons:!0});for(var s=document.getElementsByClassName("has-emoji"),c=0;c0&&(i="".concat(a,"-").concat(e[a])),void 0===e[a]?e[a]=1:e[a]+=1,(t=t.wrap('
'))).append(''))}))})),$(".issue-checkbox").click((function(){$(".issue-checkbox").children("input:checked").length>0?($("#issue-filters").addClass("hide"),$("#issue-actions").removeClass("hide")):($("#issue-filters").removeClass("hide"),$("#issue-actions").addClass("hide"))})),$(".issue-action").click((function(){var e=this.dataset.action,t=this.dataset.elementId,a=$(".issue-checkbox").children("input:checked").map((function(){return this.dataset.issueId})).get().join(),i=this.dataset.url;"0"===t&&"/assignee"===i.substr(-9)&&(t="",e="clear"),d(i,e,a,t).then((function(){"close"!==e&&"open"!==e||$('.issue-checkbox input[type="checkbox"]').each((function(e,t){t.checked=!1})),u()}))})),$('.issue-checkbox input[type="checkbox"]:checked').first().each((function(e,t){t.checked=!1,$(t).click()})),w(),$("#search-user-box").search({minCharacters:2,apiSettings:{url:"".concat(n,"/api/v1/users/search?q={query}"),onResponse:function(e){var t=[];return $.each(e.data,(function(e,i){var n=i.login;i.full_name&&i.full_name.length>0&&(n+=" (".concat(a(i.full_name),")")),t.push({title:n,image:i.avatar_url})})),{results:t}}},searchFields:["login","full_name"],showNoResults:!1}),(y=$("#search-team-box")).search({minCharacters:2,apiSettings:{url:"".concat(n,"/api/v1/orgs/").concat(y.data("org"),"/teams/search?q={query}"),headers:{"X-Csrf-Token":i},onResponse:function(e){var t=[];return $.each(e.data,(function(e,a){var i="".concat(a.name," (").concat(a.permission," access)");t.push({title:i})})),{results:t}}},searchFields:["name","description"],showNoResults:!1}),(S=$("#search-repo-box")).search({minCharacters:2,apiSettings:{url:"".concat(n,"/api/v1/repos/search?q={query}&uid=").concat(S.data("uid")),onResponse:function(e){var t=[];return $.each(e.data,(function(e,a){t.push({title:a.full_name.split("/")[1],description:a.full_name})})),{results:t}}},searchFields:["full_name"],showNoResults:!1}),f(),0!==$(".install").length&&(""===$("#db_host").val()&&($("#db_host").val("127.0.0.1:3306"),$("#db_user").val("gitea"),$("#db_name").val("gitea")),$("#db_type").change((function(){var e=$(this).val();if("SQLite3"===e)return $("#sql_settings").hide(),$("#pgsql_settings").hide(),$("#mysql_settings").hide(),$("#sqlite_settings").show(),void("SQLite3"===e&&"data/gitea_tidb"===$("#db_path").val()&&$("#db_path").val("data/gitea.db"));var t={MySQL:"127.0.0.1:3306",PostgreSQL:"127.0.0.1:5432",MSSQL:"127.0.0.1:1433"};$("#sqlite_settings").hide(),$("#sql_settings").show(),$("#pgsql_settings").toggle("PostgreSQL"===e),$("#mysql_settings").toggle("MySQL"===e),$.each(t,(function(a,i){if($("#db_host").val()===i)return $("#db_host").val(t[e]),!1}))})),$("#offline-mode input").change((function(){$(this).is(":checked")&&($("#disable-gravatar").checkbox("check"),$("#federated-avatar-lookup").checkbox("uncheck"))})),$("#disable-gravatar input").change((function(){$(this).is(":checked")?$("#federated-avatar-lookup").checkbox("uncheck"):$("#offline-mode").checkbox("uncheck")})),$("#federated-avatar-lookup input").change((function(){$(this).is(":checked")&&($("#disable-gravatar").checkbox("uncheck"),$("#offline-mode").checkbox("uncheck"))})),$("#enable-openid-signin input").change((function(){$(this).is(":checked")?$("#disable-registration input").is(":checked")||$("#enable-openid-signup").checkbox("check"):$("#enable-openid-signup").checkbox("uncheck")})),$("#disable-registration input").change((function(){$(this).is(":checked")?($("#enable-captcha").checkbox("uncheck"),$("#enable-openid-signup").checkbox("uncheck")):$("#enable-openid-signup").checkbox("check")})),$("#enable-captcha input").change((function(){$(this).is(":checked")&&$("#disable-registration").checkbox("uncheck")}))),p(),(q=function(){var e=$("#auth_username").val(),t=$("#clone_addr").val();!$("#mirror").is(":checked")&&e&&e.length>0&&void 0!==t&&(t.startsWith("https://github.com")||t.startsWith("http://github.com"))?$("#migrate_items").show():$("#migrate_items").hide()})(),$("#clone_addr").on("input",q),$("#auth_username").on("input",q),$("#mirror").on("change",q),function(){var e=$(".repository.wiki textarea#edit_area");if(e.length>0){var t=new SimpleMDE({autoDownloadFontAwesome:!1,element:e[0],forceSync:!0,previewRender:function(t,a){return setTimeout((function(){$.post(e.data("url"),{_csrf:i,mode:"gfm",context:e.data("context"),text:t},(function(e){a.innerHTML='
'.concat(e,"
"),emojify.run($(".editor-preview")[0])}))}),0),"Loading..."},renderingConfig:{singleLineBreaks:!1},indentWithTabs:!1,tabSize:4,spellChecker:!1,toolbar:["bold","italic","strikethrough","|","heading-1","heading-2","heading-3","heading-bigger","heading-smaller","|",{name:"code-inline",action:function(e){var t=e.codemirror,a=t.getSelection();if(t.replaceSelection("`".concat(a,"`")),!a){var i=t.getCursor();t.setCursor(i.line,i.ch-1)}t.focus()},className:"fa fa-angle-right",title:"Add Inline Code"},"code","quote","|",{name:"checkbox-empty",action:function(e){var t=e.codemirror;t.replaceSelection("\n- [ ] ".concat(t.getSelection())),t.focus()},className:"fa fa-square-o",title:"Add Checkbox (empty)"},{name:"checkbox-checked",action:function(e){var t=e.codemirror;t.replaceSelection("\n- [x] ".concat(t.getSelection())),t.focus()},className:"fa fa-check-square-o",title:"Add Checkbox (checked)"},"|","unordered-list","ordered-list","|","link","image","table","horizontal-rule","|","clean-block","preview","fullscreen"]});$(t.codemirror.getInputField()).addClass("js-quick-submit")}}(),l(),g(),0!==$(".organization").length&&$(".organization.settings.options").length>0&&$("#org_name").keyup((function(){var e=$("#org-name-change-prompt");$(this).val().toString().toLowerCase()!==$(this).data("org-name").toString().toLowerCase()?e.show():e.hide()})),function(){if(0!==$(".new.webhook").length){$(".events.checkbox input").change((function(){$(this).is(":checked")&&$(".events.fields").show()})),$(".non-events.checkbox input").change((function(){$(this).is(":checked")&&$(".events.fields").hide()}));var e=function(){var e="POST"===$("#http_method").val();$("#content_type").parent().parent()[e?"show":"hide"]()};e(),$("#http_method").change((function(){e()})),$("#test-delivery").click((function(){var e=$(this);e.addClass("loading disabled"),$.post(e.data("link"),{_csrf:i}).done(setTimeout((function(){window.location.href=e.data("redirect")}),5e3))}))}}(),function(){if(0!==$(".admin").length){if(($(".admin.new.user").length>0||$(".admin.edit.user").length>0)&&$("#login_type").change((function(){"0"===$(this).val().substring(0,1)?($("#login_name").removeAttr("required"),$(".non-local").hide(),$(".local").show(),$("#user_name").focus(),"required"===$(this).data("password")&&$("#password").attr("required","required")):($("#login_name").attr("required","required"),$(".non-local").show(),$(".local").hide(),$("#login_name").focus(),$("#password").removeAttr("required"))})),$(".admin.new.authentication").length>0&&($("#auth_type").change((function(){$(".ldap, .dldap, .smtp, .pam, .oauth2, .has-tls .search-page-size").hide(),$(".ldap input[required], .binddnrequired input[required], .dldap input[required], .smtp input[required], .pam input[required], .oauth2 input[required], .has-tls input[required]").removeAttr("required"),$(".binddnrequired").removeClass("required");var e=$(this).val();switch(e){case"2":$(".ldap").show(),$(".binddnrequired input, .ldap div.required:not(.dldap) input").attr("required","required"),$(".binddnrequired").addClass("required");break;case"3":$(".smtp").show(),$(".has-tls").show(),$(".smtp div.required input, .has-tls").attr("required","required");break;case"4":$(".pam").show(),$(".pam input").attr("required","required");break;case"5":$(".dldap").show(),$(".dldap div.required:not(.ldap) input").attr("required","required");break;case"6":$(".oauth2").show(),$(".oauth2 div.required:not(.oauth2_use_custom_url,.oauth2_use_custom_url_field,.open_id_connect_auto_discovery_url) input").attr("required","required"),r()}"2"!==e&&"5"!==e||n(),"2"===e&&o()})),$("#auth_type").change(),$("#security_protocol").change(n),$("#use_paged_search").change(o),$("#oauth2_provider").change(r),$("#oauth2_use_custom_url").change(s)),$(".admin.edit.authentication").length>0){var e=$("#auth_type").val();"2"===e||"5"===e?($("#security_protocol").change(n),"2"===e&&$("#use_paged_search").change(o)):"6"===e&&($("#oauth2_provider").change(r),$("#oauth2_use_custom_url").change(s),r())}if($(".admin.notice")){var t=$("#detail-modal");$(".view-detail").click((function(){return t.find(".content p").text($(this).data("content")),t.modal("show"),!1}));var a=$(".select.table .ui.checkbox");$(".select.action").click((function(){switch($(this).data("action")){case"select-all":a.checkbox("check");break;case"deselect-all":a.checkbox("uncheck");break;case"inverse":a.checkbox("toggle")}})),$("#delete-selection").click((function(){var e=$(this);e.addClass("loading disabled");var t=[];a.each((function(){$(this).checkbox("is checked")&&t.push($(this).data("id"))})),$.post(e.data("link"),{_csrf:i,ids:t}).done((function(){window.location.href=e.data("redirect")}))}))}}function n(){$("#security_protocol").val()>0?$(".has-tls").show():$(".has-tls").hide()}function o(){$("#use_paged_search").prop("checked")?$(".search-page-size").show().find("input").attr("required","required"):$(".search-page-size").hide().find("input").removeAttr("required")}function r(){switch($(".open_id_connect_auto_discovery_url, .oauth2_use_custom_url").hide(),$(".open_id_connect_auto_discovery_url input[required]").removeAttr("required"),$("#oauth2_provider").val()){case"github":case"gitlab":case"gitea":$(".oauth2_use_custom_url").show();break;case"openidConnect":$(".open_id_connect_auto_discovery_url input").attr("required","required"),$(".open_id_connect_auto_discovery_url").show()}s()}function s(){var e=$("#oauth2_provider").val();if($(".oauth2_use_custom_url_field").hide(),$(".oauth2_use_custom_url_field input[required]").removeAttr("required"),$("#oauth2_use_custom_url").is(":checked"))switch($("#oauth2_token_url").val()||$("#oauth2_token_url").val($("#".concat(e,"_token_url")).val()),$("#oauth2_auth_url").val()||$("#oauth2_auth_url").val($("#".concat(e,"_auth_url")).val()),$("#oauth2_profile_url").val()||$("#oauth2_profile_url").val($("#".concat(e,"_profile_url")).val()),$("#oauth2_email_url").val()||$("#oauth2_email_url").val($("#".concat(e,"_email_url")).val()),e){case"github":$(".oauth2_token_url input, .oauth2_auth_url input, .oauth2_profile_url input, .oauth2_email_url input").attr("required","required"),$(".oauth2_token_url, .oauth2_auth_url, .oauth2_profile_url, .oauth2_email_url").show();break;case"gitea":case"gitlab":$(".oauth2_token_url input, .oauth2_auth_url input, .oauth2_profile_url input").attr("required","required"),$(".oauth2_token_url, .oauth2_auth_url, .oauth2_profile_url").show(),$("#oauth2_email_url").val("")}}}(),k(),function(){var e=document.getElementById("app");if(!e)return;Vue.component("repo-search",{delimiters:["${","}"],props:{searchLimit:{type:Number,default:10},suburl:{type:String,required:!0},uid:{type:Number,required:!0},organizations:{type:Array,default:[]},isOrganization:{type:Boolean,default:!0},canCreateOrganization:{type:Boolean,default:!1},organizationsTotalCount:{type:Number,default:0},moreReposLink:{type:String,default:""}},data:function(){return{tab:"repos",repos:[],reposTotalCount:0,reposFilter:"all",searchQuery:"",isLoading:!1,repoTypes:{all:{count:0,searchMode:""},forks:{count:0,searchMode:"fork"},mirrors:{count:0,searchMode:"mirror"},sources:{count:0,searchMode:"source"},collaborative:{count:0,searchMode:"collaborative"}}}},computed:{showMoreReposLink:function(){return this.repos.length>0&&this.repos.length'.concat(n[r],"
")).insertBefore(o);F.css("display","none"),R.show()}})).fail((function(t){if(422===t.status)if(t.responseJSON.invalidTopics.length>0){M.formatPrompt=t.responseJSON.message;var a=t.responseJSON.invalidTopics,i=z.children("a.ui.label");e.split(",").forEach((function(e,t){for(var n=0;n]*>?/gm,""),i=!1,n=[];if(z.find("div.label.visible.topic,a.label.visible").each((function(e,t){n.push(t.dataset.value)})),e.topics){for(var o=!1,r=0;r0&&!i?(t.success=!0,t.results.unshift({description:a,"data-value":a})):a.length>0&&i&&t.results.sort((function(e,t){return e.description.toLowerCase()===a.toLowerCase()?-1:t.description.toLowerCase()===a.toLowerCase()?1:e.description>t.description?-1:e.description').concat(a(n.repository.full_name),"
"),value:n.id})})),t},cache:!1},fullTextSearch:!0}),$(".menu a.label-filter-item").each((function(){$(this).click((function(e){if(e.altKey){e.preventDefault();var t=$(this).attr("href"),a=$(this).data("label-id"),i="labels=(-?[0-9]+%2c)*(".concat(a,")(%2c-?[0-9]+)*&");window.location=t.replace(new RegExp(i),"labels=$1-$2$3&")}}))})),$(".menu .ui.dropdown.label-filter").keydown((function(e){if(e.altKey&&13===e.keyCode){var t=$(".menu .ui.dropdown.label-filter .menu .item.selected");if(t.length>0){var a=$(t[0]),i=a.attr("href"),n=a.data("label-id"),o="labels=(-?[0-9]+%2c)*(".concat(n,")(%2c-?[0-9]+)*&");window.location=i.replace(new RegExp(o),"labels=$1-$2$3&")}}}))}(),$(".title_wip_desc > a").click((function(e){e.preventDefault();var t=$("#issue_title");t.focus();var a=t.val().trim().toUpperCase();for(var i in wipPrefixes)if(a.startsWith(wipPrefixes[i].toUpperCase()))return;t.val("".concat(wipPrefixes[0]," ").concat(t.val()))})),$(".show-outdated").on("click",(function(e){e.preventDefault();var t=$(this).data("comment");$(this).addClass("hide"),$("#code-comments-".concat(t)).removeClass("hide"),$("#code-preview-".concat(t)).removeClass("hide"),$("#hide-outdated-".concat(t)).removeClass("hide")})),$(".hide-outdated").on("click",(function(e){e.preventDefault();var t=$(this).data("comment");$(this).addClass("hide"),$("#code-comments-".concat(t)).addClass("hide"),$("#code-preview-".concat(t)).addClass("hide"),$("#show-outdated-".concat(t)).removeClass("hide")})),$("button.comment-form-reply").on("click",(function(e){e.preventDefault(),$(this).hide();var t=$(this).parent().find(".comment-form");t.removeClass("hide"),m(t.find(".menu"))})),0!==$(".repository.pull.diff").length&&($(".diff-detail-box.ui.sticky").sticky(),$(".btn-review").on("click",(function(e){e.preventDefault(),$(this).closest(".dropdown").find(".menu").toggle("visible")})).closest(".dropdown").find(".link.close").on("click",(function(e){e.preventDefault(),$(this).closest(".menu").toggle("visible")})),$(".code-view .lines-code,.code-view .lines-num").on("mouseenter",(function(){var e=$(this).closest("td");$(this).closest("tr").addClass(e.hasClass("lines-num-old")||e.hasClass("lines-code-old")?"focus-lines-old":"focus-lines-new")})).on("mouseleave",(function(){$(this).closest("tr").removeClass("focus-lines-new focus-lines-old")})),$(".add-code-comment").on("click",(function(e){if(!$(e.target).hasClass("btn-add-single")){e.preventDefault();var t=$(this).closest(".code-diff").hasClass("code-diff-split"),a=$(this).data("side"),i=$(this).data("idx"),n=$(this).data("path"),o=$("#pull_review_add_comment").html(),r=$(this).closest("tr"),s=r.next();s.hasClass("add-comment")||(s=$(''.concat(t?'':'',"")),r.after(s));var c=s.find(".add-comment-".concat(a)),l=c.find(".comment-code-cloud");0===l.length&&(c.html(o),m((l=c.find(".comment-code-cloud")).find(".menu")),c.find("input[name='line']").val(i),c.find("input[name='side']").val("left"===a?"previous":"proposed"),c.find("input[name='path']").val(n)),l.find("textarea").focus()}}))),function e(){var t=$("#repo_migrating");if($("#repo_migrating_failed").hide(),t){var a=t.attr("repo");if(void 0===a)return;$.ajax({type:"GET",url:"".concat(n,"/").concat(a,"/status"),data:{_csrf:i},complete:function(t){if(200===t.status&&t.responseJSON)return 0===t.responseJSON.status?void window.location.reload():void setTimeout((function(){e()}),2e3);$("#repo_migrating_progress").hide(),$("#repo_migrating_failed").show()}})}}(),function(){var e=$("#repo_template"),t=function(){var t=$("#template_units"),a=$("#non_template");""!==e.val()?(t.show(),a.hide()):(t.hide(),a.show())};e.change(t),t();var i=function(){$("#repo_template_search").dropdown({apiSettings:{url:"".concat(n,"/api/v1/repos/search?q={query}&template=true&priority_owner_id=").concat($("#uid").val()),onResponse:function(e){var t={success:!0,results:[]};return t.results.push({name:"",value:""}),$.each(e.data,(function(e,i){t.results.push({name:a(i.full_name),value:i.id})})),t},cache:!1},fullTextSearch:!0})};$("#uid").change(i),i()}(),$("#repo-clone-url").length>0)switch(localStorage.getItem("repo-clone-protocol")){case"ssh":0===$("#repo-clone-ssh").click().length&&$("#repo-clone-https").click();break;default:$("#repo-clone-https").click()}var J,V={"div.user.settings":b,"div.repository.settings.collaboration":v};for(J in V)if($(J).length>0){V[J]();break}var H=$("#clone_addr");H.change((function(){var e=$("#repo_name");H.val().length>0&&0===e.val().length&&e.val(H.val().match(/^(.*\/)?((.+?)(\.git)?)$/)[3])}))})),$((function(){0===$(".user.signin").length&&$("form:not(.ignore-dirty)").areYouSure(),$("#ssh-key-content").on("change paste keyup",(function(){var e=$(this).val().split(" "),t=$("#ssh-key-title");""===t.val()&&3===e.length&&""!==e[2]&&t.val(e[2])}))})),window.timeAddManual=function(){$(".mini.modal").modal({duration:200,onApprove:function(){$("#add_time_manual_form").submit()}}).modal("show")},window.toggleStopwatch=function(){$("#toggle_stopwatch_form").submit()},window.cancelStopwatch=function(){$("#cancel_stopwatch_form").submit()},window.initHeatmap=function(e,t,a){var i=document.getElementById(e);if(i){(a=a||{}).contributions=a.contributions||"contributions",a.no_contributions=a.no_contributions||"No contributions";var n=["${","}"];Vue.component("activity-heatmap",{delimiters:n,props:{user:{type:String,required:!0},suburl:{type:String,required:!0},locale:{type:Object,required:!0}},data:function(){return{isLoading:!0,colorRange:[],endDate:null,values:[],totalContributions:0}},mounted:function(){this.colorRange=[this.getColor(0),this.getColor(1),this.getColor(2),this.getColor(3),this.getColor(4),this.getColor(5)],this.endDate=new Date,this.loadHeatmap(this.user)},methods:{loadHeatmap:function(e){var t=this;$.get("".concat(this.suburl,"/api/v1/users/").concat(e,"/heatmap"),(function(e){for(var a=[],i=0;i

total contributions in the last 12 months

'}),new Vue({delimiters:n,el:i,data:{suburl:document.querySelector("meta[name=_suburl]").content,heatmapUser:t,locale:a}})}},$(".commit-button").click((function(e){e.preventDefault(),$(this).parent().find(".commit-body").toggle()})),window.toggleDeadlineForm=function(){$("#deadlineForm").fadeToggle(150)},window.setDeadline=function(){var e=$("#deadlineDate").val();window.updateDeadline(e)},window.updateDeadline=function(e){$("#deadline-err-invalid-date").hide(),$("#deadline-loader").addClass("loading");var t=null;if(""!==e){var a=Date.parse(e);if(Number.isNaN(a))return $("#deadline-loader").removeClass("loading"),$("#deadline-err-invalid-date").show(),!1;t=new Date(a)}$.ajax("".concat($("#update-issue-deadline-form").attr("action"),"/deadline"),{data:JSON.stringify({due_date:t}),headers:{"X-Csrf-Token":i,"X-Remote":!0},contentType:"application/json",type:"POST",success:function(){u()},error:function(){$("#deadline-loader").removeClass("loading"),$("#deadline-err-invalid-date").show()}})},window.deleteDependencyModal=function(e,t){$(".remove-dependency").modal({closable:!1,duration:200,onApprove:function(){$("#removeDependencyID").val(e),$("#dependencyType").val(t),$("#removeDependencyForm").submit()}}).modal("show")},window.cancelCodeComment=function(e){var t=$(e).closest("form");t.length>0&&t.hasClass("comment-form")?(t.addClass("hide"),t.parent().find("button.comment-form-reply").show()):t.closest(".comment-code-cloud").remove()},window.onOAuthLoginClick=function(){var e=$("#oauth2-login-loader"),t=$("#oauth2-login-navigator");t.hide(),e.removeClass("disabled"),setTimeout((function(){e.addClass("disabled"),t.show()}),5e3)}},function(e,t){$((function(){var e=[];document.getElementById("graph-canvas")&&($("#graph-raw-list li span.node-relation").each((function(){e.push($(this).text())})),gitGraph(document.getElementById("graph-canvas"),e))}))}]); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/public/js/index.js.map b/public/js/index.js.map new file mode 100644 index 00000000000..3cbf582ed58 --- /dev/null +++ b/public/js/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./web_src/js/index.js","webpack:///./web_src/js/draw.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","htmlEncode","text","jQuery","html","csrf","suburl","previewFileModes","simpleMDEditor","codeMirrorEditor","initCommentPreviewTab","$form","$tabMenu","find","tab","data","click","$this","$","this","post","_csrf","context","val","$previewPanel","emojify","run","each","hljs","highlightBlock","buttonsClickOnEnter","initEditForm","length","$previewTab","split","initEditPreviewTab","content","$diffPreviewPanel","updateIssuesMeta","url","action","issueIds","elementId","Promise","resolve","ajax","type","issue_ids","id","success","reload","window","location","initImagePaste","target","field","addEventListener","event","pasteEvent","callback","clipboardData","items","indexOf","blob","getAsFile","preventDefault","stopPropagation","retrieveImageFromClipboardAsBlob","img","substr","lastIndexOf","selectionStart","startPos","endPos","selectionEnd","substring","insertAtCursor","file","xhr","XMLHttpRequest","onload","status","responseText","open","setRequestHeader","formData","FormData","append","send","uploadFile","res","JSON","parse","oldval","newval","replace","replaceAndKeepCursor","uuid","input","initCommentForm","$selectBranch","selectedValue","css","removeClass","addClass","initListSubmits","selectItem","selector","outerSelector","$list","$noSelect","$listMenu","hasLabelUpdateAction","labels","dropdown","promises","keys","forEach","label","promise","push","all","then","hasClass","listIds","parent","join","select_id","input_id","$menu","hasUpdateAction","initRepository","$data","searchTerm","noResults","canCreateBranch","menuVisible","active","branch","tag","selected","remove","Vue","delimiters","el","beforeMount","vm","$el","getAttribute","document","body","contains","set","watch","visible","focusSearchField","computed","filteredItems","filter","item","toLowerCase","showCreateNewBranch","showNoResults","methods","prev","getSelected","href","createNewBranch","$refs","newBranchForm","submit","nextTick","searchField","focus","j","getSelectedIndexInFiltered","scrollToActive","Array","isArray","cont","scrollContainer","offsetTop","scrollTop","clientHeight","keydown","keyCode","initFilterSearchDropdown","keyup","$prompt","toString","show","hide","change","checked","$newLabelPanel","minicolors","color_hex","modal","onApprove","$datepicker","datetimepicker","lang","inline","timepicker","startDate","formatDate","onSelectDate","ct","dateFormat","$issueTitle","$editInput","editTitleToggle","toggle","title","$textarea","$segment","next","$editContentZone","$renderContent","$rawContent","issuesTribute","attach","emojiTribute","$dropzone","$files","filenameDict","dropzone","headers","maxFiles","maxFilesize","acceptedFiles","addRemoveLinks","dictDefaultMessage","dictInvalidFileType","dictFileTooBig","dictRemoveFile","init","on","submitted","getJSON","drop","removeAllFiles","empty","imgSrc","emit","files","$editContentForm","attr","$attachments","map","$content","attachments","confirm","$statusButton","$mergeButton","e","onChange","_text","_value","$choice","closest","initReactionSelector","reactions","popup","position","metadata","actionURL","done","resp","react","insertBefore","appendTo","hasEmoji","$item","addLine","delLine","addPercent","parseFloat","localStorage","setItem","select","$repoComparePull","$dropdown","fullTextSearch","selectOnKeydown","message","assingMenuAttributes","menu","Math","floor","random","initRepositoryCollaboration","uid","initEditor","prop","$editFilename","parts","$section","$divider","getCursorPosition","last","setSelectionRange","element","trigger","$editArea","markdownFileExts","lineWrapExtensions","spec","extension","extWithDot","dataUrl","apiCall","exec","info","CodeMirror","findModeByExtension","previewLink","mime","toTextArea","SimpleMDE","autoDownloadFontAwesome","forceSync","renderingConfig","singleLineBreaks","indentWithTabs","tabSize","spellChecker","previewRender","plainText","preview","setTimeout","innerHTML","toolbar","setSimpleMDE","fromTextArea","lineNumbers","cm","_change","getValue","setCodeMirror","setOption","autoLoadMode","editorconfig","indent_style","Tab","spaces","parseInt","getOption","replaceSelection","indent_size","tab_width","$commitButton","$editForm","areYouSure","silent","dirtyClass","fieldSelector","dirty","initUserSettings","keypress","initCodeView","$select","siblings","selectRange","shiftKey","eq","getSelection","removeAllRanges","selection","$first","hash","match","offset","top","$foldButton","slideUp","slideDown","insertBlobExcerpt","$blob","$row","replaceWith","u2fSigned","stringify","contentType","fail","u2fError","u2fRegistered","errorCode","checkError","errorType","u2fErrors","browser","1","2","3","4","5","u2fRegisterRequest","req","registeredKeys","u2fApi","register","appId","registerRequests","catch","reason","undefined","metaData","code","changeHash","history","pushState","$from","a","b","classes","showDeletePopup","dialog","closable","redirect","showAddAllPopup","Dropzone","autoDiscover","fn","pos","Sel","createRange","SelLength","moveStart","ready","onShow","transition","direction","accordion","checkbox","progress","showActivity","slideToggle","nodes","slice","querySelectorAll","setConfig","img_dir","ignore_emoticons","getElementsByClassName","childNodes","nodeName","$searchTeamBox","$searchRepoBox","toggleMigrations","isExpanded","mgrBtn","editDiv","viewDiv","saveBtn","topicDropdown","topicForm","topicPrompts","hidePrompt","prompts","clipboard","Clipboard","clearSelection","setAttribute","node","encodeURIComponent","wrap","children","dataset","issueIDs","issueId","_","first","search","minCharacters","apiSettings","onResponse","response","_i","login","full_name","image","avatar_url","results","searchFields","permission","description","dbType","dbDefaults","MySQL","PostgreSQL","MSSQL","_type","defaultHost","is","authUserName","cloneAddr","startsWith","simplemde","codemirror","cursorPos","getCursor","setCursor","line","ch","className","getInputField","initWikiForm","updateContentType","initWebhook","removeAttr","authType","onOAuth2Change","onSecurityProtocolChange","onUsePagedSearchChange","onOAuth2UseCustomURLChange","$detailModal","$checkboxes","ids","provider","initAdmin","getElementById","component","props","searchLimit","Number","default","String","required","organizations","isOrganization","Boolean","canCreateOrganization","organizationsTotalCount","moreReposLink","repos","reposTotalCount","reposFilter","searchQuery","isLoading","repoTypes","count","searchMode","forks","mirrors","sources","collaborative","showMoreReposLink","searchURL","repoTypeCount","mounted","searchRepos","self","changeTab","changeReposFilter","showRepo","repo","owner","mirror","fork","searchedMode","searchedURL","searchedQuery","result","_textStatus","request","getResponseHeader","always","repoClass","private","querySelector","initVueApp","ctrlKey","altKey","metaKey","countPrompt","formatPrompt","topics","_data","responseJSON","topicArray","invalidTopics","topicLables","index","form","allowAdditions","forceSelection","fields","saveRemoteData","duration","variation","blue","basic","throttle","cache","formattedResponse","query","urlData","trim","found_query","current_topics","found","topic_name","unshift","sort","onLabelCreate","contents","onAdd","addedValue","_addedText","$addedChoice","settings","rules","validateTopic","_values","regExp","identifier","prompt","ensureSupport","sign","challenge","err","allowMultiple","repolink","repoId","crossRepoSearch","issueSearchUrl","filteredResponse","currIssueId","issue","number","repository","regStr","RegExp","selectedItems","initIssueList","toUpperCase","wipPrefixes","sticky","isSplit","side","idx","path","tr","ntr","after","td","commentCloud","initRepoStatusChecker","migrating","repo_name","complete","$repoTemplate","checkTemplate","$templateUnits","$nonTemplate","changeOwner","_r","initTemplateSearch","getItem","routes","$cloneAddr","$repoName","arrays","$title","timeAddManual","toggleStopwatch","cancelStopwatch","initHeatmap","appElementId","heatmapUser","locale","contributions","no_contributions","vueDelimeters","user","colorRange","endDate","values","totalContributions","getColor","Date","loadHeatmap","userName","chartRawData","chartData","date","timestamp","createElement","appendChild","color","getComputedStyle","backgroundColor","removeChild","template","toggleDeadlineForm","fadeToggle","setDeadline","deadline","updateDeadline","deadlineString","realDeadline","newDate","isNaN","due_date","error","deleteDependencyModal","cancelCodeComment","btn","onOAuthLoginClick","oauthLoader","oauthNav","graphList","gitGraph"],"mappings":"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","file":"index.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/* globals wipPrefixes, issuesTribute, emojiTribute */\n/* exported timeAddManual, toggleStopwatch, cancelStopwatch, initHeatmap */\n/* exported toggleDeadlineForm, setDeadline, updateDeadline, deleteDependencyModal, cancelCodeComment, onOAuthLoginClick */\n\nfunction htmlEncode(text) {\n return jQuery('
').text(text).html();\n}\n\nlet csrf;\nlet suburl;\nlet previewFileModes;\nlet simpleMDEditor;\nlet codeMirrorEditor;\n\n// Disable Dropzone auto-discover because it's manually initialized\nif (typeof (Dropzone) !== 'undefined') {\n Dropzone.autoDiscover = false;\n}\n\nfunction initCommentPreviewTab($form) {\n const $tabMenu = $form.find('.tabular.menu');\n $tabMenu.find('.item').tab();\n $tabMenu.find(`.item[data-tab=\"${$tabMenu.data('preview')}\"]`).click(function () {\n const $this = $(this);\n $.post($this.data('url'), {\n _csrf: csrf,\n mode: 'gfm',\n context: $this.data('context'),\n text: $form.find(`.tab.segment[data-tab=\"${$tabMenu.data('write')}\"] textarea`).val()\n }, (data) => {\n const $previewPanel = $form.find(`.tab.segment[data-tab=\"${$tabMenu.data('preview')}\"]`);\n $previewPanel.html(data);\n emojify.run($previewPanel[0]);\n $('pre code', $previewPanel[0]).each(function () {\n hljs.highlightBlock(this);\n });\n });\n });\n\n buttonsClickOnEnter();\n}\n\nfunction initEditPreviewTab($form) {\n const $tabMenu = $form.find('.tabular.menu');\n $tabMenu.find('.item').tab();\n const $previewTab = $tabMenu.find(`.item[data-tab=\"${$tabMenu.data('preview')}\"]`);\n if ($previewTab.length) {\n previewFileModes = $previewTab.data('preview-file-modes').split(',');\n $previewTab.click(function () {\n const $this = $(this);\n $.post($this.data('url'), {\n _csrf: csrf,\n mode: 'gfm',\n context: $this.data('context'),\n text: $form.find(`.tab.segment[data-tab=\"${$tabMenu.data('write')}\"] textarea`).val()\n }, (data) => {\n const $previewPanel = $form.find(`.tab.segment[data-tab=\"${$tabMenu.data('preview')}\"]`);\n $previewPanel.html(data);\n emojify.run($previewPanel[0]);\n $('pre code', $previewPanel[0]).each(function () {\n hljs.highlightBlock(this);\n });\n });\n });\n }\n}\n\nfunction initEditDiffTab($form) {\n const $tabMenu = $form.find('.tabular.menu');\n $tabMenu.find('.item').tab();\n $tabMenu.find(`.item[data-tab=\"${$tabMenu.data('diff')}\"]`).click(function () {\n const $this = $(this);\n $.post($this.data('url'), {\n _csrf: csrf,\n context: $this.data('context'),\n content: $form.find(`.tab.segment[data-tab=\"${$tabMenu.data('write')}\"] textarea`).val()\n }, (data) => {\n const $diffPreviewPanel = $form.find(`.tab.segment[data-tab=\"${$tabMenu.data('diff')}\"]`);\n $diffPreviewPanel.html(data);\n emojify.run($diffPreviewPanel[0]);\n });\n });\n}\n\n\nfunction initEditForm() {\n if ($('.edit.form').length === 0) {\n return;\n }\n\n initEditPreviewTab($('.edit.form'));\n initEditDiffTab($('.edit.form'));\n}\n\nfunction initBranchSelector() {\n const $selectBranch = $('.ui.select-branch');\n const $branchMenu = $selectBranch.find('.reference-list-menu');\n $branchMenu.find('.item:not(.no-select)').click(function () {\n const selectedValue = $(this).data('id');\n $($(this).data('id-selector')).val(selectedValue);\n $selectBranch.find('.ui .branch-name').text(selectedValue);\n });\n $selectBranch.find('.reference.column').click(function () {\n $selectBranch.find('.scrolling.reference-list-menu').css('display', 'none');\n $selectBranch.find('.reference .text').removeClass('black');\n $($(this).data('target')).css('display', 'block');\n $(this).find('.text').addClass('black');\n return false;\n });\n}\n\nfunction updateIssuesMeta(url, action, issueIds, elementId) {\n return new Promise(((resolve) => {\n $.ajax({\n type: 'POST',\n url,\n data: {\n _csrf: csrf,\n action,\n issue_ids: issueIds,\n id: elementId\n },\n success: resolve\n });\n }));\n}\n\nfunction initRepoStatusChecker() {\n const migrating = $('#repo_migrating');\n $('#repo_migrating_failed').hide();\n if (migrating) {\n const repo_name = migrating.attr('repo');\n if (typeof repo_name === 'undefined') {\n return;\n }\n $.ajax({\n type: 'GET',\n url: `${suburl}/${repo_name}/status`,\n data: {\n _csrf: csrf,\n },\n complete(xhr) {\n if (xhr.status === 200) {\n if (xhr.responseJSON) {\n if (xhr.responseJSON.status === 0) {\n window.location.reload();\n return;\n }\n\n setTimeout(() => {\n initRepoStatusChecker();\n }, 2000);\n return;\n }\n }\n $('#repo_migrating_progress').hide();\n $('#repo_migrating_failed').show();\n }\n });\n }\n}\n\nfunction initReactionSelector(parent) {\n let reactions = '';\n if (!parent) {\n parent = $(document);\n reactions = '.reactions > ';\n }\n\n parent.find(`${reactions}a.label`).popup({ position: 'bottom left', metadata: { content: 'title', title: 'none' } });\n\n parent.find(`.select-reaction > .menu > .item, ${reactions}a.label`).on('click', function (e) {\n const vm = this;\n e.preventDefault();\n\n if ($(this).hasClass('disabled')) return;\n\n const actionURL = $(this).hasClass('item')\n ? $(this).closest('.select-reaction').data('action-url')\n : $(this).data('action-url');\n const url = `${actionURL}/${$(this).hasClass('blue') ? 'unreact' : 'react'}`;\n $.ajax({\n type: 'POST',\n url,\n data: {\n _csrf: csrf,\n content: $(this).data('content')\n }\n }).done((resp) => {\n if (resp && (resp.html || resp.empty)) {\n const content = $(vm).closest('.content');\n let react = content.find('.segment.reactions');\n if (!resp.empty && react.length > 0) {\n react.remove();\n }\n if (!resp.empty) {\n react = $('
');\n const attachments = content.find('.segment.bottom:first');\n if (attachments.length > 0) {\n react.insertBefore(attachments);\n } else {\n react.appendTo(content);\n }\n react.html(resp.html);\n const hasEmoji = react.find('.has-emoji');\n for (let i = 0; i < hasEmoji.length; i++) {\n emojify.run(hasEmoji.get(i));\n }\n react.find('.dropdown').dropdown();\n initReactionSelector(react);\n }\n }\n });\n });\n}\n\nfunction insertAtCursor(field, value) {\n if (field.selectionStart || field.selectionStart === 0) {\n const startPos = field.selectionStart;\n const endPos = field.selectionEnd;\n field.value = field.value.substring(0, startPos)\n + value\n + field.value.substring(endPos, field.value.length);\n field.selectionStart = startPos + value.length;\n field.selectionEnd = startPos + value.length;\n } else {\n field.value += value;\n }\n}\n\nfunction replaceAndKeepCursor(field, oldval, newval) {\n if (field.selectionStart || field.selectionStart === 0) {\n const startPos = field.selectionStart;\n const endPos = field.selectionEnd;\n field.value = field.value.replace(oldval, newval);\n field.selectionStart = startPos + newval.length - oldval.length;\n field.selectionEnd = endPos + newval.length - oldval.length;\n } else {\n field.value = field.value.replace(oldval, newval);\n }\n}\n\nfunction retrieveImageFromClipboardAsBlob(pasteEvent, callback) {\n if (!pasteEvent.clipboardData) {\n return;\n }\n\n const { items } = pasteEvent.clipboardData;\n if (typeof items === 'undefined') {\n return;\n }\n\n for (let i = 0; i < items.length; i++) {\n if (items[i].type.indexOf('image') === -1) continue;\n const blob = items[i].getAsFile();\n\n if (typeof (callback) === 'function') {\n pasteEvent.preventDefault();\n pasteEvent.stopPropagation();\n callback(blob);\n }\n }\n}\n\nfunction uploadFile(file, callback) {\n const xhr = new XMLHttpRequest();\n\n xhr.onload = function () {\n if (xhr.status === 200) {\n callback(xhr.responseText);\n }\n };\n\n xhr.open('post', `${suburl}/attachments`, true);\n xhr.setRequestHeader('X-Csrf-Token', csrf);\n const formData = new FormData();\n formData.append('file', file, file.name);\n xhr.send(formData);\n}\n\nfunction reload() {\n window.location.reload();\n}\n\nfunction initImagePaste(target) {\n target.each(function () {\n const field = this;\n field.addEventListener('paste', (event) => {\n retrieveImageFromClipboardAsBlob(event, (img) => {\n const name = img.name.substr(0, img.name.lastIndexOf('.'));\n insertAtCursor(field, `![${name}]()`);\n uploadFile(img, (res) => {\n const data = JSON.parse(res);\n replaceAndKeepCursor(field, `![${name}]()`, `![${name}](${suburl}/attachments/${data.uuid})`);\n const input = $(``).val(data.uuid);\n $('.files').append(input);\n });\n });\n }, false);\n });\n}\n\nfunction initCommentForm() {\n if ($('.comment.form').length === 0) {\n return;\n }\n\n initBranchSelector();\n initCommentPreviewTab($('.comment.form'));\n initImagePaste($('.comment.form textarea'));\n\n // Listsubmit\n function initListSubmits(selector, outerSelector) {\n const $list = $(`.ui.${outerSelector}.list`);\n const $noSelect = $list.find('.no-select');\n const $listMenu = $(`.${selector} .menu`);\n let hasLabelUpdateAction = $listMenu.data('action') === 'update';\n const labels = {};\n\n $(`.${selector}`).dropdown('setting', 'onHide', () => {\n hasLabelUpdateAction = $listMenu.data('action') === 'update'; // Update the var\n if (hasLabelUpdateAction) {\n const promises = [];\n Object.keys(labels).forEach((elementId) => {\n const label = labels[elementId];\n const promise = updateIssuesMeta(\n label['update-url'],\n label.action,\n label['issue-id'],\n elementId\n );\n promises.push(promise);\n });\n Promise.all(promises).then(reload);\n }\n });\n\n $listMenu.find('.item:not(.no-select)').click(function () {\n // we don't need the action attribute when updating assignees\n if (selector === 'select-assignees-modify') {\n // UI magic. We need to do this here, otherwise it would destroy the functionality of\n // adding/removing labels\n if ($(this).hasClass('checked')) {\n $(this).removeClass('checked');\n $(this).find('.octicon').removeClass('octicon-check');\n } else {\n $(this).addClass('checked');\n $(this).find('.octicon').addClass('octicon-check');\n }\n\n updateIssuesMeta(\n $listMenu.data('update-url'),\n '',\n $listMenu.data('issue-id'),\n $(this).data('id')\n );\n $listMenu.data('action', 'update'); // Update to reload the page when we updated items\n return false;\n }\n\n if ($(this).hasClass('checked')) {\n $(this).removeClass('checked');\n $(this).find('.octicon').removeClass('octicon-check');\n if (hasLabelUpdateAction) {\n if (!($(this).data('id') in labels)) {\n labels[$(this).data('id')] = {\n 'update-url': $listMenu.data('update-url'),\n action: 'detach',\n 'issue-id': $listMenu.data('issue-id'),\n };\n } else {\n delete labels[$(this).data('id')];\n }\n }\n } else {\n $(this).addClass('checked');\n $(this).find('.octicon').addClass('octicon-check');\n if (hasLabelUpdateAction) {\n if (!($(this).data('id') in labels)) {\n labels[$(this).data('id')] = {\n 'update-url': $listMenu.data('update-url'),\n action: 'attach',\n 'issue-id': $listMenu.data('issue-id'),\n };\n } else {\n delete labels[$(this).data('id')];\n }\n }\n }\n\n const listIds = [];\n $(this).parent().find('.item').each(function () {\n if ($(this).hasClass('checked')) {\n listIds.push($(this).data('id'));\n $($(this).data('id-selector')).removeClass('hide');\n } else {\n $($(this).data('id-selector')).addClass('hide');\n }\n });\n if (listIds.length === 0) {\n $noSelect.removeClass('hide');\n } else {\n $noSelect.addClass('hide');\n }\n $($(this).parent().data('id')).val(listIds.join(','));\n return false;\n });\n $listMenu.find('.no-select.item').click(function () {\n if (hasLabelUpdateAction || selector === 'select-assignees-modify') {\n updateIssuesMeta(\n $listMenu.data('update-url'),\n 'clear',\n $listMenu.data('issue-id'),\n ''\n ).then(reload);\n }\n\n $(this).parent().find('.item').each(function () {\n $(this).removeClass('checked');\n $(this).find('.octicon').removeClass('octicon-check');\n });\n\n $list.find('.item').each(function () {\n $(this).addClass('hide');\n });\n $noSelect.removeClass('hide');\n $($(this).parent().data('id')).val('');\n });\n }\n\n // Init labels and assignees\n initListSubmits('select-label', 'labels');\n initListSubmits('select-assignees', 'assignees');\n initListSubmits('select-assignees-modify', 'assignees');\n\n function selectItem(select_id, input_id) {\n const $menu = $(`${select_id} .menu`);\n const $list = $(`.ui${select_id}.list`);\n const hasUpdateAction = $menu.data('action') === 'update';\n\n $menu.find('.item:not(.no-select)').click(function () {\n $(this).parent().find('.item').each(function () {\n $(this).removeClass('selected active');\n });\n\n $(this).addClass('selected active');\n if (hasUpdateAction) {\n updateIssuesMeta(\n $menu.data('update-url'),\n '',\n $menu.data('issue-id'),\n $(this).data('id')\n ).then(reload);\n }\n switch (input_id) {\n case '#milestone_id':\n $list.find('.selected').html(`${\n htmlEncode($(this).text())}`);\n break;\n case '#assignee_id':\n $list.find('.selected').html(``\n + `${\n htmlEncode($(this).text())}`);\n }\n $(`.ui${select_id}.list .no-select`).addClass('hide');\n $(input_id).val($(this).data('id'));\n });\n $menu.find('.no-select.item').click(function () {\n $(this).parent().find('.item:not(.no-select)').each(function () {\n $(this).removeClass('selected active');\n });\n\n if (hasUpdateAction) {\n updateIssuesMeta(\n $menu.data('update-url'),\n '',\n $menu.data('issue-id'),\n $(this).data('id')\n ).then(reload);\n }\n\n $list.find('.selected').html('');\n $list.find('.no-select').removeClass('hide');\n $(input_id).val('');\n });\n }\n\n // Milestone and assignee\n selectItem('.select-milestone', '#milestone_id');\n selectItem('.select-assignee', '#assignee_id');\n}\n\nfunction initInstall() {\n if ($('.install').length === 0) {\n return;\n }\n\n if ($('#db_host').val() === '') {\n $('#db_host').val('127.0.0.1:3306');\n $('#db_user').val('gitea');\n $('#db_name').val('gitea');\n }\n\n // Database type change detection.\n $('#db_type').change(function () {\n const sqliteDefault = 'data/gitea.db';\n const tidbDefault = 'data/gitea_tidb';\n\n const dbType = $(this).val();\n if (dbType === 'SQLite3') {\n $('#sql_settings').hide();\n $('#pgsql_settings').hide();\n $('#mysql_settings').hide();\n $('#sqlite_settings').show();\n\n if (dbType === 'SQLite3' && $('#db_path').val() === tidbDefault) {\n $('#db_path').val(sqliteDefault);\n }\n return;\n }\n\n const dbDefaults = {\n MySQL: '127.0.0.1:3306',\n PostgreSQL: '127.0.0.1:5432',\n MSSQL: '127.0.0.1:1433'\n };\n\n $('#sqlite_settings').hide();\n $('#sql_settings').show();\n\n $('#pgsql_settings').toggle(dbType === 'PostgreSQL');\n $('#mysql_settings').toggle(dbType === 'MySQL');\n $.each(dbDefaults, (_type, defaultHost) => {\n if ($('#db_host').val() === defaultHost) {\n $('#db_host').val(dbDefaults[dbType]);\n return false;\n }\n });\n });\n\n // TODO: better handling of exclusive relations.\n $('#offline-mode input').change(function () {\n if ($(this).is(':checked')) {\n $('#disable-gravatar').checkbox('check');\n $('#federated-avatar-lookup').checkbox('uncheck');\n }\n });\n $('#disable-gravatar input').change(function () {\n if ($(this).is(':checked')) {\n $('#federated-avatar-lookup').checkbox('uncheck');\n } else {\n $('#offline-mode').checkbox('uncheck');\n }\n });\n $('#federated-avatar-lookup input').change(function () {\n if ($(this).is(':checked')) {\n $('#disable-gravatar').checkbox('uncheck');\n $('#offline-mode').checkbox('uncheck');\n }\n });\n $('#enable-openid-signin input').change(function () {\n if ($(this).is(':checked')) {\n if (!$('#disable-registration input').is(':checked')) {\n $('#enable-openid-signup').checkbox('check');\n }\n } else {\n $('#enable-openid-signup').checkbox('uncheck');\n }\n });\n $('#disable-registration input').change(function () {\n if ($(this).is(':checked')) {\n $('#enable-captcha').checkbox('uncheck');\n $('#enable-openid-signup').checkbox('uncheck');\n } else {\n $('#enable-openid-signup').checkbox('check');\n }\n });\n $('#enable-captcha input').change(function () {\n if ($(this).is(':checked')) {\n $('#disable-registration').checkbox('uncheck');\n }\n });\n}\n\nfunction initRepository() {\n if ($('.repository').length === 0) {\n return;\n }\n\n function initFilterSearchDropdown(selector) {\n const $dropdown = $(selector);\n $dropdown.dropdown({\n fullTextSearch: true,\n selectOnKeydown: false,\n onChange(_text, _value, $choice) {\n if ($choice.data('url')) {\n window.location.href = $choice.data('url');\n }\n },\n message: { noResults: $dropdown.data('no-results') }\n });\n }\n\n // File list and commits\n if ($('.repository.file.list').length > 0 || ('.repository.commits').length > 0) {\n initFilterBranchTagDropdown('.choose.reference .dropdown');\n }\n\n // Wiki\n if ($('.repository.wiki.view').length > 0) {\n initFilterSearchDropdown('.choose.page .dropdown');\n }\n\n // Options\n if ($('.repository.settings.options').length > 0) {\n $('#repo_name').keyup(function () {\n const $prompt = $('#repo-name-change-prompt');\n if ($(this).val().toString().toLowerCase() !== $(this).data('name').toString().toLowerCase()) {\n $prompt.show();\n } else {\n $prompt.hide();\n }\n });\n\n // Enable or select internal/external wiki system and issue tracker.\n $('.enable-system').change(function () {\n if (this.checked) {\n $($(this).data('target')).removeClass('disabled');\n if (!$(this).data('context')) $($(this).data('context')).addClass('disabled');\n } else {\n $($(this).data('target')).addClass('disabled');\n if (!$(this).data('context')) $($(this).data('context')).removeClass('disabled');\n }\n });\n $('.enable-system-radio').change(function () {\n if (this.value === 'false') {\n $($(this).data('target')).addClass('disabled');\n if (typeof $(this).data('context') !== 'undefined') $($(this).data('context')).removeClass('disabled');\n } else if (this.value === 'true') {\n $($(this).data('target')).removeClass('disabled');\n if (typeof $(this).data('context') !== 'undefined') $($(this).data('context')).addClass('disabled');\n }\n });\n }\n\n // Labels\n if ($('.repository.labels').length > 0) {\n // Create label\n const $newLabelPanel = $('.new-label.segment');\n $('.new-label.button').click(() => {\n $newLabelPanel.show();\n });\n $('.new-label.segment .cancel').click(() => {\n $newLabelPanel.hide();\n });\n\n $('.color-picker').each(function () {\n $(this).minicolors();\n });\n $('.precolors .color').click(function () {\n const color_hex = $(this).data('color-hex');\n $('.color-picker').val(color_hex);\n $('.minicolors-swatch-color').css('background-color', color_hex);\n });\n $('.edit-label-button').click(function () {\n $('#label-modal-id').val($(this).data('id'));\n $('.edit-label .new-label-input').val($(this).data('title'));\n $('.edit-label .new-label-desc-input').val($(this).data('description'));\n $('.edit-label .color-picker').val($(this).data('color'));\n $('.minicolors-swatch-color').css('background-color', $(this).data('color'));\n $('.edit-label.modal').modal({\n onApprove() {\n $('.edit-label.form').submit();\n }\n }).modal('show');\n return false;\n });\n }\n\n // Milestones\n if ($('.repository.new.milestone').length > 0) {\n const $datepicker = $('.milestone.datepicker');\n $datepicker.datetimepicker({\n lang: $datepicker.data('lang'),\n inline: true,\n timepicker: false,\n startDate: $datepicker.data('start-date'),\n formatDate: 'Y-m-d',\n onSelectDate(ct) {\n $('#deadline').val(ct.dateFormat('Y-m-d'));\n }\n });\n $('#clear-date').click(() => {\n $('#deadline').val('');\n return false;\n });\n }\n\n // Issues\n if ($('.repository.view.issue').length > 0) {\n // Edit issue title\n const $issueTitle = $('#issue-title');\n const $editInput = $('#edit-title-input input');\n const editTitleToggle = function () {\n $issueTitle.toggle();\n $('.not-in-edit').toggle();\n $('#edit-title-input').toggle();\n $('.in-edit').toggle();\n $editInput.focus();\n return false;\n };\n $('#edit-title').click(editTitleToggle);\n $('#cancel-edit-title').click(editTitleToggle);\n $('#save-edit-title').click(editTitleToggle).click(function () {\n if ($editInput.val().length === 0 || $editInput.val() === $issueTitle.text()) {\n $editInput.val($issueTitle.text());\n return false;\n }\n\n $.post($(this).data('update-url'), {\n _csrf: csrf,\n title: $editInput.val()\n },\n (data) => {\n $editInput.val(data.title);\n $issueTitle.text(data.title);\n reload();\n });\n return false;\n });\n\n // Edit issue or comment content\n $('.edit-content').click(function () {\n const $segment = $(this).parent().parent().parent()\n .next();\n const $editContentZone = $segment.find('.edit-content-zone');\n const $renderContent = $segment.find('.render-content');\n const $rawContent = $segment.find('.raw-content');\n let $textarea;\n\n // Setup new form\n if ($editContentZone.html().length === 0) {\n $editContentZone.html($('#edit-content-form').html());\n $textarea = $editContentZone.find('textarea');\n issuesTribute.attach($textarea.get());\n emojiTribute.attach($textarea.get());\n\n const $dropzone = $editContentZone.find('.dropzone');\n $dropzone.data('saved', false);\n const $files = $editContentZone.find('.comment-files');\n if ($dropzone.length > 0) {\n const filenameDict = {};\n $dropzone.dropzone({\n url: $dropzone.data('upload-url'),\n headers: { 'X-Csrf-Token': csrf },\n maxFiles: $dropzone.data('max-file'),\n maxFilesize: $dropzone.data('max-size'),\n acceptedFiles: ($dropzone.data('accepts') === '*/*') ? null : $dropzone.data('accepts'),\n addRemoveLinks: true,\n dictDefaultMessage: $dropzone.data('default-message'),\n dictInvalidFileType: $dropzone.data('invalid-input-type'),\n dictFileTooBig: $dropzone.data('file-too-big'),\n dictRemoveFile: $dropzone.data('remove-file'),\n init() {\n this.on('success', (file, data) => {\n filenameDict[file.name] = {\n uuid: data.uuid,\n submitted: false\n };\n const input = $(``).val(data.uuid);\n $files.append(input);\n });\n this.on('removedfile', (file) => {\n if (!(file.name in filenameDict)) {\n return;\n }\n $(`#${filenameDict[file.name].uuid}`).remove();\n if ($dropzone.data('remove-url') && $dropzone.data('csrf') && !filenameDict[file.name].submitted) {\n $.post($dropzone.data('remove-url'), {\n file: filenameDict[file.name].uuid,\n _csrf: $dropzone.data('csrf')\n });\n }\n });\n this.on('submit', () => {\n $.each(filenameDict, (name) => {\n filenameDict[name].submitted = true;\n });\n });\n this.on('reload', () => {\n $.getJSON($editContentZone.data('attachment-url'), (data) => {\n const drop = $dropzone.get(0).dropzone;\n drop.removeAllFiles(true);\n $files.empty();\n $.each(data, function () {\n const imgSrc = `${$dropzone.data('upload-url')}/${this.uuid}`;\n drop.emit('addedfile', this);\n drop.emit('thumbnail', this, imgSrc);\n drop.emit('complete', this);\n drop.files.push(this);\n filenameDict[this.name] = {\n submitted: true,\n uuid: this.uuid\n };\n $dropzone.find(`img[src='${imgSrc}']`).css('max-width', '100%');\n const input = $(``).val(this.uuid);\n $files.append(input);\n });\n });\n });\n }\n });\n $dropzone.get(0).dropzone.emit('reload');\n }\n // Give new write/preview data-tab name to distinguish from others\n const $editContentForm = $editContentZone.find('.ui.comment.form');\n const $tabMenu = $editContentForm.find('.tabular.menu');\n $tabMenu.attr('data-write', $editContentZone.data('write'));\n $tabMenu.attr('data-preview', $editContentZone.data('preview'));\n $tabMenu.find('.write.item').attr('data-tab', $editContentZone.data('write'));\n $tabMenu.find('.preview.item').attr('data-tab', $editContentZone.data('preview'));\n $editContentForm.find('.write.segment').attr('data-tab', $editContentZone.data('write'));\n $editContentForm.find('.preview.segment').attr('data-tab', $editContentZone.data('preview'));\n\n initCommentPreviewTab($editContentForm);\n\n $editContentZone.find('.cancel.button').click(() => {\n $renderContent.show();\n $editContentZone.hide();\n $dropzone.get(0).dropzone.emit('reload');\n });\n $editContentZone.find('.save.button').click(() => {\n $renderContent.show();\n $editContentZone.hide();\n const $attachments = $files.find('[name=files]').map(function () {\n return $(this).val();\n }).get();\n $.post($editContentZone.data('update-url'), {\n _csrf: csrf,\n content: $textarea.val(),\n context: $editContentZone.data('context'),\n files: $attachments\n }, (data) => {\n if (data.length === 0) {\n $renderContent.html($('#no-content').html());\n } else {\n $renderContent.html(data.content);\n emojify.run($renderContent[0]);\n $('pre code', $renderContent[0]).each(function () {\n hljs.highlightBlock(this);\n });\n }\n const $content = $segment.parent();\n if (!$content.find('.ui.small.images').length) {\n if (data.attachments !== '') {\n $content.append(\n '
'\n );\n $content.find('.ui.small.images').html(data.attachments);\n }\n } else if (data.attachments === '') {\n $content.find('.ui.small.images').parent().remove();\n } else {\n $content.find('.ui.small.images').html(data.attachments);\n }\n $dropzone.get(0).dropzone.emit('submit');\n $dropzone.get(0).dropzone.emit('reload');\n });\n });\n } else {\n $textarea = $segment.find('textarea');\n }\n\n // Show write/preview tab and copy raw content as needed\n $editContentZone.show();\n $renderContent.hide();\n if ($textarea.val().length === 0) {\n $textarea.val($rawContent.text());\n }\n $textarea.focus();\n return false;\n });\n\n // Delete comment\n $('.delete-comment').click(function () {\n const $this = $(this);\n if (window.confirm($this.data('locale'))) {\n $.post($this.data('url'), {\n _csrf: csrf\n }).success(() => {\n $(`#${$this.data('comment-id')}`).remove();\n });\n }\n return false;\n });\n\n // Change status\n const $statusButton = $('#status-button');\n $('#comment-form .edit_area').keyup(function () {\n if ($(this).val().length === 0) {\n $statusButton.text($statusButton.data('status'));\n } else {\n $statusButton.text($statusButton.data('status-and-comment'));\n }\n });\n $statusButton.click(() => {\n $('#status').val($statusButton.data('status-val'));\n $('#comment-form').submit();\n });\n\n // Pull Request merge button\n const $mergeButton = $('.merge-button > button');\n $mergeButton.on('click', function (e) {\n e.preventDefault();\n $(`.${$(this).data('do')}-fields`).show();\n $(this).parent().hide();\n });\n $('.merge-button > .dropdown').dropdown({\n onChange(_text, _value, $choice) {\n if ($choice.data('do')) {\n $mergeButton.find('.button-text').text($choice.text());\n $mergeButton.data('do', $choice.data('do'));\n }\n }\n });\n $('.merge-cancel').on('click', function (e) {\n e.preventDefault();\n $(this).closest('.form').hide();\n $mergeButton.parent().show();\n });\n\n initReactionSelector();\n }\n\n // Diff\n if ($('.repository.diff').length > 0) {\n $('.diff-counter').each(function () {\n const $item = $(this);\n const addLine = $item.find('span[data-line].add').data('line');\n const delLine = $item.find('span[data-line].del').data('line');\n const addPercent = parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine)) * 100;\n $item.find('.bar .add').css('width', `${addPercent}%`);\n });\n }\n\n // Quick start and repository home\n $('#repo-clone-ssh').click(function () {\n $('.clone-url').text($(this).data('link'));\n $('#repo-clone-url').val($(this).data('link'));\n $(this).addClass('blue');\n $('#repo-clone-https').removeClass('blue');\n localStorage.setItem('repo-clone-protocol', 'ssh');\n });\n $('#repo-clone-https').click(function () {\n $('.clone-url').text($(this).data('link'));\n $('#repo-clone-url').val($(this).data('link'));\n $(this).addClass('blue');\n $('#repo-clone-ssh').removeClass('blue');\n localStorage.setItem('repo-clone-protocol', 'https');\n });\n $('#repo-clone-url').click(function () {\n $(this).select();\n });\n\n // Pull request\n const $repoComparePull = $('.repository.compare.pull');\n if ($repoComparePull.length > 0) {\n initFilterSearchDropdown('.choose.branch .dropdown');\n // show pull request form\n $repoComparePull.find('button.show-form').on('click', function (e) {\n e.preventDefault();\n $repoComparePull.find('.pullrequest-form').show();\n $(this).parent().hide();\n });\n }\n\n // Branches\n if ($('.repository.settings.branches').length > 0) {\n initFilterSearchDropdown('.protected-branches .dropdown');\n $('.enable-protection, .enable-whitelist').change(function () {\n if (this.checked) {\n $($(this).data('target')).removeClass('disabled');\n } else {\n $($(this).data('target')).addClass('disabled');\n }\n });\n }\n}\n\nfunction initMigration() {\n const toggleMigrations = function () {\n const authUserName = $('#auth_username').val();\n const cloneAddr = $('#clone_addr').val();\n if (!$('#mirror').is(':checked') && (authUserName && authUserName.length > 0)\n && (cloneAddr !== undefined && (cloneAddr.startsWith('https://github.com') || cloneAddr.startsWith('http://github.com')))) {\n $('#migrate_items').show();\n } else {\n $('#migrate_items').hide();\n }\n };\n\n toggleMigrations();\n\n $('#clone_addr').on('input', toggleMigrations);\n $('#auth_username').on('input', toggleMigrations);\n $('#mirror').on('change', toggleMigrations);\n}\n\nfunction initPullRequestReview() {\n $('.show-outdated').on('click', function (e) {\n e.preventDefault();\n const id = $(this).data('comment');\n $(this).addClass('hide');\n $(`#code-comments-${id}`).removeClass('hide');\n $(`#code-preview-${id}`).removeClass('hide');\n $(`#hide-outdated-${id}`).removeClass('hide');\n });\n\n $('.hide-outdated').on('click', function (e) {\n e.preventDefault();\n const id = $(this).data('comment');\n $(this).addClass('hide');\n $(`#code-comments-${id}`).addClass('hide');\n $(`#code-preview-${id}`).addClass('hide');\n $(`#show-outdated-${id}`).removeClass('hide');\n });\n\n $('button.comment-form-reply').on('click', function (e) {\n e.preventDefault();\n $(this).hide();\n const form = $(this).parent().find('.comment-form');\n form.removeClass('hide');\n assingMenuAttributes(form.find('.menu'));\n });\n // The following part is only for diff views\n if ($('.repository.pull.diff').length === 0) {\n return;\n }\n\n $('.diff-detail-box.ui.sticky').sticky();\n\n $('.btn-review').on('click', function (e) {\n e.preventDefault();\n $(this).closest('.dropdown').find('.menu').toggle('visible');\n }).closest('.dropdown').find('.link.close')\n .on('click', function (e) {\n e.preventDefault();\n $(this).closest('.menu').toggle('visible');\n });\n\n $('.code-view .lines-code,.code-view .lines-num')\n .on('mouseenter', function () {\n const parent = $(this).closest('td');\n $(this).closest('tr').addClass(\n parent.hasClass('lines-num-old') || parent.hasClass('lines-code-old')\n ? 'focus-lines-old' : 'focus-lines-new'\n );\n })\n .on('mouseleave', function () {\n $(this).closest('tr').removeClass('focus-lines-new focus-lines-old');\n });\n $('.add-code-comment').on('click', function (e) {\n // https://github.com/go-gitea/gitea/issues/4745\n if ($(e.target).hasClass('btn-add-single')) {\n return;\n }\n e.preventDefault();\n const isSplit = $(this).closest('.code-diff').hasClass('code-diff-split');\n const side = $(this).data('side');\n const idx = $(this).data('idx');\n const path = $(this).data('path');\n const form = $('#pull_review_add_comment').html();\n const tr = $(this).closest('tr');\n let ntr = tr.next();\n if (!ntr.hasClass('add-comment')) {\n ntr = $(`${\n isSplit ? ''\n : ''\n }`);\n tr.after(ntr);\n }\n const td = ntr.find(`.add-comment-${side}`);\n let commentCloud = td.find('.comment-code-cloud');\n if (commentCloud.length === 0) {\n td.html(form);\n commentCloud = td.find('.comment-code-cloud');\n assingMenuAttributes(commentCloud.find('.menu'));\n\n td.find(\"input[name='line']\").val(idx);\n td.find(\"input[name='side']\").val(side === 'left' ? 'previous' : 'proposed');\n td.find(\"input[name='path']\").val(path);\n }\n commentCloud.find('textarea').focus();\n });\n}\n\nfunction assingMenuAttributes(menu) {\n const id = Math.floor(Math.random() * Math.floor(1000000));\n menu.attr('data-write', menu.attr('data-write') + id);\n menu.attr('data-preview', menu.attr('data-preview') + id);\n menu.find('.item').each(function () {\n const tab = $(this).attr('data-tab') + id;\n $(this).attr('data-tab', tab);\n });\n menu.parent().find(\"*[data-tab='write']\").attr('data-tab', `write${id}`);\n menu.parent().find(\"*[data-tab='preview']\").attr('data-tab', `preview${id}`);\n initCommentPreviewTab(menu.parent('.form'));\n return id;\n}\n\nfunction initRepositoryCollaboration() {\n // Change collaborator access mode\n $('.access-mode.menu .item').click(function () {\n const $menu = $(this).parent();\n $.post($menu.data('url'), {\n _csrf: csrf,\n uid: $menu.data('uid'),\n mode: $(this).data('value')\n });\n });\n}\n\nfunction initTeamSettings() {\n // Change team access mode\n $('.organization.new.team input[name=permission]').change(() => {\n const val = $('input[name=permission]:checked', '.organization.new.team').val();\n if (val === 'admin') {\n $('.organization.new.team .team-units').hide();\n } else {\n $('.organization.new.team .team-units').show();\n }\n });\n}\n\nfunction initWikiForm() {\n const $editArea = $('.repository.wiki textarea#edit_area');\n if ($editArea.length > 0) {\n const simplemde = new SimpleMDE({\n autoDownloadFontAwesome: false,\n element: $editArea[0],\n forceSync: true,\n previewRender(plainText, preview) { // Async method\n setTimeout(() => {\n // FIXME: still send render request when return back to edit mode\n $.post($editArea.data('url'), {\n _csrf: csrf,\n mode: 'gfm',\n context: $editArea.data('context'),\n text: plainText\n }, (data) => {\n preview.innerHTML = `
${data}
`;\n emojify.run($('.editor-preview')[0]);\n });\n }, 0);\n\n return 'Loading...';\n },\n renderingConfig: {\n singleLineBreaks: false\n },\n indentWithTabs: false,\n tabSize: 4,\n spellChecker: false,\n toolbar: ['bold', 'italic', 'strikethrough', '|',\n 'heading-1', 'heading-2', 'heading-3', 'heading-bigger', 'heading-smaller', '|',\n {\n name: 'code-inline',\n action(e) {\n const cm = e.codemirror;\n const selection = cm.getSelection();\n cm.replaceSelection(`\\`${selection}\\``);\n if (!selection) {\n const cursorPos = cm.getCursor();\n cm.setCursor(cursorPos.line, cursorPos.ch - 1);\n }\n cm.focus();\n },\n className: 'fa fa-angle-right',\n title: 'Add Inline Code',\n }, 'code', 'quote', '|', {\n name: 'checkbox-empty',\n action(e) {\n const cm = e.codemirror;\n cm.replaceSelection(`\\n- [ ] ${cm.getSelection()}`);\n cm.focus();\n },\n className: 'fa fa-square-o',\n title: 'Add Checkbox (empty)',\n },\n {\n name: 'checkbox-checked',\n action(e) {\n const cm = e.codemirror;\n cm.replaceSelection(`\\n- [x] ${cm.getSelection()}`);\n cm.focus();\n },\n className: 'fa fa-check-square-o',\n title: 'Add Checkbox (checked)',\n }, '|',\n 'unordered-list', 'ordered-list', '|',\n 'link', 'image', 'table', 'horizontal-rule', '|',\n 'clean-block', 'preview', 'fullscreen']\n });\n $(simplemde.codemirror.getInputField()).addClass('js-quick-submit');\n }\n}\n\n// Adding function to get the cursor position in a text field to jQuery object.\n$.fn.getCursorPosition = function () {\n const el = $(this).get(0);\n let pos = 0;\n if ('selectionStart' in el) {\n pos = el.selectionStart;\n } else if ('selection' in document) {\n el.focus();\n const Sel = document.selection.createRange();\n const SelLength = document.selection.createRange().text.length;\n Sel.moveStart('character', -el.value.length);\n pos = Sel.text.length - SelLength;\n }\n return pos;\n};\n\nfunction setSimpleMDE($editArea) {\n if (codeMirrorEditor) {\n codeMirrorEditor.toTextArea();\n codeMirrorEditor = null;\n }\n\n if (simpleMDEditor) {\n return true;\n }\n\n simpleMDEditor = new SimpleMDE({\n autoDownloadFontAwesome: false,\n element: $editArea[0],\n forceSync: true,\n renderingConfig: {\n singleLineBreaks: false\n },\n indentWithTabs: false,\n tabSize: 4,\n spellChecker: false,\n previewRender(plainText, preview) { // Async method\n setTimeout(() => {\n // FIXME: still send render request when return back to edit mode\n $.post($editArea.data('url'), {\n _csrf: csrf,\n mode: 'gfm',\n context: $editArea.data('context'),\n text: plainText\n },\n (data) => {\n preview.innerHTML = `
${data}
`;\n emojify.run($('.editor-preview')[0]);\n });\n }, 0);\n\n return 'Loading...';\n },\n toolbar: ['bold', 'italic', 'strikethrough', '|',\n 'heading-1', 'heading-2', 'heading-3', 'heading-bigger', 'heading-smaller', '|',\n 'code', 'quote', '|',\n 'unordered-list', 'ordered-list', '|',\n 'link', 'image', 'table', 'horizontal-rule', '|',\n 'clean-block', 'preview', 'fullscreen', 'side-by-side']\n });\n\n return true;\n}\n\nfunction setCodeMirror($editArea) {\n if (simpleMDEditor) {\n simpleMDEditor.toTextArea();\n simpleMDEditor = null;\n }\n\n if (codeMirrorEditor) {\n return true;\n }\n\n codeMirrorEditor = CodeMirror.fromTextArea($editArea[0], {\n lineNumbers: true\n });\n codeMirrorEditor.on('change', (cm, _change) => {\n $editArea.val(cm.getValue());\n });\n\n return true;\n}\n\nfunction initEditor() {\n $('.js-quick-pull-choice-option').change(function () {\n if ($(this).val() === 'commit-to-new-branch') {\n $('.quick-pull-branch-name').show();\n $('.quick-pull-branch-name input').prop('required', true);\n } else {\n $('.quick-pull-branch-name').hide();\n $('.quick-pull-branch-name input').prop('required', false);\n }\n $('#commit-button').text($(this).attr('button_text'));\n });\n\n const $editFilename = $('#file-name');\n $editFilename.keyup(function (e) {\n const $section = $('.breadcrumb span.section');\n const $divider = $('.breadcrumb div.divider');\n let value;\n let parts;\n\n if (e.keyCode === 8) {\n if ($(this).getCursorPosition() === 0) {\n if ($section.length > 0) {\n value = $section.last().find('a').text();\n $(this).val(value + $(this).val());\n $(this)[0].setSelectionRange(value.length, value.length);\n $section.last().remove();\n $divider.last().remove();\n }\n }\n }\n if (e.keyCode === 191) {\n parts = $(this).val().split('/');\n for (let i = 0; i < parts.length; ++i) {\n value = parts[i];\n if (i < parts.length - 1) {\n if (value.length) {\n $(`${value}`).insertBefore($(this));\n $('
/
').insertBefore($(this));\n }\n } else {\n $(this).val(value);\n }\n $(this)[0].setSelectionRange(0, 0);\n }\n }\n parts = [];\n $('.breadcrumb span.section').each(function () {\n const element = $(this);\n if (element.find('a').length) {\n parts.push(element.find('a').text());\n } else {\n parts.push(element.text());\n }\n });\n if ($(this).val()) parts.push($(this).val());\n $('#tree_path').val(parts.join('/'));\n }).trigger('keyup');\n\n const $editArea = $('.repository.editor textarea#edit_area');\n if (!$editArea.length) return;\n\n const markdownFileExts = $editArea.data('markdown-file-exts').split(',');\n const lineWrapExtensions = $editArea.data('line-wrap-extensions').split(',');\n\n $editFilename.on('keyup', () => {\n const val = $editFilename.val();\n let mode, spec, extension, extWithDot, dataUrl, apiCall;\n\n extension = extWithDot = '';\n const m = /.+\\.([^.]+)$/.exec(val);\n if (m) {\n extension = m[1];\n extWithDot = `.${extension}`;\n }\n\n const info = CodeMirror.findModeByExtension(extension);\n const previewLink = $('a[data-tab=preview]');\n if (info) {\n mode = info.mode;\n spec = info.mime;\n apiCall = mode;\n } else {\n apiCall = extension;\n }\n\n if (previewLink.length && apiCall && previewFileModes && previewFileModes.length && previewFileModes.indexOf(apiCall) >= 0) {\n dataUrl = previewLink.data('url');\n previewLink.data('url', dataUrl.replace(/(.*)\\/.*/i, `$1/${mode}`));\n previewLink.show();\n } else {\n previewLink.hide();\n }\n\n // If this file is a Markdown extensions, we will load that editor and return\n if (markdownFileExts.indexOf(extWithDot) >= 0) {\n if (setSimpleMDE($editArea)) {\n return;\n }\n }\n\n // Else we are going to use CodeMirror\n if (!codeMirrorEditor && !setCodeMirror($editArea)) {\n return;\n }\n\n if (mode) {\n codeMirrorEditor.setOption('mode', spec);\n CodeMirror.autoLoadMode(codeMirrorEditor, mode);\n }\n\n if (lineWrapExtensions.indexOf(extWithDot) >= 0) {\n codeMirrorEditor.setOption('lineWrapping', true);\n } else {\n codeMirrorEditor.setOption('lineWrapping', false);\n }\n\n // get the filename without any folder\n let value = $editFilename.val();\n if (value.length === 0) {\n return;\n }\n value = value.split('/');\n value = value[value.length - 1];\n\n $.getJSON($editFilename.data('ec-url-prefix') + value, (editorconfig) => {\n if (editorconfig.indent_style === 'tab') {\n codeMirrorEditor.setOption('indentWithTabs', true);\n codeMirrorEditor.setOption('extraKeys', {});\n } else {\n codeMirrorEditor.setOption('indentWithTabs', false);\n // required because CodeMirror doesn't seems to use spaces correctly for {\"indentWithTabs\": false}:\n // - https://github.com/codemirror/CodeMirror/issues/988\n // - https://codemirror.net/doc/manual.html#keymaps\n codeMirrorEditor.setOption('extraKeys', {\n Tab(cm) {\n const spaces = Array(parseInt(cm.getOption('indentUnit')) + 1).join(' ');\n cm.replaceSelection(spaces);\n }\n });\n }\n codeMirrorEditor.setOption('indentUnit', editorconfig.indent_size || 4);\n codeMirrorEditor.setOption('tabSize', editorconfig.tab_width || 4);\n });\n }).trigger('keyup');\n\n // Using events from https://github.com/codedance/jquery.AreYouSure#advanced-usage\n // to enable or disable the commit button\n const $commitButton = $('#commit-button');\n const $editForm = $('.ui.edit.form');\n const dirtyFileClass = 'dirty-file';\n\n // Disabling the button at the start\n $commitButton.prop('disabled', true);\n\n // Registering a custom listener for the file path and the file content\n $editForm.areYouSure({\n silent: true,\n dirtyClass: dirtyFileClass,\n fieldSelector: ':input:not(.commit-form-wrapper :input)',\n change() {\n const dirty = $(this).hasClass(dirtyFileClass);\n $commitButton.prop('disabled', !dirty);\n }\n });\n\n $commitButton.click((event) => {\n // A modal which asks if an empty file should be committed\n if ($editArea.val().length === 0) {\n $('#edit-empty-content-modal').modal({\n onApprove() {\n $('.edit.form').submit();\n }\n }).modal('show');\n event.preventDefault();\n }\n });\n}\n\nfunction initOrganization() {\n if ($('.organization').length === 0) {\n return;\n }\n\n // Options\n if ($('.organization.settings.options').length > 0) {\n $('#org_name').keyup(function () {\n const $prompt = $('#org-name-change-prompt');\n if ($(this).val().toString().toLowerCase() !== $(this).data('org-name').toString().toLowerCase()) {\n $prompt.show();\n } else {\n $prompt.hide();\n }\n });\n }\n}\n\nfunction initUserSettings() {\n // Options\n if ($('.user.settings.profile').length > 0) {\n $('#username').keyup(function () {\n const $prompt = $('#name-change-prompt');\n if ($(this).val().toString().toLowerCase() !== $(this).data('name').toString().toLowerCase()) {\n $prompt.show();\n } else {\n $prompt.hide();\n }\n });\n }\n}\n\nfunction initWebhook() {\n if ($('.new.webhook').length === 0) {\n return;\n }\n\n $('.events.checkbox input').change(function () {\n if ($(this).is(':checked')) {\n $('.events.fields').show();\n }\n });\n $('.non-events.checkbox input').change(function () {\n if ($(this).is(':checked')) {\n $('.events.fields').hide();\n }\n });\n\n const updateContentType = function () {\n const visible = $('#http_method').val() === 'POST';\n $('#content_type').parent().parent()[visible ? 'show' : 'hide']();\n };\n updateContentType();\n $('#http_method').change(() => {\n updateContentType();\n });\n\n // Test delivery\n $('#test-delivery').click(function () {\n const $this = $(this);\n $this.addClass('loading disabled');\n $.post($this.data('link'), {\n _csrf: csrf\n }).done(\n setTimeout(() => {\n window.location.href = $this.data('redirect');\n }, 5000)\n );\n });\n}\n\nfunction initAdmin() {\n if ($('.admin').length === 0) {\n return;\n }\n\n // New user\n if ($('.admin.new.user').length > 0 || $('.admin.edit.user').length > 0) {\n $('#login_type').change(function () {\n if ($(this).val().substring(0, 1) === '0') {\n $('#login_name').removeAttr('required');\n $('.non-local').hide();\n $('.local').show();\n $('#user_name').focus();\n\n if ($(this).data('password') === 'required') {\n $('#password').attr('required', 'required');\n }\n } else {\n $('#login_name').attr('required', 'required');\n $('.non-local').show();\n $('.local').hide();\n $('#login_name').focus();\n\n $('#password').removeAttr('required');\n }\n });\n }\n\n function onSecurityProtocolChange() {\n if ($('#security_protocol').val() > 0) {\n $('.has-tls').show();\n } else {\n $('.has-tls').hide();\n }\n }\n\n function onUsePagedSearchChange() {\n if ($('#use_paged_search').prop('checked')) {\n $('.search-page-size').show()\n .find('input').attr('required', 'required');\n } else {\n $('.search-page-size').hide()\n .find('input').removeAttr('required');\n }\n }\n\n function onOAuth2Change() {\n $('.open_id_connect_auto_discovery_url, .oauth2_use_custom_url').hide();\n $('.open_id_connect_auto_discovery_url input[required]').removeAttr('required');\n\n const provider = $('#oauth2_provider').val();\n switch (provider) {\n case 'github':\n case 'gitlab':\n case 'gitea':\n $('.oauth2_use_custom_url').show();\n break;\n case 'openidConnect':\n $('.open_id_connect_auto_discovery_url input').attr('required', 'required');\n $('.open_id_connect_auto_discovery_url').show();\n break;\n }\n onOAuth2UseCustomURLChange();\n }\n\n function onOAuth2UseCustomURLChange() {\n const provider = $('#oauth2_provider').val();\n $('.oauth2_use_custom_url_field').hide();\n $('.oauth2_use_custom_url_field input[required]').removeAttr('required');\n\n if ($('#oauth2_use_custom_url').is(':checked')) {\n if (!$('#oauth2_token_url').val()) {\n $('#oauth2_token_url').val($(`#${provider}_token_url`).val());\n }\n if (!$('#oauth2_auth_url').val()) {\n $('#oauth2_auth_url').val($(`#${provider}_auth_url`).val());\n }\n if (!$('#oauth2_profile_url').val()) {\n $('#oauth2_profile_url').val($(`#${provider}_profile_url`).val());\n }\n if (!$('#oauth2_email_url').val()) {\n $('#oauth2_email_url').val($(`#${provider}_email_url`).val());\n }\n switch (provider) {\n case 'github':\n $('.oauth2_token_url input, .oauth2_auth_url input, .oauth2_profile_url input, .oauth2_email_url input').attr('required', 'required');\n $('.oauth2_token_url, .oauth2_auth_url, .oauth2_profile_url, .oauth2_email_url').show();\n break;\n case 'gitea':\n case 'gitlab':\n $('.oauth2_token_url input, .oauth2_auth_url input, .oauth2_profile_url input').attr('required', 'required');\n $('.oauth2_token_url, .oauth2_auth_url, .oauth2_profile_url').show();\n $('#oauth2_email_url').val('');\n break;\n }\n }\n }\n\n // New authentication\n if ($('.admin.new.authentication').length > 0) {\n $('#auth_type').change(function () {\n $('.ldap, .dldap, .smtp, .pam, .oauth2, .has-tls .search-page-size').hide();\n\n $('.ldap input[required], .binddnrequired input[required], .dldap input[required], .smtp input[required], .pam input[required], .oauth2 input[required], .has-tls input[required]').removeAttr('required');\n $('.binddnrequired').removeClass('required');\n\n const authType = $(this).val();\n switch (authType) {\n case '2': // LDAP\n $('.ldap').show();\n $('.binddnrequired input, .ldap div.required:not(.dldap) input').attr('required', 'required');\n $('.binddnrequired').addClass('required');\n break;\n case '3': // SMTP\n $('.smtp').show();\n $('.has-tls').show();\n $('.smtp div.required input, .has-tls').attr('required', 'required');\n break;\n case '4': // PAM\n $('.pam').show();\n $('.pam input').attr('required', 'required');\n break;\n case '5': // LDAP\n $('.dldap').show();\n $('.dldap div.required:not(.ldap) input').attr('required', 'required');\n break;\n case '6': // OAuth2\n $('.oauth2').show();\n $('.oauth2 div.required:not(.oauth2_use_custom_url,.oauth2_use_custom_url_field,.open_id_connect_auto_discovery_url) input').attr('required', 'required');\n onOAuth2Change();\n break;\n }\n if (authType === '2' || authType === '5') {\n onSecurityProtocolChange();\n }\n if (authType === '2') {\n onUsePagedSearchChange();\n }\n });\n $('#auth_type').change();\n $('#security_protocol').change(onSecurityProtocolChange);\n $('#use_paged_search').change(onUsePagedSearchChange);\n $('#oauth2_provider').change(onOAuth2Change);\n $('#oauth2_use_custom_url').change(onOAuth2UseCustomURLChange);\n }\n // Edit authentication\n if ($('.admin.edit.authentication').length > 0) {\n const authType = $('#auth_type').val();\n if (authType === '2' || authType === '5') {\n $('#security_protocol').change(onSecurityProtocolChange);\n if (authType === '2') {\n $('#use_paged_search').change(onUsePagedSearchChange);\n }\n } else if (authType === '6') {\n $('#oauth2_provider').change(onOAuth2Change);\n $('#oauth2_use_custom_url').change(onOAuth2UseCustomURLChange);\n onOAuth2Change();\n }\n }\n\n // Notice\n if ($('.admin.notice')) {\n const $detailModal = $('#detail-modal');\n\n // Attach view detail modals\n $('.view-detail').click(function () {\n $detailModal.find('.content p').text($(this).data('content'));\n $detailModal.modal('show');\n return false;\n });\n\n // Select actions\n const $checkboxes = $('.select.table .ui.checkbox');\n $('.select.action').click(function () {\n switch ($(this).data('action')) {\n case 'select-all':\n $checkboxes.checkbox('check');\n break;\n case 'deselect-all':\n $checkboxes.checkbox('uncheck');\n break;\n case 'inverse':\n $checkboxes.checkbox('toggle');\n break;\n }\n });\n $('#delete-selection').click(function () {\n const $this = $(this);\n $this.addClass('loading disabled');\n const ids = [];\n $checkboxes.each(function () {\n if ($(this).checkbox('is checked')) {\n ids.push($(this).data('id'));\n }\n });\n $.post($this.data('link'), {\n _csrf: csrf,\n ids\n }).done(() => {\n window.location.href = $this.data('redirect');\n });\n });\n }\n}\n\nfunction buttonsClickOnEnter() {\n $('.ui.button').keypress(function (e) {\n if (e.keyCode === 13 || e.keyCode === 32) { // enter key or space bar\n $(this).click();\n }\n });\n}\n\nfunction searchUsers() {\n const $searchUserBox = $('#search-user-box');\n $searchUserBox.search({\n minCharacters: 2,\n apiSettings: {\n url: `${suburl}/api/v1/users/search?q={query}`,\n onResponse(response) {\n const items = [];\n $.each(response.data, (_i, item) => {\n let title = item.login;\n if (item.full_name && item.full_name.length > 0) {\n title += ` (${htmlEncode(item.full_name)})`;\n }\n items.push({\n title,\n image: item.avatar_url\n });\n });\n\n return { results: items };\n }\n },\n searchFields: ['login', 'full_name'],\n showNoResults: false\n });\n}\n\nfunction searchTeams() {\n const $searchTeamBox = $('#search-team-box');\n $searchTeamBox.search({\n minCharacters: 2,\n apiSettings: {\n url: `${suburl}/api/v1/orgs/${$searchTeamBox.data('org')}/teams/search?q={query}`,\n headers: { 'X-Csrf-Token': csrf },\n onResponse(response) {\n const items = [];\n $.each(response.data, (_i, item) => {\n const title = `${item.name} (${item.permission} access)`;\n items.push({\n title,\n });\n });\n\n return { results: items };\n }\n },\n searchFields: ['name', 'description'],\n showNoResults: false\n });\n}\n\nfunction searchRepositories() {\n const $searchRepoBox = $('#search-repo-box');\n $searchRepoBox.search({\n minCharacters: 2,\n apiSettings: {\n url: `${suburl}/api/v1/repos/search?q={query}&uid=${$searchRepoBox.data('uid')}`,\n onResponse(response) {\n const items = [];\n $.each(response.data, (_i, item) => {\n items.push({\n title: item.full_name.split('/')[1],\n description: item.full_name\n });\n });\n\n return { results: items };\n }\n },\n searchFields: ['full_name'],\n showNoResults: false\n });\n}\n\nfunction initCodeView() {\n if ($('.code-view .linenums').length > 0) {\n $(document).on('click', '.lines-num span', function (e) {\n const $select = $(this);\n const $list = $select.parent().siblings('.lines-code').find('ol.linenums > li');\n selectRange($list, $list.filter(`[rel=${$select.attr('id')}]`), (e.shiftKey ? $list.filter('.active').eq(0) : null));\n deSelect();\n });\n\n $(window).on('hashchange', () => {\n let m = window.location.hash.match(/^#(L\\d+)-(L\\d+)$/);\n const $list = $('.code-view ol.linenums > li');\n let $first;\n if (m) {\n $first = $list.filter(`.${m[1]}`);\n selectRange($list, $first, $list.filter(`.${m[2]}`));\n $('html, body').scrollTop($first.offset().top - 200);\n return;\n }\n m = window.location.hash.match(/^#(L|n)(\\d+)$/);\n if (m) {\n $first = $list.filter(`.L${m[2]}`);\n selectRange($list, $first);\n $('html, body').scrollTop($first.offset().top - 200);\n }\n }).trigger('hashchange');\n }\n $('.ui.fold-code').on('click', (e) => {\n const $foldButton = $(e.target);\n if ($foldButton.hasClass('fa-chevron-down')) {\n $(e.target).parent().next().slideUp('fast', () => {\n $foldButton.removeClass('fa-chevron-down').addClass('fa-chevron-right');\n });\n } else {\n $(e.target).parent().next().slideDown('fast', () => {\n $foldButton.removeClass('fa-chevron-right').addClass('fa-chevron-down');\n });\n }\n });\n function insertBlobExcerpt(e) {\n const $blob = $(e.target);\n const $row = $blob.parent().parent();\n $.get(`${$blob.data('url')}?${$blob.data('query')}&anchor=${$blob.data('anchor')}`, (blob) => {\n $row.replaceWith(blob);\n $(`[data-anchor=\"${$blob.data('anchor')}\"]`).on('click', (e) => { insertBlobExcerpt(e); });\n });\n }\n $('.ui.blob-excerpt').on('click', (e) => { insertBlobExcerpt(e); });\n}\n\nfunction initU2FAuth() {\n if ($('#wait-for-key').length === 0) {\n return;\n }\n u2fApi.ensureSupport()\n .then(() => {\n $.getJSON(`${suburl}/user/u2f/challenge`).success((req) => {\n u2fApi.sign(req.appId, req.challenge, req.registeredKeys, 30)\n .then(u2fSigned)\n .catch((err) => {\n if (err === undefined) {\n u2fError(1);\n return;\n }\n u2fError(err.metaData.code);\n });\n });\n }).catch(() => {\n // Fallback in case browser do not support U2F\n window.location.href = `${suburl}/user/two_factor`;\n });\n}\nfunction u2fSigned(resp) {\n $.ajax({\n url: `${suburl}/user/u2f/sign`,\n type: 'POST',\n headers: { 'X-Csrf-Token': csrf },\n data: JSON.stringify(resp),\n contentType: 'application/json; charset=utf-8',\n }).done((res) => {\n window.location.replace(res);\n }).fail(() => {\n u2fError(1);\n });\n}\n\nfunction u2fRegistered(resp) {\n if (checkError(resp)) {\n return;\n }\n $.ajax({\n url: `${suburl}/user/settings/security/u2f/register`,\n type: 'POST',\n headers: { 'X-Csrf-Token': csrf },\n data: JSON.stringify(resp),\n contentType: 'application/json; charset=utf-8',\n success() {\n reload();\n },\n fail() {\n u2fError(1);\n }\n });\n}\n\nfunction checkError(resp) {\n if (!('errorCode' in resp)) {\n return false;\n }\n if (resp.errorCode === 0) {\n return false;\n }\n u2fError(resp.errorCode);\n return true;\n}\n\n\nfunction u2fError(errorType) {\n const u2fErrors = {\n browser: $('#unsupported-browser'),\n 1: $('#u2f-error-1'),\n 2: $('#u2f-error-2'),\n 3: $('#u2f-error-3'),\n 4: $('#u2f-error-4'),\n 5: $('.u2f-error-5')\n };\n u2fErrors[errorType].removeClass('hide');\n\n Object.keys(u2fErrors).forEach((type) => {\n if (type !== errorType) {\n u2fErrors[type].addClass('hide');\n }\n });\n $('#u2f-error').modal('show');\n}\n\nfunction initU2FRegister() {\n $('#register-device').modal({ allowMultiple: false });\n $('#u2f-error').modal({ allowMultiple: false });\n $('#register-security-key').on('click', (e) => {\n e.preventDefault();\n u2fApi.ensureSupport()\n .then(u2fRegisterRequest)\n .catch(() => {\n u2fError('browser');\n });\n });\n}\n\nfunction u2fRegisterRequest() {\n $.post(`${suburl}/user/settings/security/u2f/request_register`, {\n _csrf: csrf,\n name: $('#nickname').val()\n }).success((req) => {\n $('#nickname').closest('div.field').removeClass('error');\n $('#register-device').modal('show');\n if (req.registeredKeys === null) {\n req.registeredKeys = [];\n }\n u2fApi.register(req.appId, req.registerRequests, req.registeredKeys, 30)\n .then(u2fRegistered)\n .catch((reason) => {\n if (reason === undefined) {\n u2fError(1);\n return;\n }\n u2fError(reason.metaData.code);\n });\n }).fail((xhr) => {\n if (xhr.status === 409) {\n $('#nickname').closest('div.field').addClass('error');\n }\n });\n}\n\nfunction initWipTitle() {\n $('.title_wip_desc > a').click((e) => {\n e.preventDefault();\n\n const $issueTitle = $('#issue_title');\n $issueTitle.focus();\n const value = $issueTitle.val().trim().toUpperCase();\n\n for (const i in wipPrefixes) {\n if (value.startsWith(wipPrefixes[i].toUpperCase())) {\n return;\n }\n }\n\n $issueTitle.val(`${wipPrefixes[0]} ${$issueTitle.val()}`);\n });\n}\n\nfunction initTemplateSearch() {\n const $repoTemplate = $('#repo_template');\n const checkTemplate = function () {\n const $templateUnits = $('#template_units');\n const $nonTemplate = $('#non_template');\n if ($repoTemplate.val() !== '') {\n $templateUnits.show();\n $nonTemplate.hide();\n } else {\n $templateUnits.hide();\n $nonTemplate.show();\n }\n };\n $repoTemplate.change(checkTemplate);\n checkTemplate();\n\n const changeOwner = function () {\n $('#repo_template_search')\n .dropdown({\n apiSettings: {\n url: `${suburl}/api/v1/repos/search?q={query}&template=true&priority_owner_id=${$('#uid').val()}`,\n onResponse(response) {\n const filteredResponse = { success: true, results: [] };\n filteredResponse.results.push({\n name: '',\n value: ''\n });\n // Parse the response from the api to work with our dropdown\n $.each(response.data, (_r, repo) => {\n filteredResponse.results.push({\n name: htmlEncode(repo.full_name),\n value: repo.id\n });\n });\n return filteredResponse;\n },\n cache: false,\n },\n\n fullTextSearch: true\n });\n };\n $('#uid').change(changeOwner);\n changeOwner();\n}\n\n$(document).ready(() => {\n csrf = $('meta[name=_csrf]').attr('content');\n suburl = $('meta[name=_suburl]').attr('content');\n\n // Show exact time\n $('.time-since').each(function () {\n $(this)\n .addClass('poping up')\n .attr('data-content', $(this).attr('title'))\n .attr('data-variation', 'inverted tiny')\n .attr('title', '');\n });\n\n // Semantic UI modules.\n $('.dropdown:not(.custom)').dropdown();\n $('.jump.dropdown').dropdown({\n action: 'hide',\n onShow() {\n $('.poping.up').popup('hide');\n }\n });\n $('.slide.up.dropdown').dropdown({\n transition: 'slide up'\n });\n $('.upward.dropdown').dropdown({\n direction: 'upward'\n });\n $('.ui.accordion').accordion();\n $('.ui.checkbox').checkbox();\n $('.ui.progress').progress({\n showActivity: false\n });\n $('.poping.up').popup();\n $('.top.menu .poping.up').popup({\n onShow() {\n if ($('.top.menu .menu.transition').hasClass('visible')) {\n return false;\n }\n }\n });\n $('.tabular.menu .item').tab();\n $('.tabable.menu .item').tab();\n\n $('.toggle.button').click(function () {\n $($(this).data('target')).slideToggle(100);\n });\n\n // make table element clickable like a link\n $('tr[data-href]').click(function () {\n window.location = $(this).data('href');\n });\n\n // Highlight JS\n if (typeof hljs !== 'undefined') {\n const nodes = [].slice.call(document.querySelectorAll('pre code') || []);\n for (let i = 0; i < nodes.length; i++) {\n hljs.highlightBlock(nodes[i]);\n }\n }\n\n // Dropzone\n const $dropzone = $('#dropzone');\n if ($dropzone.length > 0) {\n const filenameDict = {};\n\n new Dropzone('#dropzone', {\n url: $dropzone.data('upload-url'),\n headers: { 'X-Csrf-Token': csrf },\n maxFiles: $dropzone.data('max-file'),\n maxFilesize: $dropzone.data('max-size'),\n acceptedFiles: ($dropzone.data('accepts') === '*/*') ? null : $dropzone.data('accepts'),\n addRemoveLinks: true,\n dictDefaultMessage: $dropzone.data('default-message'),\n dictInvalidFileType: $dropzone.data('invalid-input-type'),\n dictFileTooBig: $dropzone.data('file-too-big'),\n dictRemoveFile: $dropzone.data('remove-file'),\n init() {\n this.on('success', (file, data) => {\n filenameDict[file.name] = data.uuid;\n const input = $(``).val(data.uuid);\n $('.files').append(input);\n });\n this.on('removedfile', (file) => {\n if (file.name in filenameDict) {\n $(`#${filenameDict[file.name]}`).remove();\n }\n if ($dropzone.data('remove-url') && $dropzone.data('csrf')) {\n $.post($dropzone.data('remove-url'), {\n file: filenameDict[file.name],\n _csrf: $dropzone.data('csrf')\n });\n }\n });\n },\n });\n }\n\n // Emojify\n emojify.setConfig({\n img_dir: `${suburl}/vendor/plugins/emojify/images`,\n ignore_emoticons: true\n });\n const hasEmoji = document.getElementsByClassName('has-emoji');\n for (let i = 0; i < hasEmoji.length; i++) {\n emojify.run(hasEmoji[i]);\n for (let j = 0; j < hasEmoji[i].childNodes.length; j++) {\n if (hasEmoji[i].childNodes[j].nodeName === 'A') {\n emojify.run(hasEmoji[i].childNodes[j]);\n }\n }\n }\n\n // Clipboard JS\n const clipboard = new Clipboard('.clipboard');\n clipboard.on('success', (e) => {\n e.clearSelection();\n\n $(`#${e.trigger.getAttribute('id')}`).popup('destroy');\n e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-success'));\n $(`#${e.trigger.getAttribute('id')}`).popup('show');\n e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original'));\n });\n\n clipboard.on('error', (e) => {\n $(`#${e.trigger.getAttribute('id')}`).popup('destroy');\n e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-error'));\n $(`#${e.trigger.getAttribute('id')}`).popup('show');\n e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original'));\n });\n\n // Helpers.\n $('.delete-button').click(showDeletePopup);\n $('.add-all-button').click(showAddAllPopup);\n\n $('.delete-branch-button').click(showDeletePopup);\n\n $('.undo-button').click(function () {\n const $this = $(this);\n $.post($this.data('url'), {\n _csrf: csrf,\n id: $this.data('id')\n }).done((data) => {\n window.location.href = data.redirect;\n });\n });\n $('.show-panel.button').click(function () {\n $($(this).data('panel')).show();\n });\n $('.show-modal.button').click(function () {\n $($(this).data('modal')).modal('show');\n });\n $('.delete-post.button').click(function () {\n const $this = $(this);\n $.post($this.data('request-url'), {\n _csrf: csrf\n }).done(() => {\n window.location.href = $this.data('done-url');\n });\n });\n\n // Set anchor.\n $('.markdown').each(function () {\n const headers = {};\n $(this).find('h1, h2, h3, h4, h5, h6').each(function () {\n let node = $(this);\n const val = encodeURIComponent(node.text().toLowerCase().replace(/[^\\u00C0-\\u1FFF\\u2C00-\\uD7FF\\w\\- ]/g, '').replace(/[ ]/g, '-'));\n let name = val;\n if (headers[val] > 0) {\n name = `${val}-${headers[val]}`;\n }\n if (headers[val] === undefined) {\n headers[val] = 1;\n } else {\n headers[val] += 1;\n }\n node = node.wrap(`
`);\n node.append(``);\n });\n });\n\n $('.issue-checkbox').click(() => {\n const numChecked = $('.issue-checkbox').children('input:checked').length;\n if (numChecked > 0) {\n $('#issue-filters').addClass('hide');\n $('#issue-actions').removeClass('hide');\n } else {\n $('#issue-filters').removeClass('hide');\n $('#issue-actions').addClass('hide');\n }\n });\n\n $('.issue-action').click(function () {\n let { action } = this.dataset;\n let { elementId } = this.dataset;\n const issueIDs = $('.issue-checkbox').children('input:checked').map(function () {\n return this.dataset.issueId;\n }).get().join();\n const { url } = this.dataset;\n if (elementId === '0' && url.substr(-9) === '/assignee') {\n elementId = '';\n action = 'clear';\n }\n updateIssuesMeta(url, action, issueIDs, elementId).then(() => {\n // NOTICE: This reset of checkbox state targets Firefox caching behaviour, as the checkboxes stay checked after reload\n if (action === 'close' || action === 'open') {\n // uncheck all checkboxes\n $('.issue-checkbox input[type=\"checkbox\"]').each((_, e) => { e.checked = false; });\n }\n reload();\n });\n });\n\n // NOTICE: This event trigger targets Firefox caching behaviour, as the checkboxes stay checked after reload\n // trigger ckecked event, if checkboxes are checked on load\n $('.issue-checkbox input[type=\"checkbox\"]:checked').first().each((_, e) => {\n e.checked = false;\n $(e).click();\n });\n\n buttonsClickOnEnter();\n searchUsers();\n searchTeams();\n searchRepositories();\n\n initCommentForm();\n initInstall();\n initRepository();\n initMigration();\n initWikiForm();\n initEditForm();\n initEditor();\n initOrganization();\n initWebhook();\n initAdmin();\n initCodeView();\n initVueApp();\n initTeamSettings();\n initCtrlEnterSubmit();\n initNavbarContentToggle();\n initTopicbar();\n initU2FAuth();\n initU2FRegister();\n initIssueList();\n initWipTitle();\n initPullRequestReview();\n initRepoStatusChecker();\n initTemplateSearch();\n\n // Repo clone url.\n if ($('#repo-clone-url').length > 0) {\n switch (localStorage.getItem('repo-clone-protocol')) {\n case 'ssh':\n if ($('#repo-clone-ssh').click().length === 0) {\n $('#repo-clone-https').click();\n }\n break;\n default:\n $('#repo-clone-https').click();\n break;\n }\n }\n\n const routes = {\n 'div.user.settings': initUserSettings,\n 'div.repository.settings.collaboration': initRepositoryCollaboration\n };\n\n let selector;\n for (selector in routes) {\n if ($(selector).length > 0) {\n routes[selector]();\n break;\n }\n }\n\n const $cloneAddr = $('#clone_addr');\n $cloneAddr.change(() => {\n const $repoName = $('#repo_name');\n if ($cloneAddr.val().length > 0 && $repoName.val().length === 0) { // Only modify if repo_name input is blank\n $repoName.val($cloneAddr.val().match(/^(.*\\/)?((.+?)(\\.git)?)$/)[3]);\n }\n });\n});\n\nfunction changeHash(hash) {\n if (window.history.pushState) {\n window.history.pushState(null, null, hash);\n } else {\n window.location.hash = hash;\n }\n}\n\nfunction deSelect() {\n if (window.getSelection) {\n window.getSelection().removeAllRanges();\n } else {\n document.selection.empty();\n }\n}\n\nfunction selectRange($list, $select, $from) {\n $list.removeClass('active');\n if ($from) {\n let a = parseInt($select.attr('rel').substr(1));\n let b = parseInt($from.attr('rel').substr(1));\n let c;\n if (a !== b) {\n if (a > b) {\n c = a;\n a = b;\n b = c;\n }\n const classes = [];\n for (let i = a; i <= b; i++) {\n classes.push(`.L${i}`);\n }\n $list.filter(classes.join(',')).addClass('active');\n changeHash(`#L${a}-L${b}`);\n return;\n }\n }\n $select.addClass('active');\n changeHash(`#${$select.attr('rel')}`);\n}\n\n$(() => {\n // Warn users that try to leave a page after entering data into a form.\n // Except on sign-in pages, and for forms marked as 'ignore-dirty'.\n if ($('.user.signin').length === 0) {\n $('form:not(.ignore-dirty)').areYouSure();\n }\n\n // Parse SSH Key\n $('#ssh-key-content').on('change paste keyup', function () {\n const arrays = $(this).val().split(' ');\n const $title = $('#ssh-key-title');\n if ($title.val() === '' && arrays.length === 3 && arrays[2] !== '') {\n $title.val(arrays[2]);\n }\n });\n});\n\nfunction showDeletePopup() {\n const $this = $(this);\n let filter = '';\n if ($this.attr('id')) {\n filter += `#${$this.attr('id')}`;\n }\n\n const dialog = $(`.delete.modal${filter}`);\n dialog.find('.name').text($this.data('name'));\n\n dialog.modal({\n closable: false,\n onApprove() {\n if ($this.data('type') === 'form') {\n $($this.data('form')).submit();\n return;\n }\n\n $.post($this.data('url'), {\n _csrf: csrf,\n id: $this.data('id')\n }).done((data) => {\n window.location.href = data.redirect;\n });\n }\n }).modal('show');\n return false;\n}\n\nfunction showAddAllPopup() {\n const $this = $(this);\n let filter = '';\n if ($this.attr('id')) {\n filter += `#${$this.attr('id')}`;\n }\n\n const dialog = $(`.addall.modal${filter}`);\n dialog.find('.name').text($this.data('name'));\n\n dialog.modal({\n closable: false,\n onApprove() {\n if ($this.data('type') === 'form') {\n $($this.data('form')).submit();\n return;\n }\n\n $.post($this.data('url'), {\n _csrf: csrf,\n id: $this.data('id')\n }).done((data) => {\n window.location.href = data.redirect;\n });\n }\n }).modal('show');\n return false;\n}\n\nfunction initVueComponents() {\n const vueDelimeters = ['${', '}'];\n\n Vue.component('repo-search', {\n delimiters: vueDelimeters,\n\n props: {\n searchLimit: {\n type: Number,\n default: 10\n },\n suburl: {\n type: String,\n required: true\n },\n uid: {\n type: Number,\n required: true\n },\n organizations: {\n type: Array,\n default: []\n },\n isOrganization: {\n type: Boolean,\n default: true\n },\n canCreateOrganization: {\n type: Boolean,\n default: false\n },\n organizationsTotalCount: {\n type: Number,\n default: 0\n },\n moreReposLink: {\n type: String,\n default: ''\n }\n },\n\n data() {\n return {\n tab: 'repos',\n repos: [],\n reposTotalCount: 0,\n reposFilter: 'all',\n searchQuery: '',\n isLoading: false,\n repoTypes: {\n all: {\n count: 0,\n searchMode: '',\n },\n forks: {\n count: 0,\n searchMode: 'fork',\n },\n mirrors: {\n count: 0,\n searchMode: 'mirror',\n },\n sources: {\n count: 0,\n searchMode: 'source',\n },\n collaborative: {\n count: 0,\n searchMode: 'collaborative',\n },\n }\n };\n },\n\n computed: {\n showMoreReposLink() {\n return this.repos.length > 0 && this.repos.length < this.repoTypes[this.reposFilter].count;\n },\n searchURL() {\n return `${this.suburl}/api/v1/repos/search?sort=updated&order=desc&uid=${this.uid}&q=${this.searchQuery\n }&limit=${this.searchLimit}&mode=${this.repoTypes[this.reposFilter].searchMode\n }${this.reposFilter !== 'all' ? '&exclusive=1' : ''}`;\n },\n repoTypeCount() {\n return this.repoTypes[this.reposFilter].count;\n }\n },\n\n mounted() {\n this.searchRepos(this.reposFilter);\n\n const self = this;\n Vue.nextTick(() => {\n self.$refs.search.focus();\n });\n },\n\n methods: {\n changeTab(t) {\n this.tab = t;\n },\n\n changeReposFilter(filter) {\n this.reposFilter = filter;\n this.repos = [];\n this.repoTypes[filter].count = 0;\n this.searchRepos(filter);\n },\n\n showRepo(repo, filter) {\n switch (filter) {\n case 'sources':\n return repo.owner.id === this.uid && !repo.mirror && !repo.fork;\n case 'forks':\n return repo.owner.id === this.uid && !repo.mirror && repo.fork;\n case 'mirrors':\n return repo.mirror;\n case 'collaborative':\n return repo.owner.id !== this.uid && !repo.mirror;\n default:\n return true;\n }\n },\n\n searchRepos(reposFilter) {\n const self = this;\n\n this.isLoading = true;\n\n const searchedMode = this.repoTypes[reposFilter].searchMode;\n const searchedURL = this.searchURL;\n const searchedQuery = this.searchQuery;\n\n $.getJSON(searchedURL, (result, _textStatus, request) => {\n if (searchedURL === self.searchURL) {\n self.repos = result.data;\n const count = request.getResponseHeader('X-Total-Count');\n if (searchedQuery === '' && searchedMode === '') {\n self.reposTotalCount = count;\n }\n self.repoTypes[reposFilter].count = count;\n }\n }).always(() => {\n if (searchedURL === self.searchURL) {\n self.isLoading = false;\n }\n });\n },\n\n repoClass(repo) {\n if (repo.fork) {\n return 'octicon octicon-repo-forked';\n } if (repo.mirror) {\n return 'octicon octicon-repo-clone';\n } if (repo.private) {\n return 'octicon octicon-lock';\n }\n return 'octicon octicon-repo';\n }\n }\n });\n}\n\nfunction initCtrlEnterSubmit() {\n $('.js-quick-submit').keydown(function (e) {\n if (((e.ctrlKey && !e.altKey) || e.metaKey) && (e.keyCode === 13 || e.keyCode === 10)) {\n $(this).closest('form').submit();\n }\n });\n}\n\nfunction initVueApp() {\n const el = document.getElementById('app');\n if (!el) {\n return;\n }\n\n initVueComponents();\n\n new Vue({\n delimiters: ['${', '}'],\n el,\n data: {\n searchLimit: document.querySelector('meta[name=_search_limit]').content,\n suburl: document.querySelector('meta[name=_suburl]').content,\n uid: document.querySelector('meta[name=_context_uid]').content,\n },\n });\n}\n\nwindow.timeAddManual = function () {\n $('.mini.modal')\n .modal({\n duration: 200,\n onApprove() {\n $('#add_time_manual_form').submit();\n }\n }).modal('show');\n};\n\nwindow.toggleStopwatch = function () {\n $('#toggle_stopwatch_form').submit();\n};\nwindow.cancelStopwatch = function () {\n $('#cancel_stopwatch_form').submit();\n};\n\nwindow.initHeatmap = function (appElementId, heatmapUser, locale) {\n const el = document.getElementById(appElementId);\n if (!el) {\n return;\n }\n\n locale = locale || {};\n\n locale.contributions = locale.contributions || 'contributions';\n locale.no_contributions = locale.no_contributions || 'No contributions';\n\n const vueDelimeters = ['${', '}'];\n\n Vue.component('activity-heatmap', {\n delimiters: vueDelimeters,\n\n props: {\n user: {\n type: String,\n required: true\n },\n suburl: {\n type: String,\n required: true\n },\n locale: {\n type: Object,\n required: true\n }\n },\n\n data() {\n return {\n isLoading: true,\n colorRange: [],\n endDate: null,\n values: [],\n totalContributions: 0,\n };\n },\n\n mounted() {\n this.colorRange = [\n this.getColor(0),\n this.getColor(1),\n this.getColor(2),\n this.getColor(3),\n this.getColor(4),\n this.getColor(5)\n ];\n this.endDate = new Date();\n this.loadHeatmap(this.user);\n },\n\n methods: {\n loadHeatmap(userName) {\n const self = this;\n $.get(`${this.suburl}/api/v1/users/${userName}/heatmap`, (chartRawData) => {\n const chartData = [];\n for (let i = 0; i < chartRawData.length; i++) {\n self.totalContributions += chartRawData[i].contributions;\n chartData[i] = { date: new Date(chartRawData[i].timestamp * 1000), count: chartRawData[i].contributions };\n }\n self.values = chartData;\n self.isLoading = false;\n });\n },\n\n getColor(idx) {\n const el = document.createElement('div');\n el.className = `heatmap-color-${idx}`;\n document.body.appendChild(el);\n\n const color = getComputedStyle(el).backgroundColor;\n\n document.body.removeChild(el);\n\n return color;\n }\n },\n\n template: '

total contributions in the last 12 months

'\n });\n\n new Vue({\n delimiters: vueDelimeters,\n el,\n\n data: {\n suburl: document.querySelector('meta[name=_suburl]').content,\n heatmapUser,\n locale\n },\n });\n};\n\nfunction initFilterBranchTagDropdown(selector) {\n $(selector).each(function () {\n const $dropdown = $(this);\n const $data = $dropdown.find('.data');\n const data = {\n items: [],\n mode: $data.data('mode'),\n searchTerm: '',\n noResults: '',\n canCreateBranch: false,\n menuVisible: false,\n active: 0\n };\n $data.find('.item').each(function () {\n data.items.push({\n name: $(this).text(),\n url: $(this).data('url'),\n branch: $(this).hasClass('branch'),\n tag: $(this).hasClass('tag'),\n selected: $(this).hasClass('selected')\n });\n });\n $data.remove();\n new Vue({\n delimiters: ['${', '}'],\n el: this,\n data,\n\n beforeMount() {\n const vm = this;\n\n this.noResults = vm.$el.getAttribute('data-no-results');\n this.canCreateBranch = vm.$el.getAttribute('data-can-create-branch') === 'true';\n\n document.body.addEventListener('click', (event) => {\n if (vm.$el.contains(event.target)) {\n return;\n }\n if (vm.menuVisible) {\n Vue.set(vm, 'menuVisible', false);\n }\n });\n },\n\n watch: {\n menuVisible(visible) {\n if (visible) {\n this.focusSearchField();\n }\n }\n },\n\n computed: {\n filteredItems() {\n const vm = this;\n\n const items = vm.items.filter((item) => {\n return ((vm.mode === 'branches' && item.branch) || (vm.mode === 'tags' && item.tag))\n && (!vm.searchTerm || item.name.toLowerCase().indexOf(vm.searchTerm.toLowerCase()) >= 0);\n });\n\n vm.active = (items.length === 0 && vm.showCreateNewBranch ? 0 : -1);\n\n return items;\n },\n showNoResults() {\n return this.filteredItems.length === 0 && !this.showCreateNewBranch;\n },\n showCreateNewBranch() {\n const vm = this;\n if (!this.canCreateBranch || !vm.searchTerm || vm.mode === 'tags') {\n return false;\n }\n\n return vm.items.filter((item) => item.name.toLowerCase() === vm.searchTerm.toLowerCase()).length === 0;\n }\n },\n\n methods: {\n selectItem(item) {\n const prev = this.getSelected();\n if (prev !== null) {\n prev.selected = false;\n }\n item.selected = true;\n window.location.href = item.url;\n },\n createNewBranch() {\n if (!this.showCreateNewBranch) {\n return;\n }\n this.$refs.newBranchForm.submit();\n },\n focusSearchField() {\n const vm = this;\n Vue.nextTick(() => {\n vm.$refs.searchField.focus();\n });\n },\n getSelected() {\n for (let i = 0, j = this.items.length; i < j; ++i) {\n if (this.items[i].selected) return this.items[i];\n }\n return null;\n },\n getSelectedIndexInFiltered() {\n for (let i = 0, j = this.filteredItems.length; i < j; ++i) {\n if (this.filteredItems[i].selected) return i;\n }\n return -1;\n },\n scrollToActive() {\n let el = this.$refs[`listItem${this.active}`];\n if (!el || el.length === 0) {\n return;\n }\n if (Array.isArray(el)) {\n el = el[0];\n }\n\n const cont = this.$refs.scrollContainer;\n\n if (el.offsetTop < cont.scrollTop) {\n cont.scrollTop = el.offsetTop;\n } else if (el.offsetTop + el.clientHeight > cont.scrollTop + cont.clientHeight) {\n cont.scrollTop = el.offsetTop + el.clientHeight - cont.clientHeight;\n }\n },\n keydown(event) {\n const vm = this;\n if (event.keyCode === 40) {\n // arrow down\n event.preventDefault();\n\n if (vm.active === -1) {\n vm.active = vm.getSelectedIndexInFiltered();\n }\n\n if (vm.active + (vm.showCreateNewBranch ? 0 : 1) >= vm.filteredItems.length) {\n return;\n }\n vm.active++;\n vm.scrollToActive();\n }\n if (event.keyCode === 38) {\n // arrow up\n event.preventDefault();\n\n if (vm.active === -1) {\n vm.active = vm.getSelectedIndexInFiltered();\n }\n\n if (vm.active <= 0) {\n return;\n }\n vm.active--;\n vm.scrollToActive();\n }\n if (event.keyCode === 13) {\n // enter\n event.preventDefault();\n\n if (vm.active >= vm.filteredItems.length) {\n vm.createNewBranch();\n } else if (vm.active >= 0) {\n vm.selectItem(vm.filteredItems[vm.active]);\n }\n }\n if (event.keyCode === 27) {\n // escape\n event.preventDefault();\n vm.menuVisible = false;\n }\n }\n }\n });\n });\n}\n\n$('.commit-button').click(function (e) {\n e.preventDefault();\n $(this).parent().find('.commit-body').toggle();\n});\n\nfunction initNavbarContentToggle() {\n const content = $('#navbar');\n const toggle = $('#navbar-expand-toggle');\n let isExpanded = false;\n toggle.click(() => {\n isExpanded = !isExpanded;\n if (isExpanded) {\n content.addClass('shown');\n toggle.addClass('active');\n } else {\n content.removeClass('shown');\n toggle.removeClass('active');\n }\n });\n}\n\nfunction initTopicbar() {\n const mgrBtn = $('#manage_topic');\n const editDiv = $('#topic_edit');\n const viewDiv = $('#repo-topics');\n const saveBtn = $('#save_topic');\n const topicDropdown = $('#topic_edit .dropdown');\n const topicForm = $('#topic_edit.ui.form');\n const topicPrompts = getPrompts();\n\n mgrBtn.click(() => {\n viewDiv.hide();\n editDiv.css('display', ''); // show Semantic UI Grid\n });\n\n function getPrompts() {\n const hidePrompt = $('div.hide#validate_prompt');\n const prompts = {\n countPrompt: hidePrompt.children('#count_prompt').text(),\n formatPrompt: hidePrompt.children('#format_prompt').text()\n };\n hidePrompt.remove();\n return prompts;\n }\n\n saveBtn.click(() => {\n const topics = $('input[name=topics]').val();\n\n $.post(saveBtn.data('link'), {\n _csrf: csrf,\n topics\n }, (_data, _textStatus, xhr) => {\n if (xhr.responseJSON.status === 'ok') {\n viewDiv.children('.topic').remove();\n if (topics.length) {\n const topicArray = topics.split(',');\n\n const last = viewDiv.children('a').last();\n for (let i = 0; i < topicArray.length; i++) {\n $(`
${topicArray[i]}
`).insertBefore(last);\n }\n }\n editDiv.css('display', 'none');\n viewDiv.show();\n }\n }).fail((xhr) => {\n if (xhr.status === 422) {\n if (xhr.responseJSON.invalidTopics.length > 0) {\n topicPrompts.formatPrompt = xhr.responseJSON.message;\n\n const { invalidTopics } = xhr.responseJSON;\n const topicLables = topicDropdown.children('a.ui.label');\n\n topics.split(',').forEach((value, index) => {\n for (let i = 0; i < invalidTopics.length; i++) {\n if (invalidTopics[i] === value) {\n topicLables.eq(index).removeClass('green').addClass('red');\n }\n }\n });\n } else {\n topicPrompts.countPrompt = xhr.responseJSON.message;\n }\n }\n }).always(() => {\n topicForm.form('validate form');\n });\n });\n\n topicDropdown.dropdown({\n allowAdditions: true,\n forceSelection: false,\n fields: { name: 'description', value: 'data-value' },\n saveRemoteData: false,\n label: {\n transition: 'horizontal flip',\n duration: 200,\n variation: false,\n blue: true,\n basic: true,\n },\n className: {\n label: 'ui small label'\n },\n apiSettings: {\n url: `${suburl}/api/v1/topics/search?q={query}`,\n throttle: 500,\n cache: false,\n onResponse(res) {\n const formattedResponse = {\n success: false,\n results: [],\n };\n const stripTags = function (text) {\n return text.replace(/<[^>]*>?/gm, '');\n };\n\n const query = stripTags(this.urlData.query.trim());\n let found_query = false;\n const current_topics = [];\n topicDropdown.find('div.label.visible.topic,a.label.visible').each((_, e) => { current_topics.push(e.dataset.value); });\n\n if (res.topics) {\n let found = false;\n for (let i = 0; i < res.topics.length; i++) {\n // skip currently added tags\n if (current_topics.indexOf(res.topics[i].topic_name) !== -1) {\n continue;\n }\n\n if (res.topics[i].topic_name.toLowerCase() === query.toLowerCase()) {\n found_query = true;\n }\n formattedResponse.results.push({ description: res.topics[i].topic_name, 'data-value': res.topics[i].topic_name });\n found = true;\n }\n formattedResponse.success = found;\n }\n\n if (query.length > 0 && !found_query) {\n formattedResponse.success = true;\n formattedResponse.results.unshift({ description: query, 'data-value': query });\n } else if (query.length > 0 && found_query) {\n formattedResponse.results.sort((a, b) => {\n if (a.description.toLowerCase() === query.toLowerCase()) return -1;\n if (b.description.toLowerCase() === query.toLowerCase()) return 1;\n if (a.description > b.description) return -1;\n if (a.description < b.description) return 1;\n return 0;\n });\n }\n\n\n return formattedResponse;\n },\n },\n onLabelCreate(value) {\n value = value.toLowerCase().trim();\n this.attr('data-value', value).contents().first().replaceWith(value);\n return $(this);\n },\n onAdd(addedValue, _addedText, $addedChoice) {\n addedValue = addedValue.toLowerCase().trim();\n $($addedChoice).attr('data-value', addedValue);\n $($addedChoice).attr('data-text', addedValue);\n }\n });\n\n $.fn.form.settings.rules.validateTopic = function (_values, regExp) {\n const topics = topicDropdown.children('a.ui.label');\n const status = topics.length === 0 || topics.last().attr('data-value').match(regExp);\n if (!status) {\n topics.last().removeClass('green').addClass('red');\n }\n return status && topicDropdown.children('a.ui.label.red').length === 0;\n };\n\n topicForm.form({\n on: 'change',\n inline: true,\n fields: {\n topics: {\n identifier: 'topics',\n rules: [\n {\n type: 'validateTopic',\n value: /^[a-z0-9][a-z0-9-]{1,35}$/,\n prompt: topicPrompts.formatPrompt\n },\n {\n type: 'maxCount[25]',\n prompt: topicPrompts.countPrompt\n }\n ]\n },\n }\n });\n}\n\nwindow.toggleDeadlineForm = function () {\n $('#deadlineForm').fadeToggle(150);\n};\n\nwindow.setDeadline = function () {\n const deadline = $('#deadlineDate').val();\n window.updateDeadline(deadline);\n};\n\nwindow.updateDeadline = function (deadlineString) {\n $('#deadline-err-invalid-date').hide();\n $('#deadline-loader').addClass('loading');\n\n let realDeadline = null;\n if (deadlineString !== '') {\n const newDate = Date.parse(deadlineString);\n\n if (Number.isNaN(newDate)) {\n $('#deadline-loader').removeClass('loading');\n $('#deadline-err-invalid-date').show();\n return false;\n }\n realDeadline = new Date(newDate);\n }\n\n $.ajax(`${$('#update-issue-deadline-form').attr('action')}/deadline`, {\n data: JSON.stringify({\n due_date: realDeadline,\n }),\n headers: {\n 'X-Csrf-Token': csrf,\n 'X-Remote': true,\n },\n contentType: 'application/json',\n type: 'POST',\n success() {\n reload();\n },\n error() {\n $('#deadline-loader').removeClass('loading');\n $('#deadline-err-invalid-date').show();\n }\n });\n};\n\nwindow.deleteDependencyModal = function (id, type) {\n $('.remove-dependency')\n .modal({\n closable: false,\n duration: 200,\n onApprove() {\n $('#removeDependencyID').val(id);\n $('#dependencyType').val(type);\n $('#removeDependencyForm').submit();\n }\n }).modal('show');\n};\n\nfunction initIssueList() {\n const repolink = $('#repolink').val();\n const repoId = $('#repoId').val();\n const crossRepoSearch = $('#crossRepoSearch').val();\n let issueSearchUrl = `${suburl}/api/v1/repos/${repolink}/issues?q={query}`;\n if (crossRepoSearch === 'true') {\n issueSearchUrl = `${suburl}/api/v1/repos/issues/search?q={query}&priority_repo_id=${repoId}`;\n }\n $('#new-dependency-drop-list')\n .dropdown({\n apiSettings: {\n url: issueSearchUrl,\n onResponse(response) {\n const filteredResponse = { success: true, results: [] };\n const currIssueId = $('#new-dependency-drop-list').data('issue-id');\n // Parse the response from the api to work with our dropdown\n $.each(response, (_i, issue) => {\n // Don't list current issue in the dependency list.\n if (issue.id === currIssueId) {\n return;\n }\n filteredResponse.results.push({\n name: `#${issue.number} ${htmlEncode(issue.title)\n }
${htmlEncode(issue.repository.full_name)}
`,\n value: issue.id\n });\n });\n return filteredResponse;\n },\n cache: false,\n },\n\n fullTextSearch: true\n });\n\n $('.menu a.label-filter-item').each(function () {\n $(this).click(function (e) {\n if (e.altKey) {\n e.preventDefault();\n\n const href = $(this).attr('href');\n const id = $(this).data('label-id');\n\n const regStr = `labels=(-?[0-9]+%2c)*(${id})(%2c-?[0-9]+)*&`;\n const newStr = 'labels=$1-$2$3&';\n\n window.location = href.replace(new RegExp(regStr), newStr);\n }\n });\n });\n\n $('.menu .ui.dropdown.label-filter').keydown((e) => {\n if (e.altKey && e.keyCode === 13) {\n const selectedItems = $('.menu .ui.dropdown.label-filter .menu .item.selected');\n\n if (selectedItems.length > 0) {\n const item = $(selectedItems[0]);\n\n const href = item.attr('href');\n const id = item.data('label-id');\n\n const regStr = `labels=(-?[0-9]+%2c)*(${id})(%2c-?[0-9]+)*&`;\n const newStr = 'labels=$1-$2$3&';\n\n window.location = href.replace(new RegExp(regStr), newStr);\n }\n }\n });\n}\nwindow.cancelCodeComment = function (btn) {\n const form = $(btn).closest('form');\n if (form.length > 0 && form.hasClass('comment-form')) {\n form.addClass('hide');\n form.parent().find('button.comment-form-reply').show();\n } else {\n form.closest('.comment-code-cloud').remove();\n }\n};\nwindow.onOAuthLoginClick = function () {\n const oauthLoader = $('#oauth2-login-loader');\n const oauthNav = $('#oauth2-login-navigator');\n\n oauthNav.hide();\n oauthLoader.removeClass('disabled');\n\n setTimeout(() => {\n // recover previous content to let user try again\n // usually redirection will be performed before this action\n oauthLoader.addClass('disabled');\n oauthNav.show();\n }, 5000);\n};\n","/* globals gitGraph */\n\n$(() => {\n const graphList = [];\n\n if (!document.getElementById('graph-canvas')) {\n return;\n }\n\n $('#graph-raw-list li span.node-relation').each(function () {\n graphList.push($(this).text());\n });\n\n gitGraph(document.getElementById('graph-canvas'), graphList);\n});\n"],"sourceRoot":""} \ No newline at end of file diff --git a/public/vendor/VERSIONS b/public/vendor/VERSIONS index 8afae309fe7..4643ee7b1ee 100644 --- a/public/vendor/VERSIONS +++ b/public/vendor/VERSIONS @@ -23,7 +23,7 @@ Version: 745f604212e2abfe2f0a59169ea530857b46625c File(s): /vendor/plugins/vue/vue.min.js Version: 2.1.10 -File(s): /vendor/plugins/emojify/emojify.min.js +File(s): /vendor/plugins/emojify/emojify.custom.js Version: 1.1.0 File(s): /vendor/plugins/cssrelpreload/ diff --git a/public/vendor/librejs.html b/public/vendor/librejs.html index 703fea284b6..56c1cb287cc 100644 --- a/public/vendor/librejs.html +++ b/public/vendor/librejs.html @@ -38,12 +38,7 @@ index.js Expat - index.js - - - draw.js - Expat - draw.js + *.js clipboard.min.js @@ -61,7 +56,7 @@ vue.js-v2.6.6.tar.gz - emojify.min.js + emojify.custom.js Expat emojify-1.1.0.tar.gz diff --git a/public/vendor/plugins/emojify/emojify.custom.js b/public/vendor/plugins/emojify/emojify.custom.js new file mode 100644 index 00000000000..9ed5121fd9b --- /dev/null +++ b/public/vendor/plugins/emojify/emojify.custom.js @@ -0,0 +1 @@ +!function(e,a){"use strict";"function"==typeof define&&define.amd?define([],a):"object"==typeof exports?module.exports=a():e.emojify=a()}(this,function(){"use strict";return function(){var e,a,o="+1,-1,100,1234,8ball,a,ab,abc,abcd,accept,aerial_tramway,airplane,alarm_clock,alien,ambulance,anchor,angel,anger,angry,anguished,ant,apple,aquarius,aries,arrow_backward,arrow_double_down,arrow_double_up,arrow_down,arrow_down_small,arrow_forward,arrow_heading_down,arrow_heading_up,arrow_left,arrow_lower_left,arrow_lower_right,arrow_right,arrow_right_hook,arrow_up,arrow_up_down,arrow_up_small,arrow_upper_left,arrow_upper_right,arrows_clockwise,arrows_counterclockwise,art,articulated_lorry,astonished,atm,b,baby,baby_bottle,baby_chick,baby_symbol,back,baggage_claim,balloon,ballot_box_with_check,bamboo,banana,bangbang,bank,bar_chart,barber,baseball,basketball,bath,bathtub,battery,bear,bee,beer,beers,beetle,beginner,bell,bento,bicyclist,bike,bikini,bird,birthday,black_circle,black_joker,black_medium_small_square,black_medium_square,black_nib,black_small_square,black_square,black_square_button,blossom,blowfish,blue_book,blue_car,blue_heart,blush,boar,boat,bomb,book,bookmark,bookmark_tabs,books,boom,boot,bouquet,bow,bowling,bowtie,boy,bread,bride_with_veil,bridge_at_night,briefcase,broken_heart,bug,bulb,bullettrain_front,bullettrain_side,bus,busstop,bust_in_silhouette,busts_in_silhouette,cactus,cake,calendar,calling,camel,camera,cancer,candy,capital_abcd,capricorn,car,card_index,carousel_horse,cat,cat2,cd,chart,chart_with_downwards_trend,chart_with_upwards_trend,checkered_flag,cherries,cherry_blossom,chestnut,chicken,children_crossing,chocolate_bar,christmas_tree,church,cinema,circus_tent,city_sunrise,city_sunset,cl,clap,clapper,clipboard,clock1,clock10,clock1030,clock11,clock1130,clock12,clock1230,clock130,clock2,clock230,clock3,clock330,clock4,clock430,clock5,clock530,clock6,clock630,clock7,clock730,clock8,clock830,clock9,clock930,closed_book,closed_lock_with_key,closed_umbrella,cloud,clubs,cn,cocktail,coffee,cold_sweat,collision,computer,confetti_ball,confounded,confused,congratulations,construction,construction_worker,convenience_store,cookie,cool,cop,copyright,corn,couple,couple_with_heart,couplekiss,cow,cow2,credit_card,crescent_moon,crocodile,crossed_flags,crown,cry,crying_cat_face,crystal_ball,cupid,curly_loop,currency_exchange,curry,custard,customs,cyclone,dancer,dancers,dango,dart,dash,date,de,deciduous_tree,department_store,diamond_shape_with_a_dot_inside,diamonds,disappointed,disappointed_relieved,dizzy,dizzy_face,do_not_litter,dog,dog2,dollar,dolls,dolphin,donut,door,doughnut,dragon,dragon_face,dress,dromedary_camel,droplet,dvd,e-mail,ear,ear_of_rice,earth_africa,earth_americas,earth_asia,egg,eggplant,eight,eight_pointed_black_star,eight_spoked_asterisk,electric_plug,elephant,email,end,envelope,es,euro,european_castle,european_post_office,evergreen_tree,exclamation,expressionless,eyeglasses,eyes,facepunch,factory,fallen_leaf,family,fast_forward,fax,fearful,feelsgood,feet,ferris_wheel,file_folder,finnadie,fire,fire_engine,fireworks,first_quarter_moon,first_quarter_moon_with_face,fish,fish_cake,fishing_pole_and_fish,fist,five,flags,flashlight,floppy_disk,flower_playing_cards,flushed,foggy,football,fork_and_knife,fountain,four,four_leaf_clover,fr,free,fried_shrimp,fries,frog,frowning,fu,fuelpump,full_moon,full_moon_with_face,game_die,gb,gem,gemini,ghost,gift,gift_heart,girl,globe_with_meridians,goat,goberserk,godmode,golf,grapes,green_apple,green_book,green_heart,grey_exclamation,grey_question,grimacing,grin,grinning,guardsman,guitar,gun,haircut,hamburger,hammer,hamster,hand,handbag,hankey,hash,hatched_chick,hatching_chick,headphones,hear_no_evil,heart,heart_decoration,heart_eyes,heart_eyes_cat,heartbeat,heartpulse,hearts,heavy_check_mark,heavy_division_sign,heavy_dollar_sign,heavy_exclamation_mark,heavy_minus_sign,heavy_multiplication_x,heavy_plus_sign,helicopter,herb,hibiscus,high_brightness,high_heel,hocho,honey_pot,honeybee,horse,horse_racing,hospital,hotel,hotsprings,hourglass,hourglass_flowing_sand,house,house_with_garden,hurtrealbad,hushed,ice_cream,icecream,id,ideograph_advantage,imp,inbox_tray,incoming_envelope,information_desk_person,information_source,innocent,interrobang,iphone,it,izakaya_lantern,jack_o_lantern,japan,japanese_castle,japanese_goblin,japanese_ogre,jeans,joy,joy_cat,jp,key,keycap_ten,kimono,kiss,kissing,kissing_cat,kissing_closed_eyes,kissing_face,kissing_heart,kissing_smiling_eyes,koala,koko,kr,large_blue_circle,large_blue_diamond,large_orange_diamond,last_quarter_moon,last_quarter_moon_with_face,laughing,leaves,ledger,left_luggage,left_right_arrow,leftwards_arrow_with_hook,lemon,leo,leopard,libra,light_rail,link,lips,lipstick,lock,lock_with_ink_pen,lollipop,loop,loudspeaker,love_hotel,love_letter,low_brightness,m,mag,mag_right,mahjong,mailbox,mailbox_closed,mailbox_with_mail,mailbox_with_no_mail,man,man_with_gua_pi_mao,man_with_turban,mans_shoe,maple_leaf,mask,massage,meat_on_bone,mega,melon,memo,mens,metal,metro,microphone,microscope,milky_way,minibus,minidisc,mobile_phone_off,money_with_wings,moneybag,monkey,monkey_face,monorail,mortar_board,mount_fuji,mountain_bicyclist,mountain_cableway,mountain_railway,mouse,mouse2,movie_camera,moyai,muscle,mushroom,musical_keyboard,musical_note,musical_score,mute,nail_care,name_badge,neckbeard,necktie,negative_squared_cross_mark,neutral_face,new,new_moon,new_moon_with_face,newspaper,ng,nine,no_bell,no_bicycles,no_entry,no_entry_sign,no_good,no_mobile_phones,no_mouth,no_pedestrians,no_smoking,non-potable_water,nose,notebook,notebook_with_decorative_cover,notes,nut_and_bolt,o,o2,ocean,octocat,octopus,oden,office,ok,ok_hand,ok_woman,older_man,older_woman,on,oncoming_automobile,oncoming_bus,oncoming_police_car,oncoming_taxi,one,open_file_folder,open_hands,open_mouth,ophiuchus,orange_book,outbox_tray,ox,package,page_facing_up,page_with_curl,pager,palm_tree,panda_face,paperclip,parking,part_alternation_mark,partly_sunny,passport_control,paw_prints,peach,pear,pencil,pencil2,penguin,pensive,performing_arts,persevere,person_frowning,person_with_blond_hair,person_with_pouting_face,phone,pig,pig2,pig_nose,pill,pineapple,pisces,pizza,plus1,point_down,point_left,point_right,point_up,point_up_2,police_car,poodle,poop,post_office,postal_horn,postbox,potable_water,pouch,poultry_leg,pound,pouting_cat,pray,princess,punch,purple_heart,purse,pushpin,put_litter_in_its_place,question,rabbit,rabbit2,racehorse,radio,radio_button,rage,rage1,rage2,rage3,rage4,railway_car,rainbow,raised_hand,raised_hands,raising_hand,ram,ramen,rat,recycle,red_car,red_circle,registered,relaxed,relieved,repeat,repeat_one,restroom,revolving_hearts,rewind,ribbon,rice,rice_ball,rice_cracker,rice_scene,ring,rocket,roller_coaster,rooster,rose,rotating_light,round_pushpin,rowboat,ru,rugby_football,runner,running,running_shirt_with_sash,sa,sagittarius,sailboat,sake,sandal,santa,satellite,satisfied,saxophone,school,school_satchel,scissors,scorpius,scream,scream_cat,scroll,seat,secret,see_no_evil,seedling,seven,shaved_ice,sheep,shell,ship,shipit,shirt,shit,shoe,shower,signal_strength,six,six_pointed_star,ski,skull,sleeping,sleepy,slot_machine,small_blue_diamond,small_orange_diamond,small_red_triangle,small_red_triangle_down,smile,smile_cat,smiley,smiley_cat,smiling_imp,smirk,smirk_cat,smoking,snail,snake,snowboarder,snowflake,snowman,sob,soccer,soon,sos,sound,space_invader,spades,spaghetti,sparkle,sparkler,sparkles,sparkling_heart,speak_no_evil,speaker,speech_balloon,speedboat,squirrel,star,star2,stars,station,statue_of_liberty,steam_locomotive,stew,straight_ruler,strawberry,stuck_out_tongue,stuck_out_tongue_closed_eyes,stuck_out_tongue_winking_eye,sun_with_face,sunflower,sunglasses,sunny,sunrise,sunrise_over_mountains,surfer,sushi,suspect,suspension_railway,sweat,sweat_drops,sweat_smile,sweet_potato,swimmer,symbols,syringe,tada,tanabata_tree,tangerine,taurus,taxi,tea,telephone,telephone_receiver,telescope,tennis,tent,thought_balloon,three,thumbsdown,thumbsup,ticket,tiger,tiger2,tired_face,tm,toilet,tokyo_tower,tomato,tongue,top,tophat,tractor,traffic_light,train,train2,tram,triangular_flag_on_post,triangular_ruler,trident,triumph,trolleybus,trollface,trophy,tropical_drink,tropical_fish,truck,trumpet,tshirt,tulip,turtle,tv,twisted_rightwards_arrows,two,two_hearts,two_men_holding_hands,two_women_holding_hands,u5272,u5408,u55b6,u6307,u6708,u6709,u6e80,u7121,u7533,u7981,u7a7a,uk,umbrella,unamused,underage,unlock,up,us,v,vertical_traffic_light,vhs,vibration_mode,video_camera,video_game,violin,virgo,volcano,vs,walking,waning_crescent_moon,waning_gibbous_moon,warning,watch,water_buffalo,watermelon,wave,wavy_dash,waxing_crescent_moon,waxing_gibbous_moon,wc,weary,wedding,whale,whale2,wheelchair,white_check_mark,white_circle,white_flower,white_large_square,white_medium_small_square,white_medium_square,white_small_square,white_square_button,wind_chime,wine_glass,wink,wolf,woman,womans_clothes,womans_hat,womens,worried,wrench,x,yellow_heart,yen,yum,zap,zero,zzz",r=(o+=",gitea").split(/,/),i=r.reduce(function(e,a){return e[a]=!0,e},{});function t(){var e={named:/:([a-z0-9A-Z_-]+):/,smile:/:-?\)/g,open_mouth:/:o/gi,scream:/:-o/gi,smirk:/[:;]-?]/g,grinning:/[:;]-?d/gi,stuck_out_tongue_closed_eyes:/x-d/gi,stuck_out_tongue_winking_eye:/[:;]-?p/gi,rage:/:-?[\[@]/g,frowning:/:-?\(/g,sob:/:['’]-?\(|:'\(/g,kissing_heart:/:-?\*/g,wink:/;-?\)/g,pensive:/:-?\//g,confounded:/:-?s/gi,flushed:/:-?\|/g,relaxed:/:-?\$/g,mask:/:-x/gi,heart:/<3|<3/g,broken_heart:/<\/3|</3/g,thumbsup:/:\+1:/g,thumbsdown:/:\-1:/g};return s.ignore_emoticons&&(e={named:/:([a-z0-9A-Z_-]+):/,thumbsup:/:\+1:/g,thumbsdown:/:\-1:/g}),Object.keys(e).map(function(a){return[e[a],a]})}function n(){var a=e.map(function(e){var a=e[0],o=a.source||a;return"("+(o=o.replace(/(^|[^\[])\^/g,"$1"))+")"}).join("|");return new RegExp(a,"gi")}var s={blacklist:{ids:[],classes:["no-emojify"],elements:["script","textarea","a","pre","code"]},tag_type:null,only_crawl_id:null,img_dir:"images/emoji",ignore_emoticons:!1,mode:"img"};function l(e){return" "===e||"\t"===e||"\r"===e||"\n"===e||""===e||e===String.fromCharCode(160)}var _={img:"img",sprite:"span","data-uri":"span"};function c(e){var a=null;if(e.replacer)a=e.replacer.apply({config:s},[":"+e.emojiName+":",e.emojiName]);else{var o=s.tag_type||_[s.mode];a=e.win.document.createElement(o),"img"!==o?a.setAttribute("class","emoji emoji-"+e.emojiName):(a.setAttribute("align","absmiddle"),a.setAttribute("alt",":"+e.emojiName+":"),a.setAttribute("class","emoji"),a.setAttribute("src",s.img_dir+"/"+e.emojiName+".png")),a.setAttribute("title",":"+e.emojiName+":")}e.node.splitText(e.match.index),e.node.nextSibling.nodeValue=e.node.nextSibling.nodeValue.substr(e.match[0].length,e.node.nextSibling.nodeValue.length),a.appendChild(e.node.splitText(e.match.index)),e.node.parentNode.insertBefore(a,e.node.nextSibling)}function u(a){if(a[1]&&a[2]){var o=a[2];return i[o]?o:void 0}for(var r=3;r":":"+a+":"}function m(){this.lastEmojiTerminatedAt=-1}return m.prototype={validate:function(e,a,o){var r=this,i=u(e);if(i){var t=e[0],n=t.length;if(0===a)return _();if(o.length===t.length+a)return _();var s=this.lastEmojiTerminatedAt===a;return s?_():l(o.charAt(a-1))?_():l(o.charAt(t.length+a))&&s?_():void 0}function _(){return r.lastEmojiTerminatedAt=n+a,i}}},{defaultConfig:s,emojiNames:r,setConfig:function(e){Object.keys(s).forEach(function(a){a in e&&(s[a]=e[a])})},replace:function(o,r){if(!o)return o;r||(r=g),e=t(),a=n();var i=new m;return o.replace(a,function(){var e=Array.prototype.slice.call(arguments,0,-2),a=arguments[arguments.length-2],o=arguments[arguments.length-1],t=i.validate(e,a,o);return t?r.apply({config:s},[arguments[0],t]):arguments[0]})},run:function(o,r){void 0===o&&(o=s.only_crawl_id?document.getElementById(s.only_crawl_id):document.body);var i=o.ownerDocument,l=i.defaultView||i.parentWindow,_=function(e,a){var o;if(e.hasChildNodes())for(o=e.firstChild;o;)a(o)&&_(o,a),o=o.nextSibling};e=t(),a=n();var g=[],d=new RegExp(s.blacklist.elements.join("|"),"i"),h=new RegExp(s.blacklist.classes.join("|"),"i");if(void 0!==l.document.createTreeWalker)for(var p,b=l.document.createTreeWalker(o,l.NodeFilter.SHOW_TEXT|l.NodeFilter.SHOW_ELEMENT,function(e){return 1!==e.nodeType?l.NodeFilter.FILTER_ACCEPT:e.tagName.match(d)||"svg"===e.tagName||e.className.match(h)?l.NodeFilter.FILTER_REJECT:l.NodeFilter.FILTER_SKIP},!1);null!==(p=b.nextNode());)g.push(p);else _(o,function(e){return!(void 0!==e.tagName&&e.tagName.match(d)||void 0!==e.className&&e.className.match(h)||1!==e.nodeType&&(g.push(e),0))});g.forEach(function(e){for(var o,i=[],t=new m;null!==(o=a.exec(e.data));)t.validate(o,o.index,o.input)&&i.push(o);for(var n=i.length;n-- >0;){var s=u(i[n]);c({node:e,match:i[n],emojiName:s,replacer:r,win:l})}})}}}()}); diff --git a/public/vendor/plugins/emojify/emojify.min.js b/public/vendor/plugins/emojify/emojify.min.js deleted file mode 100644 index 4fedf320523..00000000000 --- a/public/vendor/plugins/emojify/emojify.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! emojify.js - v1.0.5 - - * Copyright (c) Hassan Khan 2015 - */ -!function(e,a){"use strict";"function"==typeof define&&define.amd?define([],a):"object"==typeof exports?module.exports=a():e.emojify=a()}(this,function(){"use strict";var e=function(){function e(){var e={named:/:([a-z0-9A-Z_-]+):/,smile:/:-?\)/g,open_mouth:/:o/gi,scream:/:-o/gi,smirk:/[:;]-?]/g,grinning:/[:;]-?d/gi,stuck_out_tongue_closed_eyes:/x-d/gi,stuck_out_tongue_winking_eye:/[:;]-?p/gi,rage:/:-?[\[@]/g,frowning:/:-?\(/g,sob:/:['’]-?\(|:'\(/g,kissing_heart:/:-?\*/g,wink:/;-?\)/g,pensive:/:-?\//g,confounded:/:-?s/gi,flushed:/:-?\|/g,relaxed:/:-?\$/g,mask:/:-x/gi,heart:/<3|<3/g,broken_heart:/<\/3|</3/g,thumbsup:/:\+1:/g,thumbsdown:/:\-1:/g};return d.ignore_emoticons&&(e={named:/:([a-z0-9A-Z_-]+):/,thumbsup:/:\+1:/g,thumbsdown:/:\-1:/g}),Object.keys(e).map(function(a){return[e[a],a]})}function a(){var e=_.map(function(e){var a=e[0],o=a.source||a;return o=o.replace(/(^|[^\[])\^/g,"$1"),"("+o+")"}).join("|");return new RegExp(e,"gi")}function o(e){return" "===e||" "===e||"\r"===e||"\n"===e||""===e||e===String.fromCharCode(160)}function r(e){var a=null;if(e.replacer)a=e.replacer.apply({config:d},[":"+e.emojiName+":",e.emojiName]);else{var o=d.tag_type||h[d.mode];a=e.win.document.createElement(o),"img"!==o?a.setAttribute("class","emoji emoji-"+e.emojiName):(a.setAttribute("align","absmiddle"),a.setAttribute("alt",":"+e.emojiName+":"),a.setAttribute("class","emoji"),a.setAttribute("src",d.img_dir+"/"+e.emojiName+".png")),a.setAttribute("title",":"+e.emojiName+":")}e.node.splitText(e.match.index),e.node.nextSibling.nodeValue=e.node.nextSibling.nodeValue.substr(e.match[0].length,e.node.nextSibling.nodeValue.length),a.appendChild(e.node.splitText(e.match.index)),e.node.parentNode.insertBefore(a,e.node.nextSibling)}function t(e){if(e[1]&&e[2]){var a=e[2];if(m[a])return a}else for(var o=3;o":":"+a+":"}function n(){this.lastEmojiTerminatedAt=-1}function s(o,r){if(!o)return o;r||(r=i),_=e(),c=a();var t=new n;return o.replace(c,function(){var e=Array.prototype.slice.call(arguments,0,-2),a=arguments[arguments.length-2],o=arguments[arguments.length-1],i=t.validate(e,a,o);return i?r.apply({config:d},[arguments[0],i]):arguments[0]})}function l(o,i){"undefined"==typeof o&&(o=d.only_crawl_id?document.getElementById(d.only_crawl_id):document.body);var s=o.ownerDocument,l=s.defaultView||s.parentWindow,u=function(e,a){var o;if(e.hasChildNodes())for(o=e.firstChild;o;)a(o)&&u(o,a),o=o.nextSibling},g=function(e){for(var a,o=[],s=new n;null!==(a=c.exec(e.data));)s.validate(a,a.index,a.input)&&o.push(a);for(var _=o.length;_-->0;){var u=t(o[_]);r({node:e,match:o[_],emojiName:u,replacer:i,win:l})}};_=e(),c=a();var m=[],h=new RegExp(d.blacklist.elements.join("|"),"i"),p=new RegExp(d.blacklist.classes.join("|"),"i");if("undefined"!=typeof l.document.createTreeWalker)for(var b,f=l.document.createTreeWalker(o,l.NodeFilter.SHOW_TEXT|l.NodeFilter.SHOW_ELEMENT,function(e){return 1!==e.nodeType?l.NodeFilter.FILTER_ACCEPT:e.tagName.match(h)||"svg"===e.tagName||e.className.match(p)?l.NodeFilter.FILTER_REJECT:l.NodeFilter.FILTER_SKIP},!1);null!==(b=f.nextNode());)m.push(b);else u(o,function(e){return"undefined"!=typeof e.tagName&&e.tagName.match(h)||"undefined"!=typeof e.className&&e.className.match(p)?!1:1===e.nodeType?!0:(m.push(e),!0)});m.forEach(g)}var _,c,u="+1,-1,100,1234,8ball,a,ab,abc,abcd,accept,aerial_tramway,airplane,alarm_clock,alien,ambulance,anchor,angel,anger,angry,anguished,ant,apple,aquarius,aries,arrow_backward,arrow_double_down,arrow_double_up,arrow_down,arrow_down_small,arrow_forward,arrow_heading_down,arrow_heading_up,arrow_left,arrow_lower_left,arrow_lower_right,arrow_right,arrow_right_hook,arrow_up,arrow_up_down,arrow_up_small,arrow_upper_left,arrow_upper_right,arrows_clockwise,arrows_counterclockwise,art,articulated_lorry,astonished,atm,b,baby,baby_bottle,baby_chick,baby_symbol,back,baggage_claim,balloon,ballot_box_with_check,bamboo,banana,bangbang,bank,bar_chart,barber,baseball,basketball,bath,bathtub,battery,bear,bee,beer,beers,beetle,beginner,bell,bento,bicyclist,bike,bikini,bird,birthday,black_circle,black_joker,black_medium_small_square,black_medium_square,black_nib,black_small_square,black_square,black_square_button,blossom,blowfish,blue_book,blue_car,blue_heart,blush,boar,boat,bomb,book,bookmark,bookmark_tabs,books,boom,boot,bouquet,bow,bowling,bowtie,boy,bread,bride_with_veil,bridge_at_night,briefcase,broken_heart,bug,bulb,bullettrain_front,bullettrain_side,bus,busstop,bust_in_silhouette,busts_in_silhouette,cactus,cake,calendar,calling,camel,camera,cancer,candy,capital_abcd,capricorn,car,card_index,carousel_horse,cat,cat2,cd,chart,chart_with_downwards_trend,chart_with_upwards_trend,checkered_flag,cherries,cherry_blossom,chestnut,chicken,children_crossing,chocolate_bar,christmas_tree,church,cinema,circus_tent,city_sunrise,city_sunset,cl,clap,clapper,clipboard,clock1,clock10,clock1030,clock11,clock1130,clock12,clock1230,clock130,clock2,clock230,clock3,clock330,clock4,clock430,clock5,clock530,clock6,clock630,clock7,clock730,clock8,clock830,clock9,clock930,closed_book,closed_lock_with_key,closed_umbrella,cloud,clubs,cn,cocktail,coffee,cold_sweat,collision,computer,confetti_ball,confounded,confused,congratulations,construction,construction_worker,convenience_store,cookie,cool,cop,copyright,corn,couple,couple_with_heart,couplekiss,cow,cow2,credit_card,crescent_moon,crocodile,crossed_flags,crown,cry,crying_cat_face,crystal_ball,cupid,curly_loop,currency_exchange,curry,custard,customs,cyclone,dancer,dancers,dango,dart,dash,date,de,deciduous_tree,department_store,diamond_shape_with_a_dot_inside,diamonds,disappointed,disappointed_relieved,dizzy,dizzy_face,do_not_litter,dog,dog2,dollar,dolls,dolphin,donut,door,doughnut,dragon,dragon_face,dress,dromedary_camel,droplet,dvd,e-mail,ear,ear_of_rice,earth_africa,earth_americas,earth_asia,egg,eggplant,eight,eight_pointed_black_star,eight_spoked_asterisk,electric_plug,elephant,email,end,envelope,es,euro,european_castle,european_post_office,evergreen_tree,exclamation,expressionless,eyeglasses,eyes,facepunch,factory,fallen_leaf,family,fast_forward,fax,fearful,feelsgood,feet,ferris_wheel,file_folder,finnadie,fire,fire_engine,fireworks,first_quarter_moon,first_quarter_moon_with_face,fish,fish_cake,fishing_pole_and_fish,fist,five,flags,flashlight,floppy_disk,flower_playing_cards,flushed,foggy,football,fork_and_knife,fountain,four,four_leaf_clover,fr,free,fried_shrimp,fries,frog,frowning,fu,fuelpump,full_moon,full_moon_with_face,game_die,gb,gem,gemini,ghost,gift,gift_heart,girl,globe_with_meridians,goat,goberserk,godmode,golf,grapes,green_apple,green_book,green_heart,grey_exclamation,grey_question,grimacing,grin,grinning,guardsman,guitar,gun,haircut,hamburger,hammer,hamster,hand,handbag,hankey,hash,hatched_chick,hatching_chick,headphones,hear_no_evil,heart,heart_decoration,heart_eyes,heart_eyes_cat,heartbeat,heartpulse,hearts,heavy_check_mark,heavy_division_sign,heavy_dollar_sign,heavy_exclamation_mark,heavy_minus_sign,heavy_multiplication_x,heavy_plus_sign,helicopter,herb,hibiscus,high_brightness,high_heel,hocho,honey_pot,honeybee,horse,horse_racing,hospital,hotel,hotsprings,hourglass,hourglass_flowing_sand,house,house_with_garden,hurtrealbad,hushed,ice_cream,icecream,id,ideograph_advantage,imp,inbox_tray,incoming_envelope,information_desk_person,information_source,innocent,interrobang,iphone,it,izakaya_lantern,jack_o_lantern,japan,japanese_castle,japanese_goblin,japanese_ogre,jeans,joy,joy_cat,jp,key,keycap_ten,kimono,kiss,kissing,kissing_cat,kissing_closed_eyes,kissing_face,kissing_heart,kissing_smiling_eyes,koala,koko,kr,large_blue_circle,large_blue_diamond,large_orange_diamond,last_quarter_moon,last_quarter_moon_with_face,laughing,leaves,ledger,left_luggage,left_right_arrow,leftwards_arrow_with_hook,lemon,leo,leopard,libra,light_rail,link,lips,lipstick,lock,lock_with_ink_pen,lollipop,loop,loudspeaker,love_hotel,love_letter,low_brightness,m,mag,mag_right,mahjong,mailbox,mailbox_closed,mailbox_with_mail,mailbox_with_no_mail,man,man_with_gua_pi_mao,man_with_turban,mans_shoe,maple_leaf,mask,massage,meat_on_bone,mega,melon,memo,mens,metal,metro,microphone,microscope,milky_way,minibus,minidisc,mobile_phone_off,money_with_wings,moneybag,monkey,monkey_face,monorail,mortar_board,mount_fuji,mountain_bicyclist,mountain_cableway,mountain_railway,mouse,mouse2,movie_camera,moyai,muscle,mushroom,musical_keyboard,musical_note,musical_score,mute,nail_care,name_badge,neckbeard,necktie,negative_squared_cross_mark,neutral_face,new,new_moon,new_moon_with_face,newspaper,ng,nine,no_bell,no_bicycles,no_entry,no_entry_sign,no_good,no_mobile_phones,no_mouth,no_pedestrians,no_smoking,non-potable_water,nose,notebook,notebook_with_decorative_cover,notes,nut_and_bolt,o,o2,ocean,octocat,octopus,oden,office,ok,ok_hand,ok_woman,older_man,older_woman,on,oncoming_automobile,oncoming_bus,oncoming_police_car,oncoming_taxi,one,open_file_folder,open_hands,open_mouth,ophiuchus,orange_book,outbox_tray,ox,package,page_facing_up,page_with_curl,pager,palm_tree,panda_face,paperclip,parking,part_alternation_mark,partly_sunny,passport_control,paw_prints,peach,pear,pencil,pencil2,penguin,pensive,performing_arts,persevere,person_frowning,person_with_blond_hair,person_with_pouting_face,phone,pig,pig2,pig_nose,pill,pineapple,pisces,pizza,plus1,point_down,point_left,point_right,point_up,point_up_2,police_car,poodle,poop,post_office,postal_horn,postbox,potable_water,pouch,poultry_leg,pound,pouting_cat,pray,princess,punch,purple_heart,purse,pushpin,put_litter_in_its_place,question,rabbit,rabbit2,racehorse,radio,radio_button,rage,rage1,rage2,rage3,rage4,railway_car,rainbow,raised_hand,raised_hands,raising_hand,ram,ramen,rat,recycle,red_car,red_circle,registered,relaxed,relieved,repeat,repeat_one,restroom,revolving_hearts,rewind,ribbon,rice,rice_ball,rice_cracker,rice_scene,ring,rocket,roller_coaster,rooster,rose,rotating_light,round_pushpin,rowboat,ru,rugby_football,runner,running,running_shirt_with_sash,sa,sagittarius,sailboat,sake,sandal,santa,satellite,satisfied,saxophone,school,school_satchel,scissors,scorpius,scream,scream_cat,scroll,seat,secret,see_no_evil,seedling,seven,shaved_ice,sheep,shell,ship,shipit,shirt,shit,shoe,shower,signal_strength,six,six_pointed_star,ski,skull,sleeping,sleepy,slot_machine,small_blue_diamond,small_orange_diamond,small_red_triangle,small_red_triangle_down,smile,smile_cat,smiley,smiley_cat,smiling_imp,smirk,smirk_cat,smoking,snail,snake,snowboarder,snowflake,snowman,sob,soccer,soon,sos,sound,space_invader,spades,spaghetti,sparkle,sparkler,sparkles,sparkling_heart,speak_no_evil,speaker,speech_balloon,speedboat,squirrel,star,star2,stars,station,statue_of_liberty,steam_locomotive,stew,straight_ruler,strawberry,stuck_out_tongue,stuck_out_tongue_closed_eyes,stuck_out_tongue_winking_eye,sun_with_face,sunflower,sunglasses,sunny,sunrise,sunrise_over_mountains,surfer,sushi,suspect,suspension_railway,sweat,sweat_drops,sweat_smile,sweet_potato,swimmer,symbols,syringe,tada,tanabata_tree,tangerine,taurus,taxi,tea,telephone,telephone_receiver,telescope,tennis,tent,thought_balloon,three,thumbsdown,thumbsup,ticket,tiger,tiger2,tired_face,tm,toilet,tokyo_tower,tomato,tongue,top,tophat,tractor,traffic_light,train,train2,tram,triangular_flag_on_post,triangular_ruler,trident,triumph,trolleybus,trollface,trophy,tropical_drink,tropical_fish,truck,trumpet,tshirt,tulip,turtle,tv,twisted_rightwards_arrows,two,two_hearts,two_men_holding_hands,two_women_holding_hands,u5272,u5408,u55b6,u6307,u6708,u6709,u6e80,u7121,u7533,u7981,u7a7a,uk,umbrella,unamused,underage,unlock,up,us,v,vertical_traffic_light,vhs,vibration_mode,video_camera,video_game,violin,virgo,volcano,vs,walking,waning_crescent_moon,waning_gibbous_moon,warning,watch,water_buffalo,watermelon,wave,wavy_dash,waxing_crescent_moon,waxing_gibbous_moon,wc,weary,wedding,whale,whale2,wheelchair,white_check_mark,white_circle,white_flower,white_large_square,white_medium_small_square,white_medium_square,white_small_square,white_square_button,wind_chime,wine_glass,wink,wolf,woman,womans_clothes,womans_hat,womens,worried,wrench,x,yellow_heart,yen,yum,zap,zero,zzz",g=u.split(/,/),m=g.reduce(function(e,a){return e[a]=!0,e},{}),d={blacklist:{ids:[],classes:["no-emojify"],elements:["script","textarea","a","pre","code"]},tag_type:null,only_crawl_id:null,img_dir:"images/emoji",ignore_emoticons:!1,mode:"img"},h={img:"img",sprite:"span","data-uri":"span"};return n.prototype={validate:function(e,a,r){function i(){return n.lastEmojiTerminatedAt=_+a,s}var n=this,s=t(e);if(s){var l=e[0],_=l.length;if(0===a)return i();if(r.length===l.length+a)return i();var c=this.lastEmojiTerminatedAt===a;if(c)return i();if(o(r.charAt(a-1)))return i();var u=o(r.charAt(l.length+a));return u&&c?i():void 0}}},{defaultConfig:d,emojiNames:g,setConfig:function(e){Object.keys(d).forEach(function(a){a in e&&(d[a]=e[a])})},replace:s,run:l}}();return e}); \ No newline at end of file diff --git a/public/vendor/plugins/emojify/images/gitea.png b/public/vendor/plugins/emojify/images/gitea.png new file mode 100644 index 00000000000..466194a1adf Binary files /dev/null and b/public/vendor/plugins/emojify/images/gitea.png differ diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 538d01f9a4e..4c4738ae8c0 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -6,6 +6,7 @@ package admin import ( + "encoding/json" "fmt" "net/url" "os" @@ -25,6 +26,7 @@ import ( "code.gitea.io/gitea/services/mailer" "gitea.com/macaron/macaron" + "gitea.com/macaron/session" "github.com/unknwon/com" ) @@ -207,7 +209,7 @@ func SendTestMail(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/admin/config") } -func shadownPasswordKV(cfgItem, splitter string) string { +func shadowPasswordKV(cfgItem, splitter string) string { fields := strings.Split(cfgItem, splitter) for i := 0; i < len(fields); i++ { if strings.HasPrefix(fields[i], "password=") { @@ -218,10 +220,10 @@ func shadownPasswordKV(cfgItem, splitter string) string { return strings.Join(fields, splitter) } -func shadownURL(provider, cfgItem string) string { +func shadowURL(provider, cfgItem string) string { u, err := url.Parse(cfgItem) if err != nil { - log.Error("shodowPassword %v failed: %v", provider, err) + log.Error("Shadowing Password for %v failed: %v", provider, err) return cfgItem } if u.User != nil { @@ -239,7 +241,7 @@ func shadownURL(provider, cfgItem string) string { func shadowPassword(provider, cfgItem string) string { switch provider { case "redis": - return shadownPasswordKV(cfgItem, ",") + return shadowPasswordKV(cfgItem, ",") case "mysql": //root:@tcp(localhost:3306)/macaron?charset=utf8 atIdx := strings.Index(cfgItem, "@") @@ -253,15 +255,21 @@ func shadowPassword(provider, cfgItem string) string { case "postgres": // user=jiahuachen dbname=macaron port=5432 sslmode=disable if !strings.HasPrefix(cfgItem, "postgres://") { - return shadownPasswordKV(cfgItem, " ") + return shadowPasswordKV(cfgItem, " ") } - + fallthrough + case "couchbase": + return shadowURL(provider, cfgItem) // postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full - // Notice: use shadwonURL + // Notice: use shadowURL + case "VirtualSession": + var realSession session.Options + if err := json.Unmarshal([]byte(cfgItem), &realSession); err == nil { + return shadowPassword(realSession.Provider, realSession.ProviderConfig) + } } - // "couchbase" - return shadownURL(provider, cfgItem) + return cfgItem } // Config show admin config page diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index f7aa366b17c..151475a8e94 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -631,15 +631,13 @@ func Edit(ctx *context.APIContext, opts api.EditRepoOption) { func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) error { owner := ctx.Repo.Owner repo := ctx.Repo.Repository - - oldRepoName := repo.Name newRepoName := repo.Name if opts.Name != nil { newRepoName = *opts.Name } // Check if repository name has been changed and not just a case change if repo.LowerName != strings.ToLower(newRepoName) { - if err := models.ChangeRepositoryName(ctx.Repo.Owner, repo.Name, newRepoName); err != nil { + if err := repo_service.ChangeRepositoryName(ctx.User, repo, newRepoName); err != nil { switch { case models.IsErrRepoAlreadyExist(err): ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is already taken [name: %s]", newRepoName), err) @@ -653,14 +651,6 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err return err } - err := models.NewRepoRedirect(ctx.Repo.Owner.ID, repo.ID, repo.Name, newRepoName) - if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "NewRepoRedirect", err) - return err - } - - notification.NotifyRenameRepository(ctx.User, repo, oldRepoName) - log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newRepoName) } // Update the name in the repo object for the response diff --git a/routers/repo/commit.go b/routers/repo/commit.go index f067729ca94..2a123a2eb9b 100644 --- a/routers/repo/commit.go +++ b/routers/repo/commit.go @@ -245,6 +245,7 @@ func Diff(ctx *context.Context) { } ctx.Data["CommitID"] = commitID + ctx.Data["AfterCommitID"] = commitID ctx.Data["Username"] = userName ctx.Data["Reponame"] = repoName diff --git a/routers/repo/compare.go b/routers/repo/compare.go index e45f0464353..203b740082d 100644 --- a/routers/repo/compare.go +++ b/routers/repo/compare.go @@ -5,21 +5,26 @@ package repo import ( + "bufio" "fmt" + "html" "path" + "path/filepath" "strings" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/highlight" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/services/gitdiff" ) const ( - tplCompare base.TplName = "repo/diff/compare" + tplCompare base.TplName = "repo/diff/compare" + tplBlobExcerpt base.TplName = "repo/diff/blob_excerpt" ) // setPathsCompareContext sets context data for source and raw paths @@ -434,3 +439,109 @@ func CompareDiff(ctx *context.Context) { ctx.HTML(200, tplCompare) } + +// ExcerptBlob render blob excerpt contents +func ExcerptBlob(ctx *context.Context) { + commitID := ctx.Params("sha") + lastLeft := ctx.QueryInt("last_left") + lastRight := ctx.QueryInt("last_right") + idxLeft := ctx.QueryInt("left") + idxRight := ctx.QueryInt("right") + leftHunkSize := ctx.QueryInt("left_hunk_size") + rightHunkSize := ctx.QueryInt("right_hunk_size") + anchor := ctx.Query("anchor") + direction := ctx.Query("direction") + filePath := ctx.Query("path") + gitRepo := ctx.Repo.GitRepo + chunkSize := gitdiff.BlobExceprtChunkSize + commit, err := gitRepo.GetCommit(commitID) + if err != nil { + ctx.Error(500, "GetCommit") + return + } + section := &gitdiff.DiffSection{ + Name: filePath, + } + if direction == "up" && (idxLeft-lastLeft) > chunkSize { + idxLeft -= chunkSize + idxRight -= chunkSize + leftHunkSize += chunkSize + rightHunkSize += chunkSize + section.Lines, err = getExcerptLines(commit, filePath, idxLeft-1, idxRight-1, chunkSize) + } else if direction == "down" && (idxLeft-lastLeft) > chunkSize { + section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, chunkSize) + lastLeft += chunkSize + lastRight += chunkSize + } else { + section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, idxRight-lastRight-1) + leftHunkSize = 0 + rightHunkSize = 0 + idxLeft = lastLeft + idxRight = lastRight + } + if err != nil { + ctx.Error(500, "getExcerptLines") + return + } + if idxRight > lastRight { + lineText := " " + if rightHunkSize > 0 || leftHunkSize > 0 { + lineText = fmt.Sprintf("@@ -%d,%d +%d,%d @@\n", idxLeft, leftHunkSize, idxRight, rightHunkSize) + } + lineText = html.EscapeString(lineText) + lineSection := &gitdiff.DiffLine{ + Type: gitdiff.DiffLineSection, + Content: lineText, + SectionInfo: &gitdiff.DiffLineSectionInfo{ + Path: filePath, + LastLeftIdx: lastLeft, + LastRightIdx: lastRight, + LeftIdx: idxLeft, + RightIdx: idxRight, + LeftHunkSize: leftHunkSize, + RightHunkSize: rightHunkSize, + }} + if direction == "up" { + section.Lines = append([]*gitdiff.DiffLine{lineSection}, section.Lines...) + } else if direction == "down" { + section.Lines = append(section.Lines, lineSection) + } + } + ctx.Data["section"] = section + ctx.Data["fileName"] = filePath + ctx.Data["highlightClass"] = highlight.FileNameToHighlightClass(filepath.Base(filePath)) + ctx.Data["AfterCommitID"] = commitID + ctx.Data["Anchor"] = anchor + ctx.HTML(200, tplBlobExcerpt) +} + +func getExcerptLines(commit *git.Commit, filePath string, idxLeft int, idxRight int, chunkSize int) ([]*gitdiff.DiffLine, error) { + blob, err := commit.Tree.GetBlobByPath(filePath) + if err != nil { + return nil, err + } + reader, err := blob.DataAsync() + if err != nil { + return nil, err + } + defer reader.Close() + scanner := bufio.NewScanner(reader) + var diffLines []*gitdiff.DiffLine + for line := 0; line < idxRight+chunkSize; line++ { + if ok := scanner.Scan(); !ok { + break + } + if line < idxRight { + continue + } + lineText := scanner.Text() + diffLine := &gitdiff.DiffLine{ + LeftIdx: idxLeft + (line - idxRight) + 1, + RightIdx: line + 1, + Type: gitdiff.DiffLinePlain, + Content: " " + lineText, + } + diffLines = append(diffLines, diffLine) + } + return diffLines, nil +} diff --git a/routers/repo/pull.go b/routers/repo/pull.go index 67849f33e12..a1a4e5e2bbe 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -552,6 +552,7 @@ func ViewPullFiles(ctx *context.Context) { ctx.Data["Username"] = pull.MustHeadUserName() ctx.Data["Reponame"] = pull.HeadRepo.Name } + ctx.Data["AfterCommitID"] = endCommitID diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(diffRepoPath, startCommitID, endCommitID, setting.Git.MaxGitDiffLines, diff --git a/routers/repo/pull_review.go b/routers/repo/pull_review.go index 7d030988fd9..b596d2578b6 100644 --- a/routers/repo/pull_review.go +++ b/routers/repo/pull_review.go @@ -11,8 +11,6 @@ import ( "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/notification" - comment_service "code.gitea.io/gitea/services/comments" pull_service "code.gitea.io/gitea/services/pull" ) @@ -31,64 +29,33 @@ func CreateCodeComment(ctx *context.Context, form auth.CodeCommentForm) { ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index)) return } - var comment *models.Comment - defer func() { - if comment != nil { - ctx.Redirect(comment.HTMLURL()) - } else { - ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index)) - } - }() + signedLine := form.Line if form.Side == "previous" { signedLine *= -1 } - review := new(models.Review) - if form.IsReview { - var err error - // Check if the user has already a pending review for this issue - if review, err = models.GetCurrentReview(ctx.User, issue); err != nil { - if !models.IsErrReviewNotExist(err) { - ctx.ServerError("CreateCodeComment", err) - return - } - // No pending review exists - // Create a new pending review for this issue & user - if review, err = pull_service.CreateReview(models.CreateReviewOptions{ - Type: models.ReviewTypePending, - Reviewer: ctx.User, - Issue: issue, - }); err != nil { - ctx.ServerError("CreateCodeComment", err) - return - } - - } - } - if review.ID == 0 { - review.ID = form.Reply - } - //FIXME check if line, commit and treepath exist - comment, err := comment_service.CreateCodeComment( + comment, err := pull_service.CreateCodeComment( ctx.User, - issue.Repo, issue, + signedLine, form.Content, form.TreePath, - signedLine, - review.ID, + form.IsReview, + form.Reply, ) if err != nil { ctx.ServerError("CreateCodeComment", err) return } - // Send no notification if comment is pending - if !form.IsReview || form.Reply != 0 { - notification.NotifyCreateIssueComment(ctx.User, issue.Repo, issue, comment) - } log.Trace("Comment created: %d/%d/%d", ctx.Repo.Repository.ID, issue.ID, comment.ID) + + if comment != nil { + ctx.Redirect(comment.HTMLURL()) + } else { + ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index)) + } } // SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist @@ -105,23 +72,17 @@ func SubmitReview(ctx *context.Context, form auth.SubmitReviewForm) { ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index)) return } - var review *models.Review - var err error reviewType := form.ReviewType() - switch reviewType { case models.ReviewTypeUnknown: - ctx.ServerError("GetCurrentReview", fmt.Errorf("unknown ReviewType: %s", form.Type)) + ctx.ServerError("ReviewType", fmt.Errorf("unknown ReviewType: %s", form.Type)) return // can not approve/reject your own PR case models.ReviewTypeApprove, models.ReviewTypeReject: - if issue.Poster.ID == ctx.User.ID { - var translated string - if reviewType == models.ReviewTypeApprove { translated = ctx.Tr("repo.issues.review.self.approval") } else { @@ -134,69 +95,16 @@ func SubmitReview(ctx *context.Context, form auth.SubmitReviewForm) { } } - review, err = models.GetCurrentReview(ctx.User, issue) - if err == nil { - review.Issue = issue - if errl := review.LoadCodeComments(); errl != nil { - ctx.ServerError("LoadCodeComments", err) - return - } - } - - if ((err == nil && len(review.CodeComments) == 0) || - (err != nil && models.IsErrReviewNotExist(err))) && - form.HasEmptyContent() { - ctx.Flash.Error(ctx.Tr("repo.issues.review.content.empty")) - ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index)) - return - } - + _, comm, err := pull_service.SubmitReview(ctx.User, issue, reviewType, form.Content) if err != nil { - if !models.IsErrReviewNotExist(err) { - ctx.ServerError("GetCurrentReview", err) - return + if models.IsContentEmptyErr(err) { + ctx.Flash.Error(ctx.Tr("repo.issues.review.content.empty")) + ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index)) + } else { + ctx.ServerError("SubmitReview", err) } - // No current review. Create a new one! - if review, err = pull_service.CreateReview(models.CreateReviewOptions{ - Type: reviewType, - Issue: issue, - Reviewer: ctx.User, - Content: form.Content, - }); err != nil { - ctx.ServerError("CreateReview", err) - return - } - } else { - review.Content = form.Content - review.Type = reviewType - if err = pull_service.UpdateReview(review); err != nil { - ctx.ServerError("UpdateReview", err) - return - } - } - comm, err := models.CreateComment(&models.CreateCommentOptions{ - Type: models.CommentTypeReview, - Doer: ctx.User, - Content: review.Content, - Issue: issue, - Repo: issue.Repo, - ReviewID: review.ID, - }) - if err != nil || comm == nil { - ctx.ServerError("CreateComment", err) return } - if err = review.Publish(); err != nil { - ctx.ServerError("Publish", err) - return - } - - pr, err := issue.GetPullRequest() - if err != nil { - ctx.ServerError("GetPullRequest", err) - return - } - notification.NotifyPullRequestReview(pr, review, comm) ctx.Redirect(fmt.Sprintf("%s/pulls/%d#%s", ctx.Repo.RepoLink, issue.Index, comm.HashTag())) } diff --git a/routers/repo/setting.go b/routers/repo/setting.go index fa215357d2d..a3650b19012 100644 --- a/routers/repo/setting.go +++ b/routers/repo/setting.go @@ -20,7 +20,6 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/validation" @@ -67,18 +66,15 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { return } - isNameChanged := false - oldRepoName := repo.Name newRepoName := form.RepoName // Check if repository name has been changed. if repo.LowerName != strings.ToLower(newRepoName) { - isNameChanged = true // Close the GitRepo if open if ctx.Repo.GitRepo != nil { ctx.Repo.GitRepo.Close() ctx.Repo.GitRepo = nil } - if err := models.ChangeRepositoryName(ctx.Repo.Owner, repo.Name, newRepoName); err != nil { + if err := repo_service.ChangeRepositoryName(ctx.Repo.Owner, repo, newRepoName); err != nil { ctx.Data["Err_RepoName"] = true switch { case models.IsErrRepoAlreadyExist(err): @@ -93,12 +89,6 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { return } - err := models.NewRepoRedirect(ctx.Repo.Owner.ID, repo.ID, repo.Name, newRepoName) - if err != nil { - ctx.ServerError("NewRepoRedirect", err) - return - } - log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newRepoName) } // In case it's just a case change. @@ -127,10 +117,6 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { } log.Trace("Repository basic settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name) - if isNameChanged { - notification.NotifyRenameRepository(ctx.User, repo, oldRepoName) - } - ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success")) ctx.Redirect(repo.Link() + "/settings") @@ -383,13 +369,12 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { return } - oldOwnerID := ctx.Repo.Owner.ID // Close the GitRepo if open if ctx.Repo.GitRepo != nil { ctx.Repo.GitRepo.Close() ctx.Repo.GitRepo = nil } - if err = models.TransferOwnership(ctx.User, newOwner, repo); err != nil { + if err = repo_service.TransferOwnership(ctx.User, newOwner, repo); err != nil { if models.IsErrRepoAlreadyExist(err) { ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil) } else { @@ -398,12 +383,6 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { return } - err = models.NewRepoRedirect(oldOwnerID, repo.ID, repo.Name, repo.Name) - if err != nil { - ctx.ServerError("NewRepoRedirect", err) - return - } - log.Trace("Repository transferred: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newOwner) ctx.Flash.Success(ctx.Tr("repo.settings.transfer_succeed")) ctx.Redirect(setting.AppSubURL + "/" + newOwner + "/" + repo.Name) @@ -707,6 +686,7 @@ func GitHooks(ctx *context.Context) { func GitHooksEdit(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("repo.settings.githooks") ctx.Data["PageIsSettingsGitHooks"] = true + ctx.Data["RequireSimpleMDE"] = true name := ctx.Params(":name") hook, err := ctx.Repo.GitRepo.GetHook(name) diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 13a5bb27084..48bba16bf6f 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -864,6 +864,10 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("", repo.Branches) }, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) + m.Group("/blob_excerpt", func() { + m.Get("/:sha", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob) + }, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) + m.Group("/pulls/:index", func() { m.Get(".diff", repo.DownloadPullDiff) m.Get(".patch", repo.DownloadPullPatch) diff --git a/services/comments/comments.go b/services/comments/comments.go index ba40bf582d3..ed479e71107 100644 --- a/services/comments/comments.go +++ b/services/comments/comments.go @@ -5,15 +5,8 @@ package comments import ( - "bytes" - "fmt" - "strings" - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/notification" - "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/services/gitdiff" ) // CreateIssueComment creates a plain issue comment. @@ -35,60 +28,6 @@ func CreateIssueComment(doer *models.User, repo *models.Repository, issue *model return comment, nil } -// CreateCodeComment creates a plain code comment at the specified line / path -func CreateCodeComment(doer *models.User, repo *models.Repository, issue *models.Issue, content, treePath string, line, reviewID int64) (*models.Comment, error) { - var commitID, patch string - pr, err := models.GetPullRequestByIssueID(issue.ID) - if err != nil { - return nil, fmt.Errorf("GetPullRequestByIssueID: %v", err) - } - if err := pr.GetBaseRepo(); err != nil { - return nil, fmt.Errorf("GetHeadRepo: %v", err) - } - gitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath()) - if err != nil { - return nil, fmt.Errorf("OpenRepository: %v", err) - } - defer gitRepo.Close() - - // FIXME validate treePath - // Get latest commit referencing the commented line - // No need for get commit for base branch changes - if line > 0 { - commit, err := gitRepo.LineBlame(pr.GetGitRefName(), gitRepo.Path, treePath, uint(line)) - if err == nil { - commitID = commit.ID.String() - } else if !strings.Contains(err.Error(), "exit status 128 - fatal: no such path") { - return nil, fmt.Errorf("LineBlame[%s, %s, %s, %d]: %v", pr.GetGitRefName(), gitRepo.Path, treePath, line, err) - } - } - - // Only fetch diff if comment is review comment - if reviewID != 0 { - headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitRefName()) - if err != nil { - return nil, fmt.Errorf("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err) - } - patchBuf := new(bytes.Buffer) - if err := gitdiff.GetRawDiffForFile(gitRepo.Path, pr.MergeBase, headCommitID, gitdiff.RawDiffNormal, treePath, patchBuf); err != nil { - return nil, fmt.Errorf("GetRawDiffForLine[%s, %s, %s, %s]: %v", err, gitRepo.Path, pr.MergeBase, headCommitID, treePath) - } - patch = gitdiff.CutDiffAroundLine(patchBuf, int64((&models.Comment{Line: line}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) - } - return models.CreateComment(&models.CreateCommentOptions{ - Type: models.CommentTypeCode, - Doer: doer, - Repo: repo, - Issue: issue, - Content: content, - LineNum: line, - TreePath: treePath, - CommitSHA: commitID, - ReviewID: reviewID, - Patch: patch, - }) -} - // UpdateComment updates information of comment. func UpdateComment(c *models.Comment, doer *models.User, oldContent string) error { if err := models.UpdateComment(c, doer); err != nil { diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 9c2aef5c97c..69c8f5603ab 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -13,6 +13,7 @@ import ( "html/template" "io" "io/ioutil" + "net/url" "os" "os/exec" "regexp" @@ -56,15 +57,42 @@ const ( DiffFileRename ) +// DiffLineExpandDirection represents the DiffLineSection expand direction +type DiffLineExpandDirection uint8 + +// DiffLineExpandDirection possible values. +const ( + DiffLineExpandNone DiffLineExpandDirection = iota + 1 + DiffLineExpandSingle + DiffLineExpandUpDown + DiffLineExpandUp + DiffLineExpandDown +) + // DiffLine represents a line difference in a DiffSection. type DiffLine struct { - LeftIdx int - RightIdx int - Type DiffLineType - Content string - Comments []*models.Comment + LeftIdx int + RightIdx int + Type DiffLineType + Content string + Comments []*models.Comment + SectionInfo *DiffLineSectionInfo } +// DiffLineSectionInfo represents diff line section meta data +type DiffLineSectionInfo struct { + Path string + LastLeftIdx int + LastRightIdx int + LeftIdx int + RightIdx int + LeftHunkSize int + RightHunkSize int +} + +// BlobExceprtChunkSize represent max lines of excerpt +const BlobExceprtChunkSize = 20 + // GetType returns the type of a DiffLine. func (d *DiffLine) GetType() int { return int(d.Type) @@ -91,6 +119,71 @@ func (d *DiffLine) GetLineTypeMarker() string { return "" } +// GetBlobExcerptQuery builds query string to get blob excerpt +func (d *DiffLine) GetBlobExcerptQuery() string { + query := fmt.Sprintf( + "last_left=%d&last_right=%d&"+ + "left=%d&right=%d&"+ + "left_hunk_size=%d&right_hunk_size=%d&"+ + "path=%s", + d.SectionInfo.LastLeftIdx, d.SectionInfo.LastRightIdx, + d.SectionInfo.LeftIdx, d.SectionInfo.RightIdx, + d.SectionInfo.LeftHunkSize, d.SectionInfo.RightHunkSize, + url.QueryEscape(d.SectionInfo.Path)) + return query +} + +// GetExpandDirection gets DiffLineExpandDirection +func (d *DiffLine) GetExpandDirection() DiffLineExpandDirection { + if d.Type != DiffLineSection || d.SectionInfo == nil || d.SectionInfo.RightIdx-d.SectionInfo.LastRightIdx <= 1 { + return DiffLineExpandNone + } + if d.SectionInfo.LastLeftIdx <= 0 && d.SectionInfo.LastRightIdx <= 0 { + return DiffLineExpandUp + } else if d.SectionInfo.RightIdx-d.SectionInfo.LastRightIdx > BlobExceprtChunkSize && d.SectionInfo.RightHunkSize > 0 { + return DiffLineExpandUpDown + } else if d.SectionInfo.LeftHunkSize <= 0 && d.SectionInfo.RightHunkSize <= 0 { + return DiffLineExpandDown + } + return DiffLineExpandSingle +} + +func getDiffLineSectionInfo(curFile *DiffFile, line string, lastLeftIdx, lastRightIdx int) *DiffLineSectionInfo { + var ( + leftLine int + leftHunk int + rightLine int + righHunk int + ) + ss := strings.Split(line, "@@") + ranges := strings.Split(ss[1][1:], " ") + leftRange := strings.Split(ranges[0], ",") + leftLine, _ = com.StrTo(leftRange[0][1:]).Int() + if len(leftRange) > 1 { + leftHunk, _ = com.StrTo(leftRange[1]).Int() + } + if len(ranges) > 1 { + rightRange := strings.Split(ranges[1], ",") + rightLine, _ = com.StrTo(rightRange[0]).Int() + if len(rightRange) > 1 { + righHunk, _ = com.StrTo(rightRange[1]).Int() + } + } else { + log.Warn("Parse line number failed: %v", line) + rightLine = leftLine + righHunk = leftHunk + } + return &DiffLineSectionInfo{ + Path: curFile.Name, + LastLeftIdx: lastLeftIdx, + LastRightIdx: lastRightIdx, + LeftIdx: leftLine, + RightIdx: rightLine, + LeftHunkSize: leftHunk, + RightHunkSize: righHunk, + } +} + // escape a line's content or return
needed for copy/paste purposes func getLineContent(content string) string { if len(content) > 0 { @@ -248,6 +341,53 @@ func (diffFile *DiffFile) GetHighlightClass() string { return highlight.FileNameToHighlightClass(diffFile.Name) } +// GetTailSection creates a fake DiffLineSection if the last section is not the end of the file +func (diffFile *DiffFile) GetTailSection(gitRepo *git.Repository, leftCommitID, rightCommitID string) *DiffSection { + if diffFile.Type != DiffFileChange || diffFile.IsBin || diffFile.IsLFSFile { + return nil + } + leftCommit, err := gitRepo.GetCommit(leftCommitID) + if err != nil { + return nil + } + rightCommit, err := gitRepo.GetCommit(rightCommitID) + if err != nil { + return nil + } + lastSection := diffFile.Sections[len(diffFile.Sections)-1] + lastLine := lastSection.Lines[len(lastSection.Lines)-1] + leftLineCount := getCommitFileLineCount(leftCommit, diffFile.Name) + rightLineCount := getCommitFileLineCount(rightCommit, diffFile.Name) + if leftLineCount <= lastLine.LeftIdx || rightLineCount <= lastLine.RightIdx { + return nil + } + tailDiffLine := &DiffLine{ + Type: DiffLineSection, + Content: " ", + SectionInfo: &DiffLineSectionInfo{ + Path: diffFile.Name, + LastLeftIdx: lastLine.LeftIdx, + LastRightIdx: lastLine.RightIdx, + LeftIdx: leftLineCount, + RightIdx: rightLineCount, + }} + tailSection := &DiffSection{Lines: []*DiffLine{tailDiffLine}} + return tailSection + +} + +func getCommitFileLineCount(commit *git.Commit, filePath string) int { + blob, err := commit.GetBlobByPath(filePath) + if err != nil { + return 0 + } + lineCount, err := blob.GetBlobLineCount() + if err != nil { + return 0 + } + return lineCount +} + // Diff represents a difference between two git trees. type Diff struct { TotalAddition, TotalDeletion int @@ -510,19 +650,16 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D case line[0] == '@': curSection = &DiffSection{} curFile.Sections = append(curFile.Sections, curSection) - ss := strings.Split(line, "@@") - diffLine := &DiffLine{Type: DiffLineSection, Content: line} - curSection.Lines = append(curSection.Lines, diffLine) - - // Parse line number. - ranges := strings.Split(ss[1][1:], " ") - leftLine, _ = com.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int() - if len(ranges) > 1 { - rightLine, _ = com.StrTo(strings.Split(ranges[1], ",")[0]).Int() - } else { - log.Warn("Parse line number failed: %v", line) - rightLine = leftLine + lineSectionInfo := getDiffLineSectionInfo(curFile, line, leftLine-1, rightLine-1) + diffLine := &DiffLine{ + Type: DiffLineSection, + Content: line, + SectionInfo: lineSectionInfo, } + curSection.Lines = append(curSection.Lines, diffLine) + // update line number. + leftLine = lineSectionInfo.LeftIdx + rightLine = lineSectionInfo.RightIdx continue case line[0] == '+': curFile.Addition++ @@ -599,6 +736,8 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D break } curFileLinesCount = 0 + leftLine = 1 + rightLine = 1 curFileLFSPrefix = false // Check file diff type and is submodule. @@ -701,6 +840,7 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID diffArgs = append(diffArgs, actualBeforeCommitID) diffArgs = append(diffArgs, afterCommitID) cmd = exec.Command(git.GitExecutable, diffArgs...) + beforeCommitID = actualBeforeCommitID } cmd.Dir = repoPath cmd.Stderr = os.Stderr @@ -721,6 +861,12 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID if err != nil { return nil, fmt.Errorf("ParsePatch: %v", err) } + for _, diffFile := range diff.Files { + tailSection := diffFile.GetTailSection(gitRepo, beforeCommitID, afterCommitID) + if tailSection != nil { + diffFile.Sections = append(diffFile.Sections, tailSection) + } + } if err = cmd.Wait(); err != nil { return nil, fmt.Errorf("Wait: %v", err) diff --git a/services/mirror/mirror_test.go b/services/mirror/mirror_test.go index 37e8a7be573..81811ffe4a1 100644 --- a/services/mirror/mirror_test.go +++ b/services/mirror/mirror_test.go @@ -76,6 +76,7 @@ func TestRelease_MirrorDelete(t *testing.T) { assert.True(t, ok) count, err := models.GetReleaseCountByRepoID(mirror.ID, findOptions) + assert.NoError(t, err) assert.EqualValues(t, initCount+1, count) release, err := models.GetRelease(repo.ID, "v0.2") @@ -86,5 +87,6 @@ func TestRelease_MirrorDelete(t *testing.T) { assert.True(t, ok) count, err = models.GetReleaseCountByRepoID(mirror.ID, findOptions) + assert.NoError(t, err) assert.EqualValues(t, initCount, count) } diff --git a/services/pull/merge.go b/services/pull/merge.go index 5fbf550ad2c..7dc3c07338a 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -424,8 +424,16 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor log.Error("setMerged [%d]: %v", pr.ID, err) } - if err = models.MergePullRequestAction(doer, pr.Issue.Repo, pr.Issue); err != nil { - log.Error("MergePullRequestAction [%d]: %v", pr.ID, err) + if err := models.NotifyWatchers(&models.Action{ + ActUserID: doer.ID, + ActUser: doer, + OpType: models.ActionMergePullRequest, + Content: fmt.Sprintf("%d|%s", pr.Issue.Index, pr.Issue.Title), + RepoID: pr.Issue.Repo.ID, + Repo: pr.Issue.Repo, + IsPrivate: pr.Issue.Repo.IsPrivate, + }); err != nil { + log.Error("NotifyWatchers [%d]: %v", pr.ID, err) } // Reset cached commit count diff --git a/services/pull/review.go b/services/pull/review.go index e4aae3c0d58..880647c6b57 100644 --- a/services/pull/review.go +++ b/services/pull/review.go @@ -6,30 +6,144 @@ package pull import ( + "bytes" + "fmt" + "strings" + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/notification" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/gitdiff" ) -// CreateReview creates a new review based on opts -func CreateReview(opts models.CreateReviewOptions) (*models.Review, error) { - review, err := models.CreateReview(opts) +// CreateCodeComment creates a comment on the code line +func CreateCodeComment(doer *models.User, issue *models.Issue, line int64, content string, treePath string, isReview bool, replyReviewID int64) (*models.Comment, error) { + // It's not a review, maybe a reply to a review comment or a single comment. + if !isReview { + if err := issue.LoadRepo(); err != nil { + return nil, err + } + + comment, err := createCodeComment( + doer, + issue.Repo, + issue, + content, + treePath, + line, + replyReviewID, + ) + if err != nil { + return nil, err + } + + notification.NotifyCreateIssueComment(doer, issue.Repo, issue, comment) + + return comment, nil + } + + review, err := models.GetCurrentReview(doer, issue) + if err != nil { + if !models.IsErrReviewNotExist(err) { + return nil, err + } + + review, err = models.CreateReview(models.CreateReviewOptions{ + Type: models.ReviewTypePending, + Reviewer: doer, + Issue: issue, + }) + if err != nil { + return nil, err + } + } + + comment, err := createCodeComment( + doer, + issue.Repo, + issue, + content, + treePath, + line, + review.ID, + ) if err != nil { return nil, err } - notification.NotifyPullRequestReview(review.Issue.PullRequest, review, nil) + // NOTICE: it's a pending review, so the notifications will not be fired until user submit review. - return review, nil + return comment, nil } -// UpdateReview updates a review -func UpdateReview(review *models.Review) error { - err := models.UpdateReview(review) +// createCodeComment creates a plain code comment at the specified line / path +func createCodeComment(doer *models.User, repo *models.Repository, issue *models.Issue, content, treePath string, line, reviewID int64) (*models.Comment, error) { + var commitID, patch string + if err := issue.LoadPullRequest(); err != nil { + return nil, fmt.Errorf("GetPullRequestByIssueID: %v", err) + } + pr := issue.PullRequest + if err := pr.GetBaseRepo(); err != nil { + return nil, fmt.Errorf("GetHeadRepo: %v", err) + } + gitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath()) if err != nil { - return err + return nil, fmt.Errorf("OpenRepository: %v", err) + } + defer gitRepo.Close() + + // FIXME validate treePath + // Get latest commit referencing the commented line + // No need for get commit for base branch changes + if line > 0 { + commit, err := gitRepo.LineBlame(pr.GetGitRefName(), gitRepo.Path, treePath, uint(line)) + if err == nil { + commitID = commit.ID.String() + } else if !strings.Contains(err.Error(), "exit status 128 - fatal: no such path") { + return nil, fmt.Errorf("LineBlame[%s, %s, %s, %d]: %v", pr.GetGitRefName(), gitRepo.Path, treePath, line, err) + } } - notification.NotifyPullRequestReview(review.Issue.PullRequest, review, nil) - - return nil + // Only fetch diff if comment is review comment + if reviewID != 0 { + headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitRefName()) + if err != nil { + return nil, fmt.Errorf("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err) + } + patchBuf := new(bytes.Buffer) + if err := gitdiff.GetRawDiffForFile(gitRepo.Path, pr.MergeBase, headCommitID, gitdiff.RawDiffNormal, treePath, patchBuf); err != nil { + return nil, fmt.Errorf("GetRawDiffForLine[%s, %s, %s, %s]: %v", err, gitRepo.Path, pr.MergeBase, headCommitID, treePath) + } + patch = gitdiff.CutDiffAroundLine(patchBuf, int64((&models.Comment{Line: line}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) + } + return models.CreateComment(&models.CreateCommentOptions{ + Type: models.CommentTypeCode, + Doer: doer, + Repo: repo, + Issue: issue, + Content: content, + LineNum: line, + TreePath: treePath, + CommitSHA: commitID, + ReviewID: reviewID, + Patch: patch, + NoAction: true, + }) +} + +// SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist +func SubmitReview(doer *models.User, issue *models.Issue, reviewType models.ReviewType, content string) (*models.Review, *models.Comment, error) { + review, comm, err := models.SubmitReview(doer, issue, reviewType, content) + if err != nil { + return nil, nil, err + } + + pr, err := issue.GetPullRequest() + if err != nil { + return nil, nil, err + } + notification.NotifyPullRequestReview(pr, review, comm) + + return review, comm, nil } diff --git a/services/repository/main_test.go b/services/repository/main_test.go new file mode 100644 index 00000000000..f13f358635b --- /dev/null +++ b/services/repository/main_test.go @@ -0,0 +1,16 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repository + +import ( + "path/filepath" + "testing" + + "code.gitea.io/gitea/models" +) + +func TestMain(m *testing.M) { + models.MainTest(m, filepath.Join("..", "..")) +} diff --git a/services/repository/transfer.go b/services/repository/transfer.go new file mode 100644 index 00000000000..2d20dcd1a2f --- /dev/null +++ b/services/repository/transfer.go @@ -0,0 +1,54 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repository + +import ( + "fmt" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/notification" +) + +// TransferOwnership transfers all corresponding setting from old user to new one. +func TransferOwnership(doer *models.User, newOwnerName string, repo *models.Repository) error { + if err := repo.GetOwner(); err != nil { + return err + } + + oldOwner := repo.Owner + + if err := models.TransferOwnership(doer, newOwnerName, repo); err != nil { + return err + } + + if err := models.NewRepoRedirect(oldOwner.ID, repo.ID, repo.Name, repo.Name); err != nil { + return fmt.Errorf("NewRepoRedirect: %v", err) + } + + notification.NotifyTransferRepository(doer, repo, oldOwner.Name) + + return nil +} + +// ChangeRepositoryName changes all corresponding setting from old repository name to new one. +func ChangeRepositoryName(doer *models.User, repo *models.Repository, newRepoName string) error { + oldRepoName := repo.Name + + if err := models.ChangeRepositoryName(doer, repo, newRepoName); err != nil { + return err + } + + if err := repo.GetOwner(); err != nil { + return err + } + + if err := models.NewRepoRedirect(repo.Owner.ID, repo.ID, oldRepoName, newRepoName); err != nil { + return err + } + + notification.NotifyRenameRepository(doer, repo, oldRepoName) + + return nil +} diff --git a/services/repository/transfer_test.go b/services/repository/transfer_test.go new file mode 100644 index 00000000000..432527921f4 --- /dev/null +++ b/services/repository/transfer_test.go @@ -0,0 +1,50 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repository + +import ( + "sync" + "testing" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/notification" + "code.gitea.io/gitea/modules/notification/action" + + "github.com/stretchr/testify/assert" + "github.com/unknwon/com" +) + +var notifySync sync.Once + +func registerNotifier() { + notifySync.Do(func() { + notification.RegisterNotifier(action.NewNotifier()) + }) +} + +func TestTransferOwnership(t *testing.T) { + registerNotifier() + + assert.NoError(t, models.PrepareTestDatabase()) + + doer := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) + repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 3}).(*models.Repository) + repo.Owner = models.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User) + assert.NoError(t, TransferOwnership(doer, "user2", repo)) + + transferredRepo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 3}).(*models.Repository) + assert.EqualValues(t, 2, transferredRepo.OwnerID) + + assert.False(t, com.IsExist(models.RepoPath("user3", "repo3"))) + assert.True(t, com.IsExist(models.RepoPath("user2", "repo3"))) + models.AssertExistsAndLoadBean(t, &models.Action{ + OpType: models.ActionTransferRepo, + ActUserID: 2, + RepoID: 3, + Content: "user3/repo3", + }) + + models.CheckConsistencyFor(t, &models.Repository{}, &models.User{}, &models.Team{}) +} diff --git a/templates/base/footer.tmpl b/templates/base/footer.tmpl index bed8eea0195..93cf9416731 100644 --- a/templates/base/footer.tmpl +++ b/templates/base/footer.tmpl @@ -26,7 +26,6 @@ {{if .RequireGitGraph}} - {{end}} @@ -117,7 +116,7 @@ } {{end}} - + @@ -129,7 +128,7 @@ {{end}} {{template "custom/footer" .}} diff --git a/templates/pwa/serviceworker_js.tmpl b/templates/pwa/serviceworker_js.tmpl index dc2453e3d82..672e504ff38 100644 --- a/templates/pwa/serviceworker_js.tmpl +++ b/templates/pwa/serviceworker_js.tmpl @@ -7,11 +7,10 @@ var urlsToCache = [ '{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.js', '{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}', '{{StaticUrlPrefix}}/js/semantic.dropdown.custom.js?v={{MD5 AppVer}}', - '{{StaticUrlPrefix}}/js/draw.js', '{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js', '{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.js', '{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js', - '{{StaticUrlPrefix}}/vendor/plugins/emojify/emojify.min.js', + '{{StaticUrlPrefix}}/vendor/plugins/emojify/emojify.custom.js', '{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/loadCSS.min.js', '{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/cssrelpreload.min.js', '{{StaticUrlPrefix}}/vendor/plugins/dropzone/dropzone.js', diff --git a/templates/repo/diff/blob_excerpt.tmpl b/templates/repo/diff/blob_excerpt.tmpl new file mode 100644 index 00000000000..5f0cd30bb7b --- /dev/null +++ b/templates/repo/diff/blob_excerpt.tmpl @@ -0,0 +1,50 @@ +{{if $.IsSplitStyle}} + {{range $k, $line := $.section.Lines}} + + {{if eq .GetType 4}} + + {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }} + + {{end}} + {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }} + + {{end}} + {{if or (eq $line.GetExpandDirection 2)}} + + {{end}} + + {{$.section.GetComputedInlineDiffFor $line}} + {{else}} + + {{if $line.LeftIdx}}{{end}} + {{if $line.LeftIdx}}{{$.section.GetComputedInlineDiffFor $line}}{{end}} + + {{if $line.RightIdx}}{{end}} + {{if $line.RightIdx}}{{$.section.GetComputedInlineDiffFor $line}}{{end}} + {{end}} + + {{end}} +{{else}} + {{range $k, $line := $.section.Lines}} + + {{if eq .GetType 4}} + + {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }} + + {{end}} + {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }} + + {{end}} + {{if or (eq $line.GetExpandDirection 2)}} + + {{end}} + + {{else}} + + + {{end}} + + {{$.section.GetComputedInlineDiffFor $line}} + + {{end}} +{{end}} \ No newline at end of file diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index a12fc9bd4b7..088dc5718dd 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -81,6 +81,15 @@ {{else}}

+ {{$isImage := false}} + {{if $file.IsDeleted}} + {{$isImage = (call $.IsImageFileInBase $file.Name)}} + {{else}} + {{$isImage = (call $.IsImageFileInHead $file.Name)}} + {{end}} + {{if or (not $file.IsBin) $isImage}} + + {{end}}
{{if $file.IsBin}} {{$.i18n.Tr "repo.diff.bin"}} @@ -104,12 +113,6 @@

{{if ne $file.Type 4}} - {{$isImage := false}} - {{if $file.IsDeleted}} - {{$isImage = (call $.IsImageFileInBase $file.Name)}} - {{else}} - {{$isImage = (call $.IsImageFileInHead $file.Name)}} - {{end}}
@@ -121,12 +124,27 @@ {{range $j, $section := $file.Sections}} {{range $k, $line := $section.Lines}} - - - - - - + {{if eq .GetType 4}} + + + {{else}} + + + + + + + {{end}} {{if gt (len $line.Comments) 0}} diff --git a/templates/repo/diff/comment_form.tmpl b/templates/repo/diff/comment_form.tmpl index 38fd3fa7fb4..573e7d46383 100644 --- a/templates/repo/diff/comment_form.tmpl +++ b/templates/repo/diff/comment_form.tmpl @@ -39,7 +39,7 @@ {{end}} {{end}} {{if or (not $.HasComments) $.hidden}} - + {{end}} diff --git a/templates/repo/diff/section_unified.tmpl b/templates/repo/diff/section_unified.tmpl index 9a60c238dcf..fcc511af75e 100644 --- a/templates/repo/diff/section_unified.tmpl +++ b/templates/repo/diff/section_unified.tmpl @@ -4,9 +4,17 @@ {{range $k, $line := $section.Lines}} {{if eq .GetType 4}} - + {{else}} diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index 637d4ad04ae..7f6ee2c4374 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -155,8 +155,8 @@ {{if $.IsStopwatchRunning}}
- - + +
{{else}} {{if .HasUserStopwatch}} @@ -165,8 +165,8 @@ {{end}}
- - + +
${ + isSplit ? '' + : '' + }`); + tr.after(ntr); + } + const td = ntr.find(`.add-comment-${side}`); + let commentCloud = td.find('.comment-code-cloud'); + if (commentCloud.length === 0) { + td.html(form); + commentCloud = td.find('.comment-code-cloud'); + assingMenuAttributes(commentCloud.find('.menu')); + + td.find("input[name='line']").val(idx); + td.find("input[name='side']").val(side === 'left' ? 'previous' : 'proposed'); + td.find("input[name='path']").val(path); + } + commentCloud.find('textarea').focus(); + }); +} + +function assingMenuAttributes(menu) { + const id = Math.floor(Math.random() * Math.floor(1000000)); + menu.attr('data-write', menu.attr('data-write') + id); + menu.attr('data-preview', menu.attr('data-preview') + id); + menu.find('.item').each(function () { + const tab = $(this).attr('data-tab') + id; + $(this).attr('data-tab', tab); + }); + menu.parent().find("*[data-tab='write']").attr('data-tab', `write${id}`); + menu.parent().find("*[data-tab='preview']").attr('data-tab', `preview${id}`); + initCommentPreviewTab(menu.parent('.form')); + return id; +} + +function initRepositoryCollaboration() { + // Change collaborator access mode + $('.access-mode.menu .item').click(function () { + const $menu = $(this).parent(); + $.post($menu.data('url'), { + _csrf: csrf, + uid: $menu.data('uid'), + mode: $(this).data('value') + }); + }); +} + +function initTeamSettings() { + // Change team access mode + $('.organization.new.team input[name=permission]').change(() => { + const val = $('input[name=permission]:checked', '.organization.new.team').val(); + if (val === 'admin') { + $('.organization.new.team .team-units').hide(); + } else { + $('.organization.new.team .team-units').show(); + } + }); +} + +function initWikiForm() { + const $editArea = $('.repository.wiki textarea#edit_area'); + if ($editArea.length > 0) { + const simplemde = new SimpleMDE({ + autoDownloadFontAwesome: false, + element: $editArea[0], + forceSync: true, + previewRender(plainText, preview) { // Async method + setTimeout(() => { + // FIXME: still send render request when return back to edit mode + $.post($editArea.data('url'), { + _csrf: csrf, + mode: 'gfm', + context: $editArea.data('context'), + text: plainText + }, (data) => { + preview.innerHTML = `
${data}
`; + emojify.run($('.editor-preview')[0]); + }); + }, 0); + + return 'Loading...'; + }, + renderingConfig: { + singleLineBreaks: false + }, + indentWithTabs: false, + tabSize: 4, + spellChecker: false, + toolbar: ['bold', 'italic', 'strikethrough', '|', + 'heading-1', 'heading-2', 'heading-3', 'heading-bigger', 'heading-smaller', '|', + { + name: 'code-inline', + action(e) { + const cm = e.codemirror; + const selection = cm.getSelection(); + cm.replaceSelection(`\`${selection}\``); + if (!selection) { + const cursorPos = cm.getCursor(); + cm.setCursor(cursorPos.line, cursorPos.ch - 1); + } + cm.focus(); + }, + className: 'fa fa-angle-right', + title: 'Add Inline Code', + }, 'code', 'quote', '|', { + name: 'checkbox-empty', + action(e) { + const cm = e.codemirror; + cm.replaceSelection(`\n- [ ] ${cm.getSelection()}`); + cm.focus(); + }, + className: 'fa fa-square-o', + title: 'Add Checkbox (empty)', + }, + { + name: 'checkbox-checked', + action(e) { + const cm = e.codemirror; + cm.replaceSelection(`\n- [x] ${cm.getSelection()}`); + cm.focus(); + }, + className: 'fa fa-check-square-o', + title: 'Add Checkbox (checked)', + }, '|', + 'unordered-list', 'ordered-list', '|', + 'link', 'image', 'table', 'horizontal-rule', '|', + 'clean-block', 'preview', 'fullscreen'] + }); + $(simplemde.codemirror.getInputField()).addClass('js-quick-submit'); + } +} + +// Adding function to get the cursor position in a text field to jQuery object. +$.fn.getCursorPosition = function () { + const el = $(this).get(0); + let pos = 0; + if ('selectionStart' in el) { + pos = el.selectionStart; + } else if ('selection' in document) { + el.focus(); + const Sel = document.selection.createRange(); + const SelLength = document.selection.createRange().text.length; + Sel.moveStart('character', -el.value.length); + pos = Sel.text.length - SelLength; + } + return pos; +}; + +function setSimpleMDE($editArea) { + if (codeMirrorEditor) { + codeMirrorEditor.toTextArea(); + codeMirrorEditor = null; + } + + if (simpleMDEditor) { + return true; + } + + simpleMDEditor = new SimpleMDE({ + autoDownloadFontAwesome: false, + element: $editArea[0], + forceSync: true, + renderingConfig: { + singleLineBreaks: false + }, + indentWithTabs: false, + tabSize: 4, + spellChecker: false, + previewRender(plainText, preview) { // Async method + setTimeout(() => { + // FIXME: still send render request when return back to edit mode + $.post($editArea.data('url'), { + _csrf: csrf, + mode: 'gfm', + context: $editArea.data('context'), + text: plainText + }, + (data) => { + preview.innerHTML = `
${data}
`; + emojify.run($('.editor-preview')[0]); + }); + }, 0); + + return 'Loading...'; + }, + toolbar: ['bold', 'italic', 'strikethrough', '|', + 'heading-1', 'heading-2', 'heading-3', 'heading-bigger', 'heading-smaller', '|', + 'code', 'quote', '|', + 'unordered-list', 'ordered-list', '|', + 'link', 'image', 'table', 'horizontal-rule', '|', + 'clean-block', 'preview', 'fullscreen', 'side-by-side'] + }); + + return true; +} + +function setCodeMirror($editArea) { + if (simpleMDEditor) { + simpleMDEditor.toTextArea(); + simpleMDEditor = null; + } + + if (codeMirrorEditor) { + return true; + } + + codeMirrorEditor = CodeMirror.fromTextArea($editArea[0], { + lineNumbers: true + }); + codeMirrorEditor.on('change', (cm, _change) => { + $editArea.val(cm.getValue()); + }); + + return true; +} + +function initEditor() { + $('.js-quick-pull-choice-option').change(function () { + if ($(this).val() === 'commit-to-new-branch') { + $('.quick-pull-branch-name').show(); + $('.quick-pull-branch-name input').prop('required', true); + } else { + $('.quick-pull-branch-name').hide(); + $('.quick-pull-branch-name input').prop('required', false); + } + $('#commit-button').text($(this).attr('button_text')); + }); + + const $editFilename = $('#file-name'); + $editFilename.keyup(function (e) { + const $section = $('.breadcrumb span.section'); + const $divider = $('.breadcrumb div.divider'); + let value; + let parts; + + if (e.keyCode === 8) { + if ($(this).getCursorPosition() === 0) { + if ($section.length > 0) { + value = $section.last().find('a').text(); + $(this).val(value + $(this).val()); + $(this)[0].setSelectionRange(value.length, value.length); + $section.last().remove(); + $divider.last().remove(); + } + } + } + if (e.keyCode === 191) { + parts = $(this).val().split('/'); + for (let i = 0; i < parts.length; ++i) { + value = parts[i]; + if (i < parts.length - 1) { + if (value.length) { + $(`${value}`).insertBefore($(this)); + $('
/
').insertBefore($(this)); + } + } else { + $(this).val(value); + } + $(this)[0].setSelectionRange(0, 0); + } + } + parts = []; + $('.breadcrumb span.section').each(function () { + const element = $(this); + if (element.find('a').length) { + parts.push(element.find('a').text()); + } else { + parts.push(element.text()); + } + }); + if ($(this).val()) parts.push($(this).val()); + $('#tree_path').val(parts.join('/')); + }).trigger('keyup'); + + const $editArea = $('.repository.editor textarea#edit_area'); + if (!$editArea.length) return; + + const markdownFileExts = $editArea.data('markdown-file-exts').split(','); + const lineWrapExtensions = $editArea.data('line-wrap-extensions').split(','); + + $editFilename.on('keyup', () => { + const val = $editFilename.val(); + let mode, spec, extension, extWithDot, dataUrl, apiCall; + + extension = extWithDot = ''; + const m = /.+\.([^.]+)$/.exec(val); + if (m) { + extension = m[1]; + extWithDot = `.${extension}`; + } + + const info = CodeMirror.findModeByExtension(extension); + const previewLink = $('a[data-tab=preview]'); + if (info) { + mode = info.mode; + spec = info.mime; + apiCall = mode; + } else { + apiCall = extension; + } + + if (previewLink.length && apiCall && previewFileModes && previewFileModes.length && previewFileModes.indexOf(apiCall) >= 0) { + dataUrl = previewLink.data('url'); + previewLink.data('url', dataUrl.replace(/(.*)\/.*/i, `$1/${mode}`)); + previewLink.show(); + } else { + previewLink.hide(); + } + + // If this file is a Markdown extensions, we will load that editor and return + if (markdownFileExts.indexOf(extWithDot) >= 0) { + if (setSimpleMDE($editArea)) { + return; + } + } + + // Else we are going to use CodeMirror + if (!codeMirrorEditor && !setCodeMirror($editArea)) { + return; + } + + if (mode) { + codeMirrorEditor.setOption('mode', spec); + CodeMirror.autoLoadMode(codeMirrorEditor, mode); + } + + if (lineWrapExtensions.indexOf(extWithDot) >= 0) { + codeMirrorEditor.setOption('lineWrapping', true); + } else { + codeMirrorEditor.setOption('lineWrapping', false); + } + + // get the filename without any folder + let value = $editFilename.val(); + if (value.length === 0) { + return; + } + value = value.split('/'); + value = value[value.length - 1]; + + $.getJSON($editFilename.data('ec-url-prefix') + value, (editorconfig) => { + if (editorconfig.indent_style === 'tab') { + codeMirrorEditor.setOption('indentWithTabs', true); + codeMirrorEditor.setOption('extraKeys', {}); + } else { + codeMirrorEditor.setOption('indentWithTabs', false); + // required because CodeMirror doesn't seems to use spaces correctly for {"indentWithTabs": false}: + // - https://github.com/codemirror/CodeMirror/issues/988 + // - https://codemirror.net/doc/manual.html#keymaps + codeMirrorEditor.setOption('extraKeys', { + Tab(cm) { + const spaces = Array(parseInt(cm.getOption('indentUnit')) + 1).join(' '); + cm.replaceSelection(spaces); + } + }); + } + codeMirrorEditor.setOption('indentUnit', editorconfig.indent_size || 4); + codeMirrorEditor.setOption('tabSize', editorconfig.tab_width || 4); + }); + }).trigger('keyup'); + + // Using events from https://github.com/codedance/jquery.AreYouSure#advanced-usage + // to enable or disable the commit button + const $commitButton = $('#commit-button'); + const $editForm = $('.ui.edit.form'); + const dirtyFileClass = 'dirty-file'; + + // Disabling the button at the start + $commitButton.prop('disabled', true); + + // Registering a custom listener for the file path and the file content + $editForm.areYouSure({ + silent: true, + dirtyClass: dirtyFileClass, + fieldSelector: ':input:not(.commit-form-wrapper :input)', + change() { + const dirty = $(this).hasClass(dirtyFileClass); + $commitButton.prop('disabled', !dirty); + } + }); + + $commitButton.click((event) => { + // A modal which asks if an empty file should be committed + if ($editArea.val().length === 0) { + $('#edit-empty-content-modal').modal({ + onApprove() { + $('.edit.form').submit(); + } + }).modal('show'); + event.preventDefault(); + } + }); +} + +function initOrganization() { + if ($('.organization').length === 0) { + return; + } + + // Options + if ($('.organization.settings.options').length > 0) { + $('#org_name').keyup(function () { + const $prompt = $('#org-name-change-prompt'); + if ($(this).val().toString().toLowerCase() !== $(this).data('org-name').toString().toLowerCase()) { + $prompt.show(); + } else { + $prompt.hide(); + } + }); + } +} + +function initUserSettings() { + // Options + if ($('.user.settings.profile').length > 0) { + $('#username').keyup(function () { + const $prompt = $('#name-change-prompt'); + if ($(this).val().toString().toLowerCase() !== $(this).data('name').toString().toLowerCase()) { + $prompt.show(); + } else { + $prompt.hide(); + } + }); + } +} + +function initGithook() { + if ($('.edit.githook').length === 0) { + return; + } + + CodeMirror.autoLoadMode(CodeMirror.fromTextArea($('#content')[0], { + lineNumbers: true, + mode: 'shell' + }), 'shell'); +} + +function initWebhook() { + if ($('.new.webhook').length === 0) { + return; + } + + $('.events.checkbox input').change(function () { + if ($(this).is(':checked')) { + $('.events.fields').show(); + } + }); + $('.non-events.checkbox input').change(function () { + if ($(this).is(':checked')) { + $('.events.fields').hide(); + } + }); + + const updateContentType = function () { + const visible = $('#http_method').val() === 'POST'; + $('#content_type').parent().parent()[visible ? 'show' : 'hide'](); + }; + updateContentType(); + $('#http_method').change(() => { + updateContentType(); + }); + + // Test delivery + $('#test-delivery').click(function () { + const $this = $(this); + $this.addClass('loading disabled'); + $.post($this.data('link'), { + _csrf: csrf + }).done( + setTimeout(() => { + window.location.href = $this.data('redirect'); + }, 5000) + ); + }); +} + +function initAdmin() { + if ($('.admin').length === 0) { + return; + } + + // New user + if ($('.admin.new.user').length > 0 || $('.admin.edit.user').length > 0) { + $('#login_type').change(function () { + if ($(this).val().substring(0, 1) === '0') { + $('#login_name').removeAttr('required'); + $('.non-local').hide(); + $('.local').show(); + $('#user_name').focus(); + + if ($(this).data('password') === 'required') { + $('#password').attr('required', 'required'); + } + } else { + $('#login_name').attr('required', 'required'); + $('.non-local').show(); + $('.local').hide(); + $('#login_name').focus(); + + $('#password').removeAttr('required'); + } + }); + } + + function onSecurityProtocolChange() { + if ($('#security_protocol').val() > 0) { + $('.has-tls').show(); + } else { + $('.has-tls').hide(); + } + } + + function onUsePagedSearchChange() { + if ($('#use_paged_search').prop('checked')) { + $('.search-page-size').show() + .find('input').attr('required', 'required'); + } else { + $('.search-page-size').hide() + .find('input').removeAttr('required'); + } + } + + function onOAuth2Change() { + $('.open_id_connect_auto_discovery_url, .oauth2_use_custom_url').hide(); + $('.open_id_connect_auto_discovery_url input[required]').removeAttr('required'); + + const provider = $('#oauth2_provider').val(); + switch (provider) { + case 'github': + case 'gitlab': + case 'gitea': + $('.oauth2_use_custom_url').show(); + break; + case 'openidConnect': + $('.open_id_connect_auto_discovery_url input').attr('required', 'required'); + $('.open_id_connect_auto_discovery_url').show(); + break; + } + onOAuth2UseCustomURLChange(); + } + + function onOAuth2UseCustomURLChange() { + const provider = $('#oauth2_provider').val(); + $('.oauth2_use_custom_url_field').hide(); + $('.oauth2_use_custom_url_field input[required]').removeAttr('required'); + + if ($('#oauth2_use_custom_url').is(':checked')) { + if (!$('#oauth2_token_url').val()) { + $('#oauth2_token_url').val($(`#${provider}_token_url`).val()); + } + if (!$('#oauth2_auth_url').val()) { + $('#oauth2_auth_url').val($(`#${provider}_auth_url`).val()); + } + if (!$('#oauth2_profile_url').val()) { + $('#oauth2_profile_url').val($(`#${provider}_profile_url`).val()); + } + if (!$('#oauth2_email_url').val()) { + $('#oauth2_email_url').val($(`#${provider}_email_url`).val()); + } + switch (provider) { + case 'github': + $('.oauth2_token_url input, .oauth2_auth_url input, .oauth2_profile_url input, .oauth2_email_url input').attr('required', 'required'); + $('.oauth2_token_url, .oauth2_auth_url, .oauth2_profile_url, .oauth2_email_url').show(); + break; + case 'gitea': + case 'gitlab': + $('.oauth2_token_url input, .oauth2_auth_url input, .oauth2_profile_url input').attr('required', 'required'); + $('.oauth2_token_url, .oauth2_auth_url, .oauth2_profile_url').show(); + $('#oauth2_email_url').val(''); + break; + } + } + } + + // New authentication + if ($('.admin.new.authentication').length > 0) { + $('#auth_type').change(function () { + $('.ldap, .dldap, .smtp, .pam, .oauth2, .has-tls .search-page-size').hide(); + + $('.ldap input[required], .binddnrequired input[required], .dldap input[required], .smtp input[required], .pam input[required], .oauth2 input[required], .has-tls input[required]').removeAttr('required'); + $('.binddnrequired').removeClass('required'); + + const authType = $(this).val(); + switch (authType) { + case '2': // LDAP + $('.ldap').show(); + $('.binddnrequired input, .ldap div.required:not(.dldap) input').attr('required', 'required'); + $('.binddnrequired').addClass('required'); + break; + case '3': // SMTP + $('.smtp').show(); + $('.has-tls').show(); + $('.smtp div.required input, .has-tls').attr('required', 'required'); + break; + case '4': // PAM + $('.pam').show(); + $('.pam input').attr('required', 'required'); + break; + case '5': // LDAP + $('.dldap').show(); + $('.dldap div.required:not(.ldap) input').attr('required', 'required'); + break; + case '6': // OAuth2 + $('.oauth2').show(); + $('.oauth2 div.required:not(.oauth2_use_custom_url,.oauth2_use_custom_url_field,.open_id_connect_auto_discovery_url) input').attr('required', 'required'); + onOAuth2Change(); + break; + } + if (authType === '2' || authType === '5') { + onSecurityProtocolChange(); + } + if (authType === '2') { + onUsePagedSearchChange(); + } + }); + $('#auth_type').change(); + $('#security_protocol').change(onSecurityProtocolChange); + $('#use_paged_search').change(onUsePagedSearchChange); + $('#oauth2_provider').change(onOAuth2Change); + $('#oauth2_use_custom_url').change(onOAuth2UseCustomURLChange); + } + // Edit authentication + if ($('.admin.edit.authentication').length > 0) { + const authType = $('#auth_type').val(); + if (authType === '2' || authType === '5') { + $('#security_protocol').change(onSecurityProtocolChange); + if (authType === '2') { + $('#use_paged_search').change(onUsePagedSearchChange); + } + } else if (authType === '6') { + $('#oauth2_provider').change(onOAuth2Change); + $('#oauth2_use_custom_url').change(onOAuth2UseCustomURLChange); + onOAuth2Change(); + } + } + + // Notice + if ($('.admin.notice')) { + const $detailModal = $('#detail-modal'); + + // Attach view detail modals + $('.view-detail').click(function () { + $detailModal.find('.content p').text($(this).data('content')); + $detailModal.modal('show'); + return false; + }); + + // Select actions + const $checkboxes = $('.select.table .ui.checkbox'); + $('.select.action').click(function () { + switch ($(this).data('action')) { + case 'select-all': + $checkboxes.checkbox('check'); + break; + case 'deselect-all': + $checkboxes.checkbox('uncheck'); + break; + case 'inverse': + $checkboxes.checkbox('toggle'); + break; + } + }); + $('#delete-selection').click(function () { + const $this = $(this); + $this.addClass('loading disabled'); + const ids = []; + $checkboxes.each(function () { + if ($(this).checkbox('is checked')) { + ids.push($(this).data('id')); + } + }); + $.post($this.data('link'), { + _csrf: csrf, + ids + }).done(() => { + window.location.href = $this.data('redirect'); + }); + }); + } +} + +function buttonsClickOnEnter() { + $('.ui.button').keypress(function (e) { + if (e.keyCode === 13 || e.keyCode === 32) { // enter key or space bar + $(this).click(); + } + }); +} + +function searchUsers() { + const $searchUserBox = $('#search-user-box'); + $searchUserBox.search({ + minCharacters: 2, + apiSettings: { + url: `${suburl}/api/v1/users/search?q={query}`, + onResponse(response) { + const items = []; + $.each(response.data, (_i, item) => { + let title = item.login; + if (item.full_name && item.full_name.length > 0) { + title += ` (${htmlEncode(item.full_name)})`; + } + items.push({ + title, + image: item.avatar_url + }); + }); + + return { results: items }; + } + }, + searchFields: ['login', 'full_name'], + showNoResults: false + }); +} + +function searchTeams() { + const $searchTeamBox = $('#search-team-box'); + $searchTeamBox.search({ + minCharacters: 2, + apiSettings: { + url: `${suburl}/api/v1/orgs/${$searchTeamBox.data('org')}/teams/search?q={query}`, + headers: { 'X-Csrf-Token': csrf }, + onResponse(response) { + const items = []; + $.each(response.data, (_i, item) => { + const title = `${item.name} (${item.permission} access)`; + items.push({ + title, + }); + }); + + return { results: items }; + } + }, + searchFields: ['name', 'description'], + showNoResults: false + }); +} + +function searchRepositories() { + const $searchRepoBox = $('#search-repo-box'); + $searchRepoBox.search({ + minCharacters: 2, + apiSettings: { + url: `${suburl}/api/v1/repos/search?q={query}&uid=${$searchRepoBox.data('uid')}`, + onResponse(response) { + const items = []; + $.each(response.data, (_i, item) => { + items.push({ + title: item.full_name.split('/')[1], + description: item.full_name + }); + }); + + return { results: items }; + } + }, + searchFields: ['full_name'], + showNoResults: false + }); +} + +function initCodeView() { + if ($('.code-view .linenums').length > 0) { + $(document).on('click', '.lines-num span', function (e) { + const $select = $(this); + const $list = $select.parent().siblings('.lines-code').find('ol.linenums > li'); + selectRange($list, $list.filter(`[rel=${$select.attr('id')}]`), (e.shiftKey ? $list.filter('.active').eq(0) : null)); + deSelect(); + }); + + $(window).on('hashchange', () => { + let m = window.location.hash.match(/^#(L\d+)-(L\d+)$/); + const $list = $('.code-view ol.linenums > li'); + let $first; + if (m) { + $first = $list.filter(`.${m[1]}`); + selectRange($list, $first, $list.filter(`.${m[2]}`)); + $('html, body').scrollTop($first.offset().top - 200); + return; + } + m = window.location.hash.match(/^#(L|n)(\d+)$/); + if (m) { + $first = $list.filter(`.L${m[2]}`); + selectRange($list, $first); + $('html, body').scrollTop($first.offset().top - 200); + } + }).trigger('hashchange'); + } + $('.ui.fold-code').on('click', (e) => { + const $foldButton = $(e.target); + if ($foldButton.hasClass('fa-chevron-down')) { + $(e.target).parent().next().slideUp('fast', () => { + $foldButton.removeClass('fa-chevron-down').addClass('fa-chevron-right'); + }); + } else { + $(e.target).parent().next().slideDown('fast', () => { + $foldButton.removeClass('fa-chevron-right').addClass('fa-chevron-down'); + }); + } + }); + function insertBlobExcerpt(e) { + const $blob = $(e.target); + const $row = $blob.parent().parent(); + $.get(`${$blob.data('url')}?${$blob.data('query')}&anchor=${$blob.data('anchor')}`, (blob) => { + $row.replaceWith(blob); + $(`[data-anchor="${$blob.data('anchor')}"]`).on('click', (e) => { insertBlobExcerpt(e); }); + }); + } + $('.ui.blob-excerpt').on('click', (e) => { insertBlobExcerpt(e); }); +} + +function initU2FAuth() { + if ($('#wait-for-key').length === 0) { + return; + } + u2fApi.ensureSupport() + .then(() => { + $.getJSON(`${suburl}/user/u2f/challenge`).success((req) => { + u2fApi.sign(req.appId, req.challenge, req.registeredKeys, 30) + .then(u2fSigned) + .catch((err) => { + if (err === undefined) { + u2fError(1); + return; + } + u2fError(err.metaData.code); + }); + }); + }).catch(() => { + // Fallback in case browser do not support U2F + window.location.href = `${suburl}/user/two_factor`; + }); +} +function u2fSigned(resp) { + $.ajax({ + url: `${suburl}/user/u2f/sign`, + type: 'POST', + headers: { 'X-Csrf-Token': csrf }, + data: JSON.stringify(resp), + contentType: 'application/json; charset=utf-8', + }).done((res) => { + window.location.replace(res); + }).fail(() => { + u2fError(1); + }); +} + +function u2fRegistered(resp) { + if (checkError(resp)) { + return; + } + $.ajax({ + url: `${suburl}/user/settings/security/u2f/register`, + type: 'POST', + headers: { 'X-Csrf-Token': csrf }, + data: JSON.stringify(resp), + contentType: 'application/json; charset=utf-8', + success() { + reload(); + }, + fail() { + u2fError(1); + } + }); +} + +function checkError(resp) { + if (!('errorCode' in resp)) { + return false; + } + if (resp.errorCode === 0) { + return false; + } + u2fError(resp.errorCode); + return true; +} + + +function u2fError(errorType) { + const u2fErrors = { + browser: $('#unsupported-browser'), + 1: $('#u2f-error-1'), + 2: $('#u2f-error-2'), + 3: $('#u2f-error-3'), + 4: $('#u2f-error-4'), + 5: $('.u2f-error-5') + }; + u2fErrors[errorType].removeClass('hide'); + + Object.keys(u2fErrors).forEach((type) => { + if (type !== errorType) { + u2fErrors[type].addClass('hide'); + } + }); + $('#u2f-error').modal('show'); +} + +function initU2FRegister() { + $('#register-device').modal({ allowMultiple: false }); + $('#u2f-error').modal({ allowMultiple: false }); + $('#register-security-key').on('click', (e) => { + e.preventDefault(); + u2fApi.ensureSupport() + .then(u2fRegisterRequest) + .catch(() => { + u2fError('browser'); + }); + }); +} + +function u2fRegisterRequest() { + $.post(`${suburl}/user/settings/security/u2f/request_register`, { + _csrf: csrf, + name: $('#nickname').val() + }).success((req) => { + $('#nickname').closest('div.field').removeClass('error'); + $('#register-device').modal('show'); + if (req.registeredKeys === null) { + req.registeredKeys = []; + } + u2fApi.register(req.appId, req.registerRequests, req.registeredKeys, 30) + .then(u2fRegistered) + .catch((reason) => { + if (reason === undefined) { + u2fError(1); + return; + } + u2fError(reason.metaData.code); + }); + }).fail((xhr) => { + if (xhr.status === 409) { + $('#nickname').closest('div.field').addClass('error'); + } + }); +} + +function initWipTitle() { + $('.title_wip_desc > a').click((e) => { + e.preventDefault(); + + const $issueTitle = $('#issue_title'); + $issueTitle.focus(); + const value = $issueTitle.val().trim().toUpperCase(); + + for (const i in wipPrefixes) { + if (value.startsWith(wipPrefixes[i].toUpperCase())) { + return; + } + } + + $issueTitle.val(`${wipPrefixes[0]} ${$issueTitle.val()}`); + }); +} + +function initTemplateSearch() { + const $repoTemplate = $('#repo_template'); + const checkTemplate = function () { + const $templateUnits = $('#template_units'); + const $nonTemplate = $('#non_template'); + if ($repoTemplate.val() !== '') { + $templateUnits.show(); + $nonTemplate.hide(); + } else { + $templateUnits.hide(); + $nonTemplate.show(); + } + }; + $repoTemplate.change(checkTemplate); + checkTemplate(); + + const changeOwner = function () { + $('#repo_template_search') + .dropdown({ + apiSettings: { + url: `${suburl}/api/v1/repos/search?q={query}&template=true&priority_owner_id=${$('#uid').val()}`, + onResponse(response) { + const filteredResponse = { success: true, results: [] }; + filteredResponse.results.push({ + name: '', + value: '' + }); + // Parse the response from the api to work with our dropdown + $.each(response.data, (_r, repo) => { + filteredResponse.results.push({ + name: htmlEncode(repo.full_name), + value: repo.id + }); + }); + return filteredResponse; + }, + cache: false, + }, + + fullTextSearch: true + }); + }; + $('#uid').change(changeOwner); + changeOwner(); +} + +$(document).ready(() => { + csrf = $('meta[name=_csrf]').attr('content'); + suburl = $('meta[name=_suburl]').attr('content'); + + // Show exact time + $('.time-since').each(function () { + $(this) + .addClass('poping up') + .attr('data-content', $(this).attr('title')) + .attr('data-variation', 'inverted tiny') + .attr('title', ''); + }); + + // Semantic UI modules. + $('.dropdown:not(.custom)').dropdown(); + $('.jump.dropdown').dropdown({ + action: 'hide', + onShow() { + $('.poping.up').popup('hide'); + } + }); + $('.slide.up.dropdown').dropdown({ + transition: 'slide up' + }); + $('.upward.dropdown').dropdown({ + direction: 'upward' + }); + $('.ui.accordion').accordion(); + $('.ui.checkbox').checkbox(); + $('.ui.progress').progress({ + showActivity: false + }); + $('.poping.up').popup(); + $('.top.menu .poping.up').popup({ + onShow() { + if ($('.top.menu .menu.transition').hasClass('visible')) { + return false; + } + } + }); + $('.tabular.menu .item').tab(); + $('.tabable.menu .item').tab(); + + $('.toggle.button').click(function () { + $($(this).data('target')).slideToggle(100); + }); + + // make table element clickable like a link + $('tr[data-href]').click(function () { + window.location = $(this).data('href'); + }); + + // Highlight JS + if (typeof hljs !== 'undefined') { + const nodes = [].slice.call(document.querySelectorAll('pre code') || []); + for (let i = 0; i < nodes.length; i++) { + hljs.highlightBlock(nodes[i]); + } + } + + // Dropzone + const $dropzone = $('#dropzone'); + if ($dropzone.length > 0) { + const filenameDict = {}; + + new Dropzone('#dropzone', { + url: $dropzone.data('upload-url'), + headers: { 'X-Csrf-Token': csrf }, + maxFiles: $dropzone.data('max-file'), + maxFilesize: $dropzone.data('max-size'), + acceptedFiles: ($dropzone.data('accepts') === '*/*') ? null : $dropzone.data('accepts'), + addRemoveLinks: true, + dictDefaultMessage: $dropzone.data('default-message'), + dictInvalidFileType: $dropzone.data('invalid-input-type'), + dictFileTooBig: $dropzone.data('file-too-big'), + dictRemoveFile: $dropzone.data('remove-file'), + init() { + this.on('success', (file, data) => { + filenameDict[file.name] = data.uuid; + const input = $(``).val(data.uuid); + $('.files').append(input); + }); + this.on('removedfile', (file) => { + if (file.name in filenameDict) { + $(`#${filenameDict[file.name]}`).remove(); + } + if ($dropzone.data('remove-url') && $dropzone.data('csrf')) { + $.post($dropzone.data('remove-url'), { + file: filenameDict[file.name], + _csrf: $dropzone.data('csrf') + }); + } + }); + }, + }); + } + + // Emojify + emojify.setConfig({ + img_dir: `${suburl}/vendor/plugins/emojify/images`, + ignore_emoticons: true + }); + const hasEmoji = document.getElementsByClassName('has-emoji'); + for (let i = 0; i < hasEmoji.length; i++) { + emojify.run(hasEmoji[i]); + for (let j = 0; j < hasEmoji[i].childNodes.length; j++) { + if (hasEmoji[i].childNodes[j].nodeName === 'A') { + emojify.run(hasEmoji[i].childNodes[j]); + } + } + } + + // Clipboard JS + const clipboard = new Clipboard('.clipboard'); + clipboard.on('success', (e) => { + e.clearSelection(); + + $(`#${e.trigger.getAttribute('id')}`).popup('destroy'); + e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-success')); + $(`#${e.trigger.getAttribute('id')}`).popup('show'); + e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original')); + }); + + clipboard.on('error', (e) => { + $(`#${e.trigger.getAttribute('id')}`).popup('destroy'); + e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-error')); + $(`#${e.trigger.getAttribute('id')}`).popup('show'); + e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original')); + }); + + // Helpers. + $('.delete-button').click(showDeletePopup); + $('.add-all-button').click(showAddAllPopup); + + $('.delete-branch-button').click(showDeletePopup); + + $('.undo-button').click(function () { + const $this = $(this); + $.post($this.data('url'), { + _csrf: csrf, + id: $this.data('id') + }).done((data) => { + window.location.href = data.redirect; + }); + }); + $('.show-panel.button').click(function () { + $($(this).data('panel')).show(); + }); + $('.show-modal.button').click(function () { + $($(this).data('modal')).modal('show'); + }); + $('.delete-post.button').click(function () { + const $this = $(this); + $.post($this.data('request-url'), { + _csrf: csrf + }).done(() => { + window.location.href = $this.data('done-url'); + }); + }); + + // Set anchor. + $('.markdown').each(function () { + const headers = {}; + $(this).find('h1, h2, h3, h4, h5, h6').each(function () { + let node = $(this); + const val = encodeURIComponent(node.text().toLowerCase().replace(/[^\u00C0-\u1FFF\u2C00-\uD7FF\w\- ]/g, '').replace(/[ ]/g, '-')); + let name = val; + if (headers[val] > 0) { + name = `${val}-${headers[val]}`; + } + if (headers[val] === undefined) { + headers[val] = 1; + } else { + headers[val] += 1; + } + node = node.wrap(`
`); + node.append(``); + }); + }); + + $('.issue-checkbox').click(() => { + const numChecked = $('.issue-checkbox').children('input:checked').length; + if (numChecked > 0) { + $('#issue-filters').addClass('hide'); + $('#issue-actions').removeClass('hide'); + } else { + $('#issue-filters').removeClass('hide'); + $('#issue-actions').addClass('hide'); + } + }); + + $('.issue-action').click(function () { + let { action } = this.dataset; + let { elementId } = this.dataset; + const issueIDs = $('.issue-checkbox').children('input:checked').map(function () { + return this.dataset.issueId; + }).get().join(); + const { url } = this.dataset; + if (elementId === '0' && url.substr(-9) === '/assignee') { + elementId = ''; + action = 'clear'; + } + updateIssuesMeta(url, action, issueIDs, elementId).then(() => { + // NOTICE: This reset of checkbox state targets Firefox caching behaviour, as the checkboxes stay checked after reload + if (action === 'close' || action === 'open') { + // uncheck all checkboxes + $('.issue-checkbox input[type="checkbox"]').each((_, e) => { e.checked = false; }); + } + reload(); + }); + }); + + // NOTICE: This event trigger targets Firefox caching behaviour, as the checkboxes stay checked after reload + // trigger ckecked event, if checkboxes are checked on load + $('.issue-checkbox input[type="checkbox"]:checked').first().each((_, e) => { + e.checked = false; + $(e).click(); + }); + + buttonsClickOnEnter(); + searchUsers(); + searchTeams(); + searchRepositories(); + + initCommentForm(); + initInstall(); + initRepository(); + initMigration(); + initWikiForm(); + initEditForm(); + initEditor(); + initOrganization(); + initGithook(); + initWebhook(); + initAdmin(); + initCodeView(); + initVueApp(); + initTeamSettings(); + initCtrlEnterSubmit(); + initNavbarContentToggle(); + initTopicbar(); + initU2FAuth(); + initU2FRegister(); + initIssueList(); + initWipTitle(); + initPullRequestReview(); + initRepoStatusChecker(); + initTemplateSearch(); + + // Repo clone url. + if ($('#repo-clone-url').length > 0) { + switch (localStorage.getItem('repo-clone-protocol')) { + case 'ssh': + if ($('#repo-clone-ssh').click().length === 0) { + $('#repo-clone-https').click(); + } + break; + default: + $('#repo-clone-https').click(); + break; + } + } + + const routes = { + 'div.user.settings': initUserSettings, + 'div.repository.settings.collaboration': initRepositoryCollaboration + }; + + let selector; + for (selector in routes) { + if ($(selector).length > 0) { + routes[selector](); + break; + } + } + + const $cloneAddr = $('#clone_addr'); + $cloneAddr.change(() => { + const $repoName = $('#repo_name'); + if ($cloneAddr.val().length > 0 && $repoName.val().length === 0) { // Only modify if repo_name input is blank + $repoName.val($cloneAddr.val().match(/^(.*\/)?((.+?)(\.git)?)$/)[3]); + } + }); +}); + +function changeHash(hash) { + if (window.history.pushState) { + window.history.pushState(null, null, hash); + } else { + window.location.hash = hash; + } +} + +function deSelect() { + if (window.getSelection) { + window.getSelection().removeAllRanges(); + } else { + document.selection.empty(); + } +} + +function selectRange($list, $select, $from) { + $list.removeClass('active'); + if ($from) { + let a = parseInt($select.attr('rel').substr(1)); + let b = parseInt($from.attr('rel').substr(1)); + let c; + if (a !== b) { + if (a > b) { + c = a; + a = b; + b = c; + } + const classes = []; + for (let i = a; i <= b; i++) { + classes.push(`.L${i}`); + } + $list.filter(classes.join(',')).addClass('active'); + changeHash(`#L${a}-L${b}`); + return; + } + } + $select.addClass('active'); + changeHash(`#${$select.attr('rel')}`); +} + +$(() => { + // Warn users that try to leave a page after entering data into a form. + // Except on sign-in pages, and for forms marked as 'ignore-dirty'. + if ($('.user.signin').length === 0) { + $('form:not(.ignore-dirty)').areYouSure(); + } + + // Parse SSH Key + $('#ssh-key-content').on('change paste keyup', function () { + const arrays = $(this).val().split(' '); + const $title = $('#ssh-key-title'); + if ($title.val() === '' && arrays.length === 3 && arrays[2] !== '') { + $title.val(arrays[2]); + } + }); +}); + +function showDeletePopup() { + const $this = $(this); + let filter = ''; + if ($this.attr('id')) { + filter += `#${$this.attr('id')}`; + } + + const dialog = $(`.delete.modal${filter}`); + dialog.find('.name').text($this.data('name')); + + dialog.modal({ + closable: false, + onApprove() { + if ($this.data('type') === 'form') { + $($this.data('form')).submit(); + return; + } + + $.post($this.data('url'), { + _csrf: csrf, + id: $this.data('id') + }).done((data) => { + window.location.href = data.redirect; + }); + } + }).modal('show'); + return false; +} + +function showAddAllPopup() { + const $this = $(this); + let filter = ''; + if ($this.attr('id')) { + filter += `#${$this.attr('id')}`; + } + + const dialog = $(`.addall.modal${filter}`); + dialog.find('.name').text($this.data('name')); + + dialog.modal({ + closable: false, + onApprove() { + if ($this.data('type') === 'form') { + $($this.data('form')).submit(); + return; + } + + $.post($this.data('url'), { + _csrf: csrf, + id: $this.data('id') + }).done((data) => { + window.location.href = data.redirect; + }); + } + }).modal('show'); + return false; +} + +function initVueComponents() { + const vueDelimeters = ['${', '}']; + + Vue.component('repo-search', { + delimiters: vueDelimeters, + + props: { + searchLimit: { + type: Number, + default: 10 + }, + suburl: { + type: String, + required: true + }, + uid: { + type: Number, + required: true + }, + organizations: { + type: Array, + default: [] + }, + isOrganization: { + type: Boolean, + default: true + }, + canCreateOrganization: { + type: Boolean, + default: false + }, + organizationsTotalCount: { + type: Number, + default: 0 + }, + moreReposLink: { + type: String, + default: '' + } + }, + + data() { + return { + tab: 'repos', + repos: [], + reposTotalCount: 0, + reposFilter: 'all', + searchQuery: '', + isLoading: false, + repoTypes: { + all: { + count: 0, + searchMode: '', + }, + forks: { + count: 0, + searchMode: 'fork', + }, + mirrors: { + count: 0, + searchMode: 'mirror', + }, + sources: { + count: 0, + searchMode: 'source', + }, + collaborative: { + count: 0, + searchMode: 'collaborative', + }, + } + }; + }, + + computed: { + showMoreReposLink() { + return this.repos.length > 0 && this.repos.length < this.repoTypes[this.reposFilter].count; + }, + searchURL() { + return `${this.suburl}/api/v1/repos/search?sort=updated&order=desc&uid=${this.uid}&q=${this.searchQuery + }&limit=${this.searchLimit}&mode=${this.repoTypes[this.reposFilter].searchMode + }${this.reposFilter !== 'all' ? '&exclusive=1' : ''}`; + }, + repoTypeCount() { + return this.repoTypes[this.reposFilter].count; + } + }, + + mounted() { + this.searchRepos(this.reposFilter); + + const self = this; + Vue.nextTick(() => { + self.$refs.search.focus(); + }); + }, + + methods: { + changeTab(t) { + this.tab = t; + }, + + changeReposFilter(filter) { + this.reposFilter = filter; + this.repos = []; + this.repoTypes[filter].count = 0; + this.searchRepos(filter); + }, + + showRepo(repo, filter) { + switch (filter) { + case 'sources': + return repo.owner.id === this.uid && !repo.mirror && !repo.fork; + case 'forks': + return repo.owner.id === this.uid && !repo.mirror && repo.fork; + case 'mirrors': + return repo.mirror; + case 'collaborative': + return repo.owner.id !== this.uid && !repo.mirror; + default: + return true; + } + }, + + searchRepos(reposFilter) { + const self = this; + + this.isLoading = true; + + const searchedMode = this.repoTypes[reposFilter].searchMode; + const searchedURL = this.searchURL; + const searchedQuery = this.searchQuery; + + $.getJSON(searchedURL, (result, _textStatus, request) => { + if (searchedURL === self.searchURL) { + self.repos = result.data; + const count = request.getResponseHeader('X-Total-Count'); + if (searchedQuery === '' && searchedMode === '') { + self.reposTotalCount = count; + } + self.repoTypes[reposFilter].count = count; + } + }).always(() => { + if (searchedURL === self.searchURL) { + self.isLoading = false; + } + }); + }, + + repoClass(repo) { + if (repo.fork) { + return 'octicon octicon-repo-forked'; + } if (repo.mirror) { + return 'octicon octicon-repo-clone'; + } if (repo.private) { + return 'octicon octicon-lock'; + } + return 'octicon octicon-repo'; + } + } + }); +} + +function initCtrlEnterSubmit() { + $('.js-quick-submit').keydown(function (e) { + if (((e.ctrlKey && !e.altKey) || e.metaKey) && (e.keyCode === 13 || e.keyCode === 10)) { + $(this).closest('form').submit(); + } + }); +} + +function initVueApp() { + const el = document.getElementById('app'); + if (!el) { + return; + } + + initVueComponents(); + + new Vue({ + delimiters: ['${', '}'], + el, + data: { + searchLimit: document.querySelector('meta[name=_search_limit]').content, + suburl: document.querySelector('meta[name=_suburl]').content, + uid: document.querySelector('meta[name=_context_uid]').content, + }, + }); +} + +window.timeAddManual = function () { + $('.mini.modal') + .modal({ + duration: 200, + onApprove() { + $('#add_time_manual_form').submit(); + } + }).modal('show'); +}; + +window.toggleStopwatch = function () { + $('#toggle_stopwatch_form').submit(); +}; +window.cancelStopwatch = function () { + $('#cancel_stopwatch_form').submit(); +}; + +window.initHeatmap = function (appElementId, heatmapUser, locale) { + const el = document.getElementById(appElementId); + if (!el) { + return; + } + + locale = locale || {}; + + locale.contributions = locale.contributions || 'contributions'; + locale.no_contributions = locale.no_contributions || 'No contributions'; + + const vueDelimeters = ['${', '}']; + + Vue.component('activity-heatmap', { + delimiters: vueDelimeters, + + props: { + user: { + type: String, + required: true + }, + suburl: { + type: String, + required: true + }, + locale: { + type: Object, + required: true + } + }, + + data() { + return { + isLoading: true, + colorRange: [], + endDate: null, + values: [], + totalContributions: 0, + }; + }, + + mounted() { + this.colorRange = [ + this.getColor(0), + this.getColor(1), + this.getColor(2), + this.getColor(3), + this.getColor(4), + this.getColor(5) + ]; + this.endDate = new Date(); + this.loadHeatmap(this.user); + }, + + methods: { + loadHeatmap(userName) { + const self = this; + $.get(`${this.suburl}/api/v1/users/${userName}/heatmap`, (chartRawData) => { + const chartData = []; + for (let i = 0; i < chartRawData.length; i++) { + self.totalContributions += chartRawData[i].contributions; + chartData[i] = { date: new Date(chartRawData[i].timestamp * 1000), count: chartRawData[i].contributions }; + } + self.values = chartData; + self.isLoading = false; + }); + }, + + getColor(idx) { + const el = document.createElement('div'); + el.className = `heatmap-color-${idx}`; + document.body.appendChild(el); + + const color = getComputedStyle(el).backgroundColor; + + document.body.removeChild(el); + + return color; + } + }, + + template: '

total contributions in the last 12 months

' + }); + + new Vue({ + delimiters: vueDelimeters, + el, + + data: { + suburl: document.querySelector('meta[name=_suburl]').content, + heatmapUser, + locale + }, + }); +}; + +function initFilterBranchTagDropdown(selector) { + $(selector).each(function () { + const $dropdown = $(this); + const $data = $dropdown.find('.data'); + const data = { + items: [], + mode: $data.data('mode'), + searchTerm: '', + noResults: '', + canCreateBranch: false, + menuVisible: false, + active: 0 + }; + $data.find('.item').each(function () { + data.items.push({ + name: $(this).text(), + url: $(this).data('url'), + branch: $(this).hasClass('branch'), + tag: $(this).hasClass('tag'), + selected: $(this).hasClass('selected') + }); + }); + $data.remove(); + new Vue({ + delimiters: ['${', '}'], + el: this, + data, + + beforeMount() { + const vm = this; + + this.noResults = vm.$el.getAttribute('data-no-results'); + this.canCreateBranch = vm.$el.getAttribute('data-can-create-branch') === 'true'; + + document.body.addEventListener('click', (event) => { + if (vm.$el.contains(event.target)) { + return; + } + if (vm.menuVisible) { + Vue.set(vm, 'menuVisible', false); + } + }); + }, + + watch: { + menuVisible(visible) { + if (visible) { + this.focusSearchField(); + } + } + }, + + computed: { + filteredItems() { + const vm = this; + + const items = vm.items.filter((item) => { + return ((vm.mode === 'branches' && item.branch) || (vm.mode === 'tags' && item.tag)) + && (!vm.searchTerm || item.name.toLowerCase().indexOf(vm.searchTerm.toLowerCase()) >= 0); + }); + + vm.active = (items.length === 0 && vm.showCreateNewBranch ? 0 : -1); + + return items; + }, + showNoResults() { + return this.filteredItems.length === 0 && !this.showCreateNewBranch; + }, + showCreateNewBranch() { + const vm = this; + if (!this.canCreateBranch || !vm.searchTerm || vm.mode === 'tags') { + return false; + } + + return vm.items.filter((item) => item.name.toLowerCase() === vm.searchTerm.toLowerCase()).length === 0; + } + }, + + methods: { + selectItem(item) { + const prev = this.getSelected(); + if (prev !== null) { + prev.selected = false; + } + item.selected = true; + window.location.href = item.url; + }, + createNewBranch() { + if (!this.showCreateNewBranch) { + return; + } + this.$refs.newBranchForm.submit(); + }, + focusSearchField() { + const vm = this; + Vue.nextTick(() => { + vm.$refs.searchField.focus(); + }); + }, + getSelected() { + for (let i = 0, j = this.items.length; i < j; ++i) { + if (this.items[i].selected) return this.items[i]; + } + return null; + }, + getSelectedIndexInFiltered() { + for (let i = 0, j = this.filteredItems.length; i < j; ++i) { + if (this.filteredItems[i].selected) return i; + } + return -1; + }, + scrollToActive() { + let el = this.$refs[`listItem${this.active}`]; + if (!el || el.length === 0) { + return; + } + if (Array.isArray(el)) { + el = el[0]; + } + + const cont = this.$refs.scrollContainer; + + if (el.offsetTop < cont.scrollTop) { + cont.scrollTop = el.offsetTop; + } else if (el.offsetTop + el.clientHeight > cont.scrollTop + cont.clientHeight) { + cont.scrollTop = el.offsetTop + el.clientHeight - cont.clientHeight; + } + }, + keydown(event) { + const vm = this; + if (event.keyCode === 40) { + // arrow down + event.preventDefault(); + + if (vm.active === -1) { + vm.active = vm.getSelectedIndexInFiltered(); + } + + if (vm.active + (vm.showCreateNewBranch ? 0 : 1) >= vm.filteredItems.length) { + return; + } + vm.active++; + vm.scrollToActive(); + } + if (event.keyCode === 38) { + // arrow up + event.preventDefault(); + + if (vm.active === -1) { + vm.active = vm.getSelectedIndexInFiltered(); + } + + if (vm.active <= 0) { + return; + } + vm.active--; + vm.scrollToActive(); + } + if (event.keyCode === 13) { + // enter + event.preventDefault(); + + if (vm.active >= vm.filteredItems.length) { + vm.createNewBranch(); + } else if (vm.active >= 0) { + vm.selectItem(vm.filteredItems[vm.active]); + } + } + if (event.keyCode === 27) { + // escape + event.preventDefault(); + vm.menuVisible = false; + } + } + } + }); + }); +} + +$('.commit-button').click(function (e) { + e.preventDefault(); + $(this).parent().find('.commit-body').toggle(); +}); + +function initNavbarContentToggle() { + const content = $('#navbar'); + const toggle = $('#navbar-expand-toggle'); + let isExpanded = false; + toggle.click(() => { + isExpanded = !isExpanded; + if (isExpanded) { + content.addClass('shown'); + toggle.addClass('active'); + } else { + content.removeClass('shown'); + toggle.removeClass('active'); + } + }); +} + +function initTopicbar() { + const mgrBtn = $('#manage_topic'); + const editDiv = $('#topic_edit'); + const viewDiv = $('#repo-topics'); + const saveBtn = $('#save_topic'); + const topicDropdown = $('#topic_edit .dropdown'); + const topicForm = $('#topic_edit.ui.form'); + const topicPrompts = getPrompts(); + + mgrBtn.click(() => { + viewDiv.hide(); + editDiv.css('display', ''); // show Semantic UI Grid + }); + + function getPrompts() { + const hidePrompt = $('div.hide#validate_prompt'); + const prompts = { + countPrompt: hidePrompt.children('#count_prompt').text(), + formatPrompt: hidePrompt.children('#format_prompt').text() + }; + hidePrompt.remove(); + return prompts; + } + + saveBtn.click(() => { + const topics = $('input[name=topics]').val(); + + $.post(saveBtn.data('link'), { + _csrf: csrf, + topics + }, (_data, _textStatus, xhr) => { + if (xhr.responseJSON.status === 'ok') { + viewDiv.children('.topic').remove(); + if (topics.length) { + const topicArray = topics.split(','); + + const last = viewDiv.children('a').last(); + for (let i = 0; i < topicArray.length; i++) { + $(`
${topicArray[i]}
`).insertBefore(last); + } + } + editDiv.css('display', 'none'); + viewDiv.show(); + } + }).fail((xhr) => { + if (xhr.status === 422) { + if (xhr.responseJSON.invalidTopics.length > 0) { + topicPrompts.formatPrompt = xhr.responseJSON.message; + + const { invalidTopics } = xhr.responseJSON; + const topicLables = topicDropdown.children('a.ui.label'); + + topics.split(',').forEach((value, index) => { + for (let i = 0; i < invalidTopics.length; i++) { + if (invalidTopics[i] === value) { + topicLables.eq(index).removeClass('green').addClass('red'); + } + } + }); + } else { + topicPrompts.countPrompt = xhr.responseJSON.message; + } + } + }).always(() => { + topicForm.form('validate form'); + }); + }); + + topicDropdown.dropdown({ + allowAdditions: true, + forceSelection: false, + fields: { name: 'description', value: 'data-value' }, + saveRemoteData: false, + label: { + transition: 'horizontal flip', + duration: 200, + variation: false, + blue: true, + basic: true, + }, + className: { + label: 'ui small label' + }, + apiSettings: { + url: `${suburl}/api/v1/topics/search?q={query}`, + throttle: 500, + cache: false, + onResponse(res) { + const formattedResponse = { + success: false, + results: [], + }; + const stripTags = function (text) { + return text.replace(/<[^>]*>?/gm, ''); + }; + + const query = stripTags(this.urlData.query.trim()); + let found_query = false; + const current_topics = []; + topicDropdown.find('div.label.visible.topic,a.label.visible').each((_, e) => { current_topics.push(e.dataset.value); }); + + if (res.topics) { + let found = false; + for (let i = 0; i < res.topics.length; i++) { + // skip currently added tags + if (current_topics.indexOf(res.topics[i].topic_name) !== -1) { + continue; + } + + if (res.topics[i].topic_name.toLowerCase() === query.toLowerCase()) { + found_query = true; + } + formattedResponse.results.push({ description: res.topics[i].topic_name, 'data-value': res.topics[i].topic_name }); + found = true; + } + formattedResponse.success = found; + } + + if (query.length > 0 && !found_query) { + formattedResponse.success = true; + formattedResponse.results.unshift({ description: query, 'data-value': query }); + } else if (query.length > 0 && found_query) { + formattedResponse.results.sort((a, b) => { + if (a.description.toLowerCase() === query.toLowerCase()) return -1; + if (b.description.toLowerCase() === query.toLowerCase()) return 1; + if (a.description > b.description) return -1; + if (a.description < b.description) return 1; + return 0; + }); + } + + + return formattedResponse; + }, + }, + onLabelCreate(value) { + value = value.toLowerCase().trim(); + this.attr('data-value', value).contents().first().replaceWith(value); + return $(this); + }, + onAdd(addedValue, _addedText, $addedChoice) { + addedValue = addedValue.toLowerCase().trim(); + $($addedChoice).attr('data-value', addedValue); + $($addedChoice).attr('data-text', addedValue); + } + }); + + $.fn.form.settings.rules.validateTopic = function (_values, regExp) { + const topics = topicDropdown.children('a.ui.label'); + const status = topics.length === 0 || topics.last().attr('data-value').match(regExp); + if (!status) { + topics.last().removeClass('green').addClass('red'); + } + return status && topicDropdown.children('a.ui.label.red').length === 0; + }; + + topicForm.form({ + on: 'change', + inline: true, + fields: { + topics: { + identifier: 'topics', + rules: [ + { + type: 'validateTopic', + value: /^[a-z0-9][a-z0-9-]{1,35}$/, + prompt: topicPrompts.formatPrompt + }, + { + type: 'maxCount[25]', + prompt: topicPrompts.countPrompt + } + ] + }, + } + }); +} + +window.toggleDeadlineForm = function () { + $('#deadlineForm').fadeToggle(150); +}; + +window.setDeadline = function () { + const deadline = $('#deadlineDate').val(); + window.updateDeadline(deadline); +}; + +window.updateDeadline = function (deadlineString) { + $('#deadline-err-invalid-date').hide(); + $('#deadline-loader').addClass('loading'); + + let realDeadline = null; + if (deadlineString !== '') { + const newDate = Date.parse(deadlineString); + + if (Number.isNaN(newDate)) { + $('#deadline-loader').removeClass('loading'); + $('#deadline-err-invalid-date').show(); + return false; + } + realDeadline = new Date(newDate); + } + + $.ajax(`${$('#update-issue-deadline-form').attr('action')}/deadline`, { + data: JSON.stringify({ + due_date: realDeadline, + }), + headers: { + 'X-Csrf-Token': csrf, + 'X-Remote': true, + }, + contentType: 'application/json', + type: 'POST', + success() { + reload(); + }, + error() { + $('#deadline-loader').removeClass('loading'); + $('#deadline-err-invalid-date').show(); + } + }); +}; + +window.deleteDependencyModal = function (id, type) { + $('.remove-dependency') + .modal({ + closable: false, + duration: 200, + onApprove() { + $('#removeDependencyID').val(id); + $('#dependencyType').val(type); + $('#removeDependencyForm').submit(); + } + }).modal('show'); +}; + +function initIssueList() { + const repolink = $('#repolink').val(); + const repoId = $('#repoId').val(); + const crossRepoSearch = $('#crossRepoSearch').val(); + let issueSearchUrl = `${suburl}/api/v1/repos/${repolink}/issues?q={query}`; + if (crossRepoSearch === 'true') { + issueSearchUrl = `${suburl}/api/v1/repos/issues/search?q={query}&priority_repo_id=${repoId}`; + } + $('#new-dependency-drop-list') + .dropdown({ + apiSettings: { + url: issueSearchUrl, + onResponse(response) { + const filteredResponse = { success: true, results: [] }; + const currIssueId = $('#new-dependency-drop-list').data('issue-id'); + // Parse the response from the api to work with our dropdown + $.each(response, (_i, issue) => { + // Don't list current issue in the dependency list. + if (issue.id === currIssueId) { + return; + } + filteredResponse.results.push({ + name: `#${issue.number} ${htmlEncode(issue.title) + }
${htmlEncode(issue.repository.full_name)}
`, + value: issue.id + }); + }); + return filteredResponse; + }, + cache: false, + }, + + fullTextSearch: true + }); + + $('.menu a.label-filter-item').each(function () { + $(this).click(function (e) { + if (e.altKey) { + e.preventDefault(); + + const href = $(this).attr('href'); + const id = $(this).data('label-id'); + + const regStr = `labels=(-?[0-9]+%2c)*(${id})(%2c-?[0-9]+)*&`; + const newStr = 'labels=$1-$2$3&'; + + window.location = href.replace(new RegExp(regStr), newStr); + } + }); + }); + + $('.menu .ui.dropdown.label-filter').keydown((e) => { + if (e.altKey && e.keyCode === 13) { + const selectedItems = $('.menu .ui.dropdown.label-filter .menu .item.selected'); + + if (selectedItems.length > 0) { + const item = $(selectedItems[0]); + + const href = item.attr('href'); + const id = item.data('label-id'); + + const regStr = `labels=(-?[0-9]+%2c)*(${id})(%2c-?[0-9]+)*&`; + const newStr = 'labels=$1-$2$3&'; + + window.location = href.replace(new RegExp(regStr), newStr); + } + } + }); +} +window.cancelCodeComment = function (btn) { + const form = $(btn).closest('form'); + if (form.length > 0 && form.hasClass('comment-form')) { + form.addClass('hide'); + form.parent().find('button.comment-form-reply').show(); + } else { + form.closest('.comment-code-cloud').remove(); + } +}; +window.onOAuthLoginClick = function () { + const oauthLoader = $('#oauth2-login-loader'); + const oauthNav = $('#oauth2-login-navigator'); + + oauthNav.hide(); + oauthLoader.removeClass('disabled'); + + setTimeout(() => { + // recover previous content to let user try again + // usually redirection will be performed before this action + oauthLoader.addClass('disabled'); + oauthNav.show(); + }, 5000); +}; diff --git a/web_src/less/_repository.less b/web_src/less/_repository.less index 84d59bbe91e..974dd571ccd 100644 --- a/web_src/less/_repository.less +++ b/web_src/less/_repository.less @@ -2438,6 +2438,10 @@ tbody.commit-list { padding-bottom: 8px; } +td.blob-excerpt { + background-color: #fafafa; +} + .issue-keyword { border-bottom: 1px dotted #959da5; display: inline-block; diff --git a/web_src/less/_review.less b/web_src/less/_review.less index c01e7533b40..d838c09c2d7 100644 --- a/web_src/less/_review.less +++ b/web_src/less/_review.less @@ -108,3 +108,26 @@ font: 12px @monospaced-fonts, monospace; color: rgba(0, 0, 0, 0.87); } + +.ui.fold-code { + margin-right: 1em; + padding-left: 5px; + cursor: pointer; + width: 22px; + font-size: 12px; +} + +.ui.fold-code:hover { + color: #428bca; +} + +.ui.blob-excerpt { + display: block; + line-height: 20px; + font-size: 16px; + cursor: pointer; +} + +.ui.blob-excerpt:hover { + color: #428bca; +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 00000000000..4fdf4ba5a49 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,42 @@ +const path = require('path'); +const TerserPlugin = require('terser-webpack-plugin'); + +module.exports = { + mode: 'production', + entry: { + index: ['./web_src/js/index', './web_src/js/draw'] + }, + devtool: 'source-map', + output: { + path: path.resolve(__dirname, 'public/js'), + filename: 'index.js' + }, + optimization: { + minimize: true, + minimizer: [new TerserPlugin({ + sourceMap: true, + })], + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + presets: [ + [ + '@babel/preset-env', + { + useBuiltIns: 'entry', + corejs: 3, + } + ] + ] + } + } + } + ] + } +};
{{if $line.LeftIdx}}{{end}}{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 2))}}+{{end}}{{if $line.LeftIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}{{if $line.RightIdx}}{{end}}{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 3))}}+{{end}}{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}} + {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }} + + {{end}} + {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }} + + {{end}} + {{if or (eq $line.GetExpandDirection 2)}} + + {{end}} + {{$section.GetComputedInlineDiffFor $line}}{{if $line.LeftIdx}}{{end}}{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 2))}}+{{end}}{{if $line.LeftIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}{{if $line.RightIdx}}{{end}}{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 3))}}+{{end}}{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}
- {{/* {{if gt $j 0}}{{end}} */}} - + {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }} + + {{end}} + {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }} + + {{end}} + {{if or (eq $line.GetExpandDirection 2)}} + + {{end}} +