loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request '[gitea] week 13 cherry-pick' (#2769) from earl-warren/forgejo:wip-gitea-cherry-pick into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/2769
Reviewed-by: oliverpool <oliverpool@noreply.codeberg.org>

+2713 -5205
+10 -1
.air.toml
··· 8 8 include_ext = ["go", "tmpl"] 9 9 include_file = ["main.go"] 10 10 include_dir = ["cmd", "models", "modules", "options", "routers", "services"] 11 - exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata", "models/fixtures", "models/migrations/fixtures", "modules/migration/file_format_testdata", "modules/avatar/identicon/testdata"] 11 + exclude_dir = [ 12 + "models/fixtures", 13 + "models/migrations/fixtures", 14 + "modules/avatar/identicon/testdata", 15 + "modules/avatar/testdata", 16 + "modules/git/tests", 17 + "modules/migration/file_format_testdata", 18 + "routers/private/tests", 19 + "services/gitdiff/testdata", 20 + ] 12 21 exclude_regex = ["_test.go$", "_gen.go$"] 13 22 stop_on_error = true
+2 -2
.devcontainer/devcontainer.json
··· 4 4 "features": { 5 5 // installs nodejs into container 6 6 "ghcr.io/devcontainers/features/node:1": { 7 - "version":"20" 7 + "version": "20" 8 8 }, 9 9 "ghcr.io/devcontainers/features/git-lfs:1.1.0": {}, 10 10 "ghcr.io/devcontainers-contrib/features/poetry:2": {}, ··· 24 24 "DavidAnson.vscode-markdownlint", 25 25 "Vue.volar", 26 26 "ms-azuretools.vscode-docker", 27 - "zixuanchen.vitest-explorer", 27 + "vitest.explorer", 28 28 "qwtel.sqlite-viewer", 29 29 "GitHub.vscode-pull-request-github" 30 30 ]
+1 -1
.dockerignore
··· 62 62 /data 63 63 /indexers 64 64 /log 65 - /public/img/avatar 66 65 /tests/integration/gitea-integration-* 67 66 /tests/integration/indexers-* 68 67 /tests/e2e/gitea-e2e-* ··· 77 76 /public/assets/js 78 77 /public/assets/css 79 78 /public/assets/fonts 79 + /public/assets/img/avatar 80 80 /public/assets/img/webpack 81 81 /vendor 82 82 /web_src/fomantic/node_modules
+3 -7
.eslintrc.yaml
··· 42 42 worker: true 43 43 rules: 44 44 no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, status, statusbar, stop, toolbar, top] 45 - - files: ["build/generate-images.js"] 46 - rules: 47 - i/no-unresolved: [0] 48 - i/no-extraneous-dependencies: [0] 49 45 - files: ["*.config.*"] 50 46 rules: 51 47 i/no-unused-modules: [0] ··· 123 119 "@stylistic/js/arrow-spacing": [2, {before: true, after: true}] 124 120 "@stylistic/js/block-spacing": [0] 125 121 "@stylistic/js/brace-style": [2, 1tbs, {allowSingleLine: true}] 126 - "@stylistic/js/comma-dangle": [2, only-multiline] 122 + "@stylistic/js/comma-dangle": [2, always-multiline] 127 123 "@stylistic/js/comma-spacing": [2, {before: false, after: true}] 128 124 "@stylistic/js/comma-style": [2, last] 129 125 "@stylistic/js/computed-property-spacing": [2, never] ··· 290 286 jquery/no-class: [0] 291 287 jquery/no-clone: [2] 292 288 jquery/no-closest: [0] 293 - jquery/no-css: [0] 289 + jquery/no-css: [2] 294 290 jquery/no-data: [0] 295 291 jquery/no-deferred: [2] 296 292 jquery/no-delegate: [2] ··· 413 409 no-jquery/no-constructor-attributes: [2] 414 410 no-jquery/no-contains: [2] 415 411 no-jquery/no-context-prop: [2] 416 - no-jquery/no-css: [0] 412 + no-jquery/no-css: [2] 417 413 no-jquery/no-data: [0] 418 414 no-jquery/no-deferred: [2] 419 415 no-jquery/no-delegate: [2]
+1 -1
.gitignore
··· 64 64 /data 65 65 /indexers 66 66 /log 67 - /public/img/avatar 67 + /public/assets/img/avatar 68 68 /tests/integration/gitea-integration-* 69 69 /tests/integration/indexers-* 70 70 /tests/e2e/gitea-e2e-*
+1 -1
.gitpod.yml
··· 42 42 - DavidAnson.vscode-markdownlint 43 43 - Vue.volar 44 44 - ms-azuretools.vscode-docker 45 - - zixuanchen.vitest-explorer 45 + - vitest.explorer 46 46 - qwtel.sqlite-viewer 47 47 - GitHub.vscode-pull-request-github 48 48
+4 -3
.stylelintrc.yaml
··· 30 30 "@stylistic/block-opening-brace-newline-after": null 31 31 "@stylistic/block-opening-brace-newline-before": null 32 32 "@stylistic/block-opening-brace-space-after": null 33 - "@stylistic/block-opening-brace-space-before": null 33 + "@stylistic/block-opening-brace-space-before": always 34 34 "@stylistic/color-hex-case": lower 35 35 "@stylistic/declaration-bang-space-after": never 36 36 "@stylistic/declaration-bang-space-before": null ··· 140 140 function-disallowed-list: null 141 141 function-linear-gradient-no-nonstandard-direction: true 142 142 function-name-case: lower 143 - function-no-unknown: null 143 + function-no-unknown: true 144 144 function-url-no-scheme-relative: null 145 145 function-url-quotes: always 146 146 function-url-scheme-allowed-list: null ··· 168 168 no-duplicate-selectors: true 169 169 no-empty-source: true 170 170 no-invalid-double-slash-comments: true 171 - no-invalid-position-at-import-rule: null 171 + no-invalid-position-at-import-rule: [true, ignoreAtRules: [tailwind]] 172 172 no-irregular-whitespace: true 173 173 no-unknown-animations: null 174 174 no-unknown-custom-properties: null ··· 181 181 rule-empty-line-before: null 182 182 rule-selector-property-disallowed-list: null 183 183 scale-unlimited/declaration-strict-value: [[/color$/, font-weight], {ignoreValues: /^(inherit|transparent|unset|initial|currentcolor|none)$/, ignoreFunctions: false, disableFix: true, expandShorthand: true}] 184 + selector-anb-no-unmatchable: true 184 185 selector-attribute-name-disallowed-list: null 185 186 selector-attribute-operator-allowed-list: null 186 187 selector-attribute-operator-disallowed-list: null
+9 -10
Makefile
··· 44 44 DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG) 45 45 46 46 ifeq ($(HAS_GO), yes) 47 - GOPATH ?= $(shell $(GO) env GOPATH) 48 - export PATH := $(GOPATH)/bin:$(PATH) 49 - 50 47 CGO_EXTRA_CFLAGS := -DSQLITE_MAX_VARIABLE_NUMBER=32766 51 48 CGO_CFLAGS ?= $(shell $(GO) env CGO_CFLAGS) $(CGO_EXTRA_CFLAGS) 52 49 endif ··· 148 145 GO_DIRS := build cmd models modules routers services tests 149 146 WEB_DIRS := web_src/js web_src/css 150 147 148 + ESLINT_FILES := web_src/js tools *.config.js tests/e2e 149 + STYLELINT_FILES := web_src/css web_src/js/components/*.vue 151 150 SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) docs/content templates options/locale/locale_en-US.ini .github 152 151 153 152 GO_SOURCES := $(wildcard *.go) ··· 396 395 397 396 .PHONY: lint-js 398 397 lint-js: node_modules 399 - npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js tests/e2e 398 + npx eslint --color --max-warnings=0 --ext js,vue $(ESLINT_FILES) 400 399 401 400 .PHONY: lint-js-fix 402 401 lint-js-fix: node_modules 403 - npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js tests/e2e --fix 402 + npx eslint --color --max-warnings=0 --ext js,vue $(ESLINT_FILES) --fix 404 403 405 404 .PHONY: lint-css 406 405 lint-css: node_modules 407 - npx stylelint --color --max-warnings=0 web_src/css web_src/js/components/*.vue 406 + npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) 408 407 409 408 .PHONY: lint-css-fix 410 409 lint-css-fix: node_modules 411 - npx stylelint --color --max-warnings=0 web_src/css web_src/js/components/*.vue --fix 410 + npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) --fix 412 411 413 412 .PHONY: lint-swagger 414 413 lint-swagger: node_modules ··· 468 467 469 468 .PHONY: watch 470 469 watch: 471 - @bash build/watch.sh 470 + @bash tools/watch.sh 472 471 473 472 .PHONY: watch-frontend 474 473 watch-frontend: node-check node_modules ··· 962 961 .PHONY: svg 963 962 svg: node-check | node_modules 964 963 rm -rf $(SVG_DEST_DIR) 965 - node build/generate-svg.js 964 + node tools/generate-svg.js 966 965 967 966 .PHONY: svg-check 968 967 svg-check: svg ··· 997 996 .PHONY: generate-images 998 997 generate-images: | node_modules 999 998 npm install --no-save fabric@6.0.0-beta19 imagemin-zopfli@7 1000 - node build/generate-images.js $(TAGS) 999 + node tools/generate-images.js $(TAGS) 1001 1000 1002 1001 .PHONY: generate-manpage 1003 1002 generate-manpage:
-79
build/generate-images.js
··· 1 - #!/usr/bin/env node 2 - import imageminZopfli from 'imagemin-zopfli'; 3 - import {optimize} from 'svgo'; 4 - import {loadSVGFromString, Canvas, Rect, util} from 'fabric/node'; 5 - import {readFile, writeFile} from 'node:fs/promises'; 6 - import {argv, exit} from 'node:process'; 7 - 8 - function doExit(err) { 9 - if (err) console.error(err); 10 - exit(err ? 1 : 0); 11 - } 12 - 13 - async function generate(svg, path, {size, bg}) { 14 - const outputFile = new URL(path, import.meta.url); 15 - 16 - if (String(outputFile).endsWith('.svg')) { 17 - const {data} = optimize(svg, { 18 - plugins: [ 19 - 'preset-default', 20 - 'removeDimensions', 21 - { 22 - name: 'addAttributesToSVGElement', 23 - params: {attributes: [{width: size}, {height: size}]} 24 - }, 25 - ], 26 - }); 27 - await writeFile(outputFile, data); 28 - return; 29 - } 30 - 31 - const {objects, options} = await loadSVGFromString(svg); 32 - const canvas = new Canvas(); 33 - canvas.setDimensions({width: size, height: size}); 34 - const ctx = canvas.getContext('2d'); 35 - ctx.scale(options.width ? (size / options.width) : 1, options.height ? (size / options.height) : 1); 36 - 37 - if (bg) { 38 - canvas.add(new Rect({ 39 - left: 0, 40 - top: 0, 41 - height: size * (1 / (size / options.height)), 42 - width: size * (1 / (size / options.width)), 43 - fill: 'white', 44 - })); 45 - } 46 - 47 - canvas.add(util.groupSVGElements(objects, options)); 48 - canvas.renderAll(); 49 - 50 - let png = Buffer.from([]); 51 - for await (const chunk of canvas.createPNGStream()) { 52 - png = Buffer.concat([png, chunk]); 53 - } 54 - 55 - png = await imageminZopfli({more: true})(png); 56 - await writeFile(outputFile, png); 57 - } 58 - 59 - async function main() { 60 - const gitea = argv.slice(2).includes('gitea'); 61 - const logoSvg = await readFile(new URL('../assets/logo.svg', import.meta.url), 'utf8'); 62 - const faviconSvg = await readFile(new URL('../assets/favicon.svg', import.meta.url), 'utf8'); 63 - 64 - await Promise.all([ 65 - generate(logoSvg, '../public/assets/img/logo.svg', {size: 32}), 66 - generate(logoSvg, '../public/assets/img/logo.png', {size: 512}), 67 - generate(faviconSvg, '../public/assets/img/favicon.svg', {size: 32}), 68 - generate(faviconSvg, '../public/assets/img/favicon.png', {size: 180}), 69 - generate(logoSvg, '../public/assets/img/avatar_default.png', {size: 200}), 70 - generate(logoSvg, '../public/assets/img/apple-touch-icon.png', {size: 180, bg: true}), 71 - gitea && generate(logoSvg, '../public/assets/img/gitea.svg', {size: 32}), 72 - ]); 73 - } 74 - 75 - try { 76 - doExit(await main()); 77 - } catch (err) { 78 - doExit(err); 79 - }
-70
build/generate-svg.js
··· 1 - #!/usr/bin/env node 2 - import fastGlob from 'fast-glob'; 3 - import {optimize} from 'svgo'; 4 - import {parse} from 'node:path'; 5 - import {readFile, writeFile, mkdir} from 'node:fs/promises'; 6 - import {fileURLToPath} from 'node:url'; 7 - import {exit} from 'node:process'; 8 - 9 - const glob = (pattern) => fastGlob.sync(pattern, { 10 - cwd: fileURLToPath(new URL('..', import.meta.url)), 11 - absolute: true, 12 - }); 13 - 14 - function doExit(err) { 15 - if (err) console.error(err); 16 - exit(err ? 1 : 0); 17 - } 18 - 19 - async function processFile(file, {prefix, fullName} = {}) { 20 - let name; 21 - if (fullName) { 22 - name = fullName; 23 - } else { 24 - name = parse(file).name; 25 - if (prefix) name = `${prefix}-${name}`; 26 - if (prefix === 'octicon') name = name.replace(/-[0-9]+$/, ''); // chop of '-16' on octicons 27 - } 28 - 29 - // Set the `xmlns` attribute so that the files are displayable in standalone documents 30 - // The svg backend module will strip the attribute during startup for inline display 31 - const {data} = optimize(await readFile(file, 'utf8'), { 32 - plugins: [ 33 - {name: 'preset-default'}, 34 - {name: 'removeDimensions'}, 35 - {name: 'prefixIds', params: {prefix: () => name}}, 36 - {name: 'addClassesToSVGElement', params: {classNames: ['svg', name]}}, 37 - { 38 - name: 'addAttributesToSVGElement', params: { 39 - attributes: [ 40 - {'xmlns': 'http://www.w3.org/2000/svg'}, 41 - {'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'}, 42 - ] 43 - } 44 - }, 45 - ], 46 - }); 47 - 48 - await writeFile(fileURLToPath(new URL(`../public/assets/img/svg/${name}.svg`, import.meta.url)), data); 49 - } 50 - 51 - function processFiles(pattern, opts) { 52 - return glob(pattern).map((file) => processFile(file, opts)); 53 - } 54 - 55 - async function main() { 56 - try { 57 - await mkdir(fileURLToPath(new URL('../public/assets/img/svg', import.meta.url)), {recursive: true}); 58 - } catch {} 59 - 60 - await Promise.all([ 61 - ...processFiles('node_modules/@primer/octicons/build/svg/*-16.svg', {prefix: 'octicon'}), 62 - ...processFiles('web_src/svg/*.svg'), 63 - ]); 64 - } 65 - 66 - try { 67 - doExit(await main()); 68 - } catch (err) { 69 - doExit(err); 70 - }
build/watch.sh tools/watch.sh
+3 -3
docs/content/administration/cmd-embedded.zh-cn.md
··· 37 37 38 38 - 列出所有模板文件,无论在哪个虚拟目录下:`**.tmpl` 39 39 - 列出所有邮件模板文件:`templates/mail/**.tmpl` 40 - - 列出 `public/img` 目录下的所有文件:`public/img/**` 40 + 列出 `public/assets/img` 目录下的所有文件:`public/assets/img/**` 41 41 42 42 不要忘记为模式使用引号,因为空格、`*` 和其他字符可能对命令行解释器有特殊含义。 43 43 ··· 49 49 50 50 ```sh 51 51 $ gitea embedded list '**openid**' 52 - public/img/auth/openid_connect.svg 53 - public/img/openid-16x16.png 52 + public/assets/img/auth/openid_connect.svg 53 + public/assets/img/openid-16x16.png 54 54 templates/user/auth/finalize_openid.tmpl 55 55 templates/user/auth/signin_openid.tmpl 56 56 templates/user/auth/signup_openid_connect.tmpl
+1 -1
docs/content/contributing/guidelines-frontend.en-us.md
··· 47 47 9. Avoid unnecessary `!important` in CSS, add comments to explain why it's necessary if it can't be avoided. 48 48 10. Avoid mixing different events in one event listener, prefer to use individual event listeners for every event. 49 49 11. Custom event names are recommended to use `ce-` prefix. 50 - 12. Prefer using Tailwind CSS which is available via `tw-` prefix, e.g. `tw-relative`. Gitea's helper CSS classes use `gt-` prefix (`gt-df`), while Gitea's own private framework-level CSS classes use `g-` prefix (`g-modal-confirm`). 50 + 12. Prefer using Tailwind CSS which is available via `tw-` prefix, e.g. `tw-relative`. Gitea's helper CSS classes use `gt-` prefix (`gt-mono`), while Gitea's own private framework-level CSS classes use `g-` prefix (`g-modal-confirm`). 51 51 13. Avoid inline scripts & styles as much as possible, it's recommended to put JS code into JS files and use CSS classes. If inline scripts & styles are unavoidable, explain the reason why it can't be avoided. 52 52 53 53 ### Accessibility / ARIA
+1 -1
docs/content/contributing/guidelines-frontend.zh-cn.md
··· 47 47 9. 避免在 CSS 中使用不必要的`!important`,如果无法避免,添加注释解释为什么需要它。 48 48 10. 避免在一个事件监听器中混合不同的事件,优先为每个事件使用独立的事件监听器。 49 49 11. 推荐使用自定义事件名称前缀`ce-`。 50 - 12. 建议使用 Tailwind CSS,它可以通过 `tw-` 前缀获得,例如 `tw-relative`. Gitea 自身的助手类 CSS 使用 `gt-` 前缀(`gt-df`),Gitea 自身的私有框架级 CSS 类使用 `g-` 前缀(`g-modal-confirm`)。 50 + 12. 建议使用 Tailwind CSS,它可以通过 `tw-` 前缀获得,例如 `tw-relative`. Gitea 自身的助手类 CSS 使用 `gt-` 前缀(`gt-mono`),Gitea 自身的私有框架级 CSS 类使用 `g-` 前缀(`g-modal-confirm`)。 51 51 13. 尽量避免内联脚本和样式,建议将JS代码放入JS文件中并使用CSS类。如果内联脚本和样式不可避免,请解释无法避免的原因。 52 52 53 53 ### 可访问性 / ARIA
+1 -1
docs/content/development/hacking-on-gitea.en-us.md
··· 214 214 215 215 ### Building and adding SVGs 216 216 217 - SVG icons are built using the `make svg` target which compiles the icon sources defined in `build/generate-svg.js` into the output directory `public/assets/img/svg`. Custom icons can be added in the `web_src/svg` directory. 217 + SVG icons are built using the `make svg` target which compiles the icon sources into the output directory `public/assets/img/svg`. Custom icons can be added in the `web_src/svg` directory. 218 218 219 219 ### Building the Logo 220 220
+1 -1
docs/content/development/hacking-on-gitea.zh-cn.md
··· 201 201 202 202 ### 构建和添加 SVGs 203 203 204 - SVG 图标是使用 `make svg` 目标构建的,该目标将 `build/generate-svg.js` 中定义的图标源编译到输出目录 `public/img/svg` 中。可以在 `web_src/svg` 目录中添加自定义图标。 204 + SVG 图标是使用 `make svg` 命令构建的,该命令将图标资源编译到输出目录 `public/assets/img/svg` 中。可以在 `web_src/svg` 目录中添加自定义图标。 205 205 206 206 ### 构建 Logo 207 207
+29
models/activities/notification.go
··· 20 20 "code.gitea.io/gitea/modules/log" 21 21 "code.gitea.io/gitea/modules/setting" 22 22 "code.gitea.io/gitea/modules/timeutil" 23 + "code.gitea.io/gitea/modules/util" 23 24 24 25 "xorm.io/builder" 25 26 ) ··· 841 842 Update(n) 842 843 return err 843 844 } 845 + 846 + // LoadIssuePullRequests loads all issues' pull requests if possible 847 + func (nl NotificationList) LoadIssuePullRequests(ctx context.Context) error { 848 + issues := make(map[int64]*issues_model.Issue, len(nl)) 849 + for _, notification := range nl { 850 + if notification.Issue != nil && notification.Issue.IsPull && notification.Issue.PullRequest == nil { 851 + issues[notification.Issue.ID] = notification.Issue 852 + } 853 + } 854 + 855 + if len(issues) == 0 { 856 + return nil 857 + } 858 + 859 + pulls, err := issues_model.GetPullRequestByIssueIDs(ctx, util.KeysOfMap(issues)) 860 + if err != nil { 861 + return err 862 + } 863 + 864 + for _, pull := range pulls { 865 + if issue := issues[pull.IssueID]; issue != nil { 866 + issue.PullRequest = pull 867 + issue.PullRequest.Issue = issue 868 + } 869 + } 870 + 871 + return nil 872 + }
+5 -2
models/asymkey/ssh_key_authorized_keys.go
··· 198 198 if err != nil { 199 199 return err 200 200 } 201 + defer f.Close() 202 + 201 203 scanner := bufio.NewScanner(f) 202 204 for scanner.Scan() { 203 205 line := scanner.Text() ··· 207 209 } 208 210 _, err = t.WriteString(line + "\n") 209 211 if err != nil { 210 - f.Close() 211 212 return err 212 213 } 213 214 } 214 - f.Close() 215 + if err = scanner.Err(); err != nil { 216 + return fmt.Errorf("RegeneratePublicKeys scan: %w", err) 217 + } 215 218 } 216 219 return nil 217 220 }
+5 -2
models/asymkey/ssh_key_authorized_principals.go
··· 120 120 if err != nil { 121 121 return err 122 122 } 123 + defer f.Close() 124 + 123 125 scanner := bufio.NewScanner(f) 124 126 for scanner.Scan() { 125 127 line := scanner.Text() ··· 129 131 } 130 132 _, err = t.WriteString(line + "\n") 131 133 if err != nil { 132 - f.Close() 133 134 return err 134 135 } 135 136 } 136 - f.Close() 137 + if err = scanner.Err(); err != nil { 138 + return fmt.Errorf("regeneratePrincipalKeys scan: %w", err) 139 + } 137 140 } 138 141 return nil 139 142 }
+1 -1
models/avatars/avatar.go
··· 24 24 25 25 const ( 26 26 // DefaultAvatarClass is the default class of a rendered avatar 27 - DefaultAvatarClass = "ui avatar gt-vm" 27 + DefaultAvatarClass = "ui avatar tw-align-middle" 28 28 // DefaultAvatarPixelSize is the default size in pixels of a rendered avatar 29 29 DefaultAvatarPixelSize = 28 30 30 )
-14
models/issues/issue.go
··· 194 194 return issue.Repo.IsTimetrackerEnabled(ctx) 195 195 } 196 196 197 - // GetPullRequest returns the issue pull request 198 - func (issue *Issue) GetPullRequest(ctx context.Context) (pr *PullRequest, err error) { 199 - if !issue.IsPull { 200 - return nil, fmt.Errorf("Issue is not a pull request") 201 - } 202 - 203 - pr, err = GetPullRequestByIssueID(ctx, issue.ID) 204 - if err != nil { 205 - return nil, err 206 - } 207 - pr.Issue = issue 208 - return pr, err 209 - } 210 - 211 197 // LoadPoster loads poster 212 198 func (issue *Issue) LoadPoster(ctx context.Context) (err error) { 213 199 if issue.Poster == nil && issue.PosterID != 0 {
+3
models/issues/issue_list.go
··· 370 370 371 371 for _, issue := range issues { 372 372 issue.PullRequest = pullRequestMaps[issue.ID] 373 + if issue.PullRequest != nil { 374 + issue.PullRequest.Issue = issue 375 + } 373 376 } 374 377 return nil 375 378 }
+12 -6
models/issues/pull_list.go
··· 11 11 access_model "code.gitea.io/gitea/models/perm/access" 12 12 "code.gitea.io/gitea/models/unit" 13 13 user_model "code.gitea.io/gitea/models/user" 14 - "code.gitea.io/gitea/modules/base" 15 14 "code.gitea.io/gitea/modules/log" 16 15 "code.gitea.io/gitea/modules/util" 17 16 ··· 23 22 db.ListOptions 24 23 State string 25 24 SortType string 26 - Labels []string 25 + Labels []int64 27 26 MilestoneID int64 28 27 } 29 28 ··· 36 35 sess.And("issue.is_closed=?", opts.State == "closed") 37 36 } 38 37 39 - if labelIDs, err := base.StringsToInt64s(opts.Labels); err != nil { 40 - return nil, err 41 - } else if len(labelIDs) > 0 { 38 + if len(opts.Labels) > 0 { 42 39 sess.Join("INNER", "issue_label", "issue.id = issue_label.issue_id"). 43 - In("issue_label.label_id", labelIDs) 40 + In("issue_label.label_id", opts.Labels) 44 41 } 45 42 46 43 if opts.MilestoneID > 0 { ··· 220 217 Limit(1). 221 218 Get(new(Issue)) 222 219 } 220 + 221 + // GetPullRequestByIssueIDs returns all pull requests by issue ids 222 + func GetPullRequestByIssueIDs(ctx context.Context, issueIDs []int64) (PullRequestList, error) { 223 + prs := make([]*PullRequest, 0, len(issueIDs)) 224 + return prs, db.GetEngine(ctx). 225 + Where("issue_id > 0"). 226 + In("issue_id", issueIDs). 227 + Find(&prs) 228 + }
-2
models/issues/pull_test.go
··· 67 67 }, 68 68 State: "open", 69 69 SortType: "newest", 70 - Labels: []string{}, 71 70 }) 72 71 assert.NoError(t, err) 73 72 assert.EqualValues(t, 3, count) ··· 114 113 }, 115 114 State: "open", 116 115 SortType: "oldest", 117 - Labels: []string{}, 118 116 }) 119 117 assert.NoError(t, err) 120 118 assert.EqualValues(t, 3, count)
+4 -5
models/issues/review.go
··· 239 239 240 240 // IsOfficialReviewer check if at least one of the provided reviewers can make official reviews in issue (counts towards required approvals) 241 241 func IsOfficialReviewer(ctx context.Context, issue *Issue, reviewer *user_model.User) (bool, error) { 242 - pr, err := GetPullRequestByIssueID(ctx, issue.ID) 243 - if err != nil { 242 + if err := issue.LoadPullRequest(ctx); err != nil { 244 243 return false, err 245 244 } 246 245 246 + pr := issue.PullRequest 247 247 rule, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch) 248 248 if err != nil { 249 249 return false, err ··· 271 271 272 272 // IsOfficialReviewerTeam check if reviewer in this team can make official reviews in issue (counts towards required approvals) 273 273 func IsOfficialReviewerTeam(ctx context.Context, issue *Issue, team *organization.Team) (bool, error) { 274 - pr, err := GetPullRequestByIssueID(ctx, issue.ID) 275 - if err != nil { 274 + if err := issue.LoadPullRequest(ctx); err != nil { 276 275 return false, err 277 276 } 278 - pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch) 277 + pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, issue.PullRequest.BaseRepoID, issue.PullRequest.BaseBranch) 279 278 if err != nil { 280 279 return false, err 281 280 }
+3 -2
models/organization/org.go
··· 319 319 320 320 // Add initial creator to organization and owner team. 321 321 if err = db.Insert(ctx, &OrgUser{ 322 - UID: owner.ID, 323 - OrgID: org.ID, 322 + UID: owner.ID, 323 + OrgID: org.ID, 324 + IsPublic: setting.Service.DefaultOrgMemberVisible, 324 325 }); err != nil { 325 326 return fmt.Errorf("insert org-user relation: %w", err) 326 327 }
+2 -2
models/user/email_address.go
··· 443 443 cond = cond.And(builder.Eq{"email_address.is_activated": opts.IsActivated.Value()}) 444 444 } 445 445 446 - count, err := db.GetEngine(ctx).Join("INNER", "`user`", "`user`.ID = email_address.uid"). 446 + count, err := db.GetEngine(ctx).Join("INNER", "`user`", "`user`.id = email_address.uid"). 447 447 Where(cond).Count(new(EmailAddress)) 448 448 if err != nil { 449 449 return nil, 0, fmt.Errorf("Count: %w", err) ··· 459 459 emails := make([]*SearchEmailResult, 0, opts.PageSize) 460 460 err = db.GetEngine(ctx).Table("email_address"). 461 461 Select("email_address.*, `user`.name, `user`.full_name"). 462 - Join("INNER", "`user`", "`user`.ID = email_address.uid"). 462 + Join("INNER", "`user`", "`user`.id = email_address.uid"). 463 463 Where(cond). 464 464 OrderBy(orderby). 465 465 Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).
+1 -1
modules/actions/log.go
··· 100 100 } 101 101 102 102 if err := scanner.Err(); err != nil { 103 - return nil, fmt.Errorf("scan: %w", err) 103 + return nil, fmt.Errorf("ReadLogs scan: %w", err) 104 104 } 105 105 106 106 return rows, nil
+12 -2
modules/actions/task_state.go
··· 41 41 } 42 42 logIndex += preStep.LogLength 43 43 44 + // lastHasRunStep is the last step that has run. 45 + // For example, 46 + // 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): lastHasRunStep is step1. 47 + // 2. preStep(Success) -> step1(Success) -> step2(Success) -> step3(Success) -> postStep(Success): lastHasRunStep is step3. 48 + // 3. preStep(Success) -> step1(Success) -> step2(Failure) -> step3 -> postStep(Waiting): lastHasRunStep is step2. 49 + // So its Stopped is the Started of postStep when there are no more steps to run. 44 50 var lastHasRunStep *actions_model.ActionTaskStep 45 51 for _, step := range task.Steps { 46 52 if step.Status.HasRun() { ··· 56 62 Name: postStepName, 57 63 Status: actions_model.StatusWaiting, 58 64 } 59 - if task.Status.IsDone() { 65 + // If the lastHasRunStep is the last step, or it has failed, postStep has started. 66 + if lastHasRunStep.Status.IsFailure() || lastHasRunStep == task.Steps[len(task.Steps)-1] { 60 67 postStep.LogIndex = logIndex 61 68 postStep.LogLength = task.LogLength - postStep.LogIndex 62 - postStep.Status = task.Status 63 69 postStep.Started = lastHasRunStep.Stopped 70 + postStep.Status = actions_model.StatusRunning 71 + } 72 + if task.Status.IsDone() { 73 + postStep.Status = task.Status 64 74 postStep.Stopped = task.Stopped 65 75 } 66 76 ret := make([]*actions_model.ActionTaskStep, 0, len(task.Steps)+2)
+34
modules/actions/task_state_test.go
··· 103 103 {Name: postStepName, Status: actions_model.StatusSuccess, LogIndex: 100, LogLength: 0, Started: 10100, Stopped: 10100}, 104 104 }, 105 105 }, 106 + { 107 + name: "all steps finished but task is running", 108 + task: &actions_model.ActionTask{ 109 + Steps: []*actions_model.ActionTaskStep{ 110 + {Status: actions_model.StatusSuccess, LogIndex: 10, LogLength: 80, Started: 10010, Stopped: 10090}, 111 + }, 112 + Status: actions_model.StatusRunning, 113 + Started: 10000, 114 + Stopped: 0, 115 + LogLength: 100, 116 + }, 117 + want: []*actions_model.ActionTaskStep{ 118 + {Name: preStepName, Status: actions_model.StatusSuccess, LogIndex: 0, LogLength: 10, Started: 10000, Stopped: 10010}, 119 + {Status: actions_model.StatusSuccess, LogIndex: 10, LogLength: 80, Started: 10010, Stopped: 10090}, 120 + {Name: postStepName, Status: actions_model.StatusRunning, LogIndex: 90, LogLength: 10, Started: 10090, Stopped: 0}, 121 + }, 122 + }, 123 + { 124 + name: "skipped task", 125 + task: &actions_model.ActionTask{ 126 + Steps: []*actions_model.ActionTaskStep{ 127 + {Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0}, 128 + }, 129 + Status: actions_model.StatusSkipped, 130 + Started: 0, 131 + Stopped: 0, 132 + LogLength: 0, 133 + }, 134 + want: []*actions_model.ActionTaskStep{ 135 + {Name: preStepName, Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0}, 136 + {Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0}, 137 + {Name: postStepName, Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0}, 138 + }, 139 + }, 106 140 } 107 141 for _, tt := range tests { 108 142 t.Run(tt.name, func(t *testing.T) {
+8 -5
modules/base/tool.go
··· 150 150 151 151 // StringsToInt64s converts a slice of string to a slice of int64. 152 152 func StringsToInt64s(strs []string) ([]int64, error) { 153 - ints := make([]int64, len(strs)) 154 - for i := range strs { 155 - n, err := strconv.ParseInt(strs[i], 10, 64) 153 + if strs == nil { 154 + return nil, nil 155 + } 156 + ints := make([]int64, 0, len(strs)) 157 + for _, s := range strs { 158 + n, err := strconv.ParseInt(s, 10, 64) 156 159 if err != nil { 157 - return ints, err 160 + return nil, err 158 161 } 159 - ints[i] = n 162 + ints = append(ints, n) 160 163 } 161 164 return ints, nil 162 165 }
+4 -3
modules/base/tool_test.go
··· 138 138 assert.NoError(t, err) 139 139 assert.Equal(t, expected, result) 140 140 } 141 + testSuccess(nil, nil) 141 142 testSuccess([]string{}, []int64{}) 142 143 testSuccess([]string{"-1234"}, []int64{-1234}) 143 - testSuccess([]string{"1", "4", "16", "64", "256"}, 144 - []int64{1, 4, 16, 64, 256}) 144 + testSuccess([]string{"1", "4", "16", "64", "256"}, []int64{1, 4, 16, 64, 256}) 145 145 146 - _, err := StringsToInt64s([]string{"-1", "a", "$"}) 146 + ints, err := StringsToInt64s([]string{"-1", "a"}) 147 + assert.Len(t, ints, 0) 147 148 assert.Error(t, err) 148 149 } 149 150
+4
modules/git/commit.go
··· 9 9 "bytes" 10 10 "context" 11 11 "errors" 12 + "fmt" 12 13 "io" 13 14 "os/exec" 14 15 "strconv" ··· 389 390 ismodule = false 390 391 } 391 392 } 393 + } 394 + if err = scanner.Err(); err != nil { 395 + return nil, fmt.Errorf("GetSubModules scan: %w", err) 392 396 } 393 397 394 398 return c.submoduleCache, nil
+1 -1
modules/git/repo.go
··· 283 283 // GetDivergingCommits returns the number of commits a targetBranch is ahead or behind a baseBranch 284 284 func GetDivergingCommits(ctx context.Context, repoPath, baseBranch, targetBranch string) (do DivergeObject, err error) { 285 285 cmd := NewCommand(ctx, "rev-list", "--count", "--left-right"). 286 - AddDynamicArguments(baseBranch + "..." + targetBranch) 286 + AddDynamicArguments(baseBranch + "..." + targetBranch).AddArguments("--") 287 287 stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) 288 288 if err != nil { 289 289 return do, err
+4
modules/git/repo_stats.go
··· 124 124 } 125 125 } 126 126 } 127 + if err = scanner.Err(); err != nil { 128 + _ = stdoutReader.Close() 129 + return fmt.Errorf("GetCodeActivityStats scan: %w", err) 130 + } 127 131 a := make([]*CodeActivityAuthor, 0, len(authors)) 128 132 for _, v := range authors { 129 133 a = append(a, v)
+2 -2
modules/graceful/manager_unix.go
··· 59 59 go func() { 60 60 defer func() { 61 61 close(startupDone) 62 - // Close the unused listeners and ignore the error here there's not much we can do with it, they're logged in the CloseProvidedListeners function 63 - _ = CloseProvidedListeners() 62 + // Close the unused listeners 63 + closeProvidedListeners() 64 64 }() 65 65 // Wait for all servers to be created 66 66 g.createServerCond.L.Lock()
+2 -10
modules/graceful/net_unix.go
··· 129 129 return savedErr 130 130 } 131 131 132 - // CloseProvidedListeners closes all unused provided listeners. 133 - func CloseProvidedListeners() error { 132 + // closeProvidedListeners closes all unused provided listeners. 133 + func closeProvidedListeners() { 134 134 mutex.Lock() 135 135 defer mutex.Unlock() 136 - var returnableError error 137 136 for _, l := range providedListeners { 138 137 err := l.Close() 139 138 if err != nil { 140 139 log.Error("Error in closing unused provided listener: %v", err) 141 - if returnableError != nil { 142 - returnableError = fmt.Errorf("%v & %w", returnableError, err) 143 - } else { 144 - returnableError = err 145 - } 146 140 } 147 141 } 148 142 providedListeners = []net.Listener{} 149 - 150 - return returnableError 151 143 } 152 144 153 145 // DefaultGetListener obtains a listener for the stream-oriented local network address:
+7 -8
modules/indexer/code/bleve/bleve.go
··· 39 39 const ( 40 40 unicodeNormalizeName = "unicodeNormalize" 41 41 maxBatchSize = 16 42 + // fuzzyDenominator determines the levenshtein distance per each character of a keyword 43 + fuzzyDenominator = 4 42 44 ) 43 45 44 46 func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error { ··· 239 241 keywordQuery query.Query 240 242 ) 241 243 244 + phraseQuery := bleve.NewMatchPhraseQuery(opts.Keyword) 245 + phraseQuery.FieldVal = "Content" 246 + phraseQuery.Analyzer = repoIndexerAnalyzer 247 + keywordQuery = phraseQuery 242 248 if opts.IsKeywordFuzzy { 243 - phraseQuery := bleve.NewMatchPhraseQuery(opts.Keyword) 244 - phraseQuery.FieldVal = "Content" 245 - phraseQuery.Analyzer = repoIndexerAnalyzer 246 - keywordQuery = phraseQuery 247 - } else { 248 - prefixQuery := bleve.NewPrefixQuery(opts.Keyword) 249 - prefixQuery.FieldVal = "Content" 250 - keywordQuery = prefixQuery 249 + phraseQuery.Fuzziness = len(opts.Keyword) / fuzzyDenominator 251 250 } 252 251 253 252 if len(opts.RepoIDs) > 0 {
+2 -8
modules/indexer/internal/bleve/query.go
··· 20 20 } 21 21 22 22 // MatchPhraseQuery generates a match phrase query for the given phrase, field and analyzer 23 - func MatchPhraseQuery(matchPhrase, field, analyzer string) *query.MatchPhraseQuery { 23 + func MatchPhraseQuery(matchPhrase, field, analyzer string, fuzziness int) *query.MatchPhraseQuery { 24 24 q := bleve.NewMatchPhraseQuery(matchPhrase) 25 25 q.FieldVal = field 26 26 q.Analyzer = analyzer 27 - return q 28 - } 29 - 30 - // PrefixQuery generates a match prefix query for the given prefix and field 31 - func PrefixQuery(matchPrefix, field string) *query.PrefixQuery { 32 - q := bleve.NewPrefixQuery(matchPrefix) 33 - q.FieldVal = field 27 + q.Fuzziness = fuzziness 34 28 return q 35 29 } 36 30
+13 -12
modules/indexer/issues/bleve/bleve.go
··· 35 35 }) 36 36 } 37 37 38 - const maxBatchSize = 16 38 + const ( 39 + maxBatchSize = 16 40 + // fuzzyDenominator determines the levenshtein distance per each character of a keyword 41 + fuzzyDenominator = 4 42 + ) 39 43 40 44 // IndexerData an update to the issue indexer 41 45 type IndexerData internal.IndexerData ··· 156 160 var queries []query.Query 157 161 158 162 if options.Keyword != "" { 163 + fuzziness := 0 159 164 if options.IsFuzzyKeyword { 160 - queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{ 161 - inner_bleve.MatchPhraseQuery(options.Keyword, "title", issueIndexerAnalyzer), 162 - inner_bleve.MatchPhraseQuery(options.Keyword, "content", issueIndexerAnalyzer), 163 - inner_bleve.MatchPhraseQuery(options.Keyword, "comments", issueIndexerAnalyzer), 164 - }...)) 165 - } else { 166 - queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{ 167 - inner_bleve.PrefixQuery(options.Keyword, "title"), 168 - inner_bleve.PrefixQuery(options.Keyword, "content"), 169 - inner_bleve.PrefixQuery(options.Keyword, "comments"), 170 - }...)) 165 + fuzziness = len(options.Keyword) / fuzzyDenominator 171 166 } 167 + 168 + queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{ 169 + inner_bleve.MatchPhraseQuery(options.Keyword, "title", issueIndexerAnalyzer, fuzziness), 170 + inner_bleve.MatchPhraseQuery(options.Keyword, "content", issueIndexerAnalyzer, fuzziness), 171 + inner_bleve.MatchPhraseQuery(options.Keyword, "comments", issueIndexerAnalyzer, fuzziness), 172 + }...)) 172 173 } 173 174 174 175 if len(options.RepoIDs) > 0 || options.AllPublic {
+16 -32
modules/indexer/issues/internal/tests/tests.go
··· 515 515 { 516 516 Name: "SortByCreatedDesc", 517 517 SearchOptions: &internal.SearchOptions{ 518 - Paginator: &db.ListOptions{ 519 - ListAll: true, 520 - }, 521 - SortBy: internal.SortByCreatedDesc, 518 + Paginator: &db.ListOptionsAll, 519 + SortBy: internal.SortByCreatedDesc, 522 520 }, 523 521 Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { 524 522 assert.Equal(t, len(data), len(result.Hits)) ··· 533 531 { 534 532 Name: "SortByUpdatedDesc", 535 533 SearchOptions: &internal.SearchOptions{ 536 - Paginator: &db.ListOptions{ 537 - ListAll: true, 538 - }, 539 - SortBy: internal.SortByUpdatedDesc, 534 + Paginator: &db.ListOptionsAll, 535 + SortBy: internal.SortByUpdatedDesc, 540 536 }, 541 537 Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { 542 538 assert.Equal(t, len(data), len(result.Hits)) ··· 551 547 { 552 548 Name: "SortByCommentsDesc", 553 549 SearchOptions: &internal.SearchOptions{ 554 - Paginator: &db.ListOptions{ 555 - ListAll: true, 556 - }, 557 - SortBy: internal.SortByCommentsDesc, 550 + Paginator: &db.ListOptionsAll, 551 + SortBy: internal.SortByCommentsDesc, 558 552 }, 559 553 Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { 560 554 assert.Equal(t, len(data), len(result.Hits)) ··· 569 563 { 570 564 Name: "SortByDeadlineDesc", 571 565 SearchOptions: &internal.SearchOptions{ 572 - Paginator: &db.ListOptions{ 573 - ListAll: true, 574 - }, 575 - SortBy: internal.SortByDeadlineDesc, 566 + Paginator: &db.ListOptionsAll, 567 + SortBy: internal.SortByDeadlineDesc, 576 568 }, 577 569 Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { 578 570 assert.Equal(t, len(data), len(result.Hits)) ··· 587 579 { 588 580 Name: "SortByCreatedAsc", 589 581 SearchOptions: &internal.SearchOptions{ 590 - Paginator: &db.ListOptions{ 591 - ListAll: true, 592 - }, 593 - SortBy: internal.SortByCreatedAsc, 582 + Paginator: &db.ListOptionsAll, 583 + SortBy: internal.SortByCreatedAsc, 594 584 }, 595 585 Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { 596 586 assert.Equal(t, len(data), len(result.Hits)) ··· 605 595 { 606 596 Name: "SortByUpdatedAsc", 607 597 SearchOptions: &internal.SearchOptions{ 608 - Paginator: &db.ListOptions{ 609 - ListAll: true, 610 - }, 611 - SortBy: internal.SortByUpdatedAsc, 598 + Paginator: &db.ListOptionsAll, 599 + SortBy: internal.SortByUpdatedAsc, 612 600 }, 613 601 Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { 614 602 assert.Equal(t, len(data), len(result.Hits)) ··· 623 611 { 624 612 Name: "SortByCommentsAsc", 625 613 SearchOptions: &internal.SearchOptions{ 626 - Paginator: &db.ListOptions{ 627 - ListAll: true, 628 - }, 629 - SortBy: internal.SortByCommentsAsc, 614 + Paginator: &db.ListOptionsAll, 615 + SortBy: internal.SortByCommentsAsc, 630 616 }, 631 617 Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { 632 618 assert.Equal(t, len(data), len(result.Hits)) ··· 641 627 { 642 628 Name: "SortByDeadlineAsc", 643 629 SearchOptions: &internal.SearchOptions{ 644 - Paginator: &db.ListOptions{ 645 - ListAll: true, 646 - }, 647 - SortBy: internal.SortByDeadlineAsc, 630 + Paginator: &db.ListOptionsAll, 631 + SortBy: internal.SortByDeadlineAsc, 648 632 }, 649 633 Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { 650 634 assert.Equal(t, len(data), len(result.Hits))
+1 -3
modules/indexer/issues/util.go
··· 61 61 ) 62 62 { 63 63 reviews, err := issue_model.FindReviews(ctx, issue_model.FindReviewOptions{ 64 - ListOptions: db.ListOptions{ 65 - ListAll: true, 66 - }, 64 + ListOptions: db.ListOptionsAll, 67 65 IssueID: issueID, 68 66 OfficialOnly: false, 69 67 })
+4
modules/markup/csv/csv.go
··· 6 6 import ( 7 7 "bufio" 8 8 "bytes" 9 + "fmt" 9 10 "html" 10 11 "io" 11 12 "regexp" ··· 122 123 if err != nil { 123 124 return err 124 125 } 126 + } 127 + if err = scan.Err(); err != nil { 128 + return fmt.Errorf("fallbackRender scan: %w", err) 125 129 } 126 130 127 131 _, err = tmpBlock.WriteString("</pre>")
+10 -1
modules/util/slice.go
··· 54 54 return values 55 55 } 56 56 57 - // TODO: Replace with "maps.Values" once available 57 + // TODO: Replace with "maps.Values" once available, current it only in golang.org/x/exp/maps but not in standard library 58 58 func ValuesOfMap[K comparable, V any](m map[K]V) []V { 59 59 values := make([]V, 0, len(m)) 60 60 for _, v := range m { ··· 62 62 } 63 63 return values 64 64 } 65 + 66 + // TODO: Replace with "maps.Keys" once available, current it only in golang.org/x/exp/maps but not in standard library 67 + func KeysOfMap[K comparable, V any](m map[K]V) []K { 68 + keys := make([]K, 0, len(m)) 69 + for k := range m { 70 + keys = append(keys, k) 71 + } 72 + return keys 73 + }
+3
options/license/threeparttable
··· 1 + This file may be distributed, modified, and used in other works with just 2 + one restriction: modified versions must clearly indicate the modification 3 + (a name change, or a displayed message, or ?).
+5 -1
options/locale/locale_en-US.ini
··· 115 115 error = Error 116 116 error404 = The page you are trying to reach either <strong>does not exist</strong> or <strong>you are not authorized</strong> to view it. 117 117 go_back = Go Back 118 + invalid_data = Invalid data: %v 118 119 119 120 never = Never 120 121 unknown = Unknown ··· 1333 1334 editor.file_deleting_no_longer_exists = The file being deleted, "%s", no longer exists in this repository. 1334 1335 editor.file_changed_while_editing = The file contents have changed since you started editing. <a target="_blank" rel="noopener noreferrer" href="%s">Click here</a> to see them or <strong>Commit Changes again</strong> to overwrite them. 1335 1336 editor.file_already_exists = A file named "%s" already exists in this repository. 1337 + editor.commit_id_not_matching = The Commit ID does not match the ID when you began editing. Commit into a patch branch and then merge. 1338 + editor.push_out_of_date = The push appears to be out of date. 1336 1339 editor.commit_empty_file_header = Commit an empty file 1337 1340 editor.commit_empty_file_text = The file you're about to commit is empty. Proceed? 1338 1341 editor.no_changes_to_show = There are no changes to show. ··· 3133 3136 auths.tip.dropbox = Create a new application at https://www.dropbox.com/developers/apps 3134 3137 auths.tip.facebook = Register a new application at https://developers.facebook.com/apps and add the product "Facebook Login" 3135 3138 auths.tip.github = Register a new OAuth application on https://github.com/settings/applications/new 3136 - auths.tip.gitlab = Register a new application on https://gitlab.com/profile/applications 3139 + auths.tip.gitlab_new = Register a new application on https://gitlab.com/-/profile/applications 3137 3140 auths.tip.google_plus = Obtain OAuth2 client credentials from the Google API console at https://console.developers.google.com/ 3138 3141 auths.tip.openid_connect = Use the OpenID Connect Discovery URL (<server>/.well-known/openid-configuration) to specify the endpoints 3139 3142 auths.tip.twitter = Go to https://dev.twitter.com/apps, create an application and ensure that the “Allow this application to be used to Sign in with Twitter” option is enabled ··· 3671 3674 runs.workflow = Workflow 3672 3675 runs.invalid_workflow_helper = Workflow config file is invalid. Please check your config file: %s 3673 3676 runs.no_matching_online_runner_helper = No matching online runner with label: %s 3677 + runs.no_job_without_needs = The workflow must contain at least one job without dependencies. 3674 3678 runs.actor = Actor 3675 3679 runs.status = Status 3676 3680 runs.actors_no_select = All actors
+320 -1063
package-lock.json
··· 85 85 "eslint-plugin-vue": "9.23.0", 86 86 "eslint-plugin-vue-scoped-css": "2.7.2", 87 87 "eslint-plugin-wc": "2.0.4", 88 - "jsdom": "24.0.0", 88 + "happy-dom": "14.2.0", 89 89 "markdownlint-cli": "0.39.0", 90 90 "postcss-html": "1.6.0", 91 91 "stylelint": "16.2.1", ··· 130 130 } 131 131 }, 132 132 "node_modules/@babel/code-frame": { 133 - "version": "7.23.5", 134 - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", 135 - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", 133 + "version": "7.24.2", 134 + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", 135 + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", 136 136 "dependencies": { 137 - "@babel/highlight": "^7.23.4", 138 - "chalk": "^2.4.2" 137 + "@babel/highlight": "^7.24.2", 138 + "picocolors": "^1.0.0" 139 139 }, 140 140 "engines": { 141 141 "node": ">=6.9.0" 142 142 } 143 143 }, 144 - "node_modules/@babel/code-frame/node_modules/ansi-styles": { 145 - "version": "3.2.1", 146 - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 147 - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 148 - "dependencies": { 149 - "color-convert": "^1.9.0" 150 - }, 151 - "engines": { 152 - "node": ">=4" 153 - } 154 - }, 155 - "node_modules/@babel/code-frame/node_modules/chalk": { 156 - "version": "2.4.2", 157 - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 158 - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 159 - "dependencies": { 160 - "ansi-styles": "^3.2.1", 161 - "escape-string-regexp": "^1.0.5", 162 - "supports-color": "^5.3.0" 163 - }, 164 - "engines": { 165 - "node": ">=4" 166 - } 167 - }, 168 - "node_modules/@babel/code-frame/node_modules/color-convert": { 169 - "version": "1.9.3", 170 - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 171 - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 172 - "dependencies": { 173 - "color-name": "1.1.3" 174 - } 175 - }, 176 - "node_modules/@babel/code-frame/node_modules/color-name": { 177 - "version": "1.1.3", 178 - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 179 - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" 180 - }, 181 - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { 182 - "version": "1.0.5", 183 - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 184 - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", 185 - "engines": { 186 - "node": ">=0.8.0" 187 - } 188 - }, 189 - "node_modules/@babel/code-frame/node_modules/has-flag": { 190 - "version": "3.0.0", 191 - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 192 - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", 193 - "engines": { 194 - "node": ">=4" 195 - } 196 - }, 197 - "node_modules/@babel/code-frame/node_modules/supports-color": { 198 - "version": "5.5.0", 199 - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 200 - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 201 - "dependencies": { 202 - "has-flag": "^3.0.0" 203 - }, 204 - "engines": { 205 - "node": ">=4" 206 - } 207 - }, 208 144 "node_modules/@babel/helper-validator-identifier": { 209 145 "version": "7.22.20", 210 146 "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", ··· 214 150 } 215 151 }, 216 152 "node_modules/@babel/highlight": { 217 - "version": "7.23.4", 218 - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", 219 - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", 153 + "version": "7.24.2", 154 + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", 155 + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", 220 156 "dependencies": { 221 157 "@babel/helper-validator-identifier": "^7.22.20", 222 158 "chalk": "^2.4.2", 223 - "js-tokens": "^4.0.0" 159 + "js-tokens": "^4.0.0", 160 + "picocolors": "^1.0.0" 224 161 }, 225 162 "engines": { 226 163 "node": ">=6.9.0" ··· 296 233 } 297 234 }, 298 235 "node_modules/@babel/parser": { 299 - "version": "7.24.0", 300 - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", 301 - "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", 236 + "version": "7.24.1", 237 + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", 238 + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", 302 239 "bin": { 303 240 "parser": "bin/babel-parser.js" 304 241 }, ··· 307 244 } 308 245 }, 309 246 "node_modules/@babel/runtime": { 310 - "version": "7.24.0", 311 - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", 312 - "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", 247 + "version": "7.24.1", 248 + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", 249 + "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", 313 250 "dependencies": { 314 251 "regenerator-runtime": "^0.14.0" 315 252 }, ··· 2204 2141 } 2205 2142 }, 2206 2143 "node_modules/@types/eslint": { 2207 - "version": "8.56.5", 2208 - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz", 2209 - "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==", 2144 + "version": "8.56.6", 2145 + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", 2146 + "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", 2210 2147 "dependencies": { 2211 2148 "@types/estree": "*", 2212 2149 "@types/json-schema": "*" ··· 2256 2193 "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" 2257 2194 }, 2258 2195 "node_modules/@types/node": { 2259 - "version": "20.11.27", 2260 - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.27.tgz", 2261 - "integrity": "sha512-qyUZfMnCg1KEz57r7pzFtSGt49f6RPkPBis3Vo4PbS7roQEDn22hiHzl/Lo1q4i4hDEgBJmBF/NTNg2XR0HbFg==", 2196 + "version": "20.11.30", 2197 + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", 2198 + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", 2262 2199 "dependencies": { 2263 2200 "undici-types": "~5.26.4" 2264 2201 } ··· 2301 2238 "dev": true 2302 2239 }, 2303 2240 "node_modules/@typescript-eslint/eslint-plugin": { 2304 - "version": "7.2.0", 2305 - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz", 2306 - "integrity": "sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==", 2241 + "version": "7.3.1", 2242 + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.3.1.tgz", 2243 + "integrity": "sha512-STEDMVQGww5lhCuNXVSQfbfuNII5E08QWkvAw5Qwf+bj2WT+JkG1uc+5/vXA3AOYMDHVOSpL+9rcbEUiHIm2dw==", 2307 2244 "dev": true, 2308 2245 "dependencies": { 2309 2246 "@eslint-community/regexpp": "^4.5.1", 2310 - "@typescript-eslint/scope-manager": "7.2.0", 2311 - "@typescript-eslint/type-utils": "7.2.0", 2312 - "@typescript-eslint/utils": "7.2.0", 2313 - "@typescript-eslint/visitor-keys": "7.2.0", 2247 + "@typescript-eslint/scope-manager": "7.3.1", 2248 + "@typescript-eslint/type-utils": "7.3.1", 2249 + "@typescript-eslint/utils": "7.3.1", 2250 + "@typescript-eslint/visitor-keys": "7.3.1", 2314 2251 "debug": "^4.3.4", 2315 2252 "graphemer": "^1.4.0", 2316 2253 "ignore": "^5.2.4", ··· 2319 2256 "ts-api-utils": "^1.0.1" 2320 2257 }, 2321 2258 "engines": { 2322 - "node": "^16.0.0 || >=18.0.0" 2259 + "node": "^18.18.0 || >=20.0.0" 2323 2260 }, 2324 2261 "funding": { 2325 2262 "type": "opencollective", ··· 2336 2273 } 2337 2274 }, 2338 2275 "node_modules/@typescript-eslint/parser": { 2339 - "version": "7.2.0", 2340 - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", 2341 - "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==", 2276 + "version": "7.3.1", 2277 + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.3.1.tgz", 2278 + "integrity": "sha512-Rq49+pq7viTRCH48XAbTA+wdLRrB/3sRq4Lpk0oGDm0VmnjBrAOVXH/Laalmwsv2VpekiEfVFwJYVk6/e8uvQw==", 2342 2279 "dev": true, 2343 2280 "dependencies": { 2344 - "@typescript-eslint/scope-manager": "7.2.0", 2345 - "@typescript-eslint/types": "7.2.0", 2346 - "@typescript-eslint/typescript-estree": "7.2.0", 2347 - "@typescript-eslint/visitor-keys": "7.2.0", 2281 + "@typescript-eslint/scope-manager": "7.3.1", 2282 + "@typescript-eslint/types": "7.3.1", 2283 + "@typescript-eslint/typescript-estree": "7.3.1", 2284 + "@typescript-eslint/visitor-keys": "7.3.1", 2348 2285 "debug": "^4.3.4" 2349 2286 }, 2350 2287 "engines": { 2351 - "node": "^16.0.0 || >=18.0.0" 2288 + "node": "^18.18.0 || >=20.0.0" 2352 2289 }, 2353 2290 "funding": { 2354 2291 "type": "opencollective", ··· 2364 2301 } 2365 2302 }, 2366 2303 "node_modules/@typescript-eslint/scope-manager": { 2367 - "version": "7.2.0", 2368 - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", 2369 - "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", 2304 + "version": "7.3.1", 2305 + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.3.1.tgz", 2306 + "integrity": "sha512-fVS6fPxldsKY2nFvyT7IP78UO1/I2huG+AYu5AMjCT9wtl6JFiDnsv4uad4jQ0GTFzcUV5HShVeN96/17bTBag==", 2370 2307 "dev": true, 2371 2308 "dependencies": { 2372 - "@typescript-eslint/types": "7.2.0", 2373 - "@typescript-eslint/visitor-keys": "7.2.0" 2309 + "@typescript-eslint/types": "7.3.1", 2310 + "@typescript-eslint/visitor-keys": "7.3.1" 2374 2311 }, 2375 2312 "engines": { 2376 - "node": "^16.0.0 || >=18.0.0" 2313 + "node": "^18.18.0 || >=20.0.0" 2377 2314 }, 2378 2315 "funding": { 2379 2316 "type": "opencollective", ··· 2381 2318 } 2382 2319 }, 2383 2320 "node_modules/@typescript-eslint/type-utils": { 2384 - "version": "7.2.0", 2385 - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz", 2386 - "integrity": "sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==", 2321 + "version": "7.3.1", 2322 + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.3.1.tgz", 2323 + "integrity": "sha512-iFhaysxFsMDQlzJn+vr3OrxN8NmdQkHks4WaqD4QBnt5hsq234wcYdyQ9uquzJJIDAj5W4wQne3yEsYA6OmXGw==", 2387 2324 "dev": true, 2388 2325 "dependencies": { 2389 - "@typescript-eslint/typescript-estree": "7.2.0", 2390 - "@typescript-eslint/utils": "7.2.0", 2326 + "@typescript-eslint/typescript-estree": "7.3.1", 2327 + "@typescript-eslint/utils": "7.3.1", 2391 2328 "debug": "^4.3.4", 2392 2329 "ts-api-utils": "^1.0.1" 2393 2330 }, 2394 2331 "engines": { 2395 - "node": "^16.0.0 || >=18.0.0" 2332 + "node": "^18.18.0 || >=20.0.0" 2396 2333 }, 2397 2334 "funding": { 2398 2335 "type": "opencollective", ··· 2408 2345 } 2409 2346 }, 2410 2347 "node_modules/@typescript-eslint/types": { 2411 - "version": "7.2.0", 2412 - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", 2413 - "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", 2348 + "version": "7.3.1", 2349 + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.3.1.tgz", 2350 + "integrity": "sha512-2tUf3uWggBDl4S4183nivWQ2HqceOZh1U4hhu4p1tPiIJoRRXrab7Y+Y0p+dozYwZVvLPRI6r5wKe9kToF9FIw==", 2414 2351 "dev": true, 2415 2352 "engines": { 2416 - "node": "^16.0.0 || >=18.0.0" 2353 + "node": "^18.18.0 || >=20.0.0" 2417 2354 }, 2418 2355 "funding": { 2419 2356 "type": "opencollective", ··· 2421 2358 } 2422 2359 }, 2423 2360 "node_modules/@typescript-eslint/typescript-estree": { 2424 - "version": "7.2.0", 2425 - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", 2426 - "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", 2361 + "version": "7.3.1", 2362 + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.3.1.tgz", 2363 + "integrity": "sha512-tLpuqM46LVkduWP7JO7yVoWshpJuJzxDOPYIVWUUZbW+4dBpgGeUdl/fQkhuV0A8eGnphYw3pp8d2EnvPOfxmQ==", 2427 2364 "dev": true, 2428 2365 "dependencies": { 2429 - "@typescript-eslint/types": "7.2.0", 2430 - "@typescript-eslint/visitor-keys": "7.2.0", 2366 + "@typescript-eslint/types": "7.3.1", 2367 + "@typescript-eslint/visitor-keys": "7.3.1", 2431 2368 "debug": "^4.3.4", 2432 2369 "globby": "^11.1.0", 2433 2370 "is-glob": "^4.0.3", ··· 2436 2373 "ts-api-utils": "^1.0.1" 2437 2374 }, 2438 2375 "engines": { 2439 - "node": "^16.0.0 || >=18.0.0" 2376 + "node": "^18.18.0 || >=20.0.0" 2440 2377 }, 2441 2378 "funding": { 2442 2379 "type": "opencollective", ··· 2449 2386 } 2450 2387 }, 2451 2388 "node_modules/@typescript-eslint/utils": { 2452 - "version": "7.2.0", 2453 - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", 2454 - "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", 2389 + "version": "7.3.1", 2390 + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.3.1.tgz", 2391 + "integrity": "sha512-jIERm/6bYQ9HkynYlNZvXpzmXWZGhMbrOvq3jJzOSOlKXsVjrrolzWBjDW6/TvT5Q3WqaN4EkmcfdQwi9tDjBQ==", 2455 2392 "dev": true, 2456 2393 "dependencies": { 2457 2394 "@eslint-community/eslint-utils": "^4.4.0", 2458 2395 "@types/json-schema": "^7.0.12", 2459 2396 "@types/semver": "^7.5.0", 2460 - "@typescript-eslint/scope-manager": "7.2.0", 2461 - "@typescript-eslint/types": "7.2.0", 2462 - "@typescript-eslint/typescript-estree": "7.2.0", 2397 + "@typescript-eslint/scope-manager": "7.3.1", 2398 + "@typescript-eslint/types": "7.3.1", 2399 + "@typescript-eslint/typescript-estree": "7.3.1", 2463 2400 "semver": "^7.5.4" 2464 2401 }, 2465 2402 "engines": { 2466 - "node": "^16.0.0 || >=18.0.0" 2403 + "node": "^18.18.0 || >=20.0.0" 2467 2404 }, 2468 2405 "funding": { 2469 2406 "type": "opencollective", ··· 2474 2411 } 2475 2412 }, 2476 2413 "node_modules/@typescript-eslint/visitor-keys": { 2477 - "version": "7.2.0", 2478 - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", 2479 - "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", 2414 + "version": "7.3.1", 2415 + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.3.1.tgz", 2416 + "integrity": "sha512-9RMXwQF8knsZvfv9tdi+4D/j7dMG28X/wMJ8Jj6eOHyHWwDW4ngQJcqEczSsqIKKjFiLFr40Mnr7a5ulDD3vmw==", 2480 2417 "dev": true, 2481 2418 "dependencies": { 2482 - "@typescript-eslint/types": "7.2.0", 2419 + "@typescript-eslint/types": "7.3.1", 2483 2420 "eslint-visitor-keys": "^3.4.1" 2484 2421 }, 2485 2422 "engines": { 2486 - "node": "^16.0.0 || >=18.0.0" 2423 + "node": "^18.18.0 || >=20.0.0" 2487 2424 }, 2488 2425 "funding": { 2489 2426 "type": "opencollective", ··· 2978 2915 "webpack": ">=5" 2979 2916 } 2980 2917 }, 2981 - "node_modules/agent-base": { 2982 - "version": "7.1.0", 2983 - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", 2984 - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", 2985 - "dev": true, 2986 - "dependencies": { 2987 - "debug": "^4.3.4" 2988 - }, 2989 - "engines": { 2990 - "node": ">= 14" 2991 - } 2992 - }, 2993 2918 "node_modules/ajv": { 2994 2919 "version": "8.12.0", 2995 2920 "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", ··· 3146 3071 } 3147 3072 }, 3148 3073 "node_modules/array-includes": { 3149 - "version": "3.1.7", 3150 - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", 3151 - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", 3074 + "version": "3.1.8", 3075 + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", 3076 + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", 3152 3077 "dev": true, 3153 3078 "dependencies": { 3154 - "call-bind": "^1.0.2", 3155 - "define-properties": "^1.2.0", 3156 - "es-abstract": "^1.22.1", 3157 - "get-intrinsic": "^1.2.1", 3079 + "call-bind": "^1.0.7", 3080 + "define-properties": "^1.2.1", 3081 + "es-abstract": "^1.23.2", 3082 + "es-object-atoms": "^1.0.0", 3083 + "get-intrinsic": "^1.2.4", 3158 3084 "is-string": "^1.0.7" 3159 3085 }, 3160 3086 "engines": { ··· 3173 3099 "node": ">=8" 3174 3100 } 3175 3101 }, 3176 - "node_modules/array.prototype.filter": { 3177 - "version": "1.0.3", 3178 - "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", 3179 - "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", 3180 - "dev": true, 3181 - "dependencies": { 3182 - "call-bind": "^1.0.2", 3183 - "define-properties": "^1.2.0", 3184 - "es-abstract": "^1.22.1", 3185 - "es-array-method-boxes-properly": "^1.0.0", 3186 - "is-string": "^1.0.7" 3187 - }, 3188 - "engines": { 3189 - "node": ">= 0.4" 3190 - }, 3191 - "funding": { 3192 - "url": "https://github.com/sponsors/ljharb" 3193 - } 3194 - }, 3195 3102 "node_modules/array.prototype.findlastindex": { 3196 - "version": "1.2.4", 3197 - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", 3198 - "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", 3103 + "version": "1.2.5", 3104 + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", 3105 + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", 3199 3106 "dev": true, 3200 3107 "dependencies": { 3201 - "call-bind": "^1.0.5", 3108 + "call-bind": "^1.0.7", 3202 3109 "define-properties": "^1.2.1", 3203 - "es-abstract": "^1.22.3", 3110 + "es-abstract": "^1.23.2", 3204 3111 "es-errors": "^1.3.0", 3112 + "es-object-atoms": "^1.0.0", 3205 3113 "es-shim-unscopables": "^1.0.2" 3206 3114 }, 3207 3115 "engines": { ··· 3331 3239 "bin": { 3332 3240 "astring": "bin/astring" 3333 3241 } 3334 - }, 3335 - "node_modules/asynciterator.prototype": { 3336 - "version": "1.0.0", 3337 - "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", 3338 - "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", 3339 - "dev": true, 3340 - "dependencies": { 3341 - "has-symbols": "^1.0.3" 3342 - } 3343 - }, 3344 - "node_modules/asynckit": { 3345 - "version": "0.4.0", 3346 - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 3347 - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", 3348 - "dev": true 3349 3242 }, 3350 3243 "node_modules/atob": { 3351 3244 "version": "2.1.2", ··· 3582 3475 } 3583 3476 }, 3584 3477 "node_modules/caniuse-lite": { 3585 - "version": "1.0.30001597", 3586 - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz", 3587 - "integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==", 3478 + "version": "1.0.30001599", 3479 + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz", 3480 + "integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==", 3588 3481 "funding": [ 3589 3482 { 3590 3483 "type": "opencollective", ··· 3868 3761 "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", 3869 3762 "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" 3870 3763 }, 3871 - "node_modules/combined-stream": { 3872 - "version": "1.0.8", 3873 - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 3874 - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 3875 - "dev": true, 3876 - "dependencies": { 3877 - "delayed-stream": "~1.0.0" 3878 - }, 3879 - "engines": { 3880 - "node": ">= 0.8" 3881 - } 3882 - }, 3883 3764 "node_modules/commander": { 3884 3765 "version": "8.3.0", 3885 3766 "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", ··· 3909 3790 "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" 3910 3791 }, 3911 3792 "node_modules/core-js-compat": { 3912 - "version": "3.36.0", 3913 - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", 3914 - "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", 3793 + "version": "3.36.1", 3794 + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", 3795 + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", 3915 3796 "dev": true, 3916 3797 "dependencies": { 3917 - "browserslist": "^4.22.3" 3798 + "browserslist": "^4.23.0" 3918 3799 }, 3919 3800 "funding": { 3920 3801 "type": "opencollective", ··· 4105 3986 "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", 4106 3987 "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", 4107 3988 "dev": true 4108 - }, 4109 - "node_modules/cssstyle": { 4110 - "version": "4.0.1", 4111 - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", 4112 - "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", 4113 - "dev": true, 4114 - "dependencies": { 4115 - "rrweb-cssom": "^0.6.0" 4116 - }, 4117 - "engines": { 4118 - "node": ">=18" 4119 - } 4120 3989 }, 4121 3990 "node_modules/csstype": { 4122 3991 "version": "3.1.3", ··· 4580 4449 "integrity": "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==", 4581 4450 "dev": true 4582 4451 }, 4583 - "node_modules/data-urls": { 4584 - "version": "5.0.0", 4585 - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", 4586 - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", 4452 + "node_modules/data-view-buffer": { 4453 + "version": "1.0.1", 4454 + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", 4455 + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", 4587 4456 "dev": true, 4588 4457 "dependencies": { 4589 - "whatwg-mimetype": "^4.0.0", 4590 - "whatwg-url": "^14.0.0" 4458 + "call-bind": "^1.0.6", 4459 + "es-errors": "^1.3.0", 4460 + "is-data-view": "^1.0.1" 4591 4461 }, 4592 4462 "engines": { 4593 - "node": ">=18" 4463 + "node": ">= 0.4" 4464 + }, 4465 + "funding": { 4466 + "url": "https://github.com/sponsors/ljharb" 4467 + } 4468 + }, 4469 + "node_modules/data-view-byte-length": { 4470 + "version": "1.0.1", 4471 + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", 4472 + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", 4473 + "dev": true, 4474 + "dependencies": { 4475 + "call-bind": "^1.0.7", 4476 + "es-errors": "^1.3.0", 4477 + "is-data-view": "^1.0.1" 4478 + }, 4479 + "engines": { 4480 + "node": ">= 0.4" 4481 + }, 4482 + "funding": { 4483 + "url": "https://github.com/sponsors/ljharb" 4484 + } 4485 + }, 4486 + "node_modules/data-view-byte-offset": { 4487 + "version": "1.0.0", 4488 + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", 4489 + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", 4490 + "dev": true, 4491 + "dependencies": { 4492 + "call-bind": "^1.0.6", 4493 + "es-errors": "^1.3.0", 4494 + "is-data-view": "^1.0.1" 4495 + }, 4496 + "engines": { 4497 + "node": ">= 0.4" 4498 + }, 4499 + "funding": { 4500 + "url": "https://github.com/sponsors/ljharb" 4594 4501 } 4595 4502 }, 4596 4503 "node_modules/dayjs": { ··· 4613 4520 "optional": true 4614 4521 } 4615 4522 } 4616 - }, 4617 - "node_modules/decimal.js": { 4618 - "version": "10.4.3", 4619 - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", 4620 - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", 4621 - "dev": true 4622 4523 }, 4623 4524 "node_modules/decode-named-character-reference": { 4624 4525 "version": "1.0.2", ··· 4710 4611 "robust-predicates": "^3.0.2" 4711 4612 } 4712 4613 }, 4713 - "node_modules/delayed-stream": { 4714 - "version": "1.0.0", 4715 - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 4716 - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 4717 - "dev": true, 4718 - "engines": { 4719 - "node": ">=0.4.0" 4720 - } 4721 - }, 4722 4614 "node_modules/dependency-graph": { 4723 4615 "version": "0.11.0", 4724 4616 "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", ··· 4829 4721 } 4830 4722 }, 4831 4723 "node_modules/dompurify": { 4832 - "version": "3.0.9", 4833 - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.9.tgz", 4834 - "integrity": "sha512-uyb4NDIvQ3hRn6NiC+SIFaP4mJ/MdXlvtunaqK9Bn6dD3RuB/1S/gasEjDHD8eiaqdSael2vBv+hOs7Y+jhYOQ==" 4724 + "version": "3.0.10", 4725 + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.10.tgz", 4726 + "integrity": "sha512-WZDL8ZHTliEVP3Lk4phtvjg8SNQ3YMc5WVstxE8cszKZrFjzI4PF4ZTIk9VGAc9vZADO7uGO2V/ZiStcRSAT4Q==" 4835 4727 }, 4836 4728 "node_modules/domutils": { 4837 4729 "version": "3.1.0", ··· 4874 4766 } 4875 4767 }, 4876 4768 "node_modules/electron-to-chromium": { 4877 - "version": "1.4.706", 4878 - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.706.tgz", 4879 - "integrity": "sha512-fO01fufoGd6jKK3HR8ofBapF3ZPfgxNJ/ua9xQAhFu93TwWIs4d+weDn3kje3GB4S7aGUTfk5nvdU5F7z5mF9Q==" 4769 + "version": "1.4.713", 4770 + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.713.tgz", 4771 + "integrity": "sha512-vDarADhwntXiULEdmWd77g2dV6FrNGa8ecAC29MZ4TwPut2fvosD0/5sJd1qWNNe8HcJFAC+F5Lf9jW1NPtWmw==" 4880 4772 }, 4881 4773 "node_modules/elkjs": { 4882 4774 "version": "0.9.2", ··· 4947 4839 } 4948 4840 }, 4949 4841 "node_modules/es-abstract": { 4950 - "version": "1.22.5", 4951 - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", 4952 - "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", 4842 + "version": "1.23.2", 4843 + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", 4844 + "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", 4953 4845 "dev": true, 4954 4846 "dependencies": { 4955 4847 "array-buffer-byte-length": "^1.0.1", 4956 4848 "arraybuffer.prototype.slice": "^1.0.3", 4957 4849 "available-typed-arrays": "^1.0.7", 4958 4850 "call-bind": "^1.0.7", 4851 + "data-view-buffer": "^1.0.1", 4852 + "data-view-byte-length": "^1.0.1", 4853 + "data-view-byte-offset": "^1.0.0", 4959 4854 "es-define-property": "^1.0.0", 4960 4855 "es-errors": "^1.3.0", 4856 + "es-object-atoms": "^1.0.0", 4961 4857 "es-set-tostringtag": "^2.0.3", 4962 4858 "es-to-primitive": "^1.2.1", 4963 4859 "function.prototype.name": "^1.1.6", ··· 4968 4864 "has-property-descriptors": "^1.0.2", 4969 4865 "has-proto": "^1.0.3", 4970 4866 "has-symbols": "^1.0.3", 4971 - "hasown": "^2.0.1", 4867 + "hasown": "^2.0.2", 4972 4868 "internal-slot": "^1.0.7", 4973 4869 "is-array-buffer": "^3.0.4", 4974 4870 "is-callable": "^1.2.7", 4871 + "is-data-view": "^1.0.1", 4975 4872 "is-negative-zero": "^2.0.3", 4976 4873 "is-regex": "^1.1.4", 4977 4874 "is-shared-array-buffer": "^1.0.3", ··· 4982 4879 "object-keys": "^1.1.1", 4983 4880 "object.assign": "^4.1.5", 4984 4881 "regexp.prototype.flags": "^1.5.2", 4985 - "safe-array-concat": "^1.1.0", 4882 + "safe-array-concat": "^1.1.2", 4986 4883 "safe-regex-test": "^1.0.3", 4987 - "string.prototype.trim": "^1.2.8", 4988 - "string.prototype.trimend": "^1.0.7", 4884 + "string.prototype.trim": "^1.2.9", 4885 + "string.prototype.trimend": "^1.0.8", 4989 4886 "string.prototype.trimstart": "^1.0.7", 4990 4887 "typed-array-buffer": "^1.0.2", 4991 4888 "typed-array-byte-length": "^1.0.1", 4992 4889 "typed-array-byte-offset": "^1.0.2", 4993 4890 "typed-array-length": "^1.0.5", 4994 4891 "unbox-primitive": "^1.0.2", 4995 - "which-typed-array": "^1.1.14" 4892 + "which-typed-array": "^1.1.15" 4996 4893 }, 4997 4894 "engines": { 4998 4895 "node": ">= 0.4" ··· 5023 4920 "url": "https://github.com/sponsors/ljharb" 5024 4921 } 5025 4922 }, 5026 - "node_modules/es-array-method-boxes-properly": { 5027 - "version": "1.0.0", 5028 - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", 5029 - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", 5030 - "dev": true 5031 - }, 5032 4923 "node_modules/es-define-property": { 5033 4924 "version": "1.0.0", 5034 4925 "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", ··· 5051 4942 } 5052 4943 }, 5053 4944 "node_modules/es-iterator-helpers": { 5054 - "version": "1.0.17", 5055 - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz", 5056 - "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==", 4945 + "version": "1.0.18", 4946 + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", 4947 + "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", 5057 4948 "dev": true, 5058 4949 "dependencies": { 5059 - "asynciterator.prototype": "^1.0.0", 5060 4950 "call-bind": "^1.0.7", 5061 4951 "define-properties": "^1.2.1", 5062 - "es-abstract": "^1.22.4", 4952 + "es-abstract": "^1.23.0", 5063 4953 "es-errors": "^1.3.0", 5064 - "es-set-tostringtag": "^2.0.2", 4954 + "es-set-tostringtag": "^2.0.3", 5065 4955 "function-bind": "^1.1.2", 5066 4956 "get-intrinsic": "^1.2.4", 5067 4957 "globalthis": "^1.0.3", 5068 4958 "has-property-descriptors": "^1.0.2", 5069 - "has-proto": "^1.0.1", 4959 + "has-proto": "^1.0.3", 5070 4960 "has-symbols": "^1.0.3", 5071 4961 "internal-slot": "^1.0.7", 5072 4962 "iterator.prototype": "^1.1.2", 5073 - "safe-array-concat": "^1.1.0" 4963 + "safe-array-concat": "^1.1.2" 5074 4964 }, 5075 4965 "engines": { 5076 4966 "node": ">= 0.4" 5077 4967 } 5078 4968 }, 5079 4969 "node_modules/es-module-lexer": { 5080 - "version": "1.4.1", 5081 - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", 5082 - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" 4970 + "version": "1.4.2", 4971 + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.2.tgz", 4972 + "integrity": "sha512-7nOqkomXZEaxUDJw21XZNtRk739QvrPSoZoRtbsEfcii00vdzZUh6zh1CQwHhrib8MdEtJfv5rJiGeb4KuV/vw==" 4973 + }, 4974 + "node_modules/es-object-atoms": { 4975 + "version": "1.0.0", 4976 + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", 4977 + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", 4978 + "dev": true, 4979 + "dependencies": { 4980 + "es-errors": "^1.3.0" 4981 + }, 4982 + "engines": { 4983 + "node": ">= 0.4" 4984 + } 5083 4985 }, 5084 4986 "node_modules/es-set-tostringtag": { 5085 4987 "version": "2.0.3", ··· 6131 6033 } 6132 6034 } 6133 6035 }, 6134 - "node_modules/fetch-ponyfill/node_modules/tr46": { 6135 - "version": "0.0.3", 6136 - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 6137 - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 6138 - }, 6139 - "node_modules/fetch-ponyfill/node_modules/webidl-conversions": { 6140 - "version": "3.0.1", 6141 - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 6142 - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 6143 - }, 6144 - "node_modules/fetch-ponyfill/node_modules/whatwg-url": { 6145 - "version": "5.0.0", 6146 - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 6147 - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 6148 - "dependencies": { 6149 - "tr46": "~0.0.3", 6150 - "webidl-conversions": "^3.0.0" 6151 - } 6152 - }, 6153 6036 "node_modules/file-entry-cache": { 6154 6037 "version": "6.0.1", 6155 6038 "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", ··· 6239 6122 }, 6240 6123 "funding": { 6241 6124 "url": "https://github.com/sponsors/isaacs" 6242 - } 6243 - }, 6244 - "node_modules/form-data": { 6245 - "version": "4.0.0", 6246 - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 6247 - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 6248 - "dev": true, 6249 - "dependencies": { 6250 - "asynckit": "^0.4.0", 6251 - "combined-stream": "^1.0.8", 6252 - "mime-types": "^2.1.12" 6253 - }, 6254 - "engines": { 6255 - "node": ">= 6" 6256 6125 } 6257 6126 }, 6258 6127 "node_modules/fs-extra": { ··· 6632 6501 "node": ">=0.8.0" 6633 6502 } 6634 6503 }, 6504 + "node_modules/happy-dom": { 6505 + "version": "14.2.0", 6506 + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-14.2.0.tgz", 6507 + "integrity": "sha512-vTqF/9MEkRKgYy5eKq9W0uiNmkgnVAmJhRwn8x8fQBR7lc4C84859jLhgZ1lR4Gi/t70oSdgvtLpxlHjgdJrAw==", 6508 + "dev": true, 6509 + "dependencies": { 6510 + "entities": "^4.5.0", 6511 + "webidl-conversions": "^7.0.0", 6512 + "whatwg-mimetype": "^3.0.0" 6513 + }, 6514 + "engines": { 6515 + "node": ">=16.0.0" 6516 + } 6517 + }, 6635 6518 "node_modules/has-bigints": { 6636 6519 "version": "1.0.2", 6637 6520 "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", ··· 6736 6619 "node": ">=14" 6737 6620 } 6738 6621 }, 6739 - "node_modules/html-encoding-sniffer": { 6740 - "version": "4.0.0", 6741 - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", 6742 - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", 6743 - "dev": true, 6744 - "dependencies": { 6745 - "whatwg-encoding": "^3.1.1" 6746 - }, 6747 - "engines": { 6748 - "node": ">=18" 6749 - } 6750 - }, 6751 6622 "node_modules/html-tags": { 6752 6623 "version": "3.3.1", 6753 6624 "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", ··· 6784 6655 "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-1.9.11.tgz", 6785 6656 "integrity": "sha512-WlVuICn8dfNOOgYmdYzYG8zSnP3++AdHkMHooQAzGZObWpVXYathpz/I37ycF4zikR6YduzfCvEcxk20JkIUsw==" 6786 6657 }, 6787 - "node_modules/http-proxy-agent": { 6788 - "version": "7.0.2", 6789 - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", 6790 - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", 6791 - "dev": true, 6792 - "dependencies": { 6793 - "agent-base": "^7.1.0", 6794 - "debug": "^4.3.4" 6795 - }, 6796 - "engines": { 6797 - "node": ">= 14" 6798 - } 6799 - }, 6800 - "node_modules/https-proxy-agent": { 6801 - "version": "7.0.4", 6802 - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", 6803 - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", 6804 - "dev": true, 6805 - "dependencies": { 6806 - "agent-base": "^7.0.2", 6807 - "debug": "4" 6808 - }, 6809 - "engines": { 6810 - "node": ">= 14" 6811 - } 6812 - }, 6813 6658 "node_modules/human-signals": { 6814 6659 "version": "5.0.0", 6815 6660 "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", ··· 7096 6941 "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", 7097 6942 "dependencies": { 7098 6943 "hasown": "^2.0.0" 6944 + }, 6945 + "funding": { 6946 + "url": "https://github.com/sponsors/ljharb" 6947 + } 6948 + }, 6949 + "node_modules/is-data-view": { 6950 + "version": "1.0.1", 6951 + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", 6952 + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", 6953 + "dev": true, 6954 + "dependencies": { 6955 + "is-typed-array": "^1.1.13" 6956 + }, 6957 + "engines": { 6958 + "node": ">= 0.4" 7099 6959 }, 7100 6960 "funding": { 7101 6961 "url": "https://github.com/sponsors/ljharb" ··· 7566 7426 "dev": true, 7567 7427 "engines": { 7568 7428 "node": ">=12.0.0" 7569 - } 7570 - }, 7571 - "node_modules/jsdom": { 7572 - "version": "24.0.0", 7573 - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.0.0.tgz", 7574 - "integrity": "sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==", 7575 - "dev": true, 7576 - "dependencies": { 7577 - "cssstyle": "^4.0.1", 7578 - "data-urls": "^5.0.0", 7579 - "decimal.js": "^10.4.3", 7580 - "form-data": "^4.0.0", 7581 - "html-encoding-sniffer": "^4.0.0", 7582 - "http-proxy-agent": "^7.0.0", 7583 - "https-proxy-agent": "^7.0.2", 7584 - "is-potential-custom-element-name": "^1.0.1", 7585 - "nwsapi": "^2.2.7", 7586 - "parse5": "^7.1.2", 7587 - "rrweb-cssom": "^0.6.0", 7588 - "saxes": "^6.0.0", 7589 - "symbol-tree": "^3.2.4", 7590 - "tough-cookie": "^4.1.3", 7591 - "w3c-xmlserializer": "^5.0.0", 7592 - "webidl-conversions": "^7.0.0", 7593 - "whatwg-encoding": "^3.1.1", 7594 - "whatwg-mimetype": "^4.0.0", 7595 - "whatwg-url": "^14.0.0", 7596 - "ws": "^8.16.0", 7597 - "xml-name-validator": "^5.0.0" 7598 - }, 7599 - "engines": { 7600 - "node": ">=18" 7601 - }, 7602 - "peerDependencies": { 7603 - "canvas": "^2.11.2" 7604 - }, 7605 - "peerDependenciesMeta": { 7606 - "canvas": { 7607 - "optional": true 7608 - } 7609 - } 7610 - }, 7611 - "node_modules/jsdom/node_modules/xml-name-validator": { 7612 - "version": "5.0.0", 7613 - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", 7614 - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", 7615 - "dev": true, 7616 - "engines": { 7617 - "node": ">=18" 7618 7429 } 7619 7430 }, 7620 7431 "node_modules/jsep": { ··· 8956 8767 } 8957 8768 } 8958 8769 }, 8959 - "node_modules/node-fetch/node_modules/tr46": { 8960 - "version": "0.0.3", 8961 - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 8962 - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 8963 - }, 8964 - "node_modules/node-fetch/node_modules/webidl-conversions": { 8965 - "version": "3.0.1", 8966 - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 8967 - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 8968 - }, 8969 - "node_modules/node-fetch/node_modules/whatwg-url": { 8970 - "version": "5.0.0", 8971 - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 8972 - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 8973 - "dependencies": { 8974 - "tr46": "~0.0.3", 8975 - "webidl-conversions": "^3.0.0" 8976 - } 8977 - }, 8978 8770 "node_modules/node-releases": { 8979 8771 "version": "2.0.14", 8980 8772 "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", ··· 9066 8858 "url": "https://github.com/fb55/nth-check?sponsor=1" 9067 8859 } 9068 8860 }, 9069 - "node_modules/nwsapi": { 9070 - "version": "2.2.7", 9071 - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", 9072 - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", 9073 - "dev": true 9074 - }, 9075 8861 "node_modules/obj-props": { 9076 8862 "version": "1.4.0", 9077 8863 "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz", ··· 9134 8920 } 9135 8921 }, 9136 8922 "node_modules/object.entries": { 9137 - "version": "1.1.7", 9138 - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", 9139 - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", 8923 + "version": "1.1.8", 8924 + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", 8925 + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", 9140 8926 "dev": true, 9141 8927 "dependencies": { 9142 - "call-bind": "^1.0.2", 9143 - "define-properties": "^1.2.0", 9144 - "es-abstract": "^1.22.1" 8928 + "call-bind": "^1.0.7", 8929 + "define-properties": "^1.2.1", 8930 + "es-object-atoms": "^1.0.0" 9145 8931 }, 9146 8932 "engines": { 9147 8933 "node": ">= 0.4" 9148 8934 } 9149 8935 }, 9150 8936 "node_modules/object.fromentries": { 9151 - "version": "2.0.7", 9152 - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", 9153 - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", 8937 + "version": "2.0.8", 8938 + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", 8939 + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", 9154 8940 "dev": true, 9155 8941 "dependencies": { 9156 - "call-bind": "^1.0.2", 9157 - "define-properties": "^1.2.0", 9158 - "es-abstract": "^1.22.1" 8942 + "call-bind": "^1.0.7", 8943 + "define-properties": "^1.2.1", 8944 + "es-abstract": "^1.23.2", 8945 + "es-object-atoms": "^1.0.0" 9159 8946 }, 9160 8947 "engines": { 9161 8948 "node": ">= 0.4" ··· 9165 8952 } 9166 8953 }, 9167 8954 "node_modules/object.groupby": { 9168 - "version": "1.0.2", 9169 - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", 9170 - "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", 8955 + "version": "1.0.3", 8956 + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", 8957 + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", 9171 8958 "dev": true, 9172 8959 "dependencies": { 9173 - "array.prototype.filter": "^1.0.3", 9174 - "call-bind": "^1.0.5", 8960 + "call-bind": "^1.0.7", 9175 8961 "define-properties": "^1.2.1", 9176 - "es-abstract": "^1.22.3", 9177 - "es-errors": "^1.0.0" 8962 + "es-abstract": "^1.23.2" 8963 + }, 8964 + "engines": { 8965 + "node": ">= 0.4" 9178 8966 } 9179 8967 }, 9180 8968 "node_modules/object.values": { 9181 - "version": "1.1.7", 9182 - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", 9183 - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", 8969 + "version": "1.2.0", 8970 + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", 8971 + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", 9184 8972 "dev": true, 9185 8973 "dependencies": { 9186 - "call-bind": "^1.0.2", 9187 - "define-properties": "^1.2.0", 9188 - "es-abstract": "^1.22.1" 8974 + "call-bind": "^1.0.7", 8975 + "define-properties": "^1.2.1", 8976 + "es-object-atoms": "^1.0.0" 9189 8977 }, 9190 8978 "engines": { 9191 8979 "node": ">= 0.4" ··· 9311 9099 "url": "https://github.com/sponsors/sindresorhus" 9312 9100 } 9313 9101 }, 9314 - "node_modules/parse5": { 9315 - "version": "7.1.2", 9316 - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", 9317 - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", 9318 - "dev": true, 9319 - "dependencies": { 9320 - "entities": "^4.4.0" 9321 - }, 9322 - "funding": { 9323 - "url": "https://github.com/inikulin/parse5?sponsor=1" 9324 - } 9325 - }, 9326 9102 "node_modules/path-exists": { 9327 9103 "version": "4.0.0", 9328 9104 "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", ··· 9949 9725 "node": ">=4" 9950 9726 } 9951 9727 }, 9952 - "node_modules/psl": { 9953 - "version": "1.9.0", 9954 - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", 9955 - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", 9956 - "dev": true 9957 - }, 9958 9728 "node_modules/punycode": { 9959 9729 "version": "2.3.1", 9960 9730 "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", ··· 9971 9741 "engines": { 9972 9742 "node": ">=6" 9973 9743 } 9974 - }, 9975 - "node_modules/querystringify": { 9976 - "version": "2.2.0", 9977 - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", 9978 - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", 9979 - "dev": true 9980 9744 }, 9981 9745 "node_modules/queue-microtask": { 9982 9746 "version": "1.2.3", ··· 10156 9920 } 10157 9921 }, 10158 9922 "node_modules/reflect.getprototypeof": { 10159 - "version": "1.0.5", 10160 - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", 10161 - "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", 9923 + "version": "1.0.6", 9924 + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", 9925 + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", 10162 9926 "dev": true, 10163 9927 "dependencies": { 10164 - "call-bind": "^1.0.5", 9928 + "call-bind": "^1.0.7", 10165 9929 "define-properties": "^1.2.1", 10166 - "es-abstract": "^1.22.3", 10167 - "es-errors": "^1.0.0", 10168 - "get-intrinsic": "^1.2.3", 9930 + "es-abstract": "^1.23.1", 9931 + "es-errors": "^1.3.0", 9932 + "get-intrinsic": "^1.2.4", 10169 9933 "globalthis": "^1.0.3", 10170 9934 "which-builtin-type": "^1.1.3" 10171 9935 }, ··· 10259 10023 "node": ">=0.10.0" 10260 10024 } 10261 10025 }, 10262 - "node_modules/requires-port": { 10263 - "version": "1.0.0", 10264 - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", 10265 - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", 10266 - "dev": true 10267 - }, 10268 10026 "node_modules/reserved": { 10269 10027 "version": "0.1.2", 10270 10028 "resolved": "https://registry.npmjs.org/reserved/-/reserved-0.1.2.tgz", ··· 10368 10126 "optionalDependencies": { 10369 10127 "fsevents": "~2.3.2" 10370 10128 } 10371 - }, 10372 - "node_modules/rrweb-cssom": { 10373 - "version": "0.6.0", 10374 - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", 10375 - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", 10376 - "dev": true 10377 10129 }, 10378 10130 "node_modules/run-con": { 10379 10131 "version": "1.3.2", ··· 10499 10251 "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", 10500 10252 "dev": true 10501 10253 }, 10502 - "node_modules/saxes": { 10503 - "version": "6.0.0", 10504 - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", 10505 - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", 10506 - "dev": true, 10507 - "dependencies": { 10508 - "xmlchars": "^2.2.0" 10509 - }, 10510 - "engines": { 10511 - "node": ">=v12.22.7" 10512 - } 10513 - }, 10514 10254 "node_modules/schema-utils": { 10515 10255 "version": "4.2.0", 10516 10256 "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", ··· 10720 10460 } 10721 10461 }, 10722 10462 "node_modules/solid-js": { 10723 - "version": "1.8.15", 10724 - "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.15.tgz", 10725 - "integrity": "sha512-d0QP/efr3UVcwGgWVPveQQ0IHOH6iU7yUhc2piy8arNG8wxKmvUy1kFxyF8owpmfCWGB87usDKMaVnsNYZm+Vw==", 10463 + "version": "1.8.16", 10464 + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.16.tgz", 10465 + "integrity": "sha512-rja94MNU9flF3qQRLNsu60QHKBDKBkVE1DldJZPIfn2ypIn3NV2WpSbGTQIvsyGPBo+9E2IMjwqnqpbgfWuzeg==", 10726 10466 "dependencies": { 10727 10467 "csstype": "^3.1.0", 10728 - "seroval": "^1.0.3", 10468 + "seroval": "^1.0.4", 10729 10469 "seroval-plugins": "^1.0.3" 10730 10470 } 10731 10471 }, ··· 10748 10488 } 10749 10489 }, 10750 10490 "node_modules/source-map-js": { 10751 - "version": "1.0.2", 10752 - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 10753 - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 10491 + "version": "1.2.0", 10492 + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", 10493 + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", 10754 10494 "engines": { 10755 10495 "node": ">=0.10.0" 10756 10496 } ··· 10904 10644 "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 10905 10645 }, 10906 10646 "node_modules/string.prototype.trim": { 10907 - "version": "1.2.8", 10908 - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", 10909 - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", 10647 + "version": "1.2.9", 10648 + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", 10649 + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", 10910 10650 "dev": true, 10911 10651 "dependencies": { 10912 - "call-bind": "^1.0.2", 10913 - "define-properties": "^1.2.0", 10914 - "es-abstract": "^1.22.1" 10652 + "call-bind": "^1.0.7", 10653 + "define-properties": "^1.2.1", 10654 + "es-abstract": "^1.23.0", 10655 + "es-object-atoms": "^1.0.0" 10915 10656 }, 10916 10657 "engines": { 10917 10658 "node": ">= 0.4" ··· 10921 10662 } 10922 10663 }, 10923 10664 "node_modules/string.prototype.trimend": { 10924 - "version": "1.0.7", 10925 - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", 10926 - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", 10665 + "version": "1.0.8", 10666 + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", 10667 + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", 10927 10668 "dev": true, 10928 10669 "dependencies": { 10929 - "call-bind": "^1.0.2", 10930 - "define-properties": "^1.2.0", 10931 - "es-abstract": "^1.22.1" 10670 + "call-bind": "^1.0.7", 10671 + "define-properties": "^1.2.1", 10672 + "es-object-atoms": "^1.0.0" 10932 10673 }, 10933 10674 "funding": { 10934 10675 "url": "https://github.com/sponsors/ljharb" ··· 11386 11127 "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.12.0.tgz", 11387 11128 "integrity": "sha512-Rt1xUpbHulJVGbiQjq9yy9/r/0Pg6TmpcG+fXTaMePDc8z5WUw4LfaWts5qcNv/8ewPvBIbY7DKq7qReIKNCCQ==" 11388 11129 }, 11389 - "node_modules/symbol-tree": { 11390 - "version": "3.2.4", 11391 - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", 11392 - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", 11393 - "dev": true 11394 - }, 11395 11130 "node_modules/sync-fetch": { 11396 11131 "version": "0.4.5", 11397 11132 "resolved": "https://registry.npmjs.org/sync-fetch/-/sync-fetch-0.4.5.tgz", ··· 11724 11459 "resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.12.0.tgz", 11725 11460 "integrity": "sha512-HeMHCO9yLPvP9k0apGSdPUWrUbLnxUKNFzgUoZp1PHCLploIX/4DSQ7V8H25ef+h4iO9n0he7ImfcndnN6nDrQ==" 11726 11461 }, 11727 - "node_modules/tough-cookie": { 11728 - "version": "4.1.3", 11729 - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", 11730 - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", 11731 - "dev": true, 11732 - "dependencies": { 11733 - "psl": "^1.1.33", 11734 - "punycode": "^2.1.1", 11735 - "universalify": "^0.2.0", 11736 - "url-parse": "^1.5.3" 11737 - }, 11738 - "engines": { 11739 - "node": ">=6" 11740 - } 11741 - }, 11742 - "node_modules/tough-cookie/node_modules/universalify": { 11743 - "version": "0.2.0", 11744 - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", 11745 - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", 11746 - "dev": true, 11747 - "engines": { 11748 - "node": ">= 4.0.0" 11749 - } 11750 - }, 11751 11462 "node_modules/tr46": { 11752 - "version": "5.0.0", 11753 - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", 11754 - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", 11755 - "dev": true, 11756 - "dependencies": { 11757 - "punycode": "^2.3.1" 11758 - }, 11759 - "engines": { 11760 - "node": ">=18" 11761 - } 11463 + "version": "0.0.3", 11464 + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 11465 + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 11762 11466 }, 11763 11467 "node_modules/tributejs": { 11764 11468 "version": "5.1.3", ··· 11927 11631 } 11928 11632 }, 11929 11633 "node_modules/typescript": { 11930 - "version": "5.4.2", 11931 - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", 11932 - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", 11634 + "version": "5.4.3", 11635 + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", 11636 + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", 11933 11637 "devOptional": true, 11934 11638 "peer": true, 11935 11639 "bin": { ··· 11952 11656 "dev": true 11953 11657 }, 11954 11658 "node_modules/ufo": { 11955 - "version": "1.4.0", 11956 - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.4.0.tgz", 11957 - "integrity": "sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==", 11659 + "version": "1.5.3", 11660 + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", 11661 + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", 11958 11662 "dev": true 11959 11663 }, 11960 11664 "node_modules/uint8-to-base64": { ··· 12058 11762 "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", 12059 11763 "dev": true 12060 11764 }, 12061 - "node_modules/url-parse": { 12062 - "version": "1.5.10", 12063 - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", 12064 - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", 12065 - "dev": true, 12066 - "dependencies": { 12067 - "querystringify": "^2.1.1", 12068 - "requires-port": "^1.0.0" 12069 - } 12070 - }, 12071 11765 "node_modules/util-deprecate": { 12072 11766 "version": "1.0.2", 12073 11767 "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", ··· 12131 11825 } 12132 11826 }, 12133 11827 "node_modules/vite": { 12134 - "version": "5.1.6", 12135 - "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz", 12136 - "integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==", 11828 + "version": "5.2.2", 11829 + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.2.tgz", 11830 + "integrity": "sha512-FWZbz0oSdLq5snUI0b6sULbz58iXFXdvkZfZWR/F0ZJuKTSPO7v72QPXt6KqYeMFb0yytNp6kZosxJ96Nr/wDQ==", 12137 11831 "dev": true, 12138 11832 "dependencies": { 12139 - "esbuild": "^0.19.3", 12140 - "postcss": "^8.4.35", 12141 - "rollup": "^4.2.0" 11833 + "esbuild": "^0.20.1", 11834 + "postcss": "^8.4.36", 11835 + "rollup": "^4.13.0" 12142 11836 }, 12143 11837 "bin": { 12144 11838 "vite": "bin/vite.js" ··· 12213 11907 "integrity": "sha512-KRCIFX3PWVUuEjpi9O7EKLT9E27OqOA3RimIvVx6cziLAUxvnk2VvHQfMrP+mKkqyqqSmnnYyTig3OyDnK/zlA==", 12214 11908 "dev": true 12215 11909 }, 12216 - "node_modules/vite/node_modules/@esbuild/aix-ppc64": { 12217 - "version": "0.19.12", 12218 - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", 12219 - "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", 12220 - "cpu": [ 12221 - "ppc64" 12222 - ], 12223 - "dev": true, 12224 - "optional": true, 12225 - "os": [ 12226 - "aix" 12227 - ], 12228 - "engines": { 12229 - "node": ">=12" 12230 - } 12231 - }, 12232 - "node_modules/vite/node_modules/@esbuild/android-arm": { 12233 - "version": "0.19.12", 12234 - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", 12235 - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", 12236 - "cpu": [ 12237 - "arm" 12238 - ], 12239 - "dev": true, 12240 - "optional": true, 12241 - "os": [ 12242 - "android" 12243 - ], 12244 - "engines": { 12245 - "node": ">=12" 12246 - } 12247 - }, 12248 - "node_modules/vite/node_modules/@esbuild/android-arm64": { 12249 - "version": "0.19.12", 12250 - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", 12251 - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", 12252 - "cpu": [ 12253 - "arm64" 12254 - ], 12255 - "dev": true, 12256 - "optional": true, 12257 - "os": [ 12258 - "android" 12259 - ], 12260 - "engines": { 12261 - "node": ">=12" 12262 - } 12263 - }, 12264 - "node_modules/vite/node_modules/@esbuild/android-x64": { 12265 - "version": "0.19.12", 12266 - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", 12267 - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", 12268 - "cpu": [ 12269 - "x64" 12270 - ], 12271 - "dev": true, 12272 - "optional": true, 12273 - "os": [ 12274 - "android" 12275 - ], 12276 - "engines": { 12277 - "node": ">=12" 12278 - } 12279 - }, 12280 - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { 12281 - "version": "0.19.12", 12282 - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", 12283 - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", 12284 - "cpu": [ 12285 - "arm64" 12286 - ], 12287 - "dev": true, 12288 - "optional": true, 12289 - "os": [ 12290 - "darwin" 12291 - ], 12292 - "engines": { 12293 - "node": ">=12" 12294 - } 12295 - }, 12296 - "node_modules/vite/node_modules/@esbuild/darwin-x64": { 12297 - "version": "0.19.12", 12298 - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", 12299 - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", 12300 - "cpu": [ 12301 - "x64" 12302 - ], 12303 - "dev": true, 12304 - "optional": true, 12305 - "os": [ 12306 - "darwin" 12307 - ], 12308 - "engines": { 12309 - "node": ">=12" 12310 - } 12311 - }, 12312 - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { 12313 - "version": "0.19.12", 12314 - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", 12315 - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", 12316 - "cpu": [ 12317 - "arm64" 12318 - ], 12319 - "dev": true, 12320 - "optional": true, 12321 - "os": [ 12322 - "freebsd" 12323 - ], 12324 - "engines": { 12325 - "node": ">=12" 12326 - } 12327 - }, 12328 - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { 12329 - "version": "0.19.12", 12330 - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", 12331 - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", 12332 - "cpu": [ 12333 - "x64" 12334 - ], 12335 - "dev": true, 12336 - "optional": true, 12337 - "os": [ 12338 - "freebsd" 12339 - ], 12340 - "engines": { 12341 - "node": ">=12" 12342 - } 12343 - }, 12344 - "node_modules/vite/node_modules/@esbuild/linux-arm": { 12345 - "version": "0.19.12", 12346 - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", 12347 - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", 12348 - "cpu": [ 12349 - "arm" 12350 - ], 12351 - "dev": true, 12352 - "optional": true, 12353 - "os": [ 12354 - "linux" 12355 - ], 12356 - "engines": { 12357 - "node": ">=12" 12358 - } 12359 - }, 12360 - "node_modules/vite/node_modules/@esbuild/linux-arm64": { 12361 - "version": "0.19.12", 12362 - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", 12363 - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", 12364 - "cpu": [ 12365 - "arm64" 12366 - ], 12367 - "dev": true, 12368 - "optional": true, 12369 - "os": [ 12370 - "linux" 12371 - ], 12372 - "engines": { 12373 - "node": ">=12" 12374 - } 12375 - }, 12376 - "node_modules/vite/node_modules/@esbuild/linux-ia32": { 12377 - "version": "0.19.12", 12378 - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", 12379 - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", 12380 - "cpu": [ 12381 - "ia32" 12382 - ], 12383 - "dev": true, 12384 - "optional": true, 12385 - "os": [ 12386 - "linux" 12387 - ], 12388 - "engines": { 12389 - "node": ">=12" 12390 - } 12391 - }, 12392 - "node_modules/vite/node_modules/@esbuild/linux-loong64": { 12393 - "version": "0.19.12", 12394 - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", 12395 - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", 12396 - "cpu": [ 12397 - "loong64" 12398 - ], 12399 - "dev": true, 12400 - "optional": true, 12401 - "os": [ 12402 - "linux" 12403 - ], 12404 - "engines": { 12405 - "node": ">=12" 12406 - } 12407 - }, 12408 - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { 12409 - "version": "0.19.12", 12410 - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", 12411 - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", 12412 - "cpu": [ 12413 - "mips64el" 12414 - ], 12415 - "dev": true, 12416 - "optional": true, 12417 - "os": [ 12418 - "linux" 12419 - ], 12420 - "engines": { 12421 - "node": ">=12" 12422 - } 12423 - }, 12424 - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { 12425 - "version": "0.19.12", 12426 - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", 12427 - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", 12428 - "cpu": [ 12429 - "ppc64" 12430 - ], 12431 - "dev": true, 12432 - "optional": true, 12433 - "os": [ 12434 - "linux" 12435 - ], 12436 - "engines": { 12437 - "node": ">=12" 12438 - } 12439 - }, 12440 - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { 12441 - "version": "0.19.12", 12442 - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", 12443 - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", 12444 - "cpu": [ 12445 - "riscv64" 12446 - ], 12447 - "dev": true, 12448 - "optional": true, 12449 - "os": [ 12450 - "linux" 12451 - ], 12452 - "engines": { 12453 - "node": ">=12" 12454 - } 12455 - }, 12456 - "node_modules/vite/node_modules/@esbuild/linux-s390x": { 12457 - "version": "0.19.12", 12458 - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", 12459 - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", 12460 - "cpu": [ 12461 - "s390x" 12462 - ], 12463 - "dev": true, 12464 - "optional": true, 12465 - "os": [ 12466 - "linux" 12467 - ], 12468 - "engines": { 12469 - "node": ">=12" 12470 - } 12471 - }, 12472 - "node_modules/vite/node_modules/@esbuild/linux-x64": { 12473 - "version": "0.19.12", 12474 - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", 12475 - "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", 12476 - "cpu": [ 12477 - "x64" 12478 - ], 12479 - "dev": true, 12480 - "optional": true, 12481 - "os": [ 12482 - "linux" 12483 - ], 12484 - "engines": { 12485 - "node": ">=12" 12486 - } 12487 - }, 12488 - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { 12489 - "version": "0.19.12", 12490 - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", 12491 - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", 12492 - "cpu": [ 12493 - "x64" 12494 - ], 12495 - "dev": true, 12496 - "optional": true, 12497 - "os": [ 12498 - "netbsd" 12499 - ], 12500 - "engines": { 12501 - "node": ">=12" 12502 - } 12503 - }, 12504 - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { 12505 - "version": "0.19.12", 12506 - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", 12507 - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", 12508 - "cpu": [ 12509 - "x64" 12510 - ], 12511 - "dev": true, 12512 - "optional": true, 12513 - "os": [ 12514 - "openbsd" 12515 - ], 12516 - "engines": { 12517 - "node": ">=12" 12518 - } 12519 - }, 12520 - "node_modules/vite/node_modules/@esbuild/sunos-x64": { 12521 - "version": "0.19.12", 12522 - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", 12523 - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", 12524 - "cpu": [ 12525 - "x64" 12526 - ], 12527 - "dev": true, 12528 - "optional": true, 12529 - "os": [ 12530 - "sunos" 12531 - ], 12532 - "engines": { 12533 - "node": ">=12" 12534 - } 12535 - }, 12536 - "node_modules/vite/node_modules/@esbuild/win32-arm64": { 12537 - "version": "0.19.12", 12538 - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", 12539 - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", 12540 - "cpu": [ 12541 - "arm64" 12542 - ], 12543 - "dev": true, 12544 - "optional": true, 12545 - "os": [ 12546 - "win32" 12547 - ], 12548 - "engines": { 12549 - "node": ">=12" 12550 - } 12551 - }, 12552 - "node_modules/vite/node_modules/@esbuild/win32-ia32": { 12553 - "version": "0.19.12", 12554 - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", 12555 - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", 12556 - "cpu": [ 12557 - "ia32" 12558 - ], 12559 - "dev": true, 12560 - "optional": true, 12561 - "os": [ 12562 - "win32" 12563 - ], 12564 - "engines": { 12565 - "node": ">=12" 12566 - } 12567 - }, 12568 - "node_modules/vite/node_modules/@esbuild/win32-x64": { 12569 - "version": "0.19.12", 12570 - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", 12571 - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", 12572 - "cpu": [ 12573 - "x64" 12574 - ], 12575 - "dev": true, 12576 - "optional": true, 12577 - "os": [ 12578 - "win32" 12579 - ], 12580 - "engines": { 12581 - "node": ">=12" 12582 - } 12583 - }, 12584 11910 "node_modules/vite/node_modules/@types/estree": { 12585 11911 "version": "1.0.5", 12586 11912 "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", 12587 11913 "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", 12588 11914 "dev": true 12589 11915 }, 12590 - "node_modules/vite/node_modules/esbuild": { 12591 - "version": "0.19.12", 12592 - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", 12593 - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", 12594 - "dev": true, 12595 - "hasInstallScript": true, 12596 - "bin": { 12597 - "esbuild": "bin/esbuild" 12598 - }, 12599 - "engines": { 12600 - "node": ">=12" 12601 - }, 12602 - "optionalDependencies": { 12603 - "@esbuild/aix-ppc64": "0.19.12", 12604 - "@esbuild/android-arm": "0.19.12", 12605 - "@esbuild/android-arm64": "0.19.12", 12606 - "@esbuild/android-x64": "0.19.12", 12607 - "@esbuild/darwin-arm64": "0.19.12", 12608 - "@esbuild/darwin-x64": "0.19.12", 12609 - "@esbuild/freebsd-arm64": "0.19.12", 12610 - "@esbuild/freebsd-x64": "0.19.12", 12611 - "@esbuild/linux-arm": "0.19.12", 12612 - "@esbuild/linux-arm64": "0.19.12", 12613 - "@esbuild/linux-ia32": "0.19.12", 12614 - "@esbuild/linux-loong64": "0.19.12", 12615 - "@esbuild/linux-mips64el": "0.19.12", 12616 - "@esbuild/linux-ppc64": "0.19.12", 12617 - "@esbuild/linux-riscv64": "0.19.12", 12618 - "@esbuild/linux-s390x": "0.19.12", 12619 - "@esbuild/linux-x64": "0.19.12", 12620 - "@esbuild/netbsd-x64": "0.19.12", 12621 - "@esbuild/openbsd-x64": "0.19.12", 12622 - "@esbuild/sunos-x64": "0.19.12", 12623 - "@esbuild/win32-arm64": "0.19.12", 12624 - "@esbuild/win32-ia32": "0.19.12", 12625 - "@esbuild/win32-x64": "0.19.12" 12626 - } 12627 - }, 12628 11916 "node_modules/vite/node_modules/fsevents": { 12629 11917 "version": "2.3.3", 12630 11918 "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", ··· 12637 11925 ], 12638 11926 "engines": { 12639 11927 "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 11928 + } 11929 + }, 11930 + "node_modules/vite/node_modules/postcss": { 11931 + "version": "8.4.38", 11932 + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", 11933 + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", 11934 + "dev": true, 11935 + "funding": [ 11936 + { 11937 + "type": "opencollective", 11938 + "url": "https://opencollective.com/postcss/" 11939 + }, 11940 + { 11941 + "type": "tidelift", 11942 + "url": "https://tidelift.com/funding/github/npm/postcss" 11943 + }, 11944 + { 11945 + "type": "github", 11946 + "url": "https://github.com/sponsors/ai" 11947 + } 11948 + ], 11949 + "dependencies": { 11950 + "nanoid": "^3.3.7", 11951 + "picocolors": "^1.0.0", 11952 + "source-map-js": "^1.2.0" 11953 + }, 11954 + "engines": { 11955 + "node": "^10 || ^12 || >=14" 12640 11956 } 12641 11957 }, 12642 11958 "node_modules/vite/node_modules/rollup": { ··· 12843 12159 "vue": "^3.2.29" 12844 12160 } 12845 12161 }, 12846 - "node_modules/w3c-xmlserializer": { 12847 - "version": "5.0.0", 12848 - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", 12849 - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", 12850 - "dev": true, 12851 - "dependencies": { 12852 - "xml-name-validator": "^5.0.0" 12853 - }, 12854 - "engines": { 12855 - "node": ">=18" 12856 - } 12857 - }, 12858 - "node_modules/w3c-xmlserializer/node_modules/xml-name-validator": { 12859 - "version": "5.0.0", 12860 - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", 12861 - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", 12862 - "dev": true, 12863 - "engines": { 12864 - "node": ">=18" 12865 - } 12866 - }, 12867 12162 "node_modules/watchpack": { 12868 12163 "version": "2.4.1", 12869 12164 "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", ··· 13088 12383 "node": ">=10.13.0" 13089 12384 } 13090 12385 }, 13091 - "node_modules/whatwg-encoding": { 13092 - "version": "3.1.1", 13093 - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", 13094 - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", 13095 - "dev": true, 13096 - "dependencies": { 13097 - "iconv-lite": "0.6.3" 13098 - }, 13099 - "engines": { 13100 - "node": ">=18" 13101 - } 13102 - }, 13103 12386 "node_modules/whatwg-mimetype": { 13104 - "version": "4.0.0", 13105 - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", 13106 - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", 12387 + "version": "3.0.0", 12388 + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", 12389 + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", 13107 12390 "dev": true, 13108 12391 "engines": { 13109 - "node": ">=18" 12392 + "node": ">=12" 13110 12393 } 13111 12394 }, 13112 12395 "node_modules/whatwg-url": { 13113 - "version": "14.0.0", 13114 - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", 13115 - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", 13116 - "dev": true, 12396 + "version": "5.0.0", 12397 + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 12398 + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 13117 12399 "dependencies": { 13118 - "tr46": "^5.0.0", 13119 - "webidl-conversions": "^7.0.0" 13120 - }, 13121 - "engines": { 13122 - "node": ">=18" 12400 + "tr46": "~0.0.3", 12401 + "webidl-conversions": "^3.0.0" 13123 12402 } 12403 + }, 12404 + "node_modules/whatwg-url/node_modules/webidl-conversions": { 12405 + "version": "3.0.1", 12406 + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 12407 + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 13124 12408 }, 13125 12409 "node_modules/which": { 13126 12410 "version": "2.0.2", ··· 13344 12628 "node": "^14.17.0 || ^16.13.0 || >=18.0.0" 13345 12629 } 13346 12630 }, 13347 - "node_modules/ws": { 13348 - "version": "8.16.0", 13349 - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", 13350 - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", 13351 - "dev": true, 13352 - "engines": { 13353 - "node": ">=10.0.0" 13354 - }, 13355 - "peerDependencies": { 13356 - "bufferutil": "^4.0.1", 13357 - "utf-8-validate": ">=5.0.2" 13358 - }, 13359 - "peerDependenciesMeta": { 13360 - "bufferutil": { 13361 - "optional": true 13362 - }, 13363 - "utf-8-validate": { 13364 - "optional": true 13365 - } 13366 - } 13367 - }, 13368 12631 "node_modules/xml-name-validator": { 13369 12632 "version": "4.0.0", 13370 12633 "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", ··· 13373 12636 "engines": { 13374 12637 "node": ">=12" 13375 12638 } 13376 - }, 13377 - "node_modules/xmlchars": { 13378 - "version": "2.2.0", 13379 - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", 13380 - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", 13381 - "dev": true 13382 12639 }, 13383 12640 "node_modules/y18n": { 13384 12641 "version": "5.0.8",
+1 -1
package.json
··· 84 84 "eslint-plugin-vue": "9.23.0", 85 85 "eslint-plugin-vue-scoped-css": "2.7.2", 86 86 "eslint-plugin-wc": "2.0.4", 87 - "jsdom": "24.0.0", 87 + "happy-dom": "14.2.0", 88 88 "markdownlint-cli": "0.39.0", 89 89 "postcss-html": "1.6.0", 90 90 "stylelint": "16.2.1",
+1 -1
playwright.config.js
··· 27 27 * Maximum time expect() should wait for the condition to be met. 28 28 * For example in `await expect(locator).toHaveText();` 29 29 */ 30 - timeout: 2000 30 + timeout: 2000, 31 31 }, 32 32 33 33 /* Fail the build on CI if you accidentally left test.only in the source code. */
+3 -2
routers/api/v1/repo/issue.go
··· 874 874 } 875 875 if form.State != nil { 876 876 if issue.IsPull { 877 - if pr, err := issue.GetPullRequest(ctx); err != nil { 877 + if err := issue.LoadPullRequest(ctx); err != nil { 878 878 ctx.Error(http.StatusInternalServerError, "GetPullRequest", err) 879 879 return 880 - } else if pr.HasMerged { 880 + } 881 + if issue.PullRequest.HasMerged { 881 882 ctx.Error(http.StatusPreconditionFailed, "MergedPRState", "cannot change state of this pull request, it was already merged") 882 883 return 883 884 }
+5 -11
routers/api/v1/repo/issue_pin.go
··· 240 240 } 241 241 242 242 apiPrs := make([]*api.PullRequest, len(issues)) 243 + if err := issues.LoadPullRequests(ctx); err != nil { 244 + ctx.Error(http.StatusInternalServerError, "LoadPullRequests", err) 245 + return 246 + } 243 247 for i, currentIssue := range issues { 244 - pr, err := currentIssue.GetPullRequest(ctx) 245 - if err != nil { 246 - ctx.Error(http.StatusInternalServerError, "GetPullRequest", err) 247 - return 248 - } 249 - 250 - if err = pr.LoadIssue(ctx); err != nil { 251 - ctx.Error(http.StatusInternalServerError, "LoadIssue", err) 252 - return 253 - } 254 - 248 + pr := currentIssue.PullRequest 255 249 if err = pr.LoadAttributes(ctx); err != nil { 256 250 ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) 257 251 return
+7 -2
routers/api/v1/repo/pull.go
··· 21 21 repo_model "code.gitea.io/gitea/models/repo" 22 22 "code.gitea.io/gitea/models/unit" 23 23 user_model "code.gitea.io/gitea/models/user" 24 + "code.gitea.io/gitea/modules/base" 24 25 "code.gitea.io/gitea/modules/git" 25 26 "code.gitea.io/gitea/modules/gitrepo" 26 27 "code.gitea.io/gitea/modules/log" ··· 96 97 // "404": 97 98 // "$ref": "#/responses/notFound" 98 99 100 + labelIDs, err := base.StringsToInt64s(ctx.FormStrings("labels")) 101 + if err != nil { 102 + ctx.Error(http.StatusInternalServerError, "PullRequests", err) 103 + return 104 + } 99 105 listOptions := utils.GetListOptions(ctx) 100 - 101 106 prs, maxResults, err := issues_model.PullRequests(ctx, ctx.Repo.Repository.ID, &issues_model.PullRequestsOptions{ 102 107 ListOptions: listOptions, 103 108 State: ctx.FormTrim("state"), 104 109 SortType: ctx.FormTrim("sort"), 105 - Labels: ctx.FormStrings("labels"), 110 + Labels: labelIDs, 106 111 MilestoneID: ctx.FormInt64("milestone"), 107 112 }) 108 113 if err != nil {
+4
routers/private/hook_post_receive.go
··· 75 75 updates = append(updates, option) 76 76 if repo.IsEmpty && (refFullName.BranchName() == "master" || refFullName.BranchName() == "main") { 77 77 // put the master/main branch first 78 + // FIXME: It doesn't always work, since the master/main branch may not be the first batch of updates. 79 + // If the user pushes many branches at once, the Git hook will call the internal API in batches, rather than all at once. 80 + // See https://github.com/go-gitea/gitea/blob/cb52b17f92e2d2293f7c003649743464492bca48/cmd/hook.go#L27 81 + // If the user executes `git push origin --all` and pushes more than 30 branches, the master/main may not be the default branch. 78 82 copy(updates[1:], updates) 79 83 updates[0] = option 80 84 }
+2 -6
routers/web/admin/users.go
··· 275 275 } 276 276 277 277 repos, count, err := repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{ 278 - ListOptions: db.ListOptions{ 279 - ListAll: true, 280 - }, 278 + ListOptions: db.ListOptionsAll, 281 279 OwnerID: u.ID, 282 280 OrderBy: db.SearchOrderByAlphabetically, 283 281 Private: true, ··· 300 298 ctx.Data["EmailsTotal"] = len(emails) 301 299 302 300 orgs, err := db.Find[org_model.Organization](ctx, org_model.FindOrgOptions{ 303 - ListOptions: db.ListOptions{ 304 - ListAll: true, 305 - }, 301 + ListOptions: db.ListOptionsAll, 306 302 UserID: u.ID, 307 303 IncludePrivate: true, 308 304 })
+9 -1
routers/web/repo/actions/actions.go
··· 104 104 workflows = append(workflows, workflow) 105 105 continue 106 106 } 107 - // Check whether have matching runner 107 + // The workflow must contain at least one job without "needs". Otherwise, a deadlock will occur and no jobs will be able to run. 108 + hasJobWithoutNeeds := false 109 + // Check whether have matching runner and a job without "needs" 108 110 for _, j := range wf.Jobs { 111 + if !hasJobWithoutNeeds && len(j.Needs()) == 0 { 112 + hasJobWithoutNeeds = true 113 + } 109 114 runsOnList := j.RunsOn() 110 115 for _, ro := range runsOnList { 111 116 if strings.Contains(ro, "${{") { ··· 122 127 if workflow.ErrMsg != "" { 123 128 break 124 129 } 130 + } 131 + if !hasJobWithoutNeeds { 132 + workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_job_without_needs") 125 133 } 126 134 workflows = append(workflows, workflow) 127 135 }
+21 -5
routers/web/repo/actions/view.go
··· 353 353 return 354 354 } 355 355 356 - if jobIndexStr != "" { 357 - jobs = []*actions_model.ActionRunJob{job} 356 + if jobIndexStr == "" { // rerun all jobs 357 + for _, j := range jobs { 358 + // if the job has needs, it should be set to "blocked" status to wait for other jobs 359 + shouldBlock := len(j.Needs) > 0 360 + if err := rerunJob(ctx, j, shouldBlock); err != nil { 361 + ctx.Error(http.StatusInternalServerError, err.Error()) 362 + return 363 + } 364 + } 365 + ctx.JSON(http.StatusOK, struct{}{}) 366 + return 358 367 } 359 368 360 - for _, j := range jobs { 361 - if err := rerunJob(ctx, j); err != nil { 369 + rerunJobs := actions_service.GetAllRerunJobs(job, jobs) 370 + 371 + for _, j := range rerunJobs { 372 + // jobs other than the specified one should be set to "blocked" status 373 + shouldBlock := j.JobID != job.JobID 374 + if err := rerunJob(ctx, j, shouldBlock); err != nil { 362 375 ctx.Error(http.StatusInternalServerError, err.Error()) 363 376 return 364 377 } ··· 367 380 ctx.JSON(http.StatusOK, struct{}{}) 368 381 } 369 382 370 - func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob) error { 383 + func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob, shouldBlock bool) error { 371 384 status := job.Status 372 385 if !status.IsDone() { 373 386 return nil ··· 375 388 376 389 job.TaskID = 0 377 390 job.Status = actions_model.StatusWaiting 391 + if shouldBlock { 392 + job.Status = actions_model.StatusBlocked 393 + } 378 394 job.Started = 0 379 395 job.Stopped = 0 380 396
+1 -1
routers/web/repo/commit.go
··· 367 367 ctx.Data["Commit"] = commit 368 368 ctx.Data["Diff"] = diff 369 369 370 - statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, commitID, db.ListOptions{ListAll: true}) 370 + statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, commitID, db.ListOptionsAll) 371 371 if err != nil { 372 372 log.Error("GetLatestCommitStatus: %v", err) 373 373 }
+7 -8
routers/web/repo/compare.go
··· 697 697 defer gitRepo.Close() 698 698 699 699 branches, err = git_model.FindBranchNames(ctx, git_model.FindBranchOptions{ 700 - RepoID: repo.ID, 701 - ListOptions: db.ListOptions{ 702 - ListAll: true, 703 - }, 700 + RepoID: repo.ID, 701 + ListOptions: db.ListOptionsAll, 704 702 IsDeletedBranch: optional.Some(false), 705 703 }) 706 704 if err != nil { ··· 754 752 } 755 753 756 754 headBranches, err := git_model.FindBranchNames(ctx, git_model.FindBranchOptions{ 757 - RepoID: ci.HeadRepo.ID, 758 - ListOptions: db.ListOptions{ 759 - ListAll: true, 760 - }, 755 + RepoID: ci.HeadRepo.ID, 756 + ListOptions: db.ListOptionsAll, 761 757 IsDeletedBranch: optional.Some(false), 762 758 }) 763 759 if err != nil { ··· 979 975 Content: " " + lineText, 980 976 } 981 977 diffLines = append(diffLines, diffLine) 978 + } 979 + if err = scanner.Err(); err != nil { 980 + return nil, fmt.Errorf("getExcerptLines scan: %w", err) 982 981 } 983 982 return diffLines, nil 984 983 }
+2 -2
routers/web/repo/editor.go
··· 374 374 ctx.Error(http.StatusInternalServerError, err.Error()) 375 375 } 376 376 } else if models.IsErrCommitIDDoesNotMatch(err) { 377 - ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(ctx.Repo.CommitID)), tplEditFile, &form) 377 + ctx.RenderWithErr(ctx.Tr("repo.editor.commit_id_not_matching"), tplEditFile, &form) 378 378 } else if git.IsErrPushOutOfDate(err) { 379 - ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(form.NewBranchName)), tplEditFile, &form) 379 + ctx.RenderWithErr(ctx.Tr("repo.editor.push_out_of_date"), tplEditFile, &form) 380 380 } else if git.IsErrPushRejected(err) { 381 381 errPushRej := err.(*git.ErrPushRejected) 382 382 if len(errPushRej.Message) == 0 {
+3 -2
routers/web/repo/find.go
··· 7 7 "net/http" 8 8 9 9 "code.gitea.io/gitea/modules/base" 10 + "code.gitea.io/gitea/modules/util" 10 11 "code.gitea.io/gitea/services/context" 11 12 ) 12 13 ··· 17 18 // FindFiles render the page to find repository files 18 19 func FindFiles(ctx *context.Context) { 19 20 path := ctx.Params("*") 20 - ctx.Data["TreeLink"] = ctx.Repo.RepoLink + "/src/" + path 21 - ctx.Data["DataLink"] = ctx.Repo.RepoLink + "/tree-list/" + path 21 + ctx.Data["TreeLink"] = ctx.Repo.RepoLink + "/src/" + util.PathEscapeSegments(path) 22 + ctx.Data["DataLink"] = ctx.Repo.RepoLink + "/tree-list/" + util.PathEscapeSegments(path) 22 23 ctx.HTML(http.StatusOK, tplFindFiles) 23 24 }
+4 -5
routers/web/repo/issue.go
··· 192 192 if len(selectLabels) > 0 { 193 193 labelIDs, err = base.StringsToInt64s(strings.Split(selectLabels, ",")) 194 194 if err != nil { 195 - ctx.ServerError("StringsToInt64s", err) 196 - return 195 + ctx.Flash.Error(ctx.Tr("invalid_data", selectLabels), true) 197 196 } 198 197 } 199 198 ··· 451 450 linkStr := "%s?q=%s&type=%s&sort=%s&state=%s&labels=%s&milestone=%d&project=%d&assignee=%d&poster=%d&archived=%t" 452 451 ctx.Data["AllStatesLink"] = fmt.Sprintf(linkStr, ctx.Link, 453 452 url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "all", url.QueryEscape(selectLabels), 454 - mentionedID, projectID, assigneeID, posterID, archived) 453 + milestoneID, projectID, assigneeID, posterID, archived) 455 454 ctx.Data["OpenLink"] = fmt.Sprintf(linkStr, ctx.Link, 456 455 url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "open", url.QueryEscape(selectLabels), 457 - mentionedID, projectID, assigneeID, posterID, archived) 456 + milestoneID, projectID, assigneeID, posterID, archived) 458 457 ctx.Data["ClosedLink"] = fmt.Sprintf(linkStr, ctx.Link, 459 458 url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "closed", url.QueryEscape(selectLabels), 460 - mentionedID, projectID, assigneeID, posterID, archived) 459 + milestoneID, projectID, assigneeID, posterID, archived) 461 460 ctx.Data["SelLabelIDs"] = labelIDs 462 461 ctx.Data["SelectLabels"] = selectLabels 463 462 ctx.Data["ViewType"] = viewType
+3 -3
routers/web/repo/pull.go
··· 505 505 506 506 if len(compareInfo.Commits) != 0 { 507 507 sha := compareInfo.Commits[0].ID.String() 508 - commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, sha, db.ListOptions{ListAll: true}) 508 + commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, sha, db.ListOptionsAll) 509 509 if err != nil { 510 510 ctx.ServerError("GetLatestCommitStatus", err) 511 511 return nil ··· 567 567 ctx.ServerError(fmt.Sprintf("GetRefCommitID(%s)", pull.GetGitRefName()), err) 568 568 return nil 569 569 } 570 - commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptions{ListAll: true}) 570 + commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptionsAll) 571 571 if err != nil { 572 572 ctx.ServerError("GetLatestCommitStatus", err) 573 573 return nil ··· 659 659 return nil 660 660 } 661 661 662 - commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptions{ListAll: true}) 662 + commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptionsAll) 663 663 if err != nil { 664 664 ctx.ServerError("GetLatestCommitStatus", err) 665 665 return nil
+1 -1
routers/web/repo/release.go
··· 136 136 } 137 137 138 138 if canReadActions { 139 - statuses, _, err := git_model.GetLatestCommitStatus(ctx, r.Repo.ID, r.Sha1, db.ListOptions{ListAll: true}) 139 + statuses, _, err := git_model.GetLatestCommitStatus(ctx, r.Repo.ID, r.Sha1, db.ListOptionsAll) 140 140 if err != nil { 141 141 return nil, err 142 142 }
+17 -16
routers/web/repo/repo.go
··· 618 618 } 619 619 } 620 620 621 - var err error 621 + // To improve performance when only the count is requested 622 + if ctx.FormBool("count_only") { 623 + if count, err := repo_model.CountRepository(ctx, opts); err != nil { 624 + log.Error("CountRepository: %v", err) 625 + ctx.JSON(http.StatusInternalServerError, nil) // frontend JS doesn't handle error response (same as below) 626 + } else { 627 + ctx.SetTotalCountHeader(count) 628 + ctx.JSONOK() 629 + } 630 + return 631 + } 632 + 622 633 repos, count, err := repo_model.SearchRepository(ctx, opts) 623 634 if err != nil { 624 - ctx.JSON(http.StatusInternalServerError, api.SearchError{ 625 - OK: false, 626 - Error: err.Error(), 627 - }) 635 + log.Error("SearchRepository: %v", err) 636 + ctx.JSON(http.StatusInternalServerError, nil) 628 637 return 629 638 } 630 639 631 640 ctx.SetTotalCountHeader(count) 632 641 633 - // To improve performance when only the count is requested 634 - if ctx.FormBool("count_only") { 635 - return 636 - } 637 - 638 642 latestCommitStatuses, err := commitstatus_service.FindReposLastestCommitStatuses(ctx, repos) 639 643 if err != nil { 640 644 log.Error("FindReposLastestCommitStatuses: %v", err) 645 + ctx.JSON(http.StatusInternalServerError, nil) 641 646 return 642 647 } 643 648 ··· 679 684 branchOpts := git_model.FindBranchOptions{ 680 685 RepoID: ctx.Repo.Repository.ID, 681 686 IsDeletedBranch: optional.Some(false), 682 - ListOptions: db.ListOptions{ 683 - ListAll: true, 684 - }, 687 + ListOptions: db.ListOptionsAll, 685 688 } 686 689 branches, err := git_model.FindBranchNames(ctx, branchOpts) 687 690 if err != nil { ··· 714 717 branchOpts := git_model.FindBranchOptions{ 715 718 RepoID: ctx.Repo.Repository.ID, 716 719 IsDeletedBranch: optional.Some(false), 717 - ListOptions: db.ListOptions{ 718 - ListAll: true, 719 - }, 720 + ListOptions: db.ListOptionsAll, 720 721 } 721 722 brs, err := git_model.FindBranchNames(ctx, branchOpts) 722 723 if err != nil {
+1 -1
routers/web/repo/view.go
··· 364 364 ctx.Data["LatestCommitVerification"] = verification 365 365 ctx.Data["LatestCommitUser"] = user_model.ValidateCommitWithEmail(ctx, latestCommit) 366 366 367 - statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, latestCommit.ID.String(), db.ListOptions{ListAll: true}) 367 + statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, latestCommit.ID.String(), db.ListOptionsAll) 368 368 if err != nil { 369 369 log.Error("GetLatestCommitStatus: %v", err) 370 370 }
+14
routers/web/shared/user/header.go
··· 16 16 "code.gitea.io/gitea/modules/git" 17 17 "code.gitea.io/gitea/modules/gitrepo" 18 18 "code.gitea.io/gitea/modules/log" 19 + "code.gitea.io/gitea/modules/markup" 20 + "code.gitea.io/gitea/modules/markup/markdown" 19 21 "code.gitea.io/gitea/modules/optional" 20 22 "code.gitea.io/gitea/modules/setting" 21 23 "code.gitea.io/gitea/services/context" ··· 35 37 prepareContextForCommonProfile(ctx) 36 38 37 39 ctx.Data["IsBlocked"] = ctx.Doer != nil && user_model.IsBlocked(ctx, ctx.Doer.ID, ctx.ContextUser.ID) 40 + ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx, ctx.Doer.ID, ctx.ContextUser.ID) 38 41 ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate 39 42 if setting.Service.UserLocationMapURL != "" { 40 43 ctx.Data["ContextUserLocationMapURL"] = setting.Service.UserLocationMapURL + url.QueryEscape(ctx.ContextUser.Location) ··· 46 49 return 47 50 } 48 51 ctx.Data["OpenIDs"] = openIDs 52 + if len(ctx.ContextUser.Description) != 0 { 53 + content, err := markdown.RenderString(&markup.RenderContext{ 54 + Metas: map[string]string{"mode": "document"}, 55 + Ctx: ctx, 56 + }, ctx.ContextUser.Description) 57 + if err != nil { 58 + ctx.ServerError("RenderString", err) 59 + return 60 + } 61 + ctx.Data["RenderedDescription"] = content 62 + } 49 63 50 64 showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) 51 65 orgs, err := db.Find[organization.Organization](ctx, organization.FindOrgOptions{
+2 -5
routers/web/user/home.go
··· 529 529 530 530 // Get IDs for labels (a filter option for issues/pulls). 531 531 // Required for IssuesOptions. 532 - var labelIDs []int64 533 532 selectedLabels := ctx.FormString("labels") 534 533 if len(selectedLabels) > 0 && selectedLabels != "0" { 535 534 var err error 536 - labelIDs, err = base.StringsToInt64s(strings.Split(selectedLabels, ",")) 535 + opts.LabelIDs, err = base.StringsToInt64s(strings.Split(selectedLabels, ",")) 537 536 if err != nil { 538 - ctx.ServerError("StringsToInt64s", err) 539 - return 537 + ctx.Flash.Error(ctx.Tr("invalid_data", selectedLabels), true) 540 538 } 541 539 } 542 - opts.LabelIDs = labelIDs 543 540 544 541 // ------------------------------ 545 542 // Get issues as defined by opts.
+7 -2
routers/web/user/notification.go
··· 144 144 ctx.ServerError("LoadIssues", err) 145 145 return 146 146 } 147 + 148 + if err = notifications.LoadIssuePullRequests(ctx); err != nil { 149 + ctx.ServerError("LoadIssuePullRequests", err) 150 + return 151 + } 152 + 147 153 notifications = notifications.Without(failures) 148 154 failCount += len(failures) 149 155 ··· 262 268 var err error 263 269 labelIDs, err = base.StringsToInt64s(strings.Split(selectedLabels, ",")) 264 270 if err != nil { 265 - ctx.ServerError("StringsToInt64s", err) 266 - return 271 + ctx.Flash.Error(ctx.Tr("invalid_data", selectedLabels), true) 267 272 } 268 273 } 269 274
+1 -1
services/actions/commit_status.go
··· 79 79 } 80 80 ctxname := fmt.Sprintf("%s / %s (%s)", runName, job.Name, event) 81 81 state := toCommitStatus(job.Status) 82 - if statuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptions{ListAll: true}); err == nil { 82 + if statuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptionsAll); err == nil { 83 83 for _, v := range statuses { 84 84 if v.Context == ctxname { 85 85 if v.State == state {
+13 -3
services/actions/notifier.go
··· 515 515 } 516 516 517 517 func (n *actionsNotifier) PushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { 518 + commitID, _ := git.NewIDFromString(opts.NewCommitID) 519 + if commitID.IsZero() { 520 + log.Trace("new commitID is empty") 521 + return 522 + } 523 + 518 524 ctx = withMethod(ctx, "PushCommits") 519 525 520 526 apiPusher := convert.ToUser(ctx, pusher, nil) ··· 547 553 apiRepo := convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}) 548 554 549 555 newNotifyInput(repo, pusher, webhook_module.HookEventCreate). 550 - WithRef(refFullName.ShortName()). // FIXME: should we use a full ref name 556 + WithRef(refFullName.String()). 551 557 WithPayload(&api.CreatePayload{ 552 - Ref: refFullName.ShortName(), 558 + Ref: refFullName.String(), 553 559 Sha: refID, 554 560 RefType: refFullName.RefType(), 555 561 Repo: apiRepo, ··· 566 572 567 573 newNotifyInput(repo, pusher, webhook_module.HookEventDelete). 568 574 WithPayload(&api.DeletePayload{ 569 - Ref: refFullName.ShortName(), 575 + Ref: refFullName.String(), 570 576 RefType: refFullName.RefType(), 571 577 PusherType: api.PusherTypeUser, 572 578 Repo: apiRepo, ··· 623 629 } 624 630 625 631 func (n *actionsNotifier) DeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) { 632 + if rel.IsTag { 633 + // has sent same action in `PushCommits`, so skip it. 634 + return 635 + } 626 636 ctx = withMethod(ctx, "DeleteRelease") 627 637 notifyRelease(ctx, doer, rel, api.HookReleaseDeleted) 628 638 }
+38
services/actions/rerun.go
··· 1 + // Copyright 2024 The Gitea Authors. All rights reserved. 2 + // SPDX-License-Identifier: MIT 3 + 4 + package actions 5 + 6 + import ( 7 + actions_model "code.gitea.io/gitea/models/actions" 8 + "code.gitea.io/gitea/modules/container" 9 + ) 10 + 11 + // GetAllRerunJobs get all jobs that need to be rerun when job should be rerun 12 + func GetAllRerunJobs(job *actions_model.ActionRunJob, allJobs []*actions_model.ActionRunJob) []*actions_model.ActionRunJob { 13 + rerunJobs := []*actions_model.ActionRunJob{job} 14 + rerunJobsIDSet := make(container.Set[string]) 15 + rerunJobsIDSet.Add(job.JobID) 16 + 17 + for { 18 + found := false 19 + for _, j := range allJobs { 20 + if rerunJobsIDSet.Contains(j.JobID) { 21 + continue 22 + } 23 + for _, need := range j.Needs { 24 + if rerunJobsIDSet.Contains(need) { 25 + found = true 26 + rerunJobs = append(rerunJobs, j) 27 + rerunJobsIDSet.Add(j.JobID) 28 + break 29 + } 30 + } 31 + } 32 + if !found { 33 + break 34 + } 35 + } 36 + 37 + return rerunJobs 38 + }
+48
services/actions/rerun_test.go
··· 1 + // Copyright 2024 The Gitea Authors. All rights reserved. 2 + // SPDX-License-Identifier: MIT 3 + 4 + package actions 5 + 6 + import ( 7 + "testing" 8 + 9 + actions_model "code.gitea.io/gitea/models/actions" 10 + 11 + "github.com/stretchr/testify/assert" 12 + ) 13 + 14 + func TestGetAllRerunJobs(t *testing.T) { 15 + job1 := &actions_model.ActionRunJob{JobID: "job1"} 16 + job2 := &actions_model.ActionRunJob{JobID: "job2", Needs: []string{"job1"}} 17 + job3 := &actions_model.ActionRunJob{JobID: "job3", Needs: []string{"job2"}} 18 + job4 := &actions_model.ActionRunJob{JobID: "job4", Needs: []string{"job2", "job3"}} 19 + 20 + jobs := []*actions_model.ActionRunJob{job1, job2, job3, job4} 21 + 22 + testCases := []struct { 23 + job *actions_model.ActionRunJob 24 + rerunJobs []*actions_model.ActionRunJob 25 + }{ 26 + { 27 + job1, 28 + []*actions_model.ActionRunJob{job1, job2, job3, job4}, 29 + }, 30 + { 31 + job2, 32 + []*actions_model.ActionRunJob{job2, job3, job4}, 33 + }, 34 + { 35 + job3, 36 + []*actions_model.ActionRunJob{job3, job4}, 37 + }, 38 + { 39 + job4, 40 + []*actions_model.ActionRunJob{job4}, 41 + }, 42 + } 43 + 44 + for _, tc := range testCases { 45 + rerunJobs := GetAllRerunJobs(tc.job, jobs) 46 + assert.ElementsMatch(t, tc.rerunJobs, rerunJobs) 47 + } 48 + }
+9 -17
services/auth/session.go
··· 4 4 package auth 5 5 6 6 import ( 7 - "context" 8 7 "net/http" 9 8 10 9 user_model "code.gitea.io/gitea/models/user" ··· 29 28 // object for that uid. 30 29 // Returns nil if there is no user uid stored in the session. 31 30 func (s *Session) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { 32 - user := SessionUser(req.Context(), sess) 33 - if user != nil { 34 - return user, nil 35 - } 36 - return nil, nil 37 - } 38 - 39 - // SessionUser returns the user object corresponding to the "uid" session variable. 40 - func SessionUser(ctx context.Context, sess SessionStore) *user_model.User { 41 31 if sess == nil { 42 - return nil 32 + return nil, nil 43 33 } 44 34 45 35 // Get user ID 46 36 uid := sess.Get("uid") 47 37 if uid == nil { 48 - return nil 38 + return nil, nil 49 39 } 50 40 log.Trace("Session Authorization: Found user[%d]", uid) 51 41 52 42 id, ok := uid.(int64) 53 43 if !ok { 54 - return nil 44 + return nil, nil 55 45 } 56 46 57 47 // Get user object 58 - user, err := user_model.GetUserByID(ctx, id) 48 + user, err := user_model.GetUserByID(req.Context(), id) 59 49 if err != nil { 60 50 if !user_model.IsErrUserNotExist(err) { 61 - log.Error("GetUserById: %v", err) 51 + log.Error("GetUserByID: %v", err) 52 + // Return the err as-is to keep current signed-in session, in case the err is something like context.Canceled. Otherwise non-existing user (nil, nil) will make the caller clear the signed-in session. 53 + return nil, err 62 54 } 63 - return nil 55 + return nil, nil 64 56 } 65 57 66 58 log.Trace("Session Authorization: Logged in user %-v", user) 67 - return user 59 + return user, nil 68 60 }
+3 -2
services/convert/notification.go
··· 61 61 result.Subject.LatestCommentHTMLURL = comment.HTMLURL(ctx) 62 62 } 63 63 64 - pr, _ := n.Issue.GetPullRequest(ctx) 65 - if pr != nil && pr.HasMerged { 64 + if err := n.Issue.LoadPullRequest(ctx); err == nil && 65 + n.Issue.PullRequest != nil && 66 + n.Issue.PullRequest.HasMerged { 66 67 result.Subject.State = "merged" 67 68 } 68 69 }
+5 -1
services/doctor/authorizedkeys.go
··· 50 50 } 51 51 linesInAuthorizedKeys.Add(line) 52 52 } 53 - f.Close() 53 + if err = scanner.Err(); err != nil { 54 + return fmt.Errorf("scan: %w", err) 55 + } 56 + // although there is a "defer close" above, here close explicitly before the generating, because it needs to open the file for writing again 57 + _ = f.Close() 54 58 55 59 // now we regenerate and check if there are any lines missing 56 60 regenerated := &bytes.Buffer{}
+1 -1
services/pull/commit_status.go
··· 153 153 return "", fmt.Errorf("LoadBaseRepo: %w", err) 154 154 } 155 155 156 - commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, pr.BaseRepo.ID, sha, db.ListOptions{ListAll: true}) 156 + commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, pr.BaseRepo.ID, sha, db.ListOptionsAll) 157 157 if err != nil { 158 158 return "", fmt.Errorf("GetLatestCommitStatus: %w", err) 159 159 }
+1 -1
services/pull/pull.go
··· 893 893 return nil, nil, shaErr 894 894 } 895 895 896 - statuses, _, err = git_model.GetLatestCommitStatus(ctx, pr.BaseRepo.ID, sha, db.ListOptions{ListAll: true}) 896 + statuses, _, err = git_model.GetLatestCommitStatus(ctx, pr.BaseRepo.ID, sha, db.ListOptionsAll) 897 897 lastStatus = git_model.CalcCommitStatus(statuses) 898 898 return statuses, lastStatus, err 899 899 }
+7 -11
services/pull/review.go
··· 52 52 issueIDs := prs.GetIssueIDs() 53 53 54 54 codeComments, err := db.Find[issues_model.Comment](ctx, issues_model.FindCommentsOptions{ 55 - ListOptions: db.ListOptions{ 56 - ListAll: true, 57 - }, 55 + ListOptions: db.ListOptionsAll, 58 56 Type: issues_model.CommentTypeCode, 59 57 Invalidated: optional.Some(false), 60 58 IssueIDs: issueIDs, ··· 268 266 269 267 // SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist 270 268 func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue, reviewType issues_model.ReviewType, content, commitID string, attachmentUUIDs []string) (*issues_model.Review, *issues_model.Comment, error) { 271 - pr, err := issue.GetPullRequest(ctx) 272 - if err != nil { 269 + if err := issue.LoadPullRequest(ctx); err != nil { 273 270 return nil, nil, err 274 271 } 275 272 273 + pr := issue.PullRequest 276 274 var stale bool 277 275 if reviewType != issues_model.ReviewTypeApprove && reviewType != issues_model.ReviewTypeReject { 278 276 stale = false ··· 322 320 // DismissApprovalReviews dismiss all approval reviews because of new commits 323 321 func DismissApprovalReviews(ctx context.Context, doer *user_model.User, pull *issues_model.PullRequest) error { 324 322 reviews, err := issues_model.FindReviews(ctx, issues_model.FindReviewOptions{ 325 - ListOptions: db.ListOptions{ 326 - ListAll: true, 327 - }, 328 - IssueID: pull.IssueID, 329 - Type: issues_model.ReviewTypeApprove, 330 - Dismissed: optional.Some(false), 323 + ListOptions: db.ListOptionsAll, 324 + IssueID: pull.IssueID, 325 + Type: issues_model.ReviewTypeApprove, 326 + Dismissed: optional.Some(false), 331 327 }) 332 328 if err != nil { 333 329 return err
+2 -4
services/repository/adopt.go
··· 144 144 } 145 145 146 146 branches, _ := git_model.FindBranchNames(ctx, git_model.FindBranchOptions{ 147 - RepoID: repo.ID, 148 - ListOptions: db.ListOptions{ 149 - ListAll: true, 150 - }, 147 + RepoID: repo.ID, 148 + ListOptions: db.ListOptionsAll, 151 149 IsDeletedBranch: optional.Some(false), 152 150 }) 153 151
+6 -4
services/repository/branch.go
··· 127 127 p := protectedBranches.GetFirstMatched(branchName) 128 128 isProtected := p != nil 129 129 130 - divergence := &git.DivergeObject{ 131 - Ahead: -1, 132 - Behind: -1, 133 - } 130 + var divergence *git.DivergeObject 134 131 135 132 // it's not default branch 136 133 if repo.DefaultBranch != dbBranch.Name && !dbBranch.IsDeleted { ··· 139 136 if err != nil { 140 137 return nil, fmt.Errorf("CountDivergingCommits: %v", err) 141 138 } 139 + } 140 + 141 + if divergence == nil { 142 + // tolerate the error that we cannot get divergence 143 + divergence = &git.DivergeObject{Ahead: -1, Behind: -1} 142 144 } 143 145 144 146 pr, err := issues_model.GetLatestPullRequestByHeadInfo(ctx, repo.ID, branchName)
+3 -1
services/webhook/telegram.go
··· 181 181 182 182 func createTelegramPayload(message string) TelegramPayload { 183 183 return TelegramPayload{ 184 - Message: strings.TrimSpace(message), 184 + Message: strings.TrimSpace(message), 185 + ParseMode: "HTML", 186 + DisableWebPreview: true, 185 187 } 186 188 } 187 189
+9
services/webhook/telegram_test.go
··· 18 18 19 19 func TestTelegramPayload(t *testing.T) { 20 20 tc := telegramConvertor{} 21 + 22 + t.Run("Correct webhook params", func(t *testing.T) { 23 + p := createTelegramPayload("testMsg ") 24 + 25 + assert.Equal(t, "HTML", p.ParseMode) 26 + assert.Equal(t, true, p.DisableWebPreview) 27 + assert.Equal(t, "testMsg", p.Message) 28 + }) 29 + 21 30 t.Run("Create", func(t *testing.T) { 22 31 p := createTestPayload() 23 32
+36
tailwind.config.js
··· 55 55 current: 'currentcolor', 56 56 transparent: 'transparent', 57 57 }, 58 + borderRadius: { 59 + 'none': '0', 60 + 'sm': '2px', 61 + 'DEFAULT': 'var(--border-radius)', // 4px 62 + 'md': 'var(--border-radius-medium)', // 6px 63 + 'lg': '8px', 64 + 'xl': '12px', 65 + '2xl': '16px', 66 + '3xl': '24px', 67 + 'full': 'var(--border-radius-circle)', // 50% 68 + }, 69 + fontWeight: { 70 + light: 'var(--font-weight-light)', 71 + normal: 'var(--font-weight-normal)', 72 + medium: 'var(--font-weight-medium)', 73 + semibold: 'var(--font-weight-semibold)', 74 + bold: 'var(--font-weight-bold)', 75 + }, 76 + fontSize: { // not using `rem` units because our root is currently 14px 77 + 'xs': '12px', 78 + 'sm': '14px', 79 + 'base': '16px', 80 + 'lg': '18px', 81 + 'xl': '20px', 82 + '2xl': '24px', 83 + '3xl': '30px', 84 + '4xl': '36px', 85 + '5xl': '48px', 86 + '6xl': '60px', 87 + '7xl': '72px', 88 + '8xl': '96px', 89 + '9xl': '128px', 90 + ...Object.fromEntries(Array.from({length: 100}, (_, i) => { 91 + return [`${i}`, `${i === 0 ? '0' : `${i}px`}`]; 92 + })), 93 + }, 58 94 }, 59 95 };
+1 -1
templates/admin/auth/new.tmpl
··· 99 99 <li>GitHub</li> 100 100 <span>{{ctx.Locale.Tr "admin.auths.tip.github"}}</span> 101 101 <li>GitLab</li> 102 - <span>{{ctx.Locale.Tr "admin.auths.tip.gitlab"}}</span> 102 + <span>{{ctx.Locale.Tr "admin.auths.tip.gitlab_new"}}</span> 103 103 <li>Google</li> 104 104 <span>{{ctx.Locale.Tr "admin.auths.tip.google_plus"}}</span> 105 105 <li>OpenID Connect</li>
+6 -6
templates/admin/emails/list.tmpl
··· 4 4 {{ctx.Locale.Tr "admin.emails.email_manage_panel"}} ({{ctx.Locale.Tr "admin.total" .Total}}) 5 5 </h4> 6 6 <div class="ui attached segment"> 7 - <div class="ui secondary filter menu gt-ac gt-mx-0"> 8 - <form class="ui form ignore-dirty gt-f1"> 7 + <div class="ui secondary filter menu tw-items-center gt-mx-0"> 8 + <form class="ui form ignore-dirty tw-flex-1"> 9 9 {{template "shared/search/combo" dict "Value" .Keyword}} 10 10 </form> 11 11 <!-- Sort --> ··· 15 15 </span> 16 16 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 17 17 <div class="menu"> 18 - <a class="{{if or (eq .SortType "email") (not .SortType)}}active {{end}}item" href="{{$.Link}}?sort=email&q={{$.Keyword}}">{{ctx.Locale.Tr "admin.emails.filter_sort.email"}}</a> 19 - <a class="{{if eq .SortType "reverseemail"}}active {{end}}item" href="{{$.Link}}?sort=reverseemail&q={{$.Keyword}}">{{ctx.Locale.Tr "admin.emails.filter_sort.email_reverse"}}</a> 20 - <a class="{{if eq .SortType "username"}}active {{end}}item" href="{{$.Link}}?sort=username&q={{$.Keyword}}">{{ctx.Locale.Tr "admin.emails.filter_sort.name"}}</a> 21 - <a class="{{if eq .SortType "reverseusername"}}active {{end}}item" href="{{$.Link}}?sort=reverseusername&q={{$.Keyword}}">{{ctx.Locale.Tr "admin.emails.filter_sort.name_reverse"}}</a> 18 + <a class="{{if or (eq .SortType "email") (not .SortType)}}active {{end}}item" href="?sort=email&q={{$.Keyword}}">{{ctx.Locale.Tr "admin.emails.filter_sort.email"}}</a> 19 + <a class="{{if eq .SortType "reverseemail"}}active {{end}}item" href="?sort=reverseemail&q={{$.Keyword}}">{{ctx.Locale.Tr "admin.emails.filter_sort.email_reverse"}}</a> 20 + <a class="{{if eq .SortType "username"}}active {{end}}item" href="?sort=username&q={{$.Keyword}}">{{ctx.Locale.Tr "admin.emails.filter_sort.name"}}</a> 21 + <a class="{{if eq .SortType "reverseusername"}}active {{end}}item" href="?sort=reverseusername&q={{$.Keyword}}">{{ctx.Locale.Tr "admin.emails.filter_sort.name_reverse"}}</a> 22 22 </div> 23 23 </div> 24 24 </div>
+4 -4
templates/admin/notice.tmpl
··· 17 17 <tbody> 18 18 {{range .Notices}} 19 19 <tr> 20 - <td><div class="ui checkbox gt-df" data-id="{{.ID}}"><input type="checkbox"></div></td> 20 + <td><div class="ui checkbox tw-flex" data-id="{{.ID}}"><input type="checkbox"></div></td> 21 21 <td>{{.ID}}</td> 22 22 <td>{{ctx.Locale.Tr .TrStr}}</td> 23 - <td class="view-detail auto-ellipsis" style="width: 80%;"><span class="notice-description">{{.Description}}</span></td> 23 + <td class="view-detail auto-ellipsis tw-w-4/5"><span class="notice-description">{{.Description}}</span></td> 24 24 <td nowrap>{{DateTime "short" .CreatedUnix}}</td> 25 25 <td class="view-detail"><a href="#">{{svg "octicon-note" 16}}</a></td> 26 26 </tr> ··· 49 49 </div> 50 50 </div> 51 51 </div> 52 - <button class="ui small teal button" id="delete-selection" data-link="{{.Link}}/delete" data-redirect="{{.Link}}?page={{.Page.Paginater.Current}}"> 53 - {{ctx.Locale.Tr "admin.notices.delete_selected"}} 52 + <button class="ui small teal button" id="delete-selection" data-link="{{.Link}}/delete" data-redirect="?page={{.Page.Paginater.Current}}"> 53 + <span class="text">{{ctx.Locale.Tr "admin.notices.delete_selected"}}</span> 54 54 </button> 55 55 </th> 56 56 </tr>
+8 -8
templates/admin/org/list.tmpl
··· 7 7 </div> 8 8 </h4> 9 9 <div class="ui attached segment"> 10 - <div class="ui secondary filter menu gt-ac gt-mx-0"> 11 - <form class="ui form ignore-dirty gt-f1"> 10 + <div class="ui secondary filter menu tw-items-center gt-mx-0"> 11 + <form class="ui form ignore-dirty tw-flex-1"> 12 12 {{template "shared/search/combo" dict "Value" .Keyword "Placeholder" (ctx.Locale.Tr "search.org_kind")}} 13 13 </form> 14 14 <!-- Sort --> ··· 18 18 </span> 19 19 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 20 20 <div class="menu"> 21 - <a class="{{if or (eq .SortType "oldest") (not .SortType)}}active {{end}}item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 22 - <a class="{{if eq .SortType "newest"}}active {{end}}item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> 23 - <a class="{{if eq .SortType "alphabetically"}}active {{end}}item" href="{{$.Link}}?sort=alphabetically&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.alphabetically"}}</a> 24 - <a class="{{if eq .SortType "reversealphabetically"}}active {{end}}item" href="{{$.Link}}?sort=reversealphabetically&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.reverse_alphabetically"}}</a> 25 - <a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="{{$.Link}}?sort=recentupdate&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> 26 - <a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="{{$.Link}}?sort=leastupdate&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> 21 + <a class="{{if or (eq .SortType "oldest") (not .SortType)}}active {{end}}item" href="?sort=oldest&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 22 + <a class="{{if eq .SortType "newest"}}active {{end}}item" href="?sort=newest&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> 23 + <a class="{{if eq .SortType "alphabetically"}}active {{end}}item" href="?sort=alphabetically&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.alphabetically"}}</a> 24 + <a class="{{if eq .SortType "reversealphabetically"}}active {{end}}item" href="?sort=reversealphabetically&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.reverse_alphabetically"}}</a> 25 + <a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="?sort=recentupdate&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> 26 + <a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="?sort=leastupdate&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> 27 27 </div> 28 28 </div> 29 29 </div>
+1 -1
templates/admin/queue_manage.tmpl
··· 30 30 - 31 31 {{else}} 32 32 {{$sum}} 33 - <form action="{{$.Link}}/remove-all-items" method="post" class="gt-dib gt-ml-4"> 33 + <form action="{{$.Link}}/remove-all-items" method="post" class="tw-inline-block gt-ml-4"> 34 34 {{$.CsrfTokenHtml}} 35 35 <button class="ui tiny basic red button">{{ctx.Locale.Tr "admin.monitor.queue.settings.remove_all_items"}}</button> 36 36 </form>
+2 -2
templates/admin/repo/unadopted.tmpl
··· 20 20 {{if .Dirs}} 21 21 <div class="ui aligned divided list"> 22 22 {{range $dirI, $dir := .Dirs}} 23 - <div class="item gt-df gt-ac"> 24 - <span class="gt-f1"> {{svg "octicon-file-directory-fill"}} {{$dir}}</span> 23 + <div class="item tw-flex tw-items-center"> 24 + <span class="tw-flex-1"> {{svg "octicon-file-directory-fill"}} {{$dir}}</span> 25 25 <div> 26 26 <button class="ui button primary show-modal gt-p-3" data-modal="#adopt-unadopted-modal-{{$dirI}}">{{svg "octicon-plus"}} {{ctx.Locale.Tr "repo.adopt_preexisting_label"}}</button> 27 27 <div class="ui g-modal-confirm modal" id="adopt-unadopted-modal-{{$dirI}}">
+4 -4
templates/admin/stacktrace-row.tmpl
··· 1 1 <div class="item"> 2 - <div class="gt-df gt-ac"> 2 + <div class="tw-flex tw-items-center"> 3 3 <div class="icon gt-ml-3 gt-mr-3"> 4 4 {{if eq .Process.Type "request"}} 5 5 {{svg "octicon-globe" 16}} ··· 11 11 {{svg "octicon-code" 16}} 12 12 {{end}} 13 13 </div> 14 - <div class="content gt-f1"> 14 + <div class="content tw-flex-1"> 15 15 <div class="header">{{.Process.Description}}</div> 16 16 <div class="description">{{if ne .Process.Type "none"}}{{TimeSince .Process.Start ctx.Locale}}{{end}}</div> 17 17 </div> ··· 40 40 </summary> 41 41 <div class="list"> 42 42 {{range .Entry}} 43 - <div class="item gt-df gt-ac"> 43 + <div class="item tw-flex tw-items-center"> 44 44 <span class="icon gt-mr-4">{{svg "octicon-dot-fill" 16}}</span> 45 - <div class="content gt-f1"> 45 + <div class="content tw-flex-1"> 46 46 <div class="header"><code>{{.Function}}</code></div> 47 47 <div class="description"><code>{{.File}}:{{.Line}}</code></div> 48 48 </div>
+4 -4
templates/admin/stacktrace.tmpl
··· 1 1 {{template "admin/layout_head" (dict "ctxData" . "pageClass" "admin monitor")}} 2 2 <div class="admin-setting-content"> 3 3 4 - <div class="gt-df gt-ac"> 5 - <div class="gt-f1"> 4 + <div class="tw-flex tw-items-center"> 5 + <div class="tw-flex-1"> 6 6 <div class="ui compact small menu"> 7 - <a class="{{if eq .ShowGoroutineList "process"}}active {{end}}item" href="{{.Link}}?show=process">{{ctx.Locale.Tr "admin.monitor.process"}}</a> 8 - <a class="{{if eq .ShowGoroutineList "stacktrace"}}active {{end}}item" href="{{.Link}}?show=stacktrace">{{ctx.Locale.Tr "admin.monitor.stacktrace"}}</a> 7 + <a class="{{if eq .ShowGoroutineList "process"}}active {{end}}item" href="?show=process">{{ctx.Locale.Tr "admin.monitor.process"}}</a> 8 + <a class="{{if eq .ShowGoroutineList "stacktrace"}}active {{end}}item" href="?show=stacktrace">{{ctx.Locale.Tr "admin.monitor.stacktrace"}}</a> 9 9 </div> 10 10 </div> 11 11 <form target="_blank" action="{{AppSubUrl}}/admin/monitor/diagnosis" class="ui form">
+1 -1
templates/admin/user/list.tmpl
··· 103 103 <td><span>{{ctx.Locale.Tr "admin.users.never_login"}}</span></td> 104 104 {{end}} 105 105 <td> 106 - <div class="gt-df gt-gap-3"> 106 + <div class="tw-flex tw-gap-2"> 107 107 <a href="{{$.Link}}/{{.ID}}" data-tooltip-content="{{ctx.Locale.Tr "admin.users.details"}}">{{svg "octicon-person"}}</a> 108 108 <a href="{{$.Link}}/{{.ID}}/edit" data-tooltip-content="{{ctx.Locale.Tr "edit"}}">{{svg "octicon-pencil"}}</a> 109 109 </div>
+2 -2
templates/admin/user/view.tmpl
··· 2 2 3 3 <div class="admin-setting-content"> 4 4 <div class="admin-responsive-columns"> 5 - <div class="gt-f1"> 5 + <div class="tw-flex-1"> 6 6 <h4 class="ui top attached header"> 7 7 {{.Title}} 8 8 <div class="ui right"> ··· 13 13 {{template "admin/user/view_details" .}} 14 14 </div> 15 15 </div> 16 - <div class="gt-f1"> 16 + <div class="tw-flex-1"> 17 17 <h4 class="ui top attached header"> 18 18 {{ctx.Locale.Tr "admin.emails"}} 19 19 <div class="ui right">
+4 -4
templates/base/head_navbar.tmpl
··· 56 56 <div class="navbar-right ui secondary menu"> 57 57 {{if and .IsSigned .MustChangePassword}} 58 58 <div class="ui dropdown jump item" data-tooltip-content="{{ctx.Locale.Tr "user_profile_and_more"}}"> 59 - <span class="text gt-df gt-ac"> 59 + <span class="text tw-flex tw-items-center"> 60 60 {{ctx.AvatarUtils.Avatar .SignedUser 24 "gt-mr-2"}} 61 61 <span class="mobile-only gt-ml-3">{{.SignedUser.Name}}</span> 62 62 <span class="not-mobile">{{svg "octicon-triangle-down"}}</span> ··· 83 83 <span class="mobile-only gt-ml-3">{{ctx.Locale.Tr "active_stopwatch"}}</span> 84 84 </a> 85 85 <div class="active-stopwatch-popup item tippy-target gt-p-3"> 86 - <div class="gt-df gt-ac"> 87 - <a class="stopwatch-link gt-df gt-ac" href="{{.ActiveStopwatch.IssueLink}}"> 86 + <div class="tw-flex tw-items-center"> 87 + <a class="stopwatch-link tw-flex tw-items-center" href="{{.ActiveStopwatch.IssueLink}}"> 88 88 {{svg "octicon-issue-opened" 16 "gt-mr-3"}} 89 89 <span class="stopwatch-issue">{{.ActiveStopwatch.RepoSlug}}#{{.ActiveStopwatch.IssueIndex}}</span> 90 90 <span class="ui primary label stopwatch-time gt-my-0 gt-mx-4" data-seconds="{{.ActiveStopwatch.Seconds}}"> ··· 142 142 </div><!-- end dropdown menu create new --> 143 143 144 144 <div class="ui dropdown jump item gt-mx-0 gt-pr-3" data-tooltip-content="{{ctx.Locale.Tr "user_profile_and_more"}}"> 145 - <span class="text gt-df gt-ac"> 145 + <span class="text tw-flex tw-items-center"> 146 146 {{ctx.AvatarUtils.Avatar .SignedUser 24 "gt-mr-2"}} 147 147 <span class="mobile-only gt-ml-3">{{.SignedUser.Name}}</span> 148 148 <span class="not-mobile">{{svg "octicon-triangle-down"}}</span>
+1 -1
templates/base/paginate.tmpl
··· 17 17 {{if eq .Num -1}} 18 18 <a class="disabled item">...</a> 19 19 {{else}} 20 - <a class="{{if .IsCurrent}}active {{end}}item tw-content-center" {{if not .IsCurrent}}href="{{$paginationLink}}?page={{.Num}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}>{{.Num}}</a> 20 + <a class="{{if .IsCurrent}}active {{end}}item tw-items-center" {{if not .IsCurrent}}href="{{$paginationLink}}?page={{.Num}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}>{{.Num}}</a> 21 21 {{end}} 22 22 {{end}} 23 23 <a class="{{if not .HasNext}}disabled{{end}} item navigation" {{if .HasNext}}href="{{$paginationLink}}?page={{.Next}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}>
+2 -2
templates/devtest/flex-list.tmpl
··· 73 73 </div> 74 74 <div class="flex-item-trailing"> 75 75 <a class="muted" href="{{$.Link}}"> 76 - <span class="flex-text-inline"><i class="color-icon gt-mr-3" style="background-color: aqua"></i>Go</span> 76 + <span class="flex-text-inline"><i class="color-icon gt-mr-3 tw-bg-blue"></i>Go</span> 77 77 </a> 78 78 <a class="text grey flex-text-inline" href="{{$.Link}}">{{svg "octicon-star" 16}}45000</a> 79 79 <a class="text grey flex-text-inline" href="{{$.Link}}">{{svg "octicon-git-branch" 16}}1234</a> ··· 104 104 </div> 105 105 106 106 <h1>If parent provides the padding/margin space:</h1> 107 - <div class="gt-border-secondary gt-py-4"> 107 + <div class="tw-border tw-border-secondary gt-py-4"> 108 108 <div class="flex-list flex-space-fitted"> 109 109 <div class="flex-item">item 1 (no padding top)</div> 110 110 <div class="flex-item">item 2 (no padding bottom)</div>
+1 -1
templates/devtest/fomantic-modal.tmpl
··· 73 73 {{template "base/modal_actions_confirm" (dict "ModalButtonDangerText" "I know and must do this is dangerous operation")}} 74 74 </div> 75 75 76 - <div class="modal-buttons flex-text-block gt-fw"></div> 76 + <div class="modal-buttons flex-text-block tw-flex-wrap"></div> 77 77 <script type="module"> 78 78 for (const el of $('.ui.modal')) { 79 79 const $btn = $('<button>').text(`${el.id}`).on('click', () => {
+2 -2
templates/devtest/gitea-ui.tmpl
··· 95 95 96 96 <div> 97 97 <h1>Loading</h1> 98 - <div class="is-loading small-loading-icon gt-border-secondary gt-py-2"><span>loading ...</span></div> 99 - <div class="is-loading gt-border-secondary gt-py-4"> 98 + <div class="is-loading small-loading-icon tw-border tw-border-secondary gt-py-2"><span>loading ...</span></div> 99 + <div class="is-loading tw-border tw-border-secondary gt-py-4"> 100 100 <p>loading ...</p> 101 101 <p>loading ...</p> 102 102 <p>loading ...</p>
+3 -3
templates/devtest/tmplerr.tmpl
··· 1 1 {{template "base/head" .}} 2 2 <div class="page-content devtest"> 3 - <div class="gt-df"> 4 - <div style="width: 80%; "> 3 + <div class="tw-flex"> 4 + <div class="tw-w-4/5"> 5 5 hello hello hello hello hello hello hello hello hello hello 6 6 </div> 7 - <div style="width: 20%;"> 7 + <div class="tw-w-1/5"> 8 8 {{template "devtest/tmplerr-sub" .}} 9 9 </div> 10 10 </div>
+1 -1
templates/explore/repo_list.tmpl
··· 32 32 </div> 33 33 <div class="flex-item-trailing"> 34 34 {{if .PrimaryLanguage}} 35 - <a class="muted" href="{{$.Link}}?q={{$.Keyword}}&sort={{$.SortType}}&language={{.PrimaryLanguage.Language}}{{if $.TabName}}&tab={{$.TabName}}{{end}}"> 35 + <a class="muted" href="?q={{$.Keyword}}&sort={{$.SortType}}&language={{.PrimaryLanguage.Language}}{{if $.TabName}}&tab={{$.TabName}}{{end}}"> 36 36 <span class="flex-text-inline"><i class="color-icon gt-mr-3" style="background-color: {{.PrimaryLanguage.Color}}"></i>{{.PrimaryLanguage.Language}}</span> 37 37 </a> 38 38 {{end}}
+6 -6
templates/explore/search.tmpl
··· 1 - <div class="ui small secondary filter menu gt-ac gt-mx-0"> 2 - <form class="ui form ignore-dirty gt-f1"> 1 + <div class="ui small secondary filter menu tw-items-center gt-mx-0"> 2 + <form class="ui form ignore-dirty tw-flex-1"> 3 3 {{if .PageIsExploreUsers}} 4 4 {{template "shared/search/combo" dict "Value" .Keyword "Placeholder" (ctx.Locale.Tr "search.user_kind")}} 5 5 {{else}} ··· 13 13 </span> 14 14 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 15 15 <div class="menu"> 16 - <a class="{{if eq .SortType "newest"}}active {{end}}item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> 17 - <a class="{{if eq .SortType "oldest"}}active {{end}}item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 18 - <a class="{{if eq .SortType "alphabetically"}}active {{end}}item" href="{{$.Link}}?sort=alphabetically&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.alphabetically"}}</a> 19 - <a class="{{if eq .SortType "reversealphabetically"}}active {{end}}item" href="{{$.Link}}?sort=reversealphabetically&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.reverse_alphabetically"}}</a> 16 + <a class="{{if eq .SortType "newest"}}active {{end}}item" href="?sort=newest&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> 17 + <a class="{{if eq .SortType "oldest"}}active {{end}}item" href="?sort=oldest&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 18 + <a class="{{if eq .SortType "alphabetically"}}active {{end}}item" href="?sort=alphabetically&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.alphabetically"}}</a> 19 + <a class="{{if eq .SortType "reversealphabetically"}}active {{end}}item" href="?sort=reversealphabetically&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.reverse_alphabetically"}}</a> 20 20 </div> 21 21 </div> 22 22 </div>
+1 -1
templates/explore/user_list.tmpl
··· 1 1 <div class="flex-list"> 2 2 {{range .Users}} 3 - <div class="flex-item gt-ac"> 3 + <div class="flex-item tw-items-center"> 4 4 <div class="flex-item-leading"> 5 5 {{ctx.AvatarUtils.Avatar . 48}} 6 6 </div>
+3 -3
templates/org/header.tmpl
··· 1 - <div class="ui container gt-df"> 1 + <div class="ui container tw-flex"> 2 2 {{ctx.AvatarUtils.Avatar .Org 100 "org-avatar"}} 3 - <div id="org-info" class="gt-df gt-fc"> 3 + <div id="org-info" class="tw-flex tw-flex-col"> 4 4 <div class="ui header"> 5 5 {{.Org.DisplayName}} 6 6 <span class="org-visibility"> 7 7 {{if .Org.Visibility.IsLimited}}<span class="ui large basic horizontal label">{{ctx.Locale.Tr "org.settings.visibility.limited_shortname"}}</span>{{end}} 8 8 {{if .Org.Visibility.IsPrivate}}<span class="ui large basic horizontal label">{{ctx.Locale.Tr "org.settings.visibility.private_shortname"}}</span>{{end}} 9 9 </span> 10 - <span class="gt-df gt-ac gt-gap-2 gt-ml-auto gt-font-16 tw-whitespace-nowrap"> 10 + <span class="tw-flex tw-items-center tw-gap-1 tw-ml-auto tw-text-16 tw-whitespace-nowrap"> 11 11 {{if .EnableFeed}} 12 12 <a class="ui basic label button gt-mr-0" href="{{.Org.HomeLink}}.rss" data-tooltip-content="{{ctx.Locale.Tr "rss_feed"}}"> 13 13 {{svg "octicon-rss" 24}}
+6 -6
templates/org/home.tmpl
··· 30 30 <div class="divider"></div> 31 31 {{end}} 32 32 {{if .NumMembers}} 33 - <h4 class="ui top attached header gt-df"> 34 - <strong class="gt-f1">{{ctx.Locale.Tr "org.members"}}</strong> 35 - <a class="text grey gt-df gt-ac" href="{{.OrgLink}}/members"><span>{{.NumMembers}}</span> {{svg "octicon-chevron-right"}}</a> 33 + <h4 class="ui top attached header tw-flex"> 34 + <strong class="tw-flex-1">{{ctx.Locale.Tr "org.members"}}</strong> 35 + <a class="text grey tw-flex tw-items-center" href="{{.OrgLink}}/members"><span>{{.NumMembers}}</span> {{svg "octicon-chevron-right"}}</a> 36 36 </h4> 37 37 <div class="ui attached segment members"> 38 38 {{$isMember := .IsOrganizationMember}} ··· 44 44 </div> 45 45 {{end}} 46 46 {{if .IsOrganizationMember}} 47 - <div class="ui top attached header gt-df"> 48 - <strong class="gt-f1">{{ctx.Locale.Tr "org.teams"}}</strong> 49 - <a class="text grey gt-df gt-ac" href="{{.OrgLink}}/teams"><span>{{.Org.NumTeams}}</span> {{svg "octicon-chevron-right"}}</a> 47 + <div class="ui top attached header tw-flex"> 48 + <strong class="tw-flex-1">{{ctx.Locale.Tr "org.teams"}}</strong> 49 + <a class="text grey tw-flex tw-items-center" href="{{.OrgLink}}/teams"><span>{{.Org.NumTeams}}</span> {{svg "octicon-chevron-right"}}</a> 50 50 </div> 51 51 <div class="ui attached table segment teams"> 52 52 {{range .Teams}}
+1 -1
templates/org/member/members.tmpl
··· 7 7 <div class="flex-list"> 8 8 {{range .Members}} 9 9 {{$isPublic := index $.MembersIsPublicMember .ID}} 10 - <div class="flex-item {{if $.PublicOnly}}gt-ac{{end}}"> 10 + <div class="flex-item {{if $.PublicOnly}}tw-items-center{{end}}"> 11 11 <div class="flex-item-leading"> 12 12 <a href="{{.HomeLink}}">{{ctx.AvatarUtils.Avatar . 48}}</a> 13 13 </div>
+1 -1
templates/org/settings/blocked_users.tmpl
··· 1 1 {{template "org/settings/layout_head" (dict "ctxData" . "pageClass" "organization settings blocked-users")}} 2 2 <div class="org-setting-content"> 3 3 <div class="ui attached segment"> 4 - <form class="ui form ignore-dirty gt-df gt-fw gt-gap-3" action="{{$.Link}}/block" method="post"> 4 + <form class="ui form ignore-dirty tw-flex tw-flex-wrap tw-gap-2" action="{{$.Link}}/block" method="post"> 5 5 {{.CsrfTokenHtml}} 6 6 <input type="hidden" name="uid" value=""> 7 7 <div class="ui left">
+2 -2
templates/org/settings/labels.tmpl
··· 1 1 {{template "org/settings/layout_head" (dict "ctxData" . "pageClass" "organization settings labels")}} 2 2 <div class="org-setting-content"> 3 - <div class="gt-df gt-ac"> 4 - <div class="gt-f1"> 3 + <div class="tw-flex tw-items-center"> 4 + <div class="tw-flex-1"> 5 5 {{ctx.Locale.Tr "org.settings.labels_desc"}} 6 6 </div> 7 7 <button class="ui small primary new-label button">{{ctx.Locale.Tr "repo.issues.new_label"}}</button>
+3 -3
templates/org/team/members.tmpl
··· 9 9 {{template "org/team/navbar" .}} 10 10 {{if .IsOrganizationOwner}} 11 11 <div class="ui attached segment"> 12 - <form class="ui form ignore-dirty gt-df gt-fw gt-gap-3" action="{{$.OrgLink}}/teams/{{$.Team.LowerName | PathEscape}}/action/add" method="post"> 12 + <form class="ui form ignore-dirty tw-flex tw-flex-wrap tw-gap-2" action="{{$.OrgLink}}/teams/{{$.Team.LowerName | PathEscape}}/action/add" method="post"> 13 13 {{.CsrfTokenHtml}} 14 14 <input type="hidden" name="uid" value="{{.SignedUser.ID}}"> 15 15 <div id="search-user-box" class="ui search gt-mr-3"{{if .IsEmailInviteEnabled}} data-allow-email="true" data-allow-email-description="{{ctx.Locale.Tr "org.teams.invite_team_member" $.Team.Name}}"{{end}}> ··· 24 24 <div class="ui attached segment"> 25 25 <div class="flex-list"> 26 26 {{range .Team.Members}} 27 - <div class="flex-item gt-ac"> 27 + <div class="flex-item tw-items-center"> 28 28 <div class="flex-item-leading"> 29 29 <a href="{{.HomeLink}}">{{ctx.AvatarUtils.Avatar . 32}}</a> 30 30 </div> ··· 56 56 <div class="ui attached segment"> 57 57 <div class="flex-list"> 58 58 {{range .Invites}} 59 - <div class="flex-item gt-ac"> 59 + <div class="flex-item tw-items-center"> 60 60 <div class="flex-item-main"> 61 61 {{.Email}} 62 62 </div>
+3 -3
templates/org/team/new.tmpl
··· 78 78 <tr> 79 79 <th>{{ctx.Locale.Tr "units.unit"}}</th> 80 80 <th class="center aligned">{{ctx.Locale.Tr "org.teams.none_access"}} 81 - <span class="gt-vm" data-tooltip-content="{{ctx.Locale.Tr "org.teams.none_access_helper"}}">{{svg "octicon-question" 16 "gt-ml-2"}}</span></th> 81 + <span class="tw-align-middle" data-tooltip-content="{{ctx.Locale.Tr "org.teams.none_access_helper"}}">{{svg "octicon-question" 16 "gt-ml-2"}}</span></th> 82 82 <th class="center aligned">{{ctx.Locale.Tr "org.teams.read_access"}} 83 - <span class="gt-vm" data-tooltip-content="{{ctx.Locale.Tr "org.teams.read_access_helper"}}">{{svg "octicon-question" 16 "gt-ml-2"}}</span></th> 83 + <span class="tw-align-middle" data-tooltip-content="{{ctx.Locale.Tr "org.teams.read_access_helper"}}">{{svg "octicon-question" 16 "gt-ml-2"}}</span></th> 84 84 <th class="center aligned">{{ctx.Locale.Tr "org.teams.write_access"}} 85 - <span class="gt-vm" data-tooltip-content="{{ctx.Locale.Tr "org.teams.write_access_helper"}}">{{svg "octicon-question" 16 "gt-ml-2"}}</span></th> 85 + <span class="tw-align-middle" data-tooltip-content="{{ctx.Locale.Tr "org.teams.write_access_helper"}}">{{svg "octicon-question" 16 "gt-ml-2"}}</span></th> 86 86 </tr> 87 87 </thead> 88 88 <tbody>
+4 -4
templates/org/team/repositories.tmpl
··· 9 9 {{template "org/team/navbar" .}} 10 10 {{$canAddRemove := and $.IsOrganizationOwner (not $.Team.IncludesAllRepositories)}} 11 11 {{if $canAddRemove}} 12 - <div class="ui attached segment gt-df gt-fw gt-gap-3"> 13 - <form class="ui form ignore-dirty gt-f1 gt-df" action="{{$.OrgLink}}/teams/{{$.Team.LowerName | PathEscape}}/action/repo/add" method="post"> 12 + <div class="ui attached segment tw-flex tw-flex-wrap tw-gap-2"> 13 + <form class="ui form ignore-dirty tw-flex-1 tw-flex" action="{{$.OrgLink}}/teams/{{$.Team.LowerName | PathEscape}}/action/repo/add" method="post"> 14 14 {{.CsrfTokenHtml}} 15 15 <div id="search-repo-box" data-uid="{{.Org.ID}}" class="ui search"> 16 16 <div class="ui input"> ··· 19 19 </div> 20 20 <button class="ui primary button gt-ml-3">{{ctx.Locale.Tr "add"}}</button> 21 21 </form> 22 - <div class="gt-dib"> 22 + <div class="tw-inline-block"> 23 23 <button class="ui primary button link-action" data-modal-confirm="{{ctx.Locale.Tr "org.teams.add_all_repos_desc"}}" data-url="{{$.OrgLink}}/teams/{{$.Team.LowerName | PathEscape}}/action/repo/addall">{{ctx.Locale.Tr "add_all"}}</button> 24 24 <button class="ui red button link-action" data-modal-confirm="{{ctx.Locale.Tr "org.teams.remove_all_repos_desc"}}" data-url="{{$.OrgLink}}/teams/{{$.Team.LowerName | PathEscape}}/action/repo/removeall">{{ctx.Locale.Tr "remove_all"}}</button> 25 25 </div> ··· 28 28 <div class="ui attached segment"> 29 29 <div class="flex-list"> 30 30 {{range .Team.Repos}} 31 - <div class="flex-item gt-ac"> 31 + <div class="flex-item tw-items-center"> 32 32 <div class="flex-item-leading"> 33 33 {{template "repo/icon" .}} 34 34 </div>
+2 -2
templates/package/view.tmpl
··· 90 90 <a class="tw-float-right" href="{{$.PackageDescriptor.PackageWebLink}}/versions">{{ctx.Locale.Tr "packages.versions.view_all"}}</a> 91 91 <div class="ui relaxed list"> 92 92 {{range .LatestVersions}} 93 - <div class="item gt-df"> 94 - <a class="gt-f1 gt-ellipsis" title="{{.Version}}" href="{{$.PackageDescriptor.PackageWebLink}}/{{PathEscape .LowerVersion}}">{{.Version}}</a> 93 + <div class="item tw-flex"> 94 + <a class="tw-flex-1 gt-ellipsis" title="{{.Version}}" href="{{$.PackageDescriptor.PackageWebLink}}/{{PathEscape .LowerVersion}}">{{.Version}}</a> 95 95 <span class="text small">{{DateTime "short" .CreatedUnix}}</span> 96 96 </div> 97 97 {{end}}
+6 -6
templates/projects/list.tmpl
··· 1 1 {{if and $.CanWriteProjects (not $.Repository.IsArchived)}} 2 - <div class="gt-df gt-sb gt-mb-4"> 2 + <div class="tw-flex tw-justify-between gt-mb-4"> 3 3 <div class="small-menu-items ui compact tiny menu list-header-toggle"> 4 - <a class="item{{if not .IsShowClosed}} active{{end}}" href="{{$.Link}}?state=open&q={{$.Keyword}}"> 4 + <a class="item{{if not .IsShowClosed}} active{{end}}" href="?state=open&q={{$.Keyword}}"> 5 5 {{svg "octicon-project-symlink" 16 "gt-mr-3"}} 6 6 {{ctx.Locale.PrettyNumber .OpenCount}}&nbsp;{{ctx.Locale.Tr "repo.issues.open_title"}} 7 7 </a> 8 - <a class="item{{if .IsShowClosed}} active{{end}}" href="{{$.Link}}?state=closed&q={{$.Keyword}}"> 8 + <a class="item{{if .IsShowClosed}} active{{end}}" href="?state=closed&q={{$.Keyword}}"> 9 9 {{svg "octicon-check" 16 "gt-mr-3"}} 10 10 {{ctx.Locale.PrettyNumber .ClosedCount}}&nbsp;{{ctx.Locale.Tr "repo.issues.closed_title"}} 11 11 </a> ··· 31 31 </span> 32 32 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 33 33 <div class="menu"> 34 - <a class="{{if eq .SortType "oldest"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&sort=oldest&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 35 - <a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&sort=recentupdate&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> 36 - <a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&sort=leastupdate&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> 34 + <a class="{{if eq .SortType "oldest"}}active {{end}}item" href="?q={{$.Keyword}}&sort=oldest&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 35 + <a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="?q={{$.Keyword}}&sort=recentupdate&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> 36 + <a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="?q={{$.Keyword}}&sort=leastupdate&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> 37 37 </div> 38 38 </div> 39 39 </div>
+1 -1
templates/projects/view.tmpl
··· 1 1 {{$canWriteProject := and .CanWriteProjects (or (not .Repository) (not .Repository.IsArchived))}} 2 2 3 3 <div class="ui container"> 4 - <div class="gt-df gt-sb gt-ac gt-mb-4"> 4 + <div class="tw-flex tw-justify-between tw-items-center gt-mb-4"> 5 5 <h2 class="gt-mb-0">{{.Project.Title}}</h2> 6 6 {{if $canWriteProject}} 7 7 <div class="ui compact mini menu">
+7 -7
templates/repo/actions/list.tmpl
··· 8 8 <div class="ui stackable grid"> 9 9 <div class="four wide column"> 10 10 <div class="ui fluid vertical menu"> 11 - <a class="item{{if not $.CurWorkflow}} active{{end}}" href="{{$.Link}}?actor={{$.CurActor}}&status={{$.CurStatus}}">{{ctx.Locale.Tr "actions.runs.all_workflows"}}</a> 11 + <a class="item{{if not $.CurWorkflow}} active{{end}}" href="?actor={{$.CurActor}}&status={{$.CurStatus}}">{{ctx.Locale.Tr "actions.runs.all_workflows"}}</a> 12 12 {{range .workflows}} 13 - <a class="item{{if eq .Entry.Name $.CurWorkflow}} active{{end}}" href="{{$.Link}}?workflow={{.Entry.Name}}&actor={{$.CurActor}}&status={{$.CurStatus}}">{{.Entry.Name}} 13 + <a class="item{{if eq .Entry.Name $.CurWorkflow}} active{{end}}" href="?workflow={{.Entry.Name}}&actor={{$.CurActor}}&status={{$.CurStatus}}">{{.Entry.Name}} 14 14 {{if .ErrMsg}} 15 15 <span data-tooltip-content="{{.ErrMsg}}"> 16 16 {{svg "octicon-alert" 16 "text red"}} ··· 25 25 </div> 26 26 </div> 27 27 <div class="twelve wide column content"> 28 - <div class="ui secondary filter menu gt-je gt-df gt-ac"> 28 + <div class="ui secondary filter menu tw-justify-end tw-flex tw-items-center"> 29 29 <!-- Actor --> 30 30 <div class="ui{{if not .Actors}} disabled{{end}} dropdown jump item"> 31 31 <span class="text">{{ctx.Locale.Tr "actions.runs.actor"}}</span> ··· 35 35 <i class="icon">{{svg "octicon-search"}}</i> 36 36 <input type="text" placeholder="{{ctx.Locale.Tr "actions.runs.actor"}}"> 37 37 </div> 38 - <a class="item{{if not $.CurActor}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&status={{$.CurStatus}}&actor=0"> 38 + <a class="item{{if not $.CurActor}} active{{end}}" href="?workflow={{$.CurWorkflow}}&status={{$.CurStatus}}&actor=0"> 39 39 {{ctx.Locale.Tr "actions.runs.actors_no_select"}} 40 40 </a> 41 41 {{range .Actors}} 42 - <a class="item{{if eq .ID $.CurActor}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{.ID}}&status={{$.CurStatus}}"> 42 + <a class="item{{if eq .ID $.CurActor}} active{{end}}" href="?workflow={{$.CurWorkflow}}&actor={{.ID}}&status={{$.CurStatus}}"> 43 43 {{ctx.AvatarUtils.Avatar . 20}} {{.GetDisplayName}} 44 44 </a> 45 45 {{end}} ··· 54 54 <i class="icon">{{svg "octicon-search"}}</i> 55 55 <input type="text" placeholder="{{ctx.Locale.Tr "actions.runs.status"}}"> 56 56 </div> 57 - <a class="item{{if not $.CurStatus}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status=0"> 57 + <a class="item{{if not $.CurStatus}} active{{end}}" href="?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status=0"> 58 58 {{ctx.Locale.Tr "actions.runs.status_no_select"}} 59 59 </a> 60 60 {{range .StatusInfoList}} 61 - <a class="item{{if eq .Status $.CurStatus}} active{{end}}" href="{{$.Link}}?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status={{.Status}}"> 61 + <a class="item{{if eq .Status $.CurStatus}} active{{end}}" href="?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status={{.Status}}"> 62 62 {{.DisplayedStatus}} 63 63 </a> 64 64 {{end}}
+1 -1
templates/repo/actions/runs_list.tmpl
··· 6 6 </div> 7 7 {{end}} 8 8 {{range .Runs}} 9 - <div class="flex-item gt-ac"> 9 + <div class="flex-item tw-items-center"> 10 10 <div class="flex-item-leading"> 11 11 {{template "repo/actions/status" (dict "status" .Status.String)}} 12 12 </div>
+1 -1
templates/repo/actions/status.tmpl
··· 12 12 {{- $className = .className -}} 13 13 {{- end -}} 14 14 15 - <span class="gt-df gt-ac" data-tooltip-content="{{ctx.Locale.Tr (printf "actions.status.%s" .status)}}"> 15 + <span class="tw-flex tw-items-center" data-tooltip-content="{{ctx.Locale.Tr (printf "actions.status.%s" .status)}}"> 16 16 {{if eq .status "success"}} 17 17 {{svg "octicon-check-circle-fill" $size (printf "text green %s" $className)}} 18 18 {{else if eq .status "skipped"}}
+3 -3
templates/repo/blame.tmpl
··· 11 11 {{end}} 12 12 {{end}} 13 13 <div class="{{TabSizeClass .Editorconfig .FileName}} non-diff-file-content"> 14 - <h4 class="file-header ui top attached header gt-df gt-ac gt-sb gt-fw"> 15 - <div class="file-header-left gt-df gt-ac gt-py-3 gt-pr-4"> 14 + <h4 class="file-header ui top attached header tw-flex tw-items-center tw-justify-between tw-flex-wrap"> 15 + <div class="file-header-left tw-flex tw-items-center gt-py-3 gt-pr-4"> 16 16 {{template "repo/file_info" .}} 17 17 </div> 18 - <div class="file-header-right file-actions gt-df gt-ac gt-fw"> 18 + <div class="file-header-right file-actions tw-flex tw-items-center tw-flex-wrap"> 19 19 <div class="ui buttons"> 20 20 <a class="ui tiny button" href="{{$.RawFileLink}}">{{ctx.Locale.Tr "repo.file_raw"}}</a> 21 21 {{if not .IsViewCommit}}
+5 -5
templates/repo/branch/list.tmpl
··· 25 25 <button class="btn interact-fg gt-px-2" data-clipboard-text="{{.DefaultBranchBranch.DBBranch.Name}}">{{svg "octicon-copy" 14}}</button> 26 26 {{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DefaultBranchBranch.DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DefaultBranchBranch.DBBranch.CommitID)}} 27 27 </div> 28 - <p class="info gt-df gt-ac gt-my-2">{{svg "octicon-git-commit" 16 "gt-mr-2"}}<a href="{{.RepoLink}}/commit/{{PathEscape .DefaultBranchBranch.DBBranch.CommitID}}">{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage (.Repository.ComposeMetas ctx)}}</span> · {{ctx.Locale.Tr "org.repo_updated"}} {{TimeSince .DefaultBranchBranch.DBBranch.CommitTime.AsTime ctx.Locale}}{{if .DefaultBranchBranch.DBBranch.Pusher}} &nbsp;{{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}</p> 28 + <p class="info tw-flex tw-items-center gt-my-2">{{svg "octicon-git-commit" 16 "gt-mr-2"}}<a href="{{.RepoLink}}/commit/{{PathEscape .DefaultBranchBranch.DBBranch.CommitID}}">{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage (.Repository.ComposeMetas ctx)}}</span> · {{ctx.Locale.Tr "org.repo_updated"}} {{TimeSince .DefaultBranchBranch.DBBranch.CommitTime.AsTime ctx.Locale}}{{if .DefaultBranchBranch.DBBranch.Pusher}} &nbsp;{{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}</p> 29 29 </td> 30 30 <td class="right aligned middle aligned overflow-visible"> 31 31 {{if and $.IsWriter (not $.Repository.IsArchived) (not .IsDeleted)}} ··· 67 67 </div> 68 68 {{end}} 69 69 70 - <h4 class="ui top attached header gt-df gt-ac gt-sb"> 71 - <div class="gt-df gt-ac"> 70 + <h4 class="ui top attached header tw-flex tw-items-center tw-justify-between"> 71 + <div class="tw-flex tw-items-center"> 72 72 {{ctx.Locale.Tr "repo.branches"}} 73 73 </div> 74 74 </h4> ··· 98 98 <button class="btn interact-fg gt-px-2" data-clipboard-text="{{.DBBranch.Name}}">{{svg "octicon-copy" 14}}</button> 99 99 {{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DBBranch.CommitID)}} 100 100 </div> 101 - <p class="info gt-df gt-ac gt-my-2">{{svg "octicon-git-commit" 16 "gt-mr-2"}}<a href="{{$.RepoLink}}/commit/{{PathEscape .DBBranch.CommitID}}">{{ShortSha .DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DBBranch.CommitMessage ($.Repository.ComposeMetas ctx)}}</span> · {{ctx.Locale.Tr "org.repo_updated"}} {{TimeSince .DBBranch.CommitTime.AsTime ctx.Locale}}{{if .DBBranch.Pusher}} &nbsp;{{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} &nbsp;{{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}</p> 101 + <p class="info tw-flex tw-items-center gt-my-2">{{svg "octicon-git-commit" 16 "gt-mr-2"}}<a href="{{$.RepoLink}}/commit/{{PathEscape .DBBranch.CommitID}}">{{ShortSha .DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DBBranch.CommitMessage ($.Repository.ComposeMetas ctx)}}</span> · {{ctx.Locale.Tr "org.repo_updated"}} {{TimeSince .DBBranch.CommitTime.AsTime ctx.Locale}}{{if .DBBranch.Pusher}} &nbsp;{{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} &nbsp;{{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}</p> 102 102 {{end}} 103 103 </td> 104 104 <td class="two wide ui"> ··· 134 134 </a> 135 135 {{end}} 136 136 {{else}} 137 - <a href="{{.LatestPullRequest.Issue.Link}}" class="gt-vm ref-issue">{{if not .LatestPullRequest.IsSameRepo}}{{.LatestPullRequest.BaseRepo.FullName}}{{end}}#{{.LatestPullRequest.Issue.Index}}</a> 137 + <a href="{{.LatestPullRequest.Issue.Link}}" class="tw-align-middle ref-issue">{{if not .LatestPullRequest.IsSameRepo}}{{.LatestPullRequest.BaseRepo.FullName}}{{end}}#{{.LatestPullRequest.Issue.Index}}</a> 138 138 {{if .LatestPullRequest.HasMerged}} 139 139 <a href="{{.LatestPullRequest.Issue.Link}}" class="ui purple large label">{{svg "octicon-git-merge" 16 "gt-mr-2"}}{{ctx.Locale.Tr "repo.pulls.merged"}}</a> 140 140 {{else if .LatestPullRequest.Issue.IsClosed}}
+2 -2
templates/repo/branch_dropdown.tmpl
··· 70 70 <div class="js-branch-tag-selector {{if .ContainerClasses}}{{.ContainerClasses}}{{end}}"> 71 71 {{/* show dummy elements before Vue componment is mounted, this code must match the code in BranchTagSelector.vue */}} 72 72 <div class="ui dropdown custom"> 73 - <button class="branch-dropdown-button gt-ellipsis ui basic small compact button gt-df gt-m-0"> 74 - <span class="text gt-df gt-ac gt-mr-2"> 73 + <button class="branch-dropdown-button gt-ellipsis ui basic small compact button tw-flex gt-m-0"> 74 + <span class="text tw-flex tw-items-center gt-mr-2"> 75 75 {{if .release}} 76 76 {{ctx.Locale.Tr "repo.release.compare"}} 77 77 {{else}}
+3 -3
templates/repo/clone_buttons.tmpl
··· 1 1 <!-- there is always at least one button (by context/repo.go) --> 2 2 {{if $.CloneButtonShowHTTPS}} 3 - <button class="ui small compact clone button" id="repo-clone-https" data-link="{{$.CloneButtonOriginLink.HTTPS}}"> 3 + <button class="ui small button" id="repo-clone-https" data-link="{{$.CloneButtonOriginLink.HTTPS}}"> 4 4 HTTPS 5 5 </button> 6 6 {{end}} 7 7 {{if $.CloneButtonShowSSH}} 8 - <button class="ui small compact clone button" id="repo-clone-ssh" data-link="{{$.CloneButtonOriginLink.SSH}}"> 8 + <button class="ui small button" id="repo-clone-ssh" data-link="{{$.CloneButtonOriginLink.SSH}}"> 9 9 SSH 10 10 </button> 11 11 {{end}} 12 12 <input id="repo-clone-url" size="20" class="js-clone-url" value="{{$.CloneButtonOriginLink.HTTPS}}" readonly> 13 - <button class="ui basic small compact icon button" id="clipboard-btn" data-tooltip-content="{{ctx.Locale.Tr "copy_url"}}" data-clipboard-target="#repo-clone-url" aria-label="{{ctx.Locale.Tr "copy_url"}}"> 13 + <button class="ui small icon button" id="clipboard-btn" data-tooltip-content="{{ctx.Locale.Tr "copy_url"}}" data-clipboard-target="#repo-clone-url" aria-label="{{ctx.Locale.Tr "copy_url"}}"> 14 14 {{svg "octicon-copy" 14}} 15 15 </button>
+2 -2
templates/repo/code/recently_pushed_new_branches.tmpl
··· 1 1 {{range .RecentlyPushedNewBranches}} 2 - <div class="ui positive message gt-df gt-ac"> 3 - <div class="gt-f1"> 2 + <div class="ui positive message tw-flex tw-items-center"> 3 + <div class="tw-flex-1"> 4 4 {{$timeSince := TimeSince .CommitTime.AsTime ctx.Locale}} 5 5 {{$repo := .GetRepo $.Context}} 6 6 {{$name := .Name}}
+4 -4
templates/repo/commit_load_branches_and_tags.tmpl
··· 7 7 <div class="branch-and-tag-detail gt-hidden"> 8 8 <div class="divider"></div> 9 9 <div>{{ctx.Locale.Tr "repo.commit.contained_in"}}</div> 10 - <div class="gt-df gt-mt-3"> 10 + <div class="tw-flex gt-mt-3"> 11 11 <div class="gt-p-2">{{svg "octicon-git-branch"}}</div> 12 - <div class="branch-area flex-text-block gt-fw gt-f1"></div> 12 + <div class="branch-area flex-text-block tw-flex-wrap tw-flex-1"></div> 13 13 </div> 14 - <div class="gt-df gt-mt-3"> 14 + <div class="tw-flex gt-mt-3"> 15 15 <div class="gt-p-2">{{svg "octicon-tag"}}</div> 16 - <div class="tag-area flex-text-block gt-fw gt-f1"></div> 16 + <div class="tag-area flex-text-block tw-flex-wrap tw-flex-1"></div> 17 17 </div> 18 18 </div> 19 19 </div>
+8 -8
templates/repo/commit_page.tmpl
··· 18 18 {{end}} 19 19 {{end}} 20 20 <div class="ui top attached header clearing segment tw-relative commit-header {{$class}}"> 21 - <div class="gt-df gt-mb-4 gt-fw"> 22 - <h3 class="gt-mb-0 gt-f1"><span class="commit-summary" title="{{.Commit.Summary}}">{{RenderCommitMessage $.Context .Commit.Message ($.Repository.ComposeMetas ctx)}}</span>{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses}}</h3> 21 + <div class="tw-flex gt-mb-4 tw-flex-wrap"> 22 + <h3 class="gt-mb-0 tw-flex-1"><span class="commit-summary" title="{{.Commit.Summary}}">{{RenderCommitMessage $.Context .Commit.Message ($.Repository.ComposeMetas ctx)}}</span>{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses}}</h3> 23 23 {{if not $.PageIsWiki}} 24 24 <div> 25 25 <a class="ui primary tiny button" href="{{.SourcePath}}"> ··· 139 139 {{end}} 140 140 {{template "repo/commit_load_branches_and_tags" .}} 141 141 </div> 142 - <div class="ui attached segment gt-df gt-ac gt-sb gt-py-2 commit-header-row gt-fw {{$class}}"> 143 - <div class="gt-df gt-ac author"> 142 + <div class="ui attached segment tw-flex tw-items-center tw-justify-between gt-py-2 commit-header-row tw-flex-wrap {{$class}}"> 143 + <div class="tw-flex tw-items-center author"> 144 144 {{if .Author}} 145 145 {{ctx.AvatarUtils.Avatar .Author 28 "gt-mr-3"}} 146 146 {{if .Author.FullName}} ··· 164 164 {{end}} 165 165 {{end}} 166 166 </div> 167 - <div class="ui horizontal list gt-df gt-ac"> 167 + <div class="ui horizontal list tw-flex tw-items-center"> 168 168 {{if .Parents}} 169 169 <div class="item"> 170 170 <span>{{ctx.Locale.Tr "repo.diff.parent"}}</span> ··· 184 184 </div> 185 185 </div> 186 186 {{if .Commit.Signature}} 187 - <div class="ui bottom attached message tw-text-left gt-df gt-ac gt-sb commit-header-row gt-fw gt-mb-0 {{$class}}"> 188 - <div class="gt-df gt-ac"> 187 + <div class="ui bottom attached message tw-text-left tw-flex tw-items-center tw-justify-between commit-header-row tw-flex-wrap gt-mb-0 {{$class}}"> 188 + <div class="tw-flex tw-items-center"> 189 189 {{if .Verification.Verified}} 190 190 {{if ne .Verification.SigningUser.ID 0}} 191 191 {{svg "gitea-lock" 16 "gt-mr-3"}} ··· 209 209 <span class="ui text">{{ctx.Locale.Tr .Verification.Reason}}</span> 210 210 {{end}} 211 211 </div> 212 - <div class="gt-df gt-ac"> 212 + <div class="tw-flex tw-items-center"> 213 213 {{if .Verification.Verified}} 214 214 {{if ne .Verification.SigningUser.ID 0}} 215 215 {{svg "octicon-verified" 16 "gt-mr-3"}}
+2 -2
templates/repo/commit_statuses.tmpl
··· 1 1 {{if .Statuses}} 2 2 {{if and (eq (len .Statuses) 1) .Status.TargetURL}} 3 - <a class="gt-vm {{.AdditionalClasses}} tw-no-underline" data-tippy="commit-statuses" href="{{.Status.TargetURL}}"> 3 + <a class="tw-align-middle {{.AdditionalClasses}} tw-no-underline" data-tippy="commit-statuses" href="{{.Status.TargetURL}}"> 4 4 {{template "repo/commit_status" .Status}} 5 5 </a> 6 6 {{else}} 7 - <span class="gt-vm {{.AdditionalClasses}}" data-tippy="commit-statuses" tabindex="0"> 7 + <span class="tw-align-middle {{.AdditionalClasses}}" data-tippy="commit-statuses" tabindex="0"> 8 8 {{template "repo/commit_status" .Status}} 9 9 </span> 10 10 {{end}}
+1 -1
templates/repo/commits.tmpl
··· 4 4 <div class="ui container"> 5 5 {{template "repo/sub_menu" .}} 6 6 <div class="repo-button-row"> 7 - <div class="gt-df gt-ac"> 7 + <div class="tw-flex tw-items-center"> 8 8 {{template "repo/branch_dropdown" dict "root" . "ContainerClasses" "gt-mr-2"}} 9 9 <a href="{{.RepoLink}}/graph" class="ui basic small compact button"> 10 10 {{svg "octicon-git-branch"}}
+1 -1
templates/repo/commits_list_small.tmpl
··· 13 13 14 14 {{$commitLink:= printf "%s/commit/%s" $.comment.Issue.PullRequest.BaseRepo.Link (PathEscape .ID.String)}} 15 15 16 - <span class="shabox gt-df gt-ac tw-float-right"> 16 + <span class="shabox tw-flex tw-items-center tw-float-right"> 17 17 {{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses}} 18 18 {{$class := "ui sha label"}} 19 19 {{if .Signature}}
+2 -2
templates/repo/commits_table.tmpl
··· 1 - <h4 class="ui top attached header commits-table gt-df gt-ac gt-sb"> 2 - <div class="commits-table-left gt-df gt-ac"> 1 + <h4 class="ui top attached header commits-table tw-flex tw-items-center tw-justify-between"> 2 + <div class="commits-table-left tw-flex tw-items-center"> 3 3 {{if or .PageIsCommits (gt .CommitCount 0)}} 4 4 {{.CommitCount}} {{ctx.Locale.Tr "repo.commits.commits"}} 5 5 {{else if .IsNothingToCompare}}
+2 -2
templates/repo/diff/blob_excerpt.tmpl
··· 3 3 <tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}"> 4 4 {{if eq .GetType 4}} 5 5 <td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"> 6 - <div class="gt-df"> 6 + <div class="tw-flex"> 7 7 {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}} 8 8 <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=split&direction=down&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}"> 9 9 {{svg "octicon-fold-down"}} ··· 49 49 <tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}"> 50 50 {{if eq .GetType 4}} 51 51 <td colspan="2" class="lines-num"> 52 - <div class="gt-df"> 52 + <div class="tw-flex"> 53 53 {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}} 54 54 <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?data-query={{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}"> 55 55 {{svg "octicon-fold-down"}}
+12 -12
templates/repo/diff/box.tmpl
··· 1 1 {{$showFileTree := (and (not .DiffNotAvailable) (gt .Diff.NumFiles 1))}} 2 2 <div> 3 3 <div class="diff-detail-box diff-box"> 4 - <div class="gt-df gt-ac gt-fw gt-gap-3 gt-ml-1"> 4 + <div class="tw-flex tw-items-center tw-flex-wrap tw-gap-2 gt-ml-1"> 5 5 {{if $showFileTree}} 6 6 <button class="diff-toggle-file-tree-button not-mobile btn interact-fg" data-show-text="{{ctx.Locale.Tr "repo.diff.show_file_tree"}}" data-hide-text="{{ctx.Locale.Tr "repo.diff.hide_file_tree"}}"> 7 7 {{/* the icon meaning is reversed here, "octicon-sidebar-collapse" means show the file tree */}} ··· 18 18 </script> 19 19 {{end}} 20 20 {{if not .DiffNotAvailable}} 21 - <div class="diff-detail-stats gt-df gt-ac gt-fw"> 21 + <div class="diff-detail-stats tw-flex tw-items-center tw-flex-wrap"> 22 22 {{svg "octicon-diff" 16 "gt-mr-2"}}{{ctx.Locale.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion}} 23 23 </div> 24 24 {{end}} 25 25 </div> 26 26 <div class="diff-detail-actions"> 27 27 {{if and .PageIsPullFiles $.SignedUserID (not .IsArchived) (not .DiffNotAvailable)}} 28 - <div class="not-mobile gt-df gt-ac gt-fc tw-whitespace-nowrap gt-mr-2"> 28 + <div class="not-mobile tw-flex tw-items-center tw-flex-col tw-whitespace-nowrap gt-mr-2"> 29 29 <label for="viewed-files-summary" id="viewed-files-summary-label" data-text-changed-template="{{ctx.Locale.Tr "repo.pulls.viewed_files_label"}}"> 30 30 {{ctx.Locale.Tr "repo.pulls.viewed_files_label" .Diff.NumViewedFiles .Diff.NumFiles}} 31 31 </label> ··· 68 68 binaryFileMessage: "{{ctx.Locale.Tr "repo.diff.bin"}}", 69 69 showMoreMessage: "{{ctx.Locale.Tr "repo.diff.show_more"}}", 70 70 statisticsMessage: "{{ctx.Locale.Tr "repo.diff.stats_desc_file"}}", 71 - linkLoadMore: "{{$.Link}}?skip-to={{.Diff.End}}&file-only=true", 71 + linkLoadMore: "?skip-to={{.Diff.End}}&file-only=true", 72 72 }; 73 73 74 74 // for first time loading, the diffFileInfo is a plain object ··· 110 110 {{$isExpandable := or (gt $file.Addition 0) (gt $file.Deletion 0) $file.IsBin}} 111 111 {{$isReviewFile := and $.IsSigned $.PageIsPullFiles (not $.IsArchived) $.IsShowingAllCommits}} 112 112 <div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}} gt-mt-0" id="diff-{{$file.NameHash}}" data-old-filename="{{$file.OldName}}" data-new-filename="{{$file.Name}}" {{if or ($file.ShouldBeHidden) (not $isExpandable)}}data-folded="true"{{end}}> 113 - <h4 class="diff-file-header sticky-2nd-row ui top attached normal header gt-df gt-ac gt-sb gt-fw"> 114 - <div class="diff-file-name gt-df gt-ac gt-gap-2 gt-fw"> 113 + <h4 class="diff-file-header sticky-2nd-row ui top attached normal header tw-flex tw-items-center tw-justify-between tw-flex-wrap"> 114 + <div class="diff-file-name tw-flex tw-items-center tw-gap-1 tw-flex-wrap"> 115 115 <button class="fold-file btn interact-bg gt-p-2{{if not $isExpandable}} tw-invisible{{end}}"> 116 116 {{if $file.ShouldBeHidden}} 117 117 {{svg "octicon-chevron-right" 18}} ··· 119 119 {{svg "octicon-chevron-down" 18}} 120 120 {{end}} 121 121 </button> 122 - <div class="gt-font-semibold gt-df gt-ac gt-mono"> 122 + <div class="tw-font-semibold tw-flex tw-items-center gt-mono"> 123 123 {{if $file.IsBin}} 124 124 <span class="gt-ml-1 gt-mr-3"> 125 125 {{ctx.Locale.Tr "repo.diff.bin"}} ··· 144 144 <span class="gt-ml-4 gt-mono">{{ctx.Locale.Tr ($file.ModeTranslationKey $file.Mode)}}</span> 145 145 {{end}} 146 146 </div> 147 - <div class="diff-file-header-actions gt-df gt-ac gt-gap-2 gt-fw"> 147 + <div class="diff-file-header-actions tw-flex tw-items-center tw-gap-1 tw-flex-wrap"> 148 148 {{if $showFileViewToggle}} 149 149 <div class="ui compact icon buttons"> 150 150 <button class="ui tiny basic button file-view-toggle" data-toggle-selector="#diff-source-{{$file.NameHash}}" data-tooltip-content="{{ctx.Locale.Tr "repo.file_view_source"}}">{{svg "octicon-code"}}</button> ··· 181 181 <div class="diff-file-body ui attached unstackable table segment" {{if and $file.IsViewed $.IsShowingAllCommits}}data-folded="true"{{end}}> 182 182 <div id="diff-source-{{$file.NameHash}}" class="file-body file-code unicode-escaped code-diff{{if $.IsSplitStyle}} code-diff-split{{else}} code-diff-unified{{end}}{{if $showFileViewToggle}} gt-hidden{{end}}"> 183 183 {{if or $file.IsIncomplete $file.IsBin}} 184 - <div class="diff-file-body binary" style="padding: 5px 10px;"> 184 + <div class="diff-file-body binary"> 185 185 {{if $file.IsIncomplete}} 186 186 {{if $file.IsIncompleteLineTooLong}} 187 187 {{ctx.Locale.Tr "repo.diff.file_suppressed_line_too_long"}} 188 188 {{else}} 189 189 {{ctx.Locale.Tr "repo.diff.file_suppressed"}} 190 - <a class="ui basic tiny button diff-load-button" data-href="{{$.Link}}?file-only=true&files={{$file.Name}}&files={{$file.OldName}}">{{ctx.Locale.Tr "repo.diff.load"}}</a> 190 + <a class="ui basic tiny button diff-load-button" data-href="?file-only=true&files={{$file.Name}}&files={{$file.OldName}}">{{ctx.Locale.Tr "repo.diff.load"}}</a> 191 191 {{end}} 192 192 {{else}} 193 193 {{ctx.Locale.Tr "repo.diff.bin_not_shown"}} ··· 221 221 222 222 {{if .Diff.IsIncomplete}} 223 223 <div class="diff-file-box diff-box file-content gt-mt-3" id="diff-incomplete"> 224 - <h4 class="ui top attached normal header gt-df gt-ac gt-sb"> 224 + <h4 class="ui top attached normal header tw-flex tw-items-center tw-justify-between"> 225 225 {{ctx.Locale.Tr "repo.diff.too_many_files"}} 226 - <a class="ui basic tiny button" id="diff-show-more-files" data-href="{{$.Link}}?skip-to={{.Diff.End}}&file-only=true">{{ctx.Locale.Tr "repo.diff.show_more"}}</a> 226 + <a class="ui basic tiny button" id="diff-show-more-files" data-href="?skip-to={{.Diff.End}}&file-only=true">{{ctx.Locale.Tr "repo.diff.show_more"}}</a> 227 227 </h4> 228 228 </div> 229 229 {{end}}
+4 -4
templates/repo/diff/comments.tmpl
··· 8 8 {{template "shared/user/avatarlink" dict "user" .Poster}} 9 9 {{end}} 10 10 <div class="content comment-container"> 11 - <div class="ui top attached header comment-header gt-df gt-ac gt-sb"> 12 - <div class="comment-header-left gt-df gt-ac"> 11 + <div class="ui top attached header comment-header tw-flex tw-items-center tw-justify-between"> 12 + <div class="comment-header-left tw-flex tw-items-center"> 13 13 {{if .OriginalAuthor}} 14 - <span class="text black gt-font-semibold gt-mr-2"> 14 + <span class="text black tw-font-semibold gt-mr-2"> 15 15 {{svg (MigrationIcon $.root.Repository.GetOriginalURLHostname)}} 16 16 {{.OriginalAuthor}} 17 17 </span> ··· 30 30 </span> 31 31 {{end}} 32 32 </div> 33 - <div class="comment-header-right actions gt-df gt-ac"> 33 + <div class="comment-header-right actions tw-flex tw-items-center"> 34 34 {{if .Invalidated}} 35 35 {{$referenceUrl := printf "%s#%s" $.root.Issue.Link .HashTag}} 36 36 <a href="{{AppSubUrl}}{{$referenceUrl}}" class="ui label basic small" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.review.outdated_description"}}">
+6 -6
templates/repo/diff/conversation.tmpl
··· 5 5 {{$referenceUrl := printf "%s#%s" $.Issue.Link (index .comments 0).HashTag}} 6 6 <div class="conversation-holder" data-path="{{(index .comments 0).TreePath}}" data-side="{{if lt (index .comments 0).Line 0}}left{{else}}right{{end}}" data-idx="{{(index .comments 0).UnsignedLine}}"> 7 7 {{if $resolved}} 8 - <div class="ui attached header resolved-placeholder gt-df gt-ac gt-sb"> 9 - <div class="ui grey text gt-df gt-ac gt-fw gt-gap-2"> 8 + <div class="ui attached header resolved-placeholder tw-flex tw-items-center tw-justify-between"> 9 + <div class="ui grey text tw-flex tw-items-center tw-flex-wrap tw-gap-1"> 10 10 {{svg "octicon-check" 16 "icon gt-mr-2"}} 11 11 <b>{{$resolveDoer.Name}}</b> {{ctx.Locale.Tr "repo.issues.review.resolved_by"}} 12 12 {{if $invalid}} ··· 19 19 </a> 20 20 {{end}} 21 21 </div> 22 - <div class="gt-df gt-ac gt-gap-3"> 23 - <button id="show-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="ui tiny labeled button show-outdated gt-df gt-ac"> 22 + <div class="tw-flex tw-items-center tw-gap-2"> 23 + <button id="show-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="ui tiny labeled button show-outdated tw-flex tw-items-center"> 24 24 {{svg "octicon-unfold" 16 "gt-mr-3"}} 25 25 {{ctx.Locale.Tr "repo.issues.review.show_resolved"}} 26 26 </button> 27 - <button id="hide-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="ui tiny labeled button hide-outdated gt-df gt-ac gt-hidden"> 27 + <button id="hide-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="ui tiny labeled button hide-outdated tw-flex tw-items-center gt-hidden"> 28 28 {{svg "octicon-fold" 16 "gt-mr-3"}} 29 29 {{ctx.Locale.Tr "repo.issues.review.hide_resolved"}} 30 30 </button> ··· 37 37 {{template "repo/diff/comments" dict "root" $ "comments" .comments}} 38 38 </ui> 39 39 </div> 40 - <div class="gt-df gt-je gt-ac gt-fw gt-mt-3"> 40 + <div class="tw-flex tw-justify-end tw-items-center tw-flex-wrap gt-mt-3"> 41 41 <div class="ui buttons gt-mr-2"> 42 42 <button class="ui icon tiny basic button previous-conversation"> 43 43 {{svg "octicon-arrow-up" 12 "icon"}} {{ctx.Locale.Tr "repo.issues.previous"}}
+5 -5
templates/repo/diff/new_review.tmpl
··· 1 1 <div id="review-box"> 2 - <button class="ui tiny primary button gt-pr-2 gt-df js-btn-review {{if not $.IsShowingAllCommits}}disabled{{end}}" {{if not $.IsShowingAllCommits}}data-tooltip-content="{{ctx.Locale.Tr "repo.pulls.review_only_possible_for_full_diff"}}"{{end}}> 2 + <button class="ui tiny primary button gt-pr-2 tw-flex js-btn-review {{if not $.IsShowingAllCommits}}disabled{{end}}" {{if not $.IsShowingAllCommits}}data-tooltip-content="{{ctx.Locale.Tr "repo.pulls.review_only_possible_for_full_diff"}}"{{end}}> 3 3 {{ctx.Locale.Tr "repo.diff.review"}} 4 4 <span class="ui small label review-comments-counter" data-pending-comment-number="{{.PendingCodeCommentNumber}}">{{.PendingCodeCommentNumber}}</span> 5 5 {{svg "octicon-triangle-down" 14 "dropdown icon"}} ··· 10 10 <form class="ui form form-fetch-action" action="{{.Link}}/reviews/submit" method="post"> 11 11 {{.CsrfTokenHtml}} 12 12 <input type="hidden" name="commit_id" value="{{.AfterCommitID}}"> 13 - <div class="field gt-df gt-ac"> 14 - <div class="gt-f1">{{ctx.Locale.Tr "repo.diff.review.header"}}</div> 13 + <div class="field tw-flex tw-items-center"> 14 + <div class="tw-flex-1">{{ctx.Locale.Tr "repo.diff.review.header"}}</div> 15 15 <a class="muted close">{{svg "octicon-x" 16}}</a> 16 16 </div> 17 17 <div class="field"> ··· 31 31 <div class="divider"></div> 32 32 {{$showSelfTooltip := (and $.IsSigned ($.Issue.IsPoster $.SignedUser.ID))}} 33 33 {{if $showSelfTooltip}} 34 - <span class="gt-dib" data-tooltip-content="{{ctx.Locale.Tr "repo.diff.review.self_approve"}}"> 34 + <span class="tw-inline-block" data-tooltip-content="{{ctx.Locale.Tr "repo.diff.review.self_approve"}}"> 35 35 <button type="submit" name="type" value="approve" disabled class="ui submit primary tiny button btn-submit">{{ctx.Locale.Tr "repo.diff.review.approve"}}</button> 36 36 </span> 37 37 {{else}} ··· 39 39 {{end}} 40 40 <button type="submit" name="type" value="comment" class="ui submit tiny basic button btn-submit">{{ctx.Locale.Tr "repo.diff.review.comment"}}</button> 41 41 {{if $showSelfTooltip}} 42 - <span class="gt-dib" data-tooltip-content="{{ctx.Locale.Tr "repo.diff.review.self_reject"}}"> 42 + <span class="tw-inline-block" data-tooltip-content="{{ctx.Locale.Tr "repo.diff.review.self_reject"}}"> 43 43 <button type="submit" name="type" value="reject" disabled class="ui submit red tiny button btn-submit">{{ctx.Locale.Tr "repo.diff.review.reject"}}</button> 44 44 </span> 45 45 {{else}}
+1 -1
templates/repo/diff/section_split.tmpl
··· 16 16 <tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}" data-line-type="{{.GetHTMLDiffLineType}}"> 17 17 {{if eq .GetType 4}} 18 18 <td class="lines-num lines-num-old"> 19 - <div class="gt-df"> 19 + <div class="tw-flex"> 20 20 {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}} 21 21 <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=split&direction=down&wiki={{$.root.PageIsWiki}}&anchor=diff-{{$file.NameHash}}K{{$line.SectionInfo.RightIdx}}"> 22 22 {{svg "octicon-fold-down"}}
+1 -1
templates/repo/diff/section_unified.tmpl
··· 12 12 {{if eq .GetType 4}} 13 13 {{if $.root.AfterCommitID}} 14 14 <td colspan="2" class="lines-num"> 15 - <div class="gt-df"> 15 + <div class="tw-flex"> 16 16 {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}} 17 17 <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.root.RepoLink}}/blob_excerpt/{{PathEscape $.root.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.root.PageIsWiki}}&anchor=diff-{{$file.NameHash}}K{{$line.SectionInfo.RightIdx}}"> 18 18 {{svg "octicon-fold-down"}}
+1 -1
templates/repo/empty.tmpl
··· 37 37 </a> 38 38 {{end}} 39 39 {{end}} 40 - <div class="ui action small input gt-df gt-f1"> 40 + <div class="clone-panel ui action small input tw-flex-1"> 41 41 {{template "repo/clone_buttons" .}} 42 42 </div> 43 43 </div>
+2 -2
templates/repo/find/files.tmpl
··· 2 2 <div role="main" aria-label="{{.Title}}" class="page-content repository"> 3 3 {{template "repo/header" .}} 4 4 <div class="ui container"> 5 - <div class="gt-df gt-ac"> 5 + <div class="tw-flex tw-items-center"> 6 6 <a href="{{$.RepoLink}}">{{.RepoName}}</a> 7 7 <span class="gt-mx-3">/</span> 8 - <div class="ui input gt-f1"> 8 + <div class="ui input tw-flex-1"> 9 9 <input id="repo-file-find-input" type="text" autofocus data-url-data-link="{{.DataLink}}" data-url-tree-link="{{.TreeLink}}"> 10 10 </div> 11 11 </div>
+1 -1
templates/repo/forks.tmpl
··· 6 6 {{ctx.Locale.Tr "repo.forks"}} 7 7 </h2> 8 8 {{range .Forks}} 9 - <div class="gt-df gt-ac gt-py-3"> 9 + <div class="tw-flex tw-items-center gt-py-3"> 10 10 <span class="gt-mr-2">{{ctx.AvatarUtils.Avatar .Owner}}</span> 11 11 <a href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a> / <a href="{{.Link}}">{{.Name}}</a> 12 12 </div>
+1 -1
templates/repo/graph.tmpl
··· 50 50 </div> 51 51 </h2> 52 52 <div class="ui dividing"></div> 53 - <div class="ui segment loading gt-hidden" id="loading-indicator"></div> 53 + <div class="is-loading tw-py-32 gt-hidden" id="loading-indicator"></div> 54 54 {{template "repo/graph/svgcontainer" .}} 55 55 {{template "repo/graph/commits" .}} 56 56 </div>
+4 -4
templates/repo/graph/commits.tmpl
··· 28 28 {{- end -}} 29 29 </a> 30 30 </span> 31 - <span class="message gt-dib gt-ellipsis gt-mr-3"> 31 + <span class="message tw-inline-block gt-ellipsis gt-mr-3"> 32 32 <span>{{RenderCommitMessage $.Context $commit.Subject ($.Repository.ComposeMetas ctx)}}</span> 33 33 </span> 34 - <span class="commit-refs gt-df gt-ac gt-mr-2"> 34 + <span class="commit-refs tw-flex tw-items-center gt-mr-2"> 35 35 {{range $commit.Refs}} 36 36 {{$refGroup := .RefGroup}} 37 37 {{if eq $refGroup "pull"}} ··· 58 58 {{end}} 59 59 {{end}} 60 60 </span> 61 - <span class="author gt-df gt-ac gt-mr-3"> 61 + <span class="author tw-flex tw-items-center gt-mr-3"> 62 62 {{$userName := $commit.Commit.Author.Name}} 63 63 {{if $commit.User}} 64 64 {{if $commit.User.FullName}} ··· 71 71 {{$userName}} 72 72 {{end}} 73 73 </span> 74 - <span class="time gt-df gt-ac">{{DateTime "full" $commit.Date}}</span> 74 + <span class="time tw-flex tw-items-center">{{DateTime "full" $commit.Date}}</span> 75 75 {{end}} 76 76 </li> 77 77 {{end}}
+3 -3
templates/repo/header.tmpl
··· 2 2 {{with .Repository}} 3 3 <div class="ui container"> 4 4 <div class="repo-header"> 5 - <div class="flex-item gt-ac"> 5 + <div class="flex-item tw-items-center"> 6 6 <div class="flex-item-leading">{{template "repo/icon" .}}</div> 7 7 <div class="flex-item-main"> 8 - <div class="flex-item-title gt-font-18"> 9 - <a class="muted gt-font-normal" href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a>/ 8 + <div class="flex-item-title tw-text-18"> 9 + <a class="muted tw-font-normal" href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a>/ 10 10 <a class="muted" href="{{$.RepoLink}}">{{.Name}}</a></div> 11 11 </div> 12 12 <div class="flex-item-trailing">
+11 -11
templates/repo/home.tmpl
··· 6 6 {{template "repo/code/recently_pushed_new_branches" .}} 7 7 {{if and (not .HideRepoInfo) (not .IsBlame)}} 8 8 <div class="ui repo-description gt-word-break"> 9 - <div id="repo-desc" class="gt-font-16"> 9 + <div id="repo-desc" class="tw-text-16"> 10 10 {{$description := .Repository.DescriptionHTML $.Context}} 11 11 {{if $description}}<span class="description">{{$description | RenderCodeBlock}}</span>{{else if .IsRepositoryAdmin}}<span class="no-description text-italic">{{ctx.Locale.Tr "repo.no_desc"}}</span>{{end}} 12 12 <a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a> ··· 27 27 </form> 28 28 </div> 29 29 </div> 30 - <div class="gt-df gt-ac gt-fw gt-gap-2" id="repo-topics"> 30 + <div class="tw-flex tw-items-center tw-flex-wrap tw-gap-1" id="repo-topics"> 31 31 {{range .Topics}}<a class="ui repo-topic large label topic gt-m-0" href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=1">{{.Name}}</a>{{end}} 32 - {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}<button id="manage_topic" class="btn interact-fg gt-font-12">{{ctx.Locale.Tr "repo.topic.manage_topics"}}</button>{{end}} 32 + {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}<button id="manage_topic" class="btn interact-fg tw-text-12">{{ctx.Locale.Tr "repo.topic.manage_topics"}}</button>{{end}} 33 33 </div> 34 34 {{end}} 35 35 {{if and .Permission.IsAdmin (not .Repository.IsArchived)}} 36 - <div class="ui form gt-hidden gt-df gt-fc gt-mt-4" id="topic_edit"> 37 - <div class="field gt-f1 gt-mb-2"> 38 - <div class="ui fluid multiple search selection dropdown gt-fw" data-text-count-prompt="{{ctx.Locale.Tr "repo.topic.count_prompt"}}" data-text-format-prompt="{{ctx.Locale.Tr "repo.topic.format_prompt"}}"> 36 + <div class="ui form gt-hidden tw-flex tw-flex-col gt-mt-4" id="topic_edit"> 37 + <div class="field tw-flex-1 gt-mb-2"> 38 + <div class="ui fluid multiple search selection dropdown tw-flex-wrap" data-text-count-prompt="{{ctx.Locale.Tr "repo.topic.count_prompt"}}" data-text-format-prompt="{{ctx.Locale.Tr "repo.topic.format_prompt"}}"> 39 39 <input type="hidden" name="topics" value="{{range $i, $v := .Topics}}{{.Name}}{{if Eval $i "+" 1 "<" (len $.Topics)}},{{end}}{{end}}"> 40 40 {{range .Topics}} 41 41 {{/* keey the same layout as Fomantic UI generated labels */}} 42 - <a class="ui label transition visible tw-cursor-default gt-dib" data-value="{{.Name}}">{{.Name}}{{svg "octicon-x" 16 "delete icon"}}</a> 42 + <a class="ui label transition visible tw-cursor-default tw-inline-block" data-value="{{.Name}}">{{.Name}}{{svg "octicon-x" 16 "delete icon"}}</a> 43 43 {{end}} 44 44 <div class="text"></div> 45 45 </div> ··· 69 69 {{end}} 70 70 {{template "repo/sub_menu" .}} 71 71 <div class="repo-button-row"> 72 - <div class="gt-df gt-ac gt-fw gt-gap-y-3"> 72 + <div class="tw-flex tw-items-center tw-flex-wrap tw-gap-y-2"> 73 73 {{template "repo/branch_dropdown" dict "root" . "ContainerClasses" "gt-mr-2"}} 74 74 {{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}} 75 75 {{$cmpBranch := ""}} ··· 129 129 </span> 130 130 {{end}} 131 131 </div> 132 - <div class="gt-df gt-ac"> 132 + <div class="tw-flex tw-items-center"> 133 133 <!-- Only show clone panel in repository home page --> 134 134 {{if eq $n 0}} 135 - <div class="ui action tiny input" id="clone-panel"> 135 + <div class="clone-panel ui action tiny input"> 136 136 {{template "repo/clone_buttons" .}} 137 - <button id="more-btn" class="ui basic small compact jump dropdown icon button" data-tooltip-content="{{ctx.Locale.Tr "repo.more_operations"}}"> 137 + <button class="ui small jump dropdown icon button" data-tooltip-content="{{ctx.Locale.Tr "repo.more_operations"}}"> 138 138 {{svg "octicon-kebab-horizontal"}} 139 139 <div class="menu"> 140 140 {{if not $.DisableDownloadSourceArchives}}
+1 -1
templates/repo/icon.tmpl
··· 1 1 {{$avatarLink := (.RelAvatarLink ctx)}} 2 2 {{if $avatarLink}} 3 - <img class="ui avatar gt-vm" src="{{$avatarLink}}" width="24" height="24" alt="{{.FullName}}"> 3 + <img class="ui avatar tw-align-middle" src="{{$avatarLink}}" width="24" height="24" alt="{{.FullName}}"> 4 4 {{else if $.IsMirror}} 5 5 {{svg "octicon-mirror" 24}} 6 6 {{else if $.IsFork}}
+8 -8
templates/repo/issue/card.tmpl
··· 7 7 </div> 8 8 {{end}} 9 9 <div class="content gt-p-0 tw-w-full"> 10 - <div class="gt-df tw-items-start"> 10 + <div class="tw-flex tw-items-start"> 11 11 <div class="issue-card-icon"> 12 12 {{template "shared/issueicon" .}} 13 13 </div> 14 14 <a class="issue-card-title muted issue-title" href="{{.Link}}">{{.Title | RenderEmoji ctx | RenderCodeBlock}}</a> 15 15 {{if and $.isPinnedIssueCard $.Page.IsRepoAdmin}} 16 - <a role="button" class="issue-card-unpin muted gt-df gt-ac" data-tooltip-content={{ctx.Locale.Tr "repo.issues.unpin_issue"}} data-issue-id="{{.ID}}" data-unpin-url="{{$.Page.Link}}/unpin/{{.Index}}"> 16 + <a role="button" class="issue-card-unpin muted tw-flex tw-items-center" data-tooltip-content={{ctx.Locale.Tr "repo.issues.unpin_issue"}} data-issue-id="{{.ID}}" data-unpin-url="{{$.Page.Link}}/unpin/{{.Index}}"> 17 17 {{svg "octicon-x" 16}} 18 18 </a> 19 19 {{end}} ··· 34 34 {{if .MilestoneID}} 35 35 <div class="meta gt-my-2"> 36 36 <a class="milestone" href="{{.Repo.Link}}/milestone/{{.MilestoneID}}"> 37 - {{svg "octicon-milestone" 16 "gt-mr-2 gt-vm"}} 38 - <span class="gt-vm">{{.Milestone.Name}}</span> 37 + {{svg "octicon-milestone" 16 "gt-mr-2 tw-align-middle"}} 38 + <span class="tw-align-middle">{{.Milestone.Name}}</span> 39 39 </a> 40 40 </div> 41 41 {{end}} ··· 43 43 {{range index $.Page.LinkedPRs .ID}} 44 44 <div class="meta gt-my-2"> 45 45 <a href="{{$.Issue.Repo.Link}}/pulls/{{.Index}}"> 46 - <span class="gt-m-0 text {{if .PullRequest.HasMerged}}purple{{else if .IsClosed}}red{{else}}green{{end}}">{{svg "octicon-git-merge" 16 "gt-mr-2 gt-vm"}}</span> 47 - <span class="gt-vm">{{.Title}} <span class="text light grey">#{{.Index}}</span></span> 46 + <span class="gt-m-0 text {{if .PullRequest.HasMerged}}purple{{else if .IsClosed}}red{{else}}green{{end}}">{{svg "octicon-git-merge" 16 "gt-mr-2 tw-align-middle"}}</span> 47 + <span class="tw-align-middle">{{.Title}} <span class="text light grey">#{{.Index}}</span></span> 48 48 </a> 49 49 </div> 50 50 {{end}} ··· 52 52 {{$tasks := .GetTasks}} 53 53 {{if gt $tasks 0}} 54 54 <div class="meta gt-my-2"> 55 - {{svg "octicon-checklist" 16 "gt-mr-2 gt-vm"}} 56 - <span class="gt-vm">{{.GetTasksDone}} / {{$tasks}}</span> 55 + {{svg "octicon-checklist" 16 "gt-mr-2 tw-align-middle"}} 56 + <span class="tw-align-middle">{{.GetTasksDone}} / {{$tasks}}</span> 57 57 </div> 58 58 {{end}} 59 59 </div>
+1 -1
templates/repo/issue/filter_actions.tmpl
··· 29 29 <div class="divider"></div> 30 30 {{end}} 31 31 {{$previousExclusiveScope = $exclusiveScope}} 32 - <div class="item issue-action gt-df gt-sb" data-action="toggle" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/labels"> 32 + <div class="item issue-action tw-flex tw-justify-between" data-action="toggle" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/labels"> 33 33 {{if SliceUtils.Contains $.SelLabelIDs .ID}}{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel $.Context .}} 34 34 {{template "repo/issue/labels/label_archived" .}} 35 35 </div>
+31 -31
templates/repo/issue/filter_list.tmpl
··· 23 23 </div> 24 24 <span class="info">{{ctx.Locale.Tr "repo.issues.filter_label_exclude"}}</span> 25 25 <div class="divider"></div> 26 - <a rel="nofollow" class="{{if .AllLabels}}active selected {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_label_no_select"}}</a> 27 - <a rel="nofollow" class="{{if .NoLabel}}active selected {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels=0&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_label_select_no_label"}}</a> 26 + <a rel="nofollow" class="{{if .AllLabels}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_label_no_select"}}</a> 27 + <a rel="nofollow" class="{{if .NoLabel}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels=0&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_label_select_no_label"}}</a> 28 28 {{$previousExclusiveScope := "_no_scope"}} 29 29 {{range .Labels}} 30 30 {{$exclusiveScope := .ExclusiveScope}} ··· 32 32 <div class="divider"></div> 33 33 {{end}} 34 34 {{$previousExclusiveScope = $exclusiveScope}} 35 - <a rel="nofollow" class="item label-filter-item gt-df gt-ac" {{if .IsArchived}}data-is-archived{{end}} href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.QueryString}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}" data-label-id="{{.ID}}"> 35 + <a rel="nofollow" class="item label-filter-item tw-flex tw-items-center" {{if .IsArchived}}data-is-archived{{end}} href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.QueryString}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}" data-label-id="{{.ID}}"> 36 36 {{if .IsExcluded}} 37 37 {{svg "octicon-circle-slash"}} 38 38 {{else if .IsSelected}} ··· 43 43 {{end}} 44 44 {{end}} 45 45 {{RenderLabel $.Context .}} 46 - <p class="gt-ml-auto">{{template "repo/issue/labels/label_archived" .}}</p> 46 + <p class="tw-ml-auto">{{template "repo/issue/labels/label_archived" .}}</p> 47 47 </a> 48 48 {{end}} 49 49 </div> ··· 62 62 <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_milestone"}}"> 63 63 </div> 64 64 <div class="divider"></div> 65 - <a rel="nofollow" class="{{if not $.MilestoneID}}active selected {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone=0&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_milestone_all"}}</a> 66 - <a rel="nofollow" class="{{if $.MilestoneID}}{{if eq $.MilestoneID -1}}active selected {{end}}{{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone=-1&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_milestone_none"}}</a> 65 + <a rel="nofollow" class="{{if not $.MilestoneID}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone=0&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_milestone_all"}}</a> 66 + <a rel="nofollow" class="{{if $.MilestoneID}}{{if eq $.MilestoneID -1}}active selected {{end}}{{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone=-1&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_milestone_none"}}</a> 67 67 {{if .OpenMilestones}} 68 68 <div class="divider"></div> 69 69 <div class="header">{{ctx.Locale.Tr "repo.issues.filter_milestone_open"}}</div> 70 70 {{range .OpenMilestones}} 71 - <a rel="nofollow" class="{{if $.MilestoneID}}{{if eq $.MilestoneID .ID}}active selected {{end}}{{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.ID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> 71 + <a rel="nofollow" class="{{if $.MilestoneID}}{{if eq $.MilestoneID .ID}}active selected {{end}}{{end}}item" href="?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.ID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> 72 72 {{svg "octicon-milestone" 16 "mr-2"}} 73 73 {{.Name}} 74 74 </a> ··· 78 78 <div class="divider"></div> 79 79 <div class="header">{{ctx.Locale.Tr "repo.issues.filter_milestone_closed"}}</div> 80 80 {{range .ClosedMilestones}} 81 - <a rel="nofollow" class="{{if $.MilestoneID}}{{if eq $.MilestoneID .ID}}active selected {{end}}{{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.ID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> 81 + <a rel="nofollow" class="{{if $.MilestoneID}}{{if eq $.MilestoneID .ID}}active selected {{end}}{{end}}item" href="?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.ID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> 82 82 {{svg "octicon-milestone" 16 "mr-2"}} 83 83 {{.Name}} 84 84 </a> ··· 99 99 <i class="icon">{{svg "octicon-search" 16}}</i> 100 100 <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_project"}}"> 101 101 </div> 102 - <a rel="nofollow" class="{{if not .ProjectID}}active selected {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_project_all"}}</a> 103 - <a rel="nofollow" class="{{if eq .ProjectID -1}}active selected {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&project=-1&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_project_none"}}</a> 102 + <a rel="nofollow" class="{{if not .ProjectID}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_project_all"}}</a> 103 + <a rel="nofollow" class="{{if eq .ProjectID -1}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&project=-1&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_project_none"}}</a> 104 104 {{if .OpenProjects}} 105 105 <div class="divider"></div> 106 106 <div class="header"> 107 107 {{ctx.Locale.Tr "repo.issues.new.open_projects"}} 108 108 </div> 109 109 {{range .OpenProjects}} 110 - <a rel="nofollow" class="{{if $.ProjectID}}{{if eq $.ProjectID .ID}}active selected{{end}}{{end}} item gt-df" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{.ID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> 111 - {{svg .IconName 18 "gt-mr-3 gt-shrink-0"}}<span class="gt-ellipsis">{{.Title}}</span> 110 + <a rel="nofollow" class="{{if $.ProjectID}}{{if eq $.ProjectID .ID}}active selected{{end}}{{end}} item tw-flex" href="?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{.ID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> 111 + {{svg .IconName 18 "gt-mr-3 tw-shrink-0"}}<span class="gt-ellipsis">{{.Title}}</span> 112 112 </a> 113 113 {{end}} 114 114 {{end}} ··· 118 118 {{ctx.Locale.Tr "repo.issues.new.closed_projects"}} 119 119 </div> 120 120 {{range .ClosedProjects}} 121 - <a rel="nofollow" class="{{if $.ProjectID}}{{if eq $.ProjectID .ID}}active selected{{end}}{{end}} item" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{.ID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> 121 + <a rel="nofollow" class="{{if $.ProjectID}}{{if eq $.ProjectID .ID}}active selected{{end}}{{end}} item" href="?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{.ID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> 122 122 {{svg .IconName 18 "gt-mr-3"}}{{.Title}} 123 123 </a> 124 124 {{end}} ··· 130 130 <div class="ui dropdown jump item user-remote-search" data-tooltip-content="{{ctx.Locale.Tr "repo.author_search_tooltip"}}" 131 131 data-search-url="{{if .Milestone}}{{$.RepoLink}}/issues/posters{{else}}{{$.Link}}/posters{{end}}" 132 132 data-selected-user-id="{{$.PosterID}}" 133 - data-action-jump-url="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={user_id}{{if $.ShowArchivedLabels}}&archived=true{{end}}" 133 + data-action-jump-url="?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={user_id}{{if $.ShowArchivedLabels}}&archived=true{{end}}" 134 134 > 135 135 <span class="text"> 136 136 {{ctx.Locale.Tr "repo.issues.filter_poster"}} ··· 156 156 <i class="icon">{{svg "octicon-search" 16}}</i> 157 157 <input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_assignee"}}"> 158 158 </div> 159 - <a rel="nofollow" class="{{if not .AssigneeID}}active selected {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_assginee_no_select"}}</a> 160 - <a rel="nofollow" class="{{if eq .AssigneeID -1}}active selected {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee=-1&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee"}}</a> 159 + <a rel="nofollow" class="{{if not .AssigneeID}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_assginee_no_select"}}</a> 160 + <a rel="nofollow" class="{{if eq .AssigneeID -1}}active selected {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee=-1&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee"}}</a> 161 161 <div class="divider"></div> 162 162 {{range .Assignees}} 163 - <a rel="nofollow" class="{{if eq $.AssigneeID .ID}}active selected{{end}} item gt-df" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{.ID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> 163 + <a rel="nofollow" class="{{if eq $.AssigneeID .ID}}active selected{{end}} item tw-flex" href="?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{.ID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}"> 164 164 {{ctx.AvatarUtils.Avatar . 20}}{{template "repo/search_name" .}} 165 165 </a> 166 166 {{end}} ··· 175 175 </span> 176 176 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 177 177 <div class="menu"> 178 - <a rel="nofollow" class="{{if eq .ViewType "all"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type=all&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.all_issues"}}</a> 179 - <a rel="nofollow" class="{{if eq .ViewType "assigned"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type=assigned&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.assigned_to_you"}}</a> 180 - <a rel="nofollow" class="{{if eq .ViewType "created_by"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type=created_by&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.created_by_you"}}</a> 178 + <a rel="nofollow" class="{{if eq .ViewType "all"}}active {{end}}item" href="?q={{$.Keyword}}&type=all&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.all_issues"}}</a> 179 + <a rel="nofollow" class="{{if eq .ViewType "assigned"}}active {{end}}item" href="?q={{$.Keyword}}&type=assigned&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.assigned_to_you"}}</a> 180 + <a rel="nofollow" class="{{if eq .ViewType "created_by"}}active {{end}}item" href="?q={{$.Keyword}}&type=created_by&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.created_by_you"}}</a> 181 181 {{if .PageIsPullList}} 182 - <a rel="nofollow" class="{{if eq .ViewType "review_requested"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type=review_requested&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.review_requested"}}</a> 183 - <a rel="nofollow" class="{{if eq .ViewType "reviewed_by"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type=reviewed_by&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.reviewed_by_you"}}</a> 182 + <a rel="nofollow" class="{{if eq .ViewType "review_requested"}}active {{end}}item" href="?q={{$.Keyword}}&type=review_requested&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.review_requested"}}</a> 183 + <a rel="nofollow" class="{{if eq .ViewType "reviewed_by"}}active {{end}}item" href="?q={{$.Keyword}}&type=reviewed_by&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.reviewed_by_you"}}</a> 184 184 {{end}} 185 - <a rel="nofollow" class="{{if eq .ViewType "mentioned"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type=mentioned&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.mentioning_you"}}</a> 185 + <a rel="nofollow" class="{{if eq .ViewType "mentioned"}}active {{end}}item" href="?q={{$.Keyword}}&type=mentioned&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_type.mentioning_you"}}</a> 186 186 </div> 187 187 </div> 188 188 {{end}} ··· 194 194 </span> 195 195 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 196 196 <div class="menu"> 197 - <a rel="nofollow" class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort=latest&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> 198 - <a rel="nofollow" class="{{if eq .SortType "oldest"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort=oldest&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 199 - <a rel="nofollow" class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort=recentupdate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> 200 - <a rel="nofollow" class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort=leastupdate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> 201 - <a rel="nofollow" class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort=mostcomment&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a> 202 - <a rel="nofollow" class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort=leastcomment&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a> 203 - <a rel="nofollow" class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort=nearduedate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a> 204 - <a rel="nofollow" class="{{if eq .SortType "farduedate"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort=farduedate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a> 197 + <a rel="nofollow" class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=latest&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> 198 + <a rel="nofollow" class="{{if eq .SortType "oldest"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=oldest&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 199 + <a rel="nofollow" class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=recentupdate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> 200 + <a rel="nofollow" class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=leastupdate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> 201 + <a rel="nofollow" class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=mostcomment&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a> 202 + <a rel="nofollow" class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=leastcomment&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a> 203 + <a rel="nofollow" class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=nearduedate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a> 204 + <a rel="nofollow" class="{{if eq .SortType "farduedate"}}active {{end}}item" href="?q={{$.Keyword}}&type={{$.ViewType}}&sort=farduedate&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a> 205 205 </div> 206 206 </div>
+2 -2
templates/repo/issue/label_precolors.tmpl
··· 1 1 <div class="precolors"> 2 - <div class="gt-df"> 2 + <div class="tw-flex"> 3 3 <a class="color" style="background-color:#e11d21" data-color-hex="#e11d21"></a> 4 4 <a class="color" style="background-color:#eb6420" data-color-hex="#eb6420"></a> 5 5 <a class="color" style="background-color:#fbca04" data-color-hex="#fbca04"></a> ··· 9 9 <a class="color" style="background-color:#0052cc" data-color-hex="#0052cc"></a> 10 10 <a class="color" style="background-color:#5319e7" data-color-hex="#5319e7"></a> 11 11 </div> 12 - <div class="gt-df"> 12 + <div class="tw-flex"> 13 13 <a class="color" style="background-color:#f6c6c7" data-color-hex="#f6c6c7"></a> 14 14 <a class="color" style="background-color:#fad8c7" data-color-hex="#fad8c7"></a> 15 15 <a class="color" style="background-color:#fef2c0" data-color-hex="#fef2c0"></a>
+6 -6
templates/repo/issue/labels/label_list.tmpl
··· 9 9 </span> 10 10 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 11 11 <div class="left menu"> 12 - <a class="{{if or (eq .SortType "alphabetically") (not .SortType)}}active {{end}}item" href="{{$.Link}}?sort=alphabetically&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.alphabetically"}}</a> 13 - <a class="{{if eq .SortType "reversealphabetically"}}active {{end}}item" href="{{$.Link}}?sort=reversealphabetically&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.reverse_alphabetically"}}</a> 14 - <a class="{{if eq .SortType "leastissues"}}active {{end}}item" href="{{$.Link}}?sort=leastissues&state={{$.State}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_issues"}}</a> 15 - <a class="{{if eq .SortType "mostissues"}}active {{end}}item" href="{{$.Link}}?sort=mostissues&state={{$.State}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_issues"}}</a> 12 + <a class="{{if or (eq .SortType "alphabetically") (not .SortType)}}active {{end}}item" href="?sort=alphabetically&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.alphabetically"}}</a> 13 + <a class="{{if eq .SortType "reversealphabetically"}}active {{end}}item" href="?sort=reversealphabetically&state={{$.State}}">{{ctx.Locale.Tr "repo.issues.label.filter_sort.reverse_alphabetically"}}</a> 14 + <a class="{{if eq .SortType "leastissues"}}active {{end}}item" href="?sort=leastissues&state={{$.State}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_issues"}}</a> 15 + <a class="{{if eq .SortType "mostissues"}}active {{end}}item" href="?sort=mostissues&state={{$.State}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_issues"}}</a> 16 16 </div> 17 17 </div> 18 18 </div> ··· 42 42 <a class="open-issues" href="{{$.RepoLink}}/issues?labels={{.ID}}">{{svg "octicon-issue-opened"}} {{ctx.Locale.Tr "repo.issues.label_open_issues" .NumOpenIssues}}</a> 43 43 {{end}} 44 44 </div> 45 - <div class="label-operation gt-df"> 45 + <div class="label-operation tw-flex"> 46 46 {{template "repo/issue/labels/label_archived" .}} 47 - <div class="gt-df gt-ml-auto"> 47 + <div class="tw-flex tw-ml-auto"> 48 48 {{if and (not $.PageIsOrgSettingsLabels) (not $.Repository.IsArchived) (or $.CanWriteIssues $.CanWritePulls)}} 49 49 <a class="edit-label-button" href="#" data-id="{{.ID}}" data-title="{{.Name}}" {{if .Exclusive}}data-exclusive{{end}} {{if gt .ArchivedUnix 0}}data-is-archived{{end}} data-num-issues="{{.NumIssues}}" data-description="{{.Description}}" data-color={{.Color}}>{{svg "octicon-pencil"}} {{ctx.Locale.Tr "repo.issues.label_edit"}}</a> 50 50 <a class="delete-button" href="#" data-url="{{$.Link}}/delete" data-id="{{.ID}}">{{svg "octicon-trash"}} {{ctx.Locale.Tr "repo.issues.label_delete"}}</a>
+1
templates/repo/issue/list.tmpl
··· 2 2 <div role="main" aria-label="{{.Title}}" class="page-content repository issue-list"> 3 3 {{template "repo/header" .}} 4 4 <div class="ui container"> 5 + {{template "base/alert" .}} 5 6 6 7 {{if .PinnedIssues}} 7 8 <div id="issue-pins" {{if .IsRepoAdmin}}data-is-repo-admin{{end}}>
+6 -6
templates/repo/issue/milestone/filter_list.tmpl
··· 5 5 </span> 6 6 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 7 7 <div class="menu"> 8 - <a class="{{if or (eq .SortType "closestduedate") (not .SortType)}}active {{end}}item" href="{{$.Link}}?sort=closestduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.earliest_due_data"}}</a> 9 - <a class="{{if eq .SortType "furthestduedate"}}active {{end}}item" href="{{$.Link}}?sort=furthestduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.latest_due_date"}}</a> 10 - <a class="{{if eq .SortType "leastcomplete"}}active {{end}}item" href="{{$.Link}}?sort=leastcomplete&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_complete"}}</a> 11 - <a class="{{if eq .SortType "mostcomplete"}}active {{end}}item" href="{{$.Link}}?sort=mostcomplete&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_complete"}}</a> 12 - <a class="{{if eq .SortType "mostissues"}}active {{end}}item" href="{{$.Link}}?sort=mostissues&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_issues"}}</a> 13 - <a class="{{if eq .SortType "leastissues"}}active {{end}}item" href="{{$.Link}}?sort=leastissues&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_issues"}}</a> 8 + <a class="{{if or (eq .SortType "closestduedate") (not .SortType)}}active {{end}}item" href="?sort=closestduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.earliest_due_data"}}</a> 9 + <a class="{{if eq .SortType "furthestduedate"}}active {{end}}item" href="?sort=furthestduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.latest_due_date"}}</a> 10 + <a class="{{if eq .SortType "leastcomplete"}}active {{end}}item" href="?sort=leastcomplete&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_complete"}}</a> 11 + <a class="{{if eq .SortType "mostcomplete"}}active {{end}}item" href="?sort=mostcomplete&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_complete"}}</a> 12 + <a class="{{if eq .SortType "mostissues"}}active {{end}}item" href="?sort=mostissues&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_issues"}}</a> 13 + <a class="{{if eq .SortType "leastissues"}}active {{end}}item" href="?sort=leastissues&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_issues"}}</a> 14 14 </div> 15 15 </div>
+6 -5
templates/repo/issue/milestone_issues.tmpl
··· 2 2 <div role="main" aria-label="{{.Title}}" class="page-content repository milestone-issue-list"> 3 3 {{template "repo/header" .}} 4 4 <div class="ui container"> 5 - <div class="gt-df"> 5 + {{template "base/alert" .}} 6 + <div class="tw-flex"> 6 7 <h1 class="gt-mb-3">{{.Milestone.Name}}</h1> 7 8 {{if not .Repository.IsArchived}} 8 - <div class="text right gt-f1"> 9 + <div class="text right tw-flex-1"> 9 10 {{if or .CanWriteIssues .CanWritePulls}} 10 11 {{if .Milestone.IsClosed}} 11 12 <a class="ui primary basic button link-action" href data-url="{{$.RepoLink}}/milestones/{{.MilestoneID}}/open">{{ctx.Locale.Tr "repo.milestones.open"}} ··· 25 26 {{.Milestone.RenderedContent}} 26 27 </div> 27 28 {{end}} 28 - <div class="gt-df gt-fc gt-gap-3"> 29 + <div class="tw-flex tw-flex-col tw-gap-2"> 29 30 <progress class="milestone-progress-big" value="{{.Milestone.Completeness}}" max="100"></progress> 30 - <div class="gt-df gt-gap-4"> 31 - <div classs="gt-df gt-ac"> 31 + <div class="tw-flex tw-gap-4"> 32 + <div classs="tw-flex tw-items-center"> 32 33 {{$closedDate:= TimeSinceUnix .Milestone.ClosedDateUnix ctx.Locale}} 33 34 {{if .IsClosed}} 34 35 {{svg "octicon-clock"}} {{ctx.Locale.Tr "repo.milestones.closed" $closedDate}}
+1 -1
templates/repo/issue/milestones.tmpl
··· 23 23 {{svg "octicon-milestone" 16}} 24 24 <a class="muted" href="{{$.RepoLink}}/milestone/{{.ID}}">{{.Name}}</a> 25 25 </h3> 26 - <div class="gt-df gt-ac"> 26 + <div class="tw-flex tw-items-center"> 27 27 <span class="gt-mr-3">{{.Completeness}}%</span> 28 28 <progress value="{{.Completeness}}" max="100"></progress> 29 29 </div>
+1 -1
templates/repo/issue/new_form.tmpl
··· 171 171 <div class="selected"> 172 172 {{range .Assignees}} 173 173 <a class="item gt-p-2 muted gt-hidden" id="assignee_{{.ID}}" href="{{$.RepoLink}}/issues?assignee={{.ID}}"> 174 - {{ctx.AvatarUtils.Avatar . 28 "gt-mr-3 gt-vm"}}{{.GetDisplayName}} 174 + {{ctx.AvatarUtils.Avatar . 28 "gt-mr-3 tw-align-middle"}}{{.GetDisplayName}} 175 175 </a> 176 176 {{end}} 177 177 </div>
+4 -4
templates/repo/issue/view_content.tmpl
··· 20 20 </a> 21 21 {{end}} 22 22 <div class="content comment-container"> 23 - <div class="ui top attached header comment-header gt-df gt-ac gt-sb" role="heading" aria-level="3"> 24 - <div class="comment-header-left gt-df gt-ac"> 23 + <div class="ui top attached header comment-header tw-flex tw-items-center tw-justify-between" role="heading" aria-level="3"> 24 + <div class="comment-header-left tw-flex tw-items-center"> 25 25 {{if .Issue.OriginalAuthor}} 26 - <span class="text black gt-font-semibold"> 26 + <span class="text black tw-font-semibold"> 27 27 {{svg (MigrationIcon .Repository.GetOriginalURLHostname)}} 28 28 {{.Issue.OriginalAuthor}} 29 29 </span> ··· 43 43 </span> 44 44 {{end}} 45 45 </div> 46 - <div class="comment-header-right actions gt-df gt-ac"> 46 + <div class="comment-header-right actions tw-flex tw-items-center"> 47 47 {{template "repo/issue/view_content/show_role" dict "ShowRole" .Issue.ShowRole "IgnorePoster" true}} 48 48 {{if not $.Repository.IsArchived}} 49 49 {{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index)}}
+3 -3
templates/repo/issue/view_content/attachments.tmpl
··· 4 4 {{end}} 5 5 {{$hasThumbnails := false}} 6 6 {{- range .Attachments -}} 7 - <div class="gt-df"> 8 - <div class="gt-f1 gt-p-3"> 7 + <div class="tw-flex"> 8 + <div class="tw-flex-1 gt-p-3"> 9 9 <a target="_blank" rel="noopener noreferrer" href="{{.DownloadURL}}" title="{{ctx.Locale.Tr "repo.issues.attachment.open_tab" .Name}}"> 10 10 {{if FilenameIsImage .Name}} 11 11 {{if not (StringUtils.Contains (StringUtils.ToString $.RenderedContent) .UUID)}} ··· 18 18 <span><strong>{{.Name}}</strong></span> 19 19 </a> 20 20 </div> 21 - <div class="gt-p-3 gt-df gt-ac"> 21 + <div class="gt-p-3 tw-flex tw-items-center"> 22 22 <span class="ui text grey">{{.Size | FileSize}}</span> 23 23 </div> 24 24 </div>
+12 -13
templates/repo/issue/view_content/comments.tmpl
··· 25 25 </a> 26 26 {{end}} 27 27 <div class="content comment-container"> 28 - <div class="ui top attached header comment-header gt-df gt-ac gt-sb" role="heading" aria-level="3"> 29 - <div class="comment-header-left gt-df gt-ac"> 28 + <div class="ui top attached header comment-header tw-flex tw-items-center tw-justify-between" role="heading" aria-level="3"> 29 + <div class="comment-header-left tw-flex tw-items-center"> 30 30 {{if .OriginalAuthor}} 31 - <span class="text black gt-font-semibold gt-mr-2"> 31 + <span class="text black tw-font-semibold gt-mr-2"> 32 32 {{svg (MigrationIcon $.Repository.GetOriginalURLHostname)}} 33 33 {{.OriginalAuthor}} 34 34 </span> ··· 50 50 </span> 51 51 {{end}} 52 52 </div> 53 - <div class="comment-header-right actions gt-df gt-ac"> 53 + <div class="comment-header-right actions tw-flex tw-items-center"> 54 54 {{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole}} 55 55 {{if not $.Repository.IsArchived}} 56 56 {{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}} ··· 376 376 <div class="timeline-item-group" id="{{.HashTag}}"> 377 377 <div class="timeline-item event"> 378 378 {{if not .OriginalAuthor}} 379 - {{/* Some timeline avatars need a offset to correctly align with their speech 380 - bubble. The condition depends on review type and for positive reviews whether 381 - there is a comment element or not */}} 382 - <a class="timeline-avatar{{if or (and (eq .Review.Type 1) (or .Content .Attachments)) (and (eq .Review.Type 2) (or .Content .Attachments)) (eq .Review.Type 3)}} timeline-avatar-offset{{end}}"{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}> 379 + {{/* Some timeline avatars need a offset to correctly align with their speech bubble. 380 + The condition depends on whether the comment has contents/attachments or reviews */}} 381 + <a class="timeline-avatar{{if or .Content .Attachments (and .Review .Review.CodeComments)}} timeline-avatar-offset{{end}}"{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}> 383 382 {{ctx.AvatarUtils.Avatar .Poster 40}} 384 383 </a> 385 384 {{end}} ··· 403 402 {{if or .Content .Attachments}} 404 403 <div class="timeline-item comment"> 405 404 <div class="content comment-container"> 406 - <div class="ui top attached header comment-header gt-df gt-ac gt-sb"> 407 - <div class="comment-header-left gt-df gt-ac"> 405 + <div class="ui top attached header comment-header tw-flex tw-items-center tw-justify-between"> 406 + <div class="comment-header-left tw-flex tw-items-center"> 408 407 {{if gt .Poster.ID 0}} 409 408 <a class="inline-timeline-avatar" href="{{.Poster.HomeLink}}"> 410 409 {{ctx.AvatarUtils.Avatar .Poster 24}} ··· 412 411 {{end}} 413 412 <span class="text grey muted-links"> 414 413 {{if .OriginalAuthor}} 415 - <span class="text black gt-font-semibold"> 414 + <span class="text black tw-font-semibold"> 416 415 {{svg (MigrationIcon $.Repository.GetOriginalURLHostname)}} 417 416 {{.OriginalAuthor}} 418 417 </span> ··· 425 424 {{ctx.Locale.Tr "repo.issues.review.left_comment"}} 426 425 </span> 427 426 </div> 428 - <div class="comment-header-right actions gt-df gt-ac"> 427 + <div class="comment-header-right actions tw-flex tw-items-center"> 429 428 {{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole}} 430 429 {{if not $.Repository.IsArchived}} 431 430 {{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}} ··· 622 621 {{if .Content}} 623 622 <div class="timeline-item comment"> 624 623 <div class="content"> 625 - <div class="ui top attached header comment-header-left gt-df gt-ac arrow-top"> 624 + <div class="ui top attached header comment-header-left tw-flex tw-items-center arrow-top"> 626 625 {{if gt .Poster.ID 0}} 627 626 <a class="inline-timeline-avatar" href="{{.Poster.HomeLink}}"> 628 627 {{ctx.AvatarUtils.Avatar .Poster 24}}
+8 -8
templates/repo/issue/view_content/conversation.tmpl
··· 3 3 {{$resolveDoer := (index .comments 0).ResolveDoer}} 4 4 {{$isNotPending := (not (eq (index .comments 0).Review.Type 0))}} 5 5 <div class="ui segments conversation-holder"> 6 - <div class="ui segment collapsible-comment-box gt-py-3 gt-df gt-ac gt-sb"> 7 - <div class="gt-df gt-ac"> 6 + <div class="ui segment collapsible-comment-box gt-py-3 tw-flex tw-items-center tw-justify-between"> 7 + <div class="tw-flex tw-items-center"> 8 8 <a href="{{(index .comments 0).CodeCommentLink ctx}}" class="file-comment gt-ml-3 gt-word-break">{{(index .comments 0).TreePath}}</a> 9 9 {{if $invalid}} 10 10 <span class="ui label basic small gt-ml-3" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.review.outdated_description"}}"> ··· 14 14 </div> 15 15 <div> 16 16 {{if or $invalid $resolved}} 17 - <button id="show-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="{{if not $resolved}}gt-hidden {{end}}ui compact labeled button show-outdated gt-df gt-ac"> 17 + <button id="show-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="{{if not $resolved}}gt-hidden {{end}}ui compact labeled button show-outdated tw-flex tw-items-center"> 18 18 {{svg "octicon-unfold" 16 "gt-mr-3"}} 19 19 {{if $resolved}} 20 20 {{ctx.Locale.Tr "repo.issues.review.show_resolved"}} ··· 22 22 {{ctx.Locale.Tr "repo.issues.review.show_outdated"}} 23 23 {{end}} 24 24 </button> 25 - <button id="hide-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="{{if $resolved}}gt-hidden {{end}}ui compact labeled button hide-outdated gt-df gt-ac"> 25 + <button id="hide-outdated-{{(index .comments 0).ID}}" data-comment="{{(index .comments 0).ID}}" class="{{if $resolved}}gt-hidden {{end}}ui compact labeled button hide-outdated tw-flex tw-items-center"> 26 26 {{svg "octicon-fold" 16 "gt-mr-3"}} 27 27 {{if $resolved}} 28 28 {{ctx.Locale.Tr "repo.issues.review.hide_resolved"}} ··· 55 55 <div class="comment code-comment gt-pb-4" id="{{.HashTag}}"> 56 56 <div class="content"> 57 57 <div class="header comment-header"> 58 - <div class="comment-header-left gt-df gt-ac"> 58 + <div class="comment-header-left tw-flex tw-items-center"> 59 59 {{if not .OriginalAuthor}} 60 60 <a class="avatar"> 61 61 {{ctx.AvatarUtils.Avatar .Poster 20}} ··· 76 76 {{ctx.Locale.Tr "repo.issues.commented_at" .HashTag $createdSubStr}} 77 77 </span> 78 78 </div> 79 - <div class="comment-header-right actions gt-df gt-ac"> 79 + <div class="comment-header-right actions tw-flex tw-items-center"> 80 80 {{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole}} 81 81 {{if not $.Repository.IsArchived}} 82 82 {{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}} ··· 106 106 </div> 107 107 {{end}} 108 108 </div> 109 - <div class="code-comment-buttons gt-df gt-ac gt-fw gt-mt-3 gt-mb-2 gt-mx-3"> 110 - <div class="gt-f1"> 109 + <div class="code-comment-buttons tw-flex tw-items-center tw-flex-wrap gt-mt-3 gt-mb-2 gt-mx-3"> 110 + <div class="tw-flex-1"> 111 111 {{if $resolved}} 112 112 <div class="ui grey text"> 113 113 {{svg "octicon-check" 16 "gt-mr-2"}}
+3 -3
templates/repo/issue/view_content/pull.tmpl
··· 33 33 <div class="ui attached merge-section segment {{if not $.LatestCommitStatus}}no-header{{end}} flex-items-block"> 34 34 {{if .Issue.PullRequest.HasMerged}} 35 35 {{if .IsPullBranchDeletable}} 36 - <div class="item item-section text gt-f1"> 36 + <div class="item item-section text tw-flex-1"> 37 37 <div class="item-section-left"> 38 38 <h3 class="gt-mb-3"> 39 39 {{ctx.Locale.Tr "repo.pulls.merged_success"}} ··· 48 48 </div> 49 49 {{end}} 50 50 {{else if .Issue.IsClosed}} 51 - <div class="item item-section text gt-f1"> 51 + <div class="item item-section text tw-flex-1"> 52 52 <div class="item-section-left"> 53 53 <h3 class="gt-mb-3">{{ctx.Locale.Tr "repo.pulls.closed"}}</h3> 54 54 <div class="merge-section-info"> ··· 82 82 </div> 83 83 {{else if .IsPullWorkInProgress}} 84 84 <div class="item toggle-wip" data-title="{{.Issue.Title}}" data-wip-prefix="{{.WorkInProgressPrefix}}" data-update-url="{{.Issue.Link}}/title"> 85 - <div class="item-section-left flex-text-inline gt-f1"> 85 + <div class="item-section-left flex-text-inline tw-flex-1"> 86 86 {{svg "octicon-x"}} 87 87 {{ctx.Locale.Tr "repo.pulls.cannot_merge_work_in_progress"}} 88 88 </div>
+1 -1
templates/repo/issue/view_content/reference_issue_dialog.tmpl
··· 2 2 <div class="header"> 3 3 {{ctx.Locale.Tr "repo.issues.context.reference_issue"}} 4 4 </div> 5 - <div class="content" style="text-align:left"> 5 + <div class="content tw-text-left"> 6 6 <form class="ui form form-fetch-action" action="{{printf "%s/issues/new" .Repository.Link}}" method="post"> 7 7 {{.CsrfTokenHtml}} 8 8 <div class="ui segment content">
+23 -23
templates/repo/issue/view_content/sidebar.tmpl
··· 3 3 {{if .Issue.IsPull}} 4 4 <input id="reviewer_id" name="reviewer_id" type="hidden" value="{{.reviewer_id}}"> 5 5 <div class="ui {{if or (and (not .Reviewers) (not .TeamReviewers)) (not .CanChooseReviewer) .Repository.IsArchived}}disabled{{end}} floating jump select-reviewers-modify dropdown"> 6 - <a class="text gt-df gt-ac muted"> 6 + <a class="text tw-flex tw-items-center muted"> 7 7 <strong>{{ctx.Locale.Tr "repo.issues.review.reviewers"}}</strong> 8 8 {{if and .CanChooseReviewer (not .Repository.IsArchived)}} 9 9 {{svg "octicon-gear" 16 "gt-ml-2"}} ··· 50 50 <span class="no-select item {{if or .OriginalReviews .PullReviewers}}gt-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_reviewers"}}</span> 51 51 <div class="selected"> 52 52 {{range .PullReviewers}} 53 - <div class="item gt-df gt-ac gt-py-3"> 54 - <div class="gt-df gt-ac gt-f1"> 53 + <div class="item tw-flex tw-items-center gt-py-3"> 54 + <div class="tw-flex tw-items-center tw-flex-1"> 55 55 {{if .User}} 56 56 <a class="muted sidebar-item-link" href="{{.User.HomeLink}}">{{ctx.AvatarUtils.Avatar .User 20 "gt-mr-3"}}{{.User.GetDisplayName}}</a> 57 57 {{else if .Team}} 58 58 <span class="text">{{svg "octicon-people" 20 "gt-mr-3"}}{{$.Issue.Repo.OwnerName}}/{{.Team.Name}}</span> 59 59 {{end}} 60 60 </div> 61 - <div class="gt-df gt-ac gt-gap-3"> 61 + <div class="tw-flex tw-items-center tw-gap-2"> 62 62 {{if (and $.Permission.IsAdmin (or (eq .Review.Type 1) (eq .Review.Type 3)) (not $.Issue.IsClosed))}} 63 - <a href="#" class="ui muted icon gt-df gt-ac show-modal" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dismiss_review"}}" data-modal="#dismiss-review-modal-{{.Review.ID}}"> 63 + <a href="#" class="ui muted icon tw-flex tw-items-center show-modal" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dismiss_review"}}" data-modal="#dismiss-review-modal-{{.Review.ID}}"> 64 64 {{svg "octicon-x" 20}} 65 65 </a> 66 66 <div class="ui small modal" id="dismiss-review-modal-{{.Review.ID}}"> ··· 99 99 </div> 100 100 {{end}} 101 101 {{range .OriginalReviews}} 102 - <div class="item gt-df gt-ac gt-py-3"> 103 - <div class="gt-df gt-ac gt-f1"> 102 + <div class="item tw-flex tw-items-center gt-py-3"> 103 + <div class="tw-flex tw-items-center tw-flex-1"> 104 104 <a class="muted" href="{{$.Repository.OriginalURL}}" data-tooltip-content="{{ctx.Locale.Tr "repo.migrated_from_fake" $.Repository.GetOriginalURLHostname}}"> 105 105 {{svg (MigrationIcon $.Repository.GetOriginalURLHostname) 20 "gt-mr-3"}} 106 106 {{.OriginalAuthor}} 107 107 </a> 108 108 </div> 109 - <div class="gt-df gt-ac gt-gap-3"> 109 + <div class="tw-flex tw-items-center tw-gap-2"> 110 110 {{svg (printf "octicon-%s" .Type.Icon) 16 (printf "text %s" (.HTMLTypeColorName))}} 111 111 </div> 112 112 </div> ··· 264 264 265 265 {{if .Participants}} 266 266 <span class="text"><strong>{{ctx.Locale.Tr "repo.issues.num_participants" .NumParticipants}}</strong></span> 267 - <div class="ui list gt-df gt-fw"> 267 + <div class="ui list tw-flex tw-flex-wrap"> 268 268 {{range .Participants}} 269 269 <a {{if gt .ID 0}}href="{{.HomeLink}}"{{end}} data-tooltip-content="{{.GetDisplayName}}"> 270 270 {{ctx.AvatarUtils.Avatar . 28 "gt-my-1 gt-mr-2"}} ··· 317 317 <div class="ui mini modal issue-start-time-modal"> 318 318 <div class="header">{{ctx.Locale.Tr "repo.issues.add_time"}}</div> 319 319 <div class="content"> 320 - <form method="post" id="add_time_manual_form" action="{{.Issue.Link}}/times/add" class="ui input fluid gt-gap-3"> 320 + <form method="post" id="add_time_manual_form" action="{{.Issue.Link}}/times/add" class="ui input fluid tw-gap-2"> 321 321 {{$.CsrfTokenHtml}} 322 322 <input placeholder='{{ctx.Locale.Tr "repo.issues.add_time_hours"}}' type="number" name="hours"> 323 323 <input placeholder='{{ctx.Locale.Tr "repo.issues.add_time_minutes"}}' type="number" name="minutes" class="ui compact"> ··· 368 368 </div> 369 369 {{if ne .Issue.DeadlineUnix 0}} 370 370 <p> 371 - <div class="gt-df gt-sb gt-ac"> 371 + <div class="tw-flex tw-justify-between tw-items-center"> 372 372 <div class="due-date {{if .Issue.IsOverdue}}text red{{end}}" {{if .Issue.IsOverdue}}data-tooltip-content="{{ctx.Locale.Tr "repo.issues.due_date_overdue"}}"{{end}}> 373 373 {{svg "octicon-calendar" 16 "gt-mr-3"}} 374 374 {{DateTime "long" .Issue.DeadlineUnix.FormatDate}} ··· 424 424 </span> 425 425 <div class="ui relaxed divided list"> 426 426 {{range .BlockingDependencies}} 427 - <div class="item dependency{{if .Issue.IsClosed}} is-closed{{end}} gt-df gt-ac gt-sb"> 428 - <div class="item-left gt-df gt-jc gt-fc gt-f1 gt-ellipsis"> 427 + <div class="item dependency{{if .Issue.IsClosed}} is-closed{{end}} tw-flex tw-items-center tw-justify-between"> 428 + <div class="item-left tw-flex tw-justify-center tw-flex-col tw-flex-1 gt-ellipsis"> 429 429 <a class="title muted" href="{{.Issue.Link}}" data-tooltip-content="#{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}}"> 430 430 #{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}} 431 431 </a> ··· 433 433 {{.Repository.OwnerName}}/{{.Repository.Name}} 434 434 </div> 435 435 </div> 436 - <div class="item-right gt-df gt-ac gt-m-2"> 436 + <div class="item-right tw-flex tw-items-center gt-m-2"> 437 437 {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} 438 438 <a class="delete-dependency-button ci muted" data-id="{{.Issue.ID}}" data-type="blocking" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}"> 439 439 {{svg "octicon-trash" 16}} ··· 443 443 </div> 444 444 {{end}} 445 445 {{if .BlockingDependenciesNotPermitted}} 446 - <div class="item gt-df gt-ac gt-sb gt-ellipsis"> 446 + <div class="item tw-flex tw-items-center tw-justify-between gt-ellipsis"> 447 447 <span>{{ctx.Locale.TrN (len .BlockingDependenciesNotPermitted) "repo.issues.dependency.no_permission_1" "repo.issues.dependency.no_permission_n" (len .BlockingDependenciesNotPermitted)}}</span> 448 448 </div> 449 449 {{end}} ··· 456 456 </span> 457 457 <div class="ui relaxed divided list"> 458 458 {{range .BlockedByDependencies}} 459 - <div class="item dependency{{if .Issue.IsClosed}} is-closed{{end}} gt-df gt-ac gt-sb"> 460 - <div class="item-left gt-df gt-jc gt-fc gt-f1 gt-ellipsis"> 459 + <div class="item dependency{{if .Issue.IsClosed}} is-closed{{end}} tw-flex tw-items-center tw-justify-between"> 460 + <div class="item-left tw-flex tw-justify-center tw-flex-col tw-flex-1 gt-ellipsis"> 461 461 <a class="title muted" href="{{.Issue.Link}}" data-tooltip-content="#{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}}"> 462 462 #{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}} 463 463 </a> ··· 465 465 {{.Repository.OwnerName}}/{{.Repository.Name}} 466 466 </div> 467 467 </div> 468 - <div class="item-right gt-df gt-ac gt-m-2"> 468 + <div class="item-right tw-flex tw-items-center gt-m-2"> 469 469 {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} 470 470 <a class="delete-dependency-button ci muted" data-id="{{.Issue.ID}}" data-type="blockedBy" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}"> 471 471 {{svg "octicon-trash" 16}} ··· 476 476 {{end}} 477 477 {{if $.CanCreateIssueDependencies}} 478 478 {{range .BlockedByDependenciesNotPermitted}} 479 - <div class="item dependency{{if .Issue.IsClosed}} is-closed{{end}} gt-df gt-ac gt-sb"> 480 - <div class="item-left gt-df gt-jc gt-fc gt-f1 gt-ellipsis"> 479 + <div class="item dependency{{if .Issue.IsClosed}} is-closed{{end}} tw-flex tw-items-center tw-justify-between"> 480 + <div class="item-left tw-flex tw-justify-center tw-flex-col tw-flex-1 gt-ellipsis"> 481 481 <div class="gt-ellipsis"> 482 482 <span data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.no_permission.can_remove"}}">{{svg "octicon-lock" 16}}</span> 483 483 <span class="title" data-tooltip-content="#{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}}"> ··· 488 488 {{.Repository.OwnerName}}/{{.Repository.Name}} 489 489 </div> 490 490 </div> 491 - <div class="item-right gt-df gt-ac gt-m-2"> 491 + <div class="item-right tw-flex tw-items-center gt-m-2"> 492 492 {{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} 493 493 <a class="delete-dependency-button ci muted" data-id="{{.Issue.ID}}" data-type="blocking" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.dependency.remove_info"}}"> 494 494 {{svg "octicon-trash" 16}} ··· 498 498 </div> 499 499 {{end}} 500 500 {{else if .BlockedByDependenciesNotPermitted}} 501 - <div class="item gt-df gt-ac gt-sb gt-ellipsis"> 501 + <div class="item tw-flex tw-items-center tw-justify-between gt-ellipsis"> 502 502 <span>{{ctx.Locale.TrN (len .BlockedByDependenciesNotPermitted) "repo.issues.dependency.no_permission_1" "repo.issues.dependency.no_permission_n" (len .BlockedByDependenciesNotPermitted)}}</span> 503 503 </div> 504 504 {{end}} ··· 555 555 <div class="divider"></div> 556 556 <div class="ui equal width compact grid"> 557 557 {{$issueReferenceLink := printf "%s#%d" .Issue.Repo.FullName .Issue.Index}} 558 - <div class="row gt-ac" data-tooltip-content="{{$issueReferenceLink}}"> 558 + <div class="row tw-items-center" data-tooltip-content="{{$issueReferenceLink}}"> 559 559 <span class="text column truncate">{{ctx.Locale.Tr "repo.issues.reference_link" $issueReferenceLink}}</span> 560 560 <button class="ui two wide button column gt-p-3" data-clipboard-text="{{$issueReferenceLink}}">{{svg "octicon-copy" 14}}</button> 561 561 </div>
+1 -1
templates/repo/issue/view_content/update_branch_by_merge.tmpl
··· 7 7 </div> 8 8 <div class="item-section-right"> 9 9 {{if and $.UpdateAllowed $.UpdateByRebaseAllowed}} 10 - <div class="gt-dib"> 10 + <div class="tw-inline-block"> 11 11 <div class="ui buttons update-button"> 12 12 <button class="ui button" data-do="{{$.Link}}/update" data-redirect="{{$.Link}}"> 13 13 <span class="button-text">
+1 -1
templates/repo/issue/view_title.tmpl
··· 8 8 <h1 class="gt-word-break"> 9 9 <span id="issue-title">{{RenderIssueTitle $.Context .Issue.Title ($.Repository.ComposeMetas ctx) | RenderCodeBlock}} <span class="index">#{{.Issue.Index}}</span> 10 10 </span> 11 - <div id="edit-title-input" class="ui input gt-f1 gt-hidden"> 11 + <div id="edit-title-input" class="ui input tw-flex-1 gt-hidden"> 12 12 <input value="{{.Issue.Title}}" maxlength="255" autocomplete="off"> 13 13 </div> 14 14 </h1>
+1 -1
templates/repo/migrate/migrate.tmpl
··· 5 5 {{template "repo/migrate/helper" .}} 6 6 <div class="ui cards migrate-entries"> 7 7 {{range .Services}} 8 - <a class="ui card migrate-entry gt-df gt-ac" href="{{AppSubUrl}}/repo/migrate?service_type={{.}}&org={{$.Org}}&mirror={{$.Mirror}}"> 8 + <a class="ui card migrate-entry tw-flex tw-items-center" href="{{AppSubUrl}}/repo/migrate?service_type={{.}}&org={{$.Org}}&mirror={{$.Mirror}}"> 9 9 {{if eq .Name "github"}} 10 10 {{svg "octicon-mark-github" 184 "gt-p-4"}} 11 11 {{else if eq .Name "gitlab"}}
+1 -1
templates/repo/projects/view.tmpl
··· 2 2 <div role="main" aria-label="{{.Title}}" class="page-content repository projects view-project"> 3 3 {{template "repo/header" .}} 4 4 <div class="ui container padded"> 5 - <div class="gt-df gt-sb gt-ac gt-mb-4"> 5 + <div class="tw-flex tw-justify-between tw-items-center gt-mb-4"> 6 6 {{template "repo/issue/navbar" .}} 7 7 <a class="ui small primary button" href="{{.RepoLink}}/issues/new/choose?project={{.Project.ID}}">{{ctx.Locale.Tr "repo.issues.new"}}</a> 8 8 </div>
+1 -1
templates/repo/pulls/fork.tmpl
··· 37 37 38 38 <div class="inline field"> 39 39 <label>{{ctx.Locale.Tr "repo.fork_from"}}</label> 40 - <a href="{{.ForkRepo.Link}}" class="gt-dib">{{.ForkRepo.FullName}}</a> 40 + <a href="{{.ForkRepo.Link}}" class="tw-inline-block">{{.ForkRepo.FullName}}</a> 41 41 </div> 42 42 <div class="inline required field {{if .Err_RepoName}}error{{end}}"> 43 43 <label for="repo_name">{{ctx.Locale.Tr "repo.repo_name"}}</label>
+1 -1
templates/repo/pulls/tab_menu.tmpl
··· 15 15 {{ctx.Locale.Tr "repo.pulls.tab_files"}} 16 16 <span class="ui small label">{{if .NumFiles}}{{.NumFiles}}{{else}}-{{end}}</span> 17 17 </a> 18 - <span class="item gt-ml-auto gt-pr-0 gt-font-bold gt-df gt-ac gt-gap-3"> 18 + <span class="item tw-ml-auto gt-pr-0 tw-font-bold tw-flex tw-items-center tw-gap-2"> 19 19 <span><span class="text green">{{if .Diff.TotalAddition}}+{{.Diff.TotalAddition}}{{end}}</span> <span class="text red">{{if .Diff.TotalDeletion}}-{{.Diff.TotalDeletion}}{{end}}</span></span> 20 20 <span class="diff-stats-bar"> 21 21 <div class="diff-stats-add-bar" style="width: {{Eval 100 "*" .Diff.TotalAddition "/" "(" .Diff.TotalAddition "+" .Diff.TotalDeletion "+" 0.0 ")"}}%"></div>
+2 -2
templates/repo/release/list.tmpl
··· 16 16 {{end}} 17 17 </div> 18 18 <div class="ui twelve wide column detail"> 19 - <div class="gt-df gt-ac gt-sb gt-fw gt-mb-3"> 19 + <div class="tw-flex tw-items-center tw-justify-between tw-flex-wrap gt-mb-3"> 20 20 <h4 class="release-list-title gt-word-break"> 21 21 <a href="{{$.RepoLink}}/releases/tag/{{$release.TagName | PathEscapeSegments}}">{{$release.Title}}</a> 22 - {{template "repo/commit_statuses" dict "Status" $info.CommitStatus "Statuses" $info.CommitStatuses "AdditionalClasses" "gt-df"}} 22 + {{template "repo/commit_statuses" dict "Status" $info.CommitStatus "Statuses" $info.CommitStatuses "AdditionalClasses" "tw-flex"}} 23 23 {{if $release.IsDraft}} 24 24 <span class="ui yellow label">{{ctx.Locale.Tr "repo.release.draft"}}</span> 25 25 {{else if $release.IsPrerelease}}
+3 -3
templates/repo/release/new.tmpl
··· 21 21 {{else}} 22 22 <input id="tag-name" name="tag_name" value="{{.tag_name}}" aria-label="{{ctx.Locale.Tr "repo.release.tag_name"}}" placeholder="{{ctx.Locale.Tr "repo.release.tag_name"}}" autofocus required maxlength="255"> 23 23 <input id="tag-name-editor" type="hidden" data-existing-tags="{{JsonUtils.EncodeToString .Tags}}" data-tag-helper="{{ctx.Locale.Tr "repo.release.tag_helper"}}" data-tag-helper-new="{{ctx.Locale.Tr "repo.release.tag_helper_new"}}" data-tag-helper-existing="{{ctx.Locale.Tr "repo.release.tag_helper_existing"}}"> 24 - <div id="tag-target-selector" class="gt-dib"> 24 + <div id="tag-target-selector" class="tw-inline-block"> 25 25 <span class="at">@</span> 26 26 <div class="ui selection dropdown"> 27 27 <input type="hidden" name="tag_target" value="{{.tag_target}}"> ··· 61 61 </div> 62 62 {{range .attachments}} 63 63 <div class="field flex-text-block" id="attachment-{{.ID}}"> 64 - <div class="flex-text-inline gt-f1"> 64 + <div class="flex-text-inline tw-flex-1"> 65 65 <input name="attachment-edit-{{.UUID}}" class="attachment_edit" required value="{{.Name}}"> 66 66 <input name="attachment-del-{{.UUID}}" type="hidden" value="false"> 67 67 <span class="ui text grey tw-whitespace-nowrap">{{.Size | FileSize}}</span> ··· 101 101 </div> 102 102 <span class="help">{{ctx.Locale.Tr "repo.release.prerelease_helper"}}</span> 103 103 <div class="divider gt-mt-0"></div> 104 - <div class="gt-df gt-je"> 104 + <div class="tw-flex tw-justify-end"> 105 105 {{if .PageIsEditRelease}} 106 106 <a class="ui small button" href="{{.RepoLink}}/releases"> 107 107 {{ctx.Locale.Tr "repo.release.cancel"}}
+2 -2
templates/repo/release_tag_header.tmpl
··· 2 2 {{$canReadCode := $.Permission.CanRead $.UnitTypeCode}} 3 3 4 4 {{if $canReadReleases}} 5 - <div class="gt-df"> 6 - <div class="gt-f1 gt-df gt-ac"> 5 + <div class="tw-flex"> 6 + <div class="tw-flex-1 tw-flex tw-items-center"> 7 7 <h2 class="ui compact small menu header small-menu-items"> 8 8 <a class="{{if and .PageIsReleaseList (not .PageIsSingleTag)}}active {{end}}item" href="{{.RepoLink}}/releases">{{ctx.Locale.PrettyNumber .NumReleases}} {{ctx.Locale.TrN .NumReleases "repo.release" "repo.releases"}}</a> 9 9 {{if $canReadCode}}
+3 -3
templates/repo/settings/branches.tmpl
··· 12 12 <p> 13 13 {{ctx.Locale.Tr "repo.settings.default_branch_desc"}} 14 14 </p> 15 - <form class="gt-df" action="{{.Link}}" method="post"> 15 + <form class="tw-flex" action="{{.Link}}" method="post"> 16 16 {{.CsrfTokenHtml}} 17 17 <input type="hidden" name="action" value="default_branch"> 18 18 {{if not .Repository.IsEmpty}} 19 - <div class="ui dropdown selection search gt-f1 gt-mr-3 tw-max-w-96"> 19 + <div class="ui dropdown selection search tw-flex-1 gt-mr-3 tw-max-w-96"> 20 20 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 21 21 <input type="hidden" name="branch" value="{{.Repository.DefaultBranch}}"> 22 22 <div class="default text">{{.Repository.DefaultBranch}}</div> ··· 41 41 <div class="ui attached segment"> 42 42 <div class="flex-list"> 43 43 {{range .ProtectedBranches}} 44 - <div class="flex-item gt-ac"> 44 + <div class="flex-item tw-items-center"> 45 45 <div class="flex-item-main"> 46 46 <div class="flex-item-title"> 47 47 <div class="ui basic primary label">{{.RuleName}}</div>
+3 -3
templates/repo/settings/collaboration.tmpl
··· 7 7 <div class="ui attached segment"> 8 8 <div class="flex-list"> 9 9 {{range .Collaborators}} 10 - <div class="flex-item gt-ac"> 10 + <div class="flex-item tw-items-center"> 11 11 <div class="flex-item-leading"> 12 12 <a href="{{.HomeLink}}">{{ctx.AvatarUtils.Avatar . 32}}</a> 13 13 </div> ··· 41 41 <div class="ui bottom attached segment"> 42 42 <form class="ui form" id="repo-collab-form" action="{{.Link}}" method="post"> 43 43 {{.CsrfTokenHtml}} 44 - <div id="search-user-box" class="ui search input gt-vm"> 44 + <div id="search-user-box" class="ui search input tw-align-middle"> 45 45 <input class="prompt" name="collaborator" placeholder="{{ctx.Locale.Tr "search.team_kind"}}" autocomplete="off" autofocus required> 46 46 </div> 47 47 <button class="ui primary button">{{ctx.Locale.Tr "repo.settings.add_collaborator"}}</button> ··· 89 89 {{if $allowedToChangeTeams}} 90 90 <form class="ui form" id="repo-collab-team-form" action="{{.Link}}/team" method="post"> 91 91 {{.CsrfTokenHtml}} 92 - <div id="search-team-box" class="ui search input gt-vm" data-org-name="{{.OrgName}}"> 92 + <div id="search-team-box" class="ui search input tw-align-middle" data-org-name="{{.OrgName}}"> 93 93 <input class="prompt" name="team" placeholder="{{ctx.Locale.Tr "search.team_kind"}}" autocomplete="off" autofocus required> 94 94 </div> 95 95 <button class="ui primary button">{{ctx.Locale.Tr "repo.settings.add_team"}}</button>
+1 -1
templates/repo/settings/deploy_keys.tmpl
··· 31 31 <label for="is_writable"> 32 32 {{ctx.Locale.Tr "repo.settings.is_writable"}} 33 33 </label> 34 - <small style="padding-left: 26px;">{{ctx.Locale.Tr "repo.settings.is_writable_info"}}</small> 34 + <small class="tw-pl-[26px]">{{ctx.Locale.Tr "repo.settings.is_writable_info"}}</small> 35 35 </div> 36 36 </div> 37 37 <button class="ui primary button">
+1 -1
templates/repo/settings/githooks.tmpl
··· 11 11 {{range .Hooks}} 12 12 <div class="item truncated-item-container"> 13 13 <span class="text {{if .IsActive}}green{{else}}grey{{end}} gt-mr-3">{{svg "octicon-dot-fill" 22}}</span> 14 - <span class="text truncate gt-f1 gt-mr-3">{{.Name}}</span> 14 + <span class="text truncate tw-flex-1 gt-mr-3">{{.Name}}</span> 15 15 <a class="muted tw-float-right gt-p-3" href="{{$.RepoLink}}/settings/hooks/git/{{.Name|PathEscape}}"> 16 16 {{svg "octicon-pencil"}} 17 17 </a>
+9 -9
templates/repo/settings/options.tmpl
··· 110 110 <table class="ui table"> 111 111 <thead> 112 112 <tr> 113 - <th style="width:40%">{{ctx.Locale.Tr "repo.settings.mirror_settings.mirrored_repository"}}</th> 113 + <th class="tw-w-2/5">{{ctx.Locale.Tr "repo.settings.mirror_settings.mirrored_repository"}}</th> 114 114 <th>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction"}}</th> 115 115 <th>{{ctx.Locale.Tr "repo.settings.mirror_settings.last_update"}}</th> 116 116 <th></th> 117 117 </tr> 118 118 </thead> 119 - {{end}} 120 119 {{if $modifyBrokenPullMirror}} 121 120 {{/* even if a repo is a pull mirror (IsMirror=true), the PullMirror might still be nil if the mirror migration is broken */}} 122 121 <tbody> 123 122 <tr> 124 123 <td colspan="4"> 125 - <div class="text red gt-py-4 gt-border-secondary-bottom">{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.pull"}}: {{ctx.Locale.Tr "error.occurred"}}</div> 124 + <div class="text red gt-py-4">{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.pull"}}: {{ctx.Locale.Tr "error.occurred"}}</div> 126 125 </td> 127 126 </tr> 128 127 </tbody> ··· 133 132 <td>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.pull"}}</td> 134 133 <td>{{DateTime "full" .PullMirror.UpdatedUnix}}</td> 135 134 <td class="right aligned"> 136 - <form method="post" class="gt-dib"> 135 + <form method="post" class="tw-inline-block"> 137 136 {{.CsrfTokenHtml}} 138 137 <input type="hidden" name="action" value="mirror-sync"> 139 138 <button class="ui primary tiny button inline text-thin">{{ctx.Locale.Tr "repo.settings.sync_mirror"}}</button> ··· 201 200 </td> 202 201 </tr> 203 202 </tbody> 203 + {{end}}{{/* end if: $modifyBrokenPullMirror / $isWorkingPullMirror */}} 204 204 </table> 205 - {{end}}{{/* end if: IsMirror */}} 205 + {{end}}{{/* end if .Repository.IsMirror */}} 206 206 207 207 <table class="ui table"> 208 208 <thead> 209 209 <tr> 210 - <th style="width:40%">{{ctx.Locale.Tr "repo.settings.mirror_settings.pushed_repository"}}</th> 210 + <th class="tw-w-2/5">{{ctx.Locale.Tr "repo.settings.mirror_settings.pushed_repository"}}</th> 211 211 <th>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction"}}</th> 212 212 <th>{{ctx.Locale.Tr "repo.settings.mirror_settings.last_update"}}</th> 213 213 <th></th> ··· 230 230 > 231 231 {{svg "octicon-pencil" 14}} 232 232 </button> 233 - <form method="post" class="gt-dib"> 233 + <form method="post" class="tw-inline-block"> 234 234 {{$.CsrfTokenHtml}} 235 235 <input type="hidden" name="action" value="push-mirror-sync"> 236 236 <input type="hidden" name="push_mirror_id" value="{{.ID}}"> 237 237 <button class="ui primary tiny button" data-tooltip-content="{{ctx.Locale.Tr "repo.settings.sync_mirror"}}">{{svg "octicon-sync" 14}}</button> 238 238 </form> 239 - <form method="post" class="gt-dib"> 239 + <form method="post" class="tw-inline-block"> 240 240 {{$.CsrfTokenHtml}} 241 241 <input type="hidden" name="action" value="push-mirror-remove"> 242 242 <input type="hidden" name="push_mirror_id" value="{{.ID}}"> ··· 492 492 </div> 493 493 </div> 494 494 {{if not .Repository.IsMirror}} 495 - <div class="flex-item gt-ac"> 495 + <div class="flex-item tw-items-center"> 496 496 <div class="flex-item-main"> 497 497 {{if .Repository.IsArchived}} 498 498 <div class="flex-item-title">{{ctx.Locale.Tr "repo.settings.unarchive.header"}}</div>
+1 -1
templates/repo/settings/tags.tmpl
··· 106 106 </td> 107 107 <td class="right aligned"> 108 108 <a class="ui tiny primary button" href="{{$.RepoLink}}/settings/tags/{{.ID}}">{{ctx.Locale.Tr "edit"}}</a> 109 - <form class="gt-dib" action="{{$.RepoLink}}/settings/tags/delete" method="post"> 109 + <form class="tw-inline-block" action="{{$.RepoLink}}/settings/tags/delete" method="post"> 110 110 {{$.CsrfTokenHtml}} 111 111 <input type="hidden" name="id" value="{{.ID}}"> 112 112 <button class="ui tiny red button">{{ctx.Locale.Tr "remove"}}</button>
+1 -1
templates/repo/settings/webhook/base_list.tmpl
··· 15 15 {{range .Webhooks}} 16 16 <div class="item truncated-item-container"> 17 17 <span class="text {{if eq .LastStatus 1}}green{{else if eq .LastStatus 2}}red{{else}}grey{{end}} gt-mr-3">{{svg "octicon-dot-fill" 22}}</span> 18 - <div class="text truncate gt-f1 gt-mr-3"> 18 + <div class="text truncate tw-flex-1 gt-mr-3"> 19 19 <a title="{{.URL}}" href="{{$.BaseLink}}/{{.ID}}">{{.URL}}</a> 20 20 </div> 21 21 <a class="muted gt-p-3" href="{{$.BaseLink}}/{{.ID}}">{{svg "octicon-pencil"}}</a>
+4 -2
templates/repo/settings/webhook/history.tmpl
··· 6 6 <div class="ui right"> 7 7 <!-- the button is wrapped with a span because the tooltip doesn't show on hover if we put data-tooltip-content directly on the button --> 8 8 <span data-tooltip-content="{{if or $isNew .Webhook.IsActive}}{{ctx.Locale.Tr "repo.settings.webhook.test_delivery_desc"}}{{else}}{{ctx.Locale.Tr "repo.settings.webhook.test_delivery_desc_disabled"}}{{end}}"> 9 - <button class="ui teal tiny button{{if not (or $isNew .Webhook.IsActive)}} disabled{{end}}" id="test-delivery" data-link="{{.Link}}/test" data-redirect="{{.Link}}">{{ctx.Locale.Tr "repo.settings.webhook.test_delivery"}}</button> 9 + <button class="ui teal tiny button{{if not (or $isNew .Webhook.IsActive)}} disabled{{end}}" id="test-delivery" data-link="{{.Link}}/test" data-redirect="{{.Link}}"> 10 + <span class="text">{{ctx.Locale.Tr "repo.settings.webhook.test_delivery"}}</span> 11 + </button> 10 12 </span> 11 13 </div> 12 14 {{end}} ··· 15 17 <div class="ui list"> 16 18 {{range .History}} 17 19 <div class="item"> 18 - <div class="flex-text-block gt-sb"> 20 + <div class="flex-text-block tw-justify-between"> 19 21 <div class="flex-text-inline"> 20 22 {{if .IsSucceed}} 21 23 <span class="text green">{{svg "octicon-check"}}</span>
+1 -1
templates/repo/sub_menu.tmpl
··· 25 25 {{range .LanguageStats}} 26 26 <div class="item"> 27 27 <i class="color-icon" style="background-color: {{.Color}}"></i> 28 - <span class="gt-font-semibold"> 28 + <span class="tw-font-semibold"> 29 29 {{if eq .Language "other"}} 30 30 {{ctx.Locale.Tr "repo.language_other"}} 31 31 {{else}}
+4 -4
templates/repo/tag/list.tmpl
··· 5 5 {{template "base/alert" .}} 6 6 {{template "repo/release_tag_header" .}} 7 7 <h4 class="ui top attached header"> 8 - <div class="five wide column gt-df gt-ac"> 8 + <div class="five wide column tw-flex tw-items-center"> 9 9 {{svg "octicon-tag" 16 "gt-mr-2"}}{{ctx.Locale.Tr "repo.release.tags"}} 10 10 </div> 11 11 </h4> ··· 18 18 <td class="tag"> 19 19 <h3 class="release-tag-name gt-mb-3"> 20 20 {{if $canReadReleases}} 21 - <a class="gt-df gt-ac" href="{{$.RepoLink}}/releases/tag/{{.TagName | PathEscapeSegments}}" rel="nofollow">{{.TagName}}</a> 21 + <a class="tw-flex tw-items-center" href="{{$.RepoLink}}/releases/tag/{{.TagName | PathEscapeSegments}}" rel="nofollow">{{.TagName}}</a> 22 22 {{else}} 23 - <a class="gt-df gt-ac" href="{{$.RepoLink}}/src/tag/{{.TagName | PathEscapeSegments}}" rel="nofollow">{{.TagName}}</a> 23 + <a class="tw-flex tw-items-center" href="{{$.RepoLink}}/src/tag/{{.TagName | PathEscapeSegments}}" rel="nofollow">{{.TagName}}</a> 24 24 {{end}} 25 25 </h3> 26 - <div class="download gt-df gt-ac"> 26 + <div class="download tw-flex tw-items-center"> 27 27 {{if $.Permission.CanRead $.UnitTypeCode}} 28 28 {{if .CreatedUnix}} 29 29 <span class="gt-mr-3">{{svg "octicon-clock" 16 "gt-mr-2"}}{{TimeSinceUnix .CreatedUnix ctx.Locale}}</span>
+4 -4
templates/repo/view_file.tmpl
··· 25 25 </div> 26 26 {{end}} 27 27 28 - <h4 class="file-header ui top attached header gt-df gt-ac gt-sb gt-fw"> 29 - <div class="file-header-left gt-df gt-ac gt-py-3 gt-pr-4"> 28 + <h4 class="file-header ui top attached header tw-flex tw-items-center tw-justify-between tw-flex-wrap"> 29 + <div class="file-header-left tw-flex tw-items-center gt-py-3 gt-pr-4"> 30 30 {{if .ReadmeInList}} 31 31 {{svg "octicon-book" 16 "gt-mr-3"}} 32 32 <strong><a class="default-link muted" href="#readme">{{.FileName}}</a></strong> ··· 34 34 {{template "repo/file_info" .}} 35 35 {{end}} 36 36 </div> 37 - <div class="file-header-right file-actions gt-df gt-ac gt-fw"> 37 + <div class="file-header-right file-actions tw-flex tw-items-center tw-flex-wrap"> 38 38 {{if .HasSourceRenderedToggle}} 39 39 <div class="ui compact icon buttons"> 40 - <a href="{{$.Link}}?display=source" class="ui mini basic button {{if .IsDisplayingSource}}active{{end}}" data-tooltip-content="{{ctx.Locale.Tr "repo.file_view_source"}}">{{svg "octicon-code" 15}}</a> 40 + <a href="?display=source" class="ui mini basic button {{if .IsDisplayingSource}}active{{end}}" data-tooltip-content="{{ctx.Locale.Tr "repo.file_view_source"}}">{{svg "octicon-code" 15}}</a> 41 41 <a href="{{$.Link}}" class="ui mini basic button {{if .IsDisplayingRendered}}active{{end}}" data-tooltip-content="{{ctx.Locale.Tr "repo.file_view_rendered"}}">{{svg "octicon-file" 15}}</a> 42 42 </div> 43 43 {{end}}
+2 -2
templates/repo/wiki/new.tmpl
··· 3 3 {{template "repo/header" .}} 4 4 <div class="ui container"> 5 5 {{template "base/alert" .}} 6 - <div class="ui header flex-text-block gt-sb"> 6 + <div class="ui header flex-text-block tw-justify-between"> 7 7 {{ctx.Locale.Tr "repo.wiki.new_page"}} 8 8 {{if .PageIsWikiEdit}} 9 9 <a class="ui tiny primary button" href="{{.RepoLink}}/wiki?action=_new">{{ctx.Locale.Tr "repo.wiki.new_page_button"}}</a> 10 10 {{end}} 11 11 </div> 12 - <form class="ui form" action="{{.Link}}?action={{if .PageIsWikiEdit}}_edit{{else}}_new{{end}}" method="post"> 12 + <form class="ui form" action="?action={{if .PageIsWikiEdit}}_edit{{else}}_new{{end}}" method="post"> 13 13 {{.CsrfTokenHtml}} 14 14 <div class="field {{if .Err_Title}}error{{end}}"> 15 15 <input name="title" value="{{.title}}" aria-label="{{ctx.Locale.Tr "repo.wiki.page_title"}}" placeholder="{{ctx.Locale.Tr "repo.wiki.page_title"}}" autofocus required>
+1 -1
templates/repo/wiki/pages.tmpl
··· 2 2 <div role="main" aria-label="{{.Title}}" class="page-content repository wiki pages"> 3 3 {{template "repo/header" .}} 4 4 <div class="ui container"> 5 - <h2 class="ui header gt-df gt-ac gt-sb"> 5 + <h2 class="ui header tw-flex tw-items-center tw-justify-between"> 6 6 <span>{{ctx.Locale.Tr "repo.wiki.pages"}}</span> 7 7 <span> 8 8 {{if and .CanWriteWiki (not .Repository.IsMirror)}}
+1 -1
templates/repo/wiki/revision.tmpl
··· 15 15 </div> 16 16 </div> 17 17 <div class="ui eight wide column text right"> 18 - <div class="ui action small input" id="clone-panel"> 18 + <div class="clone-panel ui action small input"> 19 19 {{template "repo/clone_buttons" .}} 20 20 {{template "repo/clone_script" .}} 21 21 </div>
+2 -2
templates/repo/wiki/view.tmpl
··· 4 4 {{$title := .title}} 5 5 <div class="ui container"> 6 6 <div class="repo-button-row"> 7 - <div class="gt-df gt-ac"> 7 + <div class="tw-flex tw-items-center"> 8 8 <div class="ui floating filter dropdown" data-no-results="{{ctx.Locale.Tr "repo.pulls.no_results"}}"> 9 9 <div class="ui basic small button"> 10 10 <span class="text"> ··· 28 28 </div> 29 29 </div> 30 30 </div> 31 - <div class="ui action small input gt-df gt-ac" id="clone-panel"> 31 + <div class="clone-panel ui action small input"> 32 32 {{template "repo/clone_buttons" .}} 33 33 {{template "repo/clone_script" .}} 34 34 </div>
+4 -4
templates/shared/actions/runner_edit.tmpl
··· 7 7 {{template "base/disable_form_autofill"}} 8 8 {{.CsrfTokenHtml}} 9 9 <div class="runner-basic-info"> 10 - <div class="field gt-dib gt-mr-4"> 10 + <div class="field tw-inline-block gt-mr-4"> 11 11 <label>{{ctx.Locale.Tr "actions.runners.status"}}</label> 12 12 <span class="ui {{if .Runner.IsOnline}}green{{else}}basic{{end}} label">{{.Runner.StatusLocaleName ctx.Locale}}</span> 13 13 </div> 14 - <div class="field gt-dib gt-mr-4"> 14 + <div class="field tw-inline-block gt-mr-4"> 15 15 <label>{{ctx.Locale.Tr "actions.runners.last_online"}}</label> 16 16 <span>{{if .Runner.LastOnline}}{{TimeSinceUnix .Runner.LastOnline ctx.Locale}}{{else}}{{ctx.Locale.Tr "never"}}{{end}}</span> 17 17 </div> 18 - <div class="field gt-dib gt-mr-4"> 18 + <div class="field tw-inline-block gt-mr-4"> 19 19 <label>{{ctx.Locale.Tr "actions.runners.labels"}}</label> 20 20 <span> 21 21 {{range .Runner.AgentLabels}} ··· 23 23 {{end}} 24 24 </span> 25 25 </div> 26 - <div class="field gt-dib gt-mr-4"> 26 + <div class="field tw-inline-block gt-mr-4"> 27 27 <label>{{ctx.Locale.Tr "actions.runners.owner_type"}}</label> 28 28 <span data-tooltip-content="{{.Runner.BelongsToOwnerName}}">{{.Runner.BelongsToOwnerType.LocaleString ctx.Locale}}</span> 29 29 </div>
+8 -8
templates/shared/issueicon.tmpl
··· 1 1 {{if .IsPull}} 2 - {{if and .PullRequest .PullRequest.HasMerged}} 3 - {{svg "octicon-git-merge" 16 "text purple"}} 4 - {{else if and (.GetPullRequest ctx) (.GetPullRequest ctx).HasMerged}} 5 - {{svg "octicon-git-merge" 16 "text purple"}} 2 + {{if not .PullRequest}} 3 + No PullRequest 6 4 {{else}} 7 5 {{if .IsClosed}} 8 - {{svg "octicon-git-pull-request" 16 "text red"}} 6 + {{if .PullRequest.HasMerged}} 7 + {{svg "octicon-git-merge" 16 "text purple"}} 8 + {{else}} 9 + {{svg "octicon-git-pull-request" 16 "text red"}} 10 + {{end}} 9 11 {{else}} 10 - {{if and .PullRequest (.PullRequest.IsWorkInProgress ctx)}} 11 - {{svg "octicon-git-pull-request-draft" 16 "text grey"}} 12 - {{else if and (.GetPullRequest ctx) ((.GetPullRequest ctx).IsWorkInProgress ctx)}} 12 + {{if .PullRequest.IsWorkInProgress ctx}} 13 13 {{svg "octicon-git-pull-request-draft" 16 "text grey"}} 14 14 {{else}} 15 15 {{svg "octicon-git-pull-request" 16 "text green"}}
+1 -1
templates/shared/issuelist.tmpl
··· 21 21 {{end}} 22 22 <span class="labels-list gt-ml-2"> 23 23 {{range .Labels}} 24 - <a href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}{{if ne $.listType "milestone"}}&milestone={{$.MilestoneID}}{{end}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{RenderLabel $.Context .}}</a> 24 + <a href="?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}{{if ne $.listType "milestone"}}&milestone={{$.MilestoneID}}{{end}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{RenderLabel $.Context .}}</a> 25 25 {{end}} 26 26 </span> 27 27 </div>
+1 -1
templates/shared/repo_search.tmpl
··· 1 1 <div class="ui small secondary filter menu"> 2 - <form id="repo-search-form" class="ui form ignore-dirty tw-flex-1 tw-flex tw-flex-row tw-gap-x-2 gt-ac"> 2 + <form id="repo-search-form" class="ui form ignore-dirty tw-flex-1 tw-flex tw-flex-row tw-gap-x-2 tw-items-center"> 3 3 {{if .Language}}<input hidden name="language" value="{{.Language}}">{{end}} 4 4 {{if .TopicOnly}}<input hidden name="topic" value="{{.TopicOnly}}">{{end}} 5 5 <div class="ui small fluid action input tw-flex-1">
+5 -5
templates/shared/search/code/results.tmpl
··· 1 - <div class="flex-text-block gt-fw"> 1 + <div class="flex-text-block tw-flex-wrap"> 2 2 {{range $term := .SearchResultLanguages}} 3 3 <a class="ui {{if eq $.Language $term.Language}}primary{{end}} basic label gt-m-0" 4 - href="{{$.Link}}?q={{$.Keyword}}{{if ne $.Language $term.Language}}&l={{$term.Language}}{{end}}&fuzzy={{$.IsFuzzy}}"> 4 + href="?q={{$.Keyword}}{{if ne $.Language $term.Language}}&l={{$term.Language}}{{end}}&fuzzy={{$.IsFuzzy}}"> 5 5 <i class="color-icon gt-mr-3" style="background-color: {{$term.Color}}"></i> 6 6 {{$term.Language}} 7 7 <div class="detail">{{$term.Count}}</div> ··· 12 12 {{range $result := .SearchResults}} 13 13 {{$repo := or $.Repo (index $.RepoMaps .RepoID)}} 14 14 <div class="diff-file-box diff-box file-content non-diff-file-content repo-search-result"> 15 - <h4 class="ui top attached normal header gt-df gt-fw"> 15 + <h4 class="ui top attached normal header tw-flex tw-flex-wrap"> 16 16 {{if not $.Repo}} 17 - <span class="file gt-f1"> 17 + <span class="file tw-flex-1"> 18 18 <a rel="nofollow" href="{{$repo.Link}}">{{$repo.FullName}}</a> 19 19 {{if $repo.IsArchived}} 20 20 <span class="ui basic label">{{ctx.Locale.Tr "repo.desc.archived"}}</span> ··· 22 22 - {{.Filename}} 23 23 </span> 24 24 {{else}} 25 - <span class="file gt-f1">{{.Filename}}</span> 25 + <span class="file tw-flex-1">{{.Filename}}</span> 26 26 {{end}} 27 27 <a role="button" class="ui basic tiny button" rel="nofollow" href="{{$repo.Link}}/src/{{if $.CodeIndexerDisabled}}branch{{else}}commit{{end}}/{{$result.CommitID | PathEscape}}/{{.Filename | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.diff.view_file"}}</a> 28 28 </h4>
+2 -2
templates/shared/searchbottom.tmpl
··· 1 - <div class="ui bottom attached table segment gt-df gt-ac gt-sb"> 2 - <div class="gt-df gt-ac gt-ml-4"> 1 + <div class="ui bottom attached table segment tw-flex tw-items-center tw-justify-between"> 2 + <div class="tw-flex tw-items-center gt-ml-4"> 3 3 {{if .result.Language}} 4 4 <i class="color-icon gt-mr-3" style="background-color: {{.result.Color}}"></i>{{.result.Language}} 5 5 {{end}}
+1 -1
templates/shared/secrets/add_list.tmpl
··· 14 14 {{if .Secrets}} 15 15 <div class="flex-list"> 16 16 {{range .Secrets}} 17 - <div class="flex-item gt-ac"> 17 + <div class="flex-item tw-items-center"> 18 18 <div class="flex-item-leading"> 19 19 {{svg "octicon-key" 32}} 20 20 </div>
+1 -1
templates/shared/user/authorlink.tmpl
··· 1 - <a class="author text black gt-font-semibold muted"{{if gt .ID 0}} href="{{.HomeLink}}"{{end}}>{{.GetDisplayName}}</a>{{if .IsBot}}<span class="ui basic label gt-p-2">bot</span>{{end}} 1 + <a class="author text black tw-font-semibold muted"{{if gt .ID 0}} href="{{.HomeLink}}"{{end}}>{{.GetDisplayName}}</a>{{if .IsBot}}<span class="ui basic label gt-p-2">bot</span>{{end}}
+1 -1
templates/shared/user/org_profile_avatar.tmpl
··· 2 2 <div class="ui container"> 3 3 <div class="ui vertically grid head"> 4 4 <div class="column"> 5 - <div class="ui header gt-df gt-ac gt-word-break"> 5 + <div class="ui header tw-flex tw-items-center gt-word-break"> 6 6 {{ctx.AvatarUtils.Avatar . 100}} 7 7 <span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span> 8 8 <span class="org-visibility">
+3 -3
templates/shared/user/profile_big_avatar.tmpl
··· 1 1 <div id="profile-avatar-card" class="ui card"> 2 - <div id="profile-avatar" class="content gt-df"> 2 + <div id="profile-avatar" class="content tw-flex"> 3 3 {{if eq .SignedUserID .ContextUser.ID}} 4 4 <a class="image" href="{{AppSubUrl}}/user/settings" data-tooltip-content="{{ctx.Locale.Tr "user.change_avatar"}}"> 5 5 {{/* the size doesn't take affect (and no need to take affect), image size(width) should be controlled by the parent container since this is not a flex layout*/}} ··· 30 30 {{if .ContextUser.Location}} 31 31 <li> 32 32 {{svg "octicon-location"}} 33 - <span class="gt-f1">{{.ContextUser.Location}}</span> 33 + <span class="tw-flex-1">{{.ContextUser.Location}}</span> 34 34 {{if .ContextUserLocationMapURL}} 35 35 <a href="{{.ContextUserLocationMapURL}}" rel="nofollow noreferrer" data-tooltip-content="{{ctx.Locale.Tr "user.show_on_map"}}"> 36 36 {{svg "octicon-link-external"}} ··· 41 41 {{if (eq .SignedUserID .ContextUser.ID)}} 42 42 <li> 43 43 {{svg "octicon-mail"}} 44 - <a class="gt-f1" href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a> 44 + <a class="tw-flex-1" href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a> 45 45 <a href="{{AppSubUrl}}/user/settings#privacy-user-settings"> 46 46 {{if .ShowUserEmail}} 47 47 <i data-tooltip-content="{{ctx.Locale.Tr "user.email_visibility.limited"}}">
+1 -1
templates/shared/variables/variable_list.tmpl
··· 16 16 {{if .Variables}} 17 17 <div class="flex-list"> 18 18 {{range .Variables}} 19 - <div class="flex-item gt-ac"> 19 + <div class="flex-item tw-items-center"> 20 20 <div class="flex-item-leading"> 21 21 {{svg "octicon-pencil" 32}} 22 22 </div>
+4 -3
templates/status/500.tmpl
··· 16 16 </head> 17 17 <body> 18 18 <div class="full height"> 19 - <nav class="ui secondary menu gt-border-secondary-bottom"> 20 - <div class="ui container gt-df"> 21 - <div class="item gt-f1"> 19 + <nav class="ui secondary menu"> 20 + <div class="ui container tw-flex"> 21 + <div class="item tw-flex-1"> 22 22 <a href="{{AppSubUrl}}/" aria-label="{{ctx.Locale.Tr "home"}}"> 23 23 <img width="30" height="30" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}" aria-hidden="true"> 24 24 </a> ··· 28 28 </div> 29 29 </div> 30 30 </nav> 31 + <div class="divider gt-my-0"></div> 31 32 <div role="main" class="page-content status-page-500"> 32 33 <div class="ui container" > 33 34 <style> .ui.message.flash-message { text-align: left; } </style>
+1 -1
templates/user/auth/reset_passwd.tmpl
··· 51 51 <div class="inline field"> 52 52 <button class="ui primary button">{{ctx.Locale.Tr "auth.reset_password_helper"}}</button> 53 53 {{if and .has_two_factor (not .scratch_code)}} 54 - <a href="{{.Link}}?code={{.Code}}&amp;scratch_code=true">{{ctx.Locale.Tr "auth.use_scratch_code"}}</a> 54 + <a href="?code={{.Code}}&scratch_code=true">{{ctx.Locale.Tr "auth.use_scratch_code"}}</a> 55 55 {{end}} 56 56 </div> 57 57 {{else}}
+3 -3
templates/user/auth/signin_inner.tmpl
··· 54 54 {{ctx.Locale.Tr "sign_in_or"}} 55 55 </div> 56 56 <div id="oauth2-login-navigator" class="gt-py-2"> 57 - <div class="gt-df gt-fc gt-jc"> 58 - <div id="oauth2-login-navigator-inner" class="gt-df gt-fc gt-fw gt-ac gt-gap-3"> 57 + <div class="tw-flex tw-flex-col tw-justify-center"> 58 + <div id="oauth2-login-navigator-inner" class="tw-flex tw-flex-col tw-flex-wrap tw-items-center tw-gap-2"> 59 59 {{range $provider := .OAuth2Providers}} 60 - <a class="{{$provider.Name}} ui button gt-df gt-ac gt-jc gt-py-3 tw-w-full oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$provider.DisplayName}}"> 60 + <a class="{{$provider.Name}} ui button tw-flex tw-items-center tw-justify-center gt-py-3 tw-w-full oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$provider.DisplayName}}"> 61 61 {{$provider.IconHTML 28}} 62 62 {{ctx.Locale.Tr "sign_in_with_provider" $provider.DisplayName}} 63 63 </a>
+3 -3
templates/user/auth/signup_inner.tmpl
··· 59 59 {{ctx.Locale.Tr "sign_in_or"}} 60 60 </div> 61 61 <div id="oauth2-login-navigator" class="gt-py-2"> 62 - <div class="gt-df gt-fc gt-jc"> 63 - <div id="oauth2-login-navigator-inner" class="gt-df gt-fc gt-fw gt-ac gt-gap-3"> 62 + <div class="tw-flex tw-flex-col tw-justify-center"> 63 + <div id="oauth2-login-navigator-inner" class="tw-flex tw-flex-col tw-flex-wrap tw-items-center tw-gap-2"> 64 64 {{range $provider := .OAuth2Providers}} 65 - <a class="{{$provider.Name}} ui button gt-df gt-ac gt-jc gt-py-3 tw-w-full oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$provider.DisplayName}}"> 65 + <a class="{{$provider.Name}} ui button tw-flex tw-items-center tw-justify-center gt-py-3 tw-w-full oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$provider.DisplayName}}"> 66 66 {{$provider.IconHTML 28}} 67 67 {{ctx.Locale.Tr "sign_in_with_provider" $provider.DisplayName}} 68 68 </a>
+2 -2
templates/user/auth/webauthn.tmpl
··· 10 10 {{template "base/alert" .}} 11 11 <p>{{ctx.Locale.Tr "webauthn_sign_in"}}</p> 12 12 </div> 13 - <div class="ui attached segment gt-df gt-ac gt-jc gt-gap-2 gt-py-3"> 14 - <div class="is-loading" style="width: 40px; height: 40px"></div> 13 + <div class="ui attached segment tw-flex tw-items-center tw-justify-center tw-gap-1 gt-py-3"> 14 + <div class="is-loading tw-w-[40px] tw-h-[40px]"></div> 15 15 {{ctx.Locale.Tr "webauthn_press_button"}} 16 16 </div> 17 17 {{if .HasTwoFactor}}
+3 -3
templates/user/dashboard/feeds.tmpl
··· 4 4 <div class="flex-item-leading"> 5 5 {{ctx.AvatarUtils.AvatarByAction .}} 6 6 </div> 7 - <div class="flex-item-main gt-gap-3"> 7 + <div class="flex-item-main tw-gap-2"> 8 8 <div> 9 9 {{if gt .ActUser.ID 0}} 10 10 <a href="{{AppSubUrl}}/{{(.GetActUserName ctx) | PathEscape}}" title="{{.GetActDisplayNameTitle ctx}}">{{.GetActDisplayName ctx}}</a> ··· 84 84 {{$push := ActionContent2Commits .}} 85 85 {{$repoLink := (.GetRepoLink ctx)}} 86 86 {{$repo := .Repo}} 87 - <div class="gt-df gt-fc gt-gap-2"> 87 + <div class="tw-flex tw-flex-col tw-gap-1"> 88 88 {{range $push.Commits}} 89 89 {{$commitLink := printf "%s/commit/%s" $repoLink .Sha1}} 90 90 <div class="flex-text-block"> ··· 107 107 <a href="{{.GetCommentLink ctx}}" class="text truncate issue title">{{(.GetIssueTitle ctx) | RenderEmoji $.Context | RenderCodeBlock}}</a> 108 108 {{$comment := index .GetIssueInfos 1}} 109 109 {{if $comment}} 110 - <div class="markup gt-font-14">{{RenderMarkdownToHtml ctx $comment}}</div> 110 + <div class="markup tw-text-14">{{RenderMarkdownToHtml ctx $comment}}</div> 111 111 {{end}} 112 112 {{else if .GetOpType.InActions "merge_pull_request"}} 113 113 <div class="flex-item-body text black">{{index .GetIssueInfos 1}}</div>
+17 -16
templates/user/dashboard/issues.tmpl
··· 2 2 <div role="main" aria-label="{{.Title}}" class="page-content dashboard issues"> 3 3 {{template "user/dashboard/navbar" .}} 4 4 <div class="ui container"> 5 + {{template "base/alert" .}} 5 6 <div class="flex-container"> 6 7 <div class="flex-container-nav"> 7 8 <div class="ui secondary vertical filter menu tw-bg-transparent"> 8 - <a class="{{if eq .ViewType "your_repositories"}}active{{end}} item" href="{{.Link}}?type=your_repositories&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 9 + <a class="{{if eq .ViewType "your_repositories"}}active{{end}} item" href="?type=your_repositories&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 9 10 {{ctx.Locale.Tr "home.issues.in_your_repos"}} 10 11 <strong>{{CountFmt .IssueStats.YourRepositoriesCount}}</strong> 11 12 </a> 12 - <a class="{{if eq .ViewType "assigned"}}active{{end}} item" href="{{.Link}}?type=assigned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 13 + <a class="{{if eq .ViewType "assigned"}}active{{end}} item" href="?type=assigned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 13 14 {{ctx.Locale.Tr "repo.issues.filter_type.assigned_to_you"}} 14 15 <strong>{{CountFmt .IssueStats.AssignCount}}</strong> 15 16 </a> 16 - <a class="{{if eq .ViewType "created_by"}}active{{end}} item" href="{{.Link}}?type=created_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 17 + <a class="{{if eq .ViewType "created_by"}}active{{end}} item" href="?type=created_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 17 18 {{ctx.Locale.Tr "repo.issues.filter_type.created_by_you"}} 18 19 <strong>{{CountFmt .IssueStats.CreateCount}}</strong> 19 20 </a> 20 21 {{if .PageIsPulls}} 21 - <a class="{{if eq .ViewType "review_requested"}}active{{end}} item" href="{{.Link}}?type=review_requested&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 22 + <a class="{{if eq .ViewType "review_requested"}}active{{end}} item" href="?type=review_requested&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 22 23 {{ctx.Locale.Tr "repo.issues.filter_type.review_requested"}} 23 24 <strong>{{CountFmt .IssueStats.ReviewRequestedCount}}</strong> 24 25 </a> 25 - <a class="{{if eq .ViewType "reviewed_by"}}active{{end}} item" href="{{.Link}}?type=reviewed_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 26 + <a class="{{if eq .ViewType "reviewed_by"}}active{{end}} item" href="?type=reviewed_by&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 26 27 {{ctx.Locale.Tr "repo.issues.filter_type.reviewed_by_you"}} 27 28 <strong>{{CountFmt .IssueStats.ReviewedCount}}</strong> 28 29 </a> 29 30 {{end}} 30 - <a class="{{if eq .ViewType "mentioned"}}active{{end}} item" href="{{.Link}}?type=mentioned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 31 + <a class="{{if eq .ViewType "mentioned"}}active{{end}} item" href="?type=mentioned&sort={{$.SortType}}&state={{.State}}&q={{$.Keyword}}"> 31 32 {{ctx.Locale.Tr "repo.issues.filter_type.mentioning_you"}} 32 33 <strong>{{CountFmt .IssueStats.MentionCount}}</strong> 33 34 </a> ··· 36 37 <div class="flex-container-main content"> 37 38 <div class="list-header"> 38 39 <div class="small-menu-items ui compact tiny menu list-header-toggle"> 39 - <a class="item{{if not .IsShowClosed}} active{{end}}" href="{{.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state=open&q={{$.Keyword}}"> 40 + <a class="item{{if not .IsShowClosed}} active{{end}}" href="?type={{$.ViewType}}&sort={{$.SortType}}&state=open&q={{$.Keyword}}"> 40 41 {{svg "octicon-issue-opened" 16 "gt-mr-3"}} 41 42 {{ctx.Locale.PrettyNumber .IssueStats.OpenCount}}&nbsp;{{ctx.Locale.Tr "repo.issues.open_title"}} 42 43 </a> 43 - <a class="item{{if .IsShowClosed}} active{{end}}" href="{{.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state=closed&q={{$.Keyword}}"> 44 + <a class="item{{if .IsShowClosed}} active{{end}}" href="?type={{$.ViewType}}&sort={{$.SortType}}&state=closed&q={{$.Keyword}}"> 44 45 {{svg "octicon-issue-closed" 16 "gt-mr-3"}} 45 46 {{ctx.Locale.PrettyNumber .IssueStats.ClosedCount}}&nbsp;{{ctx.Locale.Tr "repo.issues.closed_title"}} 46 47 </a> ··· 62 63 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 63 64 </span> 64 65 <div class="menu"> 65 - <a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort=recentupdate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> 66 - <a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort=leastupdate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> 67 - <a class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort=latest&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> 68 - <a class="{{if eq .SortType "oldest"}}active {{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort=oldest&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 69 - <a class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort=mostcomment&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a> 70 - <a class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort=leastcomment&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a> 71 - <a class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort=nearduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a> 72 - <a class="{{if eq .SortType "farduedate"}}active {{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort=farduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a> 66 + <a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=recentupdate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> 67 + <a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=leastupdate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> 68 + <a class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="?type={{$.ViewType}}&sort=latest&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> 69 + <a class="{{if eq .SortType "oldest"}}active {{end}}item" href="?type={{$.ViewType}}&sort=oldest&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 70 + <a class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="?type={{$.ViewType}}&sort=mostcomment&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a> 71 + <a class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="?type={{$.ViewType}}&sort=leastcomment&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a> 72 + <a class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=nearduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a> 73 + <a class="{{if eq .SortType "farduedate"}}active {{end}}item" href="?type={{$.ViewType}}&sort=farduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a> 73 74 </div> 74 75 </div> 75 76 </div>
+10 -10
templates/user/dashboard/milestones.tmpl
··· 12 12 <div class="divider"></div> 13 13 {{range .Repos}} 14 14 {{with $Repo := .}} 15 - <a class="{{range $.RepoIDs}}{{if eq . $Repo.ID}}active{{end}}{{end}} repo name item" href="{{$.Link}}?repos=[ 15 + <a class="{{range $.RepoIDs}}{{if eq . $Repo.ID}}active{{end}}{{end}} repo name item" href="?repos=[ 16 16 {{- with $include := true -}} 17 17 {{- range $.RepoIDs -}} 18 18 {{- if eq . $Repo.ID -}} ··· 36 36 <div class="flex-container-main content"> 37 37 <div class="list-header"> 38 38 <div class="small-menu-items ui compact tiny menu list-header-toggle"> 39 - <a class="item{{if not .IsShowClosed}} active{{end}}" href="{{.Link}}?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort={{$.SortType}}&state=open&q={{$.Keyword}}"> 39 + <a class="item{{if not .IsShowClosed}} active{{end}}" href="?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort={{$.SortType}}&state=open&q={{$.Keyword}}"> 40 40 {{svg "octicon-milestone" 16 "gt-mr-3"}} 41 41 {{ctx.Locale.PrettyNumber .MilestoneStats.OpenCount}}&nbsp;{{ctx.Locale.Tr "repo.issues.open_title"}} 42 42 </a> 43 - <a class="item{{if .IsShowClosed}} active{{end}}" href="{{.Link}}?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort={{$.SortType}}&state=closed&q={{$.Keyword}}"> 43 + <a class="item{{if .IsShowClosed}} active{{end}}" href="?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort={{$.SortType}}&state=closed&q={{$.Keyword}}"> 44 44 {{svg "octicon-check" 16 "gt-mr-3"}} 45 45 {{ctx.Locale.PrettyNumber .MilestoneStats.ClosedCount}}&nbsp;{{ctx.Locale.Tr "repo.issues.closed_title"}} 46 46 </a> ··· 59 59 </span> 60 60 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 61 61 <div class="menu"> 62 - <a class="{{if or (eq .SortType "closestduedate") (not .SortType)}}active {{end}}item" href="{{$.Link}}?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=closestduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.earliest_due_data"}}</a> 63 - <a class="{{if eq .SortType "furthestduedate"}}active {{end}}item" href="{{$.Link}}?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=furthestduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.latest_due_date"}}</a> 64 - <a class="{{if eq .SortType "leastcomplete"}}active {{end}}item" href="{{$.Link}}?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=leastcomplete&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_complete"}}</a> 65 - <a class="{{if eq .SortType "mostcomplete"}}active {{end}}item" href="{{$.Link}}?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=mostcomplete&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_complete"}}</a> 66 - <a class="{{if eq .SortType "mostissues"}}active {{end}}item" href="{{$.Link}}?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=mostissues&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_issues"}}</a> 67 - <a class="{{if eq .SortType "leastissues"}}active {{end}}item" href="{{$.Link}}?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=leastissues&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_issues"}}</a> 62 + <a class="{{if or (eq .SortType "closestduedate") (not .SortType)}}active {{end}}item" href="?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=closestduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.earliest_due_data"}}</a> 63 + <a class="{{if eq .SortType "furthestduedate"}}active {{end}}item" href="?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=furthestduedate&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.latest_due_date"}}</a> 64 + <a class="{{if eq .SortType "leastcomplete"}}active {{end}}item" href="?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=leastcomplete&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_complete"}}</a> 65 + <a class="{{if eq .SortType "mostcomplete"}}active {{end}}item" href="?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=mostcomplete&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_complete"}}</a> 66 + <a class="{{if eq .SortType "mostissues"}}active {{end}}item" href="?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=mostissues&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.most_issues"}}</a> 67 + <a class="{{if eq .SortType "leastissues"}}active {{end}}item" href="?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=leastissues&state={{$.State}}&q={{$.Keyword}}">{{ctx.Locale.Tr "repo.milestones.filter_sort.least_issues"}}</a> 68 68 </div> 69 69 </div> 70 70 </div> ··· 79 79 {{svg "octicon-milestone" 16}} 80 80 <a class="muted" href="{{.Repo.Link}}/milestone/{{.ID}}">{{.Name}}</a> 81 81 </h3> 82 - <div class="gt-df gt-ac"> 82 + <div class="tw-flex tw-items-center"> 83 83 <span class="gt-mr-3">{{.Completeness}}%</span> 84 84 <progress value="{{.Completeness}}" max="100"></progress> 85 85 </div>
+2 -2
templates/user/dashboard/navbar.tmpl
··· 78 78 79 79 {{if .ContextUser.IsOrganization}} 80 80 <div class="right menu"> 81 - <a class="{{if .PageIsNews}}active {{end}}item gt-ml-auto" href="{{.ContextUser.DashboardLink}}{{if .Team}}/{{PathEscape .Team.Name}}{{end}}"> 81 + <a class="{{if .PageIsNews}}active {{end}}item tw-ml-auto" href="{{.ContextUser.DashboardLink}}{{if .Team}}/{{PathEscape .Team.Name}}{{end}}"> 82 82 {{svg "octicon-rss"}}&nbsp;{{ctx.Locale.Tr "activities"}} 83 83 </a> 84 84 {{if not .UnitIssuesGlobalDisabled}} ··· 105 105 {{end}} 106 106 </div> 107 107 </div> 108 - <div class="divider"></div> 108 + <div class="divider tw-mt-0"></div>
+8 -8
templates/user/notification/notification_div.tmpl
··· 1 1 <div role="main" aria-label="{{.Title}}" class="page-content user notification" id="notification_div" data-sequence-number="{{.SequenceNumber}}"> 2 2 <div class="ui container"> 3 3 {{$notificationUnreadCount := call .NotificationUnreadCount}} 4 - <div class="gt-df gt-ac gt-sb gt-mb-4"> 4 + <div class="tw-flex tw-items-center tw-justify-between gt-mb-4"> 5 5 <div class="small-menu-items ui compact tiny menu"> 6 6 <a class="{{if eq .Status 1}}active {{end}}item" href="{{AppSubUrl}}/notifications?q=unread"> 7 7 {{ctx.Locale.Tr "notification.unread"}} ··· 25 25 <div class="gt-p-0"> 26 26 <div id="notification_table"> 27 27 {{if not .Notifications}} 28 - <div class="gt-df gt-ac gt-fc gt-p-4"> 28 + <div class="tw-flex tw-items-center tw-flex-col gt-p-4"> 29 29 {{svg "octicon-inbox" 56 "gt-mb-4"}} 30 30 {{if eq .Status 1}} 31 31 {{ctx.Locale.Tr "notification.no_unread"}} ··· 35 35 </div> 36 36 {{else}} 37 37 {{range $notification := .Notifications}} 38 - <div class="notifications-item gt-df gt-ac gt-fw gt-gap-3 gt-p-3" id="notification_{{.ID}}" data-status="{{.Status}}"> 38 + <div class="notifications-item tw-flex tw-items-center tw-flex-wrap tw-gap-2 gt-p-3" id="notification_{{.ID}}" data-status="{{.Status}}"> 39 39 <div class="notifications-icon gt-ml-3 gt-mr-2 tw-self-start gt-mt-2"> 40 40 {{if .Issue}} 41 41 {{template "shared/issueicon" .Issue}} ··· 43 43 {{svg "octicon-repo" 16 "text grey"}} 44 44 {{end}} 45 45 </div> 46 - <a class="notifications-link gt-df gt-f1 gt-fc silenced" href="{{.Link ctx}}"> 47 - <div class="notifications-top-row gt-font-13"> 46 + <a class="notifications-link tw-flex tw-flex-1 tw-flex-col silenced" href="{{.Link ctx}}"> 47 + <div class="notifications-top-row tw-text-13"> 48 48 {{.Repository.FullName}} {{if .Issue}}<span class="text light-3">#{{.Issue.Index}}</span>{{end}} 49 49 {{if eq .Status 3}} 50 50 {{svg "octicon-pin" 13 "text blue gt-mt-1 gt-ml-2"}} 51 51 {{end}} 52 52 </div> 53 - <div class="notifications-bottom-row gt-font-16 gt-py-1"> 53 + <div class="notifications-bottom-row tw-text-16 gt-py-1"> 54 54 <span class="issue-title"> 55 55 {{if .Issue}} 56 56 {{.Issue.Title | RenderEmoji $.Context | RenderCodeBlock}} ··· 60 60 </span> 61 61 </div> 62 62 </a> 63 - <div class="notifications-updated gt-ac gt-mr-3"> 63 + <div class="notifications-updated tw-items-center gt-mr-3"> 64 64 {{if .Issue}} 65 65 {{TimeSinceUnix .Issue.UpdatedUnix ctx.Locale}} 66 66 {{else}} 67 67 {{TimeSinceUnix .UpdatedUnix ctx.Locale}} 68 68 {{end}} 69 69 </div> 70 - <div class="notifications-buttons gt-ac gt-je gt-gap-2 gt-px-2"> 70 + <div class="notifications-buttons tw-items-center tw-justify-end tw-gap-1 gt-px-2"> 71 71 {{if ne .Status 3}} 72 72 <form action="{{AppSubUrl}}/notifications/status" method="post"> 73 73 {{$.CsrfTokenHtml}}
+17 -17
templates/user/notification/notification_subscriptions.tmpl
··· 11 11 </div> 12 12 <div class="ui bottom attached active tab segment"> 13 13 {{if eq .Status 1}} 14 - <div class="gt-df gt-sb"> 15 - <div class="gt-df"> 14 + <div class="tw-flex tw-justify-between"> 15 + <div class="tw-flex"> 16 16 <div class="small-menu-items ui compact tiny menu"> 17 - <a class="{{if eq .State "all"}}active {{end}}item" href="{{$.Link}}?sort={{$.SortType}}&state=all&issueType={{$.IssueType}}&labels={{$.Labels}}"> 17 + <a class="{{if eq .State "all"}}active {{end}}item" href="?sort={{$.SortType}}&state=all&issueType={{$.IssueType}}&labels={{$.Labels}}"> 18 18 {{ctx.Locale.Tr "all"}} 19 19 </a> 20 - <a class="{{if eq .State "open"}}active {{end}}item" href="{{$.Link}}?sort={{$.SortType}}&state=open&issueType={{$.IssueType}}&labels={{$.Labels}}"> 20 + <a class="{{if eq .State "open"}}active {{end}}item" href="?sort={{$.SortType}}&state=open&issueType={{$.IssueType}}&labels={{$.Labels}}"> 21 21 {{svg "octicon-issue-opened" 16 "gt-mr-3"}} 22 22 {{ctx.Locale.Tr "repo.issues.open_title"}} 23 23 </a> 24 - <a class="{{if eq .State "closed"}}active {{end}}item" href="{{$.Link}}?sort={{$.SortType}}&state=closed&issueType={{$.IssueType}}&labels={{$.Labels}}"> 24 + <a class="{{if eq .State "closed"}}active {{end}}item" href="?sort={{$.SortType}}&state=closed&issueType={{$.IssueType}}&labels={{$.Labels}}"> 25 25 {{svg "octicon-issue-closed" 16 "gt-mr-3"}} 26 26 {{ctx.Locale.Tr "repo.issues.closed_title"}} 27 27 </a> 28 28 </div> 29 29 </div> 30 - <div class="gt-df gt-sb"> 30 + <div class="tw-flex tw-justify-between"> 31 31 <div class="ui right aligned secondary filter menu labels"> 32 32 <!-- Type --> 33 33 <div class="ui dropdown type jump item"> ··· 36 36 </span> 37 37 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 38 38 <div class="menu"> 39 - <a class="{{if or (eq .IssueType "all") (not .IssueType)}}active {{end}}item" href="{{$.Link}}?sort={{$.SortType}}&state={{$.State}}&issueType=all&labels={{$.Labels}}">{{ctx.Locale.Tr "all"}}</a> 40 - <a class="{{if eq .IssueType "issues"}}active {{end}}item" href="{{$.Link}}?sort={{$.SortType}}&state={{$.State}}&issueType=issues&labels={{$.Labels}}">{{ctx.Locale.Tr "issues"}}</a> 41 - <a class="{{if eq .IssueType "pulls"}}active {{end}}item" href="{{$.Link}}?sort={{$.SortType}}&state={{$.State}}&issueType=pulls&labels={{$.Labels}}">{{ctx.Locale.Tr "pull_requests"}}</a> 39 + <a class="{{if or (eq .IssueType "all") (not .IssueType)}}active {{end}}item" href="?sort={{$.SortType}}&state={{$.State}}&issueType=all&labels={{$.Labels}}">{{ctx.Locale.Tr "all"}}</a> 40 + <a class="{{if eq .IssueType "issues"}}active {{end}}item" href="?sort={{$.SortType}}&state={{$.State}}&issueType=issues&labels={{$.Labels}}">{{ctx.Locale.Tr "issues"}}</a> 41 + <a class="{{if eq .IssueType "pulls"}}active {{end}}item" href="?sort={{$.SortType}}&state={{$.State}}&issueType=pulls&labels={{$.Labels}}">{{ctx.Locale.Tr "pull_requests"}}</a> 42 42 </div> 43 43 </div> 44 44 ··· 49 49 </span> 50 50 {{svg "octicon-triangle-down" 14 "dropdown icon"}} 51 51 <div class="menu"> 52 - <a class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="{{$.Link}}?sort=latest&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> 53 - <a class="{{if eq .SortType "oldest"}}active {{end}}item" href="{{$.Link}}?sort=oldest&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 54 - <a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="{{$.Link}}?sort=recentupdate&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> 55 - <a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="{{$.Link}}?sort=leastupdate&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> 56 - <a class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="{{$.Link}}?sort=mostcomment&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a> 57 - <a class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="{{$.Link}}?sort=leastcomment&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a> 58 - <a class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="{{$.Link}}?sort=nearduedate&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a> 59 - <a class="{{if eq .SortType "farduedate"}}active {{end}}item" href="{{$.Link}}?sort=farduedate&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a> 52 + <a class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="?sort=latest&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.latest"}}</a> 53 + <a class="{{if eq .SortType "oldest"}}active {{end}}item" href="?sort=oldest&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.oldest"}}</a> 54 + <a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="?sort=recentupdate&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.recentupdate"}}</a> 55 + <a class="{{if eq .SortType "leastupdate"}}active {{end}}item" href="?sort=leastupdate&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastupdate"}}</a> 56 + <a class="{{if eq .SortType "mostcomment"}}active {{end}}item" href="?sort=mostcomment&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.mostcomment"}}</a> 57 + <a class="{{if eq .SortType "leastcomment"}}active {{end}}item" href="?sort=leastcomment&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.leastcomment"}}</a> 58 + <a class="{{if eq .SortType "nearduedate"}}active {{end}}item" href="?sort=nearduedate&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.nearduedate"}}</a> 59 + <a class="{{if eq .SortType "farduedate"}}active {{end}}item" href="?sort=farduedate&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{ctx.Locale.Tr "repo.issues.filter_sort.farduedate"}}</a> 60 60 </div> 61 61 </div> 62 62 </div>
+2 -2
templates/user/settings/account.tmpl
··· 46 46 <form action="{{AppSubUrl}}/user/settings/account/email" class="ui form" method="post"> 47 47 {{$.CsrfTokenHtml}} 48 48 <input name="_method" type="hidden" value="NOTIFICATION"> 49 - <div class="gt-df gt-fw gt-gap-3"> 49 + <div class="tw-flex tw-flex-wrap tw-gap-2"> 50 50 <div class="ui selection dropdown"> 51 51 <input name="preference" type="hidden" value="{{.EmailNotificationsPreference}}"> 52 52 {{svg "octicon-triangle-down" 14 "dropdown icon"}} ··· 136 136 <div class="ui red message"> 137 137 <p class="text left">{{svg "octicon-alert"}} {{ctx.Locale.Tr "settings.delete_prompt"}}</p> 138 138 {{if .UserDeleteWithComments}} 139 - <p class="text left gt-font-semibold">{{ctx.Locale.Tr "settings.delete_with_all_comments" .UserDeleteWithCommentsMaxTime}}</p> 139 + <p class="text left tw-font-semibold">{{ctx.Locale.Tr "settings.delete_with_all_comments" .UserDeleteWithCommentsMaxTime}}</p> 140 140 {{end}} 141 141 </div> 142 142 <form class="ui form ignore-dirty" id="delete-form" action="{{AppSubUrl}}/user/settings/account/delete" method="post">
+1 -1
templates/user/settings/applications_oauth2_list.tmpl
··· 4 4 {{ctx.Locale.Tr "settings.oauth2_application_create_description"}} 5 5 </div> 6 6 {{range .Applications}} 7 - <div class="flex-item gt-ac"> 7 + <div class="flex-item tw-items-center"> 8 8 <div class="flex-item-leading"> 9 9 {{svg "octicon-apps" 32}} 10 10 </div>
+1 -1
templates/user/settings/keys_gpg.tmpl
··· 73 73 {{ctx.Locale.Tr "settings.delete_key"}} 74 74 </button> 75 75 {{if and (not .Verified) (ne $.VerifyingID .KeyID)}} 76 - <a class="ui primary tiny button" href="{{$.Link}}?verify_gpg={{.KeyID}}">{{ctx.Locale.Tr "settings.gpg_key_verify"}}</a> 76 + <a class="ui primary tiny button" href="?verify_gpg={{.KeyID}}">{{ctx.Locale.Tr "settings.gpg_key_verify"}}</a> 77 77 {{end}} 78 78 </div> 79 79 </div>
+1 -1
templates/user/settings/keys_ssh.tmpl
··· 61 61 {{ctx.Locale.Tr "settings.delete_key"}} 62 62 </button> 63 63 {{if and (not .Verified) (ne $.VerifyingFingerprint .Fingerprint)}} 64 - <a class="ui primary tiny button" href="{{$.Link}}?verify_ssh={{.Fingerprint}}">{{ctx.Locale.Tr "settings.ssh_key_verify"}}</a> 64 + <a class="ui primary tiny button" href="?verify_ssh={{.Fingerprint}}">{{ctx.Locale.Tr "settings.ssh_key_verify"}}</a> 65 65 {{end}} 66 66 </div> 67 67 </div>
+2 -2
templates/user/settings/repos.tmpl
··· 30 30 <span><a href="{{$repo.BaseRepo.Link}}">{{$repo.BaseRepo.OwnerName}}/{{$repo.BaseRepo.Name}}</a></span> 31 31 {{end}} 32 32 {{else}} 33 - <span class="icon gt-dib gt-pt-3">{{svg "octicon-file-directory-fill"}}</span> 34 - <span class="name gt-dib gt-pt-3">{{$.ContextUser.Name}}/{{$dir}}</span> 33 + <span class="icon tw-inline-block gt-pt-3">{{svg "octicon-file-directory-fill"}}</span> 34 + <span class="name tw-inline-block gt-pt-3">{{$.ContextUser.Name}}/{{$dir}}</span> 35 35 <div class="tw-float-right"> 36 36 {{if $.allowAdopt}} 37 37 <button class="ui button primary show-modal gt-p-3" data-modal="#adopt-unadopted-modal-{{$dirI}}"><span class="icon">{{svg "octicon-plus"}}</span><span class="label">{{ctx.Locale.Tr "repo.adopt_preexisting_label"}}</span></button>
+1 -1
templates/user/settings/security/openid.tmpl
··· 7 7 {{ctx.Locale.Tr "settings.openid_desc"}} 8 8 </div> 9 9 {{range .OpenIDs}} 10 - <div class="flex-item gt-ac"> 10 + <div class="flex-item tw-items-center"> 11 11 <div class="flex-item-leading"> 12 12 {{svg "fontawesome-openid" 20}} 13 13 </div>
+1 -1
templates/webhook/new.tmpl
··· 1 1 <h4 class="ui top attached header"> 2 2 {{.CustomHeaderTitle}} 3 3 <div class="ui right type dropdown"> 4 - <div class="text gt-df gt-ac"> 4 + <div class="text tw-flex tw-items-center"> 5 5 {{template "shared/webhook/icon" (dict "Size" 20 "HookType" .ctxData.HookType)}} 6 6 {{ctx.Locale.Tr (print "repo.settings.web_hook_name_" .ctxData.HookType)}} 7 7 </div>
+121
tests/integration/actions_trigger_test.go
··· 11 11 "time" 12 12 13 13 actions_model "code.gitea.io/gitea/models/actions" 14 + "code.gitea.io/gitea/models/db" 15 + git_model "code.gitea.io/gitea/models/git" 14 16 issues_model "code.gitea.io/gitea/models/issues" 17 + repo_model "code.gitea.io/gitea/models/repo" 15 18 unit_model "code.gitea.io/gitea/models/unit" 16 19 "code.gitea.io/gitea/models/unittest" 17 20 user_model "code.gitea.io/gitea/models/user" 18 21 actions_module "code.gitea.io/gitea/modules/actions" 19 22 "code.gitea.io/gitea/modules/git" 23 + "code.gitea.io/gitea/modules/gitrepo" 20 24 "code.gitea.io/gitea/modules/setting" 21 25 "code.gitea.io/gitea/modules/test" 22 26 webhook_module "code.gitea.io/gitea/modules/webhook" 23 27 actions_service "code.gitea.io/gitea/services/actions" 24 28 pull_service "code.gitea.io/gitea/services/pull" 29 + release_service "code.gitea.io/gitea/services/release" 25 30 repo_service "code.gitea.io/gitea/services/repository" 26 31 files_service "code.gitea.io/gitea/services/repository/files" 27 32 ··· 275 280 assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: repo.ID})) 276 281 }) 277 282 } 283 + 284 + func TestCreateDeleteRefEvent(t *testing.T) { 285 + onGiteaRun(t, func(t *testing.T, u *url.URL) { 286 + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) 287 + 288 + // create the repo 289 + repo, err := repo_service.CreateRepository(db.DefaultContext, user2, user2, repo_service.CreateRepoOptions{ 290 + Name: "create-delete-ref-event", 291 + Description: "test create delete ref ci event", 292 + AutoInit: true, 293 + Gitignores: "Go", 294 + License: "MIT", 295 + Readme: "Default", 296 + DefaultBranch: "main", 297 + IsPrivate: false, 298 + }) 299 + assert.NoError(t, err) 300 + assert.NotEmpty(t, repo) 301 + 302 + // enable actions 303 + err = repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, []repo_model.RepoUnit{{ 304 + RepoID: repo.ID, 305 + Type: unit_model.TypeActions, 306 + }}, nil) 307 + assert.NoError(t, err) 308 + 309 + // add workflow file to the repo 310 + addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{ 311 + Files: []*files_service.ChangeRepoFile{ 312 + { 313 + Operation: "create", 314 + TreePath: ".gitea/workflows/createdelete.yml", 315 + ContentReader: strings.NewReader("name: test\non:\n [create,delete]\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n"), 316 + }, 317 + }, 318 + Message: "add workflow", 319 + OldBranch: "main", 320 + NewBranch: "main", 321 + Author: &files_service.IdentityOptions{ 322 + Name: user2.Name, 323 + Email: user2.Email, 324 + }, 325 + Committer: &files_service.IdentityOptions{ 326 + Name: user2.Name, 327 + Email: user2.Email, 328 + }, 329 + Dates: &files_service.CommitDateOptions{ 330 + Author: time.Now(), 331 + Committer: time.Now(), 332 + }, 333 + }) 334 + assert.NoError(t, err) 335 + assert.NotEmpty(t, addWorkflowToBaseResp) 336 + 337 + // Get the commit ID of the default branch 338 + gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo) 339 + assert.NoError(t, err) 340 + defer gitRepo.Close() 341 + branch, err := git_model.GetBranch(db.DefaultContext, repo.ID, repo.DefaultBranch) 342 + assert.NoError(t, err) 343 + 344 + // create a branch 345 + err = repo_service.CreateNewBranchFromCommit(db.DefaultContext, user2, repo, gitRepo, branch.CommitID, "test-create-branch") 346 + assert.NoError(t, err) 347 + run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ 348 + Title: "add workflow", 349 + RepoID: repo.ID, 350 + Event: "create", 351 + Ref: "refs/heads/test-create-branch", 352 + WorkflowID: "createdelete.yml", 353 + CommitSHA: branch.CommitID, 354 + }) 355 + assert.NotNil(t, run) 356 + 357 + // create a tag 358 + err = release_service.CreateNewTag(db.DefaultContext, user2, repo, branch.CommitID, "test-create-tag", "test create tag event") 359 + assert.NoError(t, err) 360 + run = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ 361 + Title: "add workflow", 362 + RepoID: repo.ID, 363 + Event: "create", 364 + Ref: "refs/tags/test-create-tag", 365 + WorkflowID: "createdelete.yml", 366 + CommitSHA: branch.CommitID, 367 + }) 368 + assert.NotNil(t, run) 369 + 370 + // delete the branch 371 + err = repo_service.DeleteBranch(db.DefaultContext, user2, repo, gitRepo, "test-create-branch") 372 + assert.NoError(t, err) 373 + run = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ 374 + Title: "add workflow", 375 + RepoID: repo.ID, 376 + Event: "delete", 377 + Ref: "main", 378 + WorkflowID: "createdelete.yml", 379 + CommitSHA: branch.CommitID, 380 + }) 381 + assert.NotNil(t, run) 382 + 383 + // delete the tag 384 + tag, err := repo_model.GetRelease(db.DefaultContext, repo.ID, "test-create-tag") 385 + assert.NoError(t, err) 386 + err = release_service.DeleteReleaseByID(db.DefaultContext, repo, tag, user2, true) 387 + assert.NoError(t, err) 388 + run = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ 389 + Title: "add workflow", 390 + RepoID: repo.ID, 391 + Event: "delete", 392 + Ref: "main", 393 + WorkflowID: "createdelete.yml", 394 + CommitSHA: branch.CommitID, 395 + }) 396 + assert.NotNil(t, run) 397 + }) 398 + }
+6 -6
tests/integration/explore_user_test.go
··· 16 16 defer tests.PrepareTestEnv(t)() 17 17 18 18 cases := []struct{ sortOrder, expected string }{ 19 - {"", "/explore/users?sort=newest&q="}, 20 - {"newest", "/explore/users?sort=newest&q="}, 21 - {"oldest", "/explore/users?sort=oldest&q="}, 22 - {"alphabetically", "/explore/users?sort=alphabetically&q="}, 23 - {"reversealphabetically", "/explore/users?sort=reversealphabetically&q="}, 19 + {"", "?sort=newest&q="}, 20 + {"newest", "?sort=newest&q="}, 21 + {"oldest", "?sort=oldest&q="}, 22 + {"alphabetically", "?sort=alphabetically&q="}, 23 + {"reversealphabetically", "?sort=reversealphabetically&q="}, 24 24 } 25 25 for _, c := range cases { 26 26 req := NewRequest(t, "GET", "/explore/users?sort="+c.sortOrder) 27 27 resp := MakeRequest(t, req, http.StatusOK) 28 28 h := NewHTMLParser(t, resp.Body) 29 - href, _ := h.Find(`.ui.dropdown .menu a.active.item[href^="/explore/users"]`).Attr("href") 29 + href, _ := h.Find(`.ui.dropdown .menu a.active.item[href^="?sort="]`).Attr("href") 30 30 assert.Equal(t, c.expected, href) 31 31 } 32 32
+17
tests/integration/git_push_test.go
··· 69 69 return pushed, deleted 70 70 }) 71 71 }) 72 + 73 + t.Run("Push to deleted branch", func(t *testing.T) { 74 + runTestGitPush(t, u, func(t *testing.T, gitPath string) (pushed, deleted []string) { 75 + doGitPushTestRepository(gitPath, "origin", "master")(t) // make sure master is the default branch instead of a branch we are going to delete 76 + pushed = append(pushed, "master") 77 + 78 + doGitCreateBranch(gitPath, "branch-1")(t) 79 + doGitPushTestRepository(gitPath, "origin", "branch-1")(t) 80 + pushed = append(pushed, "branch-1") 81 + 82 + // delete and restore 83 + doGitPushTestRepository(gitPath, "origin", "--delete", "branch-1")(t) 84 + doGitPushTestRepository(gitPath, "origin", "branch-1")(t) 85 + 86 + return pushed, deleted 87 + }) 88 + }) 72 89 } 73 90 74 91 func runTestGitPush(t *testing.T, u *url.URL, gitOperation func(t *testing.T, gitPath string) (pushed, deleted []string)) {
+1 -1
tests/integration/issue_test.go
··· 807 807 htmlDoc := NewHTMLParser(t, resp.Body) 808 808 809 809 // Check that every link in the filter list has rel="nofollow". 810 - filterLinks := htmlDoc.Find(".issue-list-toolbar-right a[href*=\"/issues?q=\"]") 810 + filterLinks := htmlDoc.Find(".issue-list-toolbar-right a[href*=\"?q=\"]") 811 811 assert.True(t, filterLinks.Length() > 0) 812 812 filterLinks.Each(func(i int, link *goquery.Selection) { 813 813 rel, has := link.Attr("rel")
+2 -2
tests/integration/pull_merge_test.go
··· 513 513 assert.NoError(t, err) 514 514 515 515 issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "PR with conflict!"}) 516 - conflictingPR, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, issue.ID) 517 - assert.NoError(t, err) 516 + assert.NoError(t, issue.LoadPullRequest(db.DefaultContext)) 517 + conflictingPR := issue.PullRequest 518 518 519 519 // Ensure conflictedFiles is populated. 520 520 assert.Len(t, conflictingPR.ConflictedFiles, 1)
+2 -3
tests/integration/pull_update_test.go
··· 167 167 assert.NoError(t, err) 168 168 169 169 issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "Test Pull -to-update-"}) 170 - pr, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, issue.ID) 171 - assert.NoError(t, err) 170 + assert.NoError(t, issue.LoadPullRequest(db.DefaultContext)) 172 171 173 - return pr 172 + return issue.PullRequest 174 173 }
+1 -1
tests/integration/release_test.go
··· 285 285 286 286 tagNames := make([]string, 0, 5) 287 287 tags.Each(func(i int, s *goquery.Selection) { 288 - tagNames = append(tagNames, s.Find(".tag a.gt-df.gt-ac").Text()) 288 + tagNames = append(tagNames, s.Find(".tag a.tw-flex.tw-items-center").Text()) 289 289 }) 290 290 291 291 assert.EqualValues(t, []string{"v1.0", "delete-tag", "v1.1"}, tagNames)
+7 -9
tests/integration/repo_search_test.go
··· 46 46 47 47 if useExternalIndexer { 48 48 gitReference = "/commit/" 49 - executeIndexer(t, repo, code_indexer.UpdateRepoIndexer) 49 + code_indexer.UpdateRepoIndexer(repo) 50 50 } 51 51 52 52 testSearch(t, "/user2/repo1/search?q=Description&page=1", gitReference, []string{"README.md"}) ··· 58 58 repo, err = repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "glob") 59 59 assert.NoError(t, err) 60 60 61 - executeIndexer(t, repo, code_indexer.UpdateRepoIndexer) 61 + code_indexer.UpdateRepoIndexer(repo) 62 62 63 63 testSearch(t, "/user2/glob/search?q=loren&page=1", gitReference, []string{"a.txt"}) 64 - testSearch(t, "/user2/glob/search?q=file3&page=1", gitReference, []string{"x/b.txt"}) 65 - testSearch(t, "/user2/glob/search?q=file4&page=1", gitReference, []string{}) 66 - testSearch(t, "/user2/glob/search?q=file5&page=1", gitReference, []string{}) 64 + testSearch(t, "/user2/glob/search?q=loren&page=1&t=match", gitReference, []string{"a.txt"}) 65 + testSearch(t, "/user2/glob/search?q=file3&page=1", gitReference, []string{"x/b.txt", "a.txt"}) 66 + testSearch(t, "/user2/glob/search?q=file3&page=1&t=match", gitReference, []string{"x/b.txt", "a.txt"}) 67 + testSearch(t, "/user2/glob/search?q=file4&page=1&t=match", gitReference, []string{"x/b.txt", "a.txt"}) 68 + testSearch(t, "/user2/glob/search?q=file5&page=1&t=match", gitReference, []string{"x/b.txt", "a.txt"}) 67 69 } 68 70 } 69 71 ··· 88 90 89 91 checkResultLinks(t, gitRef, doc) 90 92 } 91 - 92 - func executeIndexer(t *testing.T, repo *repo_model.Repository, op func(*repo_model.Repository)) { 93 - op(repo) 94 - }
+79
tools/generate-images.js
··· 1 + #!/usr/bin/env node 2 + import imageminZopfli from 'imagemin-zopfli'; // eslint-disable-line i/no-unresolved 3 + import {loadSVGFromString, Canvas, Rect, util} from 'fabric/node'; // eslint-disable-line i/no-unresolved 4 + import {optimize} from 'svgo'; 5 + import {readFile, writeFile} from 'node:fs/promises'; 6 + import {argv, exit} from 'node:process'; 7 + 8 + function doExit(err) { 9 + if (err) console.error(err); 10 + exit(err ? 1 : 0); 11 + } 12 + 13 + async function generate(svg, path, {size, bg}) { 14 + const outputFile = new URL(path, import.meta.url); 15 + 16 + if (String(outputFile).endsWith('.svg')) { 17 + const {data} = optimize(svg, { 18 + plugins: [ 19 + 'preset-default', 20 + 'removeDimensions', 21 + { 22 + name: 'addAttributesToSVGElement', 23 + params: {attributes: [{width: size}, {height: size}]}, 24 + }, 25 + ], 26 + }); 27 + await writeFile(outputFile, data); 28 + return; 29 + } 30 + 31 + const {objects, options} = await loadSVGFromString(svg); 32 + const canvas = new Canvas(); 33 + canvas.setDimensions({width: size, height: size}); 34 + const ctx = canvas.getContext('2d'); 35 + ctx.scale(options.width ? (size / options.width) : 1, options.height ? (size / options.height) : 1); 36 + 37 + if (bg) { 38 + canvas.add(new Rect({ 39 + left: 0, 40 + top: 0, 41 + height: size * (1 / (size / options.height)), 42 + width: size * (1 / (size / options.width)), 43 + fill: 'white', 44 + })); 45 + } 46 + 47 + canvas.add(util.groupSVGElements(objects, options)); 48 + canvas.renderAll(); 49 + 50 + let png = Buffer.from([]); 51 + for await (const chunk of canvas.createPNGStream()) { 52 + png = Buffer.concat([png, chunk]); 53 + } 54 + 55 + png = await imageminZopfli({more: true})(png); 56 + await writeFile(outputFile, png); 57 + } 58 + 59 + async function main() { 60 + const gitea = argv.slice(2).includes('gitea'); 61 + const logoSvg = await readFile(new URL('../assets/logo.svg', import.meta.url), 'utf8'); 62 + const faviconSvg = await readFile(new URL('../assets/favicon.svg', import.meta.url), 'utf8'); 63 + 64 + await Promise.all([ 65 + generate(logoSvg, '../public/assets/img/logo.svg', {size: 32}), 66 + generate(logoSvg, '../public/assets/img/logo.png', {size: 512}), 67 + generate(faviconSvg, '../public/assets/img/favicon.svg', {size: 32}), 68 + generate(faviconSvg, '../public/assets/img/favicon.png', {size: 180}), 69 + generate(logoSvg, '../public/assets/img/avatar_default.png', {size: 200}), 70 + generate(logoSvg, '../public/assets/img/apple-touch-icon.png', {size: 180, bg: true}), 71 + gitea && generate(logoSvg, '../public/assets/img/gitea.svg', {size: 32}), 72 + ]); 73 + } 74 + 75 + try { 76 + doExit(await main()); 77 + } catch (err) { 78 + doExit(err); 79 + }
+70
tools/generate-svg.js
··· 1 + #!/usr/bin/env node 2 + import fastGlob from 'fast-glob'; 3 + import {optimize} from 'svgo'; 4 + import {parse} from 'node:path'; 5 + import {readFile, writeFile, mkdir} from 'node:fs/promises'; 6 + import {fileURLToPath} from 'node:url'; 7 + import {exit} from 'node:process'; 8 + 9 + const glob = (pattern) => fastGlob.sync(pattern, { 10 + cwd: fileURLToPath(new URL('..', import.meta.url)), 11 + absolute: true, 12 + }); 13 + 14 + function doExit(err) { 15 + if (err) console.error(err); 16 + exit(err ? 1 : 0); 17 + } 18 + 19 + async function processFile(file, {prefix, fullName} = {}) { 20 + let name; 21 + if (fullName) { 22 + name = fullName; 23 + } else { 24 + name = parse(file).name; 25 + if (prefix) name = `${prefix}-${name}`; 26 + if (prefix === 'octicon') name = name.replace(/-[0-9]+$/, ''); // chop of '-16' on octicons 27 + } 28 + 29 + // Set the `xmlns` attribute so that the files are displayable in standalone documents 30 + // The svg backend module will strip the attribute during startup for inline display 31 + const {data} = optimize(await readFile(file, 'utf8'), { 32 + plugins: [ 33 + {name: 'preset-default'}, 34 + {name: 'removeDimensions'}, 35 + {name: 'prefixIds', params: {prefix: () => name}}, 36 + {name: 'addClassesToSVGElement', params: {classNames: ['svg', name]}}, 37 + { 38 + name: 'addAttributesToSVGElement', params: { 39 + attributes: [ 40 + {'xmlns': 'http://www.w3.org/2000/svg'}, 41 + {'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'}, 42 + ], 43 + }, 44 + }, 45 + ], 46 + }); 47 + 48 + await writeFile(fileURLToPath(new URL(`../public/assets/img/svg/${name}.svg`, import.meta.url)), data); 49 + } 50 + 51 + function processFiles(pattern, opts) { 52 + return glob(pattern).map((file) => processFile(file, opts)); 53 + } 54 + 55 + async function main() { 56 + try { 57 + await mkdir(fileURLToPath(new URL('../public/assets/img/svg', import.meta.url)), {recursive: true}); 58 + } catch {} 59 + 60 + await Promise.all([ 61 + ...processFiles('node_modules/@primer/octicons/build/svg/*-16.svg', {prefix: 'octicon'}), 62 + ...processFiles('web_src/svg/*.svg'), 63 + ]); 64 + } 65 + 66 + try { 67 + doExit(await main()); 68 + } catch (err) { 69 + doExit(err); 70 + }
+1 -1
vitest.config.js
··· 6 6 test: { 7 7 include: ['web_src/**/*.test.js'], 8 8 setupFiles: ['web_src/js/vitest.setup.js'], 9 - environment: 'jsdom', 9 + environment: 'happy-dom', 10 10 testTimeout: 20000, 11 11 open: false, 12 12 allowOnly: true,
-4
web_src/css/actions.css
··· 14 14 color: var(--color-red-light); 15 15 } 16 16 17 - .runner-container .runner-basic-info .gt-dib { 18 - margin-right: 1em; 19 - } 20 - 21 17 .runner-container .runner-new-text { 22 18 color: var(--color-white); 23 19 }
+91 -34
web_src/css/base.css
··· 37 37 border-color: currentcolor; 38 38 } 39 39 40 + html, body { 41 + height: 100%; 42 + font-size: 14px; 43 + } 44 + 45 + body { 46 + line-height: 1.4285rem; 47 + font-family: var(--fonts-regular); 48 + color: var(--color-text); 49 + background-color: var(--color-body); 50 + tab-size: var(--tab-size); 51 + display: flex; 52 + flex-direction: column; 53 + overflow-x: visible; 54 + overflow-wrap: break-word; 55 + } 56 + 40 57 textarea { 41 58 font-family: var(--fonts-regular); 42 59 } ··· 60 77 font-weight: var(--font-weight-semibold); 61 78 } 62 79 63 - body { 64 - color: var(--color-text); 65 - background-color: var(--color-body); 66 - tab-size: var(--tab-size); 67 - display: flex; 68 - flex-direction: column; 69 - overflow-wrap: break-word; 80 + h1, 81 + h2, 82 + h3, 83 + h4, 84 + h5 { 85 + line-height: 1.28571429; 86 + margin: calc(2rem - 0.1428571428571429em) 0 1rem; 87 + font-weight: var(--font-weight-medium); 88 + padding: 0; 89 + } 90 + 91 + h1 { 92 + min-height: 1rem; 93 + font-size: 2rem; 94 + } 95 + 96 + h2 { 97 + font-size: 1.71428571rem; 98 + } 99 + 100 + h3 { 101 + font-size: 1.28571429rem; 102 + } 103 + 104 + h4 { 105 + font-size: 1.07142857rem; 106 + } 107 + 108 + h5 { 109 + font-size: 1rem; 110 + } 111 + 112 + h1:first-child, 113 + h2:first-child, 114 + h3:first-child, 115 + h4:first-child, 116 + h5:first-child { 117 + margin-top: 0; 118 + } 119 + 120 + h1:last-child, 121 + h2:last-child, 122 + h3:last-child, 123 + h4:last-child, 124 + h5:last-child { 125 + margin-bottom: 0; 126 + } 127 + 128 + p { 129 + margin: 0 0 1em; 130 + line-height: 1.4285; 131 + } 132 + 133 + p:first-child { 134 + margin-top: 0; 135 + } 136 + 137 + p:last-child { 138 + margin-bottom: 0; 70 139 } 71 140 72 141 table { ··· 132 201 } 133 202 134 203 ::selection { 135 - background: var(--color-primary-light-1) !important; 136 - color: var(--color-white) !important; 204 + background: var(--color-primary-light-1); 205 + color: var(--color-white); 137 206 } 138 207 139 208 ::placeholder, ··· 157 226 a { 158 227 color: var(--color-primary); 159 228 cursor: pointer; 229 + text-decoration: none; 160 230 text-decoration-skip-ink: all; 161 231 } 162 232 ··· 238 308 border-bottom-color: var(--color-secondary); 239 309 } 240 310 241 - .page-content { 242 - margin-top: 15px; 243 - } 244 - 245 - .page-content .header-wrapper, 246 - .page-content overflow-menu { 247 - margin-top: -15px !important; 248 - padding-top: 15px !important; 249 - } 250 - 251 311 /* fix Fomantic's line-height cutting off "g" on Windows Chrome with Segoe UI */ 252 312 .ui.input > input { 253 313 line-height: var(--line-height-default); ··· 294 354 .ui.action.input:not([class*="left action"]) > input:focus + .ui.dropdown.selection, 295 355 .ui.action.input:not([class*="left action"]) > input:focus + .ui.dropdown.selection:hover, 296 356 .ui.action.input:not([class*="left action"]) > input:focus + .button, 297 - .ui.action.input:not([class*="left action"]) > input:focus + .button:hover { 357 + .ui.action.input:not([class*="left action"]) > input:focus + .button:hover, 358 + .ui.action.input:not([class*="left action"]) > input:focus + .icon + .button, 359 + .ui.action.input:not([class*="left action"]) > input:focus + .icon + .button:hover { 298 360 border-left-color: var(--color-primary); 299 361 } 300 362 .ui.action.input:not([class*="left action"]) > input:focus { ··· 687 749 padding-bottom: 80px; 688 750 } 689 751 752 + .page-content.new:is(.repo,.migrate,.org), 753 + .page-content.profile:is(.user,.organization) { 754 + padding-top: 15px; 755 + } 756 + 690 757 /* overwrite semantic width of containers inside the main page content div (div with class "page-content") */ 691 758 .page-content .ui.ui.ui.container:not(.fluid) { 692 759 width: 1280px; ··· 721 788 .ui.pagination.menu .active.item { 722 789 color: var(--color-text); 723 790 background: var(--color-active); 724 - } 725 - 726 - .ui.loading.segment::before, 727 - .ui.loading.form::before { 728 - background: none; 729 - } 730 - 731 - .ui.loading.form > *, 732 - .ui.loading.segment > * { 733 - opacity: 0.35; 734 791 } 735 792 736 793 .ui.form .fields.error .field textarea, ··· 822 879 823 880 .ui.form .field.muted { 824 881 opacity: var(--opacity-disabled); 825 - } 826 - 827 - .ui.loading.loading.input > i.icon svg { 828 - visibility: hidden; 829 882 } 830 883 831 884 .text.primary { ··· 1970 2023 display: flex; 1971 2024 align-items: center; 1972 2025 justify-content: center; 2026 + } 2027 + 2028 + .ui.icon.input > i.icon { 2029 + transition: none; 1973 2030 } 1974 2031 1975 2032 .flex-items-block > .item,
+1 -2
web_src/css/dashboard.css
··· 78 78 } 79 79 80 80 .dashboard .dashboard-navbar { 81 - padding-left: 0.5rem; 82 - padding-right: 0.5rem; 81 + padding: 4px 12px; 83 82 } 84 83 85 84 .dashboard .dashboard-navbar .right.menu {
-6
web_src/css/features/gitgraph.css
··· 4 4 min-height: 350px; 5 5 } 6 6 7 - #git-graph-container > .ui.segment.loading { 8 - border: 0; 9 - z-index: 1; 10 - min-height: 246px; 11 - } 12 - 13 7 #git-graph-container h2 { 14 8 display: flex; 15 9 justify-content: space-between;
-67
web_src/css/helpers.css
··· 2 2 Gitea's tailwind-style CSS helper classes have `gt-` prefix. 3 3 Gitea's private styles use `g-` prefix. 4 4 */ 5 - .gt-df { display: flex !important; } 6 - .gt-dib { display: inline-block !important; } 7 - .gt-ac { align-items: center !important; } 8 - .gt-jc { justify-content: center !important; } 9 - .gt-je { justify-content: flex-end !important; } 10 - .gt-sb { justify-content: space-between !important; } 11 - .gt-fc { flex-direction: column !important; } 12 - .gt-f1 { flex: 1 !important; } 13 - .gt-fw { flex-wrap: wrap !important; } 14 - .gt-vm { vertical-align: middle !important; } 15 5 16 6 .gt-mono { 17 7 font-family: var(--fonts-monospace) !important; ··· 46 36 text-overflow: ellipsis; 47 37 } 48 38 49 - .gt-font-light { font-weight: var(--font-weight-light) !important; } 50 - .gt-font-normal { font-weight: var(--font-weight-normal) !important; } 51 - .gt-font-medium { font-weight: var(--font-weight-medium) !important; } 52 - .gt-font-semibold { font-weight: var(--font-weight-semibold) !important; } 53 - .gt-font-bold { font-weight: var(--font-weight-bold) !important; } 54 - 55 - .gt-rounded { border-radius: var(--border-radius) !important; } 56 - .gt-rounded-top { border-radius: var(--border-radius) var(--border-radius) 0 0 !important; } 57 - .gt-rounded-bottom { border-radius: 0 0 var(--border-radius) var(--border-radius) !important; } 58 - .gt-rounded-left { border-radius: var(--border-radius) 0 0 var(--border-radius) !important; } 59 - .gt-rounded-right { border-radius: 0 var(--border-radius) var(--border-radius) 0 !important; } 60 - 61 - .gt-border-secondary { border: 1px solid var(--color-secondary) !important; } 62 - .gt-border-secondary-top { border-top: 1px solid var(--color-secondary) !important; } 63 - .gt-border-secondary-bottom { border-bottom: 1px solid var(--color-secondary) !important; } 64 - .gt-border-secondary-left { border-left: 1px solid var(--color-secondary) !important; } 65 - .gt-border-secondary-right { border-right: 1px solid var(--color-secondary) !important; } 66 - 67 39 .interact-fg { color: inherit !important; } 68 40 .interact-fg:hover { color: var(--color-primary) !important; } 69 41 .interact-fg:active { color: var(--color-primary-active) !important; } ··· 121 93 .gt-my-4 { margin-top: 1rem !important; margin-bottom: 1rem !important; } 122 94 .gt-my-5 { margin-top: 2rem !important; margin-bottom: 2rem !important; } 123 95 124 - .gt-m-auto { margin: auto !important; } 125 - .gt-mx-auto { margin-left: auto !important; margin-right: auto !important; } 126 - .gt-my-auto { margin-top: auto !important; margin-bottom: auto !important; } 127 - .gt-mt-auto { margin-top: auto !important; } 128 - .gt-mr-auto { margin-right: auto !important; } 129 - .gt-mb-auto { margin-bottom: auto !important; } 130 - .gt-ml-auto { margin-left: auto !important; } 131 - 132 96 .gt-p-0 { padding: 0 !important; } 133 97 .gt-p-1 { padding: .125rem !important; } 134 98 .gt-p-2 { padding: .25rem !important; } ··· 177 141 .gt-py-3 { padding-top: .5rem !important; padding-bottom: .5rem !important; } 178 142 .gt-py-4 { padding-top: 1rem !important; padding-bottom: 1rem !important; } 179 143 .gt-py-5 { padding-top: 2rem !important; padding-bottom: 2rem !important; } 180 - 181 - .gt-gap-0 { gap: 0 !important; } 182 - .gt-gap-1 { gap: .125rem !important; } 183 - .gt-gap-2 { gap: .25rem !important; } 184 - .gt-gap-3 { gap: .5rem !important; } 185 - .gt-gap-4 { gap: 1rem !important; } 186 - .gt-gap-5 { gap: 2rem !important; } 187 - 188 - .gt-gap-x-0 { column-gap: 0 !important; } 189 - .gt-gap-x-1 { column-gap: .125rem !important; } 190 - .gt-gap-x-2 { column-gap: .25rem !important; } 191 - .gt-gap-x-3 { column-gap: .5rem !important; } 192 - .gt-gap-x-4 { column-gap: 1rem !important; } 193 - .gt-gap-x-5 { column-gap: 2rem !important; } 194 - 195 - .gt-gap-y-0 { row-gap: 0 !important; } 196 - .gt-gap-y-1 { row-gap: .125rem !important; } 197 - .gt-gap-y-2 { row-gap: .25rem !important; } 198 - .gt-gap-y-3 { row-gap: .5rem !important; } 199 - .gt-gap-y-4 { row-gap: 1rem !important; } 200 - .gt-gap-y-5 { row-gap: 2rem !important; } 201 - 202 - .gt-shrink-0 { flex-shrink: 0 !important; } 203 - 204 - .gt-font-12 { font-size: 12px !important } 205 - .gt-font-13 { font-size: 13px !important } 206 - .gt-font-14 { font-size: 14px !important } 207 - .gt-font-15 { font-size: 15px !important } 208 - .gt-font-16 { font-size: 16px !important } 209 - .gt-font-17 { font-size: 17px !important } 210 - .gt-font-18 { font-size: 18px !important } 211 144 212 145 /* 213 146 gt-hidden must win all other "display: xxx !important" classes to get the chance to "hide" an element.
+1
web_src/css/index.css
··· 1 1 @import "./modules/normalize.css"; 2 2 @import "./modules/animations.css"; 3 + @import "./modules/grid.css"; 3 4 @import "./modules/button.css"; 4 5 @import "./modules/select.css"; 5 6 @import "./modules/tippy.css";
+1 -1
web_src/css/modules/button.css
··· 154 154 } 155 155 156 156 .ui.basic.primary.buttons .button, 157 - .ui.basic.primary.button{ 157 + .ui.basic.primary.button { 158 158 color: var(--color-primary); 159 159 border-color: var(--color-primary); 160 160 }
+498
web_src/css/modules/grid.css
··· 1 + /* based on Fomantic UI grid module, with just the parts extracted that we use. If you find any 2 + unused rules here after refactoring, please remove them. */ 3 + 4 + .ui.grid { 5 + display: flex; 6 + flex-direction: row; 7 + flex-wrap: wrap; 8 + align-items: stretch; 9 + padding: 0; 10 + margin-top: -1rem; 11 + margin-bottom: -1rem; 12 + margin-left: -1rem; 13 + margin-right: -1rem; 14 + } 15 + 16 + .ui.relaxed.grid { 17 + margin-left: -1.5rem; 18 + margin-right: -1.5rem; 19 + } 20 + .ui[class*="very relaxed"].grid { 21 + margin-left: -2.5rem; 22 + margin-right: -2.5rem; 23 + } 24 + 25 + .ui.grid + .grid { 26 + margin-top: 1rem; 27 + } 28 + 29 + .ui.grid > .column:not(.row), 30 + .ui.grid > .row > .column { 31 + position: relative; 32 + display: inline-block; 33 + width: 6.25%; 34 + padding-left: 1rem; 35 + padding-right: 1rem; 36 + vertical-align: top; 37 + } 38 + .ui.grid > * { 39 + padding-left: 1rem; 40 + padding-right: 1rem; 41 + } 42 + 43 + .ui.grid > .row { 44 + position: relative; 45 + display: flex; 46 + flex-direction: row; 47 + flex-wrap: wrap; 48 + justify-content: inherit; 49 + align-items: stretch; 50 + width: 100% !important; 51 + padding: 0; 52 + padding-top: 1rem; 53 + padding-bottom: 1rem; 54 + } 55 + 56 + .ui.grid > .column:not(.row) { 57 + padding-top: 1rem; 58 + padding-bottom: 1rem; 59 + } 60 + .ui.grid > .row > .column { 61 + margin-top: 0; 62 + margin-bottom: 0; 63 + } 64 + 65 + .ui.grid > .row > img, 66 + .ui.grid > .row > .column > img { 67 + max-width: 100%; 68 + } 69 + 70 + .ui.grid > .ui.grid:first-child { 71 + margin-top: 0; 72 + } 73 + .ui.grid > .ui.grid:last-child { 74 + margin-bottom: 0; 75 + } 76 + 77 + .ui.grid .aligned.row > .column > .segment:not(.compact):not(.attached), 78 + .ui.aligned.grid .column > .segment:not(.compact):not(.attached) { 79 + width: 100%; 80 + } 81 + 82 + .ui.grid .row + .ui.divider { 83 + flex-grow: 1; 84 + margin: 1rem; 85 + } 86 + .ui.grid .column + .ui.vertical.divider { 87 + height: calc(50% - 1rem); 88 + } 89 + 90 + .ui.grid > .row > .column:last-child > .horizontal.segment, 91 + .ui.grid > .column:last-child > .horizontal.segment { 92 + box-shadow: none; 93 + } 94 + 95 + @media only screen and (max-width: 767.98px) { 96 + .ui.page.grid { 97 + width: auto; 98 + padding-left: 0; 99 + padding-right: 0; 100 + margin-left: 0; 101 + margin-right: 0; 102 + } 103 + } 104 + @media only screen and (min-width: 768px) and (max-width: 991.98px) { 105 + .ui.page.grid { 106 + width: auto; 107 + margin-left: 0; 108 + margin-right: 0; 109 + padding-left: 2em; 110 + padding-right: 2em; 111 + } 112 + } 113 + @media only screen and (min-width: 992px) and (max-width: 1199.98px) { 114 + .ui.page.grid { 115 + width: auto; 116 + margin-left: 0; 117 + margin-right: 0; 118 + padding-left: 3%; 119 + padding-right: 3%; 120 + } 121 + } 122 + @media only screen and (min-width: 1200px) and (max-width: 1919.98px) { 123 + .ui.page.grid { 124 + width: auto; 125 + margin-left: 0; 126 + margin-right: 0; 127 + padding-left: 15%; 128 + padding-right: 15%; 129 + } 130 + } 131 + @media only screen and (min-width: 1920px) { 132 + .ui.page.grid { 133 + width: auto; 134 + margin-left: 0; 135 + margin-right: 0; 136 + padding-left: 23%; 137 + padding-right: 23%; 138 + } 139 + } 140 + 141 + .ui.grid > .column:only-child, 142 + .ui.grid > .row > .column:only-child { 143 + width: 100%; 144 + } 145 + 146 + .ui[class*="one column"].grid > .row > .column, 147 + .ui[class*="one column"].grid > .column:not(.row) { 148 + width: 100%; 149 + } 150 + .ui[class*="two column"].grid > .row > .column, 151 + .ui[class*="two column"].grid > .column:not(.row) { 152 + width: 50%; 153 + } 154 + .ui[class*="three column"].grid > .row > .column, 155 + .ui[class*="three column"].grid > .column:not(.row) { 156 + width: 33.33333333%; 157 + } 158 + .ui[class*="four column"].grid > .row > .column, 159 + .ui[class*="four column"].grid > .column:not(.row) { 160 + width: 25%; 161 + } 162 + .ui[class*="five column"].grid > .row > .column, 163 + .ui[class*="five column"].grid > .column:not(.row) { 164 + width: 20%; 165 + } 166 + .ui[class*="six column"].grid > .row > .column, 167 + .ui[class*="six column"].grid > .column:not(.row) { 168 + width: 16.66666667%; 169 + } 170 + .ui[class*="seven column"].grid > .row > .column, 171 + .ui[class*="seven column"].grid > .column:not(.row) { 172 + width: 14.28571429%; 173 + } 174 + .ui[class*="eight column"].grid > .row > .column, 175 + .ui[class*="eight column"].grid > .column:not(.row) { 176 + width: 12.5%; 177 + } 178 + .ui[class*="nine column"].grid > .row > .column, 179 + .ui[class*="nine column"].grid > .column:not(.row) { 180 + width: 11.11111111%; 181 + } 182 + .ui[class*="ten column"].grid > .row > .column, 183 + .ui[class*="ten column"].grid > .column:not(.row) { 184 + width: 10%; 185 + } 186 + .ui[class*="eleven column"].grid > .row > .column, 187 + .ui[class*="eleven column"].grid > .column:not(.row) { 188 + width: 9.09090909%; 189 + } 190 + .ui[class*="twelve column"].grid > .row > .column, 191 + .ui[class*="twelve column"].grid > .column:not(.row) { 192 + width: 8.33333333%; 193 + } 194 + .ui[class*="thirteen column"].grid > .row > .column, 195 + .ui[class*="thirteen column"].grid > .column:not(.row) { 196 + width: 7.69230769%; 197 + } 198 + .ui[class*="fourteen column"].grid > .row > .column, 199 + .ui[class*="fourteen column"].grid > .column:not(.row) { 200 + width: 7.14285714%; 201 + } 202 + .ui[class*="fifteen column"].grid > .row > .column, 203 + .ui[class*="fifteen column"].grid > .column:not(.row) { 204 + width: 6.66666667%; 205 + } 206 + .ui[class*="sixteen column"].grid > .row > .column, 207 + .ui[class*="sixteen column"].grid > .column:not(.row) { 208 + width: 6.25%; 209 + } 210 + 211 + .ui.grid > [class*="one column"].row > .column { 212 + width: 100% !important; 213 + } 214 + .ui.grid > [class*="two column"].row > .column { 215 + width: 50% !important; 216 + } 217 + .ui.grid > [class*="three column"].row > .column { 218 + width: 33.33333333% !important; 219 + } 220 + .ui.grid > [class*="four column"].row > .column { 221 + width: 25% !important; 222 + } 223 + .ui.grid > [class*="five column"].row > .column { 224 + width: 20% !important; 225 + } 226 + .ui.grid > [class*="six column"].row > .column { 227 + width: 16.66666667% !important; 228 + } 229 + .ui.grid > [class*="seven column"].row > .column { 230 + width: 14.28571429% !important; 231 + } 232 + .ui.grid > [class*="eight column"].row > .column { 233 + width: 12.5% !important; 234 + } 235 + .ui.grid > [class*="nine column"].row > .column { 236 + width: 11.11111111% !important; 237 + } 238 + .ui.grid > [class*="ten column"].row > .column { 239 + width: 10% !important; 240 + } 241 + .ui.grid > [class*="eleven column"].row > .column { 242 + width: 9.09090909% !important; 243 + } 244 + .ui.grid > [class*="twelve column"].row > .column { 245 + width: 8.33333333% !important; 246 + } 247 + .ui.grid > [class*="thirteen column"].row > .column { 248 + width: 7.69230769% !important; 249 + } 250 + .ui.grid > [class*="fourteen column"].row > .column { 251 + width: 7.14285714% !important; 252 + } 253 + .ui.grid > [class*="fifteen column"].row > .column { 254 + width: 6.66666667% !important; 255 + } 256 + .ui.grid > [class*="sixteen column"].row > .column { 257 + width: 6.25% !important; 258 + } 259 + 260 + .ui.grid > .row > [class*="one wide"].column, 261 + .ui.grid > .column.row > [class*="one wide"].column, 262 + .ui.grid > [class*="one wide"].column, 263 + .ui.column.grid > [class*="one wide"].column { 264 + width: 6.25% !important; 265 + } 266 + .ui.grid > .row > [class*="two wide"].column, 267 + .ui.grid > .column.row > [class*="two wide"].column, 268 + .ui.grid > [class*="two wide"].column, 269 + .ui.column.grid > [class*="two wide"].column { 270 + width: 12.5% !important; 271 + } 272 + .ui.grid > .row > [class*="three wide"].column, 273 + .ui.grid > .column.row > [class*="three wide"].column, 274 + .ui.grid > [class*="three wide"].column, 275 + .ui.column.grid > [class*="three wide"].column { 276 + width: 18.75% !important; 277 + } 278 + .ui.grid > .row > [class*="four wide"].column, 279 + .ui.grid > .column.row > [class*="four wide"].column, 280 + .ui.grid > [class*="four wide"].column, 281 + .ui.column.grid > [class*="four wide"].column { 282 + width: 25% !important; 283 + } 284 + .ui.grid > .row > [class*="five wide"].column, 285 + .ui.grid > .column.row > [class*="five wide"].column, 286 + .ui.grid > [class*="five wide"].column, 287 + .ui.column.grid > [class*="five wide"].column { 288 + width: 31.25% !important; 289 + } 290 + .ui.grid > .row > [class*="six wide"].column, 291 + .ui.grid > .column.row > [class*="six wide"].column, 292 + .ui.grid > [class*="six wide"].column, 293 + .ui.column.grid > [class*="six wide"].column { 294 + width: 37.5% !important; 295 + } 296 + .ui.grid > .row > [class*="seven wide"].column, 297 + .ui.grid > .column.row > [class*="seven wide"].column, 298 + .ui.grid > [class*="seven wide"].column, 299 + .ui.column.grid > [class*="seven wide"].column { 300 + width: 43.75% !important; 301 + } 302 + .ui.grid > .row > [class*="eight wide"].column, 303 + .ui.grid > .column.row > [class*="eight wide"].column, 304 + .ui.grid > [class*="eight wide"].column, 305 + .ui.column.grid > [class*="eight wide"].column { 306 + width: 50% !important; 307 + } 308 + .ui.grid > .row > [class*="nine wide"].column, 309 + .ui.grid > .column.row > [class*="nine wide"].column, 310 + .ui.grid > [class*="nine wide"].column, 311 + .ui.column.grid > [class*="nine wide"].column { 312 + width: 56.25% !important; 313 + } 314 + .ui.grid > .row > [class*="ten wide"].column, 315 + .ui.grid > .column.row > [class*="ten wide"].column, 316 + .ui.grid > [class*="ten wide"].column, 317 + .ui.column.grid > [class*="ten wide"].column { 318 + width: 62.5% !important; 319 + } 320 + .ui.grid > .row > [class*="eleven wide"].column, 321 + .ui.grid > .column.row > [class*="eleven wide"].column, 322 + .ui.grid > [class*="eleven wide"].column, 323 + .ui.column.grid > [class*="eleven wide"].column { 324 + width: 68.75% !important; 325 + } 326 + .ui.grid > .row > [class*="twelve wide"].column, 327 + .ui.grid > .column.row > [class*="twelve wide"].column, 328 + .ui.grid > [class*="twelve wide"].column, 329 + .ui.column.grid > [class*="twelve wide"].column { 330 + width: 75% !important; 331 + } 332 + .ui.grid > .row > [class*="thirteen wide"].column, 333 + .ui.grid > .column.row > [class*="thirteen wide"].column, 334 + .ui.grid > [class*="thirteen wide"].column, 335 + .ui.column.grid > [class*="thirteen wide"].column { 336 + width: 81.25% !important; 337 + } 338 + .ui.grid > .row > [class*="fourteen wide"].column, 339 + .ui.grid > .column.row > [class*="fourteen wide"].column, 340 + .ui.grid > [class*="fourteen wide"].column, 341 + .ui.column.grid > [class*="fourteen wide"].column { 342 + width: 87.5% !important; 343 + } 344 + .ui.grid > .row > [class*="fifteen wide"].column, 345 + .ui.grid > .column.row > [class*="fifteen wide"].column, 346 + .ui.grid > [class*="fifteen wide"].column, 347 + .ui.column.grid > [class*="fifteen wide"].column { 348 + width: 93.75% !important; 349 + } 350 + .ui.grid > .row > [class*="sixteen wide"].column, 351 + .ui.grid > .column.row > [class*="sixteen wide"].column, 352 + .ui.grid > [class*="sixteen wide"].column, 353 + .ui.column.grid > [class*="sixteen wide"].column { 354 + width: 100% !important; 355 + } 356 + 357 + .ui.centered.grid, 358 + .ui.centered.grid > .row, 359 + .ui.grid > .centered.row { 360 + text-align: center; 361 + justify-content: center; 362 + } 363 + .ui.centered.grid > .column:not(.aligned):not(.justified):not(.row), 364 + .ui.centered.grid > .row > .column:not(.aligned):not(.justified), 365 + .ui.grid .centered.row > .column:not(.aligned):not(.justified) { 366 + text-align: left; 367 + } 368 + .ui.grid > .centered.column, 369 + .ui.grid > .row > .centered.column { 370 + display: block; 371 + margin-left: auto; 372 + margin-right: auto; 373 + } 374 + 375 + .ui.relaxed.grid > .column:not(.row), 376 + .ui.relaxed.grid > .row > .column, 377 + .ui.grid > .relaxed.row > .column { 378 + padding-left: 1.5rem; 379 + padding-right: 1.5rem; 380 + } 381 + .ui[class*="very relaxed"].grid > .column:not(.row), 382 + .ui[class*="very relaxed"].grid > .row > .column, 383 + .ui.grid > [class*="very relaxed"].row > .column { 384 + padding-left: 2.5rem; 385 + padding-right: 2.5rem; 386 + } 387 + 388 + .ui.relaxed.grid .row + .ui.divider, 389 + .ui.grid .relaxed.row + .ui.divider { 390 + margin-left: 1.5rem; 391 + margin-right: 1.5rem; 392 + } 393 + .ui[class*="very relaxed"].grid .row + .ui.divider, 394 + .ui.grid [class*="very relaxed"].row + .ui.divider { 395 + margin-left: 2.5rem; 396 + margin-right: 2.5rem; 397 + } 398 + 399 + .ui[class*="middle aligned"].grid > .column:not(.row), 400 + .ui[class*="middle aligned"].grid > .row > .column, 401 + .ui.grid > [class*="middle aligned"].row > .column, 402 + .ui.grid > [class*="middle aligned"].column:not(.row), 403 + .ui.grid > .row > [class*="middle aligned"].column { 404 + flex-direction: column; 405 + vertical-align: middle; 406 + align-self: center !important; 407 + } 408 + 409 + .ui[class*="center aligned"].grid > .column, 410 + .ui[class*="center aligned"].grid > .row > .column, 411 + .ui.grid > [class*="center aligned"].row > .column, 412 + .ui.grid > [class*="center aligned"].column.column, 413 + .ui.grid > .row > [class*="center aligned"].column.column { 414 + text-align: center; 415 + align-self: inherit; 416 + } 417 + .ui[class*="center aligned"].grid { 418 + justify-content: center; 419 + } 420 + 421 + .ui[class*="equal width"].grid > .column:not(.row), 422 + .ui[class*="equal width"].grid > .row > .column, 423 + .ui.grid > [class*="equal width"].row > .column { 424 + display: inline-block; 425 + flex-grow: 1; 426 + } 427 + .ui[class*="equal width"].grid > .wide.column, 428 + .ui[class*="equal width"].grid > .row > .wide.column, 429 + .ui.grid > [class*="equal width"].row > .wide.column { 430 + flex-grow: 0; 431 + } 432 + 433 + @media only screen and (max-width: 767.98px) { 434 + .ui[class*="mobile reversed"].grid, 435 + .ui[class*="mobile reversed"].grid > .row, 436 + .ui.grid > [class*="mobile reversed"].row { 437 + flex-direction: row-reverse; 438 + } 439 + .ui.stackable[class*="mobile reversed"] { 440 + flex-direction: column-reverse; 441 + } 442 + } 443 + 444 + @media only screen and (max-width: 767.98px) { 445 + .ui.stackable.grid { 446 + width: auto; 447 + margin-left: 0 !important; 448 + margin-right: 0 !important; 449 + } 450 + .ui.stackable.grid > .row > .wide.column, 451 + .ui.stackable.grid > .wide.column, 452 + .ui.stackable.grid > .column.grid > .column, 453 + .ui.stackable.grid > .column.row > .column, 454 + .ui.stackable.grid > .row > .column, 455 + .ui.stackable.grid > .column:not(.row), 456 + .ui.grid > .stackable.stackable.stackable.row > .column { 457 + width: 100% !important; 458 + margin: 0 !important; 459 + box-shadow: none !important; 460 + padding: 1rem; 461 + } 462 + .ui.stackable.grid:not(.vertically) > .row { 463 + margin: 0; 464 + padding: 0; 465 + } 466 + 467 + .ui.container > .ui.stackable.grid > .column, 468 + .ui.container > .ui.stackable.grid > .row > .column { 469 + padding-left: 0 !important; 470 + padding-right: 0 !important; 471 + } 472 + 473 + .ui.grid .ui.stackable.grid, 474 + .ui.segment:not(.vertical) .ui.stackable.page.grid { 475 + margin-left: -1rem !important; 476 + margin-right: -1rem !important; 477 + } 478 + } 479 + 480 + .ui.ui.ui.compact.grid > .column:not(.row), 481 + .ui.ui.ui.compact.grid > .row > .column { 482 + padding-left: 0.5rem; 483 + padding-right: 0.5rem; 484 + } 485 + .ui.ui.ui.compact.grid > * { 486 + padding-left: 0.5rem; 487 + padding-right: 0.5rem; 488 + } 489 + 490 + .ui.ui.ui.compact.grid > .row { 491 + padding-top: 0.5rem; 492 + padding-bottom: 0.5rem; 493 + } 494 + 495 + .ui.ui.ui.compact.grid > .column:not(.row) { 496 + padding-top: 0.5rem; 497 + padding-bottom: 0.5rem; 498 + }
+3
web_src/css/modules/message.css
··· 1 + /* based on Fomantic UI message module, with just the parts extracted that we use. If you find any 2 + unused rules here after refactoring, please remove them. */ 3 + 1 4 .ui.message { 2 5 background: var(--color-box-body); 3 6 color: var(--color-text);
+9 -23
web_src/css/repo.css
··· 143 143 margin-bottom: 12px; 144 144 } 145 145 146 - .repository #clone-panel #repo-clone-url { 146 + .repository .clone-panel #repo-clone-url { 147 147 width: 320px; 148 148 border-radius: 0; 149 149 } 150 150 151 - @media (min-width: 768px) and (max-width: 991.98px) { 152 - .repository #clone-panel #repo-clone-url { 153 - width: 200px; 154 - } 155 - } 156 - 157 - @media (max-width: 767.98px) { 158 - .repository #clone-panel #repo-clone-url { 151 + @media (max-width: 991.98px) { 152 + .repository .clone-panel #repo-clone-url { 159 153 width: 200px; 160 154 } 161 155 } 162 156 163 - .repository #clone-panel #repo-clone-https, 164 - .repository #clone-panel #repo-clone-ssh { 165 - border-right: none; 166 - } 167 - 168 - .repository #clone-panel #more-btn { 169 - border-left: none; 157 + .repository .ui.action.input.clone-panel > button + button, 158 + .repository .ui.action.input.clone-panel > button + input { 159 + margin-left: -1px; /* make the borders overlap to avoid double borders */ 170 160 } 171 161 172 - .repository #clone-panel button:first-of-type { 162 + .repository .clone-panel > button:first-of-type { 173 163 border-radius: var(--border-radius) 0 0 var(--border-radius) !important; 174 164 } 175 165 176 - .repository #clone-panel button:last-of-type { 166 + .repository .clone-panel > button:last-of-type { 177 167 border-radius: 0 var(--border-radius) var(--border-radius) 0 !important; 178 168 } 179 169 180 - .repository #clone-panel .dropdown .menu { 170 + .repository .clone-panel .dropdown .menu { 181 171 right: 0 !important; 182 172 left: auto !important; 183 173 } ··· 1756 1746 1757 1747 .repository.quickstart .guide .item small { 1758 1748 font-weight: var(--font-weight-normal); 1759 - } 1760 - 1761 - .repository.quickstart .guide .clone.button:first-child { 1762 - border-radius: var(--border-radius) 0 0 var(--border-radius); 1763 1749 } 1764 1750 1765 1751 .repository.quickstart .guide #repo-clone-url {
+1
web_src/css/repo/header.css
··· 71 71 } 72 72 73 73 .repository .header-wrapper { 74 + padding-top: 12px; 74 75 background-color: var(--color-header-wrapper); 75 76 } 76 77
+2 -1
web_src/css/repo/wiki.css
··· 21 21 22 22 .repository.wiki .wiki-content-parts .markup { 23 23 border: 1px solid var(--color-secondary); 24 + border-radius: var(--border-radius); 24 25 padding: 1em; 25 26 margin-top: 1em; 26 27 font-size: 1em; ··· 58 59 } 59 60 60 61 @media (max-width: 767.98px) { 61 - .repository.wiki #clone-panel #repo-clone-url { 62 + .repository.wiki .clone-panel #repo-clone-url { 62 63 width: 160px; 63 64 } 64 65 .repository.wiki .wiki-content-main.with-sidebar,
+4
web_src/css/review.css
··· 198 198 margin: 0 0 0 3em; 199 199 } 200 200 201 + .diff-file-body.binary { 202 + padding: 5px 10px; 203 + } 204 + 201 205 .file-comment { 202 206 color: var(--color-text); 203 207 }
+6 -6
web_src/css/themes/theme-gitea-dark.css
··· 180 180 --color-orange-badge-hover-bg: #f2711c4d; 181 181 --color-git: #f05133; 182 182 /* target-based colors */ 183 - --color-body: #1e2224; 183 + --color-body: #1c1f25; 184 184 --color-box-header: #1a1d1f; 185 185 --color-box-body: #14171a; 186 186 --color-box-body-highlight: #121517; 187 187 --color-text-dark: #f8f8f9; 188 - --color-text: #ced2d5; 189 - --color-text-light: #bec4c8; 190 - --color-text-light-1: #acb3b8; 191 - --color-text-light-2: #8d969c; 192 - --color-text-light-3: #747f87; 188 + --color-text: #d1d5d8; 189 + --color-text-light: #bdc3c7; 190 + --color-text-light-1: #a8afb5; 191 + --color-text-light-2: #929ba2; 192 + --color-text-light-3: #7c8790; 193 193 --color-footer: var(--color-nav-bg); 194 194 --color-timeline: #353c42; 195 195 --color-input-text: var(--color-text-dark);
+9 -9
web_src/css/themes/theme-gitea-light.css
··· 184 184 --color-box-header: #f1f3f5; 185 185 --color-box-body: #ffffff; 186 186 --color-box-body-highlight: #f4faff; 187 - --color-text-dark: #03080d; 188 - --color-text: #1c2126; 189 - --color-text-light: #3c434a; 190 - --color-text-light-1: #4b5259; 191 - --color-text-light-2: #6a7178; 192 - --color-text-light-3: #899097; 187 + --color-text-dark: #01050a; 188 + --color-text: #181c21; 189 + --color-text-light: #30363b; 190 + --color-text-light-1: #40474d; 191 + --color-text-light-2: #5b6167; 192 + --color-text-light-3: #747c84; 193 193 --color-footer: var(--color-nav-bg); 194 194 --color-timeline: #d0d7de; 195 195 --color-input-text: var(--color-text-dark); 196 - --color-input-background: #f8f9fb; 196 + --color-input-background: #fff; 197 197 --color-input-toggle-background: #d0d7de; 198 198 --color-input-border: var(--color-secondary); 199 199 --color-input-border-hover: var(--color-secondary-dark-1); 200 - --color-header-wrapper: #fafbfc; 200 + --color-header-wrapper: #f9fafb; 201 201 --color-light: #00001706; 202 202 --color-light-mimic-enabled: rgba(0, 0, 0, calc(6 / 255 * 222 / 255 / var(--opacity-disabled))); 203 203 --color-light-border: #0000171d; ··· 224 224 --color-reaction-active-bg: var(--color-primary-light-6); 225 225 --color-tooltip-text: #fbfdff; 226 226 --color-tooltip-bg: #000017f0; 227 - --color-nav-bg: #f8f9fb; 227 + --color-nav-bg: #f6f7fa; 228 228 --color-nav-hover-bg: var(--color-secondary-light-1); 229 229 --color-nav-text: var(--color-text); 230 230 --color-label-text: var(--color-text);
+4
web_src/css/user.css
··· 125 125 border: 1px solid var(--color-secondary); 126 126 } 127 127 128 + #notification_div { 129 + padding-top: 15px; 130 + } 131 + 128 132 #notification_table { 129 133 background: var(--color-box-body); 130 134 border: 1px solid var(--color-secondary);
-2180
web_src/fomantic/build/semantic.css
··· 7344 7344 Site Overrides 7345 7345 *******************************/ 7346 7346 /*! 7347 - * # Fomantic-UI - Grid 7348 - * http://github.com/fomantic/Fomantic-UI/ 7349 - * 7350 - * 7351 - * Released under the MIT license 7352 - * http://opensource.org/licenses/MIT 7353 - * 7354 - */ 7355 - 7356 - /******************************* 7357 - Standard 7358 - *******************************/ 7359 - 7360 - .ui.grid { 7361 - display: flex; 7362 - flex-direction: row; 7363 - flex-wrap: wrap; 7364 - align-items: stretch; 7365 - padding: 0; 7366 - } 7367 - 7368 - /*---------------------- 7369 - Remove Gutters 7370 - -----------------------*/ 7371 - 7372 - .ui.grid { 7373 - margin-top: -1rem; 7374 - margin-bottom: -1rem; 7375 - margin-left: -1rem; 7376 - margin-right: -1rem; 7377 - } 7378 - 7379 - .ui.relaxed.grid { 7380 - margin-left: -1.5rem; 7381 - margin-right: -1.5rem; 7382 - } 7383 - 7384 - .ui[class*="very relaxed"].grid { 7385 - margin-left: -2.5rem; 7386 - margin-right: -2.5rem; 7387 - } 7388 - 7389 - /* Preserve Rows Spacing on Consecutive Grids */ 7390 - 7391 - .ui.grid + .grid { 7392 - margin-top: 1rem; 7393 - } 7394 - 7395 - /*------------------- 7396 - Columns 7397 - --------------------*/ 7398 - 7399 - /* Standard 16 column */ 7400 - 7401 - .ui.grid > .column:not(.row), 7402 - .ui.grid > .row > .column { 7403 - position: relative; 7404 - display: inline-block; 7405 - width: 6.25%; 7406 - padding-left: 1rem; 7407 - padding-right: 1rem; 7408 - vertical-align: top; 7409 - } 7410 - 7411 - .ui.grid > * { 7412 - padding-left: 1rem; 7413 - padding-right: 1rem; 7414 - } 7415 - 7416 - /*------------------- 7417 - Rows 7418 - --------------------*/ 7419 - 7420 - .ui.grid > .row { 7421 - position: relative; 7422 - display: flex; 7423 - flex-direction: row; 7424 - flex-wrap: wrap; 7425 - justify-content: inherit; 7426 - align-items: stretch; 7427 - width: 100% !important; 7428 - padding: 0; 7429 - padding-top: 1rem; 7430 - padding-bottom: 1rem; 7431 - } 7432 - 7433 - /*------------------- 7434 - Columns 7435 - --------------------*/ 7436 - 7437 - /* Vertical padding when no rows */ 7438 - 7439 - .ui.grid > .column:not(.row) { 7440 - padding-top: 1rem; 7441 - padding-bottom: 1rem; 7442 - } 7443 - 7444 - .ui.grid > .row > .column { 7445 - margin-top: 0; 7446 - margin-bottom: 0; 7447 - } 7448 - 7449 - /*------------------- 7450 - Content 7451 - --------------------*/ 7452 - 7453 - .ui.grid > .row > img, 7454 - .ui.grid > .row > .column > img { 7455 - max-width: 100%; 7456 - } 7457 - 7458 - /*------------------- 7459 - Loose Coupling 7460 - --------------------*/ 7461 - 7462 - /* Collapse Margin on Consecutive Grid */ 7463 - 7464 - .ui.grid > .ui.grid:first-child { 7465 - margin-top: 0; 7466 - } 7467 - 7468 - .ui.grid > .ui.grid:last-child { 7469 - margin-bottom: 0; 7470 - } 7471 - 7472 - /* Segment inside Aligned Grid */ 7473 - 7474 - .ui.grid .aligned.row > .column > .segment:not(.compact):not(.attached), 7475 - .ui.aligned.grid .column > .segment:not(.compact):not(.attached) { 7476 - width: 100%; 7477 - } 7478 - 7479 - /* Align Dividers with Gutter */ 7480 - 7481 - .ui.grid .row + .ui.divider { 7482 - flex-grow: 1; 7483 - margin: 1rem 1rem; 7484 - } 7485 - 7486 - .ui.grid .column + .ui.vertical.divider { 7487 - height: calc(50% - 1rem); 7488 - } 7489 - 7490 - /* Remove Border on Last Horizontal Segment */ 7491 - 7492 - .ui.grid > .row > .column:last-child > .horizontal.segment, 7493 - .ui.grid > .column:last-child > .horizontal.segment { 7494 - box-shadow: none; 7495 - } 7496 - 7497 - /******************************* 7498 - Variations 7499 - *******************************/ 7500 - 7501 - /*----------------------- 7502 - Page Grid 7503 - -------------------------*/ 7504 - 7505 - @media only screen and (max-width: 767.98px) { 7506 - .ui.page.grid { 7507 - width: auto; 7508 - padding-left: 0; 7509 - padding-right: 0; 7510 - margin-left: 0; 7511 - margin-right: 0; 7512 - } 7513 - } 7514 - 7515 - @media only screen and (min-width: 768px) and (max-width: 991.98px) { 7516 - .ui.page.grid { 7517 - width: auto; 7518 - margin-left: 0; 7519 - margin-right: 0; 7520 - padding-left: 2em; 7521 - padding-right: 2em; 7522 - } 7523 - } 7524 - 7525 - @media only screen and (min-width: 992px) and (max-width: 1199.98px) { 7526 - .ui.page.grid { 7527 - width: auto; 7528 - margin-left: 0; 7529 - margin-right: 0; 7530 - padding-left: 3%; 7531 - padding-right: 3%; 7532 - } 7533 - } 7534 - 7535 - @media only screen and (min-width: 1200px) and (max-width: 1919.98px) { 7536 - .ui.page.grid { 7537 - width: auto; 7538 - margin-left: 0; 7539 - margin-right: 0; 7540 - padding-left: 15%; 7541 - padding-right: 15%; 7542 - } 7543 - } 7544 - 7545 - @media only screen and (min-width: 1920px) { 7546 - .ui.page.grid { 7547 - width: auto; 7548 - margin-left: 0; 7549 - margin-right: 0; 7550 - padding-left: 23%; 7551 - padding-right: 23%; 7552 - } 7553 - } 7554 - 7555 - /*------------------- 7556 - Column Count 7557 - --------------------*/ 7558 - 7559 - /* Assume full width with one column */ 7560 - 7561 - .ui.grid > .column:only-child, 7562 - .ui.grid > .row > .column:only-child { 7563 - width: 100%; 7564 - } 7565 - 7566 - /* Grid Based */ 7567 - 7568 - .ui[class*="one column"].grid > .row > .column, 7569 - .ui[class*="one column"].grid > .column:not(.row) { 7570 - width: 100%; 7571 - } 7572 - 7573 - .ui[class*="two column"].grid > .row > .column, 7574 - .ui[class*="two column"].grid > .column:not(.row) { 7575 - width: 50%; 7576 - } 7577 - 7578 - .ui[class*="three column"].grid > .row > .column, 7579 - .ui[class*="three column"].grid > .column:not(.row) { 7580 - width: 33.33333333%; 7581 - } 7582 - 7583 - .ui[class*="four column"].grid > .row > .column, 7584 - .ui[class*="four column"].grid > .column:not(.row) { 7585 - width: 25%; 7586 - } 7587 - 7588 - .ui[class*="five column"].grid > .row > .column, 7589 - .ui[class*="five column"].grid > .column:not(.row) { 7590 - width: 20%; 7591 - } 7592 - 7593 - .ui[class*="six column"].grid > .row > .column, 7594 - .ui[class*="six column"].grid > .column:not(.row) { 7595 - width: 16.66666667%; 7596 - } 7597 - 7598 - .ui[class*="seven column"].grid > .row > .column, 7599 - .ui[class*="seven column"].grid > .column:not(.row) { 7600 - width: 14.28571429%; 7601 - } 7602 - 7603 - .ui[class*="eight column"].grid > .row > .column, 7604 - .ui[class*="eight column"].grid > .column:not(.row) { 7605 - width: 12.5%; 7606 - } 7607 - 7608 - .ui[class*="nine column"].grid > .row > .column, 7609 - .ui[class*="nine column"].grid > .column:not(.row) { 7610 - width: 11.11111111%; 7611 - } 7612 - 7613 - .ui[class*="ten column"].grid > .row > .column, 7614 - .ui[class*="ten column"].grid > .column:not(.row) { 7615 - width: 10%; 7616 - } 7617 - 7618 - .ui[class*="eleven column"].grid > .row > .column, 7619 - .ui[class*="eleven column"].grid > .column:not(.row) { 7620 - width: 9.09090909%; 7621 - } 7622 - 7623 - .ui[class*="twelve column"].grid > .row > .column, 7624 - .ui[class*="twelve column"].grid > .column:not(.row) { 7625 - width: 8.33333333%; 7626 - } 7627 - 7628 - .ui[class*="thirteen column"].grid > .row > .column, 7629 - .ui[class*="thirteen column"].grid > .column:not(.row) { 7630 - width: 7.69230769%; 7631 - } 7632 - 7633 - .ui[class*="fourteen column"].grid > .row > .column, 7634 - .ui[class*="fourteen column"].grid > .column:not(.row) { 7635 - width: 7.14285714%; 7636 - } 7637 - 7638 - .ui[class*="fifteen column"].grid > .row > .column, 7639 - .ui[class*="fifteen column"].grid > .column:not(.row) { 7640 - width: 6.66666667%; 7641 - } 7642 - 7643 - .ui[class*="sixteen column"].grid > .row > .column, 7644 - .ui[class*="sixteen column"].grid > .column:not(.row) { 7645 - width: 6.25%; 7646 - } 7647 - 7648 - /* Row Based Overrides */ 7649 - 7650 - .ui.grid > [class*="one column"].row > .column { 7651 - width: 100% !important; 7652 - } 7653 - 7654 - .ui.grid > [class*="two column"].row > .column { 7655 - width: 50% !important; 7656 - } 7657 - 7658 - .ui.grid > [class*="three column"].row > .column { 7659 - width: 33.33333333% !important; 7660 - } 7661 - 7662 - .ui.grid > [class*="four column"].row > .column { 7663 - width: 25% !important; 7664 - } 7665 - 7666 - .ui.grid > [class*="five column"].row > .column { 7667 - width: 20% !important; 7668 - } 7669 - 7670 - .ui.grid > [class*="six column"].row > .column { 7671 - width: 16.66666667% !important; 7672 - } 7673 - 7674 - .ui.grid > [class*="seven column"].row > .column { 7675 - width: 14.28571429% !important; 7676 - } 7677 - 7678 - .ui.grid > [class*="eight column"].row > .column { 7679 - width: 12.5% !important; 7680 - } 7681 - 7682 - .ui.grid > [class*="nine column"].row > .column { 7683 - width: 11.11111111% !important; 7684 - } 7685 - 7686 - .ui.grid > [class*="ten column"].row > .column { 7687 - width: 10% !important; 7688 - } 7689 - 7690 - .ui.grid > [class*="eleven column"].row > .column { 7691 - width: 9.09090909% !important; 7692 - } 7693 - 7694 - .ui.grid > [class*="twelve column"].row > .column { 7695 - width: 8.33333333% !important; 7696 - } 7697 - 7698 - .ui.grid > [class*="thirteen column"].row > .column { 7699 - width: 7.69230769% !important; 7700 - } 7701 - 7702 - .ui.grid > [class*="fourteen column"].row > .column { 7703 - width: 7.14285714% !important; 7704 - } 7705 - 7706 - .ui.grid > [class*="fifteen column"].row > .column { 7707 - width: 6.66666667% !important; 7708 - } 7709 - 7710 - .ui.grid > [class*="sixteen column"].row > .column { 7711 - width: 6.25% !important; 7712 - } 7713 - 7714 - /* Celled Page */ 7715 - 7716 - .ui.celled.page.grid { 7717 - box-shadow: none; 7718 - } 7719 - 7720 - /*------------------- 7721 - Column Width 7722 - --------------------*/ 7723 - 7724 - /* Sizing Combinations */ 7725 - 7726 - .ui.grid > .row > [class*="one wide"].column, 7727 - .ui.grid > .column.row > [class*="one wide"].column, 7728 - .ui.grid > [class*="one wide"].column, 7729 - .ui.column.grid > [class*="one wide"].column { 7730 - width: 6.25% !important; 7731 - } 7732 - 7733 - .ui.grid > .row > [class*="two wide"].column, 7734 - .ui.grid > .column.row > [class*="two wide"].column, 7735 - .ui.grid > [class*="two wide"].column, 7736 - .ui.column.grid > [class*="two wide"].column { 7737 - width: 12.5% !important; 7738 - } 7739 - 7740 - .ui.grid > .row > [class*="three wide"].column, 7741 - .ui.grid > .column.row > [class*="three wide"].column, 7742 - .ui.grid > [class*="three wide"].column, 7743 - .ui.column.grid > [class*="three wide"].column { 7744 - width: 18.75% !important; 7745 - } 7746 - 7747 - .ui.grid > .row > [class*="four wide"].column, 7748 - .ui.grid > .column.row > [class*="four wide"].column, 7749 - .ui.grid > [class*="four wide"].column, 7750 - .ui.column.grid > [class*="four wide"].column { 7751 - width: 25% !important; 7752 - } 7753 - 7754 - .ui.grid > .row > [class*="five wide"].column, 7755 - .ui.grid > .column.row > [class*="five wide"].column, 7756 - .ui.grid > [class*="five wide"].column, 7757 - .ui.column.grid > [class*="five wide"].column { 7758 - width: 31.25% !important; 7759 - } 7760 - 7761 - .ui.grid > .row > [class*="six wide"].column, 7762 - .ui.grid > .column.row > [class*="six wide"].column, 7763 - .ui.grid > [class*="six wide"].column, 7764 - .ui.column.grid > [class*="six wide"].column { 7765 - width: 37.5% !important; 7766 - } 7767 - 7768 - .ui.grid > .row > [class*="seven wide"].column, 7769 - .ui.grid > .column.row > [class*="seven wide"].column, 7770 - .ui.grid > [class*="seven wide"].column, 7771 - .ui.column.grid > [class*="seven wide"].column { 7772 - width: 43.75% !important; 7773 - } 7774 - 7775 - .ui.grid > .row > [class*="eight wide"].column, 7776 - .ui.grid > .column.row > [class*="eight wide"].column, 7777 - .ui.grid > [class*="eight wide"].column, 7778 - .ui.column.grid > [class*="eight wide"].column { 7779 - width: 50% !important; 7780 - } 7781 - 7782 - .ui.grid > .row > [class*="nine wide"].column, 7783 - .ui.grid > .column.row > [class*="nine wide"].column, 7784 - .ui.grid > [class*="nine wide"].column, 7785 - .ui.column.grid > [class*="nine wide"].column { 7786 - width: 56.25% !important; 7787 - } 7788 - 7789 - .ui.grid > .row > [class*="ten wide"].column, 7790 - .ui.grid > .column.row > [class*="ten wide"].column, 7791 - .ui.grid > [class*="ten wide"].column, 7792 - .ui.column.grid > [class*="ten wide"].column { 7793 - width: 62.5% !important; 7794 - } 7795 - 7796 - .ui.grid > .row > [class*="eleven wide"].column, 7797 - .ui.grid > .column.row > [class*="eleven wide"].column, 7798 - .ui.grid > [class*="eleven wide"].column, 7799 - .ui.column.grid > [class*="eleven wide"].column { 7800 - width: 68.75% !important; 7801 - } 7802 - 7803 - .ui.grid > .row > [class*="twelve wide"].column, 7804 - .ui.grid > .column.row > [class*="twelve wide"].column, 7805 - .ui.grid > [class*="twelve wide"].column, 7806 - .ui.column.grid > [class*="twelve wide"].column { 7807 - width: 75% !important; 7808 - } 7809 - 7810 - .ui.grid > .row > [class*="thirteen wide"].column, 7811 - .ui.grid > .column.row > [class*="thirteen wide"].column, 7812 - .ui.grid > [class*="thirteen wide"].column, 7813 - .ui.column.grid > [class*="thirteen wide"].column { 7814 - width: 81.25% !important; 7815 - } 7816 - 7817 - .ui.grid > .row > [class*="fourteen wide"].column, 7818 - .ui.grid > .column.row > [class*="fourteen wide"].column, 7819 - .ui.grid > [class*="fourteen wide"].column, 7820 - .ui.column.grid > [class*="fourteen wide"].column { 7821 - width: 87.5% !important; 7822 - } 7823 - 7824 - .ui.grid > .row > [class*="fifteen wide"].column, 7825 - .ui.grid > .column.row > [class*="fifteen wide"].column, 7826 - .ui.grid > [class*="fifteen wide"].column, 7827 - .ui.column.grid > [class*="fifteen wide"].column { 7828 - width: 93.75% !important; 7829 - } 7830 - 7831 - .ui.grid > .row > [class*="sixteen wide"].column, 7832 - .ui.grid > .column.row > [class*="sixteen wide"].column, 7833 - .ui.grid > [class*="sixteen wide"].column, 7834 - .ui.column.grid > [class*="sixteen wide"].column { 7835 - width: 100% !important; 7836 - } 7837 - 7838 - /*---------------------- 7839 - Width per Device 7840 - -----------------------*/ 7841 - 7842 - /* Mobile Sizing Combinations */ 7843 - 7844 - @media only screen and (min-width: 320px) and (max-width: 767.98px) { 7845 - .ui.grid > .row > [class*="one wide mobile"].column, 7846 - .ui.grid > .column.row > [class*="one wide mobile"].column, 7847 - .ui.grid > [class*="one wide mobile"].column, 7848 - .ui.column.grid > [class*="one wide mobile"].column { 7849 - width: 6.25% !important; 7850 - } 7851 - 7852 - .ui.grid > .row > [class*="two wide mobile"].column, 7853 - .ui.grid > .column.row > [class*="two wide mobile"].column, 7854 - .ui.grid > [class*="two wide mobile"].column, 7855 - .ui.column.grid > [class*="two wide mobile"].column { 7856 - width: 12.5% !important; 7857 - } 7858 - 7859 - .ui.grid > .row > [class*="three wide mobile"].column, 7860 - .ui.grid > .column.row > [class*="three wide mobile"].column, 7861 - .ui.grid > [class*="three wide mobile"].column, 7862 - .ui.column.grid > [class*="three wide mobile"].column { 7863 - width: 18.75% !important; 7864 - } 7865 - 7866 - .ui.grid > .row > [class*="four wide mobile"].column, 7867 - .ui.grid > .column.row > [class*="four wide mobile"].column, 7868 - .ui.grid > [class*="four wide mobile"].column, 7869 - .ui.column.grid > [class*="four wide mobile"].column { 7870 - width: 25% !important; 7871 - } 7872 - 7873 - .ui.grid > .row > [class*="five wide mobile"].column, 7874 - .ui.grid > .column.row > [class*="five wide mobile"].column, 7875 - .ui.grid > [class*="five wide mobile"].column, 7876 - .ui.column.grid > [class*="five wide mobile"].column { 7877 - width: 31.25% !important; 7878 - } 7879 - 7880 - .ui.grid > .row > [class*="six wide mobile"].column, 7881 - .ui.grid > .column.row > [class*="six wide mobile"].column, 7882 - .ui.grid > [class*="six wide mobile"].column, 7883 - .ui.column.grid > [class*="six wide mobile"].column { 7884 - width: 37.5% !important; 7885 - } 7886 - 7887 - .ui.grid > .row > [class*="seven wide mobile"].column, 7888 - .ui.grid > .column.row > [class*="seven wide mobile"].column, 7889 - .ui.grid > [class*="seven wide mobile"].column, 7890 - .ui.column.grid > [class*="seven wide mobile"].column { 7891 - width: 43.75% !important; 7892 - } 7893 - 7894 - .ui.grid > .row > [class*="eight wide mobile"].column, 7895 - .ui.grid > .column.row > [class*="eight wide mobile"].column, 7896 - .ui.grid > [class*="eight wide mobile"].column, 7897 - .ui.column.grid > [class*="eight wide mobile"].column { 7898 - width: 50% !important; 7899 - } 7900 - 7901 - .ui.grid > .row > [class*="nine wide mobile"].column, 7902 - .ui.grid > .column.row > [class*="nine wide mobile"].column, 7903 - .ui.grid > [class*="nine wide mobile"].column, 7904 - .ui.column.grid > [class*="nine wide mobile"].column { 7905 - width: 56.25% !important; 7906 - } 7907 - 7908 - .ui.grid > .row > [class*="ten wide mobile"].column, 7909 - .ui.grid > .column.row > [class*="ten wide mobile"].column, 7910 - .ui.grid > [class*="ten wide mobile"].column, 7911 - .ui.column.grid > [class*="ten wide mobile"].column { 7912 - width: 62.5% !important; 7913 - } 7914 - 7915 - .ui.grid > .row > [class*="eleven wide mobile"].column, 7916 - .ui.grid > .column.row > [class*="eleven wide mobile"].column, 7917 - .ui.grid > [class*="eleven wide mobile"].column, 7918 - .ui.column.grid > [class*="eleven wide mobile"].column { 7919 - width: 68.75% !important; 7920 - } 7921 - 7922 - .ui.grid > .row > [class*="twelve wide mobile"].column, 7923 - .ui.grid > .column.row > [class*="twelve wide mobile"].column, 7924 - .ui.grid > [class*="twelve wide mobile"].column, 7925 - .ui.column.grid > [class*="twelve wide mobile"].column { 7926 - width: 75% !important; 7927 - } 7928 - 7929 - .ui.grid > .row > [class*="thirteen wide mobile"].column, 7930 - .ui.grid > .column.row > [class*="thirteen wide mobile"].column, 7931 - .ui.grid > [class*="thirteen wide mobile"].column, 7932 - .ui.column.grid > [class*="thirteen wide mobile"].column { 7933 - width: 81.25% !important; 7934 - } 7935 - 7936 - .ui.grid > .row > [class*="fourteen wide mobile"].column, 7937 - .ui.grid > .column.row > [class*="fourteen wide mobile"].column, 7938 - .ui.grid > [class*="fourteen wide mobile"].column, 7939 - .ui.column.grid > [class*="fourteen wide mobile"].column { 7940 - width: 87.5% !important; 7941 - } 7942 - 7943 - .ui.grid > .row > [class*="fifteen wide mobile"].column, 7944 - .ui.grid > .column.row > [class*="fifteen wide mobile"].column, 7945 - .ui.grid > [class*="fifteen wide mobile"].column, 7946 - .ui.column.grid > [class*="fifteen wide mobile"].column { 7947 - width: 93.75% !important; 7948 - } 7949 - 7950 - .ui.grid > .row > [class*="sixteen wide mobile"].column, 7951 - .ui.grid > .column.row > [class*="sixteen wide mobile"].column, 7952 - .ui.grid > [class*="sixteen wide mobile"].column, 7953 - .ui.column.grid > [class*="sixteen wide mobile"].column { 7954 - width: 100% !important; 7955 - } 7956 - } 7957 - 7958 - /* Tablet Sizing Combinations */ 7959 - 7960 - @media only screen and (min-width: 768px) and (max-width: 991.98px) { 7961 - .ui.grid > .row > [class*="one wide tablet"].column, 7962 - .ui.grid > .column.row > [class*="one wide tablet"].column, 7963 - .ui.grid > [class*="one wide tablet"].column, 7964 - .ui.column.grid > [class*="one wide tablet"].column { 7965 - width: 6.25% !important; 7966 - } 7967 - 7968 - .ui.grid > .row > [class*="two wide tablet"].column, 7969 - .ui.grid > .column.row > [class*="two wide tablet"].column, 7970 - .ui.grid > [class*="two wide tablet"].column, 7971 - .ui.column.grid > [class*="two wide tablet"].column { 7972 - width: 12.5% !important; 7973 - } 7974 - 7975 - .ui.grid > .row > [class*="three wide tablet"].column, 7976 - .ui.grid > .column.row > [class*="three wide tablet"].column, 7977 - .ui.grid > [class*="three wide tablet"].column, 7978 - .ui.column.grid > [class*="three wide tablet"].column { 7979 - width: 18.75% !important; 7980 - } 7981 - 7982 - .ui.grid > .row > [class*="four wide tablet"].column, 7983 - .ui.grid > .column.row > [class*="four wide tablet"].column, 7984 - .ui.grid > [class*="four wide tablet"].column, 7985 - .ui.column.grid > [class*="four wide tablet"].column { 7986 - width: 25% !important; 7987 - } 7988 - 7989 - .ui.grid > .row > [class*="five wide tablet"].column, 7990 - .ui.grid > .column.row > [class*="five wide tablet"].column, 7991 - .ui.grid > [class*="five wide tablet"].column, 7992 - .ui.column.grid > [class*="five wide tablet"].column { 7993 - width: 31.25% !important; 7994 - } 7995 - 7996 - .ui.grid > .row > [class*="six wide tablet"].column, 7997 - .ui.grid > .column.row > [class*="six wide tablet"].column, 7998 - .ui.grid > [class*="six wide tablet"].column, 7999 - .ui.column.grid > [class*="six wide tablet"].column { 8000 - width: 37.5% !important; 8001 - } 8002 - 8003 - .ui.grid > .row > [class*="seven wide tablet"].column, 8004 - .ui.grid > .column.row > [class*="seven wide tablet"].column, 8005 - .ui.grid > [class*="seven wide tablet"].column, 8006 - .ui.column.grid > [class*="seven wide tablet"].column { 8007 - width: 43.75% !important; 8008 - } 8009 - 8010 - .ui.grid > .row > [class*="eight wide tablet"].column, 8011 - .ui.grid > .column.row > [class*="eight wide tablet"].column, 8012 - .ui.grid > [class*="eight wide tablet"].column, 8013 - .ui.column.grid > [class*="eight wide tablet"].column { 8014 - width: 50% !important; 8015 - } 8016 - 8017 - .ui.grid > .row > [class*="nine wide tablet"].column, 8018 - .ui.grid > .column.row > [class*="nine wide tablet"].column, 8019 - .ui.grid > [class*="nine wide tablet"].column, 8020 - .ui.column.grid > [class*="nine wide tablet"].column { 8021 - width: 56.25% !important; 8022 - } 8023 - 8024 - .ui.grid > .row > [class*="ten wide tablet"].column, 8025 - .ui.grid > .column.row > [class*="ten wide tablet"].column, 8026 - .ui.grid > [class*="ten wide tablet"].column, 8027 - .ui.column.grid > [class*="ten wide tablet"].column { 8028 - width: 62.5% !important; 8029 - } 8030 - 8031 - .ui.grid > .row > [class*="eleven wide tablet"].column, 8032 - .ui.grid > .column.row > [class*="eleven wide tablet"].column, 8033 - .ui.grid > [class*="eleven wide tablet"].column, 8034 - .ui.column.grid > [class*="eleven wide tablet"].column { 8035 - width: 68.75% !important; 8036 - } 8037 - 8038 - .ui.grid > .row > [class*="twelve wide tablet"].column, 8039 - .ui.grid > .column.row > [class*="twelve wide tablet"].column, 8040 - .ui.grid > [class*="twelve wide tablet"].column, 8041 - .ui.column.grid > [class*="twelve wide tablet"].column { 8042 - width: 75% !important; 8043 - } 8044 - 8045 - .ui.grid > .row > [class*="thirteen wide tablet"].column, 8046 - .ui.grid > .column.row > [class*="thirteen wide tablet"].column, 8047 - .ui.grid > [class*="thirteen wide tablet"].column, 8048 - .ui.column.grid > [class*="thirteen wide tablet"].column { 8049 - width: 81.25% !important; 8050 - } 8051 - 8052 - .ui.grid > .row > [class*="fourteen wide tablet"].column, 8053 - .ui.grid > .column.row > [class*="fourteen wide tablet"].column, 8054 - .ui.grid > [class*="fourteen wide tablet"].column, 8055 - .ui.column.grid > [class*="fourteen wide tablet"].column { 8056 - width: 87.5% !important; 8057 - } 8058 - 8059 - .ui.grid > .row > [class*="fifteen wide tablet"].column, 8060 - .ui.grid > .column.row > [class*="fifteen wide tablet"].column, 8061 - .ui.grid > [class*="fifteen wide tablet"].column, 8062 - .ui.column.grid > [class*="fifteen wide tablet"].column { 8063 - width: 93.75% !important; 8064 - } 8065 - 8066 - .ui.grid > .row > [class*="sixteen wide tablet"].column, 8067 - .ui.grid > .column.row > [class*="sixteen wide tablet"].column, 8068 - .ui.grid > [class*="sixteen wide tablet"].column, 8069 - .ui.column.grid > [class*="sixteen wide tablet"].column { 8070 - width: 100% !important; 8071 - } 8072 - } 8073 - 8074 - /* Computer/Desktop Sizing Combinations */ 8075 - 8076 - @media only screen and (min-width: 992px) { 8077 - .ui.grid > .row > [class*="one wide computer"].column, 8078 - .ui.grid > .column.row > [class*="one wide computer"].column, 8079 - .ui.grid > [class*="one wide computer"].column, 8080 - .ui.column.grid > [class*="one wide computer"].column { 8081 - width: 6.25% !important; 8082 - } 8083 - 8084 - .ui.grid > .row > [class*="two wide computer"].column, 8085 - .ui.grid > .column.row > [class*="two wide computer"].column, 8086 - .ui.grid > [class*="two wide computer"].column, 8087 - .ui.column.grid > [class*="two wide computer"].column { 8088 - width: 12.5% !important; 8089 - } 8090 - 8091 - .ui.grid > .row > [class*="three wide computer"].column, 8092 - .ui.grid > .column.row > [class*="three wide computer"].column, 8093 - .ui.grid > [class*="three wide computer"].column, 8094 - .ui.column.grid > [class*="three wide computer"].column { 8095 - width: 18.75% !important; 8096 - } 8097 - 8098 - .ui.grid > .row > [class*="four wide computer"].column, 8099 - .ui.grid > .column.row > [class*="four wide computer"].column, 8100 - .ui.grid > [class*="four wide computer"].column, 8101 - .ui.column.grid > [class*="four wide computer"].column { 8102 - width: 25% !important; 8103 - } 8104 - 8105 - .ui.grid > .row > [class*="five wide computer"].column, 8106 - .ui.grid > .column.row > [class*="five wide computer"].column, 8107 - .ui.grid > [class*="five wide computer"].column, 8108 - .ui.column.grid > [class*="five wide computer"].column { 8109 - width: 31.25% !important; 8110 - } 8111 - 8112 - .ui.grid > .row > [class*="six wide computer"].column, 8113 - .ui.grid > .column.row > [class*="six wide computer"].column, 8114 - .ui.grid > [class*="six wide computer"].column, 8115 - .ui.column.grid > [class*="six wide computer"].column { 8116 - width: 37.5% !important; 8117 - } 8118 - 8119 - .ui.grid > .row > [class*="seven wide computer"].column, 8120 - .ui.grid > .column.row > [class*="seven wide computer"].column, 8121 - .ui.grid > [class*="seven wide computer"].column, 8122 - .ui.column.grid > [class*="seven wide computer"].column { 8123 - width: 43.75% !important; 8124 - } 8125 - 8126 - .ui.grid > .row > [class*="eight wide computer"].column, 8127 - .ui.grid > .column.row > [class*="eight wide computer"].column, 8128 - .ui.grid > [class*="eight wide computer"].column, 8129 - .ui.column.grid > [class*="eight wide computer"].column { 8130 - width: 50% !important; 8131 - } 8132 - 8133 - .ui.grid > .row > [class*="nine wide computer"].column, 8134 - .ui.grid > .column.row > [class*="nine wide computer"].column, 8135 - .ui.grid > [class*="nine wide computer"].column, 8136 - .ui.column.grid > [class*="nine wide computer"].column { 8137 - width: 56.25% !important; 8138 - } 8139 - 8140 - .ui.grid > .row > [class*="ten wide computer"].column, 8141 - .ui.grid > .column.row > [class*="ten wide computer"].column, 8142 - .ui.grid > [class*="ten wide computer"].column, 8143 - .ui.column.grid > [class*="ten wide computer"].column { 8144 - width: 62.5% !important; 8145 - } 8146 - 8147 - .ui.grid > .row > [class*="eleven wide computer"].column, 8148 - .ui.grid > .column.row > [class*="eleven wide computer"].column, 8149 - .ui.grid > [class*="eleven wide computer"].column, 8150 - .ui.column.grid > [class*="eleven wide computer"].column { 8151 - width: 68.75% !important; 8152 - } 8153 - 8154 - .ui.grid > .row > [class*="twelve wide computer"].column, 8155 - .ui.grid > .column.row > [class*="twelve wide computer"].column, 8156 - .ui.grid > [class*="twelve wide computer"].column, 8157 - .ui.column.grid > [class*="twelve wide computer"].column { 8158 - width: 75% !important; 8159 - } 8160 - 8161 - .ui.grid > .row > [class*="thirteen wide computer"].column, 8162 - .ui.grid > .column.row > [class*="thirteen wide computer"].column, 8163 - .ui.grid > [class*="thirteen wide computer"].column, 8164 - .ui.column.grid > [class*="thirteen wide computer"].column { 8165 - width: 81.25% !important; 8166 - } 8167 - 8168 - .ui.grid > .row > [class*="fourteen wide computer"].column, 8169 - .ui.grid > .column.row > [class*="fourteen wide computer"].column, 8170 - .ui.grid > [class*="fourteen wide computer"].column, 8171 - .ui.column.grid > [class*="fourteen wide computer"].column { 8172 - width: 87.5% !important; 8173 - } 8174 - 8175 - .ui.grid > .row > [class*="fifteen wide computer"].column, 8176 - .ui.grid > .column.row > [class*="fifteen wide computer"].column, 8177 - .ui.grid > [class*="fifteen wide computer"].column, 8178 - .ui.column.grid > [class*="fifteen wide computer"].column { 8179 - width: 93.75% !important; 8180 - } 8181 - 8182 - .ui.grid > .row > [class*="sixteen wide computer"].column, 8183 - .ui.grid > .column.row > [class*="sixteen wide computer"].column, 8184 - .ui.grid > [class*="sixteen wide computer"].column, 8185 - .ui.column.grid > [class*="sixteen wide computer"].column { 8186 - width: 100% !important; 8187 - } 8188 - } 8189 - 8190 - /* Large Monitor Sizing Combinations */ 8191 - 8192 - @media only screen and (min-width: 1200px) and (max-width: 1919.98px) { 8193 - .ui.grid > .row > [class*="one wide large screen"].column, 8194 - .ui.grid > .column.row > [class*="one wide large screen"].column, 8195 - .ui.grid > [class*="one wide large screen"].column, 8196 - .ui.column.grid > [class*="one wide large screen"].column { 8197 - width: 6.25% !important; 8198 - } 8199 - 8200 - .ui.grid > .row > [class*="two wide large screen"].column, 8201 - .ui.grid > .column.row > [class*="two wide large screen"].column, 8202 - .ui.grid > [class*="two wide large screen"].column, 8203 - .ui.column.grid > [class*="two wide large screen"].column { 8204 - width: 12.5% !important; 8205 - } 8206 - 8207 - .ui.grid > .row > [class*="three wide large screen"].column, 8208 - .ui.grid > .column.row > [class*="three wide large screen"].column, 8209 - .ui.grid > [class*="three wide large screen"].column, 8210 - .ui.column.grid > [class*="three wide large screen"].column { 8211 - width: 18.75% !important; 8212 - } 8213 - 8214 - .ui.grid > .row > [class*="four wide large screen"].column, 8215 - .ui.grid > .column.row > [class*="four wide large screen"].column, 8216 - .ui.grid > [class*="four wide large screen"].column, 8217 - .ui.column.grid > [class*="four wide large screen"].column { 8218 - width: 25% !important; 8219 - } 8220 - 8221 - .ui.grid > .row > [class*="five wide large screen"].column, 8222 - .ui.grid > .column.row > [class*="five wide large screen"].column, 8223 - .ui.grid > [class*="five wide large screen"].column, 8224 - .ui.column.grid > [class*="five wide large screen"].column { 8225 - width: 31.25% !important; 8226 - } 8227 - 8228 - .ui.grid > .row > [class*="six wide large screen"].column, 8229 - .ui.grid > .column.row > [class*="six wide large screen"].column, 8230 - .ui.grid > [class*="six wide large screen"].column, 8231 - .ui.column.grid > [class*="six wide large screen"].column { 8232 - width: 37.5% !important; 8233 - } 8234 - 8235 - .ui.grid > .row > [class*="seven wide large screen"].column, 8236 - .ui.grid > .column.row > [class*="seven wide large screen"].column, 8237 - .ui.grid > [class*="seven wide large screen"].column, 8238 - .ui.column.grid > [class*="seven wide large screen"].column { 8239 - width: 43.75% !important; 8240 - } 8241 - 8242 - .ui.grid > .row > [class*="eight wide large screen"].column, 8243 - .ui.grid > .column.row > [class*="eight wide large screen"].column, 8244 - .ui.grid > [class*="eight wide large screen"].column, 8245 - .ui.column.grid > [class*="eight wide large screen"].column { 8246 - width: 50% !important; 8247 - } 8248 - 8249 - .ui.grid > .row > [class*="nine wide large screen"].column, 8250 - .ui.grid > .column.row > [class*="nine wide large screen"].column, 8251 - .ui.grid > [class*="nine wide large screen"].column, 8252 - .ui.column.grid > [class*="nine wide large screen"].column { 8253 - width: 56.25% !important; 8254 - } 8255 - 8256 - .ui.grid > .row > [class*="ten wide large screen"].column, 8257 - .ui.grid > .column.row > [class*="ten wide large screen"].column, 8258 - .ui.grid > [class*="ten wide large screen"].column, 8259 - .ui.column.grid > [class*="ten wide large screen"].column { 8260 - width: 62.5% !important; 8261 - } 8262 - 8263 - .ui.grid > .row > [class*="eleven wide large screen"].column, 8264 - .ui.grid > .column.row > [class*="eleven wide large screen"].column, 8265 - .ui.grid > [class*="eleven wide large screen"].column, 8266 - .ui.column.grid > [class*="eleven wide large screen"].column { 8267 - width: 68.75% !important; 8268 - } 8269 - 8270 - .ui.grid > .row > [class*="twelve wide large screen"].column, 8271 - .ui.grid > .column.row > [class*="twelve wide large screen"].column, 8272 - .ui.grid > [class*="twelve wide large screen"].column, 8273 - .ui.column.grid > [class*="twelve wide large screen"].column { 8274 - width: 75% !important; 8275 - } 8276 - 8277 - .ui.grid > .row > [class*="thirteen wide large screen"].column, 8278 - .ui.grid > .column.row > [class*="thirteen wide large screen"].column, 8279 - .ui.grid > [class*="thirteen wide large screen"].column, 8280 - .ui.column.grid > [class*="thirteen wide large screen"].column { 8281 - width: 81.25% !important; 8282 - } 8283 - 8284 - .ui.grid > .row > [class*="fourteen wide large screen"].column, 8285 - .ui.grid > .column.row > [class*="fourteen wide large screen"].column, 8286 - .ui.grid > [class*="fourteen wide large screen"].column, 8287 - .ui.column.grid > [class*="fourteen wide large screen"].column { 8288 - width: 87.5% !important; 8289 - } 8290 - 8291 - .ui.grid > .row > [class*="fifteen wide large screen"].column, 8292 - .ui.grid > .column.row > [class*="fifteen wide large screen"].column, 8293 - .ui.grid > [class*="fifteen wide large screen"].column, 8294 - .ui.column.grid > [class*="fifteen wide large screen"].column { 8295 - width: 93.75% !important; 8296 - } 8297 - 8298 - .ui.grid > .row > [class*="sixteen wide large screen"].column, 8299 - .ui.grid > .column.row > [class*="sixteen wide large screen"].column, 8300 - .ui.grid > [class*="sixteen wide large screen"].column, 8301 - .ui.column.grid > [class*="sixteen wide large screen"].column { 8302 - width: 100% !important; 8303 - } 8304 - } 8305 - 8306 - /* Widescreen Sizing Combinations */ 8307 - 8308 - @media only screen and (min-width: 1920px) { 8309 - .ui.grid > .row > [class*="one wide widescreen"].column, 8310 - .ui.grid > .column.row > [class*="one wide widescreen"].column, 8311 - .ui.grid > [class*="one wide widescreen"].column, 8312 - .ui.column.grid > [class*="one wide widescreen"].column { 8313 - width: 6.25% !important; 8314 - } 8315 - 8316 - .ui.grid > .row > [class*="two wide widescreen"].column, 8317 - .ui.grid > .column.row > [class*="two wide widescreen"].column, 8318 - .ui.grid > [class*="two wide widescreen"].column, 8319 - .ui.column.grid > [class*="two wide widescreen"].column { 8320 - width: 12.5% !important; 8321 - } 8322 - 8323 - .ui.grid > .row > [class*="three wide widescreen"].column, 8324 - .ui.grid > .column.row > [class*="three wide widescreen"].column, 8325 - .ui.grid > [class*="three wide widescreen"].column, 8326 - .ui.column.grid > [class*="three wide widescreen"].column { 8327 - width: 18.75% !important; 8328 - } 8329 - 8330 - .ui.grid > .row > [class*="four wide widescreen"].column, 8331 - .ui.grid > .column.row > [class*="four wide widescreen"].column, 8332 - .ui.grid > [class*="four wide widescreen"].column, 8333 - .ui.column.grid > [class*="four wide widescreen"].column { 8334 - width: 25% !important; 8335 - } 8336 - 8337 - .ui.grid > .row > [class*="five wide widescreen"].column, 8338 - .ui.grid > .column.row > [class*="five wide widescreen"].column, 8339 - .ui.grid > [class*="five wide widescreen"].column, 8340 - .ui.column.grid > [class*="five wide widescreen"].column { 8341 - width: 31.25% !important; 8342 - } 8343 - 8344 - .ui.grid > .row > [class*="six wide widescreen"].column, 8345 - .ui.grid > .column.row > [class*="six wide widescreen"].column, 8346 - .ui.grid > [class*="six wide widescreen"].column, 8347 - .ui.column.grid > [class*="six wide widescreen"].column { 8348 - width: 37.5% !important; 8349 - } 8350 - 8351 - .ui.grid > .row > [class*="seven wide widescreen"].column, 8352 - .ui.grid > .column.row > [class*="seven wide widescreen"].column, 8353 - .ui.grid > [class*="seven wide widescreen"].column, 8354 - .ui.column.grid > [class*="seven wide widescreen"].column { 8355 - width: 43.75% !important; 8356 - } 8357 - 8358 - .ui.grid > .row > [class*="eight wide widescreen"].column, 8359 - .ui.grid > .column.row > [class*="eight wide widescreen"].column, 8360 - .ui.grid > [class*="eight wide widescreen"].column, 8361 - .ui.column.grid > [class*="eight wide widescreen"].column { 8362 - width: 50% !important; 8363 - } 8364 - 8365 - .ui.grid > .row > [class*="nine wide widescreen"].column, 8366 - .ui.grid > .column.row > [class*="nine wide widescreen"].column, 8367 - .ui.grid > [class*="nine wide widescreen"].column, 8368 - .ui.column.grid > [class*="nine wide widescreen"].column { 8369 - width: 56.25% !important; 8370 - } 8371 - 8372 - .ui.grid > .row > [class*="ten wide widescreen"].column, 8373 - .ui.grid > .column.row > [class*="ten wide widescreen"].column, 8374 - .ui.grid > [class*="ten wide widescreen"].column, 8375 - .ui.column.grid > [class*="ten wide widescreen"].column { 8376 - width: 62.5% !important; 8377 - } 8378 - 8379 - .ui.grid > .row > [class*="eleven wide widescreen"].column, 8380 - .ui.grid > .column.row > [class*="eleven wide widescreen"].column, 8381 - .ui.grid > [class*="eleven wide widescreen"].column, 8382 - .ui.column.grid > [class*="eleven wide widescreen"].column { 8383 - width: 68.75% !important; 8384 - } 8385 - 8386 - .ui.grid > .row > [class*="twelve wide widescreen"].column, 8387 - .ui.grid > .column.row > [class*="twelve wide widescreen"].column, 8388 - .ui.grid > [class*="twelve wide widescreen"].column, 8389 - .ui.column.grid > [class*="twelve wide widescreen"].column { 8390 - width: 75% !important; 8391 - } 8392 - 8393 - .ui.grid > .row > [class*="thirteen wide widescreen"].column, 8394 - .ui.grid > .column.row > [class*="thirteen wide widescreen"].column, 8395 - .ui.grid > [class*="thirteen wide widescreen"].column, 8396 - .ui.column.grid > [class*="thirteen wide widescreen"].column { 8397 - width: 81.25% !important; 8398 - } 8399 - 8400 - .ui.grid > .row > [class*="fourteen wide widescreen"].column, 8401 - .ui.grid > .column.row > [class*="fourteen wide widescreen"].column, 8402 - .ui.grid > [class*="fourteen wide widescreen"].column, 8403 - .ui.column.grid > [class*="fourteen wide widescreen"].column { 8404 - width: 87.5% !important; 8405 - } 8406 - 8407 - .ui.grid > .row > [class*="fifteen wide widescreen"].column, 8408 - .ui.grid > .column.row > [class*="fifteen wide widescreen"].column, 8409 - .ui.grid > [class*="fifteen wide widescreen"].column, 8410 - .ui.column.grid > [class*="fifteen wide widescreen"].column { 8411 - width: 93.75% !important; 8412 - } 8413 - 8414 - .ui.grid > .row > [class*="sixteen wide widescreen"].column, 8415 - .ui.grid > .column.row > [class*="sixteen wide widescreen"].column, 8416 - .ui.grid > [class*="sixteen wide widescreen"].column, 8417 - .ui.column.grid > [class*="sixteen wide widescreen"].column { 8418 - width: 100% !important; 8419 - } 8420 - } 8421 - 8422 - /*---------------------- 8423 - Centered 8424 - -----------------------*/ 8425 - 8426 - .ui.centered.grid, 8427 - .ui.centered.grid > .row, 8428 - .ui.grid > .centered.row { 8429 - text-align: center; 8430 - justify-content: center; 8431 - } 8432 - 8433 - .ui.centered.grid > .column:not(.aligned):not(.justified):not(.row), 8434 - .ui.centered.grid > .row > .column:not(.aligned):not(.justified), 8435 - .ui.grid .centered.row > .column:not(.aligned):not(.justified) { 8436 - text-align: left; 8437 - } 8438 - 8439 - .ui.grid > .centered.column, 8440 - .ui.grid > .row > .centered.column { 8441 - display: block; 8442 - margin-left: auto; 8443 - margin-right: auto; 8444 - } 8445 - 8446 - /*---------------------- 8447 - Relaxed 8448 - -----------------------*/ 8449 - 8450 - .ui.relaxed.grid > .column:not(.row), 8451 - .ui.relaxed.grid > .row > .column, 8452 - .ui.grid > .relaxed.row > .column { 8453 - padding-left: 1.5rem; 8454 - padding-right: 1.5rem; 8455 - } 8456 - 8457 - .ui[class*="very relaxed"].grid > .column:not(.row), 8458 - .ui[class*="very relaxed"].grid > .row > .column, 8459 - .ui.grid > [class*="very relaxed"].row > .column { 8460 - padding-left: 2.5rem; 8461 - padding-right: 2.5rem; 8462 - } 8463 - 8464 - /* Coupling with UI Divider */ 8465 - 8466 - .ui.relaxed.grid .row + .ui.divider, 8467 - .ui.grid .relaxed.row + .ui.divider { 8468 - margin-left: 1.5rem; 8469 - margin-right: 1.5rem; 8470 - } 8471 - 8472 - .ui[class*="very relaxed"].grid .row + .ui.divider, 8473 - .ui.grid [class*="very relaxed"].row + .ui.divider { 8474 - margin-left: 2.5rem; 8475 - margin-right: 2.5rem; 8476 - } 8477 - 8478 - /*---------------------- 8479 - Padded 8480 - -----------------------*/ 8481 - 8482 - .ui.padded.grid:not(.vertically):not(.horizontally) { 8483 - margin: 0 !important; 8484 - } 8485 - 8486 - [class*="horizontally padded"].ui.grid { 8487 - margin-left: 0 !important; 8488 - margin-right: 0 !important; 8489 - } 8490 - 8491 - [class*="vertically padded"].ui.grid { 8492 - margin-top: 0 !important; 8493 - margin-bottom: 0 !important; 8494 - } 8495 - 8496 - /*---------------------- 8497 - "Floated" 8498 - -----------------------*/ 8499 - 8500 - .ui.grid [class*="left floated"].column { 8501 - margin-right: auto; 8502 - } 8503 - 8504 - .ui.grid [class*="right floated"].column { 8505 - margin-left: auto; 8506 - } 8507 - 8508 - /*---------------------- 8509 - Divided 8510 - -----------------------*/ 8511 - 8512 - .ui.divided.grid:not([class*="vertically divided"]) > .column:not(.row), 8513 - .ui.divided.grid:not([class*="vertically divided"]) > .row > .column { 8514 - box-shadow: -1px 0 0 0 rgba(34, 36, 38, 0.15); 8515 - } 8516 - 8517 - /* Swap from padding to margin on columns to have dividers align */ 8518 - 8519 - .ui[class*="vertically divided"].grid > .column:not(.row), 8520 - .ui[class*="vertically divided"].grid > .row > .column { 8521 - margin-top: 1rem; 8522 - margin-bottom: 1rem; 8523 - padding-top: 0; 8524 - padding-bottom: 0; 8525 - } 8526 - 8527 - .ui[class*="vertically divided"].grid > .row { 8528 - margin-top: 0; 8529 - margin-bottom: 0; 8530 - } 8531 - 8532 - /* No divider on first column on row */ 8533 - 8534 - .ui.divided.grid:not([class*="vertically divided"]) > .column:first-child, 8535 - .ui.divided.grid:not([class*="vertically divided"]) > .row > .column:first-child { 8536 - box-shadow: none; 8537 - } 8538 - 8539 - /* No space on top of first row */ 8540 - 8541 - .ui[class*="vertically divided"].grid > .row:first-child > .column { 8542 - margin-top: 0; 8543 - } 8544 - 8545 - /* Divided Row */ 8546 - 8547 - .ui.grid > .divided.row > .column { 8548 - box-shadow: -1px 0 0 0 rgba(34, 36, 38, 0.15); 8549 - } 8550 - 8551 - .ui.grid > .divided.row > .column:first-child { 8552 - box-shadow: none; 8553 - } 8554 - 8555 - /* Vertically Divided */ 8556 - 8557 - .ui[class*="vertically divided"].grid > .row { 8558 - position: relative; 8559 - } 8560 - 8561 - .ui[class*="vertically divided"].grid > .row:before { 8562 - position: absolute; 8563 - content: ""; 8564 - top: 0; 8565 - left: 0; 8566 - width: calc(100% - 2rem); 8567 - height: 1px; 8568 - margin: 0 1rem; 8569 - box-shadow: 0 -1px 0 0 rgba(34, 36, 38, 0.15); 8570 - } 8571 - 8572 - /* Padded Horizontally Divided */ 8573 - 8574 - [class*="horizontally padded"].ui.divided.grid, 8575 - .ui.padded.divided.grid:not(.vertically):not(.horizontally) { 8576 - width: 100%; 8577 - } 8578 - 8579 - /* First Row Vertically Divided */ 8580 - 8581 - .ui[class*="vertically divided"].grid > .row:first-child:before { 8582 - box-shadow: none; 8583 - } 8584 - 8585 - /* Relaxed */ 8586 - 8587 - .ui.relaxed[class*="vertically divided"].grid > .row:before { 8588 - margin-left: 1.5rem; 8589 - margin-right: 1.5rem; 8590 - width: calc(100% - 3rem); 8591 - } 8592 - 8593 - .ui[class*="very relaxed"][class*="vertically divided"].grid > .row:before { 8594 - margin-left: 2.5rem; 8595 - margin-right: 2.5rem; 8596 - width: calc(100% - 5rem); 8597 - } 8598 - 8599 - /*---------------------- 8600 - Celled 8601 - -----------------------*/ 8602 - 8603 - .ui.celled.grid { 8604 - width: 100%; 8605 - margin: 1em 0; 8606 - box-shadow: 0 0 0 1px #D4D4D5; 8607 - } 8608 - 8609 - .ui.celled.grid > .row { 8610 - width: 100% !important; 8611 - margin: 0; 8612 - padding: 0; 8613 - box-shadow: 0 -1px 0 0 #D4D4D5; 8614 - } 8615 - 8616 - .ui.celled.grid > .column:not(.row), 8617 - .ui.celled.grid > .row > .column { 8618 - box-shadow: -1px 0 0 0 #D4D4D5; 8619 - } 8620 - 8621 - .ui.celled.grid > .column:first-child, 8622 - .ui.celled.grid > .row > .column:first-child { 8623 - box-shadow: none; 8624 - } 8625 - 8626 - .ui.celled.grid > .column:not(.row), 8627 - .ui.celled.grid > .row > .column { 8628 - padding: 1em; 8629 - } 8630 - 8631 - .ui.relaxed.celled.grid > .column:not(.row), 8632 - .ui.relaxed.celled.grid > .row > .column { 8633 - padding: 1.5em; 8634 - } 8635 - 8636 - .ui[class*="very relaxed"].celled.grid > .column:not(.row), 8637 - .ui[class*="very relaxed"].celled.grid > .row > .column { 8638 - padding: 2em; 8639 - } 8640 - 8641 - /* Internally Celled */ 8642 - 8643 - .ui[class*="internally celled"].grid { 8644 - box-shadow: none; 8645 - margin: 0; 8646 - } 8647 - 8648 - .ui[class*="internally celled"].grid > .row:first-child { 8649 - box-shadow: none; 8650 - } 8651 - 8652 - .ui[class*="internally celled"].grid > .row > .column:first-child { 8653 - box-shadow: none; 8654 - } 8655 - 8656 - /*---------------------- 8657 - Vertically Aligned 8658 - -----------------------*/ 8659 - 8660 - /* Top Aligned */ 8661 - 8662 - .ui[class*="top aligned"].grid > .column:not(.row), 8663 - .ui[class*="top aligned"].grid > .row > .column, 8664 - .ui.grid > [class*="top aligned"].row > .column, 8665 - .ui.grid > [class*="top aligned"].column:not(.row), 8666 - .ui.grid > .row > [class*="top aligned"].column { 8667 - flex-direction: column; 8668 - vertical-align: top; 8669 - align-self: flex-start !important; 8670 - } 8671 - 8672 - /* Middle Aligned */ 8673 - 8674 - .ui[class*="middle aligned"].grid > .column:not(.row), 8675 - .ui[class*="middle aligned"].grid > .row > .column, 8676 - .ui.grid > [class*="middle aligned"].row > .column, 8677 - .ui.grid > [class*="middle aligned"].column:not(.row), 8678 - .ui.grid > .row > [class*="middle aligned"].column { 8679 - flex-direction: column; 8680 - vertical-align: middle; 8681 - align-self: center !important; 8682 - } 8683 - 8684 - /* Bottom Aligned */ 8685 - 8686 - .ui[class*="bottom aligned"].grid > .column:not(.row), 8687 - .ui[class*="bottom aligned"].grid > .row > .column, 8688 - .ui.grid > [class*="bottom aligned"].row > .column, 8689 - .ui.grid > [class*="bottom aligned"].column:not(.row), 8690 - .ui.grid > .row > [class*="bottom aligned"].column { 8691 - flex-direction: column; 8692 - vertical-align: bottom; 8693 - align-self: flex-end !important; 8694 - } 8695 - 8696 - /* Stretched */ 8697 - 8698 - .ui.stretched.grid > .row > .column, 8699 - .ui.stretched.grid > .column, 8700 - .ui.grid > .stretched.row > .column, 8701 - .ui.grid > .stretched.column:not(.row), 8702 - .ui.grid > .row > .stretched.column { 8703 - display: inline-flex !important; 8704 - align-self: stretch; 8705 - flex-direction: column; 8706 - } 8707 - 8708 - .ui.stretched.grid > .row > .column > *, 8709 - .ui.stretched.grid > .column > *, 8710 - .ui.grid > .stretched.row > .column > *, 8711 - .ui.grid > .stretched.column:not(.row) > *, 8712 - .ui.grid > .row > .stretched.column > * { 8713 - flex-grow: 1; 8714 - } 8715 - 8716 - /*---------------------- 8717 - Horizontally Centered 8718 - -----------------------*/ 8719 - 8720 - /* Left Aligned */ 8721 - 8722 - .ui[class*="left aligned"].grid > .column, 8723 - .ui[class*="left aligned"].grid > .row > .column, 8724 - .ui.grid > [class*="left aligned"].row > .column, 8725 - .ui.grid > [class*="left aligned"].column.column, 8726 - .ui.grid > .row > [class*="left aligned"].column.column { 8727 - text-align: left; 8728 - align-self: inherit; 8729 - } 8730 - 8731 - /* Center Aligned */ 8732 - 8733 - .ui[class*="center aligned"].grid > .column, 8734 - .ui[class*="center aligned"].grid > .row > .column, 8735 - .ui.grid > [class*="center aligned"].row > .column, 8736 - .ui.grid > [class*="center aligned"].column.column, 8737 - .ui.grid > .row > [class*="center aligned"].column.column { 8738 - text-align: center; 8739 - align-self: inherit; 8740 - } 8741 - 8742 - .ui[class*="center aligned"].grid { 8743 - justify-content: center; 8744 - } 8745 - 8746 - /* Right Aligned */ 8747 - 8748 - .ui[class*="right aligned"].grid > .column, 8749 - .ui[class*="right aligned"].grid > .row > .column, 8750 - .ui.grid > [class*="right aligned"].row > .column, 8751 - .ui.grid > [class*="right aligned"].column.column, 8752 - .ui.grid > .row > [class*="right aligned"].column.column { 8753 - text-align: right; 8754 - align-self: inherit; 8755 - } 8756 - 8757 - /* Justified */ 8758 - 8759 - .ui.justified.grid > .column, 8760 - .ui.justified.grid > .row > .column, 8761 - .ui.grid > .justified.row > .column, 8762 - .ui.grid > .justified.column.column, 8763 - .ui.grid > .row > .justified.column.column { 8764 - text-align: justify; 8765 - -webkit-hyphens: auto; 8766 - hyphens: auto; 8767 - } 8768 - 8769 - /*---------------------- 8770 - Colored 8771 - -----------------------*/ 8772 - 8773 - .ui.grid > .primary.row, 8774 - .ui.grid > .primary.column, 8775 - .ui.grid > .row > .primary.column { 8776 - background-color: #2185D0; 8777 - color: #FFFFFF; 8778 - } 8779 - 8780 - .ui.grid > .secondary.row, 8781 - .ui.grid > .secondary.column, 8782 - .ui.grid > .row > .secondary.column { 8783 - background-color: #1B1C1D; 8784 - color: #FFFFFF; 8785 - } 8786 - 8787 - .ui.grid > .red.row, 8788 - .ui.grid > .red.column, 8789 - .ui.grid > .row > .red.column { 8790 - background-color: #DB2828; 8791 - color: #FFFFFF; 8792 - } 8793 - 8794 - .ui.grid > .orange.row, 8795 - .ui.grid > .orange.column, 8796 - .ui.grid > .row > .orange.column { 8797 - background-color: #F2711C; 8798 - color: #FFFFFF; 8799 - } 8800 - 8801 - .ui.grid > .yellow.row, 8802 - .ui.grid > .yellow.column, 8803 - .ui.grid > .row > .yellow.column { 8804 - background-color: #FBBD08; 8805 - color: #FFFFFF; 8806 - } 8807 - 8808 - .ui.grid > .olive.row, 8809 - .ui.grid > .olive.column, 8810 - .ui.grid > .row > .olive.column { 8811 - background-color: #B5CC18; 8812 - color: #FFFFFF; 8813 - } 8814 - 8815 - .ui.grid > .green.row, 8816 - .ui.grid > .green.column, 8817 - .ui.grid > .row > .green.column { 8818 - background-color: #21BA45; 8819 - color: #FFFFFF; 8820 - } 8821 - 8822 - .ui.grid > .teal.row, 8823 - .ui.grid > .teal.column, 8824 - .ui.grid > .row > .teal.column { 8825 - background-color: #00B5AD; 8826 - color: #FFFFFF; 8827 - } 8828 - 8829 - .ui.grid > .blue.row, 8830 - .ui.grid > .blue.column, 8831 - .ui.grid > .row > .blue.column { 8832 - background-color: #2185D0; 8833 - color: #FFFFFF; 8834 - } 8835 - 8836 - .ui.grid > .violet.row, 8837 - .ui.grid > .violet.column, 8838 - .ui.grid > .row > .violet.column { 8839 - background-color: #6435C9; 8840 - color: #FFFFFF; 8841 - } 8842 - 8843 - .ui.grid > .purple.row, 8844 - .ui.grid > .purple.column, 8845 - .ui.grid > .row > .purple.column { 8846 - background-color: #A333C8; 8847 - color: #FFFFFF; 8848 - } 8849 - 8850 - .ui.grid > .pink.row, 8851 - .ui.grid > .pink.column, 8852 - .ui.grid > .row > .pink.column { 8853 - background-color: #E03997; 8854 - color: #FFFFFF; 8855 - } 8856 - 8857 - .ui.grid > .brown.row, 8858 - .ui.grid > .brown.column, 8859 - .ui.grid > .row > .brown.column { 8860 - background-color: #A5673F; 8861 - color: #FFFFFF; 8862 - } 8863 - 8864 - .ui.grid > .grey.row, 8865 - .ui.grid > .grey.column, 8866 - .ui.grid > .row > .grey.column { 8867 - background-color: #767676; 8868 - color: #FFFFFF; 8869 - } 8870 - 8871 - .ui.grid > .black.row, 8872 - .ui.grid > .black.column, 8873 - .ui.grid > .row > .black.column { 8874 - background-color: #1B1C1D; 8875 - color: #FFFFFF; 8876 - } 8877 - 8878 - /*---------------------- 8879 - Equal Width 8880 - -----------------------*/ 8881 - 8882 - .ui[class*="equal width"].grid > .column:not(.row), 8883 - .ui[class*="equal width"].grid > .row > .column, 8884 - .ui.grid > [class*="equal width"].row > .column { 8885 - display: inline-block; 8886 - flex-grow: 1; 8887 - } 8888 - 8889 - .ui[class*="equal width"].grid > .wide.column, 8890 - .ui[class*="equal width"].grid > .row > .wide.column, 8891 - .ui.grid > [class*="equal width"].row > .wide.column { 8892 - flex-grow: 0; 8893 - } 8894 - 8895 - /*---------------------- 8896 - Reverse 8897 - -----------------------*/ 8898 - 8899 - /* Mobile */ 8900 - 8901 - @media only screen and (max-width: 767.98px) { 8902 - .ui[class*="mobile reversed"].grid, 8903 - .ui[class*="mobile reversed"].grid > .row, 8904 - .ui.grid > [class*="mobile reversed"].row { 8905 - flex-direction: row-reverse; 8906 - } 8907 - 8908 - .ui[class*="mobile vertically reversed"].grid, 8909 - .ui.stackable[class*="mobile reversed"] { 8910 - flex-direction: column-reverse; 8911 - } 8912 - 8913 - /* Divided Reversed */ 8914 - 8915 - .ui[class*="mobile reversed"].divided.grid:not([class*="vertically divided"]) > .column:first-child, 8916 - .ui[class*="mobile reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:first-child { 8917 - box-shadow: -1px 0 0 0 rgba(34, 36, 38, 0.15); 8918 - } 8919 - 8920 - .ui[class*="mobile reversed"].divided.grid:not([class*="vertically divided"]) > .column:last-child, 8921 - .ui[class*="mobile reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:last-child { 8922 - box-shadow: none; 8923 - } 8924 - 8925 - /* Vertically Divided Reversed */ 8926 - 8927 - .ui.grid[class*="vertically divided"][class*="mobile vertically reversed"] > .row:first-child:before { 8928 - box-shadow: 0 -1px 0 0 rgba(34, 36, 38, 0.15); 8929 - } 8930 - 8931 - .ui.grid[class*="vertically divided"][class*="mobile vertically reversed"] > .row:last-child:before { 8932 - box-shadow: none; 8933 - } 8934 - 8935 - /* Celled Reversed */ 8936 - 8937 - .ui[class*="mobile reversed"].celled.grid > .row > .column:first-child { 8938 - box-shadow: -1px 0 0 0 #D4D4D5; 8939 - } 8940 - 8941 - .ui[class*="mobile reversed"].celled.grid > .row > .column:last-child { 8942 - box-shadow: none; 8943 - } 8944 - } 8945 - 8946 - /* Tablet */ 8947 - 8948 - @media only screen and (min-width: 768px) and (max-width: 991.98px) { 8949 - .ui[class*="tablet reversed"].grid, 8950 - .ui[class*="tablet reversed"].grid > .row, 8951 - .ui.grid > [class*="tablet reversed"].row { 8952 - flex-direction: row-reverse; 8953 - } 8954 - 8955 - .ui[class*="tablet vertically reversed"].grid { 8956 - flex-direction: column-reverse; 8957 - } 8958 - 8959 - /* Divided Reversed */ 8960 - 8961 - .ui[class*="tablet reversed"].divided.grid:not([class*="vertically divided"]) > .column:first-child, 8962 - .ui[class*="tablet reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:first-child { 8963 - box-shadow: -1px 0 0 0 rgba(34, 36, 38, 0.15); 8964 - } 8965 - 8966 - .ui[class*="tablet reversed"].divided.grid:not([class*="vertically divided"]) > .column:last-child, 8967 - .ui[class*="tablet reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:last-child { 8968 - box-shadow: none; 8969 - } 8970 - 8971 - /* Vertically Divided Reversed */ 8972 - 8973 - .ui.grid[class*="vertically divided"][class*="tablet vertically reversed"] > .row:first-child:before { 8974 - box-shadow: 0 -1px 0 0 rgba(34, 36, 38, 0.15); 8975 - } 8976 - 8977 - .ui.grid[class*="vertically divided"][class*="tablet vertically reversed"] > .row:last-child:before { 8978 - box-shadow: none; 8979 - } 8980 - 8981 - /* Celled Reversed */ 8982 - 8983 - .ui[class*="tablet reversed"].celled.grid > .row > .column:first-child { 8984 - box-shadow: -1px 0 0 0 #D4D4D5; 8985 - } 8986 - 8987 - .ui[class*="tablet reversed"].celled.grid > .row > .column:last-child { 8988 - box-shadow: none; 8989 - } 8990 - } 8991 - 8992 - /* Computer */ 8993 - 8994 - @media only screen and (min-width: 992px) { 8995 - .ui[class*="computer reversed"].grid, 8996 - .ui[class*="computer reversed"].grid > .row, 8997 - .ui.grid > [class*="computer reversed"].row { 8998 - flex-direction: row-reverse; 8999 - } 9000 - 9001 - .ui[class*="computer vertically reversed"].grid { 9002 - flex-direction: column-reverse; 9003 - } 9004 - 9005 - /* Divided Reversed */ 9006 - 9007 - .ui[class*="computer reversed"].divided.grid:not([class*="vertically divided"]) > .column:first-child, 9008 - .ui[class*="computer reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:first-child { 9009 - box-shadow: -1px 0 0 0 rgba(34, 36, 38, 0.15); 9010 - } 9011 - 9012 - .ui[class*="computer reversed"].divided.grid:not([class*="vertically divided"]) > .column:last-child, 9013 - .ui[class*="computer reversed"].divided.grid:not([class*="vertically divided"]) > .row > .column:last-child { 9014 - box-shadow: none; 9015 - } 9016 - 9017 - /* Vertically Divided Reversed */ 9018 - 9019 - .ui.grid[class*="vertically divided"][class*="computer vertically reversed"] > .row:first-child:before { 9020 - box-shadow: 0 -1px 0 0 rgba(34, 36, 38, 0.15); 9021 - } 9022 - 9023 - .ui.grid[class*="vertically divided"][class*="computer vertically reversed"] > .row:last-child:before { 9024 - box-shadow: none; 9025 - } 9026 - 9027 - /* Celled Reversed */ 9028 - 9029 - .ui[class*="computer reversed"].celled.grid > .row > .column:first-child { 9030 - box-shadow: -1px 0 0 0 #D4D4D5; 9031 - } 9032 - 9033 - .ui[class*="computer reversed"].celled.grid > .row > .column:last-child { 9034 - box-shadow: none; 9035 - } 9036 - } 9037 - 9038 - /*------------------- 9039 - Stackable 9040 - --------------------*/ 9041 - 9042 - @media only screen and (max-width: 767.98px) { 9043 - .ui.stackable.grid { 9044 - width: auto; 9045 - margin-left: 0 !important; 9046 - margin-right: 0 !important; 9047 - } 9048 - 9049 - .ui.stackable.grid > .row > .wide.column, 9050 - .ui.stackable.grid > .wide.column, 9051 - .ui.stackable.grid > .column.grid > .column, 9052 - .ui.stackable.grid > .column.row > .column, 9053 - .ui.stackable.grid > .row > .column, 9054 - .ui.stackable.grid > .column:not(.row), 9055 - .ui.grid > .stackable.stackable.stackable.row > .column { 9056 - width: 100% !important; 9057 - margin: 0 0 !important; 9058 - box-shadow: none !important; 9059 - padding: 1rem 1rem; 9060 - } 9061 - 9062 - .ui.stackable.grid:not(.vertically) > .row { 9063 - margin: 0; 9064 - padding: 0; 9065 - } 9066 - 9067 - /* Coupling */ 9068 - 9069 - .ui.container > .ui.stackable.grid > .column, 9070 - .ui.container > .ui.stackable.grid > .row > .column { 9071 - padding-left: 0 !important; 9072 - padding-right: 0 !important; 9073 - } 9074 - 9075 - /* Don't pad inside segment or nested grid */ 9076 - 9077 - .ui.grid .ui.stackable.grid, 9078 - .ui.segment:not(.vertical) .ui.stackable.page.grid { 9079 - margin-left: -1rem !important; 9080 - margin-right: -1rem !important; 9081 - } 9082 - 9083 - /* Divided Stackable */ 9084 - 9085 - .ui.stackable.divided.grid > .row:first-child > .column:first-child, 9086 - .ui.stackable.celled.grid > .row:first-child > .column:first-child, 9087 - .ui.stackable.divided.grid > .column:not(.row):first-child, 9088 - .ui.stackable.celled.grid > .column:not(.row):first-child { 9089 - border-top: none !important; 9090 - } 9091 - 9092 - .ui.stackable.celled.grid > .column:not(.row), 9093 - .ui.stackable.divided:not(.vertically).grid > .column:not(.row), 9094 - .ui.stackable.celled.grid > .row > .column, 9095 - .ui.stackable.divided:not(.vertically).grid > .row > .column { 9096 - border-top: 1px solid rgba(34, 36, 38, 0.15); 9097 - box-shadow: none !important; 9098 - padding-top: 2rem !important; 9099 - padding-bottom: 2rem !important; 9100 - } 9101 - 9102 - .ui.stackable.celled.grid > .row { 9103 - box-shadow: none !important; 9104 - } 9105 - 9106 - .ui.stackable.divided:not(.vertically).grid > .column:not(.row), 9107 - .ui.stackable.divided:not(.vertically).grid > .row > .column { 9108 - padding-left: 0 !important; 9109 - padding-right: 0 !important; 9110 - } 9111 - } 9112 - 9113 - /*---------------------- 9114 - Only (Device) 9115 - -----------------------*/ 9116 - 9117 - /* These include arbitrary class repetitions for forced specificity */ 9118 - 9119 - /* Mobile Only Hide */ 9120 - 9121 - @media only screen and (max-width: 767.98px) { 9122 - .ui[class*="tablet only"].grid.grid.grid:not(.mobile), 9123 - .ui.grid.grid.grid > [class*="tablet only"].row:not(.mobile), 9124 - .ui.grid.grid.grid > [class*="tablet only"].column:not(.mobile), 9125 - .ui.grid.grid.grid > .row > [class*="tablet only"].column:not(.mobile) { 9126 - display: none !important; 9127 - } 9128 - 9129 - .ui[class*="computer only"].grid.grid.grid:not(.mobile), 9130 - .ui.grid.grid.grid > [class*="computer only"].row:not(.mobile), 9131 - .ui.grid.grid.grid > [class*="computer only"].column:not(.mobile), 9132 - .ui.grid.grid.grid > .row > [class*="computer only"].column:not(.mobile) { 9133 - display: none !important; 9134 - } 9135 - 9136 - .ui[class*="large screen only"].grid.grid.grid:not(.mobile), 9137 - .ui.grid.grid.grid > [class*="large screen only"].row:not(.mobile), 9138 - .ui.grid.grid.grid > [class*="large screen only"].column:not(.mobile), 9139 - .ui.grid.grid.grid > .row > [class*="large screen only"].column:not(.mobile) { 9140 - display: none !important; 9141 - } 9142 - 9143 - .ui[class*="widescreen only"].grid.grid.grid:not(.mobile), 9144 - .ui.grid.grid.grid > [class*="widescreen only"].row:not(.mobile), 9145 - .ui.grid.grid.grid > [class*="widescreen only"].column:not(.mobile), 9146 - .ui.grid.grid.grid > .row > [class*="widescreen only"].column:not(.mobile) { 9147 - display: none !important; 9148 - } 9149 - } 9150 - 9151 - /* Tablet Only Hide */ 9152 - 9153 - @media only screen and (min-width: 768px) and (max-width: 991.98px) { 9154 - .ui[class*="mobile only"].grid.grid.grid:not(.tablet), 9155 - .ui.grid.grid.grid > [class*="mobile only"].row:not(.tablet), 9156 - .ui.grid.grid.grid > [class*="mobile only"].column:not(.tablet), 9157 - .ui.grid.grid.grid > .row > [class*="mobile only"].column:not(.tablet) { 9158 - display: none !important; 9159 - } 9160 - 9161 - .ui[class*="computer only"].grid.grid.grid:not(.tablet), 9162 - .ui.grid.grid.grid > [class*="computer only"].row:not(.tablet), 9163 - .ui.grid.grid.grid > [class*="computer only"].column:not(.tablet), 9164 - .ui.grid.grid.grid > .row > [class*="computer only"].column:not(.tablet) { 9165 - display: none !important; 9166 - } 9167 - 9168 - .ui[class*="large screen only"].grid.grid.grid:not(.mobile), 9169 - .ui.grid.grid.grid > [class*="large screen only"].row:not(.mobile), 9170 - .ui.grid.grid.grid > [class*="large screen only"].column:not(.mobile), 9171 - .ui.grid.grid.grid > .row > [class*="large screen only"].column:not(.mobile) { 9172 - display: none !important; 9173 - } 9174 - 9175 - .ui[class*="widescreen only"].grid.grid.grid:not(.mobile), 9176 - .ui.grid.grid.grid > [class*="widescreen only"].row:not(.mobile), 9177 - .ui.grid.grid.grid > [class*="widescreen only"].column:not(.mobile), 9178 - .ui.grid.grid.grid > .row > [class*="widescreen only"].column:not(.mobile) { 9179 - display: none !important; 9180 - } 9181 - } 9182 - 9183 - /* Computer Only Hide */ 9184 - 9185 - @media only screen and (min-width: 992px) and (max-width: 1199.98px) { 9186 - .ui[class*="mobile only"].grid.grid.grid:not(.computer), 9187 - .ui.grid.grid.grid > [class*="mobile only"].row:not(.computer), 9188 - .ui.grid.grid.grid > [class*="mobile only"].column:not(.computer), 9189 - .ui.grid.grid.grid > .row > [class*="mobile only"].column:not(.computer) { 9190 - display: none !important; 9191 - } 9192 - 9193 - .ui[class*="tablet only"].grid.grid.grid:not(.computer), 9194 - .ui.grid.grid.grid > [class*="tablet only"].row:not(.computer), 9195 - .ui.grid.grid.grid > [class*="tablet only"].column:not(.computer), 9196 - .ui.grid.grid.grid > .row > [class*="tablet only"].column:not(.computer) { 9197 - display: none !important; 9198 - } 9199 - 9200 - .ui[class*="large screen only"].grid.grid.grid:not(.mobile), 9201 - .ui.grid.grid.grid > [class*="large screen only"].row:not(.mobile), 9202 - .ui.grid.grid.grid > [class*="large screen only"].column:not(.mobile), 9203 - .ui.grid.grid.grid > .row > [class*="large screen only"].column:not(.mobile) { 9204 - display: none !important; 9205 - } 9206 - 9207 - .ui[class*="widescreen only"].grid.grid.grid:not(.mobile), 9208 - .ui.grid.grid.grid > [class*="widescreen only"].row:not(.mobile), 9209 - .ui.grid.grid.grid > [class*="widescreen only"].column:not(.mobile), 9210 - .ui.grid.grid.grid > .row > [class*="widescreen only"].column:not(.mobile) { 9211 - display: none !important; 9212 - } 9213 - } 9214 - 9215 - /* Large Screen Only Hide */ 9216 - 9217 - @media only screen and (min-width: 1200px) and (max-width: 1919.98px) { 9218 - .ui[class*="mobile only"].grid.grid.grid:not(.computer), 9219 - .ui.grid.grid.grid > [class*="mobile only"].row:not(.computer), 9220 - .ui.grid.grid.grid > [class*="mobile only"].column:not(.computer), 9221 - .ui.grid.grid.grid > .row > [class*="mobile only"].column:not(.computer) { 9222 - display: none !important; 9223 - } 9224 - 9225 - .ui[class*="tablet only"].grid.grid.grid:not(.computer), 9226 - .ui.grid.grid.grid > [class*="tablet only"].row:not(.computer), 9227 - .ui.grid.grid.grid > [class*="tablet only"].column:not(.computer), 9228 - .ui.grid.grid.grid > .row > [class*="tablet only"].column:not(.computer) { 9229 - display: none !important; 9230 - } 9231 - 9232 - .ui[class*="widescreen only"].grid.grid.grid:not(.mobile), 9233 - .ui.grid.grid.grid > [class*="widescreen only"].row:not(.mobile), 9234 - .ui.grid.grid.grid > [class*="widescreen only"].column:not(.mobile), 9235 - .ui.grid.grid.grid > .row > [class*="widescreen only"].column:not(.mobile) { 9236 - display: none !important; 9237 - } 9238 - } 9239 - 9240 - /* Widescreen Only Hide */ 9241 - 9242 - @media only screen and (min-width: 1920px) { 9243 - .ui[class*="mobile only"].grid.grid.grid:not(.computer), 9244 - .ui.grid.grid.grid > [class*="mobile only"].row:not(.computer), 9245 - .ui.grid.grid.grid > [class*="mobile only"].column:not(.computer), 9246 - .ui.grid.grid.grid > .row > [class*="mobile only"].column:not(.computer) { 9247 - display: none !important; 9248 - } 9249 - 9250 - .ui[class*="tablet only"].grid.grid.grid:not(.computer), 9251 - .ui.grid.grid.grid > [class*="tablet only"].row:not(.computer), 9252 - .ui.grid.grid.grid > [class*="tablet only"].column:not(.computer), 9253 - .ui.grid.grid.grid > .row > [class*="tablet only"].column:not(.computer) { 9254 - display: none !important; 9255 - } 9256 - } 9257 - 9258 - /*----------------- 9259 - Compact 9260 - -----------------*/ 9261 - 9262 - .ui.ui.ui.compact.grid > .column:not(.row), 9263 - .ui.ui.ui.compact.grid > .row > .column { 9264 - padding-left: 0.5rem; 9265 - padding-right: 0.5rem; 9266 - } 9267 - 9268 - .ui.ui.ui.compact.grid > * { 9269 - padding-left: 0.5rem; 9270 - padding-right: 0.5rem; 9271 - } 9272 - 9273 - /* Row */ 9274 - 9275 - .ui.ui.ui.compact.grid > .row { 9276 - padding-top: 0.5rem; 9277 - padding-bottom: 0.5rem; 9278 - } 9279 - 9280 - /* Columns */ 9281 - 9282 - .ui.ui.ui.compact.grid > .column:not(.row) { 9283 - padding-top: 0.5rem; 9284 - padding-bottom: 0.5rem; 9285 - } 9286 - 9287 - /* Relaxed + Celled */ 9288 - 9289 - .ui.compact.relaxed.celled.grid > .column:not(.row), 9290 - .ui.compact.relaxed.celled.grid > .row > .column { 9291 - padding: 0.75em; 9292 - } 9293 - 9294 - .ui.compact[class*="very relaxed"].celled.grid > .column:not(.row), 9295 - .ui.compact[class*="very relaxed"].celled.grid > .row > .column { 9296 - padding: 1em; 9297 - } 9298 - 9299 - /*----------------- 9300 - Very compact 9301 - -----------------*/ 9302 - 9303 - .ui.ui.ui[class*="very compact"].grid > .column:not(.row), 9304 - .ui.ui.ui[class*="very compact"].grid > .row > .column { 9305 - padding-left: 0.25rem; 9306 - padding-right: 0.25rem; 9307 - } 9308 - 9309 - .ui.ui.ui[class*="very compact"].grid > * { 9310 - padding-left: 0.25rem; 9311 - padding-right: 0.25rem; 9312 - } 9313 - 9314 - /* Row */ 9315 - 9316 - .ui.ui.ui[class*="very compact"].grid > .row { 9317 - padding-top: 0.25rem; 9318 - padding-bottom: 0.25rem; 9319 - padding-left: 0.75rem; 9320 - padding-right: 0.75rem; 9321 - } 9322 - 9323 - /* Columns */ 9324 - 9325 - .ui.ui.ui[class*="very compact"].grid > .column:not(.row) { 9326 - padding-top: 0.25rem; 9327 - padding-bottom: 0.25rem; 9328 - } 9329 - 9330 - /* Relaxed + Celled */ 9331 - 9332 - .ui[class*="very compact"].relaxed.celled.grid > .column:not(.row), 9333 - .ui[class*="very compact"].relaxed.celled.grid > .row > .column { 9334 - padding: 0.375em; 9335 - } 9336 - 9337 - .ui[class*="very compact"][class*="very relaxed"].celled.grid > .column:not(.row), 9338 - .ui[class*="very compact"][class*="very relaxed"].celled.grid > .row > .column { 9339 - padding: 0.5em; 9340 - } 9341 - 9342 - /******************************* 9343 - Theme Overrides 9344 - *******************************/ 9345 - 9346 - /******************************* 9347 - Site Overrides 9348 - *******************************/ 9349 - /*! 9350 7347 * # Fomantic-UI - Header 9351 7348 * http://github.com/fomantic/Fomantic-UI/ 9352 7349 * ··· 16953 14950 16954 14951 /******************************* 16955 14952 Theme Overrides 16956 - *******************************/ 16957 - 16958 - /******************************* 16959 - Site Overrides 16960 - *******************************/ 16961 - /*! 16962 - * # Fomantic-UI - Site 16963 - * http://github.com/fomantic/Fomantic-UI/ 16964 - * 16965 - * 16966 - * Released under the MIT license 16967 - * http://opensource.org/licenses/MIT 16968 - * 16969 - */ 16970 - 16971 - /******************************* 16972 - Page 16973 - *******************************/ 16974 - 16975 - html, 16976 - body { 16977 - height: 100%; 16978 - } 16979 - 16980 - html { 16981 - font-size: 14px; 16982 - } 16983 - 16984 - body { 16985 - margin: 0; 16986 - padding: 0; 16987 - overflow-x: visible; 16988 - min-width: 320px; 16989 - background: #FFFFFF; 16990 - font-family: var(--fonts-regular); 16991 - font-size: 14px; 16992 - line-height: 1.4285em; 16993 - color: rgba(0, 0, 0, 0.87); 16994 - } 16995 - 16996 - /******************************* 16997 - Headers 16998 - *******************************/ 16999 - 17000 - h1, 17001 - h2, 17002 - h3, 17003 - h4, 17004 - h5 { 17005 - font-family: var(--fonts-regular); 17006 - line-height: 1.28571429em; 17007 - margin: calc(2rem - 0.1428571428571429em) 0 1rem; 17008 - font-weight: 500; 17009 - padding: 0; 17010 - } 17011 - 17012 - h1 { 17013 - min-height: 1rem; 17014 - font-size: 2rem; 17015 - } 17016 - 17017 - h2 { 17018 - font-size: 1.71428571rem; 17019 - } 17020 - 17021 - h3 { 17022 - font-size: 1.28571429rem; 17023 - } 17024 - 17025 - h4 { 17026 - font-size: 1.07142857rem; 17027 - } 17028 - 17029 - h5 { 17030 - font-size: 1rem; 17031 - } 17032 - 17033 - h1:first-child, 17034 - h2:first-child, 17035 - h3:first-child, 17036 - h4:first-child, 17037 - h5:first-child { 17038 - margin-top: 0; 17039 - } 17040 - 17041 - h1:last-child, 17042 - h2:last-child, 17043 - h3:last-child, 17044 - h4:last-child, 17045 - h5:last-child { 17046 - margin-bottom: 0; 17047 - } 17048 - 17049 - /******************************* 17050 - Text 17051 - *******************************/ 17052 - 17053 - p { 17054 - margin: 0 0 1em; 17055 - line-height: 1.4285em; 17056 - } 17057 - 17058 - p:first-child { 17059 - margin-top: 0; 17060 - } 17061 - 17062 - p:last-child { 17063 - margin-bottom: 0; 17064 - } 17065 - 17066 - /*------------------- 17067 - Links 17068 - --------------------*/ 17069 - 17070 - a { 17071 - color: #4183C4; 17072 - text-decoration: none; 17073 - } 17074 - 17075 - a:hover { 17076 - color: #1e70bf; 17077 - text-decoration: underline; 17078 - } 17079 - 17080 - /******************************* 17081 - Scrollbars 17082 - *******************************/ 17083 - 17084 - /******************************* 17085 - Highlighting 17086 - *******************************/ 17087 - 17088 - /* Site */ 17089 - 17090 - ::-webkit-selection { 17091 - background-color: #CCE2FF; 17092 - color: rgba(0, 0, 0, 0.87); 17093 - } 17094 - 17095 - ::-moz-selection { 17096 - background-color: #CCE2FF; 17097 - color: rgba(0, 0, 0, 0.87); 17098 - } 17099 - 17100 - ::selection { 17101 - background-color: #CCE2FF; 17102 - color: rgba(0, 0, 0, 0.87); 17103 - } 17104 - 17105 - /* Form */ 17106 - 17107 - textarea::-webkit-selection, 17108 - input::-webkit-selection { 17109 - background-color: rgba(100, 100, 100, 0.4); 17110 - color: rgba(0, 0, 0, 0.87); 17111 - } 17112 - 17113 - textarea::-moz-selection, 17114 - input::-moz-selection { 17115 - background-color: rgba(100, 100, 100, 0.4); 17116 - color: rgba(0, 0, 0, 0.87); 17117 - } 17118 - 17119 - textarea::-moz-selection, 17120 - input::-moz-selection { 17121 - background-color: rgba(100, 100, 100, 0.4); 17122 - color: rgba(0, 0, 0, 0.87); 17123 - } 17124 - 17125 - textarea::selection, 17126 - input::selection { 17127 - background-color: rgba(100, 100, 100, 0.4); 17128 - color: rgba(0, 0, 0, 0.87); 17129 - } 17130 - 17131 - /******************************* 17132 - Global Overrides 17133 14953 *******************************/ 17134 14954 17135 14955 /*******************************
-494
web_src/fomantic/build/semantic.js
··· 11867 11867 })( jQuery, window, document ); 11868 11868 11869 11869 /*! 11870 - * # Fomantic-UI - Site 11871 - * http://github.com/fomantic/Fomantic-UI/ 11872 - * 11873 - * 11874 - * Released under the MIT license 11875 - * http://opensource.org/licenses/MIT 11876 - * 11877 - */ 11878 - 11879 - ;(function ($, window, document, undefined) { 11880 - 11881 - $.isFunction = $.isFunction || function(obj) { 11882 - return typeof obj === "function" && typeof obj.nodeType !== "number"; 11883 - }; 11884 - 11885 - $.site = $.fn.site = function(parameters) { 11886 - var 11887 - time = new Date().getTime(), 11888 - performance = [], 11889 - 11890 - query = arguments[0], 11891 - methodInvoked = (typeof query == 'string'), 11892 - queryArguments = [].slice.call(arguments, 1), 11893 - 11894 - settings = ( $.isPlainObject(parameters) ) 11895 - ? $.extend(true, {}, $.site.settings, parameters) 11896 - : $.extend({}, $.site.settings), 11897 - 11898 - namespace = settings.namespace, 11899 - error = settings.error, 11900 - 11901 - moduleNamespace = 'module-' + namespace, 11902 - 11903 - $document = $(document), 11904 - $module = $document, 11905 - element = this, 11906 - instance = $module.data(moduleNamespace), 11907 - 11908 - module, 11909 - returnedValue 11910 - ; 11911 - module = { 11912 - 11913 - initialize: function() { 11914 - module.instantiate(); 11915 - }, 11916 - 11917 - instantiate: function() { 11918 - module.verbose('Storing instance of site', module); 11919 - instance = module; 11920 - $module 11921 - .data(moduleNamespace, module) 11922 - ; 11923 - }, 11924 - 11925 - normalize: function() { 11926 - module.fix.console(); 11927 - module.fix.requestAnimationFrame(); 11928 - }, 11929 - 11930 - fix: { 11931 - console: function() { 11932 - module.debug('Normalizing window.console'); 11933 - if (console === undefined || console.log === undefined) { 11934 - module.verbose('Console not available, normalizing events'); 11935 - module.disable.console(); 11936 - } 11937 - if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') { 11938 - module.verbose('Console group not available, normalizing events'); 11939 - window.console.group = function() {}; 11940 - window.console.groupEnd = function() {}; 11941 - window.console.groupCollapsed = function() {}; 11942 - } 11943 - if (typeof console.markTimeline == 'undefined') { 11944 - module.verbose('Mark timeline not available, normalizing events'); 11945 - window.console.markTimeline = function() {}; 11946 - } 11947 - }, 11948 - consoleClear: function() { 11949 - module.debug('Disabling programmatic console clearing'); 11950 - window.console.clear = function() {}; 11951 - }, 11952 - requestAnimationFrame: function() { 11953 - module.debug('Normalizing requestAnimationFrame'); 11954 - if(window.requestAnimationFrame === undefined) { 11955 - module.debug('RequestAnimationFrame not available, normalizing event'); 11956 - window.requestAnimationFrame = window.requestAnimationFrame 11957 - || window.mozRequestAnimationFrame 11958 - || window.webkitRequestAnimationFrame 11959 - || window.msRequestAnimationFrame 11960 - || function(callback) { setTimeout(callback, 0); } 11961 - ; 11962 - } 11963 - } 11964 - }, 11965 - 11966 - moduleExists: function(name) { 11967 - return ($.fn[name] !== undefined && $.fn[name].settings !== undefined); 11968 - }, 11969 - 11970 - enabled: { 11971 - modules: function(modules) { 11972 - var 11973 - enabledModules = [] 11974 - ; 11975 - modules = modules || settings.modules; 11976 - $.each(modules, function(index, name) { 11977 - if(module.moduleExists(name)) { 11978 - enabledModules.push(name); 11979 - } 11980 - }); 11981 - return enabledModules; 11982 - } 11983 - }, 11984 - 11985 - disabled: { 11986 - modules: function(modules) { 11987 - var 11988 - disabledModules = [] 11989 - ; 11990 - modules = modules || settings.modules; 11991 - $.each(modules, function(index, name) { 11992 - if(!module.moduleExists(name)) { 11993 - disabledModules.push(name); 11994 - } 11995 - }); 11996 - return disabledModules; 11997 - } 11998 - }, 11999 - 12000 - change: { 12001 - setting: function(setting, value, modules, modifyExisting) { 12002 - modules = (typeof modules === 'string') 12003 - ? (modules === 'all') 12004 - ? settings.modules 12005 - : [modules] 12006 - : modules || settings.modules 12007 - ; 12008 - modifyExisting = (modifyExisting !== undefined) 12009 - ? modifyExisting 12010 - : true 12011 - ; 12012 - $.each(modules, function(index, name) { 12013 - var 12014 - namespace = (module.moduleExists(name)) 12015 - ? $.fn[name].settings.namespace || false 12016 - : true, 12017 - $existingModules 12018 - ; 12019 - if(module.moduleExists(name)) { 12020 - module.verbose('Changing default setting', setting, value, name); 12021 - $.fn[name].settings[setting] = value; 12022 - if(modifyExisting && namespace) { 12023 - $existingModules = $(':data(module-' + namespace + ')'); 12024 - if($existingModules.length > 0) { 12025 - module.verbose('Modifying existing settings', $existingModules); 12026 - $existingModules[name]('setting', setting, value); 12027 - } 12028 - } 12029 - } 12030 - }); 12031 - }, 12032 - settings: function(newSettings, modules, modifyExisting) { 12033 - modules = (typeof modules === 'string') 12034 - ? [modules] 12035 - : modules || settings.modules 12036 - ; 12037 - modifyExisting = (modifyExisting !== undefined) 12038 - ? modifyExisting 12039 - : true 12040 - ; 12041 - $.each(modules, function(index, name) { 12042 - var 12043 - $existingModules 12044 - ; 12045 - if(module.moduleExists(name)) { 12046 - module.verbose('Changing default setting', newSettings, name); 12047 - $.extend(true, $.fn[name].settings, newSettings); 12048 - if(modifyExisting && namespace) { 12049 - $existingModules = $(':data(module-' + namespace + ')'); 12050 - if($existingModules.length > 0) { 12051 - module.verbose('Modifying existing settings', $existingModules); 12052 - $existingModules[name]('setting', newSettings); 12053 - } 12054 - } 12055 - } 12056 - }); 12057 - } 12058 - }, 12059 - 12060 - enable: { 12061 - console: function() { 12062 - module.console(true); 12063 - }, 12064 - debug: function(modules, modifyExisting) { 12065 - modules = modules || settings.modules; 12066 - module.debug('Enabling debug for modules', modules); 12067 - module.change.setting('debug', true, modules, modifyExisting); 12068 - }, 12069 - verbose: function(modules, modifyExisting) { 12070 - modules = modules || settings.modules; 12071 - module.debug('Enabling verbose debug for modules', modules); 12072 - module.change.setting('verbose', true, modules, modifyExisting); 12073 - } 12074 - }, 12075 - disable: { 12076 - console: function() { 12077 - module.console(false); 12078 - }, 12079 - debug: function(modules, modifyExisting) { 12080 - modules = modules || settings.modules; 12081 - module.debug('Disabling debug for modules', modules); 12082 - module.change.setting('debug', false, modules, modifyExisting); 12083 - }, 12084 - verbose: function(modules, modifyExisting) { 12085 - modules = modules || settings.modules; 12086 - module.debug('Disabling verbose debug for modules', modules); 12087 - module.change.setting('verbose', false, modules, modifyExisting); 12088 - } 12089 - }, 12090 - 12091 - console: function(enable) { 12092 - if(enable) { 12093 - if(instance.cache.console === undefined) { 12094 - module.error(error.console); 12095 - return; 12096 - } 12097 - module.debug('Restoring console function'); 12098 - window.console = instance.cache.console; 12099 - } 12100 - else { 12101 - module.debug('Disabling console function'); 12102 - instance.cache.console = window.console; 12103 - window.console = { 12104 - clear : function(){}, 12105 - error : function(){}, 12106 - group : function(){}, 12107 - groupCollapsed : function(){}, 12108 - groupEnd : function(){}, 12109 - info : function(){}, 12110 - log : function(){}, 12111 - markTimeline : function(){}, 12112 - warn : function(){} 12113 - }; 12114 - } 12115 - }, 12116 - 12117 - destroy: function() { 12118 - module.verbose('Destroying previous site for', $module); 12119 - $module 12120 - .removeData(moduleNamespace) 12121 - ; 12122 - }, 12123 - 12124 - cache: {}, 12125 - 12126 - setting: function(name, value) { 12127 - if( $.isPlainObject(name) ) { 12128 - $.extend(true, settings, name); 12129 - } 12130 - else if(value !== undefined) { 12131 - settings[name] = value; 12132 - } 12133 - else { 12134 - return settings[name]; 12135 - } 12136 - }, 12137 - internal: function(name, value) { 12138 - if( $.isPlainObject(name) ) { 12139 - $.extend(true, module, name); 12140 - } 12141 - else if(value !== undefined) { 12142 - module[name] = value; 12143 - } 12144 - else { 12145 - return module[name]; 12146 - } 12147 - }, 12148 - debug: function() { 12149 - if(settings.debug) { 12150 - if(settings.performance) { 12151 - module.performance.log(arguments); 12152 - } 12153 - else { 12154 - module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); 12155 - module.debug.apply(console, arguments); 12156 - } 12157 - } 12158 - }, 12159 - verbose: function() { 12160 - if(settings.verbose && settings.debug) { 12161 - if(settings.performance) { 12162 - module.performance.log(arguments); 12163 - } 12164 - else { 12165 - module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); 12166 - module.verbose.apply(console, arguments); 12167 - } 12168 - } 12169 - }, 12170 - error: function() { 12171 - module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); 12172 - module.error.apply(console, arguments); 12173 - }, 12174 - performance: { 12175 - log: function(message) { 12176 - var 12177 - currentTime, 12178 - executionTime, 12179 - previousTime 12180 - ; 12181 - if(settings.performance) { 12182 - currentTime = new Date().getTime(); 12183 - previousTime = time || currentTime; 12184 - executionTime = currentTime - previousTime; 12185 - time = currentTime; 12186 - performance.push({ 12187 - 'Element' : element, 12188 - 'Name' : message[0], 12189 - 'Arguments' : [].slice.call(message, 1) || '', 12190 - 'Execution Time' : executionTime 12191 - }); 12192 - } 12193 - clearTimeout(module.performance.timer); 12194 - module.performance.timer = setTimeout(module.performance.display, 500); 12195 - }, 12196 - display: function() { 12197 - var 12198 - title = settings.name + ':', 12199 - totalTime = 0 12200 - ; 12201 - time = false; 12202 - clearTimeout(module.performance.timer); 12203 - $.each(performance, function(index, data) { 12204 - totalTime += data['Execution Time']; 12205 - }); 12206 - title += ' ' + totalTime + 'ms'; 12207 - if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { 12208 - console.groupCollapsed(title); 12209 - if(console.table) { 12210 - console.table(performance); 12211 - } 12212 - else { 12213 - $.each(performance, function(index, data) { 12214 - console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); 12215 - }); 12216 - } 12217 - console.groupEnd(); 12218 - } 12219 - performance = []; 12220 - } 12221 - }, 12222 - invoke: function(query, passedArguments, context) { 12223 - var 12224 - object = instance, 12225 - maxDepth, 12226 - found, 12227 - response 12228 - ; 12229 - passedArguments = passedArguments || queryArguments; 12230 - context = element || context; 12231 - if(typeof query == 'string' && object !== undefined) { 12232 - query = query.split(/[\. ]/); 12233 - maxDepth = query.length - 1; 12234 - $.each(query, function(depth, value) { 12235 - var camelCaseValue = (depth != maxDepth) 12236 - ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) 12237 - : query 12238 - ; 12239 - if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { 12240 - object = object[camelCaseValue]; 12241 - } 12242 - else if( object[camelCaseValue] !== undefined ) { 12243 - found = object[camelCaseValue]; 12244 - return false; 12245 - } 12246 - else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { 12247 - object = object[value]; 12248 - } 12249 - else if( object[value] !== undefined ) { 12250 - found = object[value]; 12251 - return false; 12252 - } 12253 - else { 12254 - module.error(error.method, query); 12255 - return false; 12256 - } 12257 - }); 12258 - } 12259 - if ( $.isFunction( found ) ) { 12260 - response = found.apply(context, passedArguments); 12261 - } 12262 - else if(found !== undefined) { 12263 - response = found; 12264 - } 12265 - if(Array.isArray(returnedValue)) { 12266 - returnedValue.push(response); 12267 - } 12268 - else if(returnedValue !== undefined) { 12269 - returnedValue = [returnedValue, response]; 12270 - } 12271 - else if(response !== undefined) { 12272 - returnedValue = response; 12273 - } 12274 - return found; 12275 - } 12276 - }; 12277 - 12278 - if(methodInvoked) { 12279 - if(instance === undefined) { 12280 - module.initialize(); 12281 - } 12282 - module.invoke(query); 12283 - } 12284 - else { 12285 - if(instance !== undefined) { 12286 - module.destroy(); 12287 - } 12288 - module.initialize(); 12289 - } 12290 - return (returnedValue !== undefined) 12291 - ? returnedValue 12292 - : this 12293 - ; 12294 - }; 12295 - 12296 - $.site.settings = { 12297 - 12298 - name : 'Site', 12299 - namespace : 'site', 12300 - 12301 - error : { 12302 - console : 'Console cannot be restored, most likely it was overwritten outside of module', 12303 - method : 'The method you called is not defined.' 12304 - }, 12305 - 12306 - debug : false, 12307 - verbose : false, 12308 - performance : true, 12309 - 12310 - modules: [ 12311 - 'accordion', 12312 - 'api', 12313 - 'calendar', 12314 - 'checkbox', 12315 - 'dimmer', 12316 - 'dropdown', 12317 - 'embed', 12318 - 'form', 12319 - 'modal', 12320 - 'nag', 12321 - 'popup', 12322 - 'slider', 12323 - 'rating', 12324 - 'shape', 12325 - 'sidebar', 12326 - 'state', 12327 - 'sticky', 12328 - 'tab', 12329 - 'toast', 12330 - 'transition', 12331 - 'visibility', 12332 - 'visit' 12333 - ], 12334 - 12335 - siteNamespace : 'site', 12336 - namespaceStub : { 12337 - cache : {}, 12338 - config : {}, 12339 - sections : {}, 12340 - section : {}, 12341 - utilities : {} 12342 - } 12343 - 12344 - }; 12345 - 12346 - // allows for selection of elements with data attributes 12347 - $.extend($.expr[ ":" ], { 12348 - data: ($.expr.createPseudo) 12349 - ? $.expr.createPseudo(function(dataName) { 12350 - return function(elem) { 12351 - return !!$.data(elem, dataName); 12352 - }; 12353 - }) 12354 - : function(elem, i, match) { 12355 - // support: jQuery < 1.8 12356 - return !!$.data(elem, match[ 3 ]); 12357 - } 12358 - }); 12359 - 12360 - 12361 - })( jQuery, window, document ); 12362 - 12363 - /*! 12364 11870 * # Fomantic-UI - Tab 12365 11871 * http://github.com/fomantic/Fomantic-UI/ 12366 11872 *
-2
web_src/fomantic/semantic.json
··· 28 28 "dimmer", 29 29 "dropdown", 30 30 "form", 31 - "grid", 32 31 "header", 33 32 "input", 34 33 "label", ··· 37 36 "modal", 38 37 "search", 39 38 "segment", 40 - "site", 41 39 "tab", 42 40 "table" 43 41 ]
+1 -1
web_src/js/bootstrap.js
··· 23 23 let msgDiv = pageContent.querySelector(`.js-global-error[data-global-error-msg-compact="${msgCompact}"]`); 24 24 if (!msgDiv) { 25 25 const el = document.createElement('div'); 26 - el.innerHTML = `<div class="ui container negative message center aligned js-global-error" style="white-space: pre-line;"></div>`; 26 + el.innerHTML = `<div class="ui container negative message center aligned js-global-error tw-mt-[15px] tw-whitespace-pre-line"></div>`; 27 27 msgDiv = el.childNodes[0]; 28 28 } 29 29 // merge duplicated messages into "the message (count)" format
+6 -6
web_src/js/components/ActionRunStatus.vue
··· 10 10 props: { 11 11 status: { 12 12 type: String, 13 - required: true 13 + required: true, 14 14 }, 15 15 size: { 16 16 type: Number, 17 - default: 16 17 + default: 16, 18 18 }, 19 19 className: { 20 20 type: String, 21 - default: '' 21 + default: '', 22 22 }, 23 23 localeStatus: { 24 24 type: String, 25 - default: '' 26 - } 25 + default: '', 26 + }, 27 27 }, 28 28 }; 29 29 </script> 30 30 <template> 31 - <span class="gt-df gt-ac" :data-tooltip-content="localeStatus" v-if="status"> 31 + <span class="tw-flex tw-items-center" :data-tooltip-content="localeStatus" v-if="status"> 32 32 <SvgIcon name="octicon-check-circle-fill" class="text green" :size="size" :class-name="className" v-if="status === 'success'"/> 33 33 <SvgIcon name="octicon-skip" class="text grey" :size="size" :class-name="className" v-else-if="status === 'skipped'"/> 34 34 <SvgIcon name="octicon-clock" class="text yellow" :size="size" :class-name="className" v-else-if="status === 'waiting'"/>
+2 -2
web_src/js/components/ActivityHeatmap.vue
··· 11 11 locale: { 12 12 type: Object, 13 13 default: () => {}, 14 - } 14 + }, 15 15 }, 16 16 data: () => ({ 17 17 colorRange: [ ··· 49 49 50 50 const newSearch = params.toString(); 51 51 window.location.search = newSearch.length ? `?${newSearch}` : ''; 52 - } 52 + }, 53 53 }, 54 54 }; 55 55 </script>
+3 -3
web_src/js/components/ContextPopup.vue
··· 69 69 } 70 70 return {name: label.name, color: `#${label.color}`, textColor}; 71 71 }); 72 - } 72 + }, 73 73 }, 74 74 mounted() { 75 75 this.$refs.root.addEventListener('ce-load-context-popup', (e) => { ··· 97 97 } finally { 98 98 this.loading = false; 99 99 } 100 - } 101 - } 100 + }, 101 + }, 102 102 }; 103 103 </script> 104 104 <template>
+14 -13
web_src/js/components/DashboardRepoList.vue
··· 235 235 if (!this.reposTotalCount) { 236 236 const totalCountSearchURL = `${this.subUrl}/repo/search?count_only=1&uid=${this.uid}&team_id=${this.teamId}&q=&page=1&mode=`; 237 237 response = await GET(totalCountSearchURL); 238 - this.reposTotalCount = response.headers.get('X-Total-Count'); 238 + this.reposTotalCount = response.headers.get('X-Total-Count') ?? '?'; 239 239 } 240 240 241 241 response = await GET(searchedURL); ··· 252 252 return { 253 253 ...webSearchRepo.repository, 254 254 latest_commit_status: webSearchRepo.latest_commit_status, 255 - locale_latest_commit_status_state: webSearchRepo.locale_latest_commit_status 255 + locale_latest_commit_status: webSearchRepo.locale_latest_commit_status, 256 256 }; 257 257 }); 258 258 const count = response.headers.get('X-Total-Count'); ··· 324 324 if (this.activeIndex === -1 || this.activeIndex > this.repos.length - 1) { 325 325 this.activeIndex = 0; 326 326 } 327 - } 327 + }, 328 328 }, 329 329 }; 330 330 ··· 344 344 <a :class="{item: true, active: tab === 'organizations'}" @click="changeTab('organizations')">{{ textMyOrgs }} <span class="ui grey label gt-ml-3">{{ organizationsTotalCount }}</span></a> 345 345 </div> 346 346 <div v-show="tab === 'repos'" class="ui tab active list dashboard-repos"> 347 - <h4 v-if="isOrganization" class="ui top attached gt-mt-4 gt-df gt-ac"> 348 - <div class="gt-f1 gt-df gt-ac"> 347 + <h4 v-if="isOrganization" class="ui top attached gt-mt-4 tw-flex tw-items-center"> 348 + <div class="tw-flex-1 tw-flex tw-items-center"> 349 349 {{ textMyRepos }} 350 350 <span class="ui grey label gt-ml-3">{{ reposTotalCount }}</span> 351 351 </div> ··· 405 405 </div> 406 406 </overflow-menu> 407 407 </div> 408 - <div v-if="repos.length" class="ui attached table segment gt-rounded-bottom"> 408 + <div v-if="repos.length" class="ui attached table segment tw-rounded-b"> 409 409 <ul class="repo-owner-name-list"> 410 - <li class="gt-df gt-ac gt-py-3" v-for="repo, index in repos" :class="{'active': index === activeIndex}" :key="repo.id"> 410 + <li class="tw-flex tw-items-center gt-py-3" v-for="repo, index in repos" :class="{'active': index === activeIndex}" :key="repo.id"> 411 411 <a class="repo-list-link muted" :href="repo.link"> 412 412 <svg-icon :name="repoIcon(repo)" :size="16" class-name="repo-list-icon"/> 413 413 <div class="text truncate">{{ repo.full_name }}</div> ··· 415 415 <svg-icon name="octicon-archive" :size="16"/> 416 416 </div> 417 417 </a> 418 - <a class="gt-df gt-ac" v-if="repo.latest_commit_status" :href="repo.latest_commit_status.TargetLink" :data-tooltip-content="repo.locale_latest_commit_status.State"> 418 + <a class="tw-flex tw-items-center" v-if="repo.latest_commit_status" :href="repo.latest_commit_status.TargetLink" :data-tooltip-content="repo.locale_latest_commit_status.State"> 419 419 <!-- the commit status icon logic is taken from templates/repo/commit_status.tmpl --> 420 420 <svg-icon :name="statusIcon(repo.latest_commit_status.State)" :class-name="'gt-ml-3 commit-status icon text ' + statusColor(repo.latest_commit_status.State)" :size="16"/> 421 421 </a> 422 422 </li> 423 423 </ul> 424 - <div v-if="showMoreReposLink" class="center gt-py-3 gt-border-secondary-top"> 425 - <div class="ui borderless pagination menu narrow"> 424 + <div v-if="showMoreReposLink" class="tw-text-center"> 425 + <div class="divider gt-my-0"/> 426 + <div class="ui borderless pagination menu narrow gt-my-3"> 426 427 <a 427 428 class="item navigation gt-py-2" :class="{'disabled': page === 1}" 428 429 @click="changePage(1)" :title="textFirstPage" ··· 453 454 </div> 454 455 </div> 455 456 <div v-if="!isOrganization" v-show="tab === 'organizations'" class="ui tab active list dashboard-orgs"> 456 - <div v-if="organizations.length" class="ui attached table segment gt-rounded"> 457 + <div v-if="organizations.length" class="ui attached table segment tw-rounded-b"> 457 458 <ul class="repo-owner-name-list"> 458 - <li class="gt-df gt-ac gt-py-3" v-for="org in organizations" :key="org.name"> 459 + <li class="tw-flex tw-items-center gt-py-3" v-for="org in organizations" :key="org.name"> 459 460 <a class="repo-list-link muted" :href="subUrl + '/' + encodeURIComponent(org.name)"> 460 461 <svg-icon name="octicon-organization" :size="16" class-name="repo-list-icon"/> 461 462 <div class="text truncate">{{ org.name }}</div> ··· 465 466 </span> 466 467 </div> 467 468 </a> 468 - <div class="text light grey gt-df gt-ac gt-ml-3"> 469 + <div class="text light grey tw-flex tw-items-center gt-ml-3"> 469 470 {{ org.num_repos }} 470 471 <svg-icon name="octicon-repo" :size="16" class-name="gt-ml-2 gt-mt-1"/> 471 472 </div>
+13 -9
web_src/js/components/DiffCommitSelector.vue
··· 14 14 }, 15 15 commits: [], 16 16 hoverActivated: false, 17 - lastReviewCommitSha: null 17 + lastReviewCommitSha: null, 18 18 }; 19 19 }, 20 20 computed: { ··· 29 29 }, 30 30 issueLink() { 31 31 return this.$el.parentNode.getAttribute('data-issuelink'); 32 - } 32 + }, 33 33 }, 34 34 mounted() { 35 35 document.body.addEventListener('click', this.onBodyClick); ··· 185 185 } 186 186 } 187 187 }, 188 - } 188 + }, 189 189 }; 190 190 </script> 191 191 <template> ··· 204 204 </button> 205 205 <div class="menu left transition" id="diff-commit-selector-menu" :class="{visible: menuVisible}" v-show="menuVisible" v-cloak :aria-expanded="menuVisible ? 'true': 'false'"> 206 206 <div class="loading-indicator is-loading" v-if="isLoading"/> 207 - <div v-if="!isLoading" class="vertical item gt-df gt-fc gt-gap-2" id="diff-commit-list-show-all" role="menuitem" @keydown.enter="showAllChanges()" @click="showAllChanges()"> 207 + <div v-if="!isLoading" class="vertical item" id="diff-commit-list-show-all" role="menuitem" @keydown.enter="showAllChanges()" @click="showAllChanges()"> 208 208 <div class="gt-ellipsis"> 209 209 {{ locale.show_all_commits }} 210 210 </div> ··· 215 215 <!-- only show the show changes since last review if there is a review AND we are commits ahead of the last review --> 216 216 <div 217 217 v-if="lastReviewCommitSha != null" role="menuitem" 218 - class="vertical item gt-df gt-fc gt-gap-2 gt-border-secondary-top" 218 + class="vertical item" 219 219 :class="{disabled: commitsSinceLastReview === 0}" 220 220 @keydown.enter="changesSinceLastReviewClick()" 221 221 @click="changesSinceLastReviewClick()" ··· 227 227 {{ commitsSinceLastReview }} commits 228 228 </div> 229 229 </div> 230 - <span v-if="!isLoading" class="info gt-border-secondary-top text light-2">{{ locale.select_commit_hold_shift_for_range }}</span> 230 + <span v-if="!isLoading" class="info text light-2">{{ locale.select_commit_hold_shift_for_range }}</span> 231 231 <template v-for="commit in commits" :key="commit.id"> 232 232 <div 233 - class="vertical item gt-df gt-gap-2 gt-border-secondary-top" role="menuitem" 233 + class="vertical item" role="menuitem" 234 234 :class="{selection: commit.selected, hovered: commit.hovered}" 235 235 @keydown.enter.exact="commitClicked(commit.id)" 236 236 @keydown.enter.shift.exact="commitClickedShift(commit)" ··· 240 240 @click.meta.exact="commitClicked(commit.id, true)" 241 241 @click.shift.exact.stop.prevent="commitClickedShift(commit)" 242 242 > 243 - <div class="gt-f1 gt-df gt-fc gt-gap-2"> 243 + <div class="tw-flex-1 tw-flex tw-flex-col tw-gap-1"> 244 244 <div class="gt-ellipsis commit-list-summary"> 245 245 {{ commit.summary }} 246 246 </div> ··· 285 285 width: 350px; 286 286 } 287 287 288 - #diff-commit-selector-menu .item { 288 + #diff-commit-selector-menu .item, 289 + #diff-commit-selector-menu .info { 290 + display: flex !important; 289 291 flex-direction: row; 290 292 line-height: 1.4; 291 293 padding: 7px 14px !important; 294 + border-top: 1px solid var(--color-secondary) !important; 295 + gap: 0.25em; 292 296 } 293 297 294 298 #diff-commit-selector-menu .item:focus {
+3 -3
web_src/js/components/DiffFileList.vue
··· 31 31 }, 32 32 loadMoreData() { 33 33 loadMoreFiles(this.store.linkLoadMore); 34 - } 34 + }, 35 35 }, 36 36 }; 37 37 </script> 38 38 <template> 39 39 <ol class="diff-stats gt-m-0" ref="root" v-if="store.fileListIsVisible"> 40 40 <li v-for="file in store.files" :key="file.NameHash"> 41 - <div class="gt-font-semibold gt-df gt-ac pull-right"> 41 + <div class="tw-font-semibold tw-flex tw-items-center pull-right"> 42 42 <span v-if="file.IsBin" class="gt-ml-1 gt-mr-3">{{ store.binaryFileMessage }}</span> 43 43 {{ file.IsBin ? '' : file.Addition + file.Deletion }} 44 44 <span v-if="!file.IsBin" class="diff-stats-bar gt-mx-3" :data-tooltip-content="store.statisticsMessage.replace('%d', (file.Addition + file.Deletion)).replace('%d', file.Addition).replace('%d', file.Deletion)"> ··· 50 50 <a class="file gt-mono" :href="'#diff-' + file.NameHash">{{ file.Name }}</a> 51 51 </li> 52 52 <li v-if="store.isIncomplete" class="gt-pt-2"> 53 - <span class="file gt-df gt-ac gt-sb">{{ store.tooManyFilesMessage }} 53 + <span class="file tw-flex tw-items-center tw-justify-between">{{ store.tooManyFilesMessage }} 54 54 <a :class="['ui', 'basic', 'tiny', 'button', store.isLoadingNewData ? 'disabled' : '']" @click.stop="loadMoreData">{{ store.showMoreMessage }}</a> 55 55 </span> 56 56 </li>
+3 -3
web_src/js/components/DiffFileTree.vue
··· 30 30 let newParent = { 31 31 name: split, 32 32 children: [], 33 - isFile 33 + isFile, 34 34 }; 35 35 36 36 if (isFile === true) { ··· 40 40 if (parent) { 41 41 // check if the folder already exists 42 42 const existingFolder = parent.children.find( 43 - (x) => x.name === split 43 + (x) => x.name === split, 44 44 ); 45 45 if (existingFolder) { 46 46 newParent = existingFolder; ··· 74 74 // reduce the depth of our tree. 75 75 mergeChildIfOnlyOneDir(result); 76 76 return result; 77 - } 77 + }, 78 78 }, 79 79 mounted() { 80 80 // Default to true if unset
+2 -2
web_src/js/components/DiffFileTreeItem.vue
··· 7 7 props: { 8 8 item: { 9 9 type: Object, 10 - required: true 10 + required: true, 11 11 }, 12 12 }, 13 13 data: () => ({ ··· 37 37 > 38 38 <!-- file --> 39 39 <SvgIcon name="octicon-file"/> 40 - <span class="gt-ellipsis gt-f1">{{ item.name }}</span> 40 + <span class="gt-ellipsis tw-flex-1">{{ item.name }}</span> 41 41 <SvgIcon :name="getIconForDiffType(item.file.Type).name" :class="getIconForDiffType(item.file.Type).classes"/> 42 42 </a> 43 43 <div v-else class="item-directory" :title="item.name" @click.stop="collapsed = !collapsed">
+3 -2
web_src/js/components/PullRequestMergeForm.vue
··· 43 43 for (const elem of document.querySelectorAll('[data-pull-merge-style]')) { 44 44 toggleElem(elem, elem.getAttribute('data-pull-merge-style') === val); 45 45 } 46 - } 46 + }, 47 47 }, 48 48 created() { 49 49 this.mergeStyleAllowedCount = this.mergeForm.mergeStyles.reduce((v, msd) => v + (msd.allowed ? 1 : 0), 0); ··· 94 94 <!-- eslint-disable-next-line vue/no-v-html --> 95 95 <div v-if="mergeForm.hasPendingPullRequestMerge" v-html="mergeForm.hasPendingPullRequestMergeTip" class="ui info message"/> 96 96 97 + <!-- another similar form is in pull.tmpl (manual merge)--> 97 98 <form class="ui form form-fetch-action" v-if="showActionForm" :action="mergeForm.baseLink+'/merge'" method="post"> 98 99 <input type="hidden" name="_csrf" :value="csrfToken"> 99 100 <input type="hidden" name="head_commit_id" v-model="mergeForm.pullHeadCommitID"> ··· 135 136 </div> 136 137 </form> 137 138 138 - <div v-if="!showActionForm" class="gt-df"> 139 + <div v-if="!showActionForm" class="tw-flex"> 139 140 <!-- the merge button --> 140 141 <div class="ui buttons merge-button" :class="[mergeForm.emptyCommit ? 'grey' : mergeForm.allOverridableChecksOk ? 'primary' : 'red']" @click="toggleActionForm(true)"> 141 142 <button class="ui button">
+18 -12
web_src/js/components/RepoActionView.vue
··· 69 69 name: '', 70 70 link: '', 71 71 }, 72 - } 72 + }, 73 73 }, 74 74 currentJob: { 75 75 title: '', ··· 271 271 return ['success', 'skipped', 'failure', 'cancelled'].includes(status); 272 272 }, 273 273 274 + isExpandable(status) { 275 + return ['success', 'running', 'failure', 'cancelled'].includes(status); 276 + }, 277 + 274 278 closeDropdown() { 275 279 if (this.menuVisible) this.menuVisible = false; 276 280 }, ··· 314 318 const logLine = this.$refs.steps.querySelector(selectedLogStep); 315 319 if (!logLine) return; 316 320 logLine.querySelector('.line-num').click(); 317 - } 321 + }, 318 322 }, 319 323 }; 320 324 ··· 357 361 skipped: el.getAttribute('data-locale-status-skipped'), 358 362 blocked: el.getAttribute('data-locale-status-blocked'), 359 363 }, 360 - } 364 + }, 361 365 }); 362 366 view.mount(el); 363 367 } ··· 468 472 </div> 469 473 <div class="job-step-container" ref="steps" v-if="currentJob.steps.length"> 470 474 <div class="job-step-section" v-for="(jobStep, i) in currentJob.steps" :key="i"> 471 - <div class="job-step-summary" @click.stop="toggleStepLogs(i)" :class="currentJobStepsStates[i].expanded ? 'selected' : ''"> 475 + <div class="job-step-summary" @click.stop="jobStep.status !== 'skipped' && toggleStepLogs(i)" :class="[currentJobStepsStates[i].expanded ? 'selected' : '', isExpandable(jobStep.status) && 'step-expandable']"> 472 476 <!-- If the job is done and the job step log is loaded for the first time, show the loading icon 473 477 currentJobStepsStates[i].cursor === null means the log is loaded for the first time 474 478 --> 475 479 <SvgIcon v-if="isDone(run.status) && currentJobStepsStates[i].expanded && currentJobStepsStates[i].cursor === null" name="octicon-sync" class="gt-mr-3 job-status-rotate"/> 476 - <SvgIcon v-else :name="currentJobStepsStates[i].expanded ? 'octicon-chevron-down': 'octicon-chevron-right'" class="gt-mr-3"/> 480 + <SvgIcon v-else :name="currentJobStepsStates[i].expanded ? 'octicon-chevron-down': 'octicon-chevron-right'" :class="['gt-mr-3', !isExpandable(jobStep.status) && 'tw-invisible']"/> 477 481 <ActionRunStatus :status="jobStep.status" class="gt-mr-3"/> 478 482 479 483 <span class="step-summary-msg gt-ellipsis">{{ jobStep.summary }}</span> ··· 724 728 } 725 729 726 730 .job-step-container .job-step-summary { 727 - cursor: pointer; 728 731 padding: 5px 10px; 729 732 display: flex; 730 733 align-items: center; 731 734 border-radius: var(--border-radius); 732 735 } 733 736 737 + .job-step-container .job-step-summary.step-expandable { 738 + cursor: pointer; 739 + } 740 + 741 + .job-step-container .job-step-summary.step-expandable:hover { 742 + color: var(--color-console-fg); 743 + background-color: var(--color-console-hover-bg); 744 + } 745 + 734 746 .job-step-container .job-step-summary .step-summary-msg { 735 747 flex: 1; 736 748 } 737 749 738 750 .job-step-container .job-step-summary .step-summary-duration { 739 751 margin-left: 16px; 740 - } 741 - 742 - .job-step-container .job-step-summary:hover { 743 - color: var(--color-console-fg); 744 - background-color: var(--color-console-hover-bg); 745 - 746 752 } 747 753 748 754 .job-step-container .job-step-summary.selected {
+1 -1
web_src/js/components/RepoActivityTopAuthors.vue
··· 47 47 this.colors.barColor = refStyle.backgroundColor; 48 48 this.colors.textColor = refStyle.color; 49 49 this.colors.textAltColor = refAltStyle.color; 50 - } 50 + }, 51 51 }; 52 52 53 53 export function initRepoActivityTopAuthorsChart() {
+6 -6
web_src/js/components/RepoBranchTagSelector.vue
··· 36 36 }, 37 37 shouldCreateTag() { 38 38 return this.mode === 'tags'; 39 - } 39 + }, 40 40 }, 41 41 42 42 watch: { ··· 45 45 this.focusSearchField(); 46 46 this.fetchBranchesOrTags(); 47 47 } 48 - } 48 + }, 49 49 }, 50 50 51 51 beforeMount() { ··· 83 83 this.isViewBranch = false; 84 84 this.$refs.dropdownRefName.textContent = item.name; 85 85 if (this.setAction) { 86 - $(`#${this.branchForm}`).attr('action', url); 86 + document.getElementById(this.branchForm)?.setAttribute('action', url); 87 87 } else { 88 88 $(`#${this.branchForm} input[name="refURL"]`).val(url); 89 89 } ··· 209 209 this.isLoading = false; 210 210 } 211 211 }, 212 - } 212 + }, 213 213 }; 214 214 215 215 export function initRepoBranchTagSelector(selector) { ··· 245 245 </script> 246 246 <template> 247 247 <div class="ui dropdown custom"> 248 - <button class="branch-dropdown-button gt-ellipsis ui basic small compact button gt-df gt-m-0" @click="menuVisible = !menuVisible" @keyup.enter="menuVisible = !menuVisible"> 249 - <span class="text gt-df gt-ac gt-mr-2"> 248 + <button class="branch-dropdown-button gt-ellipsis ui basic small compact button tw-flex gt-m-0" @click="menuVisible = !menuVisible" @keyup.enter="menuVisible = !menuVisible"> 249 + <span class="text tw-flex tw-items-center gt-mr-2"> 250 250 <template v-if="release">{{ textReleaseCompare }}</template> 251 251 <template v-else> 252 252 <svg-icon v-if="isViewTag" name="octicon-tag"/>
+6 -6
web_src/js/components/RepoCodeFrequency.vue
··· 39 39 props: { 40 40 locale: { 41 41 type: Object, 42 - required: true 42 + required: true, 43 43 }, 44 44 }, 45 45 data: () => ({ ··· 128 128 }, 129 129 ticks: { 130 130 maxRotation: 0, 131 - maxTicksLimit: 12 131 + maxTicksLimit: 12, 132 132 }, 133 133 }, 134 134 y: { 135 135 ticks: { 136 - maxTicksLimit: 6 136 + maxTicksLimit: 6, 137 137 }, 138 138 }, 139 139 }, ··· 144 144 </script> 145 145 <template> 146 146 <div> 147 - <div class="ui header gt-df gt-ac gt-sb"> 147 + <div class="ui header tw-flex tw-items-center tw-justify-between"> 148 148 {{ isLoading ? locale.loadingTitle : errorText ? locale.loadingTitleFailed: `Code frequency over the history of ${repoLink.slice(1)}` }} 149 149 </div> 150 - <div class="gt-df ui segment main-graph"> 151 - <div v-if="isLoading || errorText !== ''" class="gt-tc gt-m-auto"> 150 + <div class="tw-flex ui segment main-graph"> 151 + <div v-if="isLoading || errorText !== ''" class="gt-tc tw-m-auto"> 152 152 <div v-if="isLoading"> 153 153 <SvgIcon name="octicon-sync" class="gt-mr-3 job-status-rotate"/> 154 154 {{ locale.loadingInfo }}
+10 -10
web_src/js/components/RepoContributors.vue
··· 34 34 chart.resetZoom(); 35 35 opts.instance.updateOtherCharts(args.event, true); 36 36 } 37 - } 37 + }, 38 38 }; 39 39 40 40 Chart.defaults.color = chartJsColors.text; ··· 82 82 this.xAxisMax = this.xAxisEnd; 83 83 this.type = val; 84 84 this.sortContributors(); 85 - } 85 + }, 86 86 }); 87 87 }, 88 88 methods: { ··· 175 175 // Normally, chartjs handles this automatically, but it will resize the graph when you 176 176 // zoom, pan etc. I think resizing the graph makes it harder to compare things visually. 177 177 const maxValue = Math.max( 178 - ...this.totalStats.weeks.map((o) => o[this.type]) 178 + ...this.totalStats.weeks.map((o) => o[this.type]), 179 179 ); 180 180 const [coefficient, exp] = maxValue.toExponential().split('e').map(Number); 181 181 if (coefficient % 1 === 0) return maxValue; ··· 187 187 // for contributors' graph. If I let chartjs do this for me, it will choose different 188 188 // maxY value for each contributors' graph which again makes it harder to compare. 189 189 const maxValue = Math.max( 190 - ...this.sortedContributors.map((c) => c.max_contribution_type) 190 + ...this.sortedContributors.map((c) => c.max_contribution_type), 191 191 ); 192 192 const [coefficient, exp] = maxValue.toExponential().split('e').map(Number); 193 193 if (coefficient % 1 === 0) return maxValue; ··· 303 303 </script> 304 304 <template> 305 305 <div> 306 - <div class="ui header gt-df gt-ac gt-sb"> 306 + <div class="ui header tw-flex tw-items-center tw-justify-between"> 307 307 <div> 308 308 <relative-time 309 309 v-if="xAxisMin > 0" ··· 352 352 </div> 353 353 </div> 354 354 </div> 355 - <div class="gt-df ui segment main-graph"> 356 - <div v-if="isLoading || errorText !== ''" class="gt-tc gt-m-auto"> 355 + <div class="tw-flex ui segment main-graph"> 356 + <div v-if="isLoading || errorText !== ''" class="gt-tc tw-m-auto"> 357 357 <div v-if="isLoading"> 358 358 <SvgIcon name="octicon-sync" class="gt-mr-3 job-status-rotate"/> 359 359 {{ locale.loadingInfo }} ··· 374 374 :key="index" 375 375 v-memo="[sortedContributors, type]" 376 376 > 377 - <div class="ui top attached header gt-df gt-f1"> 377 + <div class="ui top attached header tw-flex tw-flex-1"> 378 378 <b class="ui right">#{{ index + 1 }}</b> 379 379 <a :href="contributor.home_link"> 380 - <img class="ui avatar gt-vm" height="40" width="40" :src="contributor.avatar_link"> 380 + <img class="ui avatar tw-align-middle" height="40" width="40" :src="contributor.avatar_link"> 381 381 </a> 382 382 <div class="gt-ml-3"> 383 383 <a v-if="contributor.home_link !== ''" :href="contributor.home_link"><h4>{{ contributor.name }}</h4></a> 384 384 <h4 v-else class="contributor-name"> 385 385 {{ contributor.name }} 386 386 </h4> 387 - <p class="gt-font-12 gt-df gt-gap-2"> 387 + <p class="tw-text-12 tw-flex tw-gap-1"> 388 388 <strong v-if="contributor.total_commits">{{ contributor.total_commits.toLocaleString() }} {{ locale.contributionType.commits }}</strong> 389 389 <strong v-if="contributor.total_additions" class="text green">{{ contributor.total_additions.toLocaleString() }}++ </strong> 390 390 <strong v-if="contributor.total_deletions" class="text red">
+6 -6
web_src/js/components/RepoRecentCommits.vue
··· 35 35 props: { 36 36 locale: { 37 37 type: Object, 38 - required: true 38 + required: true, 39 39 }, 40 40 }, 41 41 data: () => ({ ··· 105 105 }, 106 106 ticks: { 107 107 maxRotation: 0, 108 - maxTicksLimit: 52 108 + maxTicksLimit: 52, 109 109 }, 110 110 }, 111 111 y: { 112 112 ticks: { 113 - maxTicksLimit: 6 113 + maxTicksLimit: 6, 114 114 }, 115 115 }, 116 116 }, ··· 121 121 </script> 122 122 <template> 123 123 <div> 124 - <div class="ui header gt-df gt-ac gt-sb"> 124 + <div class="ui header tw-flex tw-items-center tw-justify-between"> 125 125 {{ isLoading ? locale.loadingTitle : errorText ? locale.loadingTitleFailed: "Number of commits in the past year" }} 126 126 </div> 127 - <div class="gt-df ui segment main-graph"> 128 - <div v-if="isLoading || errorText !== ''" class="gt-tc gt-m-auto"> 127 + <div class="tw-flex ui segment main-graph"> 128 + <div v-if="isLoading || errorText !== ''" class="gt-tc tw-m-auto"> 129 129 <div v-if="isLoading"> 130 130 <SvgIcon name="octicon-sync" class="gt-mr-3 job-status-rotate"/> 131 131 {{ locale.loadingInfo }}
+2 -2
web_src/js/components/ScopedAccessTokenSelector.vue
··· 39 39 'repository', 40 40 'user'); 41 41 return categories; 42 - } 42 + }, 43 43 }, 44 44 45 45 mounted() { ··· 68 68 } 69 69 // no scopes selected, show validation error 70 70 showElem(warningEl); 71 - } 71 + }, 72 72 }, 73 73 }; 74 74
+1 -1
web_src/js/features/admin/common.js
··· 208 208 $('#delete-selection').on('click', async function (e) { 209 209 e.preventDefault(); 210 210 const $this = $(this); 211 - $this.addClass('loading disabled'); 211 + $this.addClass('is-loading disabled'); 212 212 const data = new FormData(); 213 213 $checkboxes.each(function () { 214 214 if ($(this).checkbox('is checked')) {
+2 -2
web_src/js/features/captcha.js
··· 9 9 10 10 const params = { 11 11 sitekey: siteKey, 12 - theme: isDark ? 'dark' : 'light' 12 + theme: isDark ? 'dark' : 'light', 13 13 }; 14 14 15 15 switch (captchaEl.getAttribute('data-captcha-type')) { ··· 42 42 siteKey: { 43 43 instanceUrl: new URL(instanceURL), 44 44 key: siteKey, 45 - } 45 + }, 46 46 }); 47 47 break; 48 48 }
+21 -19
web_src/js/features/citation.js
··· 1 1 import $ from 'jquery'; 2 + import {getCurrentLocale} from '../utils.js'; 2 3 3 4 const {pageData} = window.config; 4 5 5 - async function initInputCitationValue($citationCopyApa, $citationCopyBibtex) { 6 + async function initInputCitationValue(citationCopyApa, citationCopyBibtex) { 6 7 const [{Cite, plugins}] = await Promise.all([ 7 8 import(/* webpackChunkName: "citation-js-core" */'@citation-js/core'), 8 9 import(/* webpackChunkName: "citation-js-formats" */'@citation-js/plugin-software-formats'), ··· 14 15 config.constants.fieldTypes.doi = ['field', 'literal']; 15 16 config.constants.fieldTypes.version = ['field', 'literal']; 16 17 const citationFormatter = new Cite(citationFileContent); 17 - const lang = document.documentElement.lang || 'en-US'; 18 + const lang = getCurrentLocale() || 'en-US'; 18 19 const apaOutput = citationFormatter.format('bibliography', {template: 'apa', lang}); 19 20 const bibtexOutput = citationFormatter.format('bibtex', {lang}); 20 - $citationCopyBibtex.attr('data-text', bibtexOutput); 21 - $citationCopyApa.attr('data-text', apaOutput); 21 + citationCopyBibtex.setAttribute('data-text', bibtexOutput); 22 + citationCopyApa.setAttribute('data-text', apaOutput); 22 23 } 23 24 24 25 export async function initCitationFileCopyContent() { ··· 26 27 27 28 if (!pageData.citationFileContent) return; 28 29 29 - const $citationCopyApa = $('#citation-copy-apa'); 30 - const $citationCopyBibtex = $('#citation-copy-bibtex'); 31 - const $inputContent = $('#citation-copy-content'); 30 + const citationCopyApa = document.getElementById('citation-copy-apa'); 31 + const citationCopyBibtex = document.getElementById('citation-copy-bibtex'); 32 + const inputContent = document.getElementById('citation-copy-content'); 32 33 33 - if ((!$citationCopyApa.length && !$citationCopyBibtex.length) || !$inputContent.length) return; 34 + if ((!citationCopyApa && !citationCopyBibtex) || !inputContent) return; 35 + 34 36 const updateUi = () => { 35 37 const isBibtex = (localStorage.getItem('citation-copy-format') || defaultCitationFormat) === 'bibtex'; 36 - const copyContent = (isBibtex ? $citationCopyBibtex : $citationCopyApa).attr('data-text'); 37 - 38 - $inputContent.val(copyContent); 39 - $citationCopyBibtex.toggleClass('primary', isBibtex); 40 - $citationCopyApa.toggleClass('primary', !isBibtex); 38 + const copyContent = (isBibtex ? citationCopyBibtex : citationCopyApa).getAttribute('data-text'); 39 + inputContent.value = copyContent; 40 + citationCopyBibtex.classList.toggle('primary', isBibtex); 41 + citationCopyApa.classList.toggle('primary', !isBibtex); 41 42 }; 42 43 43 - $('#cite-repo-button').on('click', async (e) => { 44 + document.getElementById('cite-repo-button')?.addEventListener('click', async (e) => { 44 45 const dropdownBtn = e.target.closest('.ui.dropdown.button'); 45 46 dropdownBtn.classList.add('is-loading'); 46 47 47 48 try { 48 49 try { 49 - await initInputCitationValue($citationCopyApa, $citationCopyBibtex); 50 + await initInputCitationValue(citationCopyApa, citationCopyBibtex); 50 51 } catch (e) { 51 52 console.error(`initCitationFileCopyContent error: ${e}`, e); 52 53 return; 53 54 } 54 55 updateUi(); 55 56 56 - $citationCopyApa.on('click', () => { 57 + citationCopyApa.addEventListener('click', () => { 57 58 localStorage.setItem('citation-copy-format', 'apa'); 58 59 updateUi(); 59 60 }); 60 - $citationCopyBibtex.on('click', () => { 61 + 62 + citationCopyBibtex.addEventListener('click', () => { 61 63 localStorage.setItem('citation-copy-format', 'bibtex'); 62 64 updateUi(); 63 65 }); 64 66 65 - $inputContent.on('click', () => { 66 - $inputContent.trigger('select'); 67 + inputContent.addEventListener('click', () => { 68 + inputContent.select(); 67 69 }); 68 70 } finally { 69 71 dropdownBtn.classList.remove('is-loading');
+1 -1
web_src/js/features/code-frequency.js
··· 11 11 loadingTitle: el.getAttribute('data-locale-loading-title'), 12 12 loadingTitleFailed: el.getAttribute('data-locale-loading-title-failed'), 13 13 loadingInfo: el.getAttribute('data-locale-loading-info'), 14 - } 14 + }, 15 15 }); 16 16 View.mount(el); 17 17 } catch (err) {
+2 -2
web_src/js/features/codeeditor.js
··· 80 80 rules: [ 81 81 { 82 82 background: getColor('--color-code-bg'), 83 - } 83 + }, 84 84 ], 85 85 colors: { 86 86 'editor.background': getColor('--color-code-bg'), ··· 98 98 'input.foreground': getColor('--color-input-text'), 99 99 'scrollbar.shadow': getColor('--color-shadow'), 100 100 'progressBar.background': getColor('--color-primary'), 101 - } 101 + }, 102 102 }); 103 103 104 104 // Quick fix: https://github.com/microsoft/monaco-editor/issues/2962
+5 -3
web_src/js/features/colorpicker.js
··· 1 - export async function createColorPicker($els) { 2 - if (!$els || !$els.length) return; 1 + import $ from 'jquery'; 2 + 3 + export async function createColorPicker(els) { 4 + if (!els.length) return; 3 5 4 6 await Promise.all([ 5 7 import(/* webpackChunkName: "minicolors" */'@claviska/jquery-minicolors'), 6 8 import(/* webpackChunkName: "minicolors" */'@claviska/jquery-minicolors/jquery.minicolors.css'), 7 9 ]); 8 10 9 - $els.minicolors(); 11 + return $(els).minicolors(); 10 12 }
+7 -8
web_src/js/features/common-global.js
··· 301 301 const $this = $(this); 302 302 const dataArray = $this.data(); 303 303 let filter = ''; 304 - if ($this.attr('data-modal-id')) { 305 - filter += `#${$this.attr('data-modal-id')}`; 304 + if (this.getAttribute('data-modal-id')) { 305 + filter += `#${this.getAttribute('data-modal-id')}`; 306 306 } 307 307 308 308 const $dialog = $(`.delete.modal${filter}`); ··· 335 335 const data = await response.json(); 336 336 window.location.href = data.redirect; 337 337 } 338 - } 338 + }, 339 339 }).modal('show'); 340 340 } 341 341 ··· 352 352 // If there is a ".{attr}" part like "data-modal-form.action", then the form's "action" attribute will be set. 353 353 $('.show-modal').on('click', function (e) { 354 354 e.preventDefault(); 355 - const $el = $(this); 356 - const modalSelector = $el.attr('data-modal'); 355 + const modalSelector = this.getAttribute('data-modal'); 357 356 const $modal = $(modalSelector); 358 357 if (!$modal.length) { 359 358 throw new Error('no modal for this action'); ··· 406 405 // a '.show-panel' element can show a panel, by `data-panel="selector"` 407 406 // if it has "toggle" class, it toggles the panel 408 407 e.preventDefault(); 409 - const sel = $(this).attr('data-panel'); 408 + const sel = this.getAttribute('data-panel'); 410 409 if (this.classList.contains('toggle')) { 411 410 toggleElem(sel); 412 411 } else { ··· 417 416 $('.hide-panel').on('click', function (e) { 418 417 // a `.hide-panel` element can hide a panel, by `data-panel="selector"` or `data-panel-closest="selector"` 419 418 e.preventDefault(); 420 - let sel = $(this).attr('data-panel'); 419 + let sel = this.getAttribute('data-panel'); 421 420 if (sel) { 422 421 hideElem($(sel)); 423 422 return; 424 423 } 425 - sel = $(this).attr('data-panel-closest'); 424 + sel = this.getAttribute('data-panel-closest'); 426 425 if (sel) { 427 426 hideElem($(this).closest(sel)); 428 427 return;
+15 -18
web_src/js/features/common-issue-list.js
··· 1 - import $ from 'jquery'; 2 1 import {isElemHidden, onInputDebounce, submitEventSubmitter, toggleElem} from '../utils/dom.js'; 3 2 import {GET} from '../modules/fetch.js'; 4 3 ··· 30 29 } 31 30 32 31 export function initCommonIssueListQuickGoto() { 33 - const $goto = $('#issue-list-quick-goto'); 34 - if (!$goto.length) return; 32 + const goto = document.getElementById('issue-list-quick-goto'); 33 + if (!goto) return; 35 34 36 - const $form = $goto.closest('form'); 37 - const $input = $form.find('input[name=q]'); 38 - const repoLink = $goto.attr('data-repo-link'); 35 + const form = goto.closest('form'); 36 + const input = form.querySelector('input[name=q]'); 37 + const repoLink = goto.getAttribute('data-repo-link'); 39 38 40 - $form.on('submit', (e) => { 39 + form.addEventListener('submit', (e) => { 41 40 // if there is no goto button, or the form is submitted by non-quick-goto elements, submit the form directly 42 - let doQuickGoto = !isElemHidden($goto); 43 - const submitter = submitEventSubmitter(e.originalEvent); 44 - if (submitter !== $form[0] && submitter !== $input[0] && submitter !== $goto[0]) doQuickGoto = false; 41 + let doQuickGoto = !isElemHidden(goto); 42 + const submitter = submitEventSubmitter(e); 43 + if (submitter !== form && submitter !== input && submitter !== goto) doQuickGoto = false; 45 44 if (!doQuickGoto) return; 46 45 47 46 // if there is a goto button, use its link 48 47 e.preventDefault(); 49 - window.location.href = $goto.attr('data-issue-goto-link'); 48 + window.location.href = goto.getAttribute('data-issue-goto-link'); 50 49 }); 51 50 52 51 const onInput = async () => { 53 - const searchText = $input.val(); 54 - 52 + const searchText = input.value; 55 53 // try to check whether the parsed goto link is valid 56 54 let targetUrl = parseIssueListQuickGotoLink(repoLink, searchText); 57 55 if (targetUrl) { 58 56 const res = await GET(`${targetUrl}/info`); 59 57 if (res.status !== 200) targetUrl = ''; 60 58 } 61 - 62 59 // if the input value has changed, then ignore the result 63 - if ($input.val() !== searchText) return; 60 + if (input.value !== searchText) return; 64 61 65 - toggleElem($goto, Boolean(targetUrl)); 66 - $goto.attr('data-issue-goto-link', targetUrl); 62 + toggleElem(goto, Boolean(targetUrl)); 63 + goto.setAttribute('data-issue-goto-link', targetUrl); 67 64 }; 68 65 69 - $input.on('input', onInputDebounce(onInput)); 66 + input.addEventListener('input', onInputDebounce(onInput)); 70 67 onInput(); 71 68 }
+10 -6
web_src/js/features/comp/ColorPicker.js
··· 2 2 import {createColorPicker} from '../colorpicker.js'; 3 3 4 4 export function initCompColorPicker() { 5 - createColorPicker($('.color-picker')); 5 + (async () => { 6 + await createColorPicker(document.querySelectorAll('.color-picker')); 6 7 7 - $('.precolors .color').on('click', function () { 8 - const color_hex = $(this).data('color-hex'); 9 - $('.color-picker').val(color_hex); 10 - $('.minicolors-swatch-color').css('background-color', color_hex); 11 - }); 8 + for (const el of document.querySelectorAll('.precolors .color')) { 9 + el.addEventListener('click', (e) => { 10 + const color = e.target.getAttribute('data-color-hex'); 11 + const parent = e.target.closest('.color.picker'); 12 + $(parent.querySelector('.color-picker')).minicolors('value', color); 13 + }); 14 + } 15 + })(); 12 16 }
+1 -1
web_src/js/features/comp/EasyMDEToolbarActions.js
··· 139 139 }, 140 140 icon: svg('octicon-chevron-right'), 141 141 title: 'Add Inline Code', 142 - } 142 + }, 143 143 }; 144 144 145 145 for (const [key, value] of Object.entries(actions)) {
+2 -4
web_src/js/features/comp/LabelEdit.js
··· 43 43 44 44 // Edit label 45 45 $('.edit-label-button').on('click', function () { 46 - $('.edit-label .color-picker').minicolors('value', $(this).data('color')); 47 46 $('#label-modal-id').val($(this).data('id')); 48 47 49 48 const $nameInput = $('.edit-label .label-name-input'); ··· 60 59 (!this.hasAttribute('data-exclusive') || !isExclusiveScopeName($nameInput.val()))); 61 60 updateExclusiveLabelEdit('.edit-label'); 62 61 63 - $('.edit-label .label-desc-input').val($(this).data('description')); 64 - $('.edit-label .color-picker').val($(this).data('color')); 65 - $('.edit-label .minicolors-swatch-color').css('background-color', $(this).data('color')); 62 + $('.edit-label .label-desc-input').val(this.getAttribute('data-description')); 63 + $('.edit-label .color-picker').minicolors('value', this.getAttribute('data-color')); 66 64 67 65 $('.edit-label.modal').modal({ 68 66 onApprove() {
+10 -7
web_src/js/features/comp/SearchUserBox.js
··· 5 5 const looksLikeEmailAddressCheck = /^\S+@\S+$/; 6 6 7 7 export function initCompSearchUserBox() { 8 - const $searchUserBox = $('#search-user-box'); 9 - const allowEmailInput = $searchUserBox.attr('data-allow-email') === 'true'; 10 - const allowEmailDescription = $searchUserBox.attr('data-allow-email-description'); 8 + const searchUserBox = document.getElementById('search-user-box'); 9 + if (!searchUserBox) return; 10 + 11 + const $searchUserBox = $(searchUserBox); 12 + const allowEmailInput = searchUserBox.getAttribute('data-allow-email') === 'true'; 13 + const allowEmailDescription = searchUserBox.getAttribute('data-allow-email-description') ?? undefined; 11 14 $searchUserBox.search({ 12 15 minCharacters: 2, 13 16 apiSettings: { ··· 19 22 $.each(response.data, (_i, item) => { 20 23 const resultItem = { 21 24 title: item.login, 22 - image: item.avatar_url 25 + image: item.avatar_url, 23 26 }; 24 27 if (item.full_name) { 25 28 resultItem.description = htmlEscape(item.full_name); ··· 34 37 if (allowEmailInput && items.length === 0 && looksLikeEmailAddressCheck.test(searchQuery)) { 35 38 const resultItem = { 36 39 title: searchQuery, 37 - description: allowEmailDescription 40 + description: allowEmailDescription, 38 41 }; 39 42 items.push(resultItem); 40 43 } 41 44 42 45 return {results: items}; 43 - } 46 + }, 44 47 }, 45 48 searchFields: ['login', 'full_name'], 46 - showNoResults: false 49 + showNoResults: false, 47 50 }); 48 51 }
+1 -1
web_src/js/features/comp/WebHookEditor.js
··· 35 35 36 36 // Test delivery 37 37 document.getElementById('test-delivery')?.addEventListener('click', async function () { 38 - this.classList.add('loading', 'disabled'); 38 + this.classList.add('is-loading', 'disabled'); 39 39 await POST(this.getAttribute('data-link')); 40 40 setTimeout(() => { 41 41 window.location.href = this.getAttribute('data-redirect');
+1 -1
web_src/js/features/contextpopup.js
··· 37 37 interactiveBorder: 5, 38 38 onShow: () => { 39 39 el.firstChild.dispatchEvent(new CustomEvent('ce-load-context-popup', {detail: {owner, repo, index}})); 40 - } 40 + }, 41 41 }); 42 42 } 43 43 }
+1 -1
web_src/js/features/contributors.js
··· 18 18 loadingTitle: el.getAttribute('data-locale-loading-title'), 19 19 loadingTitleFailed: el.getAttribute('data-locale-loading-title-failed'), 20 20 loadingInfo: el.getAttribute('data-locale-loading-info'), 21 - } 21 + }, 22 22 }); 23 23 View.mount(el); 24 24 } catch (err) {
+1 -1
web_src/js/features/eventsource.sharedworker.js
··· 48 48 this.eventSource.addEventListener(eventType, (event) => { 49 49 this.notifyClients({ 50 50 type: eventType, 51 - data: event.data 51 + data: event.data, 52 52 }); 53 53 }); 54 54 }
+110 -107
web_src/js/features/imagediff.js
··· 20 20 if (img.width > 1 && img.width < MaxSize && img.height > 1 && img.height < MaxSize) { 21 21 return { 22 22 width: img.width, 23 - height: img.height 23 + height: img.height, 24 24 }; 25 25 } 26 26 if (svg.hasAttribute('viewBox')) { 27 27 const viewBox = svg.viewBox.baseVal; 28 28 return { 29 29 width: DefaultSize, 30 - height: DefaultSize * viewBox.width / viewBox.height 30 + height: DefaultSize * viewBox.width / viewBox.height, 31 31 }; 32 32 } 33 33 return { 34 34 width: DefaultSize, 35 - height: DefaultSize 35 + height: DefaultSize, 36 36 }; 37 37 } 38 38 return null; ··· 42 42 function createContext(image1, image2) { 43 43 const size1 = { 44 44 width: image1 && image1.width || 0, 45 - height: image1 && image1.height || 0 45 + height: image1 && image1.height || 0, 46 46 }; 47 47 const size2 = { 48 48 width: image2 && image2.width || 0, 49 - height: image2 && image2.height || 0 49 + height: image2 && image2.height || 0, 50 50 }; 51 51 const max = { 52 52 width: Math.max(size2.width, size1.width), 53 - height: Math.max(size2.height, size1.height) 53 + height: Math.max(size2.height, size1.height), 54 54 }; 55 55 56 56 return { 57 - image1: $(image1), 58 - image2: $(image2), 57 + $image1: $(image1), 58 + $image2: $(image2), 59 59 size1, 60 60 size2, 61 61 max, ··· 63 63 Math.floor(max.width - size1.width) / 2, 64 64 Math.floor(max.height - size1.height) / 2, 65 65 Math.floor(max.width - size2.width) / 2, 66 - Math.floor(max.height - size2.height) / 2 67 - ] 66 + Math.floor(max.height - size2.height) / 2, 67 + ], 68 68 }; 69 69 } 70 70 71 71 $('.image-diff:not([data-image-diff-loaded])').each(async function() { 72 72 const $container = $(this); 73 - $container.attr('data-image-diff-loaded', 'true'); 73 + this.setAttribute('data-image-diff-loaded', 'true'); 74 74 75 75 // the container may be hidden by "viewed" checkbox, so use the parent's width for reference 76 76 const diffContainerWidth = Math.max($container.closest('.diff-file-box').width() - 300, 100); ··· 79 79 path: this.getAttribute('data-path-after'), 80 80 mime: this.getAttribute('data-mime-after'), 81 81 $images: $container.find('img.image-after'), // matches 3 <img> 82 - $boundsInfo: $container.find('.bounds-info-after') 82 + $boundsInfo: $container.find('.bounds-info-after'), 83 83 }, { 84 84 path: this.getAttribute('data-path-before'), 85 85 mime: this.getAttribute('data-mime-before'), 86 86 $images: $container.find('img.image-before'), // matches 3 <img> 87 - $boundsInfo: $container.find('.bounds-info-before') 87 + $boundsInfo: $container.find('.bounds-info-before'), 88 88 }]; 89 89 90 90 await Promise.all(imageInfos.map(async (info) => { ··· 98 98 const text = await resp.text(); 99 99 const bounds = getDefaultSvgBoundsIfUndefined(text, info.path); 100 100 if (bounds) { 101 - info.$images.attr('width', bounds.width); 102 - info.$images.attr('height', bounds.height); 101 + info.$images.each(function() { 102 + this.setAttribute('width', bounds.width); 103 + this.setAttribute('height', bounds.height); 104 + }); 103 105 hideElem(info.$boundsInfo); 104 106 } 105 107 } ··· 122 124 factor = (diffContainerWidth - 24) / 2 / sizes.max.width; 123 125 } 124 126 125 - const widthChanged = sizes.image1.length !== 0 && sizes.image2.length !== 0 && sizes.image1[0].naturalWidth !== sizes.image2[0].naturalWidth; 126 - const heightChanged = sizes.image1.length !== 0 && sizes.image2.length !== 0 && sizes.image1[0].naturalHeight !== sizes.image2[0].naturalHeight; 127 - if (sizes.image1.length !== 0) { 128 - $container.find('.bounds-info-after .bounds-info-width').text(`${sizes.image1[0].naturalWidth}px`).addClass(widthChanged ? 'green' : ''); 129 - $container.find('.bounds-info-after .bounds-info-height').text(`${sizes.image1[0].naturalHeight}px`).addClass(heightChanged ? 'green' : ''); 127 + const widthChanged = sizes.$image1.length !== 0 && sizes.$image2.length !== 0 && sizes.$image1[0].naturalWidth !== sizes.$image2[0].naturalWidth; 128 + const heightChanged = sizes.$image1.length !== 0 && sizes.$image2.length !== 0 && sizes.$image1[0].naturalHeight !== sizes.$image2[0].naturalHeight; 129 + if (sizes.$image1.length !== 0) { 130 + $container.find('.bounds-info-after .bounds-info-width').text(`${sizes.$image1[0].naturalWidth}px`).addClass(widthChanged ? 'green' : ''); 131 + $container.find('.bounds-info-after .bounds-info-height').text(`${sizes.$image1[0].naturalHeight}px`).addClass(heightChanged ? 'green' : ''); 132 + } 133 + if (sizes.$image2.length !== 0) { 134 + $container.find('.bounds-info-before .bounds-info-width').text(`${sizes.$image2[0].naturalWidth}px`).addClass(widthChanged ? 'red' : ''); 135 + $container.find('.bounds-info-before .bounds-info-height').text(`${sizes.$image2[0].naturalHeight}px`).addClass(heightChanged ? 'red' : ''); 130 136 } 131 - if (sizes.image2.length !== 0) { 132 - $container.find('.bounds-info-before .bounds-info-width').text(`${sizes.image2[0].naturalWidth}px`).addClass(widthChanged ? 'red' : ''); 133 - $container.find('.bounds-info-before .bounds-info-height').text(`${sizes.image2[0].naturalHeight}px`).addClass(heightChanged ? 'red' : ''); 137 + 138 + const image1 = sizes.$image1[0]; 139 + if (image1) { 140 + const container = image1.parentNode; 141 + image1.style.width = `${sizes.size1.width * factor}px`; 142 + image1.style.height = `${sizes.size1.height * factor}px`; 143 + container.style.margin = '10px auto'; 144 + container.style.width = `${sizes.size1.width * factor + 2}px`; 145 + container.style.height = `${sizes.size1.height * factor + 2}px`; 134 146 } 135 147 136 - sizes.image1.css({ 137 - width: sizes.size1.width * factor, 138 - height: sizes.size1.height * factor 139 - }); 140 - sizes.image1.parent().css({ 141 - margin: `10px auto`, 142 - width: sizes.size1.width * factor + 2, 143 - height: sizes.size1.height * factor + 2 144 - }); 145 - sizes.image2.css({ 146 - width: sizes.size2.width * factor, 147 - height: sizes.size2.height * factor 148 - }); 149 - sizes.image2.parent().css({ 150 - margin: `10px auto`, 151 - width: sizes.size2.width * factor + 2, 152 - height: sizes.size2.height * factor + 2 153 - }); 148 + const image2 = sizes.$image2[0]; 149 + if (image2) { 150 + const container = image2.parentNode; 151 + image2.style.width = `${sizes.size2.width * factor}px`; 152 + image2.style.height = `${sizes.size2.height * factor}px`; 153 + container.style.margin = '10px auto'; 154 + container.style.width = `${sizes.size2.width * factor + 2}px`; 155 + container.style.height = `${sizes.size2.height * factor + 2}px`; 156 + } 154 157 } 155 158 156 159 function initSwipe(sizes) { ··· 159 162 factor = (diffContainerWidth - 12) / sizes.max.width; 160 163 } 161 164 162 - sizes.image1.css({ 163 - width: sizes.size1.width * factor, 164 - height: sizes.size1.height * factor 165 - }); 166 - sizes.image1.parent().css({ 167 - margin: `0px ${sizes.ratio[0] * factor}px`, 168 - width: sizes.size1.width * factor + 2, 169 - height: sizes.size1.height * factor + 2 170 - }); 171 - sizes.image1.parent().parent().css({ 172 - padding: `${sizes.ratio[1] * factor}px 0 0 0`, 173 - width: sizes.max.width * factor + 2 174 - }); 175 - sizes.image2.css({ 176 - width: sizes.size2.width * factor, 177 - height: sizes.size2.height * factor 178 - }); 179 - sizes.image2.parent().css({ 180 - margin: `${sizes.ratio[3] * factor}px ${sizes.ratio[2] * factor}px`, 181 - width: sizes.size2.width * factor + 2, 182 - height: sizes.size2.height * factor + 2 183 - }); 184 - sizes.image2.parent().parent().css({ 185 - width: sizes.max.width * factor + 2, 186 - height: sizes.max.height * factor + 2 187 - }); 188 - $container.find('.diff-swipe').css({ 189 - width: sizes.max.width * factor + 2, 190 - height: sizes.max.height * factor + 30 /* extra height for inner "position: absolute" elements */, 191 - }); 165 + const image1 = sizes.$image1[0]; 166 + if (image1) { 167 + const container = image1.parentNode; 168 + const swipeFrame = container.parentNode; 169 + image1.style.width = `${sizes.size1.width * factor}px`; 170 + image1.style.height = `${sizes.size1.height * factor}px`; 171 + container.style.margin = `0px ${sizes.ratio[0] * factor}px`; 172 + container.style.width = `${sizes.size1.width * factor + 2}px`; 173 + container.style.height = `${sizes.size1.height * factor + 2}px`; 174 + swipeFrame.style.padding = `${sizes.ratio[1] * factor}px 0 0 0`; 175 + swipeFrame.style.width = `${sizes.max.width * factor + 2}px`; 176 + } 177 + 178 + const image2 = sizes.$image2[0]; 179 + if (image2) { 180 + const container = image2.parentNode; 181 + const swipeFrame = container.parentNode; 182 + image2.style.width = `${sizes.size2.width * factor}px`; 183 + image2.style.height = `${sizes.size2.height * factor}px`; 184 + container.style.margin = `${sizes.ratio[3] * factor}px ${sizes.ratio[2] * factor}px`; 185 + container.style.width = `${sizes.size2.width * factor + 2}px`; 186 + container.style.height = `${sizes.size2.height * factor + 2}px`; 187 + swipeFrame.style.width = `${sizes.max.width * factor + 2}px`; 188 + swipeFrame.style.height = `${sizes.max.height * factor + 2}px`; 189 + } 190 + 191 + // extra height for inner "position: absolute" elements 192 + const swipe = $container.find('.diff-swipe')[0]; 193 + if (swipe) { 194 + swipe.style.width = `${sizes.max.width * factor + 2}px`; 195 + swipe.style.height = `${sizes.max.height * factor + 30}px`; 196 + } 197 + 192 198 $container.find('.swipe-bar').on('mousedown', function(e) { 193 199 e.preventDefault(); 194 200 ··· 200 206 e2.preventDefault(); 201 207 202 208 const value = Math.max(0, Math.min(e2.clientX - $swipeFrame.offset().left, width)); 209 + $swipeBar[0].style.left = `${value}px`; 210 + $container.find('.swipe-container')[0].style.width = `${$swipeFrame.width() - value}px`; 203 211 204 - $swipeBar.css({ 205 - left: value 206 - }); 207 - $container.find('.swipe-container').css({ 208 - width: $swipeFrame.width() - value 209 - }); 210 212 $(document).on('mouseup.diff-swipe', () => { 211 213 $(document).off('.diff-swipe'); 212 214 }); ··· 220 222 factor = (diffContainerWidth - 12) / sizes.max.width; 221 223 } 222 224 223 - sizes.image1.css({ 224 - width: sizes.size1.width * factor, 225 - height: sizes.size1.height * factor 226 - }); 227 - sizes.image2.css({ 228 - width: sizes.size2.width * factor, 229 - height: sizes.size2.height * factor 230 - }); 231 - sizes.image1.parent().css({ 232 - margin: `${sizes.ratio[1] * factor}px ${sizes.ratio[0] * factor}px`, 233 - width: sizes.size1.width * factor + 2, 234 - height: sizes.size1.height * factor + 2 235 - }); 236 - sizes.image2.parent().css({ 237 - margin: `${sizes.ratio[3] * factor}px ${sizes.ratio[2] * factor}px`, 238 - width: sizes.size2.width * factor + 2, 239 - height: sizes.size2.height * factor + 2 240 - }); 225 + const image1 = sizes.$image1[0]; 226 + if (image1) { 227 + const container = image1.parentNode; 228 + image1.style.width = `${sizes.size1.width * factor}px`; 229 + image1.style.height = `${sizes.size1.height * factor}px`; 230 + container.style.margin = `${sizes.ratio[1] * factor}px ${sizes.ratio[0] * factor}px`; 231 + container.style.width = `${sizes.size1.width * factor + 2}px`; 232 + container.style.height = `${sizes.size1.height * factor + 2}px`; 233 + } 241 234 242 - // some inner elements are `position: absolute`, so the container's height must be large enough 243 - // the "css(width, height)" is somewhat hacky and not easy to understand, it could be improved in the future 244 - sizes.image2.parent().parent().css({ 245 - width: sizes.max.width * factor + 2, 246 - height: sizes.max.height * factor + 2, 247 - }); 235 + const image2 = sizes.$image2[0]; 236 + if (image2) { 237 + const container = image2.parentNode; 238 + const overlayFrame = container.parentNode; 239 + image2.style.width = `${sizes.size2.width * factor}px`; 240 + image2.style.height = `${sizes.size2.height * factor}px`; 241 + container.style.margin = `${sizes.ratio[3] * factor}px ${sizes.ratio[2] * factor}px`; 242 + container.style.width = `${sizes.size2.width * factor + 2}px`; 243 + container.style.height = `${sizes.size2.height * factor + 2}px`; 248 244 249 - const $range = $container.find("input[type='range']"); 250 - const onInput = () => sizes.image1.parent().css({ 251 - opacity: $range.val() / 100 252 - }); 253 - $range.on('input', onInput); 254 - onInput(); 245 + // some inner elements are `position: absolute`, so the container's height must be large enough 246 + overlayFrame.style.width = `${sizes.max.width * factor + 2}px`; 247 + overlayFrame.style.height = `${sizes.max.height * factor + 2}px`; 248 + } 249 + 250 + const rangeInput = $container[0].querySelector('input[type="range"]'); 251 + function updateOpacity() { 252 + if (sizes?.$image1?.[0]) { 253 + sizes.$image1[0].parentNode.style.opacity = `${rangeInput.value / 100}`; 254 + } 255 + } 256 + rangeInput?.addEventListener('input', updateOpacity); 257 + updateOpacity(); 255 258 } 256 259 }); 257 260 }
+1 -1
web_src/js/features/install.js
··· 19 19 const defaultDbHosts = { 20 20 mysql: '127.0.0.1:3306', 21 21 postgres: '127.0.0.1:5432', 22 - mssql: '127.0.0.1:1433' 22 + mssql: '127.0.0.1:1433', 23 23 }; 24 24 25 25 const dbHost = document.getElementById('db_host');
+3 -3
web_src/js/features/org-team.js
··· 26 26 $.each(response.data, (_i, item) => { 27 27 items.push({ 28 28 title: item.repository.full_name.split('/')[1], 29 - description: item.repository.full_name 29 + description: item.repository.full_name, 30 30 }); 31 31 }); 32 32 33 33 return {results: items}; 34 - } 34 + }, 35 35 }, 36 36 searchFields: ['full_name'], 37 - showNoResults: false 37 + showNoResults: false, 38 38 }); 39 39 }
+1 -1
web_src/js/features/recent-commits.js
··· 11 11 loadingTitle: el.getAttribute('data-locale-loading-title'), 12 12 loadingTitleFailed: el.getAttribute('data-locale-loading-title-failed'), 13 13 loadingInfo: el.getAttribute('data-locale-loading-info'), 14 - } 14 + }, 15 15 }); 16 16 View.mount(el); 17 17 } catch (err) {
+1 -1
web_src/js/features/repo-code.js
··· 116 116 tippy.popper.addEventListener('click', () => { 117 117 tippy.hide(); 118 118 }, {once: true}); 119 - } 119 + }, 120 120 }); 121 121 } 122 122
+12 -8
web_src/js/features/repo-common.js
··· 3 3 import {POST} from '../modules/fetch.js'; 4 4 5 5 async function getArchive($target, url, first) { 6 + const dropdownBtn = $target[0].closest('.ui.dropdown.button'); 7 + 6 8 try { 9 + dropdownBtn.classList.add('is-loading'); 7 10 const response = await POST(url); 8 11 if (response.status === 200) { 9 12 const data = await response.json(); 10 13 if (!data) { 11 14 // XXX Shouldn't happen? 12 - $target.closest('.dropdown').children('i').removeClass('loading'); 15 + dropdownBtn.classList.remove('is-loading'); 13 16 return; 14 17 } 15 18 16 19 if (!data.complete) { 17 - $target.closest('.dropdown').children('i').addClass('loading'); 18 20 // Wait for only three quarters of a second initially, in case it's 19 21 // quickly archived. 20 22 setTimeout(() => { ··· 22 24 }, first ? 750 : 2000); 23 25 } else { 24 26 // We don't need to continue checking. 25 - $target.closest('.dropdown').children('i').removeClass('loading'); 27 + dropdownBtn.classList.remove('is-loading'); 26 28 window.location.href = url; 27 29 } 28 30 } 29 31 } catch { 30 - $target.closest('.dropdown').children('i').removeClass('loading'); 32 + dropdownBtn.classList.remove('is-loading'); 31 33 } 32 34 } 33 35 34 36 export function initRepoArchiveLinks() { 35 37 $('.archive-link').on('click', function (event) { 36 38 event.preventDefault(); 37 - const url = $(this).attr('href'); 39 + const url = this.getAttribute('href'); 38 40 if (!url) return; 39 41 getArchive($(event.target), url, true); 40 42 }); ··· 76 78 77 79 export function initRepoCommonFilterSearchDropdown(selector) { 78 80 const $dropdown = $(selector); 81 + if (!$dropdown.length) return; 82 + 79 83 $dropdown.dropdown({ 80 84 fullTextSearch: 'exact', 81 85 selectOnKeydown: false, 82 86 onChange(_text, _value, $choice) { 83 - if ($choice.attr('data-url')) { 84 - window.location.href = $choice.attr('data-url'); 87 + if ($choice[0].getAttribute('data-url')) { 88 + window.location.href = $choice[0].getAttribute('data-url'); 85 89 } 86 90 }, 87 - message: {noResults: $dropdown.attr('data-no-results')}, 91 + message: {noResults: $dropdown[0].getAttribute('data-no-results')}, 88 92 }); 89 93 }
+1 -1
web_src/js/features/repo-diff-commit.js
··· 39 39 link.href = href; 40 40 link.textContent = text; 41 41 if (tooltip) { 42 - link.classList.add('gt-border-secondary', 'gt-rounded'); 42 + link.classList.add('tw-border', 'tw-border-secondary', 'tw-rounded'); 43 43 link.setAttribute('data-tooltip-content', tooltip); 44 44 } 45 45 parent.append(link);
+13 -10
web_src/js/features/repo-diff.js
··· 13 13 const {pageData, i18n} = window.config; 14 14 15 15 function initRepoDiffReviewButton() { 16 - const $reviewBox = $('#review-box'); 17 - const $counter = $reviewBox.find('.review-comments-counter'); 16 + const reviewBox = document.getElementById('review-box'); 17 + if (!reviewBox) return; 18 + 19 + const $reviewBox = $(reviewBox); 20 + const counter = reviewBox.querySelector('.review-comments-counter'); 21 + if (!counter) return; 18 22 19 23 $(document).on('click', 'button[name="pending_review"]', (e) => { 20 24 const $form = $(e.target).closest('form'); 21 25 // Watch for the form's submit event. 22 26 $form.on('submit', () => { 23 - const num = parseInt($counter.attr('data-pending-comment-number')) + 1 || 1; 24 - $counter.attr('data-pending-comment-number', num); 25 - $counter.text(num); 27 + const num = parseInt(counter.getAttribute('data-pending-comment-number')) + 1 || 1; 28 + counter.setAttribute('data-pending-comment-number', num); 29 + counter.textContent = num; 26 30 // Force the browser to reflow the DOM. This is to ensure that the browser replay the animation 27 31 $reviewBox.removeClass('pulse'); 28 32 $reviewBox.width(); ··· 67 71 formData.append(submitter.name, submitter.value); 68 72 } 69 73 70 - const response = await POST($form.attr('action'), {data: formData}); 74 + const response = await POST(e.target.getAttribute('action'), {data: formData}); 71 75 const $newConversationHolder = $(await response.text()); 72 76 const {path, side, idx} = $newConversationHolder.data(); 73 77 ··· 120 124 const index = $conversations.index($conversation); 121 125 const previousIndex = index > 0 ? index - 1 : $conversations.length - 1; 122 126 const $previousConversation = $conversations.eq(previousIndex); 123 - const anchor = $previousConversation.find('.comment').first().attr('id'); 127 + const anchor = $previousConversation.find('.comment').first()[0].getAttribute('id'); 124 128 window.location.href = `#${anchor}`; 125 129 }); 126 130 $(document).on('click', '.next-conversation', (e) => { ··· 129 133 const index = $conversations.index($conversation); 130 134 const nextIndex = index < $conversations.length - 1 ? index + 1 : 0; 131 135 const $nextConversation = $conversations.eq(nextIndex); 132 - const anchor = $nextConversation.find('.comment').first().attr('id'); 136 + const anchor = $nextConversation.find('.comment').first()[0].getAttribute('id'); 133 137 window.location.href = `#${anchor}`; 134 138 }); 135 139 } ··· 175 179 $(document).on('click', 'a#diff-show-more-files', (e) => { 176 180 e.preventDefault(); 177 181 178 - const $target = $(e.target); 179 - const linkLoadMore = $target.attr('data-href'); 182 + const linkLoadMore = e.target.getAttribute('data-href'); 180 183 loadMoreFiles(linkLoadMore); 181 184 }); 182 185
+1 -1
web_src/js/features/repo-editor.js
··· 72 72 hideElem($('.quick-pull-branch-name')); 73 73 document.querySelector('.quick-pull-branch-name input').required = false; 74 74 } 75 - $('#commit-button').text($(this).attr('button_text')); 75 + $('#commit-button').text(this.getAttribute('button_text')); 76 76 }); 77 77 78 78 const joinTreePath = ($fileNameEl) => {
+4 -4
web_src/js/features/repo-graph.js
··· 18 18 window.history.replaceState({}, '', window.location.pathname); 19 19 } 20 20 $('.pagination a').each((_, that) => { 21 - const href = $(that).attr('href'); 21 + const href = that.getAttribute('href'); 22 22 if (!href) return; 23 23 const url = new URL(href, window.location); 24 24 const params = url.searchParams; 25 25 params.set('mode', 'monochrome'); 26 26 url.search = `?${params.toString()}`; 27 - $(that).attr('href', url.href); 27 + that.setAttribute('href', url.href); 28 28 }); 29 29 }); 30 30 $('#flow-color-colored').on('click', () => { ··· 32 32 $('#flow-color-monochrome').removeClass('active'); 33 33 $('#git-graph-container').addClass('colored').removeClass('monochrome'); 34 34 $('.pagination a').each((_, that) => { 35 - const href = $(that).attr('href'); 35 + const href = that.getAttribute('href'); 36 36 if (!href) return; 37 37 const url = new URL(href, window.location); 38 38 const params = url.searchParams; 39 39 params.delete('mode'); 40 40 url.search = `?${params.toString()}`; 41 - $(that).attr('href', url.href); 41 + that.setAttribute('href', url.href); 42 42 }); 43 43 const params = new URLSearchParams(window.location.search); 44 44 params.delete('mode');
+6 -6
web_src/js/features/repo-home.js
··· 146 146 addedValue = addedValue.toLowerCase().trim(); 147 147 $($addedChoice).attr('data-value', addedValue); 148 148 $($addedChoice).attr('data-text', addedValue); 149 - } 149 + }, 150 150 }); 151 151 152 152 $.fn.form.settings.rules.validateTopic = function (_values, regExp) { ··· 168 168 { 169 169 type: 'validateTopic', 170 170 value: /^\s*[a-z0-9][-.a-z0-9]{0,35}\s*$/, 171 - prompt: topicPrompts.formatPrompt 171 + prompt: topicPrompts.formatPrompt, 172 172 }, 173 173 { 174 174 type: 'maxCount[25]', 175 - prompt: topicPrompts.countPrompt 176 - } 177 - ] 175 + prompt: topicPrompts.countPrompt, 176 + }, 177 + ], 178 178 }, 179 - } 179 + }, 180 180 }); 181 181 }
+2 -2
web_src/js/features/repo-issue-content.js
··· 16 16 $dialog = $(` 17 17 <div class="ui modal content-history-detail-dialog"> 18 18 ${svg('octicon-x', 16, 'close icon inside')} 19 - <div class="header gt-df gt-ac gt-sb"> 19 + <div class="header tw-flex tw-items-center tw-justify-between"> 20 20 <div>${itemTitleHtml}</div> 21 21 <div class="ui dropdown dialog-header-options gt-mr-5 gt-hidden"> 22 22 ${i18nTextOptions} ··· 60 60 }, 61 61 onHide() { 62 62 $(this).dropdown('clear', true); 63 - } 63 + }, 64 64 }); 65 65 $dialog.modal({ 66 66 async onShow() {
+5 -4
web_src/js/features/repo-issue-list.js
··· 9 9 10 10 function initRepoIssueListCheckboxes() { 11 11 const issueSelectAll = document.querySelector('.issue-checkbox-all'); 12 + if (!issueSelectAll) return; // logged out state 12 13 const issueCheckboxes = document.querySelectorAll('.issue-checkbox'); 13 14 14 15 const syncIssueSelectionState = () => { ··· 92 93 const $searchDropdown = $('.user-remote-search'); 93 94 if (!$searchDropdown.length) return; 94 95 95 - let searchUrl = $searchDropdown.attr('data-search-url'); 96 - const actionJumpUrl = $searchDropdown.attr('data-action-jump-url'); 97 - const selectedUserId = $searchDropdown.attr('data-selected-user-id'); 96 + let searchUrl = $searchDropdown[0].getAttribute('data-search-url'); 97 + const actionJumpUrl = $searchDropdown[0].getAttribute('data-action-jump-url'); 98 + const selectedUserId = $searchDropdown[0].getAttribute('data-selected-user-id'); 98 99 if (!searchUrl.includes('?')) searchUrl += '?'; 99 100 100 101 $searchDropdown.dropdown('setting', { ··· 107 108 // the content is provided by backend IssuePosters handler 108 109 const processedResults = []; // to be used by dropdown to generate menu items 109 110 for (const item of resp.results) { 110 - let html = `<img class="ui avatar gt-vm" src="${htmlEscape(item.avatar_link)}" aria-hidden="true" alt="" width="20" height="20"><span class="gt-ellipsis">${htmlEscape(item.username)}</span>`; 111 + let html = `<img class="ui avatar tw-align-middle" src="${htmlEscape(item.avatar_link)}" aria-hidden="true" alt="" width="20" height="20"><span class="gt-ellipsis">${htmlEscape(item.username)}</span>`; 111 112 if (item.full_name) html += `<span class="search-fullname gt-ml-3">${htmlEscape(item.full_name)}</span>`; 112 113 processedResults.push({value: item.user_id, name: html}); 113 114 }
+19 -13
web_src/js/features/repo-issue.js
··· 43 43 44 44 async function updateDeadline(deadlineString) { 45 45 hideElem($('#deadline-err-invalid-date')); 46 - $('#deadline-loader').addClass('loading'); 46 + $('#deadline-loader').addClass('is-loading'); 47 47 48 48 let realDeadline = null; 49 49 if (deadlineString !== '') { 50 50 const newDate = Date.parse(deadlineString); 51 51 52 52 if (Number.isNaN(newDate)) { 53 - $('#deadline-loader').removeClass('loading'); 53 + $('#deadline-loader').removeClass('is-loading'); 54 54 showElem($('#deadline-err-invalid-date')); 55 55 return false; 56 56 } ··· 59 59 60 60 try { 61 61 const response = await POST($('#update-issue-deadline-form').attr('action'), { 62 - data: {due_date: realDeadline} 62 + data: {due_date: realDeadline}, 63 63 }); 64 64 65 65 if (response.ok) { ··· 69 69 } 70 70 } catch (error) { 71 71 console.error(error); 72 - $('#deadline-loader').removeClass('loading'); 72 + $('#deadline-loader').removeClass('is-loading'); 73 73 showElem($('#deadline-err-invalid-date')); 74 74 } 75 75 } ··· 162 162 const response = await POST($this.data('url')); 163 163 if (!response.ok) throw new Error('Failed to delete comment'); 164 164 const $conversationHolder = $this.closest('.conversation-holder'); 165 - 165 + const $parentTimelineItem = $this.closest('.timeline-item'); 166 + const $parentTimelineGroup = $this.closest('.timeline-item-group'); 166 167 // Check if this was a pending comment. 167 168 if ($conversationHolder.find('.pending-label').length) { 168 169 const $counter = $('#review-box .review-comments-counter'); ··· 184 185 $(`[data-path="${path}"] .add-code-comment[data-side="${side}"][data-idx="${idx}"]`).removeClass('tw-invisible'); 185 186 } 186 187 $conversationHolder.remove(); 188 + } 189 + // Check if there is no review content, move the time avatar upward to avoid overlapping the content below. 190 + if (!$parentTimelineGroup.find('.timeline-item.comment').length && !$parentTimelineItem.find('.conversation-holder').length) { 191 + const $timelineAvatar = $parentTimelineGroup.find('.timeline-avatar'); 192 + $timelineAvatar.removeClass('timeline-avatar-offset'); 187 193 } 188 194 } catch (error) { 189 195 console.error(error); ··· 231 237 e.preventDefault(); 232 238 const $this = $(this); 233 239 const redirect = $this.data('redirect'); 234 - $this.addClass('loading'); 240 + $this.addClass('is-loading'); 235 241 let response; 236 242 try { 237 243 response = await POST($this.data('do')); 238 244 } catch (error) { 239 245 console.error(error); 240 246 } finally { 241 - $this.removeClass('loading'); 247 + $this.removeClass('is-loading'); 242 248 } 243 249 let data; 244 250 try { ··· 262 268 $pullUpdateButton.find('.button-text').text($choice.text()); 263 269 $pullUpdateButton.data('do', $url); 264 270 } 265 - } 271 + }, 266 272 }); 267 273 } 268 274 ··· 310 316 $.each(response.data, (_r, repo) => { 311 317 filteredResponse.results.push({ 312 318 name: htmlEscape(repo.repository.full_name), 313 - value: repo.repository.full_name 319 + value: repo.repository.full_name, 314 320 }); 315 321 }); 316 322 return filteredResponse; ··· 321 327 const $form = $choice.closest('form'); 322 328 $form.attr('action', `${appSubUrl}/${_text}/issues/new`); 323 329 }, 324 - fullTextSearch: true 330 + fullTextSearch: true, 325 331 }); 326 332 } 327 333 ··· 437 443 } 438 444 window.scrollTo({ 439 445 top: $commentDiv.offset().top - offset, 440 - behavior: 'instant' 446 + behavior: 'instant', 441 447 }); 442 448 } 443 449 } ··· 655 661 // Replace branch name to keep translation from HTML template 656 662 $selectionTextField.html($selectionTextField.html().replace( 657 663 `${baseName}:${branchNameOld}`, 658 - `${baseName}:${branchNameNew}` 664 + `${baseName}:${branchNameNew}`, 659 665 )); 660 666 $selectionTextField.data('branch', branchNameNew); // update branch name in setting 661 667 }; ··· 689 695 const editor = await initComboMarkdownEditor($markdownEditor, { 690 696 onContentChanged: (editor) => { 691 697 $formField.val(editor.value()); 692 - } 698 + }, 693 699 }); 694 700 695 701 $formField.on('focus', async () => {
+2 -2
web_src/js/features/repo-legacy.js
··· 389 389 dz.emit('complete', attachment); 390 390 dz.files.push(attachment); 391 391 fileUuidDict[attachment.uuid] = {submitted: true}; 392 - $dropzone.find(`img[src='${imgSrc}']`).css('max-width', '100%'); 392 + $dropzone.find(`img[src='${imgSrc}']`)[0].style.maxWidth = '100%'; 393 393 const $input = $(`<input id="${attachment.uuid}" name="files" type="hidden">`).val(attachment.uuid); 394 394 $dropzone.find('.files').append($input); 395 395 } ··· 436 436 const $content = $segment; 437 437 if (!$content.find('.dropzone-attachments').length) { 438 438 if (data.attachments !== '') { 439 - $content[0].append(data.attachments); 439 + $content[0].insertAdjacentHTML('beforeend', data.attachments); 440 440 } 441 441 } else if (data.attachments === '') { 442 442 $content.find('.dropzone-attachments').remove();
+8 -7
web_src/js/features/repo-projects.js
··· 33 33 34 34 const columnSorting = { 35 35 issues: Array.from(columnCards, (card, i) => ({ 36 - issueID: parseInt($(card).attr('data-issue')), 36 + issueID: parseInt(card.getAttribute('data-issue')), 37 37 sorting: i, 38 38 })), 39 39 }; ··· 72 72 await PUT($(column).data('url'), { 73 73 data: { 74 74 sorting: i, 75 - color: rgbToHex($(column).css('backgroundColor')), 75 + color: rgbToHex(window.getComputedStyle($(column)[0]).backgroundColor), 76 76 }, 77 77 }); 78 78 } catch (error) { ··· 111 111 const $projectColorInput = $(this).find('#new_project_column_color'); 112 112 const $boardColumn = $(this).closest('.project-column'); 113 113 114 - if ($boardColumn.css('backgroundColor')) { 115 - setLabelColor($projectHeader, rgbToHex($boardColumn.css('backgroundColor'))); 114 + const bgColor = $boardColumn[0].style.backgroundColor; 115 + if (bgColor) { 116 + setLabelColor($projectHeader, rgbToHex(bgColor)); 116 117 } 117 118 118 119 $(this).find('.edit-project-column-button').on('click', async function (e) { ··· 133 134 if ($projectColorInput.val()) { 134 135 setLabelColor($projectHeader, $projectColorInput.val()); 135 136 } 136 - $boardColumn.attr('style', `background: ${$projectColorInput.val()}!important`); 137 + $boardColumn[0].style = `background: ${$projectColorInput.val()} !important`; 137 138 $('.ui.modal').modal('hide'); 138 139 } 139 140 }); ··· 158 159 }); 159 160 160 161 $('.show-delete-project-column-modal').each(function () { 161 - const $deleteColumnModal = $(`${$(this).attr('data-modal')}`); 162 + const $deleteColumnModal = $(`${this.getAttribute('data-modal')}`); 162 163 const $deleteColumnButton = $deleteColumnModal.find('.actions > .ok.button'); 163 - const deleteUrl = $(this).attr('data-url'); 164 + const deleteUrl = this.getAttribute('data-url'); 164 165 165 166 $deleteColumnButton.on('click', async (e) => { 166 167 e.preventDefault();
+20 -18
web_src/js/features/repo-settings.js
··· 8 8 9 9 export function initRepoSettingsCollaboration() { 10 10 // Change collaborator access mode 11 - $('.page-content.repository .ui.dropdown.access-mode').each((_, e) => { 12 - const $dropdown = $(e); 11 + $('.page-content.repository .ui.dropdown.access-mode').each((_, el) => { 12 + const $dropdown = $(el); 13 13 const $text = $dropdown.find('> .text'); 14 14 $dropdown.dropdown({ 15 15 async action(_text, value) { 16 - const lastValue = $dropdown.attr('data-last-value'); 16 + const lastValue = el.getAttribute('data-last-value'); 17 17 try { 18 - $dropdown.attr('data-last-value', value); 18 + el.setAttribute('data-last-value', value); 19 19 $dropdown.dropdown('hide'); 20 20 const data = new FormData(); 21 - data.append('uid', $dropdown.attr('data-uid')); 21 + data.append('uid', el.getAttribute('data-uid')); 22 22 data.append('mode', value); 23 - await POST($dropdown.attr('data-url'), {data}); 23 + await POST(el.getAttribute('data-url'), {data}); 24 24 } catch { 25 25 $text.text('(error)'); // prevent from misleading users when error occurs 26 - $dropdown.attr('data-last-value', lastValue); 26 + el.setAttribute('data-last-value', lastValue); 27 27 } 28 28 }, 29 29 onChange(_value, text, _$choice) { ··· 32 32 onHide() { 33 33 // set to the really selected value, defer to next tick to make sure `action` has finished its work because the calling order might be onHide -> action 34 34 setTimeout(() => { 35 - const $item = $dropdown.dropdown('get item', $dropdown.attr('data-last-value')); 35 + const $item = $dropdown.dropdown('get item', el.getAttribute('data-last-value')); 36 36 if ($item) { 37 - $dropdown.dropdown('set selected', $dropdown.attr('data-last-value')); 37 + $dropdown.dropdown('set selected', el.getAttribute('data-last-value')); 38 38 } else { 39 39 $text.text('(none)'); // prevent from misleading users when the access mode is undefined 40 40 } 41 41 }, 0); 42 - } 42 + }, 43 43 }); 44 44 }); 45 45 } 46 46 47 47 export function initRepoSettingSearchTeamBox() { 48 - const $searchTeamBox = $('#search-team-box'); 49 - $searchTeamBox.search({ 48 + const searchTeamBox = document.getElementById('search-team-box'); 49 + if (!searchTeamBox) return; 50 + 51 + $(searchTeamBox).search({ 50 52 minCharacters: 2, 51 53 apiSettings: { 52 - url: `${appSubUrl}/org/${$searchTeamBox.attr('data-org-name')}/teams/-/search?q={query}`, 54 + url: `${appSubUrl}/org/${searchTeamBox.getAttribute('data-org-name')}/teams/-/search?q={query}`, 53 55 headers: {'X-Csrf-Token': csrfToken}, 54 56 onResponse(response) { 55 57 const items = []; 56 58 $.each(response.data, (_i, item) => { 57 59 items.push({ 58 60 title: item.name, 59 - description: `${item.permission} access` // TODO: translate this string 61 + description: `${item.permission} access`, // TODO: translate this string 60 62 }); 61 63 }); 62 64 63 65 return {results: items}; 64 - } 66 + }, 65 67 }, 66 68 searchFields: ['name', 'description'], 67 - showNoResults: false 69 + showNoResults: false, 68 70 }); 69 71 } 70 72 ··· 77 79 export function initRepoSettingBranches() { 78 80 if (!$('.repository.settings.branches').length) return; 79 81 $('.toggle-target-enabled').on('change', function () { 80 - const $target = $($(this).attr('data-target')); 82 + const $target = $(this.getAttribute('data-target')); 81 83 $target.toggleClass('disabled', !this.checked); 82 84 }); 83 85 $('.toggle-target-disabled').on('change', function () { 84 - const $target = $($(this).attr('data-target')); 86 + const $target = $(this.getAttribute('data-target')); 85 87 if (this.checked) $target.addClass('disabled'); // only disable, do not auto enable 86 88 }); 87 89 $('#dismiss_stale_approvals').on('change', function () {
+3 -3
web_src/js/features/repo-template.js
··· 29 29 const filteredResponse = {success: true, results: []}; 30 30 filteredResponse.results.push({ 31 31 name: '', 32 - value: '' 32 + value: '', 33 33 }); 34 34 // Parse the response from the api to work with our dropdown 35 35 $.each(response.data, (_r, repo) => { 36 36 filteredResponse.results.push({ 37 37 name: htmlEscape(repo.repository.full_name), 38 - value: repo.repository.id 38 + value: repo.repository.id, 39 39 }); 40 40 }); 41 41 return filteredResponse; ··· 43 43 cache: false, 44 44 }, 45 45 46 - fullTextSearch: true 46 + fullTextSearch: true, 47 47 }); 48 48 }; 49 49 $('#uid').on('change', changeOwner);
+1 -1
web_src/js/features/repo-wiki.js
··· 60 60 'gitea-code-inline', 'code', 'quote', '|', 'gitea-checkbox-empty', 'gitea-checkbox-checked', '|', 61 61 'unordered-list', 'ordered-list', '|', 62 62 'link', 'image', 'table', 'horizontal-rule', '|', 63 - 'preview', 'fullscreen', 'side-by-side', '|', 'gitea-switch-to-textarea' 63 + 'preview', 'fullscreen', 'side-by-side', '|', 'gitea-switch-to-textarea', 64 64 ], 65 65 }, 66 66 });
+2 -2
web_src/js/features/tribute.js
··· 25 25 }, 26 26 menuItemTemplate: (item) => { 27 27 return `<div class="tribute-item">${emojiHTML(item.original)}<span>${htmlEscape(item.original)}</span></div>`; 28 - } 28 + }, 29 29 }); 30 30 } 31 31 ··· 41 41 ${item.original.fullname && item.original.fullname !== '' ? `<span class="fullname">${htmlEscape(item.original.fullname)}</span>` : ''} 42 42 </div> 43 43 `; 44 - } 44 + }, 45 45 }); 46 46 } 47 47
+3 -3
web_src/js/features/user-auth-webauthn.js
··· 26 26 } 27 27 try { 28 28 const credential = await navigator.credentials.get({ 29 - publicKey: options.publicKey 29 + publicKey: options.publicKey, 30 30 }); 31 31 await verifyAssertion(credential); 32 32 } catch (err) { ··· 37 37 delete options.publicKey.extensions.appid; 38 38 try { 39 39 const credential = await navigator.credentials.get({ 40 - publicKey: options.publicKey 40 + publicKey: options.publicKey, 41 41 }); 42 42 await verifyAssertion(credential); 43 43 } catch (err) { ··· 185 185 186 186 try { 187 187 const credential = await navigator.credentials.create({ 188 - publicKey: options.publicKey 188 + publicKey: options.publicKey, 189 189 }); 190 190 await webauthnRegistered(credential); 191 191 } catch (err) {
+54 -34
web_src/js/markup/anchors.js
··· 1 1 import {svg} from '../svg.js'; 2 2 3 - const headingSelector = '.markup h1, .markup h2, .markup h3, .markup h4, .markup h5, .markup h6'; 3 + const addPrefix = (str) => `user-content-${str}`; 4 + const removePrefix = (str) => str.replace(/^user-content-/, ''); 5 + const hasPrefix = (str) => str.startsWith('user-content-'); 4 6 5 7 // scroll to anchor while respecting the `user-content` prefix that exists on the target 6 - function scrollToAnchor(hash, initial) { 7 - // abort if the browser has already scrolled to another anchor during page load 8 - if (initial && document.querySelector(':target')) return; 9 - if (hash?.length <= 1) return; 10 - const id = decodeURIComponent(hash.substring(1)); 11 - const el = document.getElementById(`user-content-${id}`); 12 - if (el) { 13 - el.scrollIntoView(); 14 - } else if (id.startsWith('user-content-')) { // compat for links with old 'user-content-' prefixed hashes 15 - const el = document.getElementById(id); 16 - if (el) el.scrollIntoView(); 8 + function scrollToAnchor(encodedId) { 9 + if (!encodedId) return; 10 + const id = decodeURIComponent(encodedId); 11 + const prefixedId = addPrefix(id); 12 + let el = document.getElementById(prefixedId); 13 + 14 + // check for matching user-generated `a[name]` 15 + if (!el) { 16 + const nameAnchors = document.getElementsByName(prefixedId); 17 + if (nameAnchors.length) { 18 + el = nameAnchors[0]; 19 + } 17 20 } 21 + 22 + // compat for links with old 'user-content-' prefixed hashes 23 + if (!el && hasPrefix(id)) { 24 + return document.getElementById(id)?.scrollIntoView(); 25 + } 26 + 27 + el?.scrollIntoView(); 18 28 } 19 29 20 30 export function initMarkupAnchors() { 21 - if (!document.querySelector('.markup')) return; 31 + const markupEls = document.querySelectorAll('.markup'); 32 + if (!markupEls.length) return; 22 33 23 - // create link icons for markup headings, the resulting link href will remove `user-content-` 24 - for (const heading of document.querySelectorAll(headingSelector)) { 25 - const originalId = heading.id.replace(/^user-content-/, ''); 26 - const a = document.createElement('a'); 27 - a.classList.add('anchor'); 28 - a.setAttribute('href', `#${encodeURIComponent(originalId)}`); 29 - a.innerHTML = svg('octicon-link'); 30 - a.addEventListener('click', (e) => { 31 - scrollToAnchor(e.currentTarget.getAttribute('href'), false); 32 - }); 33 - heading.prepend(a); 34 - } 34 + for (const markupEl of markupEls) { 35 + // create link icons for markup headings, the resulting link href will remove `user-content-` 36 + for (const heading of markupEl.querySelectorAll('h1, h2, h3, h4, h5, h6')) { 37 + const a = document.createElement('a'); 38 + a.classList.add('anchor'); 39 + a.setAttribute('href', `#${encodeURIComponent(removePrefix(heading.id))}`); 40 + a.innerHTML = svg('octicon-link'); 41 + heading.prepend(a); 42 + } 35 43 36 - // handle user-defined `name` anchors like `[Link](#link)` linking to `<a name="link"></a>Link` 37 - for (const a of document.querySelectorAll('.markup a[href^="#"]')) { 38 - const href = a.getAttribute('href'); 39 - if (!href.startsWith('#user-content-')) continue; 40 - const originalId = href.replace(/^#user-content-/, ''); 41 - a.setAttribute('href', `#${encodeURIComponent(originalId)}`); 42 - if (a.closest('.markup').querySelectorAll(`a[name="${originalId}"]`).length !== 1) { 44 + // remove `user-content-` prefix from links so they don't show in url bar when clicked 45 + for (const a of markupEl.querySelectorAll('a[href^="#"]')) { 46 + const href = a.getAttribute('href'); 47 + if (!href.startsWith('#user-content-')) continue; 48 + a.setAttribute('href', `#${removePrefix(href.substring(1))}`); 49 + } 50 + 51 + // add `user-content-` prefix to user-generated `a[name]` link targets 52 + // TODO: this prefix should be added in backend instead 53 + for (const a of markupEl.querySelectorAll('a[name]')) { 54 + const name = a.getAttribute('name'); 55 + if (!name) continue; 56 + a.setAttribute('name', addPrefix(a.name)); 57 + } 58 + 59 + for (const a of markupEl.querySelectorAll('a[href^="#"]')) { 43 60 a.addEventListener('click', (e) => { 44 - scrollToAnchor(e.currentTarget.getAttribute('href'), false); 61 + scrollToAnchor(e.currentTarget.getAttribute('href')?.substring(1)); 45 62 }); 46 63 } 47 64 } 48 65 49 - scrollToAnchor(window.location.hash, true); 66 + // scroll to anchor unless the browser has already scrolled somewhere during page load 67 + if (!document.querySelector(':target')) { 68 + scrollToAnchor(window.location.hash?.substring(1)); 69 + } 50 70 }
+1 -1
web_src/js/modules/tippy.js
··· 148 148 const observerConnect = (observer) => observer.observe(document, { 149 149 subtree: true, 150 150 childList: true, 151 - attributeFilter: ['data-tooltip-content', 'title'] 151 + attributeFilter: ['data-tooltip-content', 'title'], 152 152 }); 153 153 const observer = new MutationObserver((mutationList, observer) => { 154 154 const pending = observer.takeRecords();
+3 -3
web_src/js/standalone/forgejo-swagger.js
··· 11 11 docExpansion: 'none', 12 12 defaultModelRendering: 'model', // don't show examples by default, because they may be incomplete 13 13 presets: [ 14 - SwaggerUI.presets.apis 14 + SwaggerUI.presets.apis, 15 15 ], 16 16 plugins: [ 17 - SwaggerUI.plugins.DownloadUrl 18 - ] 17 + SwaggerUI.plugins.DownloadUrl, 18 + ], 19 19 }); 20 20 21 21 window.ui = ui;
+3 -3
web_src/js/standalone/swagger.js
··· 21 21 docExpansion: 'none', 22 22 defaultModelRendering: 'model', // don't show examples by default, because they may be incomplete 23 23 presets: [ 24 - SwaggerUI.presets.apis 24 + SwaggerUI.presets.apis, 25 25 ], 26 26 plugins: [ 27 - SwaggerUI.plugins.DownloadUrl 28 - ] 27 + SwaggerUI.plugins.DownloadUrl, 28 + ], 29 29 }); 30 30 31 31 window.ui = ui;
+2 -2
web_src/js/svg.js
··· 189 189 name: {type: String, required: true}, 190 190 size: {type: Number, default: 16}, 191 191 className: {type: String, default: ''}, 192 - symbolId: {type: String} 192 + symbolId: {type: String}, 193 193 }, 194 194 render() { 195 195 let {svgOuter, svgInnerHtml} = svgParseOuterInner(this.name); ··· 205 205 206 206 // make the <SvgIcon class="foo" class-name="bar"> classes work together 207 207 const classes = []; 208 - for (const cls of svgOuter.classList) { 208 + for (const cls of svgOuter.classList.values()) { 209 209 classes.push(cls); 210 210 } 211 211 // TODO: drop the `className/class-name` prop in the future, only use "class" prop
+1 -1
web_src/js/utils/dom.js
··· 191 191 textarea.removeEventListener('mousemove', onUserResize); 192 192 textarea.removeEventListener('input', resizeToFit); 193 193 textarea.form?.removeEventListener('reset', onFormReset); 194 - } 194 + }, 195 195 }; 196 196 } 197 197
+1 -1
web_src/js/webcomponents/polyfills.js
··· 9 9 return { 10 10 format(value) { 11 11 return ` ${value} ${options.unit}`; 12 - } 12 + }, 13 13 }; 14 14 } 15 15 return intlNumberFormat(locales, options);
+3 -3
webpack.config.js
··· 182 182 ], 183 183 }, 184 184 }, 185 - } 185 + }, 186 186 ], 187 187 }, 188 188 { ··· 195 195 type: 'asset/resource', 196 196 generator: { 197 197 filename: 'fonts/[name].[contenthash:8][ext]', 198 - } 198 + }, 199 199 }, 200 200 { 201 201 test: /\.png$/i, 202 202 type: 'asset/resource', 203 203 generator: { 204 204 filename: 'img/webpack/[name].[contenthash:8][ext]', 205 - } 205 + }, 206 206 }, 207 207 ], 208 208 },