From fb5eb1f65572782c170e19b005dfd7f04543c81f Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Fri, 29 Dec 2023 10:33:06 +0100 Subject: [PATCH 001/422] Replace our custom `compression-webpack-plugin` patch with the fixed upstream version (#28510) --- ...-webpack-plugin-npm-6.1.1-3a2a65987e.patch | 22 ---------------- package.json | 2 +- yarn.lock | 25 ++++--------------- 3 files changed, 6 insertions(+), 43 deletions(-) delete mode 100644 .yarn/patches/compression-webpack-plugin-npm-6.1.1-3a2a65987e.patch diff --git a/.yarn/patches/compression-webpack-plugin-npm-6.1.1-3a2a65987e.patch b/.yarn/patches/compression-webpack-plugin-npm-6.1.1-3a2a65987e.patch deleted file mode 100644 index 30d5db2739..0000000000 --- a/.yarn/patches/compression-webpack-plugin-npm-6.1.1-3a2a65987e.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/dist/index.js b/dist/index.js -index 57e375592d984e9a429bcd9f800fa2d15cd662e4..0c47d96df3608e23adfd77d887a8f72abbd501c0 100644 ---- a/dist/index.js -+++ b/dist/index.js -@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", { - }); - exports.default = void 0; - --var _crypto = _interopRequireDefault(require("crypto")); -+var _createHash = _interopRequireDefault(require("webpack/lib/util/createHash")); - - var _path = _interopRequireDefault(require("path")); - -@@ -227,7 +227,7 @@ class CompressionPlugin { - originalAlgorithm: this.options.algorithm, - compressionOptions: this.options.compressionOptions, - name, -- contentHash: _crypto.default.createHash("md4").update(input).digest("hex") -+ contentHash: _createHash.default("md4").update(input).digest("hex") - }; - } else { - cacheData.name = (0, _serializeJavascript.default)({ diff --git a/package.json b/package.json index 39d387d6f4..24832bb596 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "classnames": "^2.3.2", "cocoon-js-vanilla": "^1.3.0", "color-blend": "^4.0.0", - "compression-webpack-plugin": "patch:compression-webpack-plugin@npm%3A6.1.1#~/.yarn/patches/compression-webpack-plugin-npm-6.1.1-3a2a65987e.patch", + "compression-webpack-plugin": "^6.1.2", "core-js": "^3.30.2", "cross-env": "^7.0.3", "css-loader": "^5.2.7", diff --git a/yarn.lock b/yarn.lock index 764faff27a..abc2817039 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2354,7 +2354,7 @@ __metadata: classnames: "npm:^2.3.2" cocoon-js-vanilla: "npm:^1.3.0" color-blend: "npm:^4.0.0" - compression-webpack-plugin: "patch:compression-webpack-plugin@npm%3A6.1.1#~/.yarn/patches/compression-webpack-plugin-npm-6.1.1-3a2a65987e.patch" + compression-webpack-plugin: "npm:^6.1.2" core-js: "npm:^3.30.2" cross-env: "npm:^7.0.3" css-loader: "npm:^5.2.7" @@ -5780,9 +5780,9 @@ __metadata: languageName: node linkType: hard -"compression-webpack-plugin@npm:6.1.1": - version: 6.1.1 - resolution: "compression-webpack-plugin@npm:6.1.1" +"compression-webpack-plugin@npm:^6.1.2": + version: 6.1.2 + resolution: "compression-webpack-plugin@npm:6.1.2" dependencies: cacache: "npm:^15.0.5" find-cache-dir: "npm:^3.3.1" @@ -5791,22 +5791,7 @@ __metadata: webpack-sources: "npm:^1.4.3" peerDependencies: webpack: ^4.0.0 || ^5.0.0 - checksum: 2f2ac6ba8f3cf48b523efc5d8e50e0172f4676f47bf5d62f2365185a6d37e96c2dc090e74f5f30ddf4be092e2400c5c7e1fb34301f3f939acf4c9944e1356525 - languageName: node - linkType: hard - -"compression-webpack-plugin@patch:compression-webpack-plugin@npm%3A6.1.1#~/.yarn/patches/compression-webpack-plugin-npm-6.1.1-3a2a65987e.patch": - version: 6.1.1 - resolution: "compression-webpack-plugin@patch:compression-webpack-plugin@npm%3A6.1.1#~/.yarn/patches/compression-webpack-plugin-npm-6.1.1-3a2a65987e.patch::version=6.1.1&hash=129d4d" - dependencies: - cacache: "npm:^15.0.5" - find-cache-dir: "npm:^3.3.1" - schema-utils: "npm:^3.0.0" - serialize-javascript: "npm:^5.0.1" - webpack-sources: "npm:^1.4.3" - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: 68d130bcf7dcc3fd13a286dc57426640732593db4a2f326a4b159c7c32e856e2752e4d43e5f44dc42d07a0e477ad08c08d9aba029a958ad57e71f06deb42784f + checksum: 966b1417bbeaa55af8d4b7911cf4435a187adbaaff34d3e9f2ef2b7ff747877469ff965d5b653a2211eaecfd0ce8b3c834d3a8f5519aa15dd79e68bbfea0b69e languageName: node linkType: hard From 1cba91d6d116f482d5dd052bd89adb76bf3aa41e Mon Sep 17 00:00:00 2001 From: Santiago Kozak Date: Fri, 29 Dec 2023 06:48:27 -0300 Subject: [PATCH 002/422] Fix reply icon display in picture-in-picture footer (#28519) --- .../mastodon/features/picture_in_picture/components/footer.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx index 9b26e2d753..ed86d19f5c 100644 --- a/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx +++ b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx @@ -179,7 +179,7 @@ class Footer extends ImmutablePureComponent { if (status.get('in_reply_to_id', null) === null) { replyIcon = 'reply'; - replyIconComponent = RepeatIcon; + replyIconComponent = ReplyIcon; replyTitle = intl.formatMessage(messages.reply); } else { replyIcon = 'reply-all'; From f923eeb9b816e92b0c13038a021a5a1ba4766dfa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:11:02 +0100 Subject: [PATCH 003/422] Update dependency sass to v1.69.6 (#28517) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index abc2817039..ff9af41afb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14495,15 +14495,15 @@ __metadata: linkType: hard "sass@npm:^1.62.1": - version: 1.69.5 - resolution: "sass@npm:1.69.5" + version: 1.69.6 + resolution: "sass@npm:1.69.6" dependencies: chokidar: "npm:>=3.0.0 <4.0.0" immutable: "npm:^4.0.0" source-map-js: "npm:>=0.6.2 <2.0.0" bin: sass: sass.js - checksum: a9003a9482f2e467fc412cfe58ba4fa14fb78bef7e1283ce5d64a065f8a31114ec3bbf5d4e724f94eb8512c32c768a6f91f228c7f16a26a300bbf4db293b5608 + checksum: 8153db8e51e74a9007bb54332e14d122c34288c7d21a5f2eaefef753a1b7bb13f35e042dc6247253dab5b1550b05cea27970371e7548286b4f50f23dd1147d89 languageName: node linkType: hard From fb58397a331365086147c858a16f4b80b0ab5281 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 10:11:40 +0000 Subject: [PATCH 004/422] Update dependency axios to v1.6.3 (#28509) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index ff9af41afb..ff7347a2cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4631,13 +4631,13 @@ __metadata: linkType: hard "axios@npm:^1.4.0": - version: 1.6.2 - resolution: "axios@npm:1.6.2" + version: 1.6.3 + resolution: "axios@npm:1.6.3" dependencies: follow-redirects: "npm:^1.15.0" form-data: "npm:^4.0.0" proxy-from-env: "npm:^1.1.0" - checksum: 9b77e030e85e4f9cbcba7bb52fbff67d6ce906c92d213e0bd932346a50140faf83733bf786f55bd58301bd92f9973885c7b87d6348023e10f7eaf286d0791a1d + checksum: dcc6d982353db33e6893ef01cdf81d0a0548dbd8fba0cb046dc4aee1a6a16226721faa4c2a13b2673d47130509629cdb93bb991b3a2bd4ef17a5ac27a8bba0da languageName: node linkType: hard From 851a9b80c8e3b54a71c1655bb63b782ab763f420 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:12:13 +0100 Subject: [PATCH 005/422] Update dependency react-redux-loading-bar to v5.0.7 (#28511) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index ff7347a2cc..c323d1f699 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13614,8 +13614,8 @@ __metadata: linkType: hard "react-redux-loading-bar@npm:^5.0.4": - version: 5.0.5 - resolution: "react-redux-loading-bar@npm:5.0.5" + version: 5.0.7 + resolution: "react-redux-loading-bar@npm:5.0.7" dependencies: prop-types: "npm:^15.7.2" react-lifecycles-compat: "npm:^3.0.4" @@ -13624,7 +13624,7 @@ __metadata: react-dom: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 react-redux: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 redux: ^3.0.0 || ^4.0.0 || ^5.0.0 - checksum: 0dbac046c5b8b6bd209ccfc25ccc55dc9158cd737b42b68fd1900dfe46a59c9c7e2b0082d8901b749e7cf2d7e23074590aae74f350a814f205105f47895a6214 + checksum: 45333093e7d28df923a657ad89ffe4673d7bd135ef57c0143fb4d868f21b57aeb9044691f553f7d2afbcc9080a1f8cd3cec5b274c80cb57faf0e87a70f7a2cce languageName: node linkType: hard From 3f0140bbdf72d045cbf55bcd598a0f2d4a885ce4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 10:13:29 +0000 Subject: [PATCH 006/422] Update dependency webauthn to v3.1.0 (#28507) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9b78ca733e..d78d49165d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -510,7 +510,7 @@ GEM validate_email validate_url webfinger (~> 1.2) - openssl (3.1.0) + openssl (3.2.0) openssl-signature_algorithm (1.3.0) openssl (> 2.0) orm_adapter (0.5.0) @@ -797,7 +797,7 @@ GEM public_suffix warden (1.2.9) rack (>= 2.0.9) - webauthn (3.0.0) + webauthn (3.1.0) android_key_attestation (~> 0.3.0) awrence (~> 1.1) bindata (~> 2.4) From 01df9f1abba4aea07c3934c4c075b1e91799cc13 Mon Sep 17 00:00:00 2001 From: Christian Winther Date: Fri, 29 Dec 2023 11:15:10 +0100 Subject: [PATCH 007/422] install "wget" in streaming Dockerfile (#28497) --- streaming/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/streaming/Dockerfile b/streaming/Dockerfile index 6e0a84771c..241009fe89 100644 --- a/streaming/Dockerfile +++ b/streaming/Dockerfile @@ -69,6 +69,7 @@ RUN \ ca-certificates \ curl \ tzdata \ + wget \ ; # Set /opt/mastodon as working directory @@ -101,4 +102,4 @@ USER mastodon # Expose default Streaming ports EXPOSE 4000 # Run streaming when started -CMD [ node ./streaming/index.js ] \ No newline at end of file +CMD [ node ./streaming/index.js ] From 87e9e87a146fce5fd38cbd2e97d4d0c2038220d7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:15:43 +0100 Subject: [PATCH 008/422] Update eslint (non-major) (#28494) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 140 +++++++++++++++++++++++++++--------------------------- 1 file changed, 71 insertions(+), 69 deletions(-) diff --git a/yarn.lock b/yarn.lock index c323d1f699..18eab4fd07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2585,7 +2585,7 @@ __metadata: languageName: node linkType: hard -"@pkgr/utils@npm:^2.3.1": +"@pkgr/utils@npm:^2.4.2": version: 2.4.2 resolution: "@pkgr/utils@npm:2.4.2" dependencies: @@ -3669,14 +3669,14 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^6.0.0": - version: 6.14.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.14.0" + version: 6.16.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.16.0" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:6.14.0" - "@typescript-eslint/type-utils": "npm:6.14.0" - "@typescript-eslint/utils": "npm:6.14.0" - "@typescript-eslint/visitor-keys": "npm:6.14.0" + "@typescript-eslint/scope-manager": "npm:6.16.0" + "@typescript-eslint/type-utils": "npm:6.16.0" + "@typescript-eslint/utils": "npm:6.16.0" + "@typescript-eslint/visitor-keys": "npm:6.16.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -3689,44 +3689,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 6360efb0e142ed91de5e9bddcd041f769feeedd256332733be08f7a74c8ae637cbfb78c6b85d747c73231bbb95cef95ed2d2854ab7d43aebfbedb3a191f447f1 + checksum: c8a68e0953d8b94f6b85d3a82090e61e670bcb0945cbee4d741321c56db727429ad47c48b8403ad1dab3b0842689bd2d4b85c99b76c51ac4f5be7f5f61c4c314 languageName: node linkType: hard "@typescript-eslint/parser@npm:^6.0.0": - version: 6.14.0 - resolution: "@typescript-eslint/parser@npm:6.14.0" + version: 6.16.0 + resolution: "@typescript-eslint/parser@npm:6.16.0" dependencies: - "@typescript-eslint/scope-manager": "npm:6.14.0" - "@typescript-eslint/types": "npm:6.14.0" - "@typescript-eslint/typescript-estree": "npm:6.14.0" - "@typescript-eslint/visitor-keys": "npm:6.14.0" + "@typescript-eslint/scope-manager": "npm:6.16.0" + "@typescript-eslint/types": "npm:6.16.0" + "@typescript-eslint/typescript-estree": "npm:6.16.0" + "@typescript-eslint/visitor-keys": "npm:6.16.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 0344f7f640374e7e5a5b50e9c90fbd161611b3f455132e541ef9116eef7bd3acf364db64bd38d4b6b4fe148414494620c9df660f8ddce036019c38ae8e146585 + checksum: 9d573d14df4ec661dccaca785223a8a330d64f50a9279ff9170b1da22198ff91b9afa3ee7d3d7127c0cbc148c86831e76b33fc5b47d630799e98940ef666bfe0 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/scope-manager@npm:6.14.0" +"@typescript-eslint/scope-manager@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/scope-manager@npm:6.16.0" dependencies: - "@typescript-eslint/types": "npm:6.14.0" - "@typescript-eslint/visitor-keys": "npm:6.14.0" - checksum: 8c59a215af3d7d24d8d0b21c28a858263de471650829f288a941e0eb8af8a054798da5c7594b7f39370219718270c18464b5edb96f451457e5f080a33ba57c2c + "@typescript-eslint/types": "npm:6.16.0" + "@typescript-eslint/visitor-keys": "npm:6.16.0" + checksum: 3b275e528d19f4f36c4acd6cb872b5f004175512dce30cef0ac7a9121bb23d21e5e0f4b62658dbfea2b15851e7fa930372696f25a6c87492f863171ab56f5364 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/type-utils@npm:6.14.0" +"@typescript-eslint/type-utils@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/type-utils@npm:6.16.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:6.14.0" - "@typescript-eslint/utils": "npm:6.14.0" + "@typescript-eslint/typescript-estree": "npm:6.16.0" + "@typescript-eslint/utils": "npm:6.16.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -3734,59 +3734,60 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 836a6e84be5a245b07c76968c98e2f3bae064767dde720080fe8f33e226188510778dbca4199b7e42ef675ec3fd6d0ab522ec1c77d6e2a9b50e8e275fe7c72c9 + checksum: a5339cc1375d12411fcb242249143b28401fb18890bb2a1cff5275ba946affb4a2066cd8203e83ac383bd9d791a79ea6ee1cbf7a30deed5c832ed002897bbf82 languageName: node linkType: hard -"@typescript-eslint/types@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/types@npm:6.14.0" - checksum: d59306a7a441982a4dcee7d775928fd5086aba9331f7a238f915723a0dc785df0e43af562a30a7c2f1b056a1e49fd64863a8d2450d31706193add0ade87334a4 +"@typescript-eslint/types@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/types@npm:6.16.0" + checksum: 74d9a8b7fd1b85fd1824295c92bc2f506148e450c9897f65ddaa089091017df4e25676c5b098b75c8f00529b84492f303a6b1870bb0ffee83997081325891d53 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.14.0" +"@typescript-eslint/typescript-estree@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.16.0" dependencies: - "@typescript-eslint/types": "npm:6.14.0" - "@typescript-eslint/visitor-keys": "npm:6.14.0" + "@typescript-eslint/types": "npm:6.16.0" + "@typescript-eslint/visitor-keys": "npm:6.16.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" + minimatch: "npm:9.0.3" semver: "npm:^7.5.4" ts-api-utils: "npm:^1.0.1" peerDependenciesMeta: typescript: optional: true - checksum: 767c3309987b8ad053a2403605a9bd7c4eb3283dece864a741a7531a1c28eea4d85acaa4613141b64e194f9f6c4cbc5bc762c9b9f3a67c6202aa8cbb18b180d2 + checksum: c7109e90b40b3c8f1042beb7f1a7a97eeba3b6a903acd82df4947900d68bd31d04b530a190c099666c5ca4886efc162de7b42de754a44b189e41237210797d9e languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.14.0, @typescript-eslint/utils@npm:^6.5.0": - version: 6.14.0 - resolution: "@typescript-eslint/utils@npm:6.14.0" +"@typescript-eslint/utils@npm:6.16.0, @typescript-eslint/utils@npm:^6.5.0": + version: 6.16.0 + resolution: "@typescript-eslint/utils@npm:6.16.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:6.14.0" - "@typescript-eslint/types": "npm:6.14.0" - "@typescript-eslint/typescript-estree": "npm:6.14.0" + "@typescript-eslint/scope-manager": "npm:6.16.0" + "@typescript-eslint/types": "npm:6.16.0" + "@typescript-eslint/typescript-estree": "npm:6.16.0" semver: "npm:^7.5.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 72689b2897b89e1bd1c71c1c2ae436d0ccfbcfffabf3be4378de74ad8138b2ecdbeeda7c1720e2f1754569e773f2fc7216f704335e1e56c38c7601ee1d190aeb + checksum: 586c4c0e1ca249daf9958f0d88df3af010a7592a19db1a7dc198754542b584314896536fe56ea9c93dd0ddd531154e7697002643d46e24a8d3a459721a626e91 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.14.0" +"@typescript-eslint/visitor-keys@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.16.0" dependencies: - "@typescript-eslint/types": "npm:6.14.0" + "@typescript-eslint/types": "npm:6.16.0" eslint-visitor-keys: "npm:^3.4.1" - checksum: 0e2363f9f1986ebdb41507c54a666fa1c336eb6beb383dc342a10844d3c42c89067b21c3f158851fa6f0825e1e451a5470b5454fde70a6fc33b4b0259462d954 + checksum: 13c4d90355e288eac432d2845e37bb2acc03dab6d8568564558c1914a9aa44352f2a7ff29d0f50e0b3e68d66cca5f27b2732af5ff193b82571b4366309842880 languageName: node linkType: hard @@ -7406,21 +7407,22 @@ __metadata: linkType: hard "eslint-plugin-prettier@npm:^5.0.0": - version: 5.0.1 - resolution: "eslint-plugin-prettier@npm:5.0.1" + version: 5.1.2 + resolution: "eslint-plugin-prettier@npm:5.1.2" dependencies: prettier-linter-helpers: "npm:^1.0.0" - synckit: "npm:^0.8.5" + synckit: "npm:^0.8.6" peerDependencies: "@types/eslint": ">=8.0.0" eslint: ">=8.0.0" + eslint-config-prettier: "*" prettier: ">=3.0.0" peerDependenciesMeta: "@types/eslint": optional: true eslint-config-prettier: optional: true - checksum: 08e2c7bed93d9f7c86e9aa0bd4f5cc51f65233a446ddfda11e821f12819e1e4be62cfbc2a4e17169c76fded1c4de7371e37e5f2525e81695decaf6c652a41fb0 + checksum: e16c9fbb0e9f8da45bdbb1cf6e4a190266235c3686deede3815196d2604bbe2bac531d1fc9adc3c0b9a03d88b55bd3bfaa4f9d85e34e73dc040d545a1931fab9 languageName: node linkType: hard @@ -11423,6 +11425,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:9.0.3, minimatch@npm:^9.0.1": + version: 9.0.3 + resolution: "minimatch@npm:9.0.3" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac + languageName: node + linkType: hard + "minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -11441,15 +11452,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.1": - version: 9.0.3 - resolution: "minimatch@npm:9.0.3" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac - languageName: node - linkType: hard - "minimist@npm:^1.2.0, minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" @@ -15782,13 +15784,13 @@ __metadata: languageName: node linkType: hard -"synckit@npm:^0.8.5": - version: 0.8.5 - resolution: "synckit@npm:0.8.5" +"synckit@npm:^0.8.6": + version: 0.8.6 + resolution: "synckit@npm:0.8.6" dependencies: - "@pkgr/utils": "npm:^2.3.1" - tslib: "npm:^2.5.0" - checksum: 9827f828cabc404b3a147c38f824c8d5b846eb6f65189d965aa0b71ea8ecda5048f8f50b4bdfd8813148844175233cff56c6bc8d87a7118cf10707df870519f4 + "@pkgr/utils": "npm:^2.4.2" + tslib: "npm:^2.6.2" + checksum: 200528062e3915a0190a4c6b1e01436fcfdf812e2e8d977746746f3998bb4182d758af760e51b06a64f8323e705735aff7b4b3efc4a0ab5f75eaccc044a8cfcc languageName: node linkType: hard @@ -16126,7 +16128,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2.6.2, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.0": +"tslib@npm:2.6.2, tslib@npm:^2.4.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: e03a8a4271152c8b26604ed45535954c0a45296e32445b4b87f8a5abdb2421f40b59b4ca437c4346af0f28179780d604094eb64546bee2019d903d01c6c19bdb From 07ab97d7f9d9c5c77f75fd3d1d120cf47d79eaa3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 10:16:00 +0000 Subject: [PATCH 009/422] Update dependency rubocop-rails to v2.23.1 (#28493) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index d78d49165d..68540e049c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -682,7 +682,7 @@ GEM rubocop-performance (1.20.0) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rails (2.23.0) + rubocop-rails (2.23.1) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) From de3fa293b07fc91272ad675e5f12fe4f051bfcd9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:16:26 +0100 Subject: [PATCH 010/422] Update dependency fastimage to v2.3.0 (#28488) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 68540e049c..ac186ab542 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -301,7 +301,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fast_blank (1.0.1) - fastimage (2.2.7) + fastimage (2.3.0) ffi (1.15.5) ffi-compiler (1.0.1) ffi (>= 1.0.0) From 3fbfc50f178bd04e794404f4552d98021b468693 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:17:31 +0100 Subject: [PATCH 011/422] Update dependency brakeman to v6.1.1 (#28487) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index ac186ab542..722e13d27b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -175,7 +175,8 @@ GEM blurhash (0.1.7) bootsnap (1.17.0) msgpack (~> 1.2) - brakeman (6.1.0) + brakeman (6.1.1) + racc browser (5.3.1) brpoplpush-redis_script (0.1.3) concurrent-ruby (~> 1.0, >= 1.0.5) From f6f85b9521a84e3c07a84bf8eb4351e4430c2f45 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:19:41 +0100 Subject: [PATCH 012/422] Update dependency aws-sdk-s3 to v1.142.0 (#28479) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 722e13d27b..954a4fe35a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -131,16 +131,16 @@ GEM attr_required (1.0.1) awrence (1.2.1) aws-eventstream (1.3.0) - aws-partitions (1.860.0) - aws-sdk-core (3.189.0) + aws-partitions (1.873.0) + aws-sdk-core (3.190.1) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.74.0) + aws-sdk-kms (1.75.0) aws-sdk-core (~> 3, >= 3.188.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.141.0) + aws-sdk-s3 (1.142.0) aws-sdk-core (~> 3, >= 3.189.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.8) From b01a027543cc80176574ffd0af0ba96f6e3eca96 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:19:56 +0100 Subject: [PATCH 013/422] Update dependency tzinfo-data to v1.2023.4 (#28478) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 954a4fe35a..81b4e14beb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -783,7 +783,7 @@ GEM unf (~> 0.1.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - tzinfo-data (1.2023.3) + tzinfo-data (1.2023.4) tzinfo (>= 1.0.0) unf (0.1.4) unf_ext From 87bf85ffdd75a59d0c4527052d160b3e858e3777 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:20:34 +0100 Subject: [PATCH 014/422] Update dependency classnames to v2.5.0 (#28498) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 18eab4fd07..c0515de13f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5531,9 +5531,9 @@ __metadata: linkType: hard "classnames@npm:^2.2.5, classnames@npm:^2.3.2": - version: 2.3.2 - resolution: "classnames@npm:2.3.2" - checksum: cd50ead57b4f97436aaa9f9885c6926323efc7c2bea8e3d4eb10e4e972aa6a1cfca1c7a0e06f8a199ca7498d4339e30bb6002e589e61c9f21248cbf3e8b0b18d + version: 2.5.0 + resolution: "classnames@npm:2.5.0" + checksum: f10a5b07db7fda8eb77f701f795b7006f3de86a723ec62cc10f4d82b4195fc65a578bbf91c47675b8c6fcb2921b903bfea5c670bdb43513e454daa6c2e9738b3 languageName: node linkType: hard From f7f7236fa235fd5541df164d847e1be18e58788b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 10:21:19 +0000 Subject: [PATCH 015/422] Update dependency ws to v8.16.0 (#28504) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c0515de13f..9cdeb1d7f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17496,8 +17496,8 @@ __metadata: linkType: hard "ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.14.2": - version: 8.15.1 - resolution: "ws@npm:8.15.1" + version: 8.16.0 + resolution: "ws@npm:8.16.0" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -17506,7 +17506,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 9964360dd5ab35c7376bd7c4295a3c8bd44ea0838c9413742548a6fb3ec371fc6c18552d5b8e76bdc21536db1909765612815bae072674b5ec69971605395a96 + checksum: a7783bb421c648b1e622b423409cb2a58ac5839521d2f689e84bc9dc41d59379c692dd405b15a997ea1d4c0c2e5314ad707332d0c558f15232d2bc07c0b4618a languageName: node linkType: hard From 63901bb34babd4923546375d1fae42daa76dfd0d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:22:43 +0100 Subject: [PATCH 016/422] Update github/codeql-action action to v3 (#28495) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3b40c3fd07..6fb93b7fef 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -31,7 +31,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -44,7 +44,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -57,6 +57,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: '/language:${{matrix.language}}' From 128c5b7db3ce6eef59fb6f575514c45086bf6c53 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 29 Dec 2023 05:23:30 -0500 Subject: [PATCH 017/422] Fix `Performance/StringIdentifierArgument` cop (#28508) --- app/models/concerns/remotable.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index 6118e204a1..8382c91599 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -46,7 +46,7 @@ module Remotable public_send(:"download_#{attachment_name}!", url) if download_on_assign end - alias_method(:"reset_#{attachment_name}!", "download_#{attachment_name}!") + alias_method(:"reset_#{attachment_name}!", :"download_#{attachment_name}!") end end end From 54ed01538e33874468bbdc768fcc80fcee302927 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:25:31 +0100 Subject: [PATCH 018/422] Update dependency core-js to v3.35.0 (#28518) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9cdeb1d7f4..1baa0da058 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5914,9 +5914,9 @@ __metadata: linkType: hard "core-js@npm:^3.30.2": - version: 3.34.0 - resolution: "core-js@npm:3.34.0" - checksum: 408a77898abe03bf3e5dec2a451c36f4745081cca9022f8bdf9b817d57bb6d3a534d555f47a4b95e1daa5e21dbc79122eac2402e25720d425f5925127e55dcd8 + version: 3.35.0 + resolution: "core-js@npm:3.35.0" + checksum: 1d545ff4406f2afa5e681f44b45ed5f7f119d158b380234d5aa7787ce7e47fc7a635b98b74c28c766ba8191e3db8c2316ad6ab4ff1ddecbc3fd618413a52c29c languageName: node linkType: hard From 5fd16c3ffd86e0eba436714a35e60015328472e0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:27:37 +0100 Subject: [PATCH 019/422] Update dependency nokogiri to v1.16.0 (#28513) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 81b4e14beb..5acee3d753 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -482,7 +482,7 @@ GEM net-smtp (0.4.0) net-protocol nio4r (2.5.9) - nokogiri (1.15.5) + nokogiri (1.16.0) mini_portile2 (~> 2.8.2) racc (~> 1.4) oj (3.16.3) From 7df9c4f6f3ae717a5b293ce36d4443f2a4d8492e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:39:10 +0100 Subject: [PATCH 020/422] New Crowdin Translations (automated) (#28481) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/bg.json | 2 + app/javascript/mastodon/locales/ca.json | 2 +- app/javascript/mastodon/locales/el.json | 8 + app/javascript/mastodon/locales/eo.json | 16 ++ app/javascript/mastodon/locales/es-AR.json | 4 +- app/javascript/mastodon/locales/et.json | 2 + app/javascript/mastodon/locales/fa.json | 4 +- app/javascript/mastodon/locales/fi.json | 2 +- app/javascript/mastodon/locales/gl.json | 2 + app/javascript/mastodon/locales/he.json | 2 +- app/javascript/mastodon/locales/ie.json | 8 + app/javascript/mastodon/locales/is.json | 2 + app/javascript/mastodon/locales/kk.json | 1 + app/javascript/mastodon/locales/ko.json | 6 +- app/javascript/mastodon/locales/lad.json | 3 + app/javascript/mastodon/locales/nn.json | 3 + app/javascript/mastodon/locales/no.json | 7 +- app/javascript/mastodon/locales/ru.json | 2 + app/javascript/mastodon/locales/sk.json | 4 +- app/javascript/mastodon/locales/sr-Latn.json | 2 + app/javascript/mastodon/locales/sr.json | 1 + app/javascript/mastodon/locales/th.json | 3 +- app/javascript/mastodon/locales/uk.json | 1 + app/javascript/mastodon/locales/vi.json | 2 + config/locales/activerecord.ie.yml | 48 +++++ config/locales/devise.ie.yml | 37 ++++ config/locales/devise.ko.yml | 2 +- config/locales/doorkeeper.ie.yml | 146 ++++++++++++++ config/locales/eo.yml | 39 ++++ config/locales/ie.yml | 188 ++++++++++++++++++- config/locales/lad.yml | 92 +++++++++ config/locales/simple_form.fa.yml | 2 +- config/locales/simple_form.ie.yml | 112 +++++++++++ config/locales/simple_form.lad.yml | 34 ++++ config/locales/sk.yml | 27 +++ 35 files changed, 800 insertions(+), 16 deletions(-) diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 8a6d6040d6..7ee3c868ae 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Няма публикации", "account.featured_tags.title": "Главни хаштагове на {name}", "account.follow": "Последване", + "account.follow_back": "Последване взаимно", "account.followers": "Последователи", "account.followers.empty": "Още никой не следва потребителя.", "account.followers_counter": "{count, plural, one {{counter} последовател} other {{counter} последователи}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Заглушаване на известията", "account.mute_short": "Заглушаване", "account.muted": "Заглушено", + "account.mutual": "Взаимни", "account.no_bio": "Няма представен опис.", "account.open_original_page": "Отваряне на първообразната страница", "account.posts": "Публикации", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 86f1fb4765..290b364a52 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -32,7 +32,7 @@ "account.featured_tags.last_status_never": "No hi ha tuts", "account.featured_tags.title": "etiquetes destacades de {name}", "account.follow": "Segueix", - "account.follow_back": "Segueix", + "account.follow_back": "Segueix tu també", "account.followers": "Seguidors", "account.followers.empty": "A aquest usuari encara no el segueix ningú.", "account.followers_counter": "{count, plural, one {{counter} seguidor} other {{counter} Seguidors}}", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 83a986ba4e..17a0c9d4da 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -17,9 +17,11 @@ "account.badges.group": "Ομάδα", "account.block": "Αποκλεισμός @{name}", "account.block_domain": "Αποκλεισμός τομέα {domain}", + "account.block_short": "Αποκλεισμός", "account.blocked": "Αποκλεισμένος/η", "account.browse_more_on_origin_server": "Δες περισσότερα στο αρχικό προφίλ", "account.cancel_follow_request": "Απόσυρση αιτήματος παρακολούθησης", + "account.copy": "Αντιγραφή συνδέσμου προφίλ", "account.direct": "Ιδιωτική αναφορά @{name}", "account.disable_notifications": "Σταμάτα να με ειδοποιείς όταν δημοσιεύει ο @{name}", "account.domain_blocked": "Ο τομέας αποκλείστηκε", @@ -30,6 +32,7 @@ "account.featured_tags.last_status_never": "Καμία ανάρτηση", "account.featured_tags.title": "προβεβλημένες ετικέτες του/της {name}", "account.follow": "Ακολούθησε", + "account.follow_back": "Ακολούθησε και εσύ", "account.followers": "Ακόλουθοι", "account.followers.empty": "Κανείς δεν ακολουθεί αυτόν τον χρήστη ακόμα.", "account.followers_counter": "{count, plural, one {{counter} Ακόλουθος} other {{counter} Ακόλουθοι}}", @@ -47,7 +50,11 @@ "account.mention": "Ανάφερε @{name}", "account.moved_to": "Ο/Η {name} έχει υποδείξει ότι ο νέος λογαριασμός του/της είναι τώρα:", "account.mute": "Σώπασε τον @{name}", + "account.mute_notifications_short": "Σίγαση ειδοποιήσεων", + "account.mute_short": "Σίγαση", "account.muted": "Αποσιωπημένος/η", + "account.mutual": "Αμοιβαίοι", + "account.no_bio": "Δεν υπάρχει περιγραφή.", "account.open_original_page": "Ανοικτό", "account.posts": "Τουτ", "account.posts_with_replies": "Τουτ και απαντήσεις", @@ -63,6 +70,7 @@ "account.unendorse": "Να μην παρέχεται στο προφίλ", "account.unfollow": "Άρση ακολούθησης", "account.unmute": "Διακοπή σίγασης @{name}", + "account.unmute_notifications_short": "Σίγαση ειδοποιήσεων", "account.unmute_short": "Κατάργηση σίγασης", "account_note.placeholder": "Κάνε κλικ για να προσθέσεις σημείωση", "admin.dashboard.daily_retention": "Ποσοστό χρηστών που παραμένουν μετά την εγγραφή, ανά ημέρα", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 4daa699dcf..643329ba99 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Neniu afiŝo", "account.featured_tags.title": "Rekomendataj kradvortoj de {name}", "account.follow": "Sekvi", + "account.follow_back": "Sekvu reen", "account.followers": "Sekvantoj", "account.followers.empty": "Ankoraŭ neniu sekvas ĉi tiun uzanton.", "account.followers_counter": "{count, plural, one{{counter} Sekvanto} other {{counter} Sekvantoj}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Silentigu Sciigojn", "account.mute_short": "Silentigu", "account.muted": "Silentigita", + "account.mutual": "Reciproka", "account.no_bio": "Neniu priskribo estas provizita.", "account.open_original_page": "Malfermi la originalan paĝon", "account.posts": "Afiŝoj", @@ -509,6 +511,8 @@ "onboarding.tips.2fa": "Ĉu vi scias? Vi povas sekurigi vian konton per efektivigi dufaktora autentigo en via kontoagordoj.", "onboarding.tips.accounts_from_other_servers": "Ĉu vi scias? Ĉar Mastodon estas sencentra, kelkaj profiloj kiujn vi trovi estas gastigitaj ĉe aliaj serviloj kiuj ne estas via.", "onboarding.tips.migration": "Ĉu vi scias? Se vi sentas ke {domain} ne estas bona servilelekto por vi en la estonteco, vi povas translokiĝi al alia servilo de Mastodon sen malgajni viajn sekvantojn.", + "onboarding.tips.verification": "Ĉu vi sciis? Vi povas kontroli vian konton metante ligilon al via Mastodon-profilo en via propra retejo kaj aldonante la retejon al via profilo. Neniuj kotizoj aŭ dokumentoj necesaj!", + "password_confirmation.exceeds_maxlength": "Pasvorto-konfirmo superas la maksimuman pasvortan longon", "password_confirmation.mismatching": "Pasvorto konfirmo ne kongruas", "picture_in_picture.restore": "Remetu ĝin", "poll.closed": "Finita", @@ -532,6 +536,7 @@ "privacy.unlisted.short": "Nelistigita", "privacy_policy.last_updated": "Laste ĝisdatigita en {date}", "privacy_policy.title": "Politiko de privateco", + "recommended": "Rekomendita", "refresh": "Refreŝigu", "regeneration_indicator.label": "Ŝargado…", "regeneration_indicator.sublabel": "Via abonfluo estas preparata!", @@ -549,6 +554,7 @@ "reply_indicator.cancel": "Nuligi", "report.block": "Bloki", "report.block_explanation": "Vi ne vidos iliajn afiŝojn. Ili ne povos vidi viajn afiŝojn, nek sekvi vin. Ili ne scios, ke vi blokas ilin.", + "report.categories.legal": "Laŭleĝa", "report.categories.other": "Aliaj", "report.categories.spam": "Trudmesaĝo", "report.categories.violation": "Enhavo malobservas unu aŭ plurajn servilajn regulojn", @@ -587,6 +593,7 @@ "report.unfollow": "Malsekvi @{name}", "report.unfollow_explanation": "Vi sekvas ĉi tiun konton. Por ne plu vidi ĝiajn afiŝojn en via hejma templinio, ĉesu sekvi ĝin.", "report_notification.attached_statuses": "{count, plural, one {{count} afiŝo almetita} other {{count} afiŝoj almetitaj}}", + "report_notification.categories.legal": "Laŭleĝa", "report_notification.categories.other": "Alia", "report_notification.categories.spam": "Trudmesaĝo", "report_notification.categories.violation": "Malobservo de la regulo", @@ -599,13 +606,19 @@ "search.quick_action.open_url": "Malfermi URL en Mastodono", "search.quick_action.status_search": "Afiŝoj kiuj kongruas kun {x}", "search.search_or_paste": "Serĉu aŭ algluu URL-on", + "search_popout.full_text_search_disabled_message": "Ne havebla sur {domain}.", + "search_popout.full_text_search_logged_out_message": "Disponebla nur kiam ensalutinte.", + "search_popout.language_code": "ISO-lingva kodo", + "search_popout.options": "Serĉaj opcioj", "search_popout.quick_actions": "Rapidaj agoj", "search_popout.recent": "Lastaj serĉoj", + "search_popout.specific_date": "specifa dato", "search_popout.user": "uzanto", "search_results.accounts": "Profiloj", "search_results.all": "Ĉiuj", "search_results.hashtags": "Kradvortoj", "search_results.nothing_found": "Povis trovi nenion por ĉi tiuj serĉaj terminoj", + "search_results.see_all": "Vidu ĉiujn", "search_results.statuses": "Afiŝoj", "search_results.title": "Serĉ-rezultoj por {q}", "server_banner.about_active_users": "Personoj uzantaj ĉi tiun servilon dum la lastaj 30 tagoj (Aktivaj Uzantoj Monate)", @@ -616,6 +629,8 @@ "server_banner.server_stats": "Statistikoj de la servilo:", "sign_in_banner.create_account": "Krei konton", "sign_in_banner.sign_in": "Saluti", + "sign_in_banner.sso_redirect": "Ensalutu aŭ Registriĝi", + "sign_in_banner.text": "Ensalutu por sekvi profilojn aŭ haŝetikedojn, ŝatatajn, dividi kaj respondi afiŝojn. Vi ankaŭ povas interagi de via konto sur alia servilo.", "status.admin_account": "Malfermi fasadon de moderigado por @{name}", "status.admin_domain": "Malfermu moderigan interfacon por {domain}", "status.admin_status": "Malfermi ĉi tiun mesaĝon en la kontrola interfaco", @@ -632,6 +647,7 @@ "status.edited": "Redaktita {date}", "status.edited_x_times": "Redactita {count, plural, one {{count} fojon} other {{count} fojojn}}", "status.embed": "Enkorpigi", + "status.favourite": "Ŝatata", "status.filter": "Filtri ĉi tiun afiŝon", "status.filtered": "Filtrita", "status.hide": "Kaŝi mesaĝon", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index eb6c0f3e4f..7c2e4f0d49 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -32,7 +32,7 @@ "account.featured_tags.last_status_never": "Sin mensajes", "account.featured_tags.title": "Etiquetas destacadas de {name}", "account.follow": "Seguir", - "account.follow_back": "Seguir también", + "account.follow_back": "Seguir", "account.followers": "Seguidores", "account.followers.empty": "Todavía nadie sigue a este usuario.", "account.followers_counter": "{count, plural, one {{counter} seguidor} other {{counter} seguidores}}", @@ -53,7 +53,7 @@ "account.mute_notifications_short": "Silenciar notificaciones", "account.mute_short": "Silenciar", "account.muted": "Silenciado", - "account.mutual": "Mutuo", + "account.mutual": "Seguimiento mutuo", "account.no_bio": "Sin descripción provista.", "account.open_original_page": "Abrir página original", "account.posts": "Mensajes", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index c397334109..26657d402e 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Postitusi pole", "account.featured_tags.title": "{name} esiletõstetud sildid", "account.follow": "Jälgi", + "account.follow_back": "Jälgi vastu", "account.followers": "Jälgijad", "account.followers.empty": "Keegi ei jälgi veel seda kasutajat.", "account.followers_counter": "{count, plural, one {{counter} jälgija} other {{counter} jälgijat}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Vaigista teavitused", "account.mute_short": "Vaigista", "account.muted": "Vaigistatud", + "account.mutual": "Ühine", "account.no_bio": "Kirjeldust pole lisatud.", "account.open_original_page": "Ava algne leht", "account.posts": "Postitused", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index a93d0f6617..9f3201ca78 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -13,7 +13,7 @@ "about.rules": "قوانین کارساز", "account.account_note_header": "یادداشت", "account.add_or_remove_from_list": "افزودن یا برداشتن از سیاهه‌ها", - "account.badges.bot": "روبات", + "account.badges.bot": "خودکار", "account.badges.group": "گروه", "account.block": "انسداد ‎@{name}", "account.block_domain": "انسداد دامنهٔ {domain}", @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "بدون فرسته", "account.featured_tags.title": "برچسب‌های برگزیدهٔ {name}", "account.follow": "پی‌گرفتن", + "account.follow_back": "دنبال کردن متقابل", "account.followers": "پی‌گیرندگان", "account.followers.empty": "هنوز کسی پی‌گیر این کاربر نیست.", "account.followers_counter": "{count, plural, one {{counter} پی‌گیرنده} other {{counter} پی‌گیرنده}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "خموشی آگاهی‌ها", "account.mute_short": "خموشی", "account.muted": "خموش", + "account.mutual": "دوطرفه", "account.no_bio": "شرحی فراهم نشده.", "account.open_original_page": "گشودن صفحهٔ اصلی", "account.posts": "فرسته", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index dab7eac1e9..004898651b 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -607,7 +607,7 @@ "search.quick_action.status_search": "Julkaisut haulla {x}", "search.search_or_paste": "Hae tai liitä URL-osoite", "search_popout.full_text_search_disabled_message": "Ei saatavilla palvelimella {domain}.", - "search_popout.full_text_search_logged_out_message": "Saatavilla vain sisäänkirjautuneena.", + "search_popout.full_text_search_logged_out_message": "Käytettävissä vain sisäänkirjautuneena.", "search_popout.language_code": "ISO-kielikoodi", "search_popout.options": "Hakuvalinnat", "search_popout.quick_actions": "Pikatoiminnot", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index bfd20a4673..48bbb6b307 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Sen publicacións", "account.featured_tags.title": "Cancelos destacados de {name}", "account.follow": "Seguir", + "account.follow_back": "Seguir tamén", "account.followers": "Seguidoras", "account.followers.empty": "Aínda ninguén segue esta usuaria.", "account.followers_counter": "{count, plural, one {{counter} Seguidora} other {{counter} Seguidoras}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Silenciar notificacións", "account.mute_short": "Acalar", "account.muted": "Acalada", + "account.mutual": "Mutuo", "account.no_bio": "Sen descrición.", "account.open_original_page": "Abrir páxina orixinal", "account.posts": "Publicacións", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 658e16b856..6758457273 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -32,7 +32,7 @@ "account.featured_tags.last_status_never": "אין חצרוצים", "account.featured_tags.title": "התגיות המועדפות של {name}", "account.follow": "לעקוב", - "account.follow_back": "החזרת עוקב", + "account.follow_back": "לעקוב בחזרה", "account.followers": "עוקבים", "account.followers.empty": "אף אחד לא עוקב אחר המשתמש הזה עדיין.", "account.followers_counter": "{count, plural,one {עוקב אחד} other {{counter} עוקבים}}", diff --git a/app/javascript/mastodon/locales/ie.json b/app/javascript/mastodon/locales/ie.json index a7cf1caab4..0344470edf 100644 --- a/app/javascript/mastodon/locales/ie.json +++ b/app/javascript/mastodon/locales/ie.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Null postas", "account.featured_tags.title": "Recomandat hashtags de {name}", "account.follow": "Sequer", + "account.follow_back": "Sequer reciprocmen", "account.followers": "Sequitores", "account.followers.empty": "Ancor nequi seque ti-ci usator.", "account.followers_counter": "{count, plural, one {{counter} Sequitor} other {{counter} Sequitor}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Silentiar notificationes", "account.mute_short": "Silentiar", "account.muted": "Silentiat", + "account.mutual": "Reciproc", "account.no_bio": "Null descrition providet.", "account.open_original_page": "Aperter li págine original", "account.posts": "Postas", @@ -191,7 +193,9 @@ "conversation.mark_as_read": "Marcar quam leet", "conversation.open": "Vider conversation", "conversation.with": "Con {names}", + "copy_icon_button.copied": "Copiat al Paperiere", "copypaste.copied": "Copiat", + "copypaste.copy_to_clipboard": "Copiar al Paperiere", "directory.federated": "Del conosset fediverse", "directory.local": "De solmen {domain}", "directory.new_arrivals": "Nov arivantes", @@ -280,6 +284,7 @@ "footer.directory": "Profilarium", "footer.get_app": "Obtener li aplication", "footer.invite": "Invitar gente", + "footer.keyboard_shortcuts": "Rapid-tastes", "footer.privacy_policy": "Politica pri privatie", "footer.source_code": "Vider li fonte-code", "footer.status": "Statu", @@ -342,7 +347,9 @@ "keyboard_shortcuts.favourite": "Favoritisar posta", "keyboard_shortcuts.favourites": "Aperter li liste de favorites", "keyboard_shortcuts.federated": "Aperter li federat témpor-linea", + "keyboard_shortcuts.heading": "Rapid-tastes", "keyboard_shortcuts.home": "Aperter li hemal témpor-linea", + "keyboard_shortcuts.hotkey": "Rapid clave", "keyboard_shortcuts.local": "Aperter li local témpor-linea", "keyboard_shortcuts.mention": "Mentionar li autor", "keyboard_shortcuts.muted": "Aperter li lista de silentiat usatores", @@ -599,6 +606,7 @@ "search.search_or_paste": "Serchar o glutinar URL", "search_popout.full_text_search_disabled_message": "Ne disponibil che {domain}.", "search_popout.full_text_search_logged_out_message": "Solmen disponibil con session initiat.", + "search_popout.language_code": "Code de lingue ISO", "search_popout.options": "Sercha-parametres", "search_popout.quick_actions": "Rapid actiones", "search_popout.recent": "Recent serchas", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index 46e83b4dbf..fb839503e9 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Engar færslur", "account.featured_tags.title": "Myllumerki hjá {name} með aukið vægi", "account.follow": "Fylgjast með", + "account.follow_back": "Fylgjast með til baka", "account.followers": "Fylgjendur", "account.followers.empty": "Ennþá fylgist enginn með þessum notanda.", "account.followers_counter": "{count, plural, one {Fylgjandi: {counter}} other {Fylgjendur: {counter}}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Þagga í tilkynningum", "account.mute_short": "Þagga niður", "account.muted": "Þaggaður", + "account.mutual": "Sameiginlegir", "account.no_bio": "Engri lýsingu útvegað.", "account.open_original_page": "Opna upprunalega síðu", "account.posts": "Færslur", diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json index e0e047ba14..97b1991803 100644 --- a/app/javascript/mastodon/locales/kk.json +++ b/app/javascript/mastodon/locales/kk.json @@ -17,6 +17,7 @@ "account.badges.group": "Топ", "account.block": "@{name} дегенді бұғаттау", "account.block_domain": "{domain} доменін бұғаттау", + "account.block_short": "Бұғаттау", "account.blocked": "Бұғатталған", "account.browse_more_on_origin_server": "Бастапқы профильден шолу", "account.cancel_follow_request": "Withdraw follow request", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 5746ab67a5..264781baa3 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -240,7 +240,7 @@ "empty_column.follow_requests": "아직 팔로우 요청이 없습니다. 요청을 받았을 때 여기에 나타납니다.", "empty_column.followed_tags": "아직 아무 해시태그도 팔로우하고 있지 않습니다. 해시태그를 팔로우하면, 여기에 표시됩니다.", "empty_column.hashtag": "이 해시태그는 아직 사용되지 않았습니다.", - "empty_column.home": "당신의 홈 타임라인은 비어있습니다! 더 많은 사람을 팔로우하여 채워보세요. {suggestions}", + "empty_column.home": "당신의 홈 타임라인은 비어있습니다! 더 많은 사람을 팔로우하여 채워보세요.", "empty_column.list": "리스트에 아직 아무것도 없습니다. 리스트의 누군가가 게시물을 올리면 여기에 나타납니다.", "empty_column.lists": "아직 리스트가 없습니다. 리스트를 만들면 여기에 나타납니다.", "empty_column.mutes": "아직 아무도 뮤트하지 않았습니다.", @@ -659,7 +659,7 @@ "status.media_hidden": "미디어 숨겨짐", "status.mention": "@{name} 님에게 멘션", "status.more": "자세히", - "status.mute": "@{name} 님을 뮤트하기", + "status.mute": "@{name} 뮤트", "status.mute_conversation": "이 대화를 뮤트", "status.open": "상세 정보 표시", "status.pin": "고정", @@ -674,7 +674,7 @@ "status.replied_to": "{name} 님에게", "status.reply": "답장", "status.replyAll": "글타래에 답장", - "status.report": "{name} 님을 신고하기", + "status.report": "@{name} 신고하기", "status.sensitive_warning": "민감한 내용", "status.share": "공유", "status.show_filter_reason": "그냥 표시하기", diff --git a/app/javascript/mastodon/locales/lad.json b/app/javascript/mastodon/locales/lad.json index c54ed2a7e9..ce6cb56473 100644 --- a/app/javascript/mastodon/locales/lad.json +++ b/app/javascript/mastodon/locales/lad.json @@ -482,12 +482,14 @@ "onboarding.profile.discoverable": "Faz ke mi profil apareska en bushkedas", "onboarding.profile.display_name": "Nombre amostrado", "onboarding.profile.display_name_hint": "Tu nombre para amostrar.", + "onboarding.profile.lead": "Siempre puedes kompletar esto mas tadre en las preferensyas, ande tambien ay mas opsyones de personalizasyon.", "onboarding.profile.note": "Tu deskripsyon", "onboarding.profile.note_hint": "Puedes @enmentar a otra djente o #etiketas…", "onboarding.profile.save_and_continue": "Guadra i kontinua", "onboarding.profile.title": "Konfigurasyon de profil", "onboarding.profile.upload_avatar": "Karga imaje de profil", "onboarding.profile.upload_header": "Karga kavesera de profil", + "onboarding.share.lead": "Informe a otros komo toparte en Mastodon!", "onboarding.share.message": "Soy {username} en #Mastodon! Segidme en {url}", "onboarding.share.next_steps": "Posivles sigientes pasos:", "onboarding.share.title": "Partaja tu profil", @@ -497,6 +499,7 @@ "onboarding.steps.follow_people.title": "Personaliza tu linya prinsipala", "onboarding.steps.publish_status.title": "Eskrive tu primera publikasyon", "onboarding.steps.setup_profile.title": "Personaliza tu profil", + "onboarding.steps.share_profile.body": "Informe a tus amigos komo toparte en Mastodon", "onboarding.steps.share_profile.title": "Partaja tu profil de Mastodon", "picture_in_picture.restore": "Restora", "poll.closed": "Serrado", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index 3ef2f80eaf..e5b1d2b378 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -482,6 +482,7 @@ "onboarding.follows.empty": "Me kan ikkje visa deg nokon resultat no. Du kan prøva å søkja eller bla gjennom utforsk-sida for å finna folk å fylgja, eller du kan prøva att seinare.", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Popular on Mastodon", + "onboarding.profile.discoverable": "Gjør min profil synlig", "onboarding.profile.display_name": "Synleg namn", "onboarding.profile.display_name_hint": "Det fulle namnet eller kallenamnet ditt…", "onboarding.profile.lead": "Du kan alltid fullføra dette seinare i innstillingane, og der er det endå fleire tilpassingsalternativ.", @@ -534,6 +535,7 @@ "privacy.unlisted.short": "Uoppført", "privacy_policy.last_updated": "Sist oppdatert {date}", "privacy_policy.title": "Personvernsreglar", + "recommended": "Anbefalt", "refresh": "Oppdater", "regeneration_indicator.label": "Lastar…", "regeneration_indicator.sublabel": "Heimetidslina di vert førebudd!", @@ -604,6 +606,7 @@ "search.quick_action.status_search": "Innlegg som samsvarer med {x}", "search.search_or_paste": "Søk eller lim inn URL", "search_popout.full_text_search_disabled_message": "Ikkje tilgjengeleg på {domain}.", + "search_popout.full_text_search_logged_out_message": "Bare tilgjengelig ved innlogging.", "search_popout.language_code": "ISO-språkkode", "search_popout.options": "Søkjealternativ", "search_popout.quick_actions": "Hurtighandlinger", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index 29eaeddff5..c0f50283ac 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Ingen Innlegg", "account.featured_tags.title": "{name} sine fremhevede emneknagger", "account.follow": "Følg", + "account.follow_back": "Følg tilbake", "account.followers": "Følgere", "account.followers.empty": "Ingen følger denne brukeren ennå.", "account.followers_counter": "{count, plural, one {{counter} følger} other {{counter} følgere}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Demp varsler", "account.mute_short": "Demp", "account.muted": "Dempet", + "account.mutual": "Gjensidig", "account.no_bio": "Ingen beskrivelse oppgitt.", "account.open_original_page": "Gå til originalsiden", "account.posts": "Innlegg", @@ -66,7 +68,7 @@ "account.unblock_domain": "Opphev blokkering av {domain}", "account.unblock_short": "Opphev blokkering", "account.unendorse": "Ikke vis frem på profilen", - "account.unfollow": "Avfølg", + "account.unfollow": "Slutt å følge", "account.unmute": "Opphev demping av @{name}", "account.unmute_notifications_short": "Opphev demping av varsler", "account.unmute_short": "Opphev demping", @@ -480,6 +482,7 @@ "onboarding.follows.empty": "Dessverre kan ingen resultater vises akkurat nå. Du kan prøve å bruke søk eller bla gjennom utforske-siden for å finne folk å følge, eller prøve igjen senere.", "onboarding.follows.lead": "Hjem-skjermen din er den viktigste måten å oppleve Mastodon på. Jo flere du følger, jo mer aktiv og interessant blir det. For å komme i gang, er her noen forslag:", "onboarding.follows.title": "Populært på Mastodon", + "onboarding.profile.discoverable": "Gjør min profil synlig", "onboarding.profile.display_name": "Visningsnavn", "onboarding.profile.display_name_hint": "Ditt fulle navn eller ditt morsomme navn…", "onboarding.profile.lead": "Du kan alltid fullføre dette senere i innstillingene, der enda flere tilpasningsalternativer er tilgjengelige.", @@ -532,6 +535,7 @@ "privacy.unlisted.short": "Uoppført", "privacy_policy.last_updated": "Sist oppdatert {date}", "privacy_policy.title": "Personvernregler", + "recommended": "Anbefalt", "refresh": "Oppfrisk", "regeneration_indicator.label": "Laster…", "regeneration_indicator.sublabel": "Dine tidslinje blir gjort klar!", @@ -602,6 +606,7 @@ "search.quick_action.status_search": "Innlegg som samsvarer med {x}", "search.search_or_paste": "Søk eller lim inn URL", "search_popout.full_text_search_disabled_message": "Ikke tilgjengelig på {domain}.", + "search_popout.full_text_search_logged_out_message": "Bare tilgjengelig ved innlogging.", "search_popout.language_code": "ISO språkkode", "search_popout.options": "Alternativer for søk", "search_popout.quick_actions": "Hurtighandlinger", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 37a8328c98..a8ff90cc00 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Нет постов", "account.featured_tags.title": "Избранные хэштеги {name}", "account.follow": "Подписаться", + "account.follow_back": "Подписаться в ответ", "account.followers": "Подписчики", "account.followers.empty": "На этого пользователя пока никто не подписан.", "account.followers_counter": "{count, plural, one {{counter} подписчик} many {{counter} подписчиков} other {{counter} подписчика}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Отключить уведомления", "account.mute_short": "Немой", "account.muted": "Игнорируется", + "account.mutual": "Взаимно", "account.no_bio": "Описание не предоставлено.", "account.open_original_page": "Открыть исходную страницу", "account.posts": "Посты", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index 02425d73e0..3e41a2035a 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -21,7 +21,7 @@ "account.blocked": "Blokovaný/á", "account.browse_more_on_origin_server": "Prehľadávaj viac na pôvodnom profile", "account.cancel_follow_request": "Zruš žiadosť o sledovanie", - "account.copy": "Skopíruj odkaz pre profil", + "account.copy": "Skopíruj odkaz na profil", "account.direct": "Spomeň @{name} súkromne", "account.disable_notifications": "Prestaň mi oznamovať, keď má @{name} príspevky", "account.domain_blocked": "Doména skrytá", @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Žiadne príspevky", "account.featured_tags.title": "Odporúčané hashtagy používateľa {name}", "account.follow": "Sleduj", + "account.follow_back": "Nasleduj späť", "account.followers": "Sledovatelia", "account.followers.empty": "Tohto používateľa ešte nikto nenasleduje.", "account.followers_counter": "{count, plural, one {{counter} Sledujúci} few {{counter} Sledujúci} many {{counter} Sledujúcich} other {{counter} Sledujúcich}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Stíš oznámenia", "account.mute_short": "Stíš", "account.muted": "Stíšený", + "account.mutual": "Spoločné", "account.no_bio": "Nie je uvedený žiadny popis.", "account.open_original_page": "Otvor pôvodnú stránku", "account.posts": "Príspevky", diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json index 59ad0ae84e..77c262e957 100644 --- a/app/javascript/mastodon/locales/sr-Latn.json +++ b/app/javascript/mastodon/locales/sr-Latn.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Nema objava", "account.featured_tags.title": "Istaknute heš oznake korisnika {name}", "account.follow": "Prati", + "account.follow_back": "Uzvrati praćenje", "account.followers": "Pratioci", "account.followers.empty": "Još uvek niko ne prati ovog korisnika.", "account.followers_counter": "{count, plural, one {{counter} pratilac} few {{counter} pratioca} other {{counter} pratilaca}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Isključi obaveštenja", "account.mute_short": "Isključi", "account.muted": "Ignorisan", + "account.mutual": "Zajednički", "account.no_bio": "Nema opisa.", "account.open_original_page": "Otvori originalnu stranicu", "account.posts": "Objave", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index 79786b8d44..85e7567bf4 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Нема објава", "account.featured_tags.title": "Истакнуте хеш ознаке корисника {name}", "account.follow": "Прати", + "account.follow_back": "Узврати праћење", "account.followers": "Пратиоци", "account.followers.empty": "Још увек нико не прати овог корисника.", "account.followers_counter": "{count, plural, one {{counter} пратилац} few {{counter} пратиоца} other {{counter} пратилаца}}", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index d14e37517d..b108e581a4 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -53,6 +53,7 @@ "account.mute_notifications_short": "ซ่อนการแจ้งเตือน", "account.mute_short": "ซ่อน", "account.muted": "ซ่อนอยู่", + "account.mutual": "คนที่มีร่วมกัน", "account.no_bio": "ไม่ได้ให้คำอธิบาย", "account.open_original_page": "เปิดหน้าดั้งเดิม", "account.posts": "โพสต์", @@ -203,7 +204,7 @@ "disabled_account_banner.text": "มีการปิดใช้งานบัญชีของคุณ {disabledAccount} ในปัจจุบัน", "dismissable_banner.community_timeline": "นี่คือโพสต์สาธารณะล่าสุดจากผู้คนที่บัญชีได้รับการโฮสต์โดย {domain}", "dismissable_banner.dismiss": "ปิด", - "dismissable_banner.explore_links": "นี่คือเรื่องข่าวที่ได้รับการแบ่งปันมากที่สุดในเว็บสังคมวันนี้ เรื่องข่าวที่ใหม่กว่าที่ได้รับการโพสต์โดยผู้คนต่าง ๆ มากกว่าจะได้รับการจัดอันดับที่สูงกว่า", + "dismissable_banner.explore_links": "นี่เป็นเรื่องข่าวที่ได้รับการแชร์มากที่สุดในเว็บสังคมวันนี้ เรื่องข่าวที่ใหม่กว่าที่มีคนโพสต์มากกว่าจะได้รับการจัดอันดับที่สูงกว่า", "dismissable_banner.explore_statuses": "นี่คือโพสต์จากทั่วทั้งเว็บสังคมที่กำลังได้รับความสนใจวันนี้ โพสต์ที่ใหม่กว่าที่มีการดันและรายการโปรดมากกว่าจะได้รับการจัดอันดับที่สูงกว่า", "dismissable_banner.explore_tags": "นี่คือแฮชแท็กที่กำลังได้รับความสนใจในเว็บสังคมวันนี้ แฮชแท็กที่มีการใช้โดยผู้คนต่าง ๆ มากกว่าจะได้รับการจัดอันดับที่สูงกว่า", "dismissable_banner.public_timeline": "นี่คือโพสต์สาธารณะล่าสุดจากผู้คนในเว็บสังคมที่ผู้คนใน {domain} ติดตาม", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 92eacaad14..5ec0da599b 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Немає дописів", "account.featured_tags.title": "{name} виділяє хештеґи", "account.follow": "Підписатися", + "account.follow_back": "Підписатися взаємно", "account.followers": "Підписники", "account.followers.empty": "Ніхто ще не підписаний на цього користувача.", "account.followers_counter": "{count, plural, one {{counter} підписник} few {{counter} підписники} many {{counter} підписників} other {{counter} підписники}}", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 721c7cd4ad..03c6502651 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Chưa có tút", "account.featured_tags.title": "Hashtag của {name}", "account.follow": "Theo dõi", + "account.follow_back": "Theo dõi lại", "account.followers": "Người theo dõi", "account.followers.empty": "Chưa có người theo dõi nào.", "account.followers_counter": "{count, plural, one {{counter} Người theo dõi} other {{counter} Người theo dõi}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Ẩn thông báo", "account.mute_short": "Ẩn", "account.muted": "Đã ẩn", + "account.mutual": "Đang theo dõi nhau", "account.no_bio": "Chưa có miêu tả.", "account.open_original_page": "Mở trang gốc", "account.posts": "Tút", diff --git a/config/locales/activerecord.ie.yml b/config/locales/activerecord.ie.yml index 0c63299e04..588105ae96 100644 --- a/config/locales/activerecord.ie.yml +++ b/config/locales/activerecord.ie.yml @@ -6,4 +6,52 @@ ie: expires_at: Cludent date options: Optiones user: + agreement: Acorde de servicie + email: E-posta + locale: Local password: Passa-parol + user/account: + username: Nómine del usator + user/invite_request: + text: Rason + errors: + models: + account: + attributes: + username: + reserved: es reservat + admin/webhook: + attributes: + url: + invalid: ne es un valid URL + doorkeeper/application: + attributes: + website: + invalid: ne es un valid URL + import: + attributes: + data: + malformed: es malformat + status: + attributes: + reblog: + taken: de posta ja existe + user: + attributes: + email: + unreachable: sembla ne exister + role_id: + elevated: ne posse esser plu alt quam tui actual rol + user_role: + attributes: + permissions_as_keys: + dangerous: include permissones ne secur por li rol de base + elevated: ne posse includer permissiones ne possedet de tui rol actual + own_role: ne posse esser changeat con tui actual rol + position: + elevated: ne posse esser plu alt quam tui actual rol + own_role: ne posse esser changeat con tui actual rol + webhook: + attributes: + events: + invalid_permissions: ne posse includer evenimentes por queles tu ne have li yures diff --git a/config/locales/devise.ie.yml b/config/locales/devise.ie.yml index 0cf0fbe1fe..847b0f361b 100644 --- a/config/locales/devise.ie.yml +++ b/config/locales/devise.ie.yml @@ -1,6 +1,8 @@ --- ie: devise: + confirmations: + confirmed: Tui e-mail adresse ha esset confirmat successosimen. failure: already_authenticated: Tu ha ja intrat. inactive: Tui conto ancor ne ha esset activat. @@ -13,13 +15,24 @@ ie: unauthenticated: Tu deve intrar o registrar te ante continuar. unconfirmed: Tu deve confirmar tui e-posta ante continuar. mailer: + confirmation_instructions: + action: Verificar e-posta + action_with_app: Confirma e retorna a%{app} + title: Verificar e-posta email_changed: + explanation: 'Li e-mail adresse de tui es changeat a:' extra: Si tu ne changeat tui email-adresse, it es probabil que alqui ha ganiat accesse a tui conto. Ples changear tui passa-parol strax o contacter li administrator del servitor si tu ne posse intrar tui conto. + subject: 'Mastodon: E-posta changeat' + title: Nov adresse de e-posta password_change: explanation: Li passa-parol de tui conto ha esset changeat. extra: Si tu ne changeat tui passa-parol, it es probabil que alqui ha ganiat accesse a tui conto. Ples changear tui passa-parol strax o contacter li administrator del servitor si tu ne posse intrar tui conto. subject: 'Mastodon: Passa-parol changeat' title: Passa-parol changeat + reconfirmation_instructions: + explanation: Confirmar li nov adresse por changeat tui e-posta. + subject: 'Mastodon: E-posta de confirmation por %{instance}' + title: Verificar e-posta reset_password_instructions: action: Changear passa-parol explanation: Tu demandat un nov passa-parol por tui conto. @@ -28,6 +41,18 @@ ie: title: Reiniciar passa-parol two_factor_disabled: explanation: 2-factor autentication por tui conto ha esset desactivisat. Aperter session nu es possibil solmen per email-adresse e passa-parol. + title: 2FA desvalidat + two_factor_enabled: + title: 2FA permisset + unlock_instructions: + subject: 'Mastodon: Desserral instructiones' + webauthn_credential: + added: + subject: 'Mastodon: Nov clave de securitá' + title: Un nov clave de securitá ha esset adjuntet + webauthn_disabled: + subject: 'Mastodon: Autentication con claves de securitá desactivisat' + title: Claves de securitá desactivisat omniauth_callbacks: failure: Ne posset autenticar te de %{kind} pro "%{reason}". passwords: @@ -38,3 +63,15 @@ ie: updated_not_active: Tui passa-parol ha esset changeat successosimen. registrations: signed_up: Benevenit! Tu ha successat registrar te. + updated: Tui conto ha esset actualisat successosimen. + sessions: + already_signed_out: Exeat successosimen. + signed_in: Intrat successosimen. + signed_out: Exeat successosimen. + errors: + messages: + already_confirmed: esset ja confirmat, ples prova intrar + confirmation_period_expired: besona esser confirmat intra %{period}, ples demanda un nov + expired: ha expirat, ples demandar un nov + not_found: ne trovat + not_locked: ne esset serrat diff --git a/config/locales/devise.ko.yml b/config/locales/devise.ko.yml index 3ab7c11a5c..65f660f105 100644 --- a/config/locales/devise.ko.yml +++ b/config/locales/devise.ko.yml @@ -2,7 +2,7 @@ ko: devise: confirmations: - confirmed: 이메일이 성공적으로 승인 되었습니다. + confirmed: 이메일이 성공적으로 확인 되었습니다. send_instructions: 몇 분 이내로 확인 이메일이 발송 됩니다. 이메일을 받지 못 한 경우, 스팸 폴더를 확인하세요. send_paranoid_instructions: 이메일 주소가 저희 데이터베이스에 있는 경우, 몇 분 내에 이메일 주소를 확인하는 방법에 대한 안내가 포함된 이메일을 받을 수 있습니다. 이 이메일을 받지 못했다면 스팸 폴더를 확인해 주세요. failure: diff --git a/config/locales/doorkeeper.ie.yml b/config/locales/doorkeeper.ie.yml index 83c9cc564f..e5e5146558 100644 --- a/config/locales/doorkeeper.ie.yml +++ b/config/locales/doorkeeper.ie.yml @@ -1,11 +1,157 @@ --- ie: + activerecord: + attributes: + doorkeeper/application: + name: Nómine de aplication + redirect_uri: URI de redirection + website: Situ web de aplication + errors: + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: ne posse contener un fragment. + invalid_uri: deve esser un URI valid. + relative_uri: deve esser un URI absolut. + secured_uri: deve esser un URI de HTTPS/SSL. doorkeeper: + applications: + buttons: + authorize: Autorisar + cancel: Anullar + destroy: Destructer + edit: Redacter + submit: Submisser + confirmations: + destroy: Es tu cert? + edit: + title: Modificar aplication + help: + redirect_uri: Usar un linea per URI + index: + application: Aplication + delete: Deleter + empty: Tu have null aplicationes. + name: Nómine + new: Nov aplication + show: Monstrar + title: Tui aplicationes + new: + title: Nov aplication + show: + actions: Actiones + application_id: Clave de client + secret: Secrete de client + title: 'Aplication: %{name}' + authorizations: + buttons: + authorize: Autorisar + deny: Negar + error: + title: Alquo ha errat + new: + title: Autorisation besonat + authorized_applications: + buttons: + revoke: Revocar + confirmations: + revoke: Es tu cert? + index: + authorized_at: Autorisat ye %{date} + last_used_at: Ultimmen usat ye %{date} + never_used: Nequande usat + scopes: Permissiones + superapp: Intern + title: Tui autorisat aplicationes + errors: + messages: + invalid_client: Fallit autentification pro ínconosset client, manca de client-autentification, o ne subtenet metode de autentification. + invalid_redirect_uri: Li uri de redirection includet ne es valid. + invalid_request: + unknown: Li petition manca un postulat parametre, include un ne apoyat parametre-valore, o es altrimen mal format. + unsupported_grant_type: Li tip de autorisation concedet ne es subtenet per li autorisant servitor. + unsupported_response_type: Li autorisant servitor ne subtene ti-ci tip de response. + flash: + applications: + create: + notice: Aplication creat. + destroy: + notice: Aplication deletet. + update: + notice: Aplication actualisat. + authorized_applications: + destroy: + notice: Aplication revocat. grouped_scopes: + access: + read: Accesse solmen por leer + read/write: Accesse por leer e scrir + write: Accesse solmen por scrir title: + accounts: Contos + admin/accounts: Administration de contos + admin/all: Omni functiones administrativ + admin/reports: Administration de raportes + all: Plen accesse a tui conto Mastodon + blocks: Bloccas + bookmarks: Marcatores + conversations: Conversationes + favourites: Favorites + filters: Filtres follow: Seques, silentias e bloccas + follows: Seque + lists: Listes + media: Medie-atachamentes mutes: Silentias + notifications: Notificationes + push: Notificationes push + reports: Raportes + search: Serchar + statuses: Postas + layouts: + admin: + nav: + applications: Aplicationes scopes: + admin:read: leer li tot data sur li servitor + admin:read:accounts: leer sensitiv information de omni contos + admin:read:domain_allows: leer sensitiv information pri omni permisses de dominia + admin:read:domain_blocks: leer sensitiv information pri omni bloccas de dominia + admin:read:email_domain_blocks: leer sensitiv information pri omni bloccas de dominia basat sur e-posta + admin:read:ip_blocks: leer sensitiv information pri omni bloccas de IP + admin:read:reports: leer sensitiv information pri omni raportes e raportat contos + admin:write: modificar li tot data sur li servitor + admin:write:accounts: far moderatori actiones sur contos + admin:write:canonical_email_blocks: far moderatori actiones sur canonic bloccas de e-posta + admin:write:domain_allows: far actiones de moderation sur permisses de dominia + admin:write:domain_blocks: far actiones de moderation sur bloccas de dominia + admin:write:email_domain_blocks: far actiones de moderation sur bloccas de dominia basat sur e-posta + admin:write:ip_blocks: fa moderatori actiones sur bloccas de IP + admin:write:reports: far moderatori actiones sur raportes + follow: modifica li relationes del conto + read: lee omni datas de tui conto + read:accounts: vide li informationes pri li conto + read:blocks: vider tui bloccas + read:bookmarks: vider tui marcatores + read:favourites: vider tui favorites + read:filters: vider tui filtres + read:follows: vider tui sequitores + read:lists: vider tui listes read:mutes: vider tui silentias + read:notifications: vider tui notificationes + read:reports: vider tui raportes + read:search: serchar in tui nómine + read:statuses: vider omni postas + write: modificar li tot data de tui conto + write:accounts: modifica tui profile + write:blocks: bloccar contos e dominias write:conversations: silentiar e deleter conversationes + write:favourites: favorit postas + write:filters: crea filtres + write:follows: sequer homes + write:lists: crear listes write:mutes: silentiar persones e conversationes + write:notifications: aclarar tui notificationes + write:reports: raportar altri persones + write:statuses: publicar postas diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 9ae5953943..8a0033ee6a 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -1260,11 +1260,20 @@ eo: overwrite_long: Anstataŭigi la nunajn registrojn per la novaj preface: Vi povas importi datumojn, kiujn vi eksportis el alia servilo, kiel liston de homoj, kiujn vi sekvas aŭ blokas. success: Viaj datumoj estis sukcese alŝutitaj kaj estos traktitaj kiel planite + titles: + following: Importado de sekvaj kontoj + lists: Importi listojn + muting: Importado de silentigitaj kontoj + type: Importi tipon + type_groups: + constructive: Sekvoj & Legosignoj + destructive: Blokas kaj silentigas types: blocking: Listo de blokitoj bookmarks: Legosignoj domain_blocking: Listo de blokitaj domajnoj following: Listo de sekvatoj + lists: Listoj muting: Listo de silentigitoj upload: Alŝuti invites: @@ -1279,6 +1288,7 @@ eo: '86400': 1 tago expires_in_prompt: Neniam generate: Krei + invalid: Ĉi tiu invito ne validas invited_by: 'Vi estis invitita de:' max_uses: one: 1 uzo @@ -1305,6 +1315,18 @@ eo: title: Aŭtentiga historio mail_subscriptions: unsubscribe: + action: Jes, malabonu + complete: Malabonita + confirmation_html: Ĉu vi certas, ke vi volas malaboni por ricevi %{type} por Mastodon ĉe %{domain} al via retpoŝto ĉe %{email}? Vi ĉiam povas reaboni de viaj retpoŝtaj sciigaj agordoj. + emails: + notification_emails: + favourite: plej ŝatataj sciigaj retpoŝtoj + follow: sekvu sciigajn retmesaĝojn + follow_request: sekvu petajn retpoŝtojn + mention: menciu sciigajn retmesaĝojn + reblog: plifortigi sciigajn retpoŝtojn + resubscribe_html: Se vi malabonis erare, vi povas reaboni de viaj retpoŝtaj sciigaj agordoj. + success_html: Vi ne plu ricevos %{type} por Mastodon sur %{domain} al via retpoŝto ĉe %{email}. title: Malaboni media_attachments: validations: @@ -1385,6 +1407,7 @@ eo: update: subject: "%{name} redaktis afiŝon" notifications: + administration_emails: Admin retpoŝtaj sciigoj email_events: Eventoj por retpoŝtaj sciigoj email_events_hint: 'Elekti la eventojn pri kioj vi volas ricevi sciigojn:' other_settings: Aliaj agordoj de sciigoj @@ -1421,6 +1444,7 @@ eo: expired: La enketo jam finiĝis invalid_choice: La elektita voĉdono ne ekzistas over_character_limit: ne povas esti po pli longa ol %{max} signoj + self_vote: Vi ne povas voĉdoni en viaj propraj balotenketoj too_few_options: devas enhavi pli da unu propono too_many_options: ne povas enhavi pli da %{max} proponoj preferences: @@ -1428,7 +1452,14 @@ eo: posting_defaults: Afiŝaj defaŭltoj public_timelines: Publikaj templinioj privacy: + hint_html: "Agordu kiel vi volas ke via profilo kaj viaj afiŝoj estu trovitaj. Diversaj funkcioj en Mastodon povas helpi vin atingi pli larĝan publikon kiam ĝi estas ebligita. Prenu momenton por revizii ĉi tiujn agordojn por certigi, ke ili taŭgas por via uzokazo." privacy: Privateco + privacy_hint_html: Kontrolu kiom vi volas malkaŝi por la avantaĝo de aliaj. Homoj malkovras interesajn profilojn kaj bonegajn apojn foliumante la sekvaĵojn de aliaj homoj kaj vidante de kiuj aplikaĵoj ili afiŝas, sed vi eble preferas konservi ĝin kaŝita. + reach: Atingo + reach_hint_html: Kontrolu ĉu vi volas esti malkovrita kaj sekvita de novaj homoj. Ĉu vi volas ke viaj afiŝoj aperu sur la ekrano Esplori? Ĉu vi volas ke aliaj homoj vidu vin en siaj sekvaj rekomendoj? Ĉu vi volas akcepti ĉiujn novajn sekvantojn aŭtomate, aŭ havi granulan kontrolon pri ĉiu? + search: Serĉu + search_hint_html: Kontrolu kiel vi volas esti trovita. Ĉu vi volas, ke homoj trovu vin laŭ tio, pri kio vi publike afiŝis? Ĉu vi volas, ke homoj ekster Mastodonto trovu vian profilon dum serĉado en la reto? Bonvolu memori, ke totala ekskludo de ĉiuj serĉiloj ne povas esti garantiita por publika informo. + title: Privateco kaj atingo privacy_policy: title: Privateca politiko reactions: @@ -1470,6 +1501,9 @@ eo: over_daily_limit: Vi transpasis la limigon al %{limit} samtage planitaj mesaĝoj over_total_limit: Vi transpasis la limigon al %{limit} planitaj mesaĝoj too_soon: La planita dato devas esti en la estonteco + self_destruct: + lead_html: Bedaŭrinde, %{domain} konstante fermiĝas. Se vi havis konton tie, vi ne povos daŭrigi uzi ĝin, sed vi ankoraŭ povas peti sekurkopion de viaj datumoj. + title: Ĉi tiu servilo fermiĝas sessions: activity: Lasta ago browser: Retumilo @@ -1638,6 +1672,10 @@ eo: default: "%Y.%b.%d, %H:%M" month: "%b %Y" time: "%H:%M" + translation: + errors: + quota_exceeded: La tutservila uzkvoto por la tradukservo estas superita. + too_many_requests: Lastatempe estis tro multaj petoj al la tradukservo. two_factor_authentication: add: Aldoni disable: Malebligi 2FA-n @@ -1717,6 +1755,7 @@ eo: title: Bonvenon, %{name}! users: follow_limit_reached: Vi ne povas sekvi pli ol %{limit} homo(j) + go_to_sso_account_settings: Iru al la agordoj de la konto de via identeca provizanto invalid_otp_token: Nevalida kodo de dufaktora aŭtentigo otp_lost_help_html: Se vi perdas aliron al ambaŭ, vi povas kontakti %{email} seamless_external_login: Vi estas ensalutinta per ekstera servo, do pasvortaj kaj retadresaj agordoj ne estas disponeblaj. diff --git a/config/locales/ie.yml b/config/locales/ie.yml index 6013923e3f..99e628fe3b 100644 --- a/config/locales/ie.yml +++ b/config/locales/ie.yml @@ -72,6 +72,7 @@ ie: enabled_msg: Successosimen desgelat li conto de %{username} followers: Sequitores follows: Seque + header: Cap-image inbox_url: Inbuxe URL invite_request_text: Rason por adhesion invited_by: Invitat de @@ -118,6 +119,7 @@ ie: remote_suspension_irreversible: Li data de ti-ci conto ha esset deletet ínreversibilmen. remote_suspension_reversible_hint_html: Li conto ha esset suspendet che su servitor, e li data va esser completmen removet ye %{date}. Til tande, li lontan servitor posse restaurar ti conto sin quelcunc mal efectes. Si tu vole remover omni data del conto ínmediatmen, tu posse far it in infra. remove_avatar: Remover li avatar + remove_header: Remover cap-image removed_avatar_msg: Successosimen removet li avatar-image de %{username} removed_header_msg: Successosimen removet li cap-image de %{username} resend_confirmation: @@ -287,6 +289,7 @@ ie: deleted_account: deletet conto filter_by_action: Filtrar per action filter_by_user: Filtrar per usator + title: Jurnale de audit announcements: destroyed_msg: Proclamation deletet successosimen! edit: @@ -330,6 +333,7 @@ ie: no_emoji_selected: Null emoji esset changeat pro que null esset selectet not_permitted: Tu ne es permisset far ti action overwrite: Remplazzar + shortcode: Curt-code shortcode_hint: Adminim 2 carácteres, solmen lítteres, ciffres e sublineas title: Customisat emoji uncategorized: Íncategorisat @@ -461,6 +465,9 @@ ie: unsuppress: Restaurar seque-recomandation instances: availability: + failures_recorded: + one: Fallit prova por %{count} die. + other: Fallit provas por %{count} dies. no_failures_recorded: Null fallimentes registrat. title: Disponibilitá warning: Li ultim prova conexer a ti servitor ha esset ínsuccessosi @@ -485,6 +492,8 @@ ie: instance_followers_measure: nor sequitores ta instance_follows_measure: lor sequitores ci instance_languages_dimension: Max grand lingues + instance_media_attachments_measure: salvat medie-atachamentes + instance_reports_measure: raportes pri les instance_statuses_measure: salvat postas delivery: all: Omni @@ -565,6 +574,7 @@ ie: notes: one: "%{count} nota" other: "%{count} notas" + action_log: Jurnale de audit action_taken_by: Action fat de actions: delete_description_html: Li raportat postas va esser deletet e un admoniment va esser registrat por auxiliar te escalar si hay futuri infractiones del sam conto. @@ -670,26 +680,36 @@ ie: manage_announcements: Tractar proclamationes manage_announcements_description: Permisse usatores tractar proclamationes sur li servitor manage_appeals: Gerer Apelles + manage_appeals_description: Permisse que usatores inspecte apelles contra actiones de moderatores manage_blocks: Gerer Bloccas manage_blocks_description: Permisse que usatores blocca provisores de e-posta e IP-adresses manage_custom_emojis: Gerer Customisat Emojis manage_custom_emojis_description: Permisse que usatores gere customisat emojis sur li servitor manage_federation: Gerer Federation - manage_federation_description: Permisse que usatores sive blocca sive permisse federation con altri domenes, e controla liverabilitá + manage_federation_description: Permisse que usatores sive blocca sive permisse federation con altri dominias, e controla liverabilitá manage_invites: Gerer Invitationes + manage_invites_description: Permisse que usatores naviga e deactiva ligamentes de invitation manage_reports: Gerer Raportes + manage_reports_description: Permisse que usatores inspecte raportes e fa actiones de moderation contra les manage_roles: Gerer Roles + manage_roles_description: Permisse que usatores gere e assigna roles sub li lores manage_rules: Gerer Regules manage_rules_description: Permisse que usatores changea regules del servitor manage_settings: Gerer Parametres manage_settings_description: Permisse que usatores changea parametres del situ manage_taxonomies: Gerer Taxonomies + manage_taxonomies_description: Permisse que usatores inspecte contenete de tendentie e actualisar parametres de hashtags manage_user_access: Gerer Usator-Accesse manage_user_access_description: Permisse usatores desactivisar li 2-factor autentication de altri usatores, changear lor email-adresses, e reiniciar lor passa-paroles manage_users: Gerer usatores - manage_webhooks: Gerer Web-crocs + manage_users_description: Permisse que usatores vide detallies de altri usatores e fa actiones de moderation contra les + manage_webhooks: Gerer Webcrocs + view_audit_log: Vider li Jurnale de Audit view_audit_log_description: Permisse que usatores vide li historie de administrativ actiones sur li servitor + view_dashboard: Vider Panel de Control + view_dashboard_description: Permisse que usatores usa li panel de control e varie metricas view_devops: DevOps + view_devops_description: Permise que usatores usa paneles de control de Sidekiq e pgHero title: Roles rules: add_new: Adjunter un regule @@ -704,6 +724,8 @@ ie: appearance: preamble: Customisar li interfacie web de Mastodon. title: Aspecte + content_retention: + title: Retention de contenete discovery: follow_recommendations: Seque-recomandationes preamble: Exposir interessant contenete es importantissim por incorporar nov usatores qui fórsan conosse nequi che Mastodon. Decider qualmen diferent utensiles de decovrition functiona che vor servitor. @@ -740,6 +762,9 @@ ie: documentation_link: Aprender plu title: Actualisationes disponibil type: Specie + types: + major: Majori lansament + minor: Minori lansament version: Version statuses: account: Autor @@ -781,16 +806,39 @@ ie: system_checks: database_schema_check: message_html: Hay pendent migrationes de database. Ples far les por far cert que li aplication functiona quam expectat + elasticsearch_health_red: + message_html: Li cluster Elasticsearch es ínsalubri (statu rubi), functiones por serchar ne disponibil + elasticsearch_health_yellow: + message_html: Li cluster Elasticsearch es ínsalubri (statu yelb); investigar li rason vell esser un bon idé elasticsearch_preset: action: Vider li documentation + message_html: Tui cluster Elasticsearch have plu quam un node, ma Mastodon ne es configurat por usar les. elasticsearch_preset_single_node: action: Vider li documentation + message_html: Tui cluster Elasticsearch have solmen un node, ples configurar ES_PRESET quam single_node_cluster. + elasticsearch_running_check: + message_html: Ne posset conexer a Elasticsearch. Ples confirmar que it ha esset executet, o desactivar serchada de plen textu + elasticsearch_version_check: + message_html: 'Version de Elasticsearch íncompatibil: %{value}' + version_comparison: Elasticsearch %{running_version} executet ma %{required_version} postulat rules_check: action: Gerer regules de servitor + message_html: Tu ancor ne ha definit quelcunc regules de servitor. software_version_critical_check: + action: Vider actualisationes disponibil message_html: Un critical actualisation por Mastodon es disposibil, ples actualisar tam rapidmen possibil. software_version_patch_check: action: Vider actualisationes disponibil + message_html: Un actualisation por Mastodon quel fixa problemas es disponibil. + upload_check_privacy_error: + action: Vider ci por plu information + message_html: "Vor web-servitor es misconfigurat. Li privatie de vor usatores es in risca." + upload_check_privacy_error_object_storage: + action: Cliccar ci por plu information + message_html: "Vor inmagasinage de objectes es misconfigurat. Li privatie de vor usatores es in risca." + tags: + review: Statu de revision + updated_msg: Parametres pri hashtags actualisat successosimen title: Administration trends: allow: Permisser @@ -805,9 +853,13 @@ ie: no_link_selected: Null ligamentes esset changeat pro que null esset selectet publishers: no_publisher_selected: Null editores esset changeat pro que necun esset selectet + shared_by_over_week: + one: Partit de un person durant li ultim semane + other: Partit de %{count} persones durant li ultim semane title: Ligamentes in tendentie usage_comparison: Partit %{today} vezes hodie, in comparation a %{yesterday} yer not_allowed_to_trend: Ne permisset esser in tendentie + only_allowed: Solmen li permissetes pending_review: Sub inspection preview_card_providers: allowed: Ligamentes de ti-ci editor posse esser in tendentie @@ -859,10 +911,50 @@ ie: empty: Vu ancor ha definit null prefigurationes de avise. title: Modificar prefigurationes de avise webhooks: + add_new: Adjunter punctu terminal + delete: Deleter + disable: Desactivisar + disabled: Desactivisat + edit: Redacter punctu terminal + empty: Tu ancor ne have quelcunc configurat punctus terminal por webcrocs. + enable: Activisar enabled: Activ + enabled_events: + one: 1 eveniment activisat + other: "%{count} evenimentes activisat" events: Evenimentes + new: Nov webcroc + rotate_secret: Rotar secrete + secret: Secrete de signation status: Statu + title: Webcrocs + webhook: Webcroc admin_mailer: + new_appeal: + actions: + delete_statuses: deleter su postas + disable: gelar su conto + mark_statuses_as_sensitive: marcar su postas quam sensitiv + none: un admoniment + sensitive: marcar su conto quam sensitiv + silence: limitar su conto + suspend: suspender su conto + body: "%{target} apella un moderatori decision fat de %{action_taken_by} ye %{date}, quel esset %{type}. Ilu scrit:" + next_steps: Tu posse aprobar li apelle por desfar li decision moderatori, o ignorar it. + subject: "%{username} apella un moderatori decision che %{instance}" + new_critical_software_updates: + body: Nov critic versiones de Mastodon ha esset lansat, vu fórsan vole actualisar tam tost quam es possibil! + subject: Critic actualisationes por Mastodon es disponibil por %{instance}! + new_pending_account: + body: Li detallies del nov conto es in-infra. Vu posse aprobar o rejecter ti aplication. + subject: Nov conto por tractation che %{instance} (%{username}) + new_report: + body: "%{reporter} ha raportet %{target}" + body_remote: Alqui de %{domain} ha raportet %{target} + subject: Nov raporte por %{instance} (#%{id}) + new_software_updates: + body: Nov versiones de Mastodon ha esset lansat, vu fórsan vole actualisar! + subject: Nov versiones Mastodon es disponibil por %{instance}! new_trends: new_trending_links: title: Populari ligamentes @@ -1284,10 +1376,45 @@ ie: images_and_video: On ne posse atachar un video a un posta quel ja contene images migrations: acct: Translocat a + cancel: Anullar redirection + cancelled_msg: Anullat redirection con successe. + errors: + already_moved: es li sam conto a equel tu ha ja translocat + missing_also_known_as: ne es un alias de ti-ci conto + move_to_self: ne posse esser li conto actual + not_found: ne posset esser trovat + followers_count: Sequitores al témpor de translocation + incoming_migrations: Translocant de un conto diferent + on_cooldown: Tu ha recentmen migrat tui conto. Ti function va esser disponibil denov pos %{count} dies. + past_migrations: Passat migrationes + proceed_with_move: Translocar sequitores + redirected_msg: Tui conto nu have un redirection a %{acct}. + redirecting_to: Tui conto redirecte a %{acct}. set_redirect: Configurar un redirection + warning: + backreference_required: Li nov conto deve in prim esser configurat por retroreferentiar ti-ci conto + before: 'Ante proceder, ples leer ti notas cuidosimen:' + other_data: Necun altri data va esser translocat automaticmen + moderation: + title: Moderation move_handler: + carry_blocks_over_text: Ti usator translocat se de %{acct}, quel tu hat bloccat. carry_mutes_over_text: Ti-ci usator movet se de %{acct}, quel tu hat silentiat. + copy_account_note_text: 'Vi tui notas pri ti usator qui translocat se de %{acct}:' notification_mailer: + admin: + report: + subject: "%{name} inviat un raporte" + sign_up: + subject: "%{name} adheret" + favourite: + body: 'Tui posta esset favoritisat de %{name}:' + subject: "%{name} favoritisat tui posta" + title: Nov favoritisation + follow: + body: "%{name} nu seque te!" + subject: "%{name} nu seque te" + title: Nov sequitor follow_request: action: Tractar petitiones de sequer body: "%{name} ha petit sequer te" @@ -1295,6 +1422,8 @@ ie: title: Nov petition de sequer mention: action: Responder + body: 'Tu esset mentionat de %{name} in:' + subject: Tu esset mentionat de %{name} title: Nov mention poll: subject: Un balotation de %{name} ha finit @@ -1346,6 +1475,7 @@ ie: too_many_options: ne posse contener plu quam %{max} optiones preferences: other: Altri + posting_defaults: Predefinitiones por postar public_timelines: Public témpor-lineas privacy: hint_html: "Customisa qualmen tu vole que tui profil e tui postas posse esser trovat. Mastodon have un varietá de manieres por auxiliar te atinger un auditorie plu grand quande activisat. Prende un moment por reviser ti parametres por far cert que ili concorda tui casu de usation." @@ -1383,6 +1513,11 @@ ie: remove_selected_followers: Remover selectet sequitores remove_selected_follows: Dessequer selectet usatores status: Statu del conto + remote_follow: + missing_resource: Ne posset trovar li besonat URL de redirection por tui conto + reports: + errors: + invalid_rules: ne refere valid regules rss: content_warning: 'Avise pri li contenete:' descriptions: @@ -1476,9 +1611,16 @@ ie: one: "%{count} video" other: "%{count} videos" boosted_from_html: Boostat de %{acct_link} + content_warning: 'Avise de contenete: %{warning}' default_language: Sam quam li lingue del interfacie + disallowed_hashtags: + one: 'contenet un ínpermisset hashtag: %{tags}' + other: 'contenet li ínpermisset hashtags: %{tags}' edited_at_html: Modificat ye %{date} + errors: + in_reply_not_found: Li posta a quel tu prova responder ne sembla exister. open_in_web: Aperter in web + over_character_limit: límite de carácteres de %{max} transpassat pin_errors: direct: On ne posse pinglar postas queles es visibil solmen a mentionat usatores limit: Tu ja ha pinglat li maxim númere de postas @@ -1495,8 +1637,11 @@ ie: show_more: Monstrar plu show_newer: Monstrar plu nov show_older: Monstrar plu old + show_thread: Monstrar fil title: "%{name}: «%{quote}»" visibilities: + direct: Direct + private: Solmen por sequitores private_long: Monstrar solmen a sequitores public: Public public_long: Omnes posse vider @@ -1508,17 +1653,37 @@ ie: exceptions: Exceptiones explanation: Deletion de postas es un operation expensiv, e pro to es efectuat lentmen quande li servitor ne es ocupat. Pro to, on posse deleter tui postas un cert témpor pos atinger un cert etá. ignore_favs: Ignorar favorites + ignore_reblogs: Ignorar boosts interaction_exceptions: Exceptiones basat sur interactiones + interaction_exceptions_explanation: Nota que it ne es garantit que un posta va esser deletet si su númere de favoritisationes o boosts descresce sub li sill pos que it ha esset súper it. keep_direct: Retener missages direct keep_direct_hint: Ne delete quelcunc de tui direct missages + keep_media: Conservar postas con medie-atachamentes + keep_media_hint: Ne delete quelcunc de tui postas quel have medie-atachamentes keep_pinned: Conservar pinglat postas keep_pinned_hint: Delete null de tui pinglat postas keep_polls: Conservar balotationes keep_polls_hint: Delete null de tui balotationes + keep_self_bookmark: Conservar postas queles tu ha marcat + keep_self_bookmark_hint: Ne delete tui propri postas si tu ha marcat les keep_self_fav: Retener postas favorit de te + keep_self_fav_hint: Ne delete tui propri postas si tu ha favoritisat les min_age: '1209600': 2 semanes + '15778476': 6 mensus + '2629746': 1 mensu '31556952': 1 annu + '5259492': 2 mensus + '604800': 1 semane + '63113904': 2 annus + '7889238': 3 mensus + min_age_label: Sill de etá + min_favs: Conservar postas favoritisat adminim + min_favs_hint: Ne delete quelcunc de tui postas quel ha recivet adminim ti-ci númere de favoritisationes. Lassar vacui por deleter postas sin egard a su númere de favoritisationes + min_reblogs: Conservar postas boostat adminim + min_reblogs_hint: Ne delete quelcunc de tui postas quel ha recivet adminim ti-ci númere de boosts. Lassar vacui por deleter postas sin egard a su númere de boosts + stream_entries: + sensitive_content: Sensitiv contenete strikes: errors: too_late: It es tro tard por apellar ti admoniment @@ -1595,22 +1760,37 @@ ie: mark_statuses_as_sensitive: Tui postas che %{acct} ha esset marcat quam sensitiv none: Admoniment por %{acct} sensitive: Tui postas che %{acct} ve esser marcat quam sensitiv pos nu + silence: Tui conto %{acct} ha esset limitat + suspend: Tui conto %{acct} ha esset suspendet title: delete_statuses: Postas efaciat + disable: Conto gelat + mark_statuses_as_sensitive: Postas marcat quam sensitiv + none: Admoniment sensitive: Conto marcat quam sensitiv silence: Conto limitat suspend: Conto suspendet welcome: edit_profile_action: Configuration de profil + edit_profile_step: Tu posse personalisar tui profil por cargar un profil-image, changear tui monstrat nómine e plu. Tu posse optar tractar nov sequitores ante que ili es permisset sequer te. explanation: Vi quelc suggestiones por que tu mey comensar final_action: Comensar postar + final_step: 'Comensa a postar! Mem sin sequitores, tui public postas posse esser videt de altres, per exemple in li local témpor-linea o in hashtags. Tu fórsan vole introducter te per li hashtag #introductions.' + full_handle: Tui plen usator-nómine + full_handle_hint: Ti-ci es ti quel tu vell dir a tui amics por que ili mey inviar missages a te o sequer te de un altri servitor. subject: Benevenit a Mastodon title: Benevenit, %{name}! users: + follow_limit_reached: Tu ne posse sequer plu quam %{limit} persones + go_to_sso_account_settings: Ear al parametres de conto de tui provisor de identification + invalid_otp_token: Ínvalid 2-factor code + otp_lost_help_html: Si tu perdit accesse a ambis, tu posse contacter %{email} seamless_external_login: Tu ha intrat per un servicie external, dunc parametres pri tui passa-parol e email-adresse ne es disponibil. + signed_in_as: 'Session apertet quam:' verification: extra_instructions_html: 'Nota: Li ligament in tui websitu posse esser ínvisibil. Li important parte es rel="me" quel prevente fals self-identification in websitus con contenete generat de usatores. Tu posse mem usar un link element in li cap-section del págine vice a, ma li HTML code deve esser accessibil sin executer JavaScript.' here_is_how: Vide qualmen + instructions_html: Copiar e collar li code ci infra in li HTML de tui web-situ. Poy adjunter li adresse de tui web-situ ad-in un del aditional campes sur tui profil ex li section "Modificar profil" e salvar li changes. verification: Verification verified_links: Tui verificat ligamentes webauthn_credentials: @@ -1620,3 +1800,7 @@ ie: success: Tui clave de securitá esset adjuntet con successe. delete: Deleter delete_confirmation: Vole tu vermen deleter ti-ci clave de securitá? + invalid_credential: Ínvalid clave de securitá + not_enabled: Tu ancor ne ha possibilisat WebAuthn + not_supported: Ti-ci navigator ne subtene claves de securitá + registered_on: Adheret ye %{date} diff --git a/config/locales/lad.yml b/config/locales/lad.yml index 471b830a3e..5c541d9f99 100644 --- a/config/locales/lad.yml +++ b/config/locales/lad.yml @@ -333,6 +333,7 @@ lad: not_permitted: No tienes permiso para realizar esta aksyon overwrite: Sobreskrive shortcode: Kodiche kurto + shortcode_hint: Al menos 2 karakteres, solo karakteres alfanumerikos i sulinyados title: Emojis personalizados uncategorized: No kategorizado unlist: No lista @@ -525,6 +526,7 @@ lad: total_reported: Raportos sovre eyos total_storage: Aneksos de multimedia totals_time_period_hint_html: Los totales amostrados a kontinuasyon inkluyen datos para todo el tiempo. + unknown_instance: Por agora no ay dingun rejistro en este domeno en este sirvidor. invites: deactivate_all: Dezaktiva todos filter: @@ -705,27 +707,41 @@ lad: manage_users: Administra utilizadores manage_users_description: Permete a los utilizadores ver los peratim de otros utilizadores i realizar aksyones de moderasyon kontra eyos manage_webhooks: Administrar webhooks + view_audit_log: Mostra defter de revisyon + view_audit_log_description: Permete a los utilizadores ver una estoria de aksyones administrativas en el sirvidor view_dashboard: Ve pano + view_dashboard_description: Permete a los utilizadores akseder al panel de kontrolo i varias metrikas view_devops: DevOps + view_devops_description: Permete a los utilizadores akseder a los paneles de kontrolo Sidekiq i pgHero title: Rolos rules: add_new: Adjusta regla delete: Efasa + description_html: Aunke la majorita afirma aver meldado i estar de akodro kon los terminos de servisyo, la djente normalmente no los melda asta dempues de ke surja algun problema. Az ke sea mas kolay ver las normas de tu sirvidor de un vistazo estipulándolas en una lista de puntos. Aprova ke kada norma sea corta i kolay, ama sin estar divididas en munchos puntos. edit: Edita regla + empty: Dinguna regla del sirvidor tiene sido definida. title: Reglas del sirvidor settings: about: manage_rules: Administra reglas del sirvidor + preamble: Mete aki enformasyon detalyada sovre komo el sirvidor es operado, moderado i finansyado. + rules_hint: Ay una area dedikada para las reglas a las ke se aspera ke tus utilizadores sigan. title: Sovre esto appearance: preamble: Personaliza la enterfaz web de Mastodon. title: Aparensya branding: + preamble: La marka de tu sirvidor lo desferensia de otros sirvidores de la red. Esta enformasyon puede amostrarse por una varieta de entornos, komo en la enterfaz web de Mastodon, en aplikasyones nativas, en previsualizasiones de atadijos en otros sitios internetikos i en aplikasyones de mesajes, etc. Por esta razon, es mijor mantener esta enformasyon klara, breve i konsiza. title: Marka content_retention: + preamble: Kontrola komo el kontenido jenerado por el utilizador se magazina en Mastodon. title: Retensyon de kontenido + default_noindex: + desc_html: Afekta a todos los utilizadores ke no trokaron esta preferensya eyos mezmos + title: Ekskluye utilizadores de la indeksasyon de los bushkadores komo preferensya predeterminada discovery: follow_recommendations: Rekomendasyones de kuentos + preamble: Ekspone kontenido enteresante a la superfisie es fundamental para inkorporar muevos utilizadores ke pueden no koneser a dinguno Mastodon. Kontrola komo fonksionan varias opsiones de diskuvrimiento en tu sirvidor. profile_directory: Katalogo de profiles public_timelines: Linyas de tiempo publikas publish_discovered_servers: Publika sirvidores diskuviertos @@ -816,6 +832,7 @@ lad: software_version_patch_check: action: Amostra aktualizasyones desponivles upload_check_privacy_error: + action: Klika aki para mas enformasyon message_html: "Tu sirvidor de web es mal konfigurado. La privasita de tus utilizadores esta en riziko." upload_check_privacy_error_object_storage: action: Ve aki para mas enformasyon @@ -837,6 +854,9 @@ lad: no_link_selected: No se troko dingun atadijo porke no eskojites dinguno publishers: no_publisher_selected: No se troko dingun publikador porke no eskojites dinguno + shared_by_over_week: + one: Partajado por una persona durante la ultima semana + other: Partajado por %{count} personas durante la ultima semana title: Atadijos en trend usage_comparison: Partajado %{today} vezes oy, komparado kon %{yesterday} ayer not_allowed_to_trend: Sin permiso para estar en trendes @@ -874,6 +894,7 @@ lad: not_listable: No seran rekomendadas not_trendable: No aperesera en trendes not_usable: No se pueden uzar + peaked_on_and_decaying: Alkanso el piko en %{date}, agora dekresiendo title: Etiketas en trend trendable: Pueden apareser en trendes trending_rank: Trend n.º %{rank} @@ -943,16 +964,23 @@ lad: title: Publikasyones en trend new_trending_tags: title: Etiketas en trend + subject: Muevo trend para revizion en %{instance} aliases: add_new: Kriya un alias + created_msg: Tienes kriyado djustamente el muevo alias. Agora puedes ampesar la movida dizde el kuento viejo. + deleted_msg: El alias fue supremido djustamente. La movida de akel kuento a esta ya no sera posivle. empty: No tienes aliases. + hint_html: Si keres migrar de otro kuento a este, aki puedes kriyar un alias, kale proseder antes de ampesar a mover suivantes del kuento anterior a este. Esta aksion por si mezma es inofensiva i reversivle. La migrasyon del kuento se inisya dizde el kuento viejo. remove: Dezata alias appearance: advanced_web_interface: Enterfaz web avanzada + advanced_web_interface_hint: 'Si keres utilizar todo el ancho de ekran, la enterfaz web avanzada te permete konfigurar varias kolumnas desferentes para ver tanta enformasyon al mezmo tiempo komo keras: Linya prinsipala, avizos, linya de tiempo federada, kualkier numero de listas i etiketas.' animations_and_accessibility: Animasyones i aksesivilita confirmation_dialogs: Dialogos de konfirmasyon discovery: Diskuvrimiento localization: + body: Mastodon es trezladado por volontarios. + guide_link: https://crowdin.com/project/mastodon guide_link_text: Todos pueden kontribuir. sensitive_content: Kontenido sensivle application_mailer: @@ -1067,15 +1095,27 @@ lad: x_months: "%{count} me" x_seconds: "%{count} s" deletes: + challenge_not_passed: Los datos introdusidos son yerrados + confirm_password: Eskrive tu kod aktual para demostrar tu identita + confirm_username: Eskrive tu nombre de utilizador para konfirmar proceed: Efasa kuento success_msg: Tu kuento fue efasado kon reusho warning: before: 'Antes de kontinuar, por favor melda kon atensyon las sigientes notas:' + caches: El kontenido ke tiene sido magazinado en kashe por otros sirvidores puede persistir + data_removal: Tus publikasyones i el resto de datos se supremiran definitivamente + email_change_html: Puedes trokar tu adreso de posta elektronika sin supremir tu kuento + email_contact_html: Si ainda no te tiene parvenido, puedes eskrivir a %{email} para pider ayuda + email_reconfirmation_html: Si no te tiene parvenido la posta de konfirmasyon, puedes retornar a solisitarlo + irreversible: No podras restaurar ni reaktivar tu kuento + more_details_html: Para mas detalyos, ver la politika de privasita. + username_available: Tu nombre de utilizador retornara a estar desponivle username_unavailable: Tu nombre de utilizador no estara desponivle disputes: strikes: action_taken: Aksyon tomada appeal: Apela + appeal_approved: Este amonestamiento fue apelado kon sukseso i ya no es valido appeal_rejected: La apelasyon fue refuzada appeal_submitted_at: Apelasyon embiada appealed_msg: Tu apelasyon fue embiada. Si la achetamos, se te avizara. @@ -1143,6 +1183,7 @@ lad: add_new: Adjusta muevo errors: limit: Tienes alkansado el karar maksimo de etiketas + hint_html: "Avalia tus etiketas mas importantes en tu profil. Se amostran de forma prominente en tu profil publiko i permeten a los utilizadores navigar por tus publikasyones publikas espesifikamente basho akeyas etiketas." filters: contexts: account: Profiles @@ -1154,7 +1195,11 @@ lad: add_keyword: Adjusta biervo yave keywords: Biervos yaves statuses: Publikasyones individualas + statuses_hint_html: Este filtro se aplika a las publikasyones individualas eskojidas endependientemente de si koensidan kon los biervos yave a kontinuasyon. Revize o suprema publikasyones del filtro. title: Edita filtro + errors: + deprecated_api_multiple_keywords: Estos parametros no se pueden trokar dizde esta aplikasyon porke se aplikan a mas de un biervo yave de filtro. Utiliza una aplikasyon mas reziente o la enterfaz web. + invalid_context: Se suminstro un konteksto malato o vazyo index: contexts: Filtros en %{contexts} delete: Efasa @@ -1191,7 +1236,13 @@ lad: none: Dinguno order_by: Ordena por save_changes: Guadra trokamientos + select_all_matching_items: + one: Eskoje %{count} elemento ke koensida kon tu bushkeda. + other: Eskoje todos los %{count} elementos ke koensidan kon tu bushkeda. today: oy + validation_errors: + one: Algo no esta bien! Por favor, reviza el yerro mas abasho + other: Algo no esta bien! Por favor, reviza %{count} yerros mas abasho imports: errors: empty: Dosya CSV vaziya @@ -1208,6 +1259,7 @@ lad: recent_imports: Importasyones resyentes states: finished: Finalizado + in_progress: En progreso scheduled: Programado unconfirmed: Sin konfirmasyon status: Estado @@ -1250,6 +1302,7 @@ lad: one: 1 uzo other: "%{count} uzos" max_uses_prompt: Sin limito + prompt: Djenera i partaja atadijos kon otros para darles akseso a este sirvidor table: expires_at: Kaduka uses: Uzos @@ -1314,8 +1367,16 @@ lad: disabled_account: Tu kuento aktual no sera kompletamente utilizable dempues. Portanto, tendras akseso a la eksportasyon de datos ansi komo a la reaktivasyon. followers: Esta aksion migrara a todos los suivantes del kuento aktual al muevo kuento only_redirect_html: Alternativamente, solo puedes poner un readreso en tu profil. + other_data: No se moveran otros datos otomatikamente + redirect: El profil de tu kuento aktual se aktualizara kon un avizo de readreso i sera eskluido de las bushkedas moderation: title: Moderasyon + move_handler: + carry_blocks_over_text: Este utilizador se movio dizde %{acct}, ke blokates. + carry_mutes_over_text: Este utilizador se movio dizde %{acct}, ke silensiates. + copy_account_note_text: 'Este utilizador se movio dizde %{acct}, aki estavan tus notas anteriores sovre el:' + navigation: + toggle_menu: Alterna menu notification_mailer: admin: report: @@ -1353,6 +1414,7 @@ lad: notifications: administration_emails: Avizos de administrasyon por posta email_events: Evenimyentos para avizos por posta + email_events_hint: 'Eskoje los evenimientos para los kualos keres risivir avizos:' other_settings: Otras preferensyas de avizos number: human: @@ -1365,6 +1427,8 @@ lad: thousand: K trillion: T otp_authentication: + code_hint: Introduse el kodiche jenerado por tu aplikasyon de autentifikasyon para konfirmar + description_html: Si kapasitas autentifikasyon en dos pasos kon una aplikasyon de autentifikasyon, la entrada rekerira ke estes en posesyon de tu telefon, ke djenerara kodiches para ke entres. enable: Kapasita instructions_html: "Eskanea este kodiche QR dizde Google Authenticator o una aplikasyon similar en tu telefon. A partir de agora, esta aplikasyon djenerara kodiches ke tendras ke ingresar kuando keras konektarte kon tu kuento." manual_instructions: 'Si no puedes eskanear el kodiche QR i nesesitas introdusirlo manualmente, este es el sekreto en teksto plano:' @@ -1418,14 +1482,24 @@ lad: mutual: Mutual primary: Prinsipal relationship: Relasyon + remove_selected_domains: Kita todos los suivantes de los domenos eskojidos remove_selected_followers: Kita a los suivantes eskojidos remove_selected_follows: Desige a los utilizadores eskojidos status: Estado del kuento + remote_follow: + missing_resource: No se pudo topar el URL del readreso rekerido para tu kuento + reports: + errors: + invalid_rules: no faze referensia a reglas validas rss: content_warning: 'Avertensya de kontenido:' descriptions: account: Publikasyones publikas de @%{acct} tag: 'Publikasyones publikas etiketadas kon #%{hashtag}' + scheduled_statuses: + over_daily_limit: Tienes superado el limito de %{limit} publikasyones programadas para akel diya + over_total_limit: Tienes superado el limito de %{limit} publikasyones programadas + too_soon: La data programada deve estar en el avenir self_destruct: title: Este sirvidor esta serrando sessions: @@ -1453,6 +1527,7 @@ lad: weibo: Weibo current_session: Sesyon aktuala description: "%{browser} en %{platform}" + explanation: Estos son los navigadores internetikos konektados aktualmente kon tu kuento de Mastodon. ip: IP platforms: adobe_air: Adobe Air @@ -1543,11 +1618,16 @@ lad: public: Publiko public_long: Todos pueden ver unlisted: No listado + unlisted_long: Todos pueden ver, ama no esta listado en las linyas de tiempo publikas statuses_cleanup: enabled: Otomatikamente efasa publikasyones viejas + enabled_hint: Supreme otomatikamente tus publikasyones kuando alkansen un limito de tiempo espesifikado, a manko ke koensiden kon alguna de las eksepsiones detalyadas debasho exceptions: Eksepsiones + explanation: Porke la efasasion de mesajes es una operasyon kostoza, esto se faze avagar, a lo longo de un tiempo, kuando el sirvidor no esta okupado. Por esta razon, puede ser ke tus publikasyones sean efasadas un tiempo dempues de ke alkansen el limito de tiempo espesifikado. ignore_favs: Ignora favoritos ignore_reblogs: Ignora repartajasyones + interaction_exceptions: Eksepsiones bazadas en enteraksyones + interaction_exceptions_explanation: Akodrate ke no ay garantiya de ke se supremen las publikasyones ke estan por debasho de los limitos de favoritos o de repartajasiones si los tienen superado en algun momento. keep_direct: Manten enmentaduras privadas keep_direct_hint: No efasa dingunos mesajes privados keep_media: Manten publikasyones kon atamientos @@ -1569,8 +1649,11 @@ lad: '604800': 1 semana '63113904': 2 anyos '7889238': 3 mezes + min_age_label: Limito de tiempo min_favs: Manten publikasyones favoritadas a lo manko + min_favs_hint: No efasa dinguna de las publikasyones ke plazgan a mas de esta kantita de personas. Desha en blanko para supremir publikasyones sin importar el numero de personas a las ke plazen las publikasyones min_reblogs: Manten publikasyones repartajadas a lo manko + min_reblogs_hint: No efasa dinguna de las publikasyones ke ayan sido repartajadas mas de este numero de vezes. Desha en blanko para supremir publikasyones sin importar el numero de repartajasiones stream_entries: sensitive_content: Kontenido sensivle strikes: @@ -1635,6 +1718,8 @@ lad: disable: Ya no puedes uzar tu kuento, ama tu profil i el resto de datos permanesen intactos. Puedes solisitar una kopia de sigurita de tus datos, trokar la konfigurasyon de tu kuento o supremirlo. mark_statuses_as_sensitive: Algunas de tus publikasyones an sido markados komo sensivles por los moderadores de %{instance}. Esto sinyifika ke la djente tendra ke pulsar los dosyas multimedia en las publikasyones antes de ke se amostre una vista previa. Puedes markar los dosyas multimedia komo sensivles tu mezmo kuando publikes en el avenir. sensitive: A partir de agora todas los dosyas multimedia ke subas seran markados komo sensivles i eskondidos tras una avertensya. + silence: Ainda puedes uzar tu kuento, ama solo las personas ke te estan sigiendo veran tus publikasyones en este sirvidor, i puedes ser eskluido de varias fonksionalitas de diskuvrimiento. Portanto, otros kuentos podran ampesar a segirte manualmente. + suspend: Ya no puedes utilizar tu kuento, i tu profil i el resto de datos ya no son aksesivles. Ainda puedes inisyar sesion para solisitar una kopia de sigurita de tus datos, asta ke estos sean supremidos por kompleto en unos 30 diyas, aunke konservaremos algunos datos bazikos para impedir ke evitas la suspensyon. reason: 'Razon:' statuses: 'Publikasyones relevantes:' subject: @@ -1655,7 +1740,12 @@ lad: suspend: Kuento suspendido welcome: edit_profile_action: Konfigurasyon de profil + edit_profile_step: Puedes personalizar tu profil kargando una foto de profil, trokando tu nombre de utilizador i muncho mas. Puedes optar por revizar a los muevos suivantes antes de ke puedan segirte. + explanation: Aki ay algunos konsejos para ampesar final_action: Ampesa a publikar + final_step: 'Ampesa a publikar! Inkluzo sin suivantes, tus publikasyones publikas pueden ser vistas por otros, por enshemplo en la linya de tiempo lokal o en etiketas. Tal vez keras aprezentarte kon la etiketa de #introduksiones.' + full_handle: Tu sovrenombre kompleto + full_handle_hint: Esto es lo ke le dirias a tus haverim para ke eyos puedan embiarte mesajes o segirte dizde otra instansya. subject: Bienvenido a Mastodon title: Bienvenido, %{name}! users: @@ -1668,10 +1758,12 @@ lad: webauthn_credentials: add: Adjusta mueva yave de sigurita create: + error: Uvo un problem al adjustar tu yave de sigurita. Por favor aprova de muevo. success: Tu yave de sigurita fue adjustada kon sukseso. delete: Efasa delete_confirmation: Estas siguro ke keres efasar esta yave de sigurita? destroy: + error: Uvo un problem al efasar tu yave de sigurita. Por favor aprova de muevo. success: Tu yave de sigurita fue efasada kon sukseso. invalid_credential: Yave de sigurita no valida nickname_hint: Introduska el sovrenombre de tu mueva yave de sigurita diff --git a/config/locales/simple_form.fa.yml b/config/locales/simple_form.fa.yml index 5ff495a540..23fbc43b07 100644 --- a/config/locales/simple_form.fa.yml +++ b/config/locales/simple_form.fa.yml @@ -162,7 +162,7 @@ fa: defaults: autofollow: دعوت از دیگران برای عضو شدن و پیگیری حساب شما avatar: تصویر نمایه - bot: این حساب یک ربات است + bot: این یک حساب خودکار شده است chosen_languages: جدا کردن زبان‌ها confirm_new_password: تأیید گذرواژه تازه confirm_password: تأیید گذرواژه diff --git a/config/locales/simple_form.ie.yml b/config/locales/simple_form.ie.yml index 672ff9d003..3bcce47d36 100644 --- a/config/locales/simple_form.ie.yml +++ b/config/locales/simple_form.ie.yml @@ -3,11 +3,20 @@ ie: simple_form: hints: account: + discoverable: Tui public postas e profil posse esser recomandat in multiplic areas de Mastodon e tui profil posse esser suggestat a altri usatores. + display_name: Tui complet nómine o tui amusant nómine. + fields: Tui websitu, pronómines, etá, quocunc quel tu vole. + note: 'Tu posse @mentionar altri persones o #hashtags.' unlocked: Persones va posser sequer te sin petir aprobation. Desselecte si tu vole manualmen tractar petitiones de sequer e decider ca acceptar o rejecter nov sequitores. + account_alias: + acct: Specificar li usatornomine@dominia del conto ex quel tu vole translocar + account_migration: + acct: Specificar li usatornomine@dominia del conto a quel tu vole translocar account_warning_preset: text: Tu posse usar posta-sintaxe, quam URLs, hashtags e mentiones title: Ínobligatori. Ne visibil al recipiente admin_account_action: + include_statuses: Li usator va posser vider quel postas ha causat li moderatori action o admonition send_email_notification: Li usator va reciver un explication de ti quel evenit con su conto text_html: Ínobligatori. Tu posse usar posta-sintaxe. Tu posse adjunter preconfigurationes de avises por sparar témpor type_html: Selecte quo far con %{acct} @@ -48,24 +57,49 @@ ie: setting_display_media_default: Celar medie marcat quam sensitiv setting_display_media_hide_all: Sempre celar medie setting_display_media_show_all: Sempre monstrar medie + featured_tag: + name: 'Vi quelc hashtags usat max recentmen de te:' + filters: + action: Selecter quel action a far quande un posta egala un filtre + actions: + hide: Celar completmen li contenete filtrat, quam si it ne existe + warn: Celar li contenete filtrat detra un avise mentionant li titul del filtre form_admin_settings: bootstrap_timeline_accounts: Ti-ci contos va esser pinglat al parte superiori del recomandationes por nov usatores. + peers_api_enabled: Un liste de nómines de dominia queles ti-ci servitor ha incontrat in li fediverse. Ci null data es includet pri ca tu confedera con un cert servitor o ne; it indica solmen que tui servitor conosse it. Usat per servicies colectent general statisticas pri federation. + profile_directory: Li profilarium monstra omni usatores volent esser decovribil. + site_contact_email: Qualmen on posse contacter te por inquestes legal o de apoy. site_contact_username: Qualmen li gente posse atinger te sur Mastodon. + site_title: Quant persones posse aluder a tui servitor ultra su nómine de dominia. theme: Li dessine quel ínregistrat visitantes e nov usatores vide. timeline_preview: Ínregistrat visitantes va posser vider li max recent public postas disponibil che li servitor. trends_as_landing_page: Monstrar populari contenete a ínregistrat visitantes vice un description del servitor. Besona que tendenties es activisat. form_challenge: current_password: Tu nu intra un area secur ip_block: + comment: Facultativ. Ne obliviar pro quo tu adjuntet ti-ci regul. severities: sign_up_block: Nov registrationes ne va esser possibil sign_up_requires_approval: Nov registrationes va besonar tui aprobation + severity: Selecter quo va evenir con demandes ex ti-ci IP + rule: + text: Descrir un regul o postulation por usatores sur ti-ci servitor. Prova scrir un descrition curt e simplic + user: + role: Permissiones de usator decidet per su rol + user_role: + color: Color a usar por li rol tra li UI, quam RGB (rubi-verdi-blu) in formate hex + highlighted: Va far li rol publicmen visibil + name: Public nómine del rol, si li rol va esser monstrat quam signe + permissions_as_keys: Usatores con ti-ci rol va haver accesse a... webhook: events: Selecter evenimentes a misser + template: Composir tui propri carga JSON usant interpolation de variabiles. Lassa blanc por JSON predefinit. url: Ad u misser evenimentes labels: account: + discoverable: Monstrar profil e postas in algoritmes de decovrition fields: + name: Etiquette value: Contenete indexable: Includer public postas in resultates de sercha account_warning_preset: @@ -73,7 +107,14 @@ ie: title: Titul admin_account_action: send_email_notification: Notificar li usator per e-posta + text: Admonition customisat type: Action + types: + disable: Gelar + none: Misser un admonition + sensitive: Sensitiv + silence: Limitar + suspend: Suspender warning_preset_id: Usar un prefiguration de avise announcement: all_day: Eveniment del tot die @@ -81,7 +122,12 @@ ie: scheduled_at: Planar publication starts_at: Comense del eveniment text: Proclamation + appeal: + text: Explicar pro que ti-ci decision mey esser renversat defaults: + autofollow: Invitar a sequer tui conto + avatar: Foto de profil + bot: Ti-ci conto es automatisat chosen_languages: Filtrar lingues confirm_new_password: Confirmar nov passa-parol confirm_password: Confirmar passa-parol @@ -91,28 +137,94 @@ ie: display_name: Nómine a monstrar email: E-posta expires_in: Expirar pos + fields: Campes aditional + header: Cap-image honeypot: "%{label} (ne plenar)" + irreversible: Lassar cader vice celar locale: Lingue del interfacie new_password: Nov passa-parol note: Biografie password: Passa-parol + phrase: Clave-parol o frase + setting_advanced_layout: Possibilisar web-interfacie avansat setting_default_language: Lingue in quel postar setting_default_privacy: Privatie de postada setting_default_sensitive: Sempre marcar medie quam sensitiv setting_display_media_default: Predefinitiones setting_display_media_hide_all: Celar omno setting_display_media_show_all: Monstrar omno + setting_expand_spoilers: Sempre expander postas marcat con admonitiones de contenete + setting_system_font_ui: Usar predefinit fonte de sistema setting_theme: Tema de situ setting_trends: Monstrar li hodial tendenties setting_unfollow_modal: Monstrar dialog de confirmation ante dessequer alquem setting_use_pending_items: Mode lent + severity: Severitá + sign_in_token_attempt: Code de securitá + title: Titul + username: Nómine de usator + whole_word: Plen parol + filters: + actions: + warn: Celar con un admonition form_admin_settings: + custom_css: Custom CSS + profile_directory: Possibilisar profilarium registrations_mode: Qui posse registrar se + show_domain_blocks: Vider bloccas de dominia + show_domain_blocks_rationale: Monstrar pro quo cert dominias esset bloccat + site_contact_email: Contact e-mail adresse + site_title: Nómine de servitor theme: Predefenit tema + trendable_by_default: Possibilisar tendenties sin priori inspection trends: Possibilisar tendenties trends_as_landing_page: Usar tendenties quam frontispicie + invite: + comment: Comentar + invite_request: + text: Pro quo tu vole adherer? + ip_block: + comment: Comentar + ip: IP + severities: + no_access: Bloccar accesse + sign_up_block: Bloccar usator-registrationes + sign_up_requires_approval: Limitar usator-registrationes + severity: Regul notification_emails: + favourite: Alqui favoritisat tui posta + follow: Alqui sequet te follow_request: Alqui petit sequer te + mention: Alqui mentionat te + pending_account: Nov conto besonant inspection + report: Nov raporte es submisset + software_updates: + all: Notificar pri omni nov actualisationes + critical: Notificar solmen pri critical actualisationes + label: Un nov version de Mastodon es disponibil trending_tag: Nov tendentie besonant inspection + rule: + text: Regul tag: + name: Hashtag trendable: Permisse que ti-ci hashtag apari sub tendenties + user: + role: Rol + time_zone: Zone temporal + user_role: + color: Color del insignie + name: Nómine + permissions_as_keys: Permissiones + position: Prioritá + webhook: + events: Evenimentes activisat + url: URL de punctu terminal + 'no': 'No' + recommended: Recomandat + required: + mark: "*" + text: besonat + title: + sessions: + webauthn: Usar un de tui claves de securitá por intrar + 'yes': 'Yes' diff --git a/config/locales/simple_form.lad.yml b/config/locales/simple_form.lad.yml index aeac5f1c58..c23960e07d 100644 --- a/config/locales/simple_form.lad.yml +++ b/config/locales/simple_form.lad.yml @@ -3,10 +3,13 @@ lad: simple_form: hints: account: + discoverable: Tus publikasyones publikas i profil pueden ser avaliadas o rekomendadas en varias partes de Mastodon i tu profil puede ser sujerido a otros utilizadores. display_name: Tu nombre para amostrar. fields: Tu deskripsyon, pronombres, edad, todo lo ke keras. + indexable: Tus publikasyones publikas pueden apareser en rezultados de bushkeda en Mastodon. Personas ke enteraktuaron kon tus publikasyones syempre pueden bushkarlas inkluzo si trokes esta preferensya. note: 'Puedes @enmentar a otra djente o #etiketas.' show_collections: Otra djente podra ver tus segidos i suivantes. Personas a las kualas siges siempre podran ver que las estas sigiendo. + unlocked: Djente va poder segirte sin solisitar tu achetasyon. Deseleksyona si keres revizar solisitasyones de segimyento i dechidir si keres achetar o refuzar a muevos suivantes. account_alias: acct: Espesifika tu nombre de utilizador@domeno del kuento de ande keres migrar account_migration: @@ -118,6 +121,7 @@ lad: otp: 'Introduse el kodiche de autentifikasyon de dos pasos djenerado por tu aplikasyon de telefon o uza uno de tus kodiches de recuperasyon:' webauthn: Si es una yave USB, asigurete de insertarla y, si es necesario, pulsala. settings: + indexable: Tu pajina de profil puede apareser en rezultados de bushkeda en Google, Bing i otros. show_application: Tu siempre podras ver dizde kuala aplikasyon publikates tu publikasyon. tag: name: Solo se puede trokar la kapitalizasyon de las letras, por enshemplo, para ke sea mas meldable @@ -132,9 +136,11 @@ lad: position: Un rolo mas alto deside la rezolusyon de konfliktos en algunas situasyones. Algunas aksyones solo pueden levarse por rolos kon menor priorita webhook: events: Eskoje evenimientos para embiar + template: Kriya tu propio JSON uzando interpolasyon de las variavlas. Deshalo en blanko para el JSON predeterminado. url: Ande los evenimientos seran embiados labels: account: + discoverable: Avalia profil i publikasyones en algoritmos de deskuvrimyento fields: name: Etiketa value: Kontenido @@ -183,6 +189,9 @@ lad: expires_in: Kaduka dempues de fields: Datos adisyonales header: Imaje de kavesera + honeypot: "%{label} (no inche)" + inbox_url: URL del kuti de relevo + irreversible: Refuza en lugar de eskonder locale: Lingua de enterfaz max_uses: Maksimo numero de uzos new_password: Muevo kod @@ -190,17 +199,27 @@ lad: otp_attempt: Kodiche de dos pasos password: Kod phrase: Biervo yave o fraza + setting_advanced_layout: Kapasita la enterfaz web avanzada setting_aggregate_reblogs: Agrupa repartajasyones en linyas setting_always_send_emails: Siempre embia avizos por posta setting_auto_play_gif: Siempre reproduse los GIFs animados + setting_boost_modal: Amostra ventana de konfirmasyon antes de repartajar setting_default_language: Lingua de publikasyones setting_default_privacy: Privasita de publikasyones + setting_default_sensitive: Syempre marka multimedia komo sensivles + setting_delete_modal: Mostra dialogo de konfirmasyon antes de efasar una publikasyon + setting_disable_swiping: Inkapasita movimyentos de arresvalamiento + setting_display_media: Vizualizasyon de multimedia setting_display_media_default: Predeterminado setting_display_media_hide_all: Eskonde todo setting_display_media_show_all: Amostra todo + setting_expand_spoilers: Siempre espande las publikasyones markadas kon avertensyas de kontenido + setting_hide_network: Eskonde tu red sosyala setting_reduce_motion: Reduse el movimyento en animasyones setting_system_font_ui: Uza el font predeterminado del sistem + setting_theme: Tema del sitio setting_trends: Amostra los trendes de oy + setting_unfollow_modal: Mostra dialogo de konfirmasyon antes de desegir a alguno setting_use_blurhash: Amostra gradientes koloridos para kontenido multimedia eskondido setting_use_pending_items: Modo lento severity: Severita @@ -263,6 +282,8 @@ lad: sign_up_requires_approval: Limita enrejistrasyones severity: Regla notification_emails: + appeal: Alguno tiene apelado una dechizyon de moderasyon + digest: Embia rezumen de posta elektronika favourite: A alguno le plaze tu publikasyon follow: Alguno te ampeso a segir follow_request: Alguno tiene solisitado segirte @@ -276,25 +297,38 @@ lad: label: Mueva version de Mastodon esta desponivle none: Nunkua avizame de aktualizasyones (no rekomendado) patch: Avizame de aktualizasyones de yerros + trending_tag: Un muevo trend nesesita revizyon rule: text: Regla settings: indexable: Inkluye la pajina de profil en los bushkadores + show_application: Amostra aplikasyon uzada para adjustar publikasyones tag: + listable: Permite ke esta etiketa apareska en bushkedas i sujestyones name: Etiketa + trendable: Permite ke esta etiketa apareska en trendes + usable: Permite ke publikasyones uzen esta etiketa user: role: Rolo + time_zone: Zona de tiempo user_role: + color: Kolor de insinya + highlighted: Mostra rolo komo insinya en profiles de utilizadores name: Nombre permissions_as_keys: Permisos position: Priorita webhook: events: Evenimientos kapasitados + template: Modelo de kontenido url: URL de Endpoint 'no': 'No' not_recommended: No rekomendado + overridden: Sovreskrive recommended: Rekomendado required: mark: "*" text: rekerido + title: + sessions: + webauthn: Uza una de tus yaves de sigurita para konektarte 'yes': Si diff --git a/config/locales/sk.yml b/config/locales/sk.yml index ab2bc51553..4fe190cfec 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -435,6 +435,7 @@ sk: delivery: all: Všetko failing: Zlyhávajúce + stop: Zastav doručenie unavailable: Nedostupné delivery_available: Je v dosahu doručovania empty: Nenájdené žiadne domény. @@ -579,6 +580,7 @@ sk: manage_roles: Spravuj postavenia manage_rules: Spravuj pravidlá manage_settings: Spravuj nastavenia + manage_user_access: Spravuj užívateľský prístup manage_users: Spravuj užívateľov title: Postavenia rules: @@ -621,9 +623,11 @@ sk: software_updates: critical_update: Kritické — prosím aktualizuj rýchlo documentation_link: Zisti viac + release_notes: Poznámky k vydaniu title: Dostupné aktualizácie types: major: Hlavné vydanie + patch: Opravné vydanie - opravy a jednoducho uplatniteľné zmeny version: Verzia statuses: account: Autor @@ -692,7 +696,9 @@ sk: title: Populárne príspevky tags: dashboard: + tag_servers_measure: iné servery tag_uses_measure: užívateľov celkovo + not_usable: Nemôže byť použitý title: Populárne štítky trending_rank: 'Populárne #%{rank}' usable: Môže byť použitý @@ -708,7 +714,11 @@ sk: disable: Vypni disabled: Vypnuté enable: Povoľ + status: Stav admin_mailer: + new_appeal: + actions: + none: varovanie new_pending_account: body: Podrobnosti o novom účte sú uvedené nižšie. Môžeš túto registračnú požiadavku buď prijať, alebo zamietnúť. subject: Nový účet očakáva preverenie na %{instance} (%{username}) @@ -757,6 +767,9 @@ sk: apply_for_account: Vyžiadaj si účet captcha_confirmation: title: Bezpečnostná kontrola + confirmations: + login_link: prihlás sa + welcome_title: Vitaj, %{name}! delete_account: Vymaž účet delete_account_html: Pokiaľ chceš svoj účet odtiaľto vymazať, môžeš tak urobiť tu. Budeš požiadaný/á o potvrdenie tohto kroku. description: @@ -786,6 +799,9 @@ sk: setup: link_not_received: Nedostal/a si odkaz? title: Skontroluj svoju schránku + sign_in: + preamble_html: Prihlás sa so svojimi údajmi pre %{domain}. Pokiaľ je tvoj účet hostovaný na inom serveri, nebudeš sa môcť prihlásiť tu. + title: Prihlás sa na %{domain} status: account_status: Stav účtu confirming: Čaká sa na dokončenie potvrdenia emailom. @@ -841,6 +857,9 @@ sk: silence: Obmedzenie účtu domain_validator: invalid_domain: nieje správny tvar domény + edit_profile: + basic_information: Základné informácie + other: Ostatné errors: '400': Požiadavka, ktorú si odoslal/a, bola buď nesprávna, alebo znehodnotená. '403': Nemáš povolenie pre zobrazenie tejto stránky. @@ -885,22 +904,28 @@ sk: public: Verejné osi thread: Konverzácie edit: + add_keyword: Pridaj kľúčové slovo + keywords: Kľúčové slová title: Uprav triedenie errors: invalid_context: Nebola poskytnutá žiadna, alebo ide o neplatnú súvislosť index: delete: Vymaž empty: Nemáš žiadné filtrovanie. + expires_on: Expiruje dňa %{date} title: Triedenia new: title: Pridaj nové triedenie generic: all: Všetko + cancel: Zruš changes_saved_msg: Zmeny boli úspešne uložené! + confirm: Potvrď copy: Kopíruj delete: Vymaž order_by: Zoraď podľa save_changes: Ulož zmeny + today: dnes validation_errors: few: Niečo ešte nieje celkom v poriadku! Prosím skontroluj %{count} chýb uvedených nižšie many: Niečo ešte nieje celkom v poriadku! Prosím skontroluj %{count} chýb uvedených nižšie @@ -923,6 +948,7 @@ sk: bookmarks: Záložky domain_blocking: Zoznam blokovaných domén following: Zoznam sledovaných + lists: Zoznamy muting: Zoznam ignorovaných upload: Nahraj invites: @@ -1182,6 +1208,7 @@ sk: keep_pinned: Ponechaj pripnuté príspevky keep_pinned_hint: Nevymaže žiadne s tvojich pripnutých príspevkov keep_self_bookmark: Ponechaj príspevky, ktoré sú záložkami + keep_self_fav: Ponechať príspevky, ktoré si si obľúbil/a stream_entries: sensitive_content: Senzitívny obsah tags: From fd57e40681f1f9c15f83a440858bcd117af9ba1f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:55:05 +0100 Subject: [PATCH 021/422] Update dependency rubocop-performance to v1.20.1 (#28492) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5acee3d753..8e25f302bc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -680,7 +680,7 @@ GEM rubocop (~> 1.41) rubocop-factory_bot (2.24.0) rubocop (~> 1.33) - rubocop-performance (1.20.0) + rubocop-performance (1.20.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.30.0, < 2.0) rubocop-rails (2.23.1) From ba5f659bb3066dc8a70eaab469bba1b1398919a9 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 29 Dec 2023 05:55:50 -0500 Subject: [PATCH 022/422] Use shorter attribute query methods in `Announcement` (#28474) --- app/models/announcement.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/announcement.rb b/app/models/announcement.rb index 2cd7c1d5ed..83a8d3682c 100644 --- a/app/models/announcement.rb +++ b/app/models/announcement.rb @@ -28,8 +28,8 @@ class Announcement < ApplicationRecord has_many :announcement_reactions, dependent: :destroy validates :text, presence: true - validates :starts_at, presence: true, if: -> { ends_at.present? } - validates :ends_at, presence: true, if: -> { starts_at.present? } + validates :starts_at, presence: true, if: :ends_at? + validates :ends_at, presence: true, if: :starts_at? before_validation :set_published, on: :create @@ -46,7 +46,7 @@ class Announcement < ApplicationRecord end def time_range? - starts_at.present? && ends_at.present? + starts_at? && ends_at? end def mentions From 3599622b5bcdfd44f7df664428a749896fde319e Mon Sep 17 00:00:00 2001 From: Cal Moody Date: Fri, 29 Dec 2023 06:32:40 -0500 Subject: [PATCH 023/422] Fix destructive actions in dropdowns not using error color in light theme (#28484) --- app/javascript/styles/mastodon-light/diff.scss | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss index 3777fccbfb..3a27c974ad 100644 --- a/app/javascript/styles/mastodon-light/diff.scss +++ b/app/javascript/styles/mastodon-light/diff.scss @@ -300,10 +300,15 @@ html { } &__item { + color: $darker-text-color; + + &--dangerous { + color: $error-value-color; + } + a, button { background: $white; - color: $darker-text-color; } } } @@ -315,9 +320,9 @@ html { .privacy-dropdown__option.active .privacy-dropdown__option__content strong, .privacy-dropdown__option:hover .privacy-dropdown__option__content, .privacy-dropdown__option:hover .privacy-dropdown__option__content strong, -.dropdown-menu__item a:active, -.dropdown-menu__item a:focus, -.dropdown-menu__item a:hover, +.dropdown-menu__item:not(.dropdown-menu__item--dangerous) a:active, +.dropdown-menu__item:not(.dropdown-menu__item--dangerous) a:focus, +.dropdown-menu__item:not(.dropdown-menu__item--dangerous) a:hover, .actions-modal ul li:not(:empty) a.active, .actions-modal ul li:not(:empty) a.active button, .actions-modal ul li:not(:empty) a:active, From fcfdeadc04983ab6937df6ce6a04dbe38e33b1a5 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 29 Dec 2023 17:23:07 +0100 Subject: [PATCH 024/422] Fix random `NoMethodError` errors on cached `CustomFilter` objects (#28521) --- app/models/custom_filter.rb | 19 +++++++++++++++++-- app/models/custom_filter_keyword.rb | 10 +++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb index 5a53e73ba8..9c936fed39 100644 --- a/app/models/custom_filter.rb +++ b/app/models/custom_filter.rb @@ -17,8 +17,23 @@ class CustomFilter < ApplicationRecord self.ignored_columns += %w(whole_word irreversible) - alias_attribute :title, :phrase - alias_attribute :filter_action, :action + # NOTE: We previously used `alias_attribute` but this does not play nicely + # with cache + def title + phrase + end + + def title=(value) + self.phrase = value + end + + def filter_action + action + end + + def filter_action=(value) + self.action = value + end VALID_CONTEXTS = %w( home diff --git a/app/models/custom_filter_keyword.rb b/app/models/custom_filter_keyword.rb index 3158b3b79a..1812a43081 100644 --- a/app/models/custom_filter_keyword.rb +++ b/app/models/custom_filter_keyword.rb @@ -17,7 +17,15 @@ class CustomFilterKeyword < ApplicationRecord validates :keyword, presence: true - alias_attribute :phrase, :keyword + # NOTE: We previously used `alias_attribute` but this does not play nicely + # with cache + def phrase + keyword + end + + def phrase=(value) + self.keyword = value + end before_save :prepare_cache_invalidation! before_destroy :prepare_cache_invalidation! From 6374358357ee81b5f137f471f028a56974109155 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 29 Dec 2023 17:34:13 +0100 Subject: [PATCH 025/422] Change media to be hidden/blurred by default in report modal (#28522) --- app/javascript/mastodon/components/media_attachments.jsx | 5 ++++- .../mastodon/features/report/components/status_check_box.jsx | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/components/media_attachments.jsx b/app/javascript/mastodon/components/media_attachments.jsx index 7b945a0ea2..63fe3e67f9 100644 --- a/app/javascript/mastodon/components/media_attachments.jsx +++ b/app/javascript/mastodon/components/media_attachments.jsx @@ -15,6 +15,7 @@ export default class MediaAttachments extends ImmutablePureComponent { lang: PropTypes.string, height: PropTypes.number, width: PropTypes.number, + visible: PropTypes.bool, }; static defaultProps = { @@ -51,7 +52,7 @@ export default class MediaAttachments extends ImmutablePureComponent { }; render () { - const { status, width, height } = this.props; + const { status, width, height, visible } = this.props; const mediaAttachments = status.get('media_attachments'); const language = status.getIn(['language', 'translation']) || status.get('language') || this.props.lang; @@ -99,6 +100,7 @@ export default class MediaAttachments extends ImmutablePureComponent { height={height} inline sensitive={status.get('sensitive')} + visible={visible} onOpenVideo={noop} /> )} @@ -113,6 +115,7 @@ export default class MediaAttachments extends ImmutablePureComponent { lang={language} sensitive={status.get('sensitive')} defaultWidth={width} + visible={visible} height={height} onOpenMedia={noop} /> diff --git a/app/javascript/mastodon/features/report/components/status_check_box.jsx b/app/javascript/mastodon/features/report/components/status_check_box.jsx index 8bee76e591..481ee3e5ed 100644 --- a/app/javascript/mastodon/features/report/components/status_check_box.jsx +++ b/app/javascript/mastodon/features/report/components/status_check_box.jsx @@ -47,7 +47,7 @@ class StatusCheckBox extends PureComponent { - + ); From ac588daf37784d5f7260577d404605e85f2df56f Mon Sep 17 00:00:00 2001 From: Dennis Kamau <97116157+devcamke@users.noreply.github.com> Date: Mon, 1 Jan 2024 22:08:01 +0300 Subject: [PATCH 026/422] Update copyright year to 2024 (#28550) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b22d61b5e..267f0ed295 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ You can open issues for bugs you've found or features you think are missing. You ## License -Copyright (C) 2016-2023 Eugen Rochko & other Mastodon contributors (see [AUTHORS.md](AUTHORS.md)) +Copyright (C) 2016-2024 Eugen Rochko & other Mastodon contributors (see [AUTHORS.md](AUTHORS.md)) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. From c652b0e46b6655366d976e8e18b92c63b734b91b Mon Sep 17 00:00:00 2001 From: Michael Stanclift Date: Tue, 2 Jan 2024 02:47:38 -0600 Subject: [PATCH 027/422] Add wget to base Dockerfile (#28548) --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 4d5bd57f11..96f8b5cd27 100644 --- a/Dockerfile +++ b/Dockerfile @@ -103,6 +103,7 @@ RUN \ procps \ tini \ tzdata \ + wget \ ; \ # Patch Ruby to use jemalloc patchelf --add-needed libjemalloc.so.2 /usr/local/bin/ruby; \ From e082a98b4d2b3adc8cd4172a51ee53000af4eaab Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:50:08 +0100 Subject: [PATCH 028/422] Update dependency mime-types to v3.5.2 (#28556) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8e25f302bc..08b9fc0de4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -457,9 +457,9 @@ GEM azure-storage-blob (~> 2.0.1) hashie (~> 5.0) memory_profiler (1.0.1) - mime-types (3.5.1) + mime-types (3.5.2) mime-types-data (~> 3.2015) - mime-types-data (3.2023.1003) + mime-types-data (3.2023.1205) mini_mime (1.1.5) mini_portile2 (2.8.5) minitest (5.20.0) From 663a7b6ba91b5d10944f8555aca3fb99e009e0ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 08:50:29 +0000 Subject: [PATCH 029/422] Update devDependencies (non-major) (#28543) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 107 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 48 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1baa0da058..298ffd4eea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,10 +12,10 @@ __metadata: languageName: node linkType: hard -"@adobe/css-tools@npm:^4.3.1": - version: 4.3.1 - resolution: "@adobe/css-tools@npm:4.3.1" - checksum: 05672719b544cc0c21ae3ed0eb6349bf458e9d09457578eeeb07cf0f696469ac6417e9c9be1b129e5d6a18098a061c1db55b2275591760ef30a79822436fcbfa +"@adobe/css-tools@npm:^4.3.2": + version: 4.3.2 + resolution: "@adobe/css-tools@npm:4.3.2" + checksum: 296a03dd29f227c60500d2da8c7f64991fecf1d8b456ce2b4adb8cec7363d9c08b5b03f1463673fc8cbfe54b538745588e7a13c736d2dd14a80c01a20f127f39 languageName: node linkType: hard @@ -1539,38 +1539,38 @@ __metadata: languageName: node linkType: hard -"@csstools/css-parser-algorithms@npm:^2.3.2": - version: 2.3.2 - resolution: "@csstools/css-parser-algorithms@npm:2.3.2" +"@csstools/css-parser-algorithms@npm:^2.4.0": + version: 2.5.0 + resolution: "@csstools/css-parser-algorithms@npm:2.5.0" peerDependencies: - "@csstools/css-tokenizer": ^2.2.1 - checksum: ccae373a3ab5c10716418b69ce1f6db10a26d3a2d60b65df5fe69099afe4fb1d3192925f3c0f93c3b17c3ab1964b0f39ad2b0e97312ec4a51caa55d6b6a31672 + "@csstools/css-tokenizer": ^2.2.3 + checksum: 31b4a523d956e204af9842183678cca5a88ad76551d54dcb6083f8a6f2dfd8fdec6c09bca5410842af54b90997308bebee7593c17dbc1a4e951453b54bd3f024 languageName: node linkType: hard -"@csstools/css-tokenizer@npm:^2.2.1": - version: 2.2.1 - resolution: "@csstools/css-tokenizer@npm:2.2.1" - checksum: 0c6901d291e99c567893846a47068057c2a28b3edc4219b6da589a530f55f51ddd4675f906f707b393bfe7a508ab2604bf3f75708f064db857bb277636bd5a44 +"@csstools/css-tokenizer@npm:^2.2.2": + version: 2.2.3 + resolution: "@csstools/css-tokenizer@npm:2.2.3" + checksum: 557266ec52e8b36c19008a5bbd7151effba085cdd6d68270c01afebf914981caac698eda754b2a530a8a9947a3dd70e3f3a39a5e037c4170bb2a055a92754acb languageName: node linkType: hard -"@csstools/media-query-list-parser@npm:^2.1.5": - version: 2.1.5 - resolution: "@csstools/media-query-list-parser@npm:2.1.5" +"@csstools/media-query-list-parser@npm:^2.1.6": + version: 2.1.7 + resolution: "@csstools/media-query-list-parser@npm:2.1.7" peerDependencies: - "@csstools/css-parser-algorithms": ^2.3.2 - "@csstools/css-tokenizer": ^2.2.1 - checksum: ae0692c6f92cdc82053291c7a50028b692094dfed795f0259571c5eb40f4b3fa580182ac3701e56c2834e40a62a122ea6639299e43ae88b3a835ae4c869a1a12 + "@csstools/css-parser-algorithms": ^2.5.0 + "@csstools/css-tokenizer": ^2.2.3 + checksum: 433aef06b00f1d402fd24074a1919b8e2de94245a3b780da6466c8cc9e0f3cc93d2db930f0fce36c7d6908cd50b626cd61e803d3f62dddad79eeb742858028ef languageName: node linkType: hard -"@csstools/selector-specificity@npm:^3.0.0": - version: 3.0.0 - resolution: "@csstools/selector-specificity@npm:3.0.0" +"@csstools/selector-specificity@npm:^3.0.1": + version: 3.0.1 + resolution: "@csstools/selector-specificity@npm:3.0.1" peerDependencies: postcss-selector-parser: ^6.0.13 - checksum: 6f0e2fa9a3c5dcbc7a446fd827d3eb85ca775cc884f73f0bbb119ab49b4f5f0af8763dd23a37d423f4e7989069c09bb977e7e5f017db296e1417abb1fba75c30 + checksum: 4280f494726d5e38de74e28dee2ff74ec86244560dff4edeec3ddff3ac73c774c19535bd1bb70cad77949bfb359cf87e977d0ec3264591e3b7260342a20dd84f languageName: node linkType: hard @@ -2894,10 +2894,10 @@ __metadata: linkType: hard "@testing-library/jest-dom@npm:^6.0.0": - version: 6.1.5 - resolution: "@testing-library/jest-dom@npm:6.1.5" + version: 6.1.6 + resolution: "@testing-library/jest-dom@npm:6.1.6" dependencies: - "@adobe/css-tools": "npm:^4.3.1" + "@adobe/css-tools": "npm:^4.3.2" "@babel/runtime": "npm:^7.9.2" aria-query: "npm:^5.0.0" chalk: "npm:^3.0.0" @@ -2919,7 +2919,7 @@ __metadata: optional: true vitest: optional: true - checksum: f3643a56fcd970b5c7e8fd10faf3c4817d8ab0e74fb1198d726643bdc5ac675ceaac3b0068c5b4fbad254470e8f98ed50028741de875a29ceaa2f854570979c9 + checksum: f98f79f3e470517469c86947d0ff1bb83ac2e59fd2a29728ab306eca5fba63c948084ec06b7b531642e6002d1f0211d918c298c628f0d386c0ef63ba881c47ba languageName: node linkType: hard @@ -7940,12 +7940,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^7.0.2": - version: 7.0.2 - resolution: "file-entry-cache@npm:7.0.2" +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" dependencies: - flat-cache: "npm:^3.2.0" - checksum: 822664e35c3e295e6a8ca7ec490d8d8077017607f41f94b29922f1f49c6dd07025048e3ed528e2909a1439eba66d60f802c0774aa612cf6ee053ee4ecc16c8c5 + flat-cache: "npm:^4.0.0" + checksum: 9e2b5938b1cd9b6d7e3612bdc533afd4ac17b2fc646569e9a8abbf2eb48e5eb8e316bc38815a3ef6a1b456f4107f0d0f055a614ca613e75db6bf9ff4d72c1638 languageName: node linkType: hard @@ -8079,7 +8079,7 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^3.0.4, flat-cache@npm:^3.2.0": +"flat-cache@npm:^3.0.4": version: 3.2.0 resolution: "flat-cache@npm:3.2.0" dependencies: @@ -8090,6 +8090,17 @@ __metadata: languageName: node linkType: hard +"flat-cache@npm:^4.0.0": + version: 4.0.0 + resolution: "flat-cache@npm:4.0.0" + dependencies: + flatted: "npm:^3.2.9" + keyv: "npm:^4.5.4" + rimraf: "npm:^5.0.5" + checksum: 8f99e27bb3de94e91e7b4ca5120488cdc2b7f8cd952a538f1a566101963057eb42ca318e9fac0d36987dcca34316ff04b61c1dc3dcc8084f6f5e801a52a8e547 + languageName: node + linkType: hard + "flat@npm:^5.0.2": version: 5.0.2 resolution: "flat@npm:5.0.2" @@ -10737,7 +10748,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.3": +"keyv@npm:^4.5.3, keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -11265,10 +11276,10 @@ __metadata: languageName: node linkType: hard -"meow@npm:^12.1.1": - version: 12.1.1 - resolution: "meow@npm:12.1.1" - checksum: a125ca99a32e2306e2f4cbe651a0d27f6eb67918d43a075f6e80b35e9bf372ebf0fc3a9fbc201cbbc9516444b6265fb3c9f80c5b7ebd32f548aa93eb7c28e088 +"meow@npm:^13.0.0": + version: 13.0.0 + resolution: "meow@npm:13.0.0" + checksum: fab0f91578154c048e792a81704f3f28099ffff900f364df8a85f6e770a57e1c124859a25e186186e149dad30692c7893af0dfd71517bea343bfe5d749b1fa04 languageName: node linkType: hard @@ -14344,7 +14355,7 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^5.0.1": +"rimraf@npm:^5.0.1, rimraf@npm:^5.0.5": version: 5.0.5 resolution: "rimraf@npm:5.0.5" dependencies: @@ -15609,13 +15620,13 @@ __metadata: linkType: hard "stylelint@npm:^16.0.2": - version: 16.0.2 - resolution: "stylelint@npm:16.0.2" + version: 16.1.0 + resolution: "stylelint@npm:16.1.0" dependencies: - "@csstools/css-parser-algorithms": "npm:^2.3.2" - "@csstools/css-tokenizer": "npm:^2.2.1" - "@csstools/media-query-list-parser": "npm:^2.1.5" - "@csstools/selector-specificity": "npm:^3.0.0" + "@csstools/css-parser-algorithms": "npm:^2.4.0" + "@csstools/css-tokenizer": "npm:^2.2.2" + "@csstools/media-query-list-parser": "npm:^2.1.6" + "@csstools/selector-specificity": "npm:^3.0.1" balanced-match: "npm:^2.0.0" colord: "npm:^2.9.3" cosmiconfig: "npm:^9.0.0" @@ -15624,7 +15635,7 @@ __metadata: debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" fastest-levenshtein: "npm:^1.0.16" - file-entry-cache: "npm:^7.0.2" + file-entry-cache: "npm:^8.0.0" global-modules: "npm:^2.0.0" globby: "npm:^11.1.0" globjoin: "npm:^0.1.4" @@ -15634,7 +15645,7 @@ __metadata: is-plain-object: "npm:^5.0.0" known-css-properties: "npm:^0.29.0" mathml-tag-names: "npm:^2.1.3" - meow: "npm:^12.1.1" + meow: "npm:^13.0.0" micromatch: "npm:^4.0.5" normalize-path: "npm:^3.0.0" picocolors: "npm:^1.0.0" @@ -15652,7 +15663,7 @@ __metadata: write-file-atomic: "npm:^5.0.1" bin: stylelint: bin/stylelint.mjs - checksum: 5ec755e209beb1877ff40d50f18c1ebb05bf251925da1f98f28fb3911e4031195eb86adaf641ac5cdb01ba973f4c999bc0c6b0270d08c1d5c070adbdd9e734cf + checksum: 765eea0b07319d1e7989502c07b8b5794938e5a8542bec00990b09ec10c3f7006891689930099e948d06c9ef9982066edb98b1ea64a435138a6b0f0905eb2b87 languageName: node linkType: hard From 629152a80d170cd08fa81b850488f2e6295f6fa0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:50:45 +0100 Subject: [PATCH 030/422] Update DefinitelyTyped types (non-major) (#28542) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 24832bb596..7b09178adb 100644 --- a/package.json +++ b/package.json @@ -166,7 +166,7 @@ "@types/react-dom": "^18.2.4", "@types/react-helmet": "^6.1.6", "@types/react-immutable-proptypes": "^2.1.0", - "@types/react-motion": "^0.0.39", + "@types/react-motion": "^0.0.40", "@types/react-overlays": "^3.1.0", "@types/react-router": "^5.1.20", "@types/react-router-dom": "^5.3.3", diff --git a/yarn.lock b/yarn.lock index 298ffd4eea..2e246ae5e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2323,7 +2323,7 @@ __metadata: "@types/react-dom": "npm:^18.2.4" "@types/react-helmet": "npm:^6.1.6" "@types/react-immutable-proptypes": "npm:^2.1.0" - "@types/react-motion": "npm:^0.0.39" + "@types/react-motion": "npm:^0.0.40" "@types/react-overlays": "npm:^3.1.0" "@types/react-router": "npm:^5.1.20" "@types/react-router-dom": "npm:^5.3.3" @@ -3379,12 +3379,12 @@ __metadata: languageName: node linkType: hard -"@types/react-motion@npm:^0.0.39": - version: 0.0.39 - resolution: "@types/react-motion@npm:0.0.39" +"@types/react-motion@npm:^0.0.40": + version: 0.0.40 + resolution: "@types/react-motion@npm:0.0.40" dependencies: "@types/react": "npm:*" - checksum: 0dfcde777576b3c3289b4dbf2a5085decf71aba6d543697f4c1069d02ed3b543792a253692bd98870af04112c92469328a4fdb93988f93af2e099de8f2c9bc2e + checksum: 8a560051be917833fdbe051185b53aeafbe8657968ac8e073ac874b9a55c6f16e3793748b13cfb9bd6d9a3d27aba116d6f8f296ec1950f4175dc94d17c5e8470 languageName: node linkType: hard @@ -3482,13 +3482,13 @@ __metadata: linkType: hard "@types/react@npm:*, @types/react@npm:16 || 17 || 18, @types/react@npm:>=16.9.11, @types/react@npm:^18.2.7": - version: 18.2.45 - resolution: "@types/react@npm:18.2.45" + version: 18.2.46 + resolution: "@types/react@npm:18.2.46" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 4cc650c47ffb88baac29fb7a74e842e4af4a55f437086ef70250fdc75f0a5f2fcf8adc272d05ab2e00b1de6e14613296881271caee037dadf9130fdeb498c59e + checksum: 814cc67107e5e69501d65bfc371cc2c716665d2a3608d395a2f81e24c3a2875db28e2cad717dfb17017eabcffd1d68ee2c9e09ecaba3f7108d5b7fbb9888ebab languageName: node linkType: hard From c2340682aa3db3d0c4b181f369074aeac9a2a139 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:51:58 +0100 Subject: [PATCH 031/422] Update babel monorepo to v7.23.7 (#28528) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 130 +++++++++++++++++++++++++++--------------------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2e246ae5e9..1f21b80657 100644 --- a/yarn.lock +++ b/yarn.lock @@ -60,25 +60,25 @@ __metadata: linkType: hard "@babel/core@npm:^7.10.4, @babel/core@npm:^7.11.1, @babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.22.1": - version: 7.23.6 - resolution: "@babel/core@npm:7.23.6" + version: 7.23.7 + resolution: "@babel/core@npm:7.23.7" dependencies: "@ampproject/remapping": "npm:^2.2.0" "@babel/code-frame": "npm:^7.23.5" "@babel/generator": "npm:^7.23.6" "@babel/helper-compilation-targets": "npm:^7.23.6" "@babel/helper-module-transforms": "npm:^7.23.3" - "@babel/helpers": "npm:^7.23.6" + "@babel/helpers": "npm:^7.23.7" "@babel/parser": "npm:^7.23.6" "@babel/template": "npm:^7.22.15" - "@babel/traverse": "npm:^7.23.6" + "@babel/traverse": "npm:^7.23.7" "@babel/types": "npm:^7.23.6" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: a02bae7d916029b70706dc301535e1b31e5d216f55d4ee6f64a15825c6b69ee2c14c52a213d1497ec414e925ed4e9d897d41fb0d75df9fea28ed2c0008790e31 + checksum: 38c9934973d384ed83369712978453eac91dc3f22167404dbdb272b64f602e74728a6f37012c53ee57e521b8ae2da60097f050497d9b6a212d28b59cdfb2cd1d languageName: node linkType: hard @@ -167,9 +167,9 @@ __metadata: languageName: node linkType: hard -"@babel/helper-define-polyfill-provider@npm:^0.4.3": - version: 0.4.3 - resolution: "@babel/helper-define-polyfill-provider@npm:0.4.3" +"@babel/helper-define-polyfill-provider@npm:^0.4.4": + version: 0.4.4 + resolution: "@babel/helper-define-polyfill-provider@npm:0.4.4" dependencies: "@babel/helper-compilation-targets": "npm:^7.22.6" "@babel/helper-plugin-utils": "npm:^7.22.5" @@ -178,7 +178,7 @@ __metadata: resolve: "npm:^1.14.2" peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 0007035157e0d32ee9cb4ca319b89d6f3705523383efe52a59eb3d4dfa2ed08c5147e49c10a6e6d69c15221d89c76c8e5875475d6710fb44a5c37b8e69388e40 + checksum: 60126f5f719b9e2114df62e3bf3ac0797b71d8dc733db60192eb169b004fde72ee309fa5848c5fdfe98b8e8863c46f55e16da5aa8a4e420b4d2670cd0c5dd708 languageName: node linkType: hard @@ -342,14 +342,14 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.23.6": - version: 7.23.6 - resolution: "@babel/helpers@npm:7.23.6" +"@babel/helpers@npm:^7.23.7": + version: 7.23.7 + resolution: "@babel/helpers@npm:7.23.7" dependencies: "@babel/template": "npm:^7.22.15" - "@babel/traverse": "npm:^7.23.6" + "@babel/traverse": "npm:^7.23.7" "@babel/types": "npm:^7.23.6" - checksum: df1cf6607676ad36f52f652ec03536f2732d70aef5e76dba5c964e34d49f3c2d3dcf9fb3740db359f53071d74b64606a833d5ba156f79f437f71bfe06e2e7e19 + checksum: f74a61ad28a1bc1fdd9133ad571c07787b66d6db017c707b87c203b0cd06879cea8b33e9c6a8585765a4949efa5df3cc9e19b710fe867f11be38ee29fd4a0488 languageName: node linkType: hard @@ -397,15 +397,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.23.3" +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.23.7": + version: 7.23.7 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.23.7" dependencies: "@babel/helper-environment-visitor": "npm:^7.22.20" "@babel/helper-plugin-utils": "npm:^7.22.5" peerDependencies: "@babel/core": ^7.0.0 - checksum: 0f43b74741d50e637ba4dcef2786621126fe4da6ccf4ee2e94423ee23f6a04ecd91d458e59764c43e4968be139e5197ee43be8a2fea2c09f0b202a3391e548cc + checksum: 355746e21ad7f43e4f4daef54cfe2ef461ecd19446b2afedd53c39df1bf9aa2eeeeaabee2279b1321de89a97c9360e4f76e9ba950fee50ff1676c25f6929d625 languageName: node linkType: hard @@ -661,9 +661,9 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.23.4" +"@babel/plugin-transform-async-generator-functions@npm:^7.23.7": + version: 7.23.7 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.23.7" dependencies: "@babel/helper-environment-visitor": "npm:^7.22.20" "@babel/helper-plugin-utils": "npm:^7.22.5" @@ -671,7 +671,7 @@ __metadata: "@babel/plugin-syntax-async-generators": "npm:^7.8.4" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f2eef4de609975a3f7da7832576b5ffc93e43c80f87e1a99e886b0f8591096cfc4c37e2d5f52fdeaa2a9c09a25a59f3e621159abaca75d3193922a5c0e4cbe0c + checksum: 63d314edc9fbeaf2700745ca0e19bf9840e87f2d7d1f6c5638e06d2aec3e7418d0d7493ed09087e2fe369cc15e9d96c113fb2cd367cb5e3ff922e3712c27b7d4 languageName: node linkType: hard @@ -1201,18 +1201,18 @@ __metadata: linkType: hard "@babel/plugin-transform-runtime@npm:^7.22.4": - version: 7.23.6 - resolution: "@babel/plugin-transform-runtime@npm:7.23.6" + version: 7.23.7 + resolution: "@babel/plugin-transform-runtime@npm:7.23.7" dependencies: "@babel/helper-module-imports": "npm:^7.22.15" "@babel/helper-plugin-utils": "npm:^7.22.5" - babel-plugin-polyfill-corejs2: "npm:^0.4.6" - babel-plugin-polyfill-corejs3: "npm:^0.8.5" - babel-plugin-polyfill-regenerator: "npm:^0.5.3" + babel-plugin-polyfill-corejs2: "npm:^0.4.7" + babel-plugin-polyfill-corejs3: "npm:^0.8.7" + babel-plugin-polyfill-regenerator: "npm:^0.5.4" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 94a7ee92f073df53fd8bebf9ed391a95553716077da1c6c3a57f10f042358c938495d55e6b09b4b50544c01f03560c4770c17698e1c24817a15d3668e8231249 + checksum: 0d5038462a5762c3a88d820785f685ce1b659075527a3ad538647fd9ce486052777d5aea3d62e626639d60441a04dd0ded2ed32c86b92cf8afbdbd3d54460c13 languageName: node linkType: hard @@ -1334,8 +1334,8 @@ __metadata: linkType: hard "@babel/preset-env@npm:^7.11.0, @babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.22.4": - version: 7.23.6 - resolution: "@babel/preset-env@npm:7.23.6" + version: 7.23.7 + resolution: "@babel/preset-env@npm:7.23.7" dependencies: "@babel/compat-data": "npm:^7.23.5" "@babel/helper-compilation-targets": "npm:^7.23.6" @@ -1343,7 +1343,7 @@ __metadata: "@babel/helper-validator-option": "npm:^7.23.5" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.23.3" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.23.3" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.23.3" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.23.7" "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" "@babel/plugin-syntax-async-generators": "npm:^7.8.4" "@babel/plugin-syntax-class-properties": "npm:^7.12.13" @@ -1364,7 +1364,7 @@ __metadata: "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" "@babel/plugin-transform-arrow-functions": "npm:^7.23.3" - "@babel/plugin-transform-async-generator-functions": "npm:^7.23.4" + "@babel/plugin-transform-async-generator-functions": "npm:^7.23.7" "@babel/plugin-transform-async-to-generator": "npm:^7.23.3" "@babel/plugin-transform-block-scoped-functions": "npm:^7.23.3" "@babel/plugin-transform-block-scoping": "npm:^7.23.4" @@ -1412,14 +1412,14 @@ __metadata: "@babel/plugin-transform-unicode-regex": "npm:^7.23.3" "@babel/plugin-transform-unicode-sets-regex": "npm:^7.23.3" "@babel/preset-modules": "npm:0.1.6-no-external-plugins" - babel-plugin-polyfill-corejs2: "npm:^0.4.6" - babel-plugin-polyfill-corejs3: "npm:^0.8.5" - babel-plugin-polyfill-regenerator: "npm:^0.5.3" + babel-plugin-polyfill-corejs2: "npm:^0.4.7" + babel-plugin-polyfill-corejs3: "npm:^0.8.7" + babel-plugin-polyfill-regenerator: "npm:^0.5.4" core-js-compat: "npm:^3.31.0" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5b24d179af52f082d04b9b98cc4777e37bf31a97cef5a91d8917e996dbd75f2f743c88c40f80744cb8529355bb674619d150c0260c32d834aa4067e21d0c8962 + checksum: ac9def873cec52ee02a550bde6e22eced16d1ae331bb8ebc82c03e4c91c12ac17e3e4027647e61612937bcc25ac46e71370aaf99dc2e85dbd11f7777ffeed54e languageName: node linkType: hard @@ -1484,11 +1484,11 @@ __metadata: linkType: hard "@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.22.3, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": - version: 7.23.6 - resolution: "@babel/runtime@npm:7.23.6" + version: 7.23.7 + resolution: "@babel/runtime@npm:7.23.7" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: d886954e985ef8e421222f7a2848884d96a752e0020d3078b920dd104e672fdf23bcc6f51a44313a048796319f1ac9d09c2c88ec8cbb4e1f09174bcd3335b9ff + checksum: 3e304133ee55b0750e03e53cb4efb47fb2bdcdb5795f85bbffa10595196c34b9be60eb65bd6d833c87f49fc827f0365f86f95f51d85b188004d3128bb5129c93 languageName: node linkType: hard @@ -1503,9 +1503,9 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:7, @babel/traverse@npm:^7.23.6": - version: 7.23.6 - resolution: "@babel/traverse@npm:7.23.6" +"@babel/traverse@npm:7, @babel/traverse@npm:^7.23.7": + version: 7.23.7 + resolution: "@babel/traverse@npm:7.23.7" dependencies: "@babel/code-frame": "npm:^7.23.5" "@babel/generator": "npm:^7.23.6" @@ -1517,7 +1517,7 @@ __metadata: "@babel/types": "npm:^7.23.6" debug: "npm:^4.3.1" globals: "npm:^11.1.0" - checksum: 5b4ebb94a00a7e1daf111e4b0b45a7998d5b7598637a14e75e855e88cc1b702789e09a958726b5d599a003be1e9032dbdfde4b88ea6061332228738950d5582d + checksum: e32fceb4249beec2bde83968ddffe17444221c1ee5cd18c543a2feaf94e3ca83f2a4dfbc2dcca87cf226e0105973e0fe3717063a21e982a9de9945615ab3f3f5 languageName: node linkType: hard @@ -4764,39 +4764,39 @@ __metadata: languageName: node linkType: hard -"babel-plugin-polyfill-corejs2@npm:^0.4.6": - version: 0.4.6 - resolution: "babel-plugin-polyfill-corejs2@npm:0.4.6" +"babel-plugin-polyfill-corejs2@npm:^0.4.7": + version: 0.4.7 + resolution: "babel-plugin-polyfill-corejs2@npm:0.4.7" dependencies: "@babel/compat-data": "npm:^7.22.6" - "@babel/helper-define-polyfill-provider": "npm:^0.4.3" + "@babel/helper-define-polyfill-provider": "npm:^0.4.4" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 64a98811f343492aa6970ab253760194e389c0417e5b830522f944009c1f0c78e1251975fd1b9869cd48cc4623111b20a3389cf6732a1d10ba0d19de6fa5114f + checksum: f80f7284ec72c63e7dd751e0bdf25e9978df195a79e0887470603bfdea13ee518d62573cf360bb1bc01b80819e54915dd5edce9cff14c52d0af5f984aa3d36a3 languageName: node linkType: hard -"babel-plugin-polyfill-corejs3@npm:^0.8.5": - version: 0.8.5 - resolution: "babel-plugin-polyfill-corejs3@npm:0.8.5" +"babel-plugin-polyfill-corejs3@npm:^0.8.7": + version: 0.8.7 + resolution: "babel-plugin-polyfill-corejs3@npm:0.8.7" dependencies: - "@babel/helper-define-polyfill-provider": "npm:^0.4.3" - core-js-compat: "npm:^3.32.2" + "@babel/helper-define-polyfill-provider": "npm:^0.4.4" + core-js-compat: "npm:^3.33.1" peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 577a072971bda2929a87655c816ad14b6a8f7276e6914851b98a6465bdb56f7f2e3db6136c8b8607bd6ba4cde3cd9cbde21f0078250cd93aee3df977c0a731d0 + checksum: 094e40f4ab9f131408202063964d63740609fd4fdb70a5b6332b371761921b540ffbcee7a434c0199b8317dfb2ba4675eef674867215fd3b85e24054607c1501 languageName: node linkType: hard -"babel-plugin-polyfill-regenerator@npm:^0.5.3": - version: 0.5.3 - resolution: "babel-plugin-polyfill-regenerator@npm:0.5.3" +"babel-plugin-polyfill-regenerator@npm:^0.5.4": + version: 0.5.4 + resolution: "babel-plugin-polyfill-regenerator@npm:0.5.4" dependencies: - "@babel/helper-define-polyfill-provider": "npm:^0.4.3" + "@babel/helper-define-polyfill-provider": "npm:^0.4.4" peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: cc32313b9ebbf1d7bedc33524a861136b9e5d3b6e9be317ac360a1c2a59ae5ed1b465a6c68b2715cdefb089780ddfb0c11f4a148e49827a947beee76e43da598 + checksum: 0b903f5fe2f8c487b4260935dfe60bd9a95bcaee7ae63958f063045093b16d4e8288c232199d411261300aa21f6b106a3cb83c42cc996de013b337f5825a79fe languageName: node linkType: hard @@ -5151,7 +5151,7 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.22.1, browserslist@npm:^4.22.2": +"browserslist@npm:^4.0.0, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.22.2": version: 4.22.2 resolution: "browserslist@npm:4.22.2" dependencies: @@ -5897,12 +5897,12 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.32.2": - version: 3.33.1 - resolution: "core-js-compat@npm:3.33.1" +"core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.33.1": + version: 3.35.0 + resolution: "core-js-compat@npm:3.35.0" dependencies: - browserslist: "npm:^4.22.1" - checksum: 9c7361b370eac30756e6ec52469988d62c6110759efa1c85edd15e6b30f05ace8319a9cc0671bf596a98e7e81c67ad693ceaab2691b85cb62c636da1afe8feb9 + browserslist: "npm:^4.22.2" + checksum: 8c4379240b8decb94b21e81d5ba6f768418721061923b28c9dfc97574680c35d778d39c010207402fc7c8308a68a4cf6d5e02bcbcb96e931c52e6e0dce29a68c languageName: node linkType: hard From 1982137590a888fb3a29e6b23cada06c799f25a7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:52:09 +0100 Subject: [PATCH 032/422] Update dependency classnames to v2.5.1 (#28524) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1f21b80657..a0a74ec3c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5531,9 +5531,9 @@ __metadata: linkType: hard "classnames@npm:^2.2.5, classnames@npm:^2.3.2": - version: 2.5.0 - resolution: "classnames@npm:2.5.0" - checksum: f10a5b07db7fda8eb77f701f795b7006f3de86a723ec62cc10f4d82b4195fc65a578bbf91c47675b8c6fcb2921b903bfea5c670bdb43513e454daa6c2e9738b3 + version: 2.5.1 + resolution: "classnames@npm:2.5.1" + checksum: afff4f77e62cea2d79c39962980bf316bacb0d7c49e13a21adaadb9221e1c6b9d3cdb829d8bb1b23c406f4e740507f37e1dcf506f7e3b7113d17c5bab787aa69 languageName: node linkType: hard From fdec8d7ffbdaf480d8fb144c27983f7e0de0373e Mon Sep 17 00:00:00 2001 From: Michael Stanclift Date: Tue, 2 Jan 2024 03:09:54 -0600 Subject: [PATCH 033/422] Fix OCR when using S3/CDN for assets (#28551) --- .../mastodon/features/ui/components/focal_point_modal.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx b/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx index 5353ebdb8a..91dca26718 100644 --- a/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx +++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx @@ -222,7 +222,7 @@ class FocalPointModal extends ImmutablePureComponent { const worker = createWorker({ workerPath: tesseractWorkerPath, corePath: tesseractCorePath, - langPath: `${assetHost}/ocr/lang-data/`, + langPath: `${assetHost}/ocr/lang-data`, logger: ({ status, progress }) => { if (status === 'recognizing text') { this.setState({ ocrStatus: 'detecting', progress }); From 0374e110919fe99b4e4da86363febf433d47a5d9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 09:11:53 +0000 Subject: [PATCH 034/422] New Crowdin Translations (automated) (#28529) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/cy.json | 11 ++++++++-- app/javascript/mastodon/locales/hr.json | 28 +++++++++++++++++++++++++ app/javascript/mastodon/locales/ie.json | 2 ++ app/javascript/mastodon/locales/ta.json | 28 +++++++++++++++++++++++++ config/locales/cy.yml | 1 + config/locales/devise.ie.yml | 2 ++ config/locales/doorkeeper.ie.yml | 1 + config/locales/fi.yml | 2 +- config/locales/ie.yml | 17 +++++++++++++++ config/locales/simple_form.ie.yml | 20 ++++++++++++++++++ config/locales/sk.yml | 2 ++ 11 files changed, 111 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 17133631a5..04b39904e4 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -21,6 +21,7 @@ "account.blocked": "Blociwyd", "account.browse_more_on_origin_server": "Pori mwy ar y proffil gwreiddiol", "account.cancel_follow_request": "Tynnu cais i ddilyn", + "account.copy": "Copïo dolen i'r proffil", "account.direct": "Crybwyll yn breifat @{name}", "account.disable_notifications": "Stopiwch fy hysbysu pan fydd @{name} yn postio", "account.domain_blocked": "Parth wedi ei flocio", @@ -31,6 +32,7 @@ "account.featured_tags.last_status_never": "Dim postiadau", "account.featured_tags.title": "Prif hashnodau {name}", "account.follow": "Dilyn", + "account.follow_back": "Dilyn yn ôl", "account.followers": "Dilynwyr", "account.followers.empty": "Does neb yn dilyn y defnyddiwr hwn eto.", "account.followers_counter": "{count, plural, one {Dilynwr: {counter}} other {Dilynwyr: {counter}}}", @@ -51,6 +53,7 @@ "account.mute_notifications_short": "Distewi hysbysiadau", "account.mute_short": "Tewi", "account.muted": "Wedi anwybyddu", + "account.mutual": "Cydgydnabod", "account.no_bio": "Dim disgrifiad wedi'i gynnig.", "account.open_original_page": "Agor y dudalen wreiddiol", "account.posts": "Postiadau", @@ -168,9 +171,9 @@ "confirmations.delete.confirm": "Dileu", "confirmations.delete.message": "Ydych chi'n sicr eich bod eisiau dileu y post hwn?", "confirmations.delete_list.confirm": "Dileu", - "confirmations.delete_list.message": "Ydych chi'n siŵr eich bod eisiau dileu y rhestr hwn am byth?", + "confirmations.delete_list.message": "Ydych chi'n siŵr eich bod eisiau dileu'r rhestr hwn am byth?", "confirmations.discard_edit_media.confirm": "Dileu", - "confirmations.discard_edit_media.message": "Mae gennych newidiadau heb eu cadw i'r disgrifiad cyfryngau neu'r rhagolwg, eu taflu beth bynnag?", + "confirmations.discard_edit_media.message": "Mae gennych newidiadau heb eu cadw i'r disgrifiad cyfryngau neu'r rhagolwg - eu dileu beth bynnag?", "confirmations.domain_block.confirm": "Blocio parth cyfan", "confirmations.domain_block.message": "Ydych chi wir, wir eisiau blocio'r holl {domain}? Fel arfer, mae blocio neu dewi pobl penodol yn broses mwy effeithiol. Fyddwch chi ddim yn gweld cynnwys o'r parth hwnnw mewn ffrydiau cyhoeddus neu yn eich hysbysiadau. Bydd eich dilynwyr o'r parth hwnnw yn cael eu ddileu.", "confirmations.edit.confirm": "Golygu", @@ -481,12 +484,15 @@ "onboarding.follows.title": "Yn boblogaidd ar Mastodon", "onboarding.profile.discoverable": "Gwnewch fy mhroffil yn un y gellir ei ddarganfod", "onboarding.profile.discoverable_hint": "Pan fyddwch yn optio i mewn i ddarganfodadwyedd ar Mastodon, gall eich postiadau ymddangos mewn canlyniadau chwilio a thueddiadau, ac efallai y bydd eich proffil yn cael ei awgrymu i bobl sydd â diddordebau tebyg i chi.", + "onboarding.profile.display_name": "Enw dangos", "onboarding.profile.display_name_hint": "Eich enw llawn neu'ch enw hwyl…", + "onboarding.profile.lead": "Gallwch chi bob amser gwblhau hyn yn ddiweddarach yn y gosodiadau, lle mae hyd yn oed mwy o ddewisiadau cyfaddasu ar gael.", "onboarding.profile.note": "Bywgraffiad", "onboarding.profile.note_hint": "Gallwch @grybwyll pobl eraill neu #hashnodau…", "onboarding.profile.save_and_continue": "Cadw a pharhau", "onboarding.profile.title": "Gosodiad proffil", "onboarding.profile.upload_avatar": "Llwytho llun proffil", + "onboarding.profile.upload_header": "Llwytho pennyn proffil", "onboarding.share.lead": "Cofiwch ddweud wrth bobl sut y gallan nhw ddod o hyd i chi ar Mastodon!", "onboarding.share.message": "Fi yw {username} ar #Mastodon! Dewch i'm dilyn i yn {url}", "onboarding.share.next_steps": "Camau nesaf posib:", @@ -601,6 +607,7 @@ "search.quick_action.status_search": "Postiadau sy'n cyfateb i {x}", "search.search_or_paste": "Chwilio neu gludo URL", "search_popout.full_text_search_disabled_message": "Ddim ar gael ar {domain}.", + "search_popout.full_text_search_logged_out_message": "Dim ond ar gael pan wedi mewngofnodi.", "search_popout.language_code": "Cod iaith ISO", "search_popout.options": "Dewisiadau chwilio", "search_popout.quick_actions": "Gweithredoedd cyflym", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index 654991a0f9..c535f1affc 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -1,8 +1,15 @@ { "about.blocks": "Moderirani poslužitelji", "about.contact": "Kontakt:", + "about.disclaimer": "Mastodon je besplatan softver otvorenog koda i zaštitni znak tvrtke Mastodon gGmbH.", "about.domain_blocks.no_reason_available": "Razlog nije dostupan", + "about.domain_blocks.preamble": "Mastodon vam općenito omogućuje pregled sadržaja i interakciju s korisnicima s bilo kojeg drugog poslužitelja u fediverse. Ovo su iznimke napravljene na ovom poslužitelju.", + "about.domain_blocks.silenced.explanation": "Obično nećete vidjeti profile i sadržaj s ovog poslužitelja, osim ako ga izričito ne potražite ili uključite u njega slijedeći ga.", + "about.domain_blocks.silenced.title": "Ograničen", + "about.domain_blocks.suspended.explanation": "Podatci s ovog poslužitelja neće se obrađivati, pohranjivati ili razmjenjivati, što onemogućuje bilo kakvu interakciju ili komunikaciju s korisnicima s ovog poslužitelja.", "about.domain_blocks.suspended.title": "Suspendiran", + "about.not_available": "Te informacije nisu dostupne na ovom poslužitelju.", + "about.powered_by": "Decentralizirani društveni mediji koje pokreće {mastodon}", "about.rules": "Pravila servera", "account.account_note_header": "Bilješka", "account.add_or_remove_from_list": "Dodaj ili ukloni s liste", @@ -14,6 +21,8 @@ "account.blocked": "Blokirano", "account.browse_more_on_origin_server": "Pogledajte više na izvornom profilu", "account.cancel_follow_request": "Withdraw follow request", + "account.copy": "Kopiraj vezu u profil", + "account.direct": "Privatno spomeni @{name}", "account.disable_notifications": "Nemoj me obavjestiti kada @{name} napravi objavu", "account.domain_blocked": "Domena je blokirana", "account.edit_profile": "Uredi profil", @@ -21,7 +30,9 @@ "account.endorse": "Istakni na profilu", "account.featured_tags.last_status_at": "Zadnji post {date}", "account.featured_tags.last_status_never": "Nema postova", + "account.featured_tags.title": "Istaknuti hashtagovi {name}", "account.follow": "Prati", + "account.follow_back": "Slijedi natrag", "account.followers": "Pratitelji", "account.followers.empty": "Nitko još ne prati korisnika/cu.", "account.followers_counter": "{count, plural, one {{counter} pratitelj} other {{counter} pratitelja}}", @@ -32,6 +43,7 @@ "account.hide_reblogs": "Sakrij boostove od @{name}", "account.in_memoriam": "U sjećanje.", "account.joined_short": "Pridružen", + "account.languages": "Promjeni pretplaćene jezike", "account.link_verified_on": "Vlasništvo ove poveznice provjereno je {date}", "account.locked_info": "Status privatnosti ovog računa postavljen je na zaključano. Vlasnik ručno pregledava tko ih može pratiti.", "account.media": "Medijski sadržaj", @@ -40,11 +52,14 @@ "account.mute_notifications_short": "Utišaj obavijesti", "account.mute_short": "Utišaj", "account.muted": "Utišano", + "account.mutual": "Uzajamno", + "account.no_bio": "Nije dan opis.", "account.open_original_page": "Otvori originalnu stranicu", "account.posts": "Objave", "account.posts_with_replies": "Objave i odgovori", "account.report": "Prijavi @{name}", "account.requested": "Čekanje na potvrdu. Kliknite za poništavanje zahtjeva za praćenje", + "account.requested_follow": "{name} zatražio/la je praćenje", "account.share": "Podijeli profil @{name}", "account.show_reblogs": "Prikaži boostove od @{name}", "account.statuses_counter": "{count, plural, one {{counter} toot} other {{counter} toota}}", @@ -54,11 +69,18 @@ "account.unendorse": "Ne ističi na profilu", "account.unfollow": "Prestani pratiti", "account.unmute": "Poništi utišavanje @{name}", + "account.unmute_notifications_short": "Uključi utišane obavijesti", "account.unmute_short": "Poništi utišavanje", "account_note.placeholder": "Kliknite za dodavanje bilješke", + "admin.dashboard.daily_retention": "Stopa zadržavanja korisnika po danu nakon prijave", + "admin.dashboard.monthly_retention": "Stopa zadržavanja korisnika po mjesecu nakon prijave", "admin.dashboard.retention.average": "Prosječno", "admin.dashboard.retention.cohort": "Mjesec prijave", "admin.dashboard.retention.cohort_size": "Novi korisnici", + "admin.impact_report.instance_accounts": "Profili računa koji bi ovo izbrisali", + "admin.impact_report.instance_followers": "Sljedbenici koje bi izgubili naši korisnici", + "admin.impact_report.instance_follows": "Sljedbenici koje bi izgubili njihovi korisnici", + "admin.impact_report.title": "Sažetak učinka", "alert.rate_limited.message": "Molimo pokušajte nakon {retry_time, time, medium}.", "alert.rate_limited.title": "Ograničenje učestalosti", "alert.unexpected.message": "Dogodila se neočekivana greška.", @@ -68,10 +90,14 @@ "audio.hide": "Sakrij audio", "autosuggest_hashtag.per_week": "{count} tjedno", "boost_modal.combo": "Možete pritisnuti {combo} kako biste preskočili ovo sljedeći put", + "bundle_column_error.copy_stacktrace": "Kopiraj izvješće o pogrešci", + "bundle_column_error.error.body": "Zaraženu stranicu nije moguće prikazati. To bi moglo biti zbog pogreške u našem kodu ili problema s kompatibilnošću preglednika.", "bundle_column_error.error.title": "Oh, ne!", + "bundle_column_error.network.body": "Došlo je do pogreške prilikom pokušaja učitavanja ove stranice. Razlog može biti privremeni problem s internetskom vezom ili ovim poslužiteljem.", "bundle_column_error.network.title": "Greška mreže", "bundle_column_error.retry": "Pokušajte ponovno", "bundle_column_error.return": "Na glavnu", + "bundle_column_error.routing.body": "Traženu stranicu nije moguće pronaći. Jeste li sigurni da je URL u adresnoj traci točan?", "bundle_column_error.routing.title": "404", "bundle_modal_error.close": "Zatvori", "bundle_modal_error.message": "Nešto je pošlo po zlu tijekom učitavanja ove komponente.", @@ -171,6 +197,7 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Evo kako će izgledati:", "emoji_button.activity": "Aktivnost", + "emoji_button.clear": "Obriši", "emoji_button.custom": "Prilagođeno", "emoji_button.flags": "Zastave", "emoji_button.food": "Hrana i piće", @@ -211,6 +238,7 @@ "explore.trending_links": "Novosti", "explore.trending_statuses": "Objave", "explore.trending_tags": "Hashtagovi", + "filter_modal.added.context_mismatch_title": "Nepodudaranje konteksta!", "filter_modal.added.review_and_configure_title": "Postavke filtara", "filter_modal.added.title": "Filtar dodan!", "filter_modal.select_filter.prompt_new": "Nova kategorija: {name}", diff --git a/app/javascript/mastodon/locales/ie.json b/app/javascript/mastodon/locales/ie.json index 0344470edf..8579fc89c6 100644 --- a/app/javascript/mastodon/locales/ie.json +++ b/app/javascript/mastodon/locales/ie.json @@ -250,6 +250,7 @@ "error.unexpected_crash.explanation_addons": "Ti-ci págine ne posset esser monstrat correctmen. Li error es probabilmen causat de un extension al navigator o instrumentes por automatic traduction.", "error.unexpected_crash.next_steps": "Prova recargar li págine. Si to ne auxilia, tu fórsan posse usar Mastodon per un diferent navigator o aplication.", "error.unexpected_crash.next_steps_addons": "Prova desactivisar les e recargar li págine. Si to ne auxilia, tu fórsan posse usar Mastodon per un diferent navigator o aplication.", + "errors.unexpected_crash.copy_stacktrace": "Copiar cumul-tracie a paperiere", "errors.unexpected_crash.report_issue": "Raportar un problema", "explore.search_results": "Resultates de sercha", "explore.suggested_follows": "Gente", @@ -350,6 +351,7 @@ "keyboard_shortcuts.heading": "Rapid-tastes", "keyboard_shortcuts.home": "Aperter li hemal témpor-linea", "keyboard_shortcuts.hotkey": "Rapid clave", + "keyboard_shortcuts.legend": "Monstrar ti-ci legende", "keyboard_shortcuts.local": "Aperter li local témpor-linea", "keyboard_shortcuts.mention": "Mentionar li autor", "keyboard_shortcuts.muted": "Aperter li lista de silentiat usatores", diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json index 6b2332d5b8..955955b8c2 100644 --- a/app/javascript/mastodon/locales/ta.json +++ b/app/javascript/mastodon/locales/ta.json @@ -10,6 +10,7 @@ "account.badges.group": "குழு", "account.block": "@{name} -ஐத் தடு", "account.block_domain": "{domain} யில் இருந்து வரும் எல்லாவற்றையும் மறை", + "account.block_short": "தடு", "account.blocked": "முடக்கப்பட்டது", "account.browse_more_on_origin_server": "மேலும் உலாவ சுயவிவரத்திற்குச் செல்க", "account.cancel_follow_request": "Withdraw follow request", @@ -18,20 +19,26 @@ "account.edit_profile": "சுயவிவரத்தை மாற்று", "account.enable_notifications": "@{name} பதிவிட்டல் எனக்குத் தெரியப்படுத்தவும்", "account.endorse": "சுயவிவரத்தில் வெளிப்படுத்து", + "account.featured_tags.last_status_never": "இடுகைகள் இல்லை", "account.follow": "பின்தொடர்", + "account.follow_back": "பின்தொடரு", "account.followers": "பின்தொடர்பவர்கள்", "account.followers.empty": "இதுவரை யாரும் இந்த பயனரைப் பின்தொடரவில்லை.", "account.followers_counter": "{count, plural, one {{counter} வாசகர்} other {{counter} வாசகர்கள்}}", "account.following": "பின்தொடரும்", "account.following_counter": "{count, plural,one {{counter} சந்தா} other {{counter} சந்தாக்கள்}}", "account.follows.empty": "இந்த பயனர் இதுவரை யாரையும் பின்தொடரவில்லை.", + "account.go_to_profile": "சுயவிவரத்திற்குச் செல்லவும்", "account.hide_reblogs": "இருந்து ஊக்கியாக மறை @{name}", "account.link_verified_on": "இந்த இணைப்பை உரிமையாளர் சரிபார்க்கப்பட்டது {date}", "account.locked_info": "இந்தக் கணக்கு தனியுரிமை நிலை பூட்டப்பட்டுள்ளது. அவர்களைப் பின்தொடர்பவர் யார் என்பதை உரிமையாளர் கைமுறையாக மதிப்பாய்வு செய்கிறார்.", "account.media": "ஊடகங்கள்", "account.mention": "குறிப்பிடு @{name}", "account.mute": "ஊமையான @{name}", + "account.mute_notifications_short": "அறிவிப்புகளை ஒலியடக்கு", + "account.mute_short": "அமைதியாக்கு", "account.muted": "முடக்கியது", + "account.no_bio": "விளக்கம் எதுவும் வழங்கப்படவில்லை.", "account.posts": "டூட்டுகள்", "account.posts_with_replies": "Toots மற்றும் பதில்கள்", "account.report": "@{name} -ஐப் புகாரளி", @@ -61,15 +68,29 @@ "audio.hide": "ஆடியோவை மறை", "autosuggest_hashtag.per_week": "ஒவ்வொரு வாரம் {count}", "boost_modal.combo": "நீங்கள் இதை அடுத்தமுறை தவிர்க்க {combo} வை அழுத்தவும்", + "bundle_column_error.error.title": "அடடே!", + "bundle_column_error.network.body": "இந்தப் பக்கத்தைத் திறக்கும்பொழுது ஒரு பிழை ஏற்பட்டுவிட்டது. இது உங்கள் இணைய தொடர்பில் அல்லது இப்பத்தின் வழங்க்கியில் ஏற்பட்டுள்ள ஒரு தற்காலிக பிரச்சணையாக இருக்கலாம்.", + "bundle_column_error.network.title": "பிணையப் பிழை", "bundle_column_error.retry": "மீண்டும் முயற்சிக்கவும்", + "bundle_column_error.return": "முகப்பிற்கு செல்லவும்", + "bundle_column_error.routing.body": "கேட்கப்பட்ட பக்கத்தைக் காணவில்லை. நீங்கள் உள்ளிட்ட முகவரி சரியனதா?", + "bundle_column_error.routing.title": "404", "bundle_modal_error.close": "மூடுக", "bundle_modal_error.message": "இக்கூற்றை ஏற்றம் செய்யும்பொழுது ஏதோ தவறு ஏற்பட்டுள்ளது.", "bundle_modal_error.retry": "மீண்டும் முயற்சி செய்", + "closed_registrations.other_server_instructions": "மசுடோடன் இரு பரவலாக்கப்பட்ட மென்பொருள் என்பதால், நீங்கள் வேரு ஒரு வழங்கியில் கணக்கை உருவாக்கியிருந்தாலும் இந்த வழங்கியில் பயன்படுத்தலாம்.", + "closed_registrations_modal.description": "{domain} இல் இப்பொழுது கணக்குகள் உருவாக்க முடியாது. நீங்கள் மசுடோடன் பயன்படுத்த, குறிப்பாக {domain} முகவரியில் கணக்கைத் துவங்க வேண்டும் என்ற அவசியமில்லை என்பதை மனதில் வைத்துக் கொள்ளவும்.", + "closed_registrations_modal.find_another_server": "வேறொரு வழங்கியைக் கண்டுபிடி", + "closed_registrations_modal.preamble": "மசுடோடன் ஒரு பரவலாக்கப்பட்ட மென்பொருள். ஆதனால் நீங்கள் எங்குக் கணக்கை உருவாக்கினாலும் இந்த வழங்கியில் உள்ள யாருடன் வேண்டும் என்றாலும் உரவாடலாம். நீங்களே கூட ஒரு வழங்கியை நிறுவலாம்!", + "closed_registrations_modal.title": "மசுடோடன் கணக்கு துவங்கப்படுகிறது", + "column.about": "பற்றி", "column.blocks": "தடுக்கப்பட்ட பயனர்கள்", "column.bookmarks": "அடையாளக்குறிகள்", "column.community": "சுய நிகழ்வு காலவரிசை", + "column.direct": "தனிப்பட்ட குறிப்புகள்", "column.directory": "சுயவிவரங்களை உலாவு", "column.domain_blocks": "மறைந்திருக்கும் திரளங்கள்", + "column.favourites": "பிடித்தவை", "column.follow_requests": "பின்தொடர அனுமதிகள்", "column.home": "முகப்பு", "column.lists": "பட்டியல்கள்", @@ -90,6 +111,9 @@ "community.column_settings.remote_only": "தொலைவிலிருந்து மட்டுமே", "compose.language.change": "மொழியை மாற்று", "compose.language.search": "தேடல் மொழிகள்...", + "compose.published.body": "பதிவிடப்பட்டது.", + "compose.published.open": "திற", + "compose.saved.body": "பதிவி சேமிக்கப்பட்டது.", "compose_form.direct_message_warning_learn_more": "மேலும் அறிய", "compose_form.encryption_warning": "Mastodonல் உள்ள பதிவுகள் முறையாக என்க்ரிப்ட்(encrypt) செய்யபடவில்லை. அதனால் முக்கிய தகவல்களை இங்கே பகிர வேண்டாம்.", "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", @@ -180,6 +204,10 @@ "error.unexpected_crash.next_steps": "பக்கத்தைப் புதுப்பித்துப் பார்க்கவும். அப்படியும் வேலை செய்யவில்லை எனில், மாஸ்டடானை வேறு ஒரு உலாவியின் மூலமோ, அல்லது பொருத்தமான செயலியின் மூலமோ பயன்படுத்திப் பார்க்கவும்.", "errors.unexpected_crash.copy_stacktrace": "Stacktrace-ஐ clipboard-ல் நகலெடு", "errors.unexpected_crash.report_issue": "புகாரளி", + "explore.title": "உலாவு", + "explore.trending_links": "செய்திகள்", + "explore.trending_statuses": "பதிவுகள்", + "explore.trending_tags": "ஹேஷ்டேக்குகள்", "follow_request.authorize": "அனுமதியளி", "follow_request.reject": "நிராகரி", "follow_requests.unlocked_explanation": "உங்கள் கணக்கு பூட்டப்படவில்லை என்றாலும், இந்தக் கணக்குகளிலிருந்து உங்களைப் பின்தொடர விரும்பும் கோரிக்கைகளை நீங்கள் பரீசீலிப்பது நலம் என்று {domain} ஊழியர் எண்ணுகிறார்.", diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 7f60e93422..9dd533b2ad 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -659,6 +659,7 @@ cy: created_at: Adroddwyd delete_and_resolve: Dileu postiadau forwarded: Wedi'i anfon ymlaen + forwarded_replies_explanation: Mae'r adroddiad hwn gan ddefnyddiwr o weinydd arall ac am gynnwys pell. Mae wedi ei anfon ymlaen atoch chi oherwydd bod y cynnwys sy'n cael ei adrodd yn ateb i un o'ch defnyddwyr. forwarded_to: Wedi'i anfon ymlaen i %{domain} mark_as_resolved: Nodi fel wedi'i ddatrys mark_as_sensitive: Marcio fel sensitif diff --git a/config/locales/devise.ie.yml b/config/locales/devise.ie.yml index 847b0f361b..e4f2e6fb19 100644 --- a/config/locales/devise.ie.yml +++ b/config/locales/devise.ie.yml @@ -18,6 +18,8 @@ ie: confirmation_instructions: action: Verificar e-posta action_with_app: Confirma e retorna a%{app} + explanation: Tu ha creat un conto sur %{host} con ti-ci e-posta, quel tu posse activar per un sol clicc. Si it ne esset tu qui creat li conto, ples ignorar ti-ci missage. + explanation_when_pending: Tu ha demandat un invitation a %{host} con ti-ci e-posta. Pos confirmation de tui adresse, noi va inspecter tui aplication. Tu posse inloggar por changear detallies o deleter li conto, ma li pluparte del functiones va restar ínusabil til quande tui conto es aprobat. Tui data va esser deletet si tui conto es rejectet, e in ti casu tu ne besona far quelcunc cose. Si it ne esset tu qui creat li conto, ples ignorar ti-ci missage. title: Verificar e-posta email_changed: explanation: 'Li e-mail adresse de tui es changeat a:' diff --git a/config/locales/doorkeeper.ie.yml b/config/locales/doorkeeper.ie.yml index e5e5146558..1b4b5994bd 100644 --- a/config/locales/doorkeeper.ie.yml +++ b/config/locales/doorkeeper.ie.yml @@ -151,6 +151,7 @@ ie: write:filters: crea filtres write:follows: sequer homes write:lists: crear listes + write:media: adcargar files de medie write:mutes: silentiar persones e conversationes write:notifications: aclarar tui notificationes write:reports: raportar altri persones diff --git a/config/locales/fi.yml b/config/locales/fi.yml index d48653edcc..93545b6a1b 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1559,7 +1559,7 @@ fi: last_active: Viimeksi aktiivinen most_recent: Viimeisimmät moved: Muuttaneet - mutual: Molemmat + mutual: Seuraatte toisianne primary: Ensisijaiset relationship: Suhde remove_selected_domains: Poista kaikki seuraajat valituista verkkotunnuksista diff --git a/config/locales/ie.yml b/config/locales/ie.yml index 99e628fe3b..87aa1c41cc 100644 --- a/config/locales/ie.yml +++ b/config/locales/ie.yml @@ -112,6 +112,7 @@ ie: promote: Promoer protocol: Protocol public: Public + push_subscription_expires: Subscrition a PuSH expira redownload: Recargar li profil redownloaded_msg: Successosimen recargat li profil de %{username} del original fonte reject: Rejecter @@ -465,6 +466,7 @@ ie: unsuppress: Restaurar seque-recomandation instances: availability: + failure_threshold_reached: Límite de falliment atinget ye %{date}. failures_recorded: one: Fallit prova por %{count} die. other: Fallit provas por %{count} dies. @@ -478,6 +480,8 @@ ie: confirm_purge: Vole tu vermen permanentmen deleter data de ti dominia? content_policies: comment: Internal nota + description_html: Tu posse definar planes de contenete a aplicar sur omni contos de ti-ci dominia e omni su subdominias. + limited_federation_mode_description_html: Tu posse selecter ca permisser federation a ti-ci dominia. policies: reject_media: Rejecter medie reject_reports: Rejecter raportes @@ -704,6 +708,7 @@ ie: manage_users: Gerer usatores manage_users_description: Permisse que usatores vide detallies de altri usatores e fa actiones de moderation contra les manage_webhooks: Gerer Webcrocs + manage_webhooks_description: Permisse que usatores configura webcrocs por evenimentes administrativ view_audit_log: Vider li Jurnale de Audit view_audit_log_description: Permisse que usatores vide li historie de administrativ actiones sur li servitor view_dashboard: Vider Panel de Control @@ -714,6 +719,7 @@ ie: rules: add_new: Adjunter un regule delete: Deleter + description_html: Benque li pluparte di que ili ha leet e acorda con li termines de servicie, presc nequi perlee les til quande un problema eveni. Tu posse facilitar li perletura del regules de tui servitor per dar les sur un liste de plat balle-punctus. Li índividual regules posse esser curt e simplic, ma mem un liste de micri punctus posse esser tro exigent por li letor si it es tro grand. edit: Redacter regul empty: Ancor null regules de servitor ha esset definit. title: Regules del servitor @@ -724,6 +730,11 @@ ie: appearance: preamble: Customisar li interfacie web de Mastodon. title: Aspecte + branding: + title: Marca + captcha_enabled: + desc_html: To ci usa extern scrites de hCaptcha, quel posse esser ínquietant pro rasones de securitá e privatie. In plu, it posse far li processu de registration mult plu desfacil (particularimen por tis con deshabilitás). Pro ti rasones, ples considerar alternativ mesuras, tales quam registration per aprobation o invitation. + title: Exige que nov usatores solue un CAPTCHA por confirmar lor conto content_retention: title: Retention de contenete discovery: @@ -1374,6 +1385,7 @@ ie: media_attachments: validations: images_and_video: On ne posse atachar un video a un posta quel ja contene images + too_many: Ne posse atachar plu quam 4 files migrations: acct: Translocat a cancel: Anullar redirection @@ -1401,6 +1413,8 @@ ie: carry_blocks_over_text: Ti usator translocat se de %{acct}, quel tu hat bloccat. carry_mutes_over_text: Ti-ci usator movet se de %{acct}, quel tu hat silentiat. copy_account_note_text: 'Vi tui notas pri ti usator qui translocat se de %{acct}:' + navigation: + toggle_menu: Changear menú notification_mailer: admin: report: @@ -1443,6 +1457,7 @@ ie: number: human: decimal_units: + format: "%n%u" units: billion: B million: M @@ -1800,6 +1815,8 @@ ie: success: Tui clave de securitá esset adjuntet con successe. delete: Deleter delete_confirmation: Vole tu vermen deleter ti-ci clave de securitá? + destroy: + success: Tui clave de securitá esset successosimen deletet. invalid_credential: Ínvalid clave de securitá not_enabled: Tu ancor ne ha possibilisat WebAuthn not_supported: Ti-ci navigator ne subtene claves de securitá diff --git a/config/locales/simple_form.ie.yml b/config/locales/simple_form.ie.yml index 3bcce47d36..f945e2342e 100644 --- a/config/locales/simple_form.ie.yml +++ b/config/locales/simple_form.ie.yml @@ -6,6 +6,7 @@ ie: discoverable: Tui public postas e profil posse esser recomandat in multiplic areas de Mastodon e tui profil posse esser suggestat a altri usatores. display_name: Tui complet nómine o tui amusant nómine. fields: Tui websitu, pronómines, etá, quocunc quel tu vole. + indexable: Tui public postas posse aparir in sercha-resultates sur Mastodon. E in omni casu, tis qui ha interactet con tui postas va posser serchar e trovar les. note: 'Tu posse @mentionar altri persones o #hashtags.' unlocked: Persones va posser sequer te sin petir aprobation. Desselecte si tu vole manualmen tractar petitiones de sequer e decider ca acceptar o rejecter nov sequitores. account_alias: @@ -65,20 +66,27 @@ ie: hide: Celar completmen li contenete filtrat, quam si it ne existe warn: Celar li contenete filtrat detra un avise mentionant li titul del filtre form_admin_settings: + backups_retention_period: Mantener usator-generat archives por li specificat quantitá de dies. bootstrap_timeline_accounts: Ti-ci contos va esser pinglat al parte superiori del recomandationes por nov usatores. peers_api_enabled: Un liste de nómines de dominia queles ti-ci servitor ha incontrat in li fediverse. Ci null data es includet pri ca tu confedera con un cert servitor o ne; it indica solmen que tui servitor conosse it. Usat per servicies colectent general statisticas pri federation. profile_directory: Li profilarium monstra omni usatores volent esser decovribil. site_contact_email: Qualmen on posse contacter te por inquestes legal o de apoy. site_contact_username: Qualmen li gente posse atinger te sur Mastodon. + site_short_description: Un curt descrition por auxiliar identificar tui servitor. Qui gere it, por qual persones it es? site_title: Quant persones posse aluder a tui servitor ultra su nómine de dominia. + status_page_url: URL de un págine monstrant li statu de ti-ci servitor durant un ruptura de servicie theme: Li dessine quel ínregistrat visitantes e nov usatores vide. + thumbnail: Un image de dimensiones circa 2:1 monstrat along tui servitor-information. timeline_preview: Ínregistrat visitantes va posser vider li max recent public postas disponibil che li servitor. + trends: Tendenties monstra quel postas, hashtags e novas es ganiant atention sur tui servitor. trends_as_landing_page: Monstrar populari contenete a ínregistrat visitantes vice un description del servitor. Besona que tendenties es activisat. form_challenge: current_password: Tu nu intra un area secur ip_block: comment: Facultativ. Ne obliviar pro quo tu adjuntet ti-ci regul. + expires_in: IP-adresses es un ressurse finit, quelcvez partit e transferet de manu a manu. Pro to, un índefinit bloccada de IP ne es recomandat. severities: + no_access: Bloccar accesse a omni ressurses sign_up_block: Nov registrationes ne va esser possibil sign_up_requires_approval: Nov registrationes va besonar tui aprobation severity: Selecter quo va evenir con demandes ex ti-ci IP @@ -142,11 +150,13 @@ ie: honeypot: "%{label} (ne plenar)" irreversible: Lassar cader vice celar locale: Lingue del interfacie + max_uses: Max grand númere de usas new_password: Nov passa-parol note: Biografie password: Passa-parol phrase: Clave-parol o frase setting_advanced_layout: Possibilisar web-interfacie avansat + setting_always_send_emails: Sempre misser notificationes de e-posta setting_default_language: Lingue in quel postar setting_default_privacy: Privatie de postada setting_default_sensitive: Sempre marcar medie quam sensitiv @@ -162,18 +172,27 @@ ie: severity: Severitá sign_in_token_attempt: Code de securitá title: Titul + type: Specie de importation username: Nómine de usator whole_word: Plen parol + featured_tag: + name: Hashtag filters: actions: + hide: Celar completmen warn: Celar con un admonition form_admin_settings: + backups_retention_period: Periode de retener archives de usator + bootstrap_timeline_accounts: Sempre recomandar ti-ci contos a nov usatores + closed_registrations_message: Customisat missage quande registration ne disponibil custom_css: Custom CSS profile_directory: Possibilisar profilarium registrations_mode: Qui posse registrar se show_domain_blocks: Vider bloccas de dominia show_domain_blocks_rationale: Monstrar pro quo cert dominias esset bloccat site_contact_email: Contact e-mail adresse + site_contact_username: Usator-nómine de contact + site_extended_description: Extendet descrition site_title: Nómine de servitor theme: Predefenit tema trendable_by_default: Possibilisar tendenties sin priori inspection @@ -220,6 +239,7 @@ ie: events: Evenimentes activisat url: URL de punctu terminal 'no': 'No' + not_recommended: Ne recomandat recommended: Recomandat required: mark: "*" diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 4fe190cfec..feb84ea984 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -574,6 +574,7 @@ sk: manage_announcements: Spravuj oboznámenia manage_appeals: Spravuj námietky manage_blocks: Spravuj blokovania + manage_custom_emojis: Spravuj vlastné emotikony manage_federation: Spravuj federáciu manage_invites: Spravuj pozvánky manage_reports: Spravuj hlásenia @@ -696,6 +697,7 @@ sk: title: Populárne príspevky tags: dashboard: + tag_accounts_measure: unikátnych použití tag_servers_measure: iné servery tag_uses_measure: užívateľov celkovo not_usable: Nemôže byť použitý From cd09be054fcf12ba2bd0b85c20cfa0432b8d5532 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:13:22 +0100 Subject: [PATCH 035/422] Update dependency eslint-plugin-jsdoc to v47 (#28541) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 7b09178adb..479852cd51 100644 --- a/package.json +++ b/package.json @@ -189,7 +189,7 @@ "eslint-import-resolver-typescript": "^3.5.5", "eslint-plugin-formatjs": "^4.10.1", "eslint-plugin-import": "~2.29.0", - "eslint-plugin-jsdoc": "^46.1.0", + "eslint-plugin-jsdoc": "^47.0.0", "eslint-plugin-jsx-a11y": "~6.8.0", "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-promise": "~6.1.1", diff --git a/yarn.lock b/yarn.lock index a0a74ec3c2..b44c218016 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2368,7 +2368,7 @@ __metadata: eslint-import-resolver-typescript: "npm:^3.5.5" eslint-plugin-formatjs: "npm:^4.10.1" eslint-plugin-import: "npm:~2.29.0" - eslint-plugin-jsdoc: "npm:^46.1.0" + eslint-plugin-jsdoc: "npm:^47.0.0" eslint-plugin-jsx-a11y: "npm:~6.8.0" eslint-plugin-prettier: "npm:^5.0.0" eslint-plugin-promise: "npm:~6.1.1" @@ -7361,9 +7361,9 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsdoc@npm:^46.1.0": - version: 46.9.1 - resolution: "eslint-plugin-jsdoc@npm:46.9.1" +"eslint-plugin-jsdoc@npm:^47.0.0": + version: 47.0.1 + resolution: "eslint-plugin-jsdoc@npm:47.0.1" dependencies: "@es-joy/jsdoccomment": "npm:~0.41.0" are-docs-informative: "npm:^0.0.2" @@ -7375,8 +7375,8 @@ __metadata: semver: "npm:^7.5.4" spdx-expression-parse: "npm:^4.0.0" peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - checksum: d15d68797e85bb7b6fdcfc1170653683c16ab1d62c2e9c537101e774cb3231913e2bc4781f2bb808d074adce5699e5b545e450c6801b637c6434587d226ad6ac + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + checksum: f2657cfc1394af0fca2c9c079065ffbc4e5fd41678299afb9ae261aff246cbd861d0ff38b57258caf6c9e9c57eb9975c75cd47c9f8c92bfefdaa4924eef62c24 languageName: node linkType: hard From 1184887b012e863fbf44f65ef5c65e0049123c27 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 2 Jan 2024 13:27:51 +0100 Subject: [PATCH 036/422] Fix streaming API redirection ignoring the port of `streaming_api_base_url` (#28558) --- app/controllers/api/v1/streaming_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/streaming_controller.rb b/app/controllers/api/v1/streaming_controller.rb index 0cdd00d62f..0cb6e856f2 100644 --- a/app/controllers/api/v1/streaming_controller.rb +++ b/app/controllers/api/v1/streaming_controller.rb @@ -13,7 +13,9 @@ class Api::V1::StreamingController < Api::BaseController def streaming_api_url Addressable::URI.parse(request.url).tap do |uri| - uri.host = Addressable::URI.parse(Rails.configuration.x.streaming_api_base_url).host + base_url = Addressable::URI.parse(Rails.configuration.x.streaming_api_base_url) + uri.host = base_url.host + uri.port = base_url.port end.to_s end end From 65ea097f1df5f14a4b389aa6ec0b955f2066b41c Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 2 Jan 2024 16:02:25 +0100 Subject: [PATCH 037/422] Fix loading local accounts with extraneous domain part in WebUI (#28559) --- app/javascript/mastodon/reducers/accounts_map.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/reducers/accounts_map.js b/app/javascript/mastodon/reducers/accounts_map.js index d5ecad7dbf..9053dcc9c0 100644 --- a/app/javascript/mastodon/reducers/accounts_map.js +++ b/app/javascript/mastodon/reducers/accounts_map.js @@ -2,8 +2,13 @@ import { Map as ImmutableMap } from 'immutable'; import { ACCOUNT_LOOKUP_FAIL } from '../actions/accounts'; import { importAccounts } from '../actions/accounts_typed'; +import { domain } from '../initial_state'; -export const normalizeForLookup = str => str.toLowerCase(); +export const normalizeForLookup = str => { + str = str.toLowerCase(); + const trailingIndex = str.indexOf(`@${domain.toLowerCase()}`); + return (trailingIndex > 0) ? str.slice(0, trailingIndex) : str; +}; const initialState = ImmutableMap(); From 3944b12b5eec8c6ae4666ec922411b32b3442dd6 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 2 Jan 2024 10:19:54 -0500 Subject: [PATCH 038/422] Update `@typescript-eslint/parser` to version 6.17.0 (#28218) --- package.json | 2 +- yarn.lock | 64 ++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 479852cd51..54dac54cd5 100644 --- a/package.json +++ b/package.json @@ -181,7 +181,7 @@ "@types/webpack": "^4.41.33", "@types/yargs": "^17.0.24", "@typescript-eslint/eslint-plugin": "^6.0.0", - "@typescript-eslint/parser": "^6.0.0", + "@typescript-eslint/parser": "^6.17.0", "babel-jest": "^29.5.0", "eslint": "^8.41.0", "eslint-config-prettier": "^9.0.0", diff --git a/yarn.lock b/yarn.lock index b44c218016..571e29e7d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2338,7 +2338,7 @@ __metadata: "@types/webpack": "npm:^4.41.33" "@types/yargs": "npm:^17.0.24" "@typescript-eslint/eslint-plugin": "npm:^6.0.0" - "@typescript-eslint/parser": "npm:^6.0.0" + "@typescript-eslint/parser": "npm:^6.17.0" arrow-key-navigation: "npm:^1.2.0" async-mutex: "npm:^0.4.0" autoprefixer: "npm:^10.4.14" @@ -3693,21 +3693,21 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^6.0.0": - version: 6.16.0 - resolution: "@typescript-eslint/parser@npm:6.16.0" +"@typescript-eslint/parser@npm:^6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/parser@npm:6.17.0" dependencies: - "@typescript-eslint/scope-manager": "npm:6.16.0" - "@typescript-eslint/types": "npm:6.16.0" - "@typescript-eslint/typescript-estree": "npm:6.16.0" - "@typescript-eslint/visitor-keys": "npm:6.16.0" + "@typescript-eslint/scope-manager": "npm:6.17.0" + "@typescript-eslint/types": "npm:6.17.0" + "@typescript-eslint/typescript-estree": "npm:6.17.0" + "@typescript-eslint/visitor-keys": "npm:6.17.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 9d573d14df4ec661dccaca785223a8a330d64f50a9279ff9170b1da22198ff91b9afa3ee7d3d7127c0cbc148c86831e76b33fc5b47d630799e98940ef666bfe0 + checksum: 66b53159688083eb48259de5b4daf076f3de284ac3b4d2618bda3f7ab2d8ee27b01ae851b08e8487047e33ff3668424f17d677d66413164cb231f1519dcff82f languageName: node linkType: hard @@ -3721,6 +3721,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/scope-manager@npm:6.17.0" + dependencies: + "@typescript-eslint/types": "npm:6.17.0" + "@typescript-eslint/visitor-keys": "npm:6.17.0" + checksum: b7ac7d9c39515c2a1b3844577fab967bf126ec25ccf28076240748b3f42d60ab3e64131bfffee61f66251bdf2d59e50e39f5cb0bee7987c85c49140c75d26b5f + languageName: node + linkType: hard + "@typescript-eslint/type-utils@npm:6.16.0": version: 6.16.0 resolution: "@typescript-eslint/type-utils@npm:6.16.0" @@ -3745,6 +3755,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/types@npm:6.17.0" + checksum: c458d985b9ab4f369018536bcb88f0aedafb0c8c4b22ffd376e0c0c768a44e3956475c85ebeef40ae44238841c8df268893477b85873aa2621995c37e738e37e + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:6.16.0": version: 6.16.0 resolution: "@typescript-eslint/typescript-estree@npm:6.16.0" @@ -3764,6 +3781,25 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.17.0" + dependencies: + "@typescript-eslint/types": "npm:6.17.0" + "@typescript-eslint/visitor-keys": "npm:6.17.0" + debug: "npm:^4.3.4" + globby: "npm:^11.1.0" + is-glob: "npm:^4.0.3" + minimatch: "npm:9.0.3" + semver: "npm:^7.5.4" + ts-api-utils: "npm:^1.0.1" + peerDependenciesMeta: + typescript: + optional: true + checksum: 5a858288bb05f45a2a45b04394115826ff19f85555144bfb67dc281d4e75fc3a1e1aceb3dee68022e86b91f199d1310c15bda3100a4890004b8e474d86afad51 + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:6.16.0, @typescript-eslint/utils@npm:^6.5.0": version: 6.16.0 resolution: "@typescript-eslint/utils@npm:6.16.0" @@ -3791,6 +3827,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.17.0" + dependencies: + "@typescript-eslint/types": "npm:6.17.0" + eslint-visitor-keys: "npm:^3.4.1" + checksum: 75a48f5810c6a69bc1c082b07d2b840c40895807b1b4ecf9d3ab9eb783176eeb3e7b11eb89d652e8331da79d604f82300f315ffc21cd937819197a8601b48d1d + languageName: node + linkType: hard + "@ungap/structured-clone@npm:^1.2.0": version: 1.2.0 resolution: "@ungap/structured-clone@npm:1.2.0" From c2b4588f1cd65f2b36fc45f998681492ef2f0f79 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 10:04:59 +0100 Subject: [PATCH 039/422] Update dependency sass to v1.69.7 (#28570) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 571e29e7d3..2bab9a2d0d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14554,15 +14554,15 @@ __metadata: linkType: hard "sass@npm:^1.62.1": - version: 1.69.6 - resolution: "sass@npm:1.69.6" + version: 1.69.7 + resolution: "sass@npm:1.69.7" dependencies: chokidar: "npm:>=3.0.0 <4.0.0" immutable: "npm:^4.0.0" source-map-js: "npm:>=0.6.2 <2.0.0" bin: sass: sass.js - checksum: 8153db8e51e74a9007bb54332e14d122c34288c7d21a5f2eaefef753a1b7bb13f35e042dc6247253dab5b1550b05cea27970371e7548286b4f50f23dd1147d89 + checksum: 773d0938e7d4ff3972d3fda3132f34fe98a2f712e028a58e28fecd615434795eff3266eddc38d5e13f03b90c0d6360d0e737b30bff2949a47280c64a18e0fb18 languageName: node linkType: hard From 8c5d3e527892dee08f5f6ae7517f9af8f3b4963e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 09:05:52 +0000 Subject: [PATCH 040/422] Update dependency puma to v6.4.1 (#28569) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 08b9fc0de4..295461bd35 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -544,7 +544,7 @@ GEM psych (5.1.2) stringio public_suffix (5.0.4) - puma (6.4.0) + puma (6.4.1) nio4r (~> 2.0) pundit (2.3.1) activesupport (>= 3.0.0) From 2b330ede224d4fcc79b48f0de36da1ca9909d83d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 10:10:19 +0100 Subject: [PATCH 041/422] Update dependency eslint-plugin-jsdoc to v48 (#28564) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 54dac54cd5..82cfd689a5 100644 --- a/package.json +++ b/package.json @@ -189,7 +189,7 @@ "eslint-import-resolver-typescript": "^3.5.5", "eslint-plugin-formatjs": "^4.10.1", "eslint-plugin-import": "~2.29.0", - "eslint-plugin-jsdoc": "^47.0.0", + "eslint-plugin-jsdoc": "^48.0.0", "eslint-plugin-jsx-a11y": "~6.8.0", "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-promise": "~6.1.1", diff --git a/yarn.lock b/yarn.lock index 2bab9a2d0d..3cd45a11d6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2368,7 +2368,7 @@ __metadata: eslint-import-resolver-typescript: "npm:^3.5.5" eslint-plugin-formatjs: "npm:^4.10.1" eslint-plugin-import: "npm:~2.29.0" - eslint-plugin-jsdoc: "npm:^47.0.0" + eslint-plugin-jsdoc: "npm:^48.0.0" eslint-plugin-jsx-a11y: "npm:~6.8.0" eslint-plugin-prettier: "npm:^5.0.0" eslint-plugin-promise: "npm:~6.1.1" @@ -7407,9 +7407,9 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsdoc@npm:^47.0.0": - version: 47.0.1 - resolution: "eslint-plugin-jsdoc@npm:47.0.1" +"eslint-plugin-jsdoc@npm:^48.0.0": + version: 48.0.1 + resolution: "eslint-plugin-jsdoc@npm:48.0.1" dependencies: "@es-joy/jsdoccomment": "npm:~0.41.0" are-docs-informative: "npm:^0.0.2" @@ -7422,7 +7422,7 @@ __metadata: spdx-expression-parse: "npm:^4.0.0" peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - checksum: f2657cfc1394af0fca2c9c079065ffbc4e5fd41678299afb9ae261aff246cbd861d0ff38b57258caf6c9e9c57eb9975c75cd47c9f8c92bfefdaa4924eef62c24 + checksum: 9b211cfb2e07e076dad12681cd2045c65766dd24fe9399fd0adeaf6f8785f9a4dd58608f1183195f63d3c6c91013aa1cf9edc9101580cff9cb60e1e688f456f9 languageName: node linkType: hard From 7cce2a41f279ff157cb04d826bd5c46a129689aa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 10:19:46 +0100 Subject: [PATCH 042/422] New Crowdin Translations (automated) (#28573) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/ia.json | 63 ++++++++++++++++++++++++- app/javascript/mastodon/locales/lt.json | 4 +- app/javascript/mastodon/locales/ta.json | 10 ++-- config/locales/doorkeeper.ie.yml | 4 ++ config/locales/simple_form.ie.yml | 6 +++ 5 files changed, 79 insertions(+), 8 deletions(-) diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index 917a034667..35397b8e12 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -1,23 +1,84 @@ { "account.add_or_remove_from_list": "Adder o remover ab listas", + "account.badges.group": "Gruppo", + "account.block": "Blocar @{name}", + "account.block_short": "Blocar", + "account.blocked": "Blocate", "account.copy": "Copiar ligamine a profilo", + "account.edit_profile": "Modificar profilo", + "account.go_to_profile": "Vader al profilo", + "account.moved_to": "{name} indicava que lor nove conto ora es:", + "account.share": "Compartir profilo de @{name}", + "account.unblock": "Disblocar @{name}", + "account.unblock_short": "Disblocar", + "account.unendorse": "Non evidentiar sur le profilo", + "account_note.placeholder": "Clicca pro adder un nota", + "admin.dashboard.retention.cohort_size": "Nove usatores", + "audio.hide": "Celar audio", + "autosuggest_hashtag.per_week": "{count} per septimana", "bundle_column_error.network.title": "Error de rete", + "bundle_column_error.retry": "Tentar novemente", + "bundle_column_error.return": "Retornar al initio", "bundle_modal_error.close": "Clauder", + "bundle_modal_error.retry": "Tentar novemente", + "column.blocks": "Usatores blocate", + "column.directory": "Navigar profilos", + "column.favourites": "Favoritos", "column.home": "Initio", + "column.lists": "Listas", + "column.notifications": "Notificationes", + "column_header.hide_settings": "Celar le parametros", + "column_header.show_settings": "Monstrar le parametros", "column_subheading.settings": "Parametros", + "compose.language.change": "Cambiar le lingua", "compose.language.search": "Cercar linguas...", "compose.published.open": "Aperir", + "compose_form.poll.add_option": "Adder un option", + "compose_form.poll.remove_option": "Remover iste option", "confirmation_modal.cancel": "Cancellar", + "confirmations.delete.confirm": "Deler", + "confirmations.delete_list.confirm": "Deler", "confirmations.logout.confirm": "Clauder le session", + "copy_icon_button.copied": "Copiate al area de transferentia", "copypaste.copy_to_clipboard": "Copiar al area de transferentia", + "disabled_account_banner.account_settings": "Parametros de conto", "dismissable_banner.dismiss": "Dimitter", + "emoji_button.activity": "Activitate", + "emoji_button.custom": "Personalisate", + "emoji_button.search_results": "Resultatos de recerca", + "empty_column.account_unavailable": "Profilo non disponibile", + "errors.unexpected_crash.report_issue": "Signalar un defecto", + "explore.search_results": "Resultatos de recerca", + "explore.trending_links": "Novas", + "firehose.all": "Toto", "firehose.local": "Iste servitor", + "firehose.remote": "Altere servitores", "footer.about": "A proposito de", + "footer.directory": "Directorio de profilos", + "footer.privacy_policy": "Politica de confidentialitate", + "footer.source_code": "Vider le codice fonte", + "footer.status": "Stato", "home.pending_critical_update.link": "Vider actualisationes", "keyboard_shortcuts.my_profile": "Aperir tu profilo", "lightbox.close": "Clauder", "lightbox.next": "Sequente", "link_preview.author": "Per {name}", "lists.account.add": "Adder al lista", - "navigation_bar.about": "A proposito de" + "mute_modal.duration": "Duration", + "mute_modal.hide_notifications": "Celar notificationes de iste usator?", + "navigation_bar.about": "A proposito de", + "navigation_bar.advanced_interface": "Aperir in un interfacie web avantiate", + "navigation_bar.blocks": "Usatores blocate", + "navigation_bar.favourites": "Favoritos", + "navigation_bar.lists": "Listas", + "navigation_bar.logout": "Clauder le session", + "navigation_bar.preferences": "Preferentias", + "navigation_bar.security": "Securitate", + "notifications.column_settings.alert": "Notificationes de scriptorio", + "notifications.column_settings.filter_bar.advanced": "Monstrar tote le categorias", + "notifications.column_settings.sound": "Reproducer sono", + "notifications.filter.all": "Toto", + "onboarding.compose.template": "Salute #Mastodon!", + "onboarding.profile.save_and_continue": "Salvar e continuar", + "onboarding.share.title": "Compartir tu profilo" } diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index 82f1669b1a..ec0d30363c 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -2,7 +2,7 @@ "about.blocks": "Prižiūrimi serveriai", "about.contact": "Kontaktuoti:", "about.disclaimer": "Mastodon – nemokama atvirojo kodo programa ir Mastodon gGmbH prekės ženklas.", - "about.domain_blocks.no_reason_available": "Priežastis nežinoma", + "about.domain_blocks.no_reason_available": "Priežastis nepateikta", "about.domain_blocks.preamble": "Mastodon paprastai leidžia peržiūrėti turinį ir bendrauti su naudotojais iš bet kurio kito fediverse esančio serverio. Šios yra išimtys, kurios buvo padarytos šiame konkrečiame serveryje.", "about.domain_blocks.silenced.explanation": "Paprastai nematysi profilių ir turinio iš šio serverio, nebent jį aiškiai ieškosi arba pasirinksi jį sekdamas (-a).", "about.domain_blocks.silenced.title": "Ribota", @@ -35,7 +35,7 @@ "account.follow_back": "Sekti atgal", "account.followers": "Sekėjai", "account.followers.empty": "Šio naudotojo dar niekas neseka.", - "account.followers_counter": "{count, plural, one {{counter} sekėjas (-a)} few {{counter} sekėjai} many {{counter} sekėjo} other {{counter} sekėjų}}", + "account.followers_counter": "{count, plural, one {{counter} sekėjas} few {{counter} sekėjai} many {{counter} sekėjo} other {{counter} sekėjų}}", "account.following": "Seka", "account.following_counter": "{count, plural, one {{counter} Seka} few {{counter} Seka} many {{counter} Seka} other {{counter} Seka}}", "account.follows.empty": "Šis (-i) naudotojas (-a) dar nieko neseka.", diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json index 955955b8c2..5290e13ff4 100644 --- a/app/javascript/mastodon/locales/ta.json +++ b/app/javascript/mastodon/locales/ta.json @@ -78,11 +78,11 @@ "bundle_modal_error.close": "மூடுக", "bundle_modal_error.message": "இக்கூற்றை ஏற்றம் செய்யும்பொழுது ஏதோ தவறு ஏற்பட்டுள்ளது.", "bundle_modal_error.retry": "மீண்டும் முயற்சி செய்", - "closed_registrations.other_server_instructions": "மசுடோடன் இரு பரவலாக்கப்பட்ட மென்பொருள் என்பதால், நீங்கள் வேரு ஒரு வழங்கியில் கணக்கை உருவாக்கியிருந்தாலும் இந்த வழங்கியில் பயன்படுத்தலாம்.", - "closed_registrations_modal.description": "{domain} இல் இப்பொழுது கணக்குகள் உருவாக்க முடியாது. நீங்கள் மசுடோடன் பயன்படுத்த, குறிப்பாக {domain} முகவரியில் கணக்கைத் துவங்க வேண்டும் என்ற அவசியமில்லை என்பதை மனதில் வைத்துக் கொள்ளவும்.", + "closed_registrations.other_server_instructions": "மேச்டடான் இரு பரவலாக்கப்பட்ட மென்பொருள் என்பதால், நீங்கள் வேரு ஒரு வழங்கியில் கணக்கை உருவாக்கியிருந்தாலும் இந்த வழங்கியில் பயன்படுத்தலாம்.", + "closed_registrations_modal.description": "{domain} இல் இப்பொழுது கணக்குகள் உருவாக்க முடியாது. நீங்கள் மேச்டடான் பயன்படுத்த, குறிப்பாக {domain} முகவரியில் கணக்கைத் துவங்க வேண்டும் என்ற அவசியமில்லை என்பதை மனதில் வைத்துக் கொள்ளவும்.", "closed_registrations_modal.find_another_server": "வேறொரு வழங்கியைக் கண்டுபிடி", - "closed_registrations_modal.preamble": "மசுடோடன் ஒரு பரவலாக்கப்பட்ட மென்பொருள். ஆதனால் நீங்கள் எங்குக் கணக்கை உருவாக்கினாலும் இந்த வழங்கியில் உள்ள யாருடன் வேண்டும் என்றாலும் உரவாடலாம். நீங்களே கூட ஒரு வழங்கியை நிறுவலாம்!", - "closed_registrations_modal.title": "மசுடோடன் கணக்கு துவங்கப்படுகிறது", + "closed_registrations_modal.preamble": "மேச்டடான் ஒரு பரவலாக்கப்பட்ட மென்பொருள். ஆதனால் நீங்கள் எங்குக் கணக்கை உருவாக்கினாலும் இந்த வழங்கியில் உள்ள யாருடன் வேண்டும் என்றாலும் உரவாடலாம். நீங்களே கூட ஒரு வழங்கியை நிறுவலாம்!", + "closed_registrations_modal.title": "மேச்டடான் கணக்கு துவங்கப்படுகிறது", "column.about": "பற்றி", "column.blocks": "தடுக்கப்பட்ட பயனர்கள்", "column.bookmarks": "அடையாளக்குறிகள்", @@ -113,7 +113,7 @@ "compose.language.search": "தேடல் மொழிகள்...", "compose.published.body": "பதிவிடப்பட்டது.", "compose.published.open": "திற", - "compose.saved.body": "பதிவி சேமிக்கப்பட்டது.", + "compose.saved.body": "பதிவு சேமிக்கப்பட்டது.", "compose_form.direct_message_warning_learn_more": "மேலும் அறிய", "compose_form.encryption_warning": "Mastodonல் உள்ள பதிவுகள் முறையாக என்க்ரிப்ட்(encrypt) செய்யபடவில்லை. அதனால் முக்கிய தகவல்களை இங்கே பகிர வேண்டாம்.", "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", diff --git a/config/locales/doorkeeper.ie.yml b/config/locales/doorkeeper.ie.yml index 1b4b5994bd..86a5de7b37 100644 --- a/config/locales/doorkeeper.ie.yml +++ b/config/locales/doorkeeper.ie.yml @@ -70,6 +70,10 @@ ie: invalid_redirect_uri: Li uri de redirection includet ne es valid. invalid_request: unknown: Li petition manca un postulat parametre, include un ne apoyat parametre-valore, o es altrimen mal format. + invalid_token: + expired: Li access-clave expirat + revoked: Li access-clave esset revocat + unknown: Li accesse-clave es ínvalid unsupported_grant_type: Li tip de autorisation concedet ne es subtenet per li autorisant servitor. unsupported_response_type: Li autorisant servitor ne subtene ti-ci tip de response. flash: diff --git a/config/locales/simple_form.ie.yml b/config/locales/simple_form.ie.yml index f945e2342e..bde52e2a78 100644 --- a/config/locales/simple_form.ie.yml +++ b/config/locales/simple_form.ie.yml @@ -68,6 +68,7 @@ ie: form_admin_settings: backups_retention_period: Mantener usator-generat archives por li specificat quantitá de dies. bootstrap_timeline_accounts: Ti-ci contos va esser pinglat al parte superiori del recomandationes por nov usatores. + mascot: Substitue li ilustration in li avansat interfacie web. peers_api_enabled: Un liste de nómines de dominia queles ti-ci servitor ha incontrat in li fediverse. Ci null data es includet pri ca tu confedera con un cert servitor o ne; it indica solmen que tui servitor conosse it. Usat per servicies colectent general statisticas pri federation. profile_directory: Li profilarium monstra omni usatores volent esser decovribil. site_contact_email: Qualmen on posse contacter te por inquestes legal o de apoy. @@ -110,6 +111,10 @@ ie: name: Etiquette value: Contenete indexable: Includer public postas in resultates de sercha + account_alias: + acct: Usator-nómine del anteyan conto + account_migration: + acct: Usator-nómine del nov conto account_warning_preset: text: Textu prefigurat title: Titul @@ -240,6 +245,7 @@ ie: url: URL de punctu terminal 'no': 'No' not_recommended: Ne recomandat + overridden: Substituet recommended: Recomandat required: mark: "*" From bd415af9a11fe7057c9f428b7bdaeb8d4fb3a77b Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 3 Jan 2024 11:23:58 +0100 Subject: [PATCH 043/422] Change streaming API host to not be overridden to localhost in development mode (#28557) --- config/initializers/1_hosts.rb | 2 +- spec/requests/content_security_policy_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/initializers/1_hosts.rb b/config/initializers/1_hosts.rb index 6ff0845c46..5c59e28bd1 100644 --- a/config/initializers/1_hosts.rb +++ b/config/initializers/1_hosts.rb @@ -23,7 +23,7 @@ Rails.application.configure do if Rails.env.production? "ws#{https ? 's' : ''}://#{web_host}" else - "ws://#{ENV['REMOTE_DEV'] == 'true' ? host.split(':').first : 'localhost'}:4000" + "ws://#{host.split(':').first}:4000" end end diff --git a/spec/requests/content_security_policy_spec.rb b/spec/requests/content_security_policy_spec.rb index 7610e698cd..d4cc40bce5 100644 --- a/spec/requests/content_security_policy_spec.rb +++ b/spec/requests/content_security_policy_spec.rb @@ -20,7 +20,7 @@ describe 'Content-Security-Policy' do "form-action 'self'", "child-src 'self' blob: https://cb6e6126.ngrok.io", "worker-src 'self' blob: https://cb6e6126.ngrok.io", - "connect-src 'self' data: blob: https://cb6e6126.ngrok.io ws://localhost:4000", + "connect-src 'self' data: blob: https://cb6e6126.ngrok.io ws://cb6e6126.ngrok.io:4000", "script-src 'self' https://cb6e6126.ngrok.io 'wasm-unsafe-eval'" ) end From 092bb8a27af9ee87ff9ebabaf354477470ea3a94 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 3 Jan 2024 12:29:26 +0100 Subject: [PATCH 044/422] Fix Mastodon not correctly processing HTTP Signatures with query strings (#28476) --- .../concerns/signature_verification.rb | 22 ++++++- app/lib/request.rb | 11 +++- spec/requests/signature_verification_spec.rb | 66 +++++++++++++++++++ 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb index f0a344f1c9..35391e64c4 100644 --- a/app/controllers/concerns/signature_verification.rb +++ b/app/controllers/concerns/signature_verification.rb @@ -91,14 +91,23 @@ module SignatureVerification raise SignatureVerificationError, "Public key not found for key #{signature_params['keyId']}" if actor.nil? signature = Base64.decode64(signature_params['signature']) - compare_signed_string = build_signed_string + compare_signed_string = build_signed_string(include_query_string: true) return actor unless verify_signature(actor, signature, compare_signed_string).nil? + # Compatibility quirk with older Mastodon versions + compare_signed_string = build_signed_string(include_query_string: false) + return actor unless verify_signature(actor, signature, compare_signed_string).nil? + actor = stoplight_wrap_request { actor_refresh_key!(actor) } raise SignatureVerificationError, "Could not refresh public key #{signature_params['keyId']}" if actor.nil? + compare_signed_string = build_signed_string(include_query_string: true) + return actor unless verify_signature(actor, signature, compare_signed_string).nil? + + # Compatibility quirk with older Mastodon versions + compare_signed_string = build_signed_string(include_query_string: false) return actor unless verify_signature(actor, signature, compare_signed_string).nil? fail_with! "Verification failed for #{actor.to_log_human_identifier} #{actor.uri} using rsa-sha256 (RSASSA-PKCS1-v1_5 with SHA-256)", signed_string: compare_signed_string, signature: signature_params['signature'] @@ -180,11 +189,18 @@ module SignatureVerification nil end - def build_signed_string + def build_signed_string(include_query_string: true) signed_headers.map do |signed_header| case signed_header when Request::REQUEST_TARGET - "#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}" + if include_query_string + "#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.original_fullpath}" + else + # Current versions of Mastodon incorrectly omit the query string from the (request-target) pseudo-header. + # Therefore, temporarily support such incorrect signatures for compatibility. + # TODO: remove eventually some time after release of the fixed version + "#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}" + end when '(created)' raise SignatureVerificationError, 'Invalid pseudo-header (created) for rsa-sha256' unless signature_algorithm == 'hs2019' raise SignatureVerificationError, 'Pseudo-header (created) used but corresponding argument missing' if signature_params['created'].blank? diff --git a/app/lib/request.rb b/app/lib/request.rb index 5f128af734..8d4120868d 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -77,6 +77,7 @@ class Request @url = Addressable::URI.parse(url).normalize @http_client = options.delete(:http_client) @allow_local = options.delete(:allow_local) + @full_path = options.delete(:with_query_string) @options = options.merge(socket_class: use_proxy? || @allow_local ? ProxySocket : Socket) @options = @options.merge(timeout_class: PerOperationWithDeadline, timeout_options: TIMEOUT) @options = @options.merge(proxy_url) if use_proxy? @@ -146,7 +147,7 @@ class Request private def set_common_headers! - @headers[REQUEST_TARGET] = "#{@verb} #{@url.path}" + @headers[REQUEST_TARGET] = request_target @headers['User-Agent'] = Mastodon::Version.user_agent @headers['Host'] = @url.host @headers['Date'] = Time.now.utc.httpdate @@ -157,6 +158,14 @@ class Request @headers['Digest'] = "SHA-256=#{Digest::SHA256.base64digest(@options[:body])}" end + def request_target + if @url.query.nil? || !@full_path + "#{@verb} #{@url.path}" + else + "#{@verb} #{@url.path}?#{@url.query}" + end + end + def signature algorithm = 'rsa-sha256' signature = Base64.strict_encode64(@keypair.sign(OpenSSL::Digest.new('SHA256'), signed_string)) diff --git a/spec/requests/signature_verification_spec.rb b/spec/requests/signature_verification_spec.rb index b753750b84..401828c4a3 100644 --- a/spec/requests/signature_verification_spec.rb +++ b/spec/requests/signature_verification_spec.rb @@ -94,6 +94,72 @@ describe 'signature verification concern' do end end + context 'with a valid signature on a GET request that has a query string' do + let(:signature_header) do + 'keyId="https://remote.domain/users/bob#main-key",algorithm="rsa-sha256",headers="date host (request-target)",signature="SDMa4r/DQYMXYxVgYO2yEqGWWUXugKjVuz0I8dniQAk+aunzBaF2aPu+4grBfawAshlx1Xytl8lhb0H2MllEz16/tKY7rUrb70MK0w8ohXgpb0qs3YvQgdj4X24L1x2MnkFfKHR/J+7TBlnivq0HZqXm8EIkPWLv+eQxu8fbowLwHIVvRd/3t6FzvcfsE0UZKkoMEX02542MhwSif6cu7Ec/clsY9qgKahb9JVGOGS1op9Lvg/9y1mc8KCgD83U5IxVygYeYXaVQ6gixA9NgZiTCwEWzHM5ELm7w5hpdLFYxYOHg/3G3fiqJzpzNQAcCD4S4JxfE7hMI0IzVlNLT6A=="' # rubocop:disable Layout/LineLength + end + + it 'successfuly verifies signature', :aggregate_failures do + expect(signature_header).to eq build_signature_string(actor_keypair, 'https://remote.domain/users/bob#main-key', 'get /activitypub/success?foo=42', { 'Date' => 'Wed, 20 Dec 2023 10:00:00 GMT', 'Host' => 'www.example.com' }) + + get '/activitypub/success?foo=42', headers: { + 'Host' => 'www.example.com', + 'Date' => 'Wed, 20 Dec 2023 10:00:00 GMT', + 'Signature' => signature_header, + } + + expect(response).to have_http_status(200) + expect(body_as_json).to match( + signed_request: true, + signature_actor_id: actor.id.to_s + ) + end + end + + context 'when the query string is missing from the signature verification (compatibility quirk)' do + let(:signature_header) do + 'keyId="https://remote.domain/users/bob#main-key",algorithm="rsa-sha256",headers="date host (request-target)",signature="Z8ilar3J7bOwqZkMp7sL8sRs4B1FT+UorbmvWoE+A5UeoOJ3KBcUmbsh+k3wQwbP5gMNUrra9rEWabpasZGphLsbDxfbsWL3Cf0PllAc7c1c7AFEwnewtExI83/qqgEkfWc2z7UDutXc2NfgAx89Ox8DXU/fA2GG0jILjB6UpFyNugkY9rg6oI31UnvfVi3R7sr3/x8Ea3I9thPvqI2byF6cojknSpDAwYzeKdngX3TAQEGzFHz3SDWwyp3jeMWfwvVVbM38FxhvAnSumw7YwWW4L7M7h4M68isLimoT3yfCn2ucBVL5Dz8koBpYf/40w7QidClAwCafZQFC29yDOg=="' # rubocop:disable Layout/LineLength + end + + it 'successfuly verifies signature', :aggregate_failures do + expect(signature_header).to eq build_signature_string(actor_keypair, 'https://remote.domain/users/bob#main-key', 'get /activitypub/success', { 'Date' => 'Wed, 20 Dec 2023 10:00:00 GMT', 'Host' => 'www.example.com' }) + + get '/activitypub/success?foo=42', headers: { + 'Host' => 'www.example.com', + 'Date' => 'Wed, 20 Dec 2023 10:00:00 GMT', + 'Signature' => signature_header, + } + + expect(response).to have_http_status(200) + expect(body_as_json).to match( + signed_request: true, + signature_actor_id: actor.id.to_s + ) + end + end + + context 'with mismatching query string' do + let(:signature_header) do + 'keyId="https://remote.domain/users/bob#main-key",algorithm="rsa-sha256",headers="date host (request-target)",signature="SDMa4r/DQYMXYxVgYO2yEqGWWUXugKjVuz0I8dniQAk+aunzBaF2aPu+4grBfawAshlx1Xytl8lhb0H2MllEz16/tKY7rUrb70MK0w8ohXgpb0qs3YvQgdj4X24L1x2MnkFfKHR/J+7TBlnivq0HZqXm8EIkPWLv+eQxu8fbowLwHIVvRd/3t6FzvcfsE0UZKkoMEX02542MhwSif6cu7Ec/clsY9qgKahb9JVGOGS1op9Lvg/9y1mc8KCgD83U5IxVygYeYXaVQ6gixA9NgZiTCwEWzHM5ELm7w5hpdLFYxYOHg/3G3fiqJzpzNQAcCD4S4JxfE7hMI0IzVlNLT6A=="' # rubocop:disable Layout/LineLength + end + + it 'fails to verify signature', :aggregate_failures do + expect(signature_header).to eq build_signature_string(actor_keypair, 'https://remote.domain/users/bob#main-key', 'get /activitypub/success?foo=42', { 'Date' => 'Wed, 20 Dec 2023 10:00:00 GMT', 'Host' => 'www.example.com' }) + + get '/activitypub/success?foo=43', headers: { + 'Host' => 'www.example.com', + 'Date' => 'Wed, 20 Dec 2023 10:00:00 GMT', + 'Signature' => signature_header, + } + + expect(body_as_json).to match( + signed_request: true, + signature_actor_id: nil, + error: anything + ) + end + end + context 'with a mismatching path' do it 'fails to verify signature', :aggregate_failures do get '/activitypub/alternative-path', headers: { From e12d8893f42e5d2b2c71b43e0dff09438fbe81a2 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 3 Jan 2024 08:06:15 -0500 Subject: [PATCH 045/422] Fix intermittent failure from unspecified order in `export_domain_blocks` controller spec (#28562) --- app/controllers/admin/export_domain_blocks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/export_domain_blocks_controller.rb b/app/controllers/admin/export_domain_blocks_controller.rb index 433b8a1587..ffc4478172 100644 --- a/app/controllers/admin/export_domain_blocks_controller.rb +++ b/app/controllers/admin/export_domain_blocks_controller.rb @@ -68,7 +68,7 @@ module Admin def export_data CSV.generate(headers: export_headers, write_headers: true) do |content| - DomainBlock.with_limitations.each do |instance| + DomainBlock.with_limitations.order(id: :asc).each do |instance| content << [instance.domain, instance.severity, instance.reject_media, instance.reject_reports, instance.public_comment, instance.obfuscate] end end From 74a0d81e90607c275ab9c411a8b9c29512afa961 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 3 Jan 2024 08:06:38 -0500 Subject: [PATCH 046/422] Add coverage for CLI `self-destruct` command (#28565) Co-authored-by: Claire --- spec/lib/mastodon/cli/main_spec.rb | 109 +++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/spec/lib/mastodon/cli/main_spec.rb b/spec/lib/mastodon/cli/main_spec.rb index 59f1fc4784..931ca57c30 100644 --- a/spec/lib/mastodon/cli/main_spec.rb +++ b/spec/lib/mastodon/cli/main_spec.rb @@ -20,4 +20,113 @@ describe Mastodon::CLI::Main do .to output_results(Mastodon::Version.to_s) end end + + describe '#self_destruct' do + let(:action) { :self_destruct } + + context 'with self destruct mode enabled' do + before do + allow(SelfDestructHelper).to receive(:self_destruct?).and_return(true) + end + + context 'with pending accounts' do + before { Fabricate(:account) } + + it 'reports about pending accounts' do + expect { subject } + .to output_results( + 'already enabled', + 'still pending deletion' + ) + .and raise_error(SystemExit) + end + end + + context 'with sidekiq notices being processed' do + before do + Account.delete_all + stats_double = instance_double(Sidekiq::Stats, enqueued: 5) + allow(Sidekiq::Stats).to receive(:new).and_return(stats_double) + end + + it 'reports about notices' do + expect { subject } + .to output_results( + 'already enabled', + 'notices are still being' + ) + .and raise_error(SystemExit) + end + end + + context 'with sidekiq failed deliveries' do + before do + Account.delete_all + stats_double = instance_double(Sidekiq::Stats, enqueued: 0, retry_size: 10) + allow(Sidekiq::Stats).to receive(:new).and_return(stats_double) + end + + it 'reports about notices' do + expect { subject } + .to output_results( + 'already enabled', + 'some have failed and are scheduled' + ) + .and raise_error(SystemExit) + end + end + + context 'with self descruct mode ready' do + before do + Account.delete_all + stats_double = instance_double(Sidekiq::Stats, enqueued: 0, retry_size: 0) + allow(Sidekiq::Stats).to receive(:new).and_return(stats_double) + end + + it 'reports about notices' do + expect { subject } + .to output_results( + 'already enabled', + 'can safely delete all data' + ) + .and raise_error(SystemExit) + end + end + end + + context 'with self destruct mode disabled' do + before do + allow(SelfDestructHelper).to receive(:self_destruct?).and_return(false) + end + + context 'with an incorrect response to hostname' do + let(:prompt_double) { instance_double(TTY::Prompt, ask: 'wrong') } + + before do + allow(TTY::Prompt).to receive(:new).and_return(prompt_double) + end + + it 'reports failed answer' do + expect { subject } + .to raise_error(SystemExit) + end + end + + context 'with a correct response to hostname' do + # TODO: Update after tty-prompt replace with Thor methods + let(:prompt_double) { instance_double(TTY::Prompt, ask: Rails.configuration.x.local_domain, warn: nil, no?: false, ok: nil) } + + before do + allow(TTY::Prompt).to receive(:new).and_return(prompt_double) + end + + it 'instructs to set the appropriate environment variable' do + expect { subject } + .to_not raise_error + # TODO: Update after tty-prompt replace with Thor methods + expect(prompt_double).to have_received(:ok).with(/add the following variable/) + end + end + end + end end From 51d2b80ff7407a6c49a44eee80c67f81dc09d7dc Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 3 Jan 2024 08:22:03 -0500 Subject: [PATCH 047/422] Solve `Abc/*` metrics for `db/*migrate*` files (#28568) --- .rubocop.yml | 2 - ...221101190723_backfill_admin_action_logs.rb | 209 +++++++++++------- ...114142_backfill_admin_action_logs_again.rb | 209 +++++++++++------- 3 files changed, 254 insertions(+), 166 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 61cb1164b4..8832e28f6e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -74,14 +74,12 @@ Metrics/ModuleLength: Metrics/AbcSize: Exclude: - 'lib/mastodon/cli/*.rb' - - db/*migrate/**/* # Reason: Currently disabled in .rubocop_todo.yml # https://docs.rubocop.org/rubocop/cops_metrics.html#metricscyclomaticcomplexity Metrics/CyclomaticComplexity: Exclude: - lib/mastodon/cli/*.rb - - db/*migrate/**/* # Reason: # https://docs.rubocop.org/rubocop/cops_metrics.html#metricsparameterlists diff --git a/db/post_migrate/20221101190723_backfill_admin_action_logs.rb b/db/post_migrate/20221101190723_backfill_admin_action_logs.rb index 6476f4b13a..1d8d983b3a 100644 --- a/db/post_migrate/20221101190723_backfill_admin_action_logs.rb +++ b/db/post_migrate/20221101190723_backfill_admin_action_logs.rb @@ -77,90 +77,135 @@ class BackfillAdminActionLogs < ActiveRecord::Migration[6.1] def up safety_assured do - AdminActionLog.includes(:account).where(target_type: 'Account', human_identifier: nil).find_each do |log| - next if log.account.nil? - - log.update_attribute('human_identifier', log.account.acct) - end - - AdminActionLog.includes(user: :account).where(target_type: 'User', human_identifier: nil).find_each do |log| - next if log.user.nil? - - log.update_attribute('human_identifier', log.user.account.acct) - log.update_attribute('route_param', log.user.account_id) - end - - AdminActionLog.where(target_type: 'Report', human_identifier: nil).in_batches.update_all('human_identifier = target_id::text') - - AdminActionLog.includes(:domain_block).where(target_type: 'DomainBlock').find_each do |log| - next if log.domain_block.nil? - - log.update_attribute('human_identifier', log.domain_block.domain) - end - - AdminActionLog.includes(:domain_allow).where(target_type: 'DomainAllow').find_each do |log| - next if log.domain_allow.nil? - - log.update_attribute('human_identifier', log.domain_allow.domain) - end - - AdminActionLog.includes(:email_domain_block).where(target_type: 'EmailDomainBlock').find_each do |log| - next if log.email_domain_block.nil? - - log.update_attribute('human_identifier', log.email_domain_block.domain) - end - - AdminActionLog.includes(:unavailable_domain).where(target_type: 'UnavailableDomain').find_each do |log| - next if log.unavailable_domain.nil? - - log.update_attribute('human_identifier', log.unavailable_domain.domain) - end - - AdminActionLog.includes(status: :account).where(target_type: 'Status', human_identifier: nil).find_each do |log| - next if log.status.nil? - - log.update_attribute('human_identifier', log.status.account.acct) - log.update_attribute('permalink', log.status.uri) - end - - AdminActionLog.includes(account_warning: :account).where(target_type: 'AccountWarning', human_identifier: nil).find_each do |log| - next if log.account_warning.nil? - - log.update_attribute('human_identifier', log.account_warning.account.acct) - end - - AdminActionLog.includes(:announcement).where(target_type: 'Announcement', human_identifier: nil).find_each do |log| - next if log.announcement.nil? - - log.update_attribute('human_identifier', log.announcement.text) - end - - AdminActionLog.includes(:ip_block).where(target_type: 'IpBlock', human_identifier: nil).find_each do |log| - next if log.ip_block.nil? - - log.update_attribute('human_identifier', "#{log.ip_block.ip}/#{log.ip_block.ip.prefix}") - end - - AdminActionLog.includes(:custom_emoji).where(target_type: 'CustomEmoji', human_identifier: nil).find_each do |log| - next if log.custom_emoji.nil? - - log.update_attribute('human_identifier', log.custom_emoji.shortcode) - end - - AdminActionLog.includes(:canonical_email_block).where(target_type: 'CanonicalEmailBlock', human_identifier: nil).find_each do |log| - next if log.canonical_email_block.nil? - - log.update_attribute('human_identifier', log.canonical_email_block.canonical_email_hash) - end - - AdminActionLog.includes(appeal: :account).where(target_type: 'Appeal', human_identifier: nil).find_each do |log| - next if log.appeal.nil? - - log.update_attribute('human_identifier', log.appeal.account.acct) - log.update_attribute('route_param', log.appeal.account_warning_id) - end + process_logs_for_account + process_logs_for_user + process_logs_for_report + process_logs_for_domain_block + process_logs_for_domain_allow + process_logs_for_email_domain_block + process_logs_for_unavailable_domain + process_logs_for_status + process_logs_for_account_warning + process_logs_for_announcement + process_logs_for_ip_block + process_logs_for_custom_emoji + process_logs_for_canonical_email_block + process_logs_for_appeal end end def down; end + + private + + def process_logs_for_account + AdminActionLog.includes(:account).where(target_type: 'Account', human_identifier: nil).find_each do |log| + next if log.account.nil? + + log.update_attribute('human_identifier', log.account.acct) + end + end + + def process_logs_for_user + AdminActionLog.includes(user: :account).where(target_type: 'User', human_identifier: nil).find_each do |log| + next if log.user.nil? + + log.update_attribute('human_identifier', log.user.account.acct) + log.update_attribute('route_param', log.user.account_id) + end + end + + def process_logs_for_report + AdminActionLog.where(target_type: 'Report', human_identifier: nil).in_batches.update_all('human_identifier = target_id::text') + end + + def process_logs_for_domain_block + AdminActionLog.includes(:domain_block).where(target_type: 'DomainBlock').find_each do |log| + next if log.domain_block.nil? + + log.update_attribute('human_identifier', log.domain_block.domain) + end + end + + def process_logs_for_domain_allow + AdminActionLog.includes(:domain_allow).where(target_type: 'DomainAllow').find_each do |log| + next if log.domain_allow.nil? + + log.update_attribute('human_identifier', log.domain_allow.domain) + end + end + + def process_logs_for_email_domain_block + AdminActionLog.includes(:email_domain_block).where(target_type: 'EmailDomainBlock').find_each do |log| + next if log.email_domain_block.nil? + + log.update_attribute('human_identifier', log.email_domain_block.domain) + end + end + + def process_logs_for_unavailable_domain + AdminActionLog.includes(:unavailable_domain).where(target_type: 'UnavailableDomain').find_each do |log| + next if log.unavailable_domain.nil? + + log.update_attribute('human_identifier', log.unavailable_domain.domain) + end + end + + def process_logs_for_status + AdminActionLog.includes(status: :account).where(target_type: 'Status', human_identifier: nil).find_each do |log| + next if log.status.nil? + + log.update_attribute('human_identifier', log.status.account.acct) + log.update_attribute('permalink', log.status.uri) + end + end + + def process_logs_for_account_warning + AdminActionLog.includes(account_warning: :account).where(target_type: 'AccountWarning', human_identifier: nil).find_each do |log| + next if log.account_warning.nil? + + log.update_attribute('human_identifier', log.account_warning.account.acct) + end + end + + def process_logs_for_announcement + AdminActionLog.includes(:announcement).where(target_type: 'Announcement', human_identifier: nil).find_each do |log| + next if log.announcement.nil? + + log.update_attribute('human_identifier', log.announcement.text) + end + end + + def process_logs_for_ip_block + AdminActionLog.includes(:ip_block).where(target_type: 'IpBlock', human_identifier: nil).find_each do |log| + next if log.ip_block.nil? + + log.update_attribute('human_identifier', "#{log.ip_block.ip}/#{log.ip_block.ip.prefix}") + end + end + + def process_logs_for_custom_emoji + AdminActionLog.includes(:custom_emoji).where(target_type: 'CustomEmoji', human_identifier: nil).find_each do |log| + next if log.custom_emoji.nil? + + log.update_attribute('human_identifier', log.custom_emoji.shortcode) + end + end + + def process_logs_for_canonical_email_block + AdminActionLog.includes(:canonical_email_block).where(target_type: 'CanonicalEmailBlock', human_identifier: nil).find_each do |log| + next if log.canonical_email_block.nil? + + log.update_attribute('human_identifier', log.canonical_email_block.canonical_email_hash) + end + end + + def process_logs_for_appeal + AdminActionLog.includes(appeal: :account).where(target_type: 'Appeal', human_identifier: nil).find_each do |log| + next if log.appeal.nil? + + log.update_attribute('human_identifier', log.appeal.account.acct) + log.update_attribute('route_param', log.appeal.account_warning_id) + end + end end diff --git a/db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb b/db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb index 3c68470a7f..c080e77ecf 100644 --- a/db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb +++ b/db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb @@ -77,90 +77,135 @@ class BackfillAdminActionLogsAgain < ActiveRecord::Migration[6.1] def up safety_assured do - AdminActionLog.includes(:account).where(target_type: 'Account', human_identifier: nil).find_each do |log| - next if log.account.nil? - - log.update_attribute('human_identifier', log.account.acct) - end - - AdminActionLog.includes(user: :account).where(target_type: 'User', human_identifier: nil).find_each do |log| - next if log.user.nil? - - log.update_attribute('human_identifier', log.user.account.acct) - log.update_attribute('route_param', log.user.account_id) - end - - AdminActionLog.where(target_type: 'Report', human_identifier: nil).in_batches.update_all('human_identifier = target_id::text') - - AdminActionLog.includes(:domain_block).where(target_type: 'DomainBlock').find_each do |log| - next if log.domain_block.nil? - - log.update_attribute('human_identifier', log.domain_block.domain) - end - - AdminActionLog.includes(:domain_allow).where(target_type: 'DomainAllow').find_each do |log| - next if log.domain_allow.nil? - - log.update_attribute('human_identifier', log.domain_allow.domain) - end - - AdminActionLog.includes(:email_domain_block).where(target_type: 'EmailDomainBlock').find_each do |log| - next if log.email_domain_block.nil? - - log.update_attribute('human_identifier', log.email_domain_block.domain) - end - - AdminActionLog.includes(:unavailable_domain).where(target_type: 'UnavailableDomain').find_each do |log| - next if log.unavailable_domain.nil? - - log.update_attribute('human_identifier', log.unavailable_domain.domain) - end - - AdminActionLog.includes(status: :account).where(target_type: 'Status', human_identifier: nil).find_each do |log| - next if log.status.nil? - - log.update_attribute('human_identifier', log.status.account.acct) - log.update_attribute('permalink', log.status.uri) - end - - AdminActionLog.includes(account_warning: :account).where(target_type: 'AccountWarning', human_identifier: nil).find_each do |log| - next if log.account_warning.nil? - - log.update_attribute('human_identifier', log.account_warning.account.acct) - end - - AdminActionLog.includes(:announcement).where(target_type: 'Announcement', human_identifier: nil).find_each do |log| - next if log.announcement.nil? - - log.update_attribute('human_identifier', log.announcement.text) - end - - AdminActionLog.includes(:ip_block).where(target_type: 'IpBlock', human_identifier: nil).find_each do |log| - next if log.ip_block.nil? - - log.update_attribute('human_identifier', "#{log.ip_block.ip}/#{log.ip_block.ip.prefix}") - end - - AdminActionLog.includes(:custom_emoji).where(target_type: 'CustomEmoji', human_identifier: nil).find_each do |log| - next if log.custom_emoji.nil? - - log.update_attribute('human_identifier', log.custom_emoji.shortcode) - end - - AdminActionLog.includes(:canonical_email_block).where(target_type: 'CanonicalEmailBlock', human_identifier: nil).find_each do |log| - next if log.canonical_email_block.nil? - - log.update_attribute('human_identifier', log.canonical_email_block.canonical_email_hash) - end - - AdminActionLog.includes(appeal: :account).where(target_type: 'Appeal', human_identifier: nil).find_each do |log| - next if log.appeal.nil? - - log.update_attribute('human_identifier', log.appeal.account.acct) - log.update_attribute('route_param', log.appeal.account_warning_id) - end + process_logs_for_account + process_logs_for_user + process_logs_for_report + process_logs_for_domain_block + process_logs_for_domain_allow + process_logs_for_email_domain_block + process_logs_for_unavailable_domain + process_logs_for_status + process_logs_for_account_warning + process_logs_for_announcement + process_logs_for_ip_block + process_logs_for_custom_emoji + process_logs_for_canonical_email_block + process_logs_for_appeal end end def down; end + + private + + def process_logs_for_account + AdminActionLog.includes(:account).where(target_type: 'Account', human_identifier: nil).find_each do |log| + next if log.account.nil? + + log.update_attribute('human_identifier', log.account.acct) + end + end + + def process_logs_for_user + AdminActionLog.includes(user: :account).where(target_type: 'User', human_identifier: nil).find_each do |log| + next if log.user.nil? + + log.update_attribute('human_identifier', log.user.account.acct) + log.update_attribute('route_param', log.user.account_id) + end + end + + def process_logs_for_report + AdminActionLog.where(target_type: 'Report', human_identifier: nil).in_batches.update_all('human_identifier = target_id::text') + end + + def process_logs_for_domain_block + AdminActionLog.includes(:domain_block).where(target_type: 'DomainBlock').find_each do |log| + next if log.domain_block.nil? + + log.update_attribute('human_identifier', log.domain_block.domain) + end + end + + def process_logs_for_domain_allow + AdminActionLog.includes(:domain_allow).where(target_type: 'DomainAllow').find_each do |log| + next if log.domain_allow.nil? + + log.update_attribute('human_identifier', log.domain_allow.domain) + end + end + + def process_logs_for_email_domain_block + AdminActionLog.includes(:email_domain_block).where(target_type: 'EmailDomainBlock').find_each do |log| + next if log.email_domain_block.nil? + + log.update_attribute('human_identifier', log.email_domain_block.domain) + end + end + + def process_logs_for_unavailable_domain + AdminActionLog.includes(:unavailable_domain).where(target_type: 'UnavailableDomain').find_each do |log| + next if log.unavailable_domain.nil? + + log.update_attribute('human_identifier', log.unavailable_domain.domain) + end + end + + def process_logs_for_status + AdminActionLog.includes(status: :account).where(target_type: 'Status', human_identifier: nil).find_each do |log| + next if log.status.nil? + + log.update_attribute('human_identifier', log.status.account.acct) + log.update_attribute('permalink', log.status.uri) + end + end + + def process_logs_for_account_warning + AdminActionLog.includes(account_warning: :account).where(target_type: 'AccountWarning', human_identifier: nil).find_each do |log| + next if log.account_warning.nil? + + log.update_attribute('human_identifier', log.account_warning.account.acct) + end + end + + def process_logs_for_announcement + AdminActionLog.includes(:announcement).where(target_type: 'Announcement', human_identifier: nil).find_each do |log| + next if log.announcement.nil? + + log.update_attribute('human_identifier', log.announcement.text) + end + end + + def process_logs_for_ip_block + AdminActionLog.includes(:ip_block).where(target_type: 'IpBlock', human_identifier: nil).find_each do |log| + next if log.ip_block.nil? + + log.update_attribute('human_identifier', "#{log.ip_block.ip}/#{log.ip_block.ip.prefix}") + end + end + + def process_logs_for_custom_emoji + AdminActionLog.includes(:custom_emoji).where(target_type: 'CustomEmoji', human_identifier: nil).find_each do |log| + next if log.custom_emoji.nil? + + log.update_attribute('human_identifier', log.custom_emoji.shortcode) + end + end + + def process_logs_for_canonical_email_block + AdminActionLog.includes(:canonical_email_block).where(target_type: 'CanonicalEmailBlock', human_identifier: nil).find_each do |log| + next if log.canonical_email_block.nil? + + log.update_attribute('human_identifier', log.canonical_email_block.canonical_email_hash) + end + end + + def process_logs_for_appeal + AdminActionLog.includes(appeal: :account).where(target_type: 'Appeal', human_identifier: nil).find_each do |log| + next if log.appeal.nil? + + log.update_attribute('human_identifier', log.appeal.account.acct) + log.update_attribute('route_param', log.appeal.account_warning_id) + end + end end From 5c769de096ce7205308deaf5d62ad516b1e39259 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 3 Jan 2024 09:12:56 -0500 Subject: [PATCH 048/422] Add spec coverage for `CLI::Media#remove_orphans` command (#28267) --- lib/mastodon/cli/base.rb | 1 + spec/lib/mastodon/cli/media_spec.rb | 54 +++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/lib/mastodon/cli/base.rb b/lib/mastodon/cli/base.rb index 32aff2fcc5..8c222bbb2b 100644 --- a/lib/mastodon/cli/base.rb +++ b/lib/mastodon/cli/base.rb @@ -4,6 +4,7 @@ require_relative '../../../config/boot' require_relative '../../../config/environment' require 'thor' +require 'pastel' require_relative 'progress_helper' module Mastodon diff --git a/spec/lib/mastodon/cli/media_spec.rb b/spec/lib/mastodon/cli/media_spec.rb index 24e1467a3c..071bcd9e34 100644 --- a/spec/lib/mastodon/cli/media_spec.rb +++ b/spec/lib/mastodon/cli/media_spec.rb @@ -184,4 +184,58 @@ describe Mastodon::CLI::Media do end end end + + describe '#remove_orphans' do + let(:action) { :remove_orphans } + + before do + FileUtils.mkdir_p Rails.public_path.join('system') + end + + context 'without any options' do + it 'runs without error' do + expect { subject } + .to output_results('Removed', 'orphans (approx') + end + end + + context 'when in azure mode' do + before do + allow(Paperclip::Attachment).to receive(:default_options).and_return(storage: :azure) + end + + it 'warns about usage and exits' do + expect { subject } + .to output_results('azure storage driver is not supported') + .and raise_error(SystemExit) + end + end + + context 'when in fog mode' do + before do + allow(Paperclip::Attachment).to receive(:default_options).and_return(storage: :fog) + end + + it 'warns about usage and exits' do + expect { subject } + .to output_results('fog storage driver is not supported') + .and raise_error(SystemExit) + end + end + + context 'when in filesystem mode' do + before do + allow(File).to receive(:delete).and_return(true) + media_attachment.delete + end + + let(:media_attachment) { Fabricate(:media_attachment) } + + it 'removes the unlinked files' do + expect { subject } + .to output_results('Removed', 'orphans (approx') + expect(File).to have_received(:delete).with(media_attachment.file.path) + end + end + end end From 905794fd57386a33f8773cbeaec7b1cbb37c3e68 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 3 Jan 2024 16:04:10 +0100 Subject: [PATCH 049/422] Remove v3.5 branch from supported Mastodon versions (#28574) --- SECURITY.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 954ff73a24..81472b01b4 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -13,10 +13,8 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through ## Supported Versions -| Version | Supported | -| ------- | ---------------- | -| 4.2.x | Yes | -| 4.1.x | Yes | -| 4.0.x | No | -| 3.5.x | Until 2023-12-31 | -| < 3.5 | No | +| Version | Supported | +| ------- | --------- | +| 4.2.x | Yes | +| 4.1.x | Yes | +| < 4.1 | No | From f92d8c654df654538096efff05e9b1a989d01490 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 3 Jan 2024 10:08:08 -0500 Subject: [PATCH 050/422] Standardize on Thor methods in CLI classes (#28566) --- lib/mastodon/cli/federation.rb | 36 ++++++---------- lib/mastodon/cli/preview_cards.rb | 1 - spec/lib/mastodon/cli/main_spec.rb | 68 ++++++++++++++++++++++++------ 3 files changed, 70 insertions(+), 35 deletions(-) diff --git a/lib/mastodon/cli/federation.rb b/lib/mastodon/cli/federation.rb index 1b4cb467a5..4a4dde3686 100644 --- a/lib/mastodon/cli/federation.rb +++ b/lib/mastodon/cli/federation.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require 'tty-prompt' - module Mastodon::CLI module Federation extend ActiveSupport::Concern @@ -30,45 +28,39 @@ module Mastodon::CLI LONG_DESC def self_destruct if SelfDestructHelper.self_destruct? - prompt.ok('Self-destruct mode is already enabled for this Mastodon server') + say('Self-destruct mode is already enabled for this Mastodon server', :green) pending_accounts = Account.local.without_suspended.count + Account.local.suspended.joins(:deletion_request).count sidekiq_stats = Sidekiq::Stats.new if pending_accounts.positive? - prompt.warn("#{pending_accounts} accounts are still pending deletion.") + say("#{pending_accounts} accounts are still pending deletion.", :yellow) elsif sidekiq_stats.enqueued.positive? - prompt.warn('Deletion notices are still being processed') + say('Deletion notices are still being processed', :yellow) elsif sidekiq_stats.retry_size.positive? - prompt.warn('At least one delivery attempt for each deletion notice has been made, but some have failed and are scheduled for retry') + say('At least one delivery attempt for each deletion notice has been made, but some have failed and are scheduled for retry', :yellow) else - prompt.ok('Every deletion notice has been sent! You can safely delete all data and decomission your servers!') + say('Every deletion notice has been sent! You can safely delete all data and decomission your servers!', :green) end exit(0) end - exit(1) unless prompt.ask('Type in the domain of the server to confirm:', required: true) == Rails.configuration.x.local_domain + exit(1) unless ask('Type in the domain of the server to confirm:') == Rails.configuration.x.local_domain - prompt.warn('This operation WILL NOT be reversible.') - prompt.warn('While the data won\'t be erased locally, the server will be in a BROKEN STATE afterwards.') - prompt.warn('The deletion process itself may take a long time, and will be handled by Sidekiq, so do not shut it down until it has finished (you will be able to re-run this command to see the state of the self-destruct process).') + say('This operation WILL NOT be reversible.', :yellow) + say('While the data won\'t be erased locally, the server will be in a BROKEN STATE afterwards.', :yellow) + say('The deletion process itself may take a long time, and will be handled by Sidekiq, so do not shut it down until it has finished (you will be able to re-run this command to see the state of the self-destruct process).', :yellow) - exit(1) if prompt.no?('Are you sure you want to proceed?') + exit(1) if no?('Are you sure you want to proceed?') self_destruct_value = Rails.application.message_verifier('self-destruct').generate(Rails.configuration.x.local_domain) - prompt.ok('To switch Mastodon to self-destruct mode, add the following variable to your evironment (e.g. by adding a line to your `.env.production`) and restart all Mastodon processes:') - prompt.ok(" SELF_DESTRUCT=#{self_destruct_value}") - prompt.ok("\nYou can re-run this command to see the state of the self-destruct process.") - rescue TTY::Reader::InputInterrupt + say('To switch Mastodon to self-destruct mode, add the following variable to your evironment (e.g. by adding a line to your `.env.production`) and restart all Mastodon processes:', :green) + say(" SELF_DESTRUCT=#{self_destruct_value}", :green) + say("\nYou can re-run this command to see the state of the self-destruct process.", :green) + rescue Interrupt exit(1) end - - private - - def prompt - @prompt ||= TTY::Prompt.new - end end end end diff --git a/lib/mastodon/cli/preview_cards.rb b/lib/mastodon/cli/preview_cards.rb index 2df3d095da..9b20a0cbb8 100644 --- a/lib/mastodon/cli/preview_cards.rb +++ b/lib/mastodon/cli/preview_cards.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require 'tty-prompt' require_relative 'base' module Mastodon::CLI diff --git a/spec/lib/mastodon/cli/main_spec.rb b/spec/lib/mastodon/cli/main_spec.rb index 931ca57c30..081cd2dd47 100644 --- a/spec/lib/mastodon/cli/main_spec.rb +++ b/spec/lib/mastodon/cli/main_spec.rb @@ -100,33 +100,77 @@ describe Mastodon::CLI::Main do end context 'with an incorrect response to hostname' do - let(:prompt_double) { instance_double(TTY::Prompt, ask: 'wrong') } - before do - allow(TTY::Prompt).to receive(:new).and_return(prompt_double) + answer_hostname_incorrectly end - it 'reports failed answer' do + it 'exits silently' do expect { subject } .to raise_error(SystemExit) end end - context 'with a correct response to hostname' do - # TODO: Update after tty-prompt replace with Thor methods - let(:prompt_double) { instance_double(TTY::Prompt, ask: Rails.configuration.x.local_domain, warn: nil, no?: false, ok: nil) } - + context 'with a correct response to hostname but no to proceed' do before do - allow(TTY::Prompt).to receive(:new).and_return(prompt_double) + answer_hostname_correctly + decline_proceed + end + + it 'passes first step but stops before instructions' do + expect { subject } + .to output_results('operation WILL NOT') + .and raise_error(SystemExit) + end + end + + context 'with a correct response to hostname and yes to proceed' do + before do + answer_hostname_correctly + accept_proceed end it 'instructs to set the appropriate environment variable' do expect { subject } - .to_not raise_error - # TODO: Update after tty-prompt replace with Thor methods - expect(prompt_double).to have_received(:ok).with(/add the following variable/) + .to output_results( + 'operation WILL NOT', + 'the following variable' + ) end end + + private + + def answer_hostname_incorrectly + allow(cli.shell) + .to receive(:ask) + .with('Type in the domain of the server to confirm:') + .and_return('wrong.host') + .once + end + + def answer_hostname_correctly + allow(cli.shell) + .to receive(:ask) + .with('Type in the domain of the server to confirm:') + .and_return(Rails.configuration.x.local_domain) + .once + end + + def decline_proceed + allow(cli.shell) + .to receive(:no?) + .with('Are you sure you want to proceed?') + .and_return(true) + .once + end + + def accept_proceed + allow(cli.shell) + .to receive(:no?) + .with('Are you sure you want to proceed?') + .and_return(false) + .once + end end end end From 195b89d33619e0ce4271cef33fc29379254206f1 Mon Sep 17 00:00:00 2001 From: Michael Stanclift Date: Wed, 3 Jan 2024 13:02:53 -0600 Subject: [PATCH 051/422] Fix .opus file uploads being misidentified by Paperclip (#28580) --- app/models/concerns/attachmentable.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/concerns/attachmentable.rb b/app/models/concerns/attachmentable.rb index 4cdbdeb473..3b7db1fcef 100644 --- a/app/models/concerns/attachmentable.rb +++ b/app/models/concerns/attachmentable.rb @@ -11,11 +11,12 @@ module Attachmentable # For some file extensions, there exist different content # type variants, and browsers often send the wrong one, # for example, sending an audio .ogg file as video/ogg, - # likewise, MimeMagic also misreports them as such. For + # likewise, kt-paperclip also misreports them as such. For # those files, it is necessary to use the output of the # `file` utility instead INCORRECT_CONTENT_TYPES = %w( audio/vorbis + audio/opus video/ogg video/webm ).freeze From dfdadb92e834cc099d16d7539a661105e1d12390 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 4 Jan 2024 10:07:05 +0100 Subject: [PATCH 052/422] Add ability to require approval when users sign up using specific email domains (#28468) --- .../admin/email_domain_blocks_controller.rb | 4 ++-- .../admin/email_domain_blocks_controller.rb | 2 +- app/models/email_domain_block.rb | 23 +++++++++++-------- app/models/user.rb | 8 ++++++- .../admin/email_domain_block_serializer.rb | 2 +- .../_email_domain_block.html.haml | 4 ++++ .../admin/email_domain_blocks/new.html.haml | 3 +++ config/locales/en.yml | 1 + ...ow_with_approval_to_email_domain_blocks.rb | 7 ++++++ db/schema.rb | 3 ++- .../email_domain_blocks_controller_spec.rb | 3 ++- .../auth/registrations_controller_spec.rb | 19 +++++++++++++++ spec/services/app_sign_up_service_spec.rb | 21 +++++++++++++++++ 13 files changed, 84 insertions(+), 16 deletions(-) create mode 100644 db/migrate/20231222100226_add_allow_with_approval_to_email_domain_blocks.rb diff --git a/app/controllers/admin/email_domain_blocks_controller.rb b/app/controllers/admin/email_domain_blocks_controller.rb index 4a3228ec30..ff754bc0b4 100644 --- a/app/controllers/admin/email_domain_blocks_controller.rb +++ b/app/controllers/admin/email_domain_blocks_controller.rb @@ -40,7 +40,7 @@ module Admin (@email_domain_block.other_domains || []).uniq.each do |domain| next if EmailDomainBlock.where(domain: domain).exists? - other_email_domain_block = EmailDomainBlock.create!(domain: domain, parent: @email_domain_block) + other_email_domain_block = EmailDomainBlock.create!(domain: domain, allow_with_approval: @email_domain_block.allow_with_approval, parent: @email_domain_block) log_action :create, other_email_domain_block end end @@ -65,7 +65,7 @@ module Admin end def resource_params - params.require(:email_domain_block).permit(:domain, other_domains: []) + params.require(:email_domain_block).permit(:domain, :allow_with_approval, other_domains: []) end def form_email_domain_block_batch_params diff --git a/app/controllers/api/v1/admin/email_domain_blocks_controller.rb b/app/controllers/api/v1/admin/email_domain_blocks_controller.rb index 850eda6224..df54b9f0a4 100644 --- a/app/controllers/api/v1/admin/email_domain_blocks_controller.rb +++ b/app/controllers/api/v1/admin/email_domain_blocks_controller.rb @@ -55,7 +55,7 @@ class Api::V1::Admin::EmailDomainBlocksController < Api::BaseController end def resource_params - params.permit(:domain) + params.permit(:domain, :allow_with_approval) end def insert_pagination_headers diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb index 60e90208db..f1b14c8b08 100644 --- a/app/models/email_domain_block.rb +++ b/app/models/email_domain_block.rb @@ -4,11 +4,12 @@ # # Table name: email_domain_blocks # -# id :bigint(8) not null, primary key -# domain :string default(""), not null -# created_at :datetime not null -# updated_at :datetime not null -# parent_id :bigint(8) +# id :bigint(8) not null, primary key +# domain :string default(""), not null +# created_at :datetime not null +# updated_at :datetime not null +# parent_id :bigint(8) +# allow_with_approval :boolean default(FALSE), not null # class EmailDomainBlock < ApplicationRecord @@ -42,8 +43,8 @@ class EmailDomainBlock < ApplicationRecord @attempt_ip = attempt_ip end - def match? - blocking? || invalid_uri? + def match?(...) + blocking?(...) || invalid_uri? end private @@ -52,8 +53,8 @@ class EmailDomainBlock < ApplicationRecord @uris.any?(&:nil?) end - def blocking? - blocks = EmailDomainBlock.where(domain: domains_with_variants).order(Arel.sql('char_length(domain) desc')) + def blocking?(allow_with_approval: false) + blocks = EmailDomainBlock.where(domain: domains_with_variants, allow_with_approval: allow_with_approval).order(Arel.sql('char_length(domain) desc')) blocks.each { |block| block.history.add(@attempt_ip) } if @attempt_ip.present? blocks.any? end @@ -86,4 +87,8 @@ class EmailDomainBlock < ApplicationRecord def self.block?(domain_or_domains, attempt_ip: nil) Matcher.new(domain_or_domains, attempt_ip: attempt_ip).match? end + + def self.requires_approval?(domain_or_domains, attempt_ip: nil) + Matcher.new(domain_or_domains, attempt_ip: attempt_ip).match?(allow_with_approval: true) + end end diff --git a/app/models/user.rb b/app/models/user.rb index a1574c02ad..be1e84b49c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -418,7 +418,7 @@ class User < ApplicationRecord def set_approved self.approved = begin - if sign_up_from_ip_requires_approval? + if sign_up_from_ip_requires_approval? || sign_up_email_requires_approval? false else open_registrations? || valid_invitation? || external? @@ -430,6 +430,12 @@ class User < ApplicationRecord !sign_up_ip.nil? && IpBlock.where(severity: :sign_up_requires_approval).where('ip >>= ?', sign_up_ip.to_s).exists? end + def sign_up_email_requires_approval? + return false unless email.present? || unconfirmed_email.present? + + EmailDomainBlock.requires_approval?(email.presence || unconfirmed_email, attempt_ip: sign_up_ip) + end + def open_registrations? Setting.registrations_mode == 'open' end diff --git a/app/serializers/rest/admin/email_domain_block_serializer.rb b/app/serializers/rest/admin/email_domain_block_serializer.rb index a026ff680e..afe7722cb5 100644 --- a/app/serializers/rest/admin/email_domain_block_serializer.rb +++ b/app/serializers/rest/admin/email_domain_block_serializer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class REST::Admin::EmailDomainBlockSerializer < ActiveModel::Serializer - attributes :id, :domain, :created_at, :history + attributes :id, :domain, :created_at, :history, :allow_with_approval def id object.id.to_s diff --git a/app/views/admin/email_domain_blocks/_email_domain_block.html.haml b/app/views/admin/email_domain_blocks/_email_domain_block.html.haml index 7cb973c4b4..f6a6e82667 100644 --- a/app/views/admin/email_domain_blocks/_email_domain_block.html.haml +++ b/app/views/admin/email_domain_blocks/_email_domain_block.html.haml @@ -12,3 +12,7 @@ · = t('admin.email_domain_blocks.attempts_over_week', count: email_domain_block.history.reduce(0) { |sum, day| sum + day.accounts }) + + - if email_domain_block.allow_with_approval? + · + = t('admin.email_domain_blocks.allow_registrations_with_approval') diff --git a/app/views/admin/email_domain_blocks/new.html.haml b/app/views/admin/email_domain_blocks/new.html.haml index fa1d950ad2..3d31487733 100644 --- a/app/views/admin/email_domain_blocks/new.html.haml +++ b/app/views/admin/email_domain_blocks/new.html.haml @@ -7,6 +7,9 @@ .fields-group = f.input :domain, wrapper: :with_block_label, label: t('admin.email_domain_blocks.domain'), input_html: { readonly: defined?(@resolved_records) } + .fields-group + = f.input :allow_with_approval, wrapper: :with_label, hint: false, label: I18n.t('admin.email_domain_blocks.allow_registrations_with_approval') + - if defined?(@resolved_records) %p.hint= t('admin.email_domain_blocks.resolved_dns_records_hint_html') diff --git a/config/locales/en.yml b/config/locales/en.yml index 15d682d173..50f814a81d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -425,6 +425,7 @@ en: view: View domain block email_domain_blocks: add_new: Add new + allow_registrations_with_approval: Allow registrations with approval attempts_over_week: one: "%{count} attempt over the last week" other: "%{count} sign-up attempts over the last week" diff --git a/db/migrate/20231222100226_add_allow_with_approval_to_email_domain_blocks.rb b/db/migrate/20231222100226_add_allow_with_approval_to_email_domain_blocks.rb new file mode 100644 index 0000000000..01e8edfed4 --- /dev/null +++ b/db/migrate/20231222100226_add_allow_with_approval_to_email_domain_blocks.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddAllowWithApprovalToEmailDomainBlocks < ActiveRecord::Migration[7.1] + def change + add_column :email_domain_blocks, :allow_with_approval, :boolean, default: false, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 126ed8785a..4ea9744f40 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2023_12_12_073317) do +ActiveRecord::Schema[7.1].define(version: 2023_12_22_100226) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -435,6 +435,7 @@ ActiveRecord::Schema[7.1].define(version: 2023_12_12_073317) do t.datetime "created_at", precision: nil, null: false t.datetime "updated_at", precision: nil, null: false t.bigint "parent_id" + t.boolean "allow_with_approval", default: false, null: false t.index ["domain"], name: "index_email_domain_blocks_on_domain", unique: true end diff --git a/spec/controllers/admin/email_domain_blocks_controller_spec.rb b/spec/controllers/admin/email_domain_blocks_controller_spec.rb index 4286600144..9379fe374a 100644 --- a/spec/controllers/admin/email_domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/email_domain_blocks_controller_spec.rb @@ -12,13 +12,14 @@ RSpec.describe Admin::EmailDomainBlocksController do describe 'GET #index' do around do |example| default_per_page = EmailDomainBlock.default_per_page - EmailDomainBlock.paginates_per 1 + EmailDomainBlock.paginates_per 2 example.run EmailDomainBlock.paginates_per default_per_page end it 'returns http success' do 2.times { Fabricate(:email_domain_block) } + Fabricate(:email_domain_block, allow_with_approval: true) get :index, params: { page: 2 } expect(response).to have_http_status(200) end diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb index 37172f8d24..bd1c616595 100644 --- a/spec/controllers/auth/registrations_controller_spec.rb +++ b/spec/controllers/auth/registrations_controller_spec.rb @@ -135,6 +135,25 @@ RSpec.describe Auth::RegistrationsController do end end + context 'when user has an email address requiring approval' do + subject do + Setting.registrations_mode = 'open' + Fabricate(:email_domain_block, allow_with_approval: true, domain: 'example.com') + request.headers['Accept-Language'] = accept_language + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } } + end + + it 'creates unapproved user and redirects to setup' do + subject + expect(response).to redirect_to auth_setup_path + + user = User.find_by(email: 'test@example.com') + expect(user).to_not be_nil + expect(user.locale).to eq(accept_language) + expect(user.approved).to be(false) + end + end + context 'with Approval-based registrations without invite' do subject do Setting.registrations_mode = 'approved' diff --git a/spec/services/app_sign_up_service_spec.rb b/spec/services/app_sign_up_service_spec.rb index 0adb473f17..86e64dab21 100644 --- a/spec/services/app_sign_up_service_spec.rb +++ b/spec/services/app_sign_up_service_spec.rb @@ -27,6 +27,27 @@ RSpec.describe AppSignUpService, type: :service do end end + context 'when the email address requires approval' do + before do + Setting.registrations_mode = 'open' + Fabricate(:email_domain_block, allow_with_approval: true, domain: 'email.com') + end + + it 'creates an unapproved user', :aggregate_failures do + access_token = subject.call(app, remote_ip, params) + expect(access_token).to_not be_nil + expect(access_token.scopes.to_s).to eq 'read write' + + user = User.find_by(id: access_token.resource_owner_id) + expect(user).to_not be_nil + expect(user.confirmed?).to be false + expect(user.approved?).to be false + + expect(user.account).to_not be_nil + expect(user.invite_request).to be_nil + end + end + context 'when registrations are closed' do before do Setting.registrations_mode = 'none' From 38e5d1b53f042f17d18092471302445a902fae07 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 10:15:56 +0100 Subject: [PATCH 053/422] Update dependency net-ldap to v0.19.0 (#28588) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 295461bd35..8d01167537 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -474,7 +474,7 @@ GEM net-imap (0.4.4) date net-protocol - net-ldap (0.18.0) + net-ldap (0.19.0) net-pop (0.1.2) net-protocol net-protocol (0.2.2) From 0f3f98c01f33b0fd5968c8247f15dd0961afc9bc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 10:16:12 +0100 Subject: [PATCH 054/422] Update dependency react-redux-loading-bar to v5.0.8 (#28587) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3cd45a11d6..fd18bd9635 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13673,8 +13673,8 @@ __metadata: linkType: hard "react-redux-loading-bar@npm:^5.0.4": - version: 5.0.7 - resolution: "react-redux-loading-bar@npm:5.0.7" + version: 5.0.8 + resolution: "react-redux-loading-bar@npm:5.0.8" dependencies: prop-types: "npm:^15.7.2" react-lifecycles-compat: "npm:^3.0.4" @@ -13683,7 +13683,7 @@ __metadata: react-dom: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 react-redux: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 redux: ^3.0.0 || ^4.0.0 || ^5.0.0 - checksum: 45333093e7d28df923a657ad89ffe4673d7bd135ef57c0143fb4d868f21b57aeb9044691f553f7d2afbcc9080a1f8cd3cec5b274c80cb57faf0e87a70f7a2cce + checksum: 797c1abf8bcc947feb127380e6d363db264c12bc94e578d635f86f1d806b0ec714dc3723e54c884937448b17f9042cfc995fe7a1deaf558efc01681e43e4669c languageName: node linkType: hard From 9c268c9413a5bb6f1bad5c531dfdd0391326873f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 09:16:29 +0000 Subject: [PATCH 055/422] Update dependency axios to v1.6.4 (#28586) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index fd18bd9635..b2ffa3b9ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4678,13 +4678,13 @@ __metadata: linkType: hard "axios@npm:^1.4.0": - version: 1.6.3 - resolution: "axios@npm:1.6.3" + version: 1.6.4 + resolution: "axios@npm:1.6.4" dependencies: - follow-redirects: "npm:^1.15.0" + follow-redirects: "npm:^1.15.4" form-data: "npm:^4.0.0" proxy-from-env: "npm:^1.1.0" - checksum: dcc6d982353db33e6893ef01cdf81d0a0548dbd8fba0cb046dc4aee1a6a16226721faa4c2a13b2673d47130509629cdb93bb991b3a2bd4ef17a5ac27a8bba0da + checksum: daac697fa1ea9865cb48e9edb7eacd99e8a9214997f2d8e886cb61c380a613e5c270078bfc153ac96206680106c223f005f0e4bf2f3b2ddd88e559ecf970521f languageName: node linkType: hard @@ -8163,13 +8163,13 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.0": - version: 1.15.3 - resolution: "follow-redirects@npm:1.15.3" +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.4": + version: 1.15.4 + resolution: "follow-redirects@npm:1.15.4" peerDependenciesMeta: debug: optional: true - checksum: 915a2cf22e667bdf47b1a43cc6b7dce14d95039e9bbf9a24d0e739abfbdfa00077dd43c86d4a7a19efefcc7a99af144920a175eedc3888d268af5df67c272ee5 + checksum: 5f37ed9170c9eb19448c5418fdb0f2b73f644b5364834e70791a76ecc7db215246f9773bbef4852cfae4067764ffc852e047f744b661b0211532155b73556a6a languageName: node linkType: hard From 9826b7780ab4f0a6cbb633bf159fcea4db1b7ed9 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Thu, 4 Jan 2024 10:18:03 +0100 Subject: [PATCH 056/422] Streaming: use standard cors package instead of custom implementation (#28523) --- streaming/index.js | 16 ++-------------- streaming/package.json | 2 ++ yarn.lock | 25 +++++++++++++++++++++++-- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/streaming/index.js b/streaming/index.js index fb3e3fb2be..42d0afc7c5 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -5,6 +5,7 @@ const http = require('http'); const path = require('path'); const url = require('url'); +const cors = require('cors'); const dotenv = require('dotenv'); const express = require('express'); const Redis = require('ioredis'); @@ -187,6 +188,7 @@ const startServer = async () => { const pgPool = new pg.Pool(pgConfigFromEnv(process.env)); const server = http.createServer(app); + app.use(cors()); /** * @type {Object.): void>>} @@ -327,19 +329,6 @@ const startServer = async () => { } }; - /** - * @param {any} req - * @param {any} res - * @param {function(Error=): void} next - */ - const allowCrossDomain = (req, res, next) => { - res.header('Access-Control-Allow-Origin', '*'); - res.header('Access-Control-Allow-Headers', 'Authorization, Accept, Cache-Control'); - res.header('Access-Control-Allow-Methods', 'GET, OPTIONS'); - - next(); - }; - /** * @param {any} req * @param {any} res @@ -987,7 +976,6 @@ const startServer = async () => { api.use(setRequestId); api.use(setRemoteAddress); - api.use(allowCrossDomain); api.use(authenticationMiddleware); api.use(errorMiddleware); diff --git a/streaming/package.json b/streaming/package.json index 0cfc5b3276..2d70acb829 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -16,6 +16,7 @@ "check:types": "tsc --noEmit" }, "dependencies": { + "cors": "^2.8.5", "dotenv": "^16.0.3", "express": "^4.18.2", "ioredis": "^5.3.2", @@ -28,6 +29,7 @@ "ws": "^8.12.1" }, "devDependencies": { + "@types/cors": "^2.8.16", "@types/express": "^4.17.17", "@types/npmlog": "^7.0.0", "@types/pg": "^8.6.6", diff --git a/yarn.lock b/yarn.lock index b2ffa3b9ea..7b7f0e3153 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2468,12 +2468,14 @@ __metadata: version: 0.0.0-use.local resolution: "@mastodon/streaming@workspace:streaming" dependencies: + "@types/cors": "npm:^2.8.16" "@types/express": "npm:^4.17.17" "@types/npmlog": "npm:^7.0.0" "@types/pg": "npm:^8.6.6" "@types/uuid": "npm:^9.0.0" "@types/ws": "npm:^8.5.9" bufferutil: "npm:^4.0.7" + cors: "npm:^2.8.5" dotenv: "npm:^16.0.3" eslint-define-config: "npm:^2.0.0" express: "npm:^4.18.2" @@ -3027,6 +3029,15 @@ __metadata: languageName: node linkType: hard +"@types/cors@npm:^2.8.16": + version: 2.8.16 + resolution: "@types/cors@npm:2.8.16" + dependencies: + "@types/node": "npm:*" + checksum: ebcfb325b102739249bbaa4845cf1cf4830baf5490a32bcd1a85cd9b8c4d4b9eaaaea94423e454b5b7c9da77e46a64db80d2381d3bc3f940d15d13814e87b70a + languageName: node + linkType: hard + "@types/emoji-mart@npm:^3.0.9": version: 3.0.14 resolution: "@types/emoji-mart@npm:3.0.14" @@ -5973,6 +5984,16 @@ __metadata: languageName: node linkType: hard +"cors@npm:^2.8.5": + version: 2.8.5 + resolution: "cors@npm:2.8.5" + dependencies: + object-assign: "npm:^4" + vary: "npm:^1" + checksum: 373702b7999409922da80de4a61938aabba6929aea5b6fd9096fefb9e8342f626c0ebd7507b0e8b0b311380744cc985f27edebc0a26e0ddb784b54e1085de761 + languageName: node + linkType: hard + "cosmiconfig@npm:^7.0.0": version: 7.1.0 resolution: "cosmiconfig@npm:7.1.0" @@ -11953,7 +11974,7 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4.0.1, object-assign@npm:^4.1.1": +"object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: 1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 @@ -16728,7 +16749,7 @@ __metadata: languageName: node linkType: hard -"vary@npm:~1.1.2": +"vary@npm:^1, vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: f15d588d79f3675135ba783c91a4083dcd290a2a5be9fcb6514220a1634e23df116847b1cc51f66bfb0644cf9353b2abb7815ae499bab06e46dd33c1a6bf1f4f From 06374d07c3ce5eab2560ae85b56939cef575aee8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 10:19:38 +0100 Subject: [PATCH 057/422] Update dependency cssnano to v6.0.3 (#28581) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 196 +++++++++++++++++++++++++++--------------------------- 1 file changed, 98 insertions(+), 98 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7b7f0e3153..99c3eedb26 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5208,7 +5208,7 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.22.2": +"browserslist@npm:^4.0.0, browserslist@npm:^4.21.10, browserslist@npm:^4.22.2": version: 4.22.2 resolution: "browserslist@npm:4.22.2" dependencies: @@ -6140,7 +6140,7 @@ __metadata: languageName: node linkType: hard -"css-declaration-sorter@npm:^7.0.0": +"css-declaration-sorter@npm:^7.1.1": version: 7.1.1 resolution: "css-declaration-sorter@npm:7.1.1" peerDependencies: @@ -6228,7 +6228,7 @@ __metadata: languageName: node linkType: hard -"css-tree@npm:^2.2.1, css-tree@npm:^2.3.1": +"css-tree@npm:^2.3.1": version: 2.3.1 resolution: "css-tree@npm:2.3.1" dependencies: @@ -6278,42 +6278,42 @@ __metadata: languageName: node linkType: hard -"cssnano-preset-default@npm:^6.0.2": - version: 6.0.2 - resolution: "cssnano-preset-default@npm:6.0.2" +"cssnano-preset-default@npm:^6.0.3": + version: 6.0.3 + resolution: "cssnano-preset-default@npm:6.0.3" dependencies: - css-declaration-sorter: "npm:^7.0.0" + css-declaration-sorter: "npm:^7.1.1" cssnano-utils: "npm:^4.0.1" postcss-calc: "npm:^9.0.1" - postcss-colormin: "npm:^6.0.1" - postcss-convert-values: "npm:^6.0.1" + postcss-colormin: "npm:^6.0.2" + postcss-convert-values: "npm:^6.0.2" postcss-discard-comments: "npm:^6.0.1" postcss-discard-duplicates: "npm:^6.0.1" postcss-discard-empty: "npm:^6.0.1" postcss-discard-overridden: "npm:^6.0.1" - postcss-merge-longhand: "npm:^6.0.1" - postcss-merge-rules: "npm:^6.0.2" + postcss-merge-longhand: "npm:^6.0.2" + postcss-merge-rules: "npm:^6.0.3" postcss-minify-font-values: "npm:^6.0.1" postcss-minify-gradients: "npm:^6.0.1" - postcss-minify-params: "npm:^6.0.1" - postcss-minify-selectors: "npm:^6.0.1" + postcss-minify-params: "npm:^6.0.2" + postcss-minify-selectors: "npm:^6.0.2" postcss-normalize-charset: "npm:^6.0.1" postcss-normalize-display-values: "npm:^6.0.1" postcss-normalize-positions: "npm:^6.0.1" postcss-normalize-repeat-style: "npm:^6.0.1" postcss-normalize-string: "npm:^6.0.1" postcss-normalize-timing-functions: "npm:^6.0.1" - postcss-normalize-unicode: "npm:^6.0.1" + postcss-normalize-unicode: "npm:^6.0.2" postcss-normalize-url: "npm:^6.0.1" postcss-normalize-whitespace: "npm:^6.0.1" postcss-ordered-values: "npm:^6.0.1" - postcss-reduce-initial: "npm:^6.0.1" + postcss-reduce-initial: "npm:^6.0.2" postcss-reduce-transforms: "npm:^6.0.1" - postcss-svgo: "npm:^6.0.1" - postcss-unique-selectors: "npm:^6.0.1" + postcss-svgo: "npm:^6.0.2" + postcss-unique-selectors: "npm:^6.0.2" peerDependencies: postcss: ^8.4.31 - checksum: c6f97674704c3a2a2473440549eac38ac722feebabbd39f2d4d1b8fae7f137f8fd0dfb88929e1ff737d54008de583c39e96f9dc450f2d71f8be6fc3bac2840a3 + checksum: d100a1f8ab71adbb6df85e00f4a9e5d04ac06fc50343157eef853aded3f75dd0489dd845a5b2fb43ca701bd88c39c5aa88673f842bc1f94f4318c7b38ced1963 languageName: node linkType: hard @@ -6327,23 +6327,14 @@ __metadata: linkType: hard "cssnano@npm:^6.0.1": - version: 6.0.2 - resolution: "cssnano@npm:6.0.2" + version: 6.0.3 + resolution: "cssnano@npm:6.0.3" dependencies: - cssnano-preset-default: "npm:^6.0.2" + cssnano-preset-default: "npm:^6.0.3" lilconfig: "npm:^3.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 5f4146a6c8937d24b0d1d33e3acd85db7913c7558cc80b23169f86c9a552d091a26e0af6adcc535f8355561872f797a917b9353e38fe935bbaf08ec2b66f5ff8 - languageName: node - linkType: hard - -"csso@npm:5.0.5": - version: 5.0.5 - resolution: "csso@npm:5.0.5" - dependencies: - css-tree: "npm:~2.2.0" - checksum: ab4beb1e97dd7e207c10e9925405b45f15a6cd1b4880a8686ad573aa6d476aed28b4121a666cffd26c37a26179f7b54741f7c257543003bfb244d06a62ad569b + checksum: d1669eb987fd96159bae262ef2f76c1a64fffefe8fa593918a6bda377977798b60fb4a6a871a9b9a9deb11258130ee254fdb8c3144769b3060ad9f2a95a4ed0a languageName: node linkType: hard @@ -6356,6 +6347,15 @@ __metadata: languageName: node linkType: hard +"csso@npm:^5.0.5": + version: 5.0.5 + resolution: "csso@npm:5.0.5" + dependencies: + css-tree: "npm:~2.2.0" + checksum: ab4beb1e97dd7e207c10e9925405b45f15a6cd1b4880a8686ad573aa6d476aed28b4121a666cffd26c37a26179f7b54741f7c257543003bfb244d06a62ad569b + languageName: node + linkType: hard + "cssom@npm:^0.5.0": version: 0.5.0 resolution: "cssom@npm:0.5.0" @@ -12743,29 +12743,29 @@ __metadata: languageName: node linkType: hard -"postcss-colormin@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-colormin@npm:6.0.1" +"postcss-colormin@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-colormin@npm:6.0.2" dependencies: - browserslist: "npm:^4.21.4" + browserslist: "npm:^4.22.2" caniuse-api: "npm:^3.0.0" colord: "npm:^2.9.1" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: b0056812b3436b05b6b84284a1ebe68a72299f23e7eeb0b7b40a775978d06a1cbe235f3665e3f694f5de76fe7d9b93db607536d07697b31a59fd4e8705e5b64d + checksum: 229681f9b89ba0909b4c69563837b0c32cc3d1c17ed1b00c33d4abfb0a0ef455124968e4885b5f92c64482e92074cd1958018ec111ed5d118f1e24baeda19c14 languageName: node linkType: hard -"postcss-convert-values@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-convert-values@npm:6.0.1" +"postcss-convert-values@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-convert-values@npm:6.0.2" dependencies: - browserslist: "npm:^4.21.4" + browserslist: "npm:^4.22.2" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 53b951d7475206969c63b8427a2dea0ccba0a7cb08122e5f05aee8d12b09c870c070b101c9f8eceda76ff4d0fd9e5fa9385e83f143d658bb729dbb6a3583b872 + checksum: 882d0b7839ef07ac8ffbf9cb48db0f610939a3496bd0321c7f23096ead676f13e09ab3d9c20ff3dbe2c887e855826051ca7dffeaffce5068cfdc9aaa573a3842 languageName: node linkType: hard @@ -12828,29 +12828,29 @@ __metadata: languageName: node linkType: hard -"postcss-merge-longhand@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-merge-longhand@npm:6.0.1" +"postcss-merge-longhand@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-merge-longhand@npm:6.0.2" dependencies: postcss-value-parser: "npm:^4.2.0" - stylehacks: "npm:^6.0.1" + stylehacks: "npm:^6.0.2" peerDependencies: postcss: ^8.4.31 - checksum: 2c0eb81b6c6d3d2af3b129c46d10317b7923f218db1cadcb4723091fb951fe4624638002b65f235151129d4ce9b4775a6ed0d5fa13419c0df580f72e15fa4ad3 + checksum: 2b3fae51bffc5962258d638bc7f415237593b515f369233e023f0eae5b13116297463c04b8c47a7b7af51cba5faaa7f517b653f6123e51935d670d4d4de5a26d languageName: node linkType: hard -"postcss-merge-rules@npm:^6.0.2": - version: 6.0.2 - resolution: "postcss-merge-rules@npm:6.0.2" +"postcss-merge-rules@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-merge-rules@npm:6.0.3" dependencies: - browserslist: "npm:^4.21.4" + browserslist: "npm:^4.22.2" caniuse-api: "npm:^3.0.0" cssnano-utils: "npm:^4.0.1" - postcss-selector-parser: "npm:^6.0.5" + postcss-selector-parser: "npm:^6.0.15" peerDependencies: postcss: ^8.4.31 - checksum: 138a9921423420116b20e5761a1139392f0bcfcf34264fe11e254917d9c3170e3c0478a1b409e227d22bb0d9820b0168a871a240215d114e9c1e218ee6c132e6 + checksum: c8355db11aa60bedcb1e6535fcd70f6ecec2dadd5c2975d3accf0eedbc92af782ac1f5e91a53866816ce332e4cbf1b94749a9425067935be066bc0c974e30fee languageName: node linkType: hard @@ -12878,27 +12878,27 @@ __metadata: languageName: node linkType: hard -"postcss-minify-params@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-minify-params@npm:6.0.1" +"postcss-minify-params@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-minify-params@npm:6.0.2" dependencies: - browserslist: "npm:^4.21.4" + browserslist: "npm:^4.22.2" cssnano-utils: "npm:^4.0.1" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 0b34817f032ec9793fad4d33f3ba5551531073a36c9120d77194a3edeee860132951ed6954913494e5a6752ae8da1bc5cdb2a44fa5f428621afae8edddb0ca80 + checksum: 6638460d2be4a2eca8adee8409b70d6c6a19aff8cf93fda1b45c9da627b258b6baaa6acb48f51d26cd287704a235f9c9ae2e4744335b1fd47e163177c33896df languageName: node linkType: hard -"postcss-minify-selectors@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-minify-selectors@npm:6.0.1" +"postcss-minify-selectors@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-minify-selectors@npm:6.0.2" dependencies: - postcss-selector-parser: "npm:^6.0.5" + postcss-selector-parser: "npm:^6.0.15" peerDependencies: postcss: ^8.4.31 - checksum: ffc7ebb286beda2b2aa0ed13abafc89b5ffe232a48d57d3f2b9f69e167e354482a6f5279e9118bed753bf6e82d3cfb21228a6b07acd93d0dc9e01bbf0e7ebc75 + checksum: 5437b586c1237fc442e7e6078d4f23c987efc456366368b07a0da67332b04bd55821cedf0441e73e1209689f63139e272d930508e2963ba6e27c46561a661128 languageName: node linkType: hard @@ -13010,15 +13010,15 @@ __metadata: languageName: node linkType: hard -"postcss-normalize-unicode@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-normalize-unicode@npm:6.0.1" +"postcss-normalize-unicode@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-unicode@npm:6.0.2" dependencies: - browserslist: "npm:^4.21.4" + browserslist: "npm:^4.22.2" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 8057748dade94dc2dd63a3b75a85e394c2e9a7076053886ff08aa9b7729d383f204eda52d882e5361ae1ec493036e90b2e18dcc5f8c9b3a8f1cbfada12bcc05b + checksum: ea696194f65ad31de2a9c022f1946a07c298f04070706d88a20061845e1e052e645c74b5bc785595814db87d14e435f85e968a44855dedc207d8c0b5d43b1aee languageName: node linkType: hard @@ -13056,15 +13056,15 @@ __metadata: languageName: node linkType: hard -"postcss-reduce-initial@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-reduce-initial@npm:6.0.1" +"postcss-reduce-initial@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-reduce-initial@npm:6.0.2" dependencies: - browserslist: "npm:^4.21.4" + browserslist: "npm:^4.22.2" caniuse-api: "npm:^3.0.0" peerDependencies: postcss: ^8.4.31 - checksum: 3f8f6c26ceeb79ddc285b0e01183fe30e911dd26b3abcdca56568e2bef3747f2b7f22ee3f9117e9752e1e93c10bcd88bd6a2842ca525b54336726292ebd3c3ad + checksum: d35ad6f9725cdceb390a97a461e8594df7fbed4c55497c90d07c42f8343bf80139e720eaebc580bf480bf10e92959490aa308af66d8802ba71c327bdf08c93a1 languageName: node linkType: hard @@ -13104,36 +13104,36 @@ __metadata: languageName: node linkType: hard -"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.13, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5": - version: 6.0.13 - resolution: "postcss-selector-parser@npm:6.0.13" +"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.13, postcss-selector-parser@npm:^6.0.15, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4": + version: 6.0.15 + resolution: "postcss-selector-parser@npm:6.0.15" dependencies: cssesc: "npm:^3.0.0" util-deprecate: "npm:^1.0.2" - checksum: 51f099b27f7c7198ea1826470ef0adfa58b3bd3f59b390fda123baa0134880a5fa9720137b6009c4c1373357b144f700b0edac73335d0067422063129371444e + checksum: 48b425d6cef497bcf6b7d136f6fd95cfca43026955e07ec9290d3c15457de3a862dbf251dd36f42c07a0d5b5ab6f31e41acefeff02528995a989b955505e440b languageName: node linkType: hard -"postcss-svgo@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-svgo@npm:6.0.1" +"postcss-svgo@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-svgo@npm:6.0.2" dependencies: postcss-value-parser: "npm:^4.2.0" - svgo: "npm:^3.0.5" + svgo: "npm:^3.2.0" peerDependencies: postcss: ^8.4.31 - checksum: 021da9b0d0696fce970f407891a0d6c05e51d1908af435026e0cd5936a75cd8502a7d504cd0e6a33b6f3369fee41f01b848e5bd919aecc3e804ce6308e91a6cc + checksum: db607404d09af256c7957a0ace822d651a00a52a1796da603f93ba3f0a095ac7595e1f624b9dc53f362ab10e382845d7873f485980f9c92fcb86256833f5e835 languageName: node linkType: hard -"postcss-unique-selectors@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-unique-selectors@npm:6.0.1" +"postcss-unique-selectors@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-unique-selectors@npm:6.0.2" dependencies: - postcss-selector-parser: "npm:^6.0.5" + postcss-selector-parser: "npm:^6.0.15" peerDependencies: postcss: ^8.4.31 - checksum: 637e35775d0ee8fbcf4a81b28d3832c5076de7c0232eb7769d4fbbf783f26793e2ec95e18461ae3b9f5f5cd63c3de9db102464487ba2488d4947aad24dc8841f + checksum: a0fe112d1094f90e1bfcfd2174a74b2fd0630a24449e9942923d02956c7d64ea4add5adede53d9efb3f6d40cd388ac150d032a115f6a46b73d5f3d3d26fa1bb7 languageName: node linkType: hard @@ -15606,15 +15606,15 @@ __metadata: languageName: node linkType: hard -"stylehacks@npm:^6.0.1": - version: 6.0.1 - resolution: "stylehacks@npm:6.0.1" +"stylehacks@npm:^6.0.2": + version: 6.0.2 + resolution: "stylehacks@npm:6.0.2" dependencies: - browserslist: "npm:^4.21.4" - postcss-selector-parser: "npm:^6.0.4" + browserslist: "npm:^4.22.2" + postcss-selector-parser: "npm:^6.0.15" peerDependencies: postcss: ^8.4.31 - checksum: 0877016f5b2a06b8ceaf39382b0c33da11ea93268209444f67f29b1ce465994058f305fc3bc90dda21e8664c959561fbb06ba12b82289c3b26ba832c6979d513 + checksum: 658cac8b28edcb94d1db67808ab3aaa511cb1b9293594fc95607ee42ac4f57e742d9a1fa3ff5d5849db692971dc2a310e9ac1ed0bd4ea4bc48c80f5a6ef823fc languageName: node linkType: hard @@ -15838,20 +15838,20 @@ __metadata: languageName: node linkType: hard -"svgo@npm:^3.0.5": - version: 3.1.0 - resolution: "svgo@npm:3.1.0" +"svgo@npm:^3.2.0": + version: 3.2.0 + resolution: "svgo@npm:3.2.0" dependencies: "@trysound/sax": "npm:0.2.0" commander: "npm:^7.2.0" css-select: "npm:^5.1.0" - css-tree: "npm:^2.2.1" + css-tree: "npm:^2.3.1" css-what: "npm:^6.1.0" - csso: "npm:5.0.5" + csso: "npm:^5.0.5" picocolors: "npm:^1.0.0" bin: svgo: ./bin/svgo - checksum: b3f00b3319dee6ddc53f8b8ac5acef581860e1708c98b492169e096621edc1bdf46e3778099e3dffb5116bf0d4c074a686099843dbc020c73b3ccfae7b6a88f0 + checksum: 28fa9061ccbcf2e3616d48d1feb613aaa05f8f290a329beb0e585914f1864385152934a7d4d683a4609fafbae3d51666633437c359c5c5ef74fb58ad09092a7c languageName: node linkType: hard From f06c1f1552f289bd357e4f05cd6486832cf5028f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 4 Jan 2024 04:20:32 -0500 Subject: [PATCH 058/422] Fix `Capybara/ClickLinkOrButtonStyle` cop in spec/features (#28576) --- Gemfile.lock | 2 +- spec/features/admin/accounts_spec.rb | 8 ++--- spec/features/admin/custom_emojis_spec.rb | 2 +- spec/features/admin/domain_blocks_spec.rb | 18 +++++----- .../admin/email_domain_blocks_spec.rb | 2 +- spec/features/admin/ip_blocks_spec.rb | 2 +- spec/features/admin/software_updates_spec.rb | 4 +-- spec/features/admin/statuses_spec.rb | 2 +- .../links/preview_card_providers_spec.rb | 2 +- spec/features/admin/trends/links_spec.rb | 2 +- spec/features/admin/trends/statuses_spec.rb | 2 +- spec/features/admin/trends/tags_spec.rb | 2 +- spec/features/captcha_spec.rb | 2 +- spec/features/log_in_spec.rb | 6 ++-- spec/features/oauth_spec.rb | 36 +++++++++---------- spec/support/stories/profile_stories.rb | 2 +- spec/system/new_statuses_spec.rb | 4 +-- 17 files changed, 49 insertions(+), 49 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8d01167537..c3f27966d6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -676,7 +676,7 @@ GEM unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.30.0) parser (>= 3.2.1.0) - rubocop-capybara (2.19.0) + rubocop-capybara (2.20.0) rubocop (~> 1.41) rubocop-factory_bot (2.24.0) rubocop (~> 1.33) diff --git a/spec/features/admin/accounts_spec.rb b/spec/features/admin/accounts_spec.rb index ad9c51485a..6d7bab1844 100644 --- a/spec/features/admin/accounts_spec.rb +++ b/spec/features/admin/accounts_spec.rb @@ -22,7 +22,7 @@ describe 'Admin::Accounts' do context 'without selecting any accounts' do it 'displays a notice about account selection' do - click_button button_for_suspend + click_on button_for_suspend expect(page).to have_content(selection_error_text) end @@ -32,7 +32,7 @@ describe 'Admin::Accounts' do it 'suspends the account' do batch_checkbox_for(approved_user_account).check - click_button button_for_suspend + click_on button_for_suspend expect(approved_user_account.reload).to be_suspended end @@ -42,7 +42,7 @@ describe 'Admin::Accounts' do it 'approves the account user' do batch_checkbox_for(unapproved_user_account).check - click_button button_for_approve + click_on button_for_approve expect(unapproved_user_account.reload.user).to be_approved end @@ -52,7 +52,7 @@ describe 'Admin::Accounts' do it 'rejects and removes the account' do batch_checkbox_for(unapproved_user_account).check - click_button button_for_reject + click_on button_for_reject expect { unapproved_user_account.reload }.to raise_error(ActiveRecord::RecordNotFound) end diff --git a/spec/features/admin/custom_emojis_spec.rb b/spec/features/admin/custom_emojis_spec.rb index 3fea8f06fe..8a8b6efcd1 100644 --- a/spec/features/admin/custom_emojis_spec.rb +++ b/spec/features/admin/custom_emojis_spec.rb @@ -16,7 +16,7 @@ describe 'Admin::CustomEmojis' do context 'without selecting any records' do it 'displays a notice about selection' do - click_button button_for_enable + click_on button_for_enable expect(page).to have_content(selection_error_text) end diff --git a/spec/features/admin/domain_blocks_spec.rb b/spec/features/admin/domain_blocks_spec.rb index 4379ac91db..6a1405cdf6 100644 --- a/spec/features/admin/domain_blocks_spec.rb +++ b/spec/features/admin/domain_blocks_spec.rb @@ -14,7 +14,7 @@ describe 'blocking domains through the moderation interface' do fill_in 'domain_block_domain', with: 'example.com' select I18n.t('admin.domain_blocks.new.severity.silence'), from: 'domain_block_severity' - click_button I18n.t('admin.domain_blocks.new.create') + click_on I18n.t('admin.domain_blocks.new.create') expect(DomainBlock.exists?(domain: 'example.com', severity: 'silence')).to be true expect(DomainBlockWorker).to have_received(:perform_async) @@ -27,14 +27,14 @@ describe 'blocking domains through the moderation interface' do fill_in 'domain_block_domain', with: 'example.com' select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' - click_button I18n.t('admin.domain_blocks.new.create') + click_on I18n.t('admin.domain_blocks.new.create') # It doesn't immediately block but presents a confirmation screen expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com')) expect(DomainBlockWorker).to_not have_received(:perform_async) # Confirming creates a block - click_button I18n.t('admin.domain_blocks.confirm_suspension.confirm') + click_on I18n.t('admin.domain_blocks.confirm_suspension.confirm') expect(DomainBlock.exists?(domain: 'example.com', severity: 'suspend')).to be true expect(DomainBlockWorker).to have_received(:perform_async) @@ -49,14 +49,14 @@ describe 'blocking domains through the moderation interface' do fill_in 'domain_block_domain', with: 'example.com' select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' - click_button I18n.t('admin.domain_blocks.new.create') + click_on I18n.t('admin.domain_blocks.new.create') # It doesn't immediately block but presents a confirmation screen expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com')) expect(DomainBlockWorker).to_not have_received(:perform_async) # Confirming updates the block - click_button I18n.t('admin.domain_blocks.confirm_suspension.confirm') + click_on I18n.t('admin.domain_blocks.confirm_suspension.confirm') expect(domain_block.reload.severity).to eq 'suspend' expect(DomainBlockWorker).to have_received(:perform_async) @@ -71,14 +71,14 @@ describe 'blocking domains through the moderation interface' do fill_in 'domain_block_domain', with: 'subdomain.example.com' select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' - click_button I18n.t('admin.domain_blocks.new.create') + click_on I18n.t('admin.domain_blocks.new.create') # It doesn't immediately block but presents a confirmation screen expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'subdomain.example.com')) expect(DomainBlockWorker).to_not have_received(:perform_async) # Confirming creates the block - click_button I18n.t('admin.domain_blocks.confirm_suspension.confirm') + click_on I18n.t('admin.domain_blocks.confirm_suspension.confirm') expect(DomainBlock.where(domain: 'subdomain.example.com', severity: 'suspend')).to exist expect(DomainBlockWorker).to have_received(:perform_async) @@ -96,14 +96,14 @@ describe 'blocking domains through the moderation interface' do visit edit_admin_domain_block_path(domain_block) select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' - click_button I18n.t('generic.save_changes') + click_on I18n.t('generic.save_changes') # It doesn't immediately block but presents a confirmation screen expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com')) expect(DomainBlockWorker).to_not have_received(:perform_async) # Confirming updates the block - click_button I18n.t('admin.domain_blocks.confirm_suspension.confirm') + click_on I18n.t('admin.domain_blocks.confirm_suspension.confirm') expect(DomainBlockWorker).to have_received(:perform_async) expect(domain_block.reload.severity).to eq 'suspend' diff --git a/spec/features/admin/email_domain_blocks_spec.rb b/spec/features/admin/email_domain_blocks_spec.rb index 80efe72e95..14959cbe74 100644 --- a/spec/features/admin/email_domain_blocks_spec.rb +++ b/spec/features/admin/email_domain_blocks_spec.rb @@ -16,7 +16,7 @@ describe 'Admin::EmailDomainBlocks' do context 'without selecting any records' do it 'displays a notice about selection' do - click_button button_for_delete + click_on button_for_delete expect(page).to have_content(selection_error_text) end diff --git a/spec/features/admin/ip_blocks_spec.rb b/spec/features/admin/ip_blocks_spec.rb index 465c889190..c9b16f6f78 100644 --- a/spec/features/admin/ip_blocks_spec.rb +++ b/spec/features/admin/ip_blocks_spec.rb @@ -16,7 +16,7 @@ describe 'Admin::IpBlocks' do context 'without selecting any records' do it 'displays a notice about selection' do - click_button button_for_delete + click_on button_for_delete expect(page).to have_content(selection_error_text) end diff --git a/spec/features/admin/software_updates_spec.rb b/spec/features/admin/software_updates_spec.rb index a2373d35a6..4a635d1a79 100644 --- a/spec/features/admin/software_updates_spec.rb +++ b/spec/features/admin/software_updates_spec.rb @@ -11,13 +11,13 @@ describe 'finding software updates through the admin interface' do it 'shows a link to the software updates page, which links to release notes' do visit settings_profile_path - click_link I18n.t('admin.critical_update_pending') + click_on I18n.t('admin.critical_update_pending') expect(page).to have_title(I18n.t('admin.software_updates.title')) expect(page).to have_content('99.99.99') - click_link I18n.t('admin.software_updates.release_notes') + click_on I18n.t('admin.software_updates.release_notes') expect(page).to have_current_path('https://github.com/mastodon/mastodon/releases/v99', url: true) end end diff --git a/spec/features/admin/statuses_spec.rb b/spec/features/admin/statuses_spec.rb index a21c901a92..531d0de953 100644 --- a/spec/features/admin/statuses_spec.rb +++ b/spec/features/admin/statuses_spec.rb @@ -17,7 +17,7 @@ describe 'Admin::Statuses' do context 'without selecting any records' do it 'displays a notice about selection' do - click_button button_for_report + click_on button_for_report expect(page).to have_content(selection_error_text) end diff --git a/spec/features/admin/trends/links/preview_card_providers_spec.rb b/spec/features/admin/trends/links/preview_card_providers_spec.rb index cf9796abf3..dca89117b1 100644 --- a/spec/features/admin/trends/links/preview_card_providers_spec.rb +++ b/spec/features/admin/trends/links/preview_card_providers_spec.rb @@ -16,7 +16,7 @@ describe 'Admin::Trends::Links::PreviewCardProviders' do context 'without selecting any records' do it 'displays a notice about selection' do - click_button button_for_allow + click_on button_for_allow expect(page).to have_content(selection_error_text) end diff --git a/spec/features/admin/trends/links_spec.rb b/spec/features/admin/trends/links_spec.rb index 8b1b991a5a..99638bc069 100644 --- a/spec/features/admin/trends/links_spec.rb +++ b/spec/features/admin/trends/links_spec.rb @@ -16,7 +16,7 @@ describe 'Admin::Trends::Links' do context 'without selecting any records' do it 'displays a notice about selection' do - click_button button_for_allow + click_on button_for_allow expect(page).to have_content(selection_error_text) end diff --git a/spec/features/admin/trends/statuses_spec.rb b/spec/features/admin/trends/statuses_spec.rb index a578ab0559..779a15d38f 100644 --- a/spec/features/admin/trends/statuses_spec.rb +++ b/spec/features/admin/trends/statuses_spec.rb @@ -16,7 +16,7 @@ describe 'Admin::Trends::Statuses' do context 'without selecting any records' do it 'displays a notice about selection' do - click_button button_for_allow + click_on button_for_allow expect(page).to have_content(selection_error_text) end diff --git a/spec/features/admin/trends/tags_spec.rb b/spec/features/admin/trends/tags_spec.rb index 7502bc8c6f..52e49c3a5d 100644 --- a/spec/features/admin/trends/tags_spec.rb +++ b/spec/features/admin/trends/tags_spec.rb @@ -16,7 +16,7 @@ describe 'Admin::Trends::Tags' do context 'without selecting any records' do it 'displays a notice about selection' do - click_button button_for_allow + click_on button_for_allow expect(page).to have_content(selection_error_text) end diff --git a/spec/features/captcha_spec.rb b/spec/features/captcha_spec.rb index 906aec4af9..15c37eb463 100644 --- a/spec/features/captcha_spec.rb +++ b/spec/features/captcha_spec.rb @@ -23,7 +23,7 @@ describe 'email confirmation flow when captcha is enabled' do expect(user.reload.confirmed?).to be false # It redirects to app and confirms user - click_button I18n.t('challenge.confirm') + click_on I18n.t('challenge.confirm') expect(user.reload.confirmed?).to be true expect(page).to have_current_path(/\A#{client_app.confirmation_redirect_uri}/, url: true) diff --git a/spec/features/log_in_spec.rb b/spec/features/log_in_spec.rb index 7e5196aba9..c64e19d2b7 100644 --- a/spec/features/log_in_spec.rb +++ b/spec/features/log_in_spec.rb @@ -19,7 +19,7 @@ describe 'Log in' do it 'A valid email and password user is able to log in' do fill_in 'user_email', with: email fill_in 'user_password', with: password - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(subject).to have_css('div.app-holder') end @@ -27,7 +27,7 @@ describe 'Log in' do it 'A invalid email and password user is not able to log in' do fill_in 'user_email', with: 'invalid_email' fill_in 'user_password', with: 'invalid_password' - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(subject).to have_css('.flash-message', text: failure_message('invalid')) end @@ -38,7 +38,7 @@ describe 'Log in' do it 'A unconfirmed user is able to log in' do fill_in 'user_email', with: email fill_in 'user_password', with: password - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(subject).to have_css('div.admin-wrapper') end diff --git a/spec/features/oauth_spec.rb b/spec/features/oauth_spec.rb index 0e612b56a5..967956cc8e 100644 --- a/spec/features/oauth_spec.rb +++ b/spec/features/oauth_spec.rb @@ -20,7 +20,7 @@ describe 'Using OAuth from an external app' do expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) # Upon authorizing, it redirects to the apps' callback URL - click_button I18n.t('doorkeeper.authorizations.buttons.authorize') + click_on I18n.t('doorkeeper.authorizations.buttons.authorize') expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) # It grants the app access to the account @@ -35,7 +35,7 @@ describe 'Using OAuth from an external app' do expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.deny')) # Upon denying, it redirects to the apps' callback URL - click_button I18n.t('doorkeeper.authorizations.buttons.deny') + click_on I18n.t('doorkeeper.authorizations.buttons.deny') expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) # It does not grant the app access to the account @@ -63,17 +63,17 @@ describe 'Using OAuth from an external app' do # Failing to log-in presents the form again fill_in 'user_email', with: email fill_in 'user_password', with: 'wrong password' - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('auth.login')) # Logging in redirects to an authorization page fill_in 'user_email', with: email fill_in 'user_password', with: password - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) # Upon authorizing, it redirects to the apps' callback URL - click_button I18n.t('doorkeeper.authorizations.buttons.authorize') + click_on I18n.t('doorkeeper.authorizations.buttons.authorize') expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) # It grants the app access to the account @@ -90,17 +90,17 @@ describe 'Using OAuth from an external app' do # Failing to log-in presents the form again fill_in 'user_email', with: email fill_in 'user_password', with: 'wrong password' - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('auth.login')) # Logging in redirects to an authorization page fill_in 'user_email', with: email fill_in 'user_password', with: password - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) # Upon denying, it redirects to the apps' callback URL - click_button I18n.t('doorkeeper.authorizations.buttons.deny') + click_on I18n.t('doorkeeper.authorizations.buttons.deny') expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) # It does not grant the app access to the account @@ -120,27 +120,27 @@ describe 'Using OAuth from an external app' do # Failing to log-in presents the form again fill_in 'user_email', with: email fill_in 'user_password', with: 'wrong password' - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('auth.login')) # Logging in redirects to a two-factor authentication page fill_in 'user_email', with: email fill_in 'user_password', with: password - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('simple_form.hints.sessions.otp')) # Filling in an incorrect two-factor authentication code presents the form again fill_in 'user_otp_attempt', with: 'wrong' - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('simple_form.hints.sessions.otp')) # Filling in the correct TOTP code redirects to an app authorization page fill_in 'user_otp_attempt', with: user.current_otp - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) # Upon authorizing, it redirects to the apps' callback URL - click_button I18n.t('doorkeeper.authorizations.buttons.authorize') + click_on I18n.t('doorkeeper.authorizations.buttons.authorize') expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) # It grants the app access to the account @@ -157,27 +157,27 @@ describe 'Using OAuth from an external app' do # Failing to log-in presents the form again fill_in 'user_email', with: email fill_in 'user_password', with: 'wrong password' - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('auth.login')) # Logging in redirects to a two-factor authentication page fill_in 'user_email', with: email fill_in 'user_password', with: password - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('simple_form.hints.sessions.otp')) # Filling in an incorrect two-factor authentication code presents the form again fill_in 'user_otp_attempt', with: 'wrong' - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('simple_form.hints.sessions.otp')) # Filling in the correct TOTP code redirects to an app authorization page fill_in 'user_otp_attempt', with: user.current_otp - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) # Upon denying, it redirects to the apps' callback URL - click_button I18n.t('doorkeeper.authorizations.buttons.deny') + click_on I18n.t('doorkeeper.authorizations.buttons.deny') expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) # It does not grant the app access to the account diff --git a/spec/support/stories/profile_stories.rb b/spec/support/stories/profile_stories.rb index 82667ca080..2b345ddef1 100644 --- a/spec/support/stories/profile_stories.rb +++ b/spec/support/stories/profile_stories.rb @@ -18,7 +18,7 @@ module ProfileStories visit new_user_session_path fill_in 'user_email', with: email fill_in 'user_password', with: password - click_button I18n.t('auth.login') + click_on I18n.t('auth.login') end def with_alice_as_local_user diff --git a/spec/system/new_statuses_spec.rb b/spec/system/new_statuses_spec.rb index 244101f4d4..02f2e28393 100644 --- a/spec/system/new_statuses_spec.rb +++ b/spec/system/new_statuses_spec.rb @@ -24,7 +24,7 @@ describe 'NewStatuses' do within('.compose-form') do fill_in "What's on your mind?", with: status_text - click_button 'Publish!' + click_on 'Publish!' end expect(subject).to have_css('.status__content__text', text: status_text) @@ -37,7 +37,7 @@ describe 'NewStatuses' do within('.compose-form') do fill_in "What's on your mind?", with: status_text - click_button 'Publish!' + click_on 'Publish!' end expect(subject).to have_css('.status__content__text', text: status_text) From 1af5c3770153e7c3569d13c431e988049956ae8b Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 4 Jan 2024 04:21:27 -0500 Subject: [PATCH 059/422] Use heredoc on federation CLI warning strings (#28578) --- lib/mastodon/cli/federation.rb | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/mastodon/cli/federation.rb b/lib/mastodon/cli/federation.rb index 4a4dde3686..8bb46ecb1a 100644 --- a/lib/mastodon/cli/federation.rb +++ b/lib/mastodon/cli/federation.rb @@ -48,19 +48,31 @@ module Mastodon::CLI exit(1) unless ask('Type in the domain of the server to confirm:') == Rails.configuration.x.local_domain - say('This operation WILL NOT be reversible.', :yellow) - say('While the data won\'t be erased locally, the server will be in a BROKEN STATE afterwards.', :yellow) - say('The deletion process itself may take a long time, and will be handled by Sidekiq, so do not shut it down until it has finished (you will be able to re-run this command to see the state of the self-destruct process).', :yellow) + say(<<~WARNING, :yellow) + This operation WILL NOT be reversible. + While the data won't be erased locally, the server will be in a BROKEN STATE afterwards. + The deletion process itself may take a long time, and will be handled by Sidekiq, so do not shut it down until it has finished (you will be able to re-run this command to see the state of the self-destruct process). + WARNING exit(1) if no?('Are you sure you want to proceed?') - self_destruct_value = Rails.application.message_verifier('self-destruct').generate(Rails.configuration.x.local_domain) - say('To switch Mastodon to self-destruct mode, add the following variable to your evironment (e.g. by adding a line to your `.env.production`) and restart all Mastodon processes:', :green) - say(" SELF_DESTRUCT=#{self_destruct_value}", :green) - say("\nYou can re-run this command to see the state of the self-destruct process.", :green) + say(<<~INSTRUCTIONS, :green) + To switch Mastodon to self-destruct mode, add the following variable to your evironment (e.g. by adding a line to your `.env.production`) and restart all Mastodon processes: + SELF_DESTRUCT=#{self_destruct_value} + You can re-run this command to see the state of the self-destruct process. + INSTRUCTIONS rescue Interrupt exit(1) end + + private + + def self_destruct_value + Rails + .application + .message_verifier('self-destruct') + .generate(Rails.configuration.x.local_domain) + end end end end From bdf4750633703d97269522759ea6f2f8ecbd4976 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 09:24:13 +0000 Subject: [PATCH 060/422] New Crowdin Translations (automated) (#28590) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/ia.json | 25 +++++++++++++++++++++++- app/javascript/mastodon/locales/lad.json | 1 + app/javascript/mastodon/locales/nn.json | 2 +- app/javascript/mastodon/locales/no.json | 2 +- config/locales/devise.ie.yml | 7 +++++++ config/locales/doorkeeper.ie.yml | 3 +++ config/locales/lad.yml | 21 ++++++++++++++++++++ config/locales/simple_form.ie.yml | 12 ++++++++++++ 8 files changed, 70 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index 35397b8e12..9781d6aa77 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -38,12 +38,14 @@ "confirmation_modal.cancel": "Cancellar", "confirmations.delete.confirm": "Deler", "confirmations.delete_list.confirm": "Deler", + "confirmations.edit.confirm": "Modificar", "confirmations.logout.confirm": "Clauder le session", "copy_icon_button.copied": "Copiate al area de transferentia", "copypaste.copy_to_clipboard": "Copiar al area de transferentia", "disabled_account_banner.account_settings": "Parametros de conto", "dismissable_banner.dismiss": "Dimitter", "emoji_button.activity": "Activitate", + "emoji_button.clear": "Rader", "emoji_button.custom": "Personalisate", "emoji_button.search_results": "Resultatos de recerca", "empty_column.account_unavailable": "Profilo non disponibile", @@ -69,16 +71,37 @@ "navigation_bar.about": "A proposito de", "navigation_bar.advanced_interface": "Aperir in un interfacie web avantiate", "navigation_bar.blocks": "Usatores blocate", + "navigation_bar.discover": "Discoperir", + "navigation_bar.edit_profile": "Modificar profilo", "navigation_bar.favourites": "Favoritos", "navigation_bar.lists": "Listas", "navigation_bar.logout": "Clauder le session", "navigation_bar.preferences": "Preferentias", + "navigation_bar.search": "Cercar", "navigation_bar.security": "Securitate", "notifications.column_settings.alert": "Notificationes de scriptorio", "notifications.column_settings.filter_bar.advanced": "Monstrar tote le categorias", "notifications.column_settings.sound": "Reproducer sono", "notifications.filter.all": "Toto", + "notifications.grant_permission": "Conceder permission.", + "notifications.group": "{count} notificationes", "onboarding.compose.template": "Salute #Mastodon!", "onboarding.profile.save_and_continue": "Salvar e continuar", - "onboarding.share.title": "Compartir tu profilo" + "onboarding.share.title": "Compartir tu profilo", + "onboarding.steps.share_profile.title": "Compartir tu profilo de Mastodon", + "relative_time.just_now": "ora", + "relative_time.today": "hodie", + "reply_indicator.cancel": "Cancellar", + "report.next": "Sequente", + "report.placeholder": "Commentos additional", + "report.reasons.dislike": "Non me place", + "search.quick_action.go_to_account": "Vader al profilo {x}", + "search_results.accounts": "Profilos", + "search_results.see_all": "Vider toto", + "status.delete": "Deler", + "status.share": "Compartir", + "status.translate": "Traducer", + "status.translated_from_with": "Traducite ab {lang} usante {provider}", + "tabs_bar.home": "Initio", + "tabs_bar.notifications": "Notificationes" } diff --git a/app/javascript/mastodon/locales/lad.json b/app/javascript/mastodon/locales/lad.json index ce6cb56473..2067edcc70 100644 --- a/app/javascript/mastodon/locales/lad.json +++ b/app/javascript/mastodon/locales/lad.json @@ -501,6 +501,7 @@ "onboarding.steps.setup_profile.title": "Personaliza tu profil", "onboarding.steps.share_profile.body": "Informe a tus amigos komo toparte en Mastodon", "onboarding.steps.share_profile.title": "Partaja tu profil de Mastodon", + "password_confirmation.mismatching": "Los dos kodes son desferentes", "picture_in_picture.restore": "Restora", "poll.closed": "Serrado", "poll.refresh": "Arefreska", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index e5b1d2b378..ec2ff82144 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -606,7 +606,7 @@ "search.quick_action.status_search": "Innlegg som samsvarer med {x}", "search.search_or_paste": "Søk eller lim inn URL", "search_popout.full_text_search_disabled_message": "Ikkje tilgjengeleg på {domain}.", - "search_popout.full_text_search_logged_out_message": "Bare tilgjengelig ved innlogging.", + "search_popout.full_text_search_logged_out_message": "Bare tilgjengelig når man er logget inn.", "search_popout.language_code": "ISO-språkkode", "search_popout.options": "Søkjealternativ", "search_popout.quick_actions": "Hurtighandlinger", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index c0f50283ac..50da3bb2be 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -606,7 +606,7 @@ "search.quick_action.status_search": "Innlegg som samsvarer med {x}", "search.search_or_paste": "Søk eller lim inn URL", "search_popout.full_text_search_disabled_message": "Ikke tilgjengelig på {domain}.", - "search_popout.full_text_search_logged_out_message": "Bare tilgjengelig ved innlogging.", + "search_popout.full_text_search_logged_out_message": "Bare tilgjengelig når man er logget inn.", "search_popout.language_code": "ISO språkkode", "search_popout.options": "Alternativer for søk", "search_popout.quick_actions": "Hurtighandlinger", diff --git a/config/locales/devise.ie.yml b/config/locales/devise.ie.yml index e4f2e6fb19..687e7115a6 100644 --- a/config/locales/devise.ie.yml +++ b/config/locales/devise.ie.yml @@ -46,6 +46,10 @@ ie: title: 2FA desvalidat two_factor_enabled: title: 2FA permisset + two_factor_recovery_codes_changed: + explanation: Li anteyan codes de recuperation ha esset ínvalidat, e novis generat. + subject: 'Mastodon: 2-factor codes de recuperation regenerat' + title: 2FA codes de recuperation changeat unlock_instructions: subject: 'Mastodon: Desserral instructiones' webauthn_credential: @@ -55,8 +59,11 @@ ie: webauthn_disabled: subject: 'Mastodon: Autentication con claves de securitá desactivisat' title: Claves de securitá desactivisat + webauthn_enabled: + title: Claves de securitá activisat omniauth_callbacks: failure: Ne posset autenticar te de %{kind} pro "%{reason}". + success: Successosimen autenticat de conto %{kind}. passwords: no_token: Tu ne posse accessar ti-ci págine sin venir de un email pri reiniciar li passa-parol. Si tu ha venit de un email pri reiniciar li passa-parol, ples far cert que tu usat li complet URL providet. send_instructions: Si tui email-adresse existe in nor database, tu va reciver un ligament por recuperar li passa-parol a tui email-adresse in quelc minutes. Ples vider tui spam-emails si tu ne recivet ti email. diff --git a/config/locales/doorkeeper.ie.yml b/config/locales/doorkeeper.ie.yml index 86a5de7b37..b778871e3a 100644 --- a/config/locales/doorkeeper.ie.yml +++ b/config/locales/doorkeeper.ie.yml @@ -31,6 +31,7 @@ ie: redirect_uri: Usar un linea per URI index: application: Aplication + callback_url: URL de retrovocada delete: Deleter empty: Tu have null aplicationes. name: Nómine @@ -42,6 +43,7 @@ ie: show: actions: Actiones application_id: Clave de client + callback_urls: URLs de retrovocada secret: Secrete de client title: 'Aplication: %{name}' authorizations: @@ -51,6 +53,7 @@ ie: error: title: Alquo ha errat new: + review_permissions: Inspecter permissiones title: Autorisation besonat authorized_applications: buttons: diff --git a/config/locales/lad.yml b/config/locales/lad.yml index 5c541d9f99..323ade8ddb 100644 --- a/config/locales/lad.yml +++ b/config/locales/lad.yml @@ -383,7 +383,11 @@ lad: confirm_suspension: cancel: Anula confirm: Suspende + permanent_action: Si kites la suspensyon no restoraras dingunos datos ni relasyones. + remove_all_data: Esto efasara todo el kontenido, multimedia i datos de profiles de los kuentos en este domeno de tu sirvidor. + stop_communication: Tu sirvidor deshara de komunikarse kon estos sirvidores. title: Konfirma bloko de domeno para %{domain} + undo_relationships: Esto kitara todas las relasyones de segimyento entre tu kuentos en estos sirvidores i el tu sirvidor. created_msg: El bloko de domeno esta siendo prosesado destroyed_msg: El bloko de domeno se dezizo domain: Domeno @@ -772,6 +776,8 @@ lad: type: Tipo types: major: Versyon prinsipala + minor: Versyon minora + patch: Versyon de remendo – koreksyones de yerros i trokamientos simples version: Versyon statuses: account: Autor @@ -829,8 +835,10 @@ lad: message_html: No ay dingun prosedura Sidekiq en egzekusion para la(s) kola(s) %{value}. Por favor, reviza tu konfigurasyon de Sidekiq software_version_critical_check: action: Amostra aktualizasyones desponivles + message_html: Una aktualizasyon kritika de Mastodon esta desponivle. Por favor aktualiza pishin. software_version_patch_check: action: Amostra aktualizasyones desponivles + message_html: Una aktualizasyon de Mastodon kon koreksyon de yerros esta desponivle. upload_check_privacy_error: action: Klika aki para mas enformasyon message_html: "Tu sirvidor de web es mal konfigurado. La privasita de tus utilizadores esta en riziko." @@ -945,6 +953,7 @@ lad: next_steps: Puedes achetar la apelasyon para dezazer la dechizyon de moderasyon, o ignorarla. subject: "%{username} esta apelando a una dechizyon de moderasyon en %{instance}" new_critical_software_updates: + body: Ay mueva versyon kritika de Mastodon. Es posivle ke keras aktualizar pishin! subject: Ay aktualizasyones kritikas de Mastodon desponivles para %{instance}! new_pending_account: body: Los peratim del muevo kuento estan abashos. Puedes achetar o refuzar esta aplikasyon. @@ -1045,13 +1054,17 @@ lad: accept: Acheta back: Atras preamble: Estas son establesidas i aplikadas por los moderadores de %{domain}. + preamble_invited: Antes de kontinuar, por favor reviza las reglas del sirvidor establesidas por los moderatores de %{domain}. title: Algunas reglas bazikas. title_invited: Fuites envitado. security: Sigurita set_new_password: Establese muevo kod setup: email_below_hint_html: Mira en tu kuti de spam o solisita de muevo. Si el adreso de posta elektronika ke aparese aki es yerrado, puedes trokarlo aki. + email_settings_hint_html: Klika el atadjiko ke te embimos para verifikar %{email}. Asperaremos aki. link_not_received: No risivites un atadijo? + new_confirmation_instructions_sent: Resiviras un muevo mesaj de posta elektronika kon el atadjio de konfirmasyon en unos minutos! + title: Reviza tu kuti de arivo sign_in: preamble_html: Konektate kon tus kredensiales de %{domain}. Si tu kuento esta balabayado en otruno servidor, no puedras konektarte aki. title: Konektate kon %{domain} @@ -1246,9 +1259,11 @@ lad: imports: errors: empty: Dosya CSV vaziya + incompatible_type: Inkompativle kon el tipo de importo eskojido invalid_csv_file: 'Dosya CSV no valida. Yerro: %{error}' over_rows_processing_limit: kontiene mas de %{count} filas too_large: Dosya es mas grande + failures: Yerros imported: Importado modes: merge: Une @@ -1671,6 +1686,9 @@ lad: month: "%b %Y" time: "%H:%M" with_time_zone: "%d de %b del %Y, %H:%M %Z" + translation: + errors: + too_many_requests: Ay demaziadas solisitudes de servisyo de traduksyon. two_factor_authentication: add: Adjusta disable: Inkapasita autentifikasyon en dos pasos @@ -1750,9 +1768,12 @@ lad: title: Bienvenido, %{name}! users: follow_limit_reached: No puedes segir a mas de %{limit} personas + go_to_sso_account_settings: Va a la konfigurasyon de kuento de tu prokurador de identita invalid_otp_token: Kodiche de dos pasos no valido + otp_lost_help_html: Si pedriste akseso a los dos, puedes kontaktarte kon %{email} signed_in_as: 'Konektado komo:' verification: + here_is_how: Ansina es komo verification: Verifikasyon verified_links: Tus atadijos verifikados webauthn_credentials: diff --git a/config/locales/simple_form.ie.yml b/config/locales/simple_form.ie.yml index bde52e2a78..bd055b1c9e 100644 --- a/config/locales/simple_form.ie.yml +++ b/config/locales/simple_form.ie.yml @@ -86,6 +86,7 @@ ie: ip_block: comment: Facultativ. Ne obliviar pro quo tu adjuntet ti-ci regul. expires_in: IP-adresses es un ressurse finit, quelcvez partit e transferet de manu a manu. Pro to, un índefinit bloccada de IP ne es recomandat. + ip: Intrar un adresse IPv4 o IPv6. Tu posse bloccar un tot intervalle de ili con li sintaxe CIDR. Atention a ne bloccar te self! severities: no_access: Bloccar accesse a omni ressurses sign_up_block: Nov registrationes ne va esser possibil @@ -93,6 +94,10 @@ ie: severity: Selecter quo va evenir con demandes ex ti-ci IP rule: text: Descrir un regul o postulation por usatores sur ti-ci servitor. Prova scrir un descrition curt e simplic + sessions: + otp: 'Intrar li 2-factor code generat del app sur tui portabile o usar un de tui codes de recuperation:' + settings: + show_application: Totvez, tu va sempre posser vider quel app ha publicat tui posta. user: role: Permissiones de usator decidet per su rol user_role: @@ -111,6 +116,7 @@ ie: name: Etiquette value: Contenete indexable: Includer public postas in resultates de sercha + unlocked: Automaticmen acceptar nov sequitores account_alias: acct: Usator-nómine del anteyan conto account_migration: @@ -158,6 +164,7 @@ ie: max_uses: Max grand númere de usas new_password: Nov passa-parol note: Biografie + otp_attempt: 2-factor code password: Passa-parol phrase: Clave-parol o frase setting_advanced_layout: Possibilisar web-interfacie avansat @@ -165,10 +172,12 @@ ie: setting_default_language: Lingue in quel postar setting_default_privacy: Privatie de postada setting_default_sensitive: Sempre marcar medie quam sensitiv + setting_display_media: Exposition de medie setting_display_media_default: Predefinitiones setting_display_media_hide_all: Celar omno setting_display_media_show_all: Monstrar omno setting_expand_spoilers: Sempre expander postas marcat con admonitiones de contenete + setting_hide_network: Celar tui grafica social setting_system_font_ui: Usar predefinit fonte de sistema setting_theme: Tema de situ setting_trends: Monstrar li hodial tendenties @@ -179,6 +188,7 @@ ie: title: Titul type: Specie de importation username: Nómine de usator + username_or_email: Usator-nómine o E-posta whole_word: Plen parol featured_tag: name: Hashtag @@ -193,11 +203,13 @@ ie: custom_css: Custom CSS profile_directory: Possibilisar profilarium registrations_mode: Qui posse registrar se + require_invite_text: Exiger un rason por adherer se show_domain_blocks: Vider bloccas de dominia show_domain_blocks_rationale: Monstrar pro quo cert dominias esset bloccat site_contact_email: Contact e-mail adresse site_contact_username: Usator-nómine de contact site_extended_description: Extendet descrition + site_short_description: Descrition del servitor site_title: Nómine de servitor theme: Predefenit tema trendable_by_default: Possibilisar tendenties sin priori inspection From da7290839aa140e5aa082dc1d57bfa59933178c3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 10:24:43 +0100 Subject: [PATCH 061/422] Update dependency stylelint-config-standard-scss to v13 (#28589) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 82cfd689a5..a5b6a228ca 100644 --- a/package.json +++ b/package.json @@ -202,7 +202,7 @@ "prettier": "^3.0.0", "react-test-renderer": "^18.2.0", "stylelint": "^16.0.2", - "stylelint-config-standard-scss": "^12.0.0", + "stylelint-config-standard-scss": "^13.0.0", "typescript": "^5.0.4", "webpack-dev-server": "^3.11.3", "yargs": "^17.7.2" diff --git a/yarn.lock b/yarn.lock index 99c3eedb26..e1c8ab3fb8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2433,7 +2433,7 @@ __metadata: stacktrace-js: "npm:^2.0.2" stringz: "npm:^2.1.0" stylelint: "npm:^16.0.2" - stylelint-config-standard-scss: "npm:^12.0.0" + stylelint-config-standard-scss: "npm:^13.0.0" substring-trie: "npm:^1.0.2" terser-webpack-plugin: "npm:^4.2.3" tesseract.js: "npm:^2.1.5" @@ -15644,30 +15644,30 @@ __metadata: languageName: node linkType: hard -"stylelint-config-standard-scss@npm:^12.0.0": - version: 12.0.0 - resolution: "stylelint-config-standard-scss@npm:12.0.0" +"stylelint-config-standard-scss@npm:^13.0.0": + version: 13.0.0 + resolution: "stylelint-config-standard-scss@npm:13.0.0" dependencies: stylelint-config-recommended-scss: "npm:^14.0.0" - stylelint-config-standard: "npm:^35.0.0" + stylelint-config-standard: "npm:^36.0.0" peerDependencies: postcss: ^8.3.3 - stylelint: ^16.0.2 + stylelint: ^16.1.0 peerDependenciesMeta: postcss: optional: true - checksum: 7f3ccfb4175f9c50b69d30ca35a97887008c5ba493dbe7d5bce0b57b1eafd21b268177b82404368e7780600077cba784f98e1046671724be3b29a00c6a7913a4 + checksum: 4abf317676184f4aaace6ce72b9fc9e2dffe051d43dd5637afc5803b062ea381e2807ae983c045dff22e96af58388a8b1fe9a8bdda9f97bc3660280cf24fb4d3 languageName: node linkType: hard -"stylelint-config-standard@npm:^35.0.0": - version: 35.0.0 - resolution: "stylelint-config-standard@npm:35.0.0" +"stylelint-config-standard@npm:^36.0.0": + version: 36.0.0 + resolution: "stylelint-config-standard@npm:36.0.0" dependencies: stylelint-config-recommended: "npm:^14.0.0" peerDependencies: - stylelint: ^16.0.0 - checksum: 791fbc26cc3029ce3c2423a643e903545b5e4cd605251b18f0ce790bac6fbaaf380469845c1ff45f4e320126af9f8a9dc1ca85d0df9274277ae60da91e81895b + stylelint: ^16.1.0 + checksum: 1fc9adddfc5cf0a1d7a443182a0731712a3950ace72a24081b4ede2b0bb6fc1eebd003c009f1d8d06c3a64ba9b31b0ed12512db2f91c8fa549238d8341580e4b languageName: node linkType: hard From 419c659bc445fa258550b7e1bf00251663ca6a21 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 4 Jan 2024 15:14:46 +0100 Subject: [PATCH 062/422] Add fallback redirection when getting a webfinger query `WEB_DOMAIN@WEB_DOMAIN` (#28592) --- app/controllers/well_known/webfinger_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/well_known/webfinger_controller.rb b/app/controllers/well_known/webfinger_controller.rb index 364fbf8a18..72f0ea890f 100644 --- a/app/controllers/well_known/webfinger_controller.rb +++ b/app/controllers/well_known/webfinger_controller.rb @@ -21,7 +21,7 @@ module WellKnown username = username_from_resource @account = begin - if username == Rails.configuration.x.local_domain + if username == Rails.configuration.x.local_domain || username == Rails.configuration.x.web_domain Account.representative else Account.find_local!(username) From d0fd14f851871659834ae600f043d81e352cdc1f Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 4 Jan 2024 15:17:38 +0100 Subject: [PATCH 063/422] Fix scrolling to detailed status not always working (#28577) --- .../mastodon/features/status/index.jsx | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index 67a9697311..c581255c99 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -582,16 +582,20 @@ class Status extends ImmutablePureComponent { )); } - setRef = c => { + setContainerRef = c => { this.node = c; }; + setStatusRef = c => { + this.statusNode = c; + }; + _scrollStatusIntoView () { const { status, multiColumn } = this.props; if (status) { - window.requestAnimationFrame(() => { - this.node?.querySelector('.detailed-status__wrapper')?.scrollIntoView(true); + requestIdleCallback(() => { + this.statusNode?.scrollIntoView(true); // In the single-column interface, `scrollIntoView` will put the post behind the header, // so compensate for that. @@ -629,9 +633,8 @@ class Status extends ImmutablePureComponent { } // Scroll to focused post if it is loaded - const child = this.node?.querySelector('.detailed-status__wrapper'); - if (child) { - return [0, child.offsetTop]; + if (this.statusNode) { + return [0, this.statusNode.offsetTop]; } // Do not scroll otherwise, `componentDidUpdate` will take care of that @@ -692,11 +695,11 @@ class Status extends ImmutablePureComponent { /> -
+
{ancestors} -
+
Date: Thu, 4 Jan 2024 11:40:28 -0500 Subject: [PATCH 064/422] Solve remaining `db/*migrate*` cops (#28579) --- .rubocop_todo.yml | 4 - .../20170901141119_truncate_preview_cards.rb | 10 +-- ...024224956_migrate_account_conversations.rb | 2 +- ..._preserve_old_layout_for_existing_users.rb | 2 +- ...04024901_migrate_settings_to_user_roles.rb | 77 ++++++++++++------- 5 files changed, 54 insertions(+), 41 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index bc66bc4add..d68832e85e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -165,7 +165,6 @@ Rails/WhereExists: - 'app/validators/reaction_validator.rb' - 'app/validators/vote_validator.rb' - 'app/workers/move_worker.rb' - - 'db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb' - 'lib/tasks/tests.rake' - 'spec/models/account_spec.rb' - 'spec/services/activitypub/process_collection_service_spec.rb' @@ -253,8 +252,6 @@ Style/GuardClause: - 'app/workers/redownload_media_worker.rb' - 'app/workers/remote_account_refresh_worker.rb' - 'config/initializers/devise.rb' - - 'db/migrate/20170901141119_truncate_preview_cards.rb' - - 'db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb' - 'lib/devise/strategies/two_factor_ldap_authenticatable.rb' - 'lib/devise/strategies/two_factor_pam_authenticatable.rb' - 'lib/mastodon/cli/accounts.rb' @@ -275,7 +272,6 @@ Style/HashAsLastArrayItem: - 'app/models/status.rb' - 'app/services/batched_remove_status_service.rb' - 'app/services/notify_service.rb' - - 'db/migrate/20181024224956_migrate_account_conversations.rb' # This cop supports unsafe autocorrection (--autocorrect-all). Style/HashTransformValues: diff --git a/db/migrate/20170901141119_truncate_preview_cards.rb b/db/migrate/20170901141119_truncate_preview_cards.rb index 22a7731099..b4ba8c45ea 100644 --- a/db/migrate/20170901141119_truncate_preview_cards.rb +++ b/db/migrate/20170901141119_truncate_preview_cards.rb @@ -22,11 +22,9 @@ class TruncatePreviewCards < ActiveRecord::Migration[5.1] end def down - if ActiveRecord::Base.connection.table_exists? 'deprecated_preview_cards' - drop_table :preview_cards - rename_table :deprecated_preview_cards, :preview_cards - else - raise ActiveRecord::IrreversibleMigration, 'Previous preview cards table has already been removed' - end + raise ActiveRecord::IrreversibleMigration, 'Previous preview cards table has already been removed' unless ActiveRecord::Base.connection.table_exists? 'deprecated_preview_cards' + + drop_table :preview_cards + rename_table :deprecated_preview_cards, :preview_cards end end diff --git a/db/migrate/20181024224956_migrate_account_conversations.rb b/db/migrate/20181024224956_migrate_account_conversations.rb index 93ef5da615..d879fd88a2 100644 --- a/db/migrate/20181024224956_migrate_account_conversations.rb +++ b/db/migrate/20181024224956_migrate_account_conversations.rb @@ -105,7 +105,7 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] end end - notifications_about_direct_statuses.includes(:account, mention: { status: [:account, mentions: :account] }).find_each do |notification| + notifications_about_direct_statuses.includes(:account, mention: { status: [:account, { mentions: :account }] }).find_each do |notification| MigrationAccountConversation.add_status(notification.account, notification.target_status) migrated += 1 diff --git a/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb b/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb index 88dcea4360..4597ec5ef4 100644 --- a/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb +++ b/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb @@ -9,7 +9,7 @@ class PreserveOldLayoutForExistingUsers < ActiveRecord::Migration[5.2] # on the to-be-changed default User.where(User.arel_table[:current_sign_in_at].gteq(1.month.ago)).find_each do |user| - next if Setting.unscoped.where(thing_type: 'User', thing_id: user.id, var: 'advanced_layout').exists? + next if Setting.unscoped.exists?(thing_type: 'User', thing_id: user.id, var: 'advanced_layout') user.settings.advanced_layout = true end diff --git a/db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb b/db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb index 254690cc3a..00afee26d0 100644 --- a/db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb +++ b/db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb @@ -6,36 +6,55 @@ class MigrateSettingsToUserRoles < ActiveRecord::Migration[6.1] class UserRole < ApplicationRecord; end def up - owner_role = UserRole.find_by(name: 'Owner') - admin_role = UserRole.find_by(name: 'Admin') - moderator_role = UserRole.find_by(name: 'Moderator') - everyone_role = UserRole.find_by(id: -99) - - min_invite_role = Setting.min_invite_role - show_staff_badge = Setting.show_staff_badge - - if everyone_role - everyone_role.permissions &= ~::UserRole::FLAGS[:invite_users] unless min_invite_role == 'user' - everyone_role.save - end - - if owner_role - owner_role.highlighted = show_staff_badge - owner_role.save - end - - if admin_role - admin_role.permissions |= ::UserRole::FLAGS[:invite_users] if %w(admin moderator).include?(min_invite_role) - admin_role.highlighted = show_staff_badge - admin_role.save - end - - if moderator_role - moderator_role.permissions |= ::UserRole::FLAGS[:invite_users] if %w(moderator).include?(min_invite_role) - moderator_role.highlighted = show_staff_badge - moderator_role.save - end + process_role_everyone + process_role_owner + process_role_admin + process_role_moderator end def down; end + + private + + def process_role_everyone + everyone_role = UserRole.find_by(id: -99) + return unless everyone_role + + everyone_role.permissions &= ~::UserRole::FLAGS[:invite_users] unless min_invite_role == 'user' + everyone_role.save + end + + def process_role_owner + owner_role = UserRole.find_by(name: 'Owner') + return unless owner_role + + owner_role.highlighted = show_staff_badge + owner_role.save + end + + def process_role_admin + admin_role = UserRole.find_by(name: 'Admin') + return unless admin_role + + admin_role.permissions |= ::UserRole::FLAGS[:invite_users] if %w(admin moderator).include?(min_invite_role) + admin_role.highlighted = show_staff_badge + admin_role.save + end + + def process_role_moderator + moderator_role = UserRole.find_by(name: 'Moderator') + return unless moderator_role + + moderator_role.permissions |= ::UserRole::FLAGS[:invite_users] if %w(moderator).include?(min_invite_role) + moderator_role.highlighted = show_staff_badge + moderator_role.save + end + + def min_invite_role + Setting.min_invite_role + end + + def show_staff_badge + Setting.show_staff_badge + end end From 964a0ecf37c46bafba3e33aceacc9f80c78d9779 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 4 Jan 2024 11:55:00 -0500 Subject: [PATCH 065/422] Add sleep statement to nudge thread scheduler in request pool spec (#28596) --- spec/lib/request_pool_spec.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/lib/request_pool_spec.rb b/spec/lib/request_pool_spec.rb index f179e6ca94..bdb0859d76 100644 --- a/spec/lib/request_pool_spec.rb +++ b/spec/lib/request_pool_spec.rb @@ -33,11 +33,13 @@ describe RequestPool do subject - threads = Array.new(20) do |_i| + threads = Array.new(3) do Thread.new do - 20.times do + 2.times do subject.with('http://example.com') do |http_client| http_client.get('/').flush + # Nudge scheduler to yield and exercise the full pool + sleep(0) end end end From 5f4643b895191ecc8ad8136008e0a0b33f88851c Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 5 Jan 2024 11:45:36 +0100 Subject: [PATCH 066/422] Add `PAPERCLIP_ROOT_URL` to Content-Security-Policy when used (#28561) --- app/lib/content_security_policy.rb | 11 ++++++++++- spec/lib/content_security_policy_spec.rb | 12 ++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/lib/content_security_policy.rb b/app/lib/content_security_policy.rb index 966e41f03b..210f37cea0 100644 --- a/app/lib/content_security_policy.rb +++ b/app/lib/content_security_policy.rb @@ -10,7 +10,7 @@ class ContentSecurityPolicy end def media_hosts - [assets_host, cdn_host_value].compact + [assets_host, cdn_host_value, paperclip_root_url].compact end private @@ -23,6 +23,15 @@ class ContentSecurityPolicy s3_alias_host || s3_cloudfront_host || azure_alias_host || s3_hostname_host end + def paperclip_root_url + root_url = ENV.fetch('PAPERCLIP_ROOT_URL', nil) + return if root_url.blank? + + (Addressable::URI.parse(assets_host) + root_url).tap do |uri| + uri.path += '/' unless uri.path.blank? || uri.path.end_with?('/') + end.to_s + end + def url_from_base_host host_to_url(base_host) end diff --git a/spec/lib/content_security_policy_spec.rb b/spec/lib/content_security_policy_spec.rb index 4286f14980..27a3e80257 100644 --- a/spec/lib/content_security_policy_spec.rb +++ b/spec/lib/content_security_policy_spec.rb @@ -125,5 +125,17 @@ describe ContentSecurityPolicy do expect(subject.media_hosts).to contain_exactly(subject.assets_host, 'https://asset-host.s3.example') end end + + context 'when PAPERCLIP_ROOT_URL is configured' do + around do |example| + ClimateControl.modify PAPERCLIP_ROOT_URL: 'https://paperclip-host.example' do + example.run + end + end + + it 'uses the provided URL in the content security policy' do + expect(subject.media_hosts).to contain_exactly(subject.assets_host, 'https://paperclip-host.example') + end + end end end From 9ecf99df149eb75f27562ab8ee8f4022b57604dc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 11:45:55 +0100 Subject: [PATCH 067/422] Update dependency net-http to v0.4.1 (#28606) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index c3f27966d6..d1dfd6e86a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -467,7 +467,7 @@ GEM multi_json (1.15.0) multipart-post (2.3.0) mutex_m (0.2.0) - net-http (0.4.0) + net-http (0.4.1) uri net-http-persistent (4.0.2) connection_pool (~> 2.2) From 6b63652656f9b1af5b8d1838591c071c5e19880f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 11:46:32 +0100 Subject: [PATCH 068/422] Update dependency rubocop-rspec to v2.26.0 (#28595) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index d1dfd6e86a..009293167f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -678,7 +678,7 @@ GEM parser (>= 3.2.1.0) rubocop-capybara (2.20.0) rubocop (~> 1.41) - rubocop-factory_bot (2.24.0) + rubocop-factory_bot (2.25.0) rubocop (~> 1.33) rubocop-performance (1.20.1) rubocop (>= 1.48.1, < 2.0) @@ -688,7 +688,7 @@ GEM rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rspec (2.25.0) + rubocop-rspec (2.26.0) rubocop (~> 1.40) rubocop-capybara (~> 2.17) rubocop-factory_bot (~> 2.22) From d537b3926fda5693d4f08a6ea30684479f5e7668 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 11:46:38 +0100 Subject: [PATCH 069/422] Update dependency sass-loader to v10.5.2 (#28594) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e1c8ab3fb8..8849124e18 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14550,8 +14550,8 @@ __metadata: linkType: hard "sass-loader@npm:^10.2.0": - version: 10.5.1 - resolution: "sass-loader@npm:10.5.1" + version: 10.5.2 + resolution: "sass-loader@npm:10.5.2" dependencies: klona: "npm:^2.0.4" loader-utils: "npm:^2.0.0" @@ -14570,7 +14570,7 @@ __metadata: optional: true sass: optional: true - checksum: 841448d02045b0c65595eab4cb701384b01a2adcb3594beacbb767b0cee5bd9d444027f4fc3a10acef3fe1c7eb6510fccffdee72a20e9877777789a5e349cb49 + checksum: 5ba4a83459fbb50e21d4f4b1b59baf1ddf8dd404099b6d1f2ec887c6903659e505879915030dd9efb1c6dd5fde2d515a19f418487b73d1cc59f6aad60c79bcf5 languageName: node linkType: hard From 9699ea22d6be08d5809c0a05500e6778f96a09a2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 11:47:22 +0100 Subject: [PATCH 070/422] Update dependency postcss to v8.4.33 (#28602) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 8849124e18..70d98332ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13145,13 +13145,13 @@ __metadata: linkType: hard "postcss@npm:^8.2.15, postcss@npm:^8.4.24, postcss@npm:^8.4.32": - version: 8.4.32 - resolution: "postcss@npm:8.4.32" + version: 8.4.33 + resolution: "postcss@npm:8.4.33" dependencies: nanoid: "npm:^3.3.7" picocolors: "npm:^1.0.0" source-map-js: "npm:^1.0.2" - checksum: 39308a9195fa34d4dbdd7b58a896cff0c7809f84f7a4ac1b95b68ca86c9138a395addff33075668ed3983d41b90aac05754c445237a9365eb1c3a5602ebd03ad + checksum: 16eda83458fcd8a91bece287b5920c7f57164c3ea293e6c80d0ea71ce7843007bcd8592260a5160b9a7f02693e6ac93e2495b02d8c7596d3f3f72c1447e3ba79 languageName: node linkType: hard From 6ad0fb5a77dcdb12d3bf61617978dcd6e6f6fb20 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 5 Jan 2024 12:07:57 +0100 Subject: [PATCH 071/422] Fix NULL MX handling and tighten DNS resolving specs (#28607) --- app/validators/email_mx_validator.rb | 1 + .../admin/email_domain_blocks_controller_spec.rb | 10 ++++++++++ spec/rails_helper.rb | 4 ++++ spec/validators/email_mx_validator_spec.rb | 2 +- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/validators/email_mx_validator.rb b/app/validators/email_mx_validator.rb index a30a0c820d..7943778943 100644 --- a/app/validators/email_mx_validator.rb +++ b/app/validators/email_mx_validator.rb @@ -47,6 +47,7 @@ class EmailMxValidator < ActiveModel::Validator dns.timeouts = 5 records = dns.getresources(domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s } + next if records == [''] # This domain explicitly rejects emails ([domain] + records).uniq.each do |hostname| ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.address.to_s }) diff --git a/spec/controllers/admin/email_domain_blocks_controller_spec.rb b/spec/controllers/admin/email_domain_blocks_controller_spec.rb index 9379fe374a..4de3ef0f62 100644 --- a/spec/controllers/admin/email_domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/email_domain_blocks_controller_spec.rb @@ -35,6 +35,16 @@ RSpec.describe Admin::EmailDomainBlocksController do describe 'POST #create' do context 'when resolve button is pressed' do before do + resolver = instance_double(Resolv::DNS) + + allow(resolver).to receive(:getresources) + .with('example.com', Resolv::DNS::Resource::IN::MX) + .and_return([]) + allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([]) + allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([]) + allow(resolver).to receive(:timeouts=).and_return(nil) + allow(Resolv::DNS).to receive(:open).and_yield(resolver) + post :create, params: { email_domain_block: { domain: 'example.com' } } end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index c9352a4d5d..e5d432b45f 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -128,6 +128,10 @@ RSpec.configure do |config| self.use_transactional_tests = true end + config.before do |example| + allow(Resolv::DNS).to receive(:open).and_raise('Real DNS queries are disabled, stub Resolv::DNS as needed') unless example.metadata[:type] == :system + end + config.before do |example| unless example.metadata[:paperclip_processing] allow_any_instance_of(Paperclip::Attachment).to receive(:post_process).and_return(true) # rubocop:disable RSpec/AnyInstance diff --git a/spec/validators/email_mx_validator_spec.rb b/spec/validators/email_mx_validator_spec.rb index 876d73c184..21b1ad0a11 100644 --- a/spec/validators/email_mx_validator_spec.rb +++ b/spec/validators/email_mx_validator_spec.rb @@ -111,7 +111,7 @@ describe EmailMxValidator do allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([]) allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([]) allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([instance_double(Resolv::DNS::Resource::IN::A, address: '2.3.4.5')]) - allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([instance_double(Resolv::DNS::Resource::IN::A, address: 'fd00::2')]) + allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([instance_double(Resolv::DNS::Resource::IN::AAAA, address: 'fd00::2')]) allow(resolver).to receive(:timeouts=).and_return(nil) allow(Resolv::DNS).to receive(:open).and_yield(resolver) From 43d800ada64478e3a9119ca9313b47018b811243 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 12:29:19 +0100 Subject: [PATCH 072/422] New Crowdin Translations (automated) (#28604) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/el.json | 11 +++++ app/javascript/mastodon/locales/ia.json | 16 +++++++ app/javascript/mastodon/locales/sq.json | 2 + app/javascript/mastodon/locales/zh-CN.json | 6 +-- config/locales/activerecord.ia.yml | 1 + config/locales/activerecord.ie.yml | 2 + config/locales/be.yml | 1 + config/locales/ca.yml | 1 + config/locales/cy.yml | 1 + config/locales/da.yml | 1 + config/locales/devise.el.yml | 2 +- config/locales/devise.ia.yml | 24 ++++++++++ config/locales/devise.ie.yml | 5 ++ config/locales/doorkeeper.el.yml | 10 ++-- config/locales/doorkeeper.ia.yml | 54 ++++++++++++++++++++++ config/locales/doorkeeper.ie.yml | 9 ++++ config/locales/el.yml | 9 +++- config/locales/es-AR.yml | 1 + config/locales/es-MX.yml | 1 + config/locales/es.yml | 1 + config/locales/eu.yml | 1 + config/locales/fo.yml | 1 + config/locales/fy.yml | 1 + config/locales/gl.yml | 1 + config/locales/he.yml | 1 + config/locales/hu.yml | 1 + config/locales/ia.yml | 23 +++++++++ config/locales/ie.yml | 26 +++++++++++ config/locales/it.yml | 1 + config/locales/ko.yml | 1 + config/locales/lt.yml | 1 + config/locales/nl.yml | 1 + config/locales/nn.yml | 1 + config/locales/no.yml | 1 + config/locales/pl.yml | 1 + config/locales/pt-BR.yml | 1 + config/locales/pt-PT.yml | 1 + config/locales/simple_form.ia.yml | 45 ++++++++++++++++++ config/locales/simple_form.ie.yml | 39 ++++++++++++++++ config/locales/simple_form.sk.yml | 2 + config/locales/sk.yml | 1 + config/locales/sl.yml | 1 + config/locales/sq.yml | 1 + config/locales/sr-Latn.yml | 1 + config/locales/sr.yml | 1 + config/locales/th.yml | 1 + config/locales/tr.yml | 1 + config/locales/uk.yml | 1 + config/locales/vi.yml | 1 + config/locales/zh-CN.yml | 1 + config/locales/zh-HK.yml | 1 + 51 files changed, 309 insertions(+), 10 deletions(-) diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 17a0c9d4da..53e55fa950 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -260,6 +260,9 @@ "filter_modal.select_filter.subtitle": "Χρησιμοποιήστε μια υπάρχουσα κατηγορία ή δημιουργήστε μια νέα", "filter_modal.select_filter.title": "Φιλτράρισμα αυτής της ανάρτησης", "filter_modal.title.status": "Φιλτράρισμα μιας ανάρτησης", + "firehose.all": "Όλα", + "firehose.local": "Αυτός ο διακομιστής", + "firehose.remote": "Άλλοι διακομιστές", "follow_request.authorize": "Εξουσιοδότησε", "follow_request.reject": "Απέρριψε", "follow_requests.unlocked_explanation": "Παρόλο που ο λογαριασμός σου δεν είναι κλειδωμένος, το προσωπικό του {domain} θεώρησαν πως ίσως να θέλεις να ελέγξεις χειροκίνητα αυτά τα αιτήματα ακολούθησης.", @@ -285,11 +288,15 @@ "hashtag.column_settings.tag_toggle": "Προσθήκη επιπλέον ταμπελών για την κολώνα", "hashtag.follow": "Παρακολούθηση ετικέτας", "hashtag.unfollow": "Διακοπή παρακολούθησης ετικέτας", + "home.actions.go_to_suggestions": "Βρείτε άτομα για να ακολουθήσετε", "home.column_settings.basic": "Βασικές ρυθμίσεις", "home.column_settings.show_reblogs": "Εμφάνιση προωθήσεων", "home.column_settings.show_replies": "Εμφάνιση απαντήσεων", "home.explore_prompt.body": "Your home feed will have a mix of posts from the hashtags you've chosen to follow, the people you've chosen to follow, and the posts they boost. If that feels too quiet, you may want to:\nΗ τροφοδοσία της αρχικής σελίδας σας είναι ένα μίγμα από αναρτήσεις με τις ετικέτες και τα άτομα που επιλέξατε να ακολουθείτε, και τις αναρτήσεις που προωθούν. Εάν αυτό σας φαίνεται πολύ ήσυχο, μπορεί να θέλετε:", + "home.explore_prompt.title": "Αυτό είναι το σπίτι σας στο Mastodon.", "home.hide_announcements": "Απόκρυψη ανακοινώσεων", + "home.pending_critical_update.link": "Δείτε ενημερώσεις", + "home.pending_critical_update.title": "Κρίσιμη ενημέρωση ασφαλείας διαθέσιμη!", "home.show_announcements": "Εμφάνιση ανακοινώσεων", "interaction_modal.description.follow": "Με έναν λογαριασμό Mastodon, μπορείς να ακολουθήσεις τον/την {name} ώστε να λαμβάνεις τις αναρτήσεις του/της στη δική σου ροή.", "interaction_modal.description.reblog": "Με ένα λογαριασμό Mastodon, μπορείς να ενισχύσεις αυτή την ανάρτηση για να τη μοιραστείς με τους δικούς σου ακολούθους.", @@ -314,6 +321,7 @@ "keyboard_shortcuts.direct": "για το άνοιγμα της στήλης ιδιωτικών επισημάνσεων", "keyboard_shortcuts.down": "κίνηση προς τα κάτω στη λίστα", "keyboard_shortcuts.enter": "Εμφάνιση ανάρτησης", + "keyboard_shortcuts.favourite": "Αγαπημένη δημοσίευση", "keyboard_shortcuts.federated": "Άνοιγμα ροής συναλλαγών", "keyboard_shortcuts.heading": "Συντομεύσεις πληκτρολογίου", "keyboard_shortcuts.home": "Άνοιγμα ροής αρχικής σελίδας", @@ -358,6 +366,7 @@ "lists.search": "Αναζήτησε μεταξύ των ανθρώπων που ακουλουθείς", "lists.subheading": "Οι λίστες σου", "load_pending": "{count, plural, one {# νέο στοιχείο} other {# νέα στοιχεία}}", + "loading_indicator.label": "Φόρτωση…", "media_gallery.toggle_visible": "{number, plural, one {Απόκρυψη εικόνας} other {Απόκρυψη εικόνων}}", "moved_to_account_banner.text": "Ο λογαριασμός σου {disabledAccount} είναι προσωρινά απενεργοποιημένος επειδή μεταφέρθηκες στον {movedToAccount}.", "mute_modal.duration": "Διάρκεια", @@ -380,6 +389,7 @@ "navigation_bar.lists": "Λίστες", "navigation_bar.logout": "Αποσύνδεση", "navigation_bar.mutes": "Αποσιωπημένοι χρήστες", + "navigation_bar.opened_in_classic_interface": "Δημοσιεύσεις, λογαριασμοί και άλλες συγκεκριμένες σελίδες ανοίγονται από προεπιλογή στην κλασική διεπαφή ιστού.", "navigation_bar.personal": "Προσωπικά", "navigation_bar.pins": "Καρφιτσωμένες αναρτήσεις", "navigation_bar.preferences": "Προτιμήσεις", @@ -403,6 +413,7 @@ "notifications.column_settings.admin.report": "Νέες αναφορές:", "notifications.column_settings.admin.sign_up": "Νέες εγγραφές:", "notifications.column_settings.alert": "Ειδοποιήσεις επιφάνειας εργασίας", + "notifications.column_settings.favourite": "Αγαπημένα:", "notifications.column_settings.filter_bar.advanced": "Εμφάνιση όλων των κατηγοριών", "notifications.column_settings.filter_bar.category": "Μπάρα γρήγορου φίλτρου", "notifications.column_settings.filter_bar.show_bar": "Εμφάνιση μπάρας φίλτρου", diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index 9781d6aa77..00cafe260b 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -1,4 +1,8 @@ { + "about.blocks": "Servitores moderate", + "about.contact": "Contacto:", + "about.disclaimer": "Mastodon es software libere, de codice aperte, e un marca de Mastodon gGmbH.", + "account.account_note_header": "Nota", "account.add_or_remove_from_list": "Adder o remover ab listas", "account.badges.group": "Gruppo", "account.block": "Blocar @{name}", @@ -21,9 +25,12 @@ "bundle_column_error.return": "Retornar al initio", "bundle_modal_error.close": "Clauder", "bundle_modal_error.retry": "Tentar novemente", + "column.about": "A proposito de", "column.blocks": "Usatores blocate", + "column.bookmarks": "Marcapaginas", "column.directory": "Navigar profilos", "column.favourites": "Favoritos", + "column.firehose": "Fluxos in directe", "column.home": "Initio", "column.lists": "Listas", "column.notifications": "Notificationes", @@ -33,6 +40,7 @@ "compose.language.change": "Cambiar le lingua", "compose.language.search": "Cercar linguas...", "compose.published.open": "Aperir", + "compose_form.direct_message_warning_learn_more": "Apprender plus", "compose_form.poll.add_option": "Adder un option", "compose_form.poll.remove_option": "Remover iste option", "confirmation_modal.cancel": "Cancellar", @@ -41,6 +49,7 @@ "confirmations.edit.confirm": "Modificar", "confirmations.logout.confirm": "Clauder le session", "copy_icon_button.copied": "Copiate al area de transferentia", + "copypaste.copied": "Copiate", "copypaste.copy_to_clipboard": "Copiar al area de transferentia", "disabled_account_banner.account_settings": "Parametros de conto", "dismissable_banner.dismiss": "Dimitter", @@ -52,6 +61,7 @@ "errors.unexpected_crash.report_issue": "Signalar un defecto", "explore.search_results": "Resultatos de recerca", "explore.trending_links": "Novas", + "filter_modal.select_filter.prompt_new": "Nove categoria: {name}", "firehose.all": "Toto", "firehose.local": "Iste servitor", "firehose.remote": "Altere servitores", @@ -64,8 +74,13 @@ "keyboard_shortcuts.my_profile": "Aperir tu profilo", "lightbox.close": "Clauder", "lightbox.next": "Sequente", + "lightbox.previous": "Precedente", "link_preview.author": "Per {name}", "lists.account.add": "Adder al lista", + "lists.delete": "Deler lista", + "lists.edit": "Modificar lista", + "lists.new.create": "Adder lista", + "lists.subheading": "Tu listas", "mute_modal.duration": "Duration", "mute_modal.hide_notifications": "Celar notificationes de iste usator?", "navigation_bar.about": "A proposito de", @@ -83,6 +98,7 @@ "notifications.column_settings.filter_bar.advanced": "Monstrar tote le categorias", "notifications.column_settings.sound": "Reproducer sono", "notifications.filter.all": "Toto", + "notifications.filter.favourites": "Favoritos", "notifications.grant_permission": "Conceder permission.", "notifications.group": "{count} notificationes", "onboarding.compose.template": "Salute #Mastodon!", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 48eac1487e..f45266c845 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "Pa postime", "account.featured_tags.title": "Hashtagë të zgjedhur të {name}", "account.follow": "Ndiqeni", + "account.follow_back": "Ndiqe gjithashtu", "account.followers": "Ndjekës", "account.followers.empty": "Këtë përdorues ende s’e ndjek kush.", "account.followers_counter": "{count, plural, one {{counter} Ndjekës} other {{counter} Ndjekës}}", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "Mos shfaq njoftime", "account.mute_short": "Mos i shfaq", "account.muted": "Heshtuar", + "account.mutual": "Reciproke", "account.no_bio": "S’u dha përshkrim.", "account.open_original_page": "Hap faqen origjinale", "account.posts": "Mesazhe", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 575e0c7aeb..720e4331b3 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -53,7 +53,7 @@ "account.mute_notifications_short": "关闭通知", "account.mute_short": "隐藏", "account.muted": "已隐藏", - "account.mutual": "互相关注", + "account.mutual": "互粉好友", "account.no_bio": "未提供描述。", "account.open_original_page": "打开原始页面", "account.posts": "嘟文", @@ -446,7 +446,7 @@ "notifications.column_settings.filter_bar.advanced": "显示所有类别", "notifications.column_settings.filter_bar.category": "快速过滤栏", "notifications.column_settings.filter_bar.show_bar": "显示过滤栏", - "notifications.column_settings.follow": "新关注者:", + "notifications.column_settings.follow": "新粉丝:", "notifications.column_settings.follow_request": "新关注请求:", "notifications.column_settings.mention": "提及:", "notifications.column_settings.poll": "投票结果:", @@ -700,7 +700,7 @@ "time_remaining.moments": "即将结束", "time_remaining.seconds": "剩余 {number, plural, one {# 秒} other {# 秒}}", "timeline_hint.remote_resource_not_displayed": "不会显示来自其它服务器的{resource}", - "timeline_hint.resources.followers": "关注者", + "timeline_hint.resources.followers": "粉丝", "timeline_hint.resources.follows": "关注", "timeline_hint.resources.statuses": "更早的嘟文", "trends.counter_by_accounts": "过去 {days, plural, other {{days} 天}}有{count, plural, other { {counter} 人}}讨论", diff --git a/config/locales/activerecord.ia.yml b/config/locales/activerecord.ia.yml index 480fd56f63..7d1e7d7190 100644 --- a/config/locales/activerecord.ia.yml +++ b/config/locales/activerecord.ia.yml @@ -3,6 +3,7 @@ ia: activerecord: attributes: user: + email: Adresse de e-mail password: Contrasigno user/account: username: Nomine de usator diff --git a/config/locales/activerecord.ie.yml b/config/locales/activerecord.ie.yml index 588105ae96..0b22dd886c 100644 --- a/config/locales/activerecord.ie.yml +++ b/config/locales/activerecord.ie.yml @@ -19,6 +19,7 @@ ie: account: attributes: username: + invalid: deve contener solmen lítteres, númeres e sublineas reserved: es reservat admin/webhook: attributes: @@ -39,6 +40,7 @@ ie: user: attributes: email: + blocked: usa un ne-permisset provisor de e-posta unreachable: sembla ne exister role_id: elevated: ne posse esser plu alt quam tui actual rol diff --git a/config/locales/be.yml b/config/locales/be.yml index d8703b7992..ca9b0d2b88 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -439,6 +439,7 @@ be: view: Праглядзець новы блок дамену email_domain_blocks: add_new: Дадаць + allow_registrations_with_approval: Дазволіць рэгістрацыю з дазволам attempts_over_week: few: "%{count} спробы рэгіістрацыі за апошні тыдзень" many: "%{count} спроб рэгіістрацыі за апошні тыдзень" diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 0d7605f023..25f19ef25f 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -425,6 +425,7 @@ ca: view: Veure el bloqueig del domini email_domain_blocks: add_new: Afegir nou + allow_registrations_with_approval: Registre permès amb validació attempts_over_week: one: "%{count} intent en la darrera setmana" other: "%{count} intents de registre en la darrera setmana" diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 9dd533b2ad..70b994903e 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -453,6 +453,7 @@ cy: view: Gweld bloc parth email_domain_blocks: add_new: Ychwanegu + allow_registrations_with_approval: Caniatáu cofrestriadau wedi'u cymeradwyo attempts_over_week: few: "%{count} ymgais i gofrestru dros yr wythnos ddiwethaf" many: "%{count} ymgais i gofrestru dros yr wythnos ddiwethaf" diff --git a/config/locales/da.yml b/config/locales/da.yml index 6403ac1ccb..3d6850ca5e 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -425,6 +425,7 @@ da: view: Vis domæneblokering email_domain_blocks: add_new: Tilføj ny + allow_registrations_with_approval: Tillad registreringer med godkendelse attempts_over_week: one: "%{count} tilmeldingsforsøg over den seneste uge" other: "%{count} tilmeldingsforsøg over den seneste uge" diff --git a/config/locales/devise.el.yml b/config/locales/devise.el.yml index ba3ee59fab..13daa4b97a 100644 --- a/config/locales/devise.el.yml +++ b/config/locales/devise.el.yml @@ -34,7 +34,7 @@ el: explanation: Το συνθηματικό του λογαριασμού σου άλλαξε. extra: Αν δεν άλλαξες εσύ το συνθηματικό σου, ίσως κάποιος να έχει αποκτήσει πρόσβαση στο λογαριασμό σου. Παρακαλούμε άλλαξε το συνθηματικό σου άμεσα ή επικοινώνησε με τον διαχειριστή του κόμβου σου αν έχεις κλειδωθεί απ' έξω. subject: 'Mastodon: Αλλαγή συνθηματικού' - title: Αλλαγή συνθηματικού + title: Ο κωδικός άλλαξε reconfirmation_instructions: explanation: Επιβεβαίωσε τη νέα διεύθυνση για να αλλάξεις το email σου. extra: Αν δεν ζήτησες εσύ αυτή την αλλαγή, παρακαλούμε αγνόησε αυτό το email. Η διεύθυνση email για τον λογαριασμό σου στο Mastodon δεν θα αλλάξει μέχρι να επισκεφτείς τον παραπάνω σύνδεσμο. diff --git a/config/locales/devise.ia.yml b/config/locales/devise.ia.yml index 6ab26788bd..7b0ec29579 100644 --- a/config/locales/devise.ia.yml +++ b/config/locales/devise.ia.yml @@ -1 +1,25 @@ +--- ia: + devise: + mailer: + confirmation_instructions: + action: Verificar adresse de e-mail + action_with_app: Confirmar e retornar a %{app} + title: Verificar adresse de e-mail + email_changed: + title: Nove adresse de e-mail + reconfirmation_instructions: + title: Verificar adresse de e-mail + reset_password_instructions: + action: Cambiar contrasigno + title: Reinitialisar contrasigno + two_factor_disabled: + title: 2FA disactivate + registrations: + updated: Tu conto ha essite actualisate con successo. + unlocks: + unlocked: Tu conto ha essite disblocate con successo. Initia session a continuar. + errors: + messages: + already_confirmed: jam esseva confirmate, tenta initiar session + not_found: non trovate diff --git a/config/locales/devise.ie.yml b/config/locales/devise.ie.yml index 687e7115a6..c6468d34c2 100644 --- a/config/locales/devise.ie.yml +++ b/config/locales/devise.ie.yml @@ -56,6 +56,8 @@ ie: added: subject: 'Mastodon: Nov clave de securitá' title: Un nov clave de securitá ha esset adjuntet + deleted: + subject: 'Mastodon: Clave de securitá deletet' webauthn_disabled: subject: 'Mastodon: Autentication con claves de securitá desactivisat' title: Claves de securitá desactivisat @@ -84,3 +86,6 @@ ie: expired: ha expirat, ples demandar un nov not_found: ne trovat not_locked: ne esset serrat + not_saved: + one: '1 error prohibit ti %{resource} de esser conservat:' + other: "%{count} errores prohibit ti %{resource} de esser conservat:" diff --git a/config/locales/doorkeeper.el.yml b/config/locales/doorkeeper.el.yml index b275af3365..1cb9b3513b 100644 --- a/config/locales/doorkeeper.el.yml +++ b/config/locales/doorkeeper.el.yml @@ -127,6 +127,7 @@ el: bookmarks: Σελιδοδείκτες conversations: Συνομιλίες crypto: Κρυπτογράφηση από άκρο σε άκρο + favourites: Αγαπημένα filters: Φίλτρα follow: Ακολουθείτε, σε Σίγαση και Αποκλεισμοί follows: Ακολουθείτε @@ -169,9 +170,10 @@ el: read:accounts: να βλέπει τα στοιχεία λογαριασμών read:blocks: να βλέπει τους αποκλεισμένους σου read:bookmarks: εμφάνιση των σελιδοδεικτών σας + read:favourites: δείτε τα αγαπημένα σας read:filters: να βλέπει τα φίλτρα σου - read:follows: να βλέπει ποιους ακολουθείς - read:lists: να βλέπει τις λίστες σου + read:follows: δές ποιους ακολουθείς + read:lists: δές τις λίστες σου read:mutes: να βλέπει ποιους αποσιωπείς read:notifications: να βλέπει τις ειδοποιήσεις σου read:reports: να βλέπει τις καταγγελίες σου @@ -183,8 +185,8 @@ el: write:bookmarks: προσθήκη σελιδοδεικτών write:conversations: σίγαση και διαγραφή συνομιλιών write:filters: να δημιουργεί φίλτρα - write:follows: να ακολουθεί ανθρώπους - write:lists: να δημιουργεί λίστες + write:follows: ακολουθήστε ανθρώπους + write:lists: δημιουργία λιστών write:media: να ανεβάζει πολυμέσα write:mutes: να αποσιωπεί ανθρώπους και συζητήσεις write:notifications: να καθαρίζει τις ειδοποιήσεις σου diff --git a/config/locales/doorkeeper.ia.yml b/config/locales/doorkeeper.ia.yml index 6ab26788bd..55f28634a5 100644 --- a/config/locales/doorkeeper.ia.yml +++ b/config/locales/doorkeeper.ia.yml @@ -1 +1,55 @@ +--- ia: + activerecord: + attributes: + doorkeeper/application: + name: Nomine de application + website: Sito web de application + doorkeeper: + applications: + buttons: + cancel: Cancellar + edit: Modificar + edit: + title: Modificar application + index: + application: Application + delete: Deler + name: Nomine + new: Nove application + show: Monstrar + title: Tu applicationes + new: + title: Nove application + show: + actions: Actiones + title: 'Application: %{name}' + authorizations: + error: + title: Ocurreva un error + authorized_applications: + confirmations: + revoke: Es tu secur? + index: + scopes: Permissiones + title: Tu applicationes autorisate + flash: + applications: + create: + notice: Application create. + destroy: + notice: Application delite. + update: + notice: Application actualisate. + grouped_scopes: + title: + accounts: Contos + admin/accounts: Gestion de contos + favourites: Favoritos + lists: Listas + notifications: Notificationes + push: Notificationes push + layouts: + admin: + nav: + applications: Applicationes diff --git a/config/locales/doorkeeper.ie.yml b/config/locales/doorkeeper.ie.yml index b778871e3a..f49eb1d968 100644 --- a/config/locales/doorkeeper.ie.yml +++ b/config/locales/doorkeeper.ie.yml @@ -5,6 +5,7 @@ ie: doorkeeper/application: name: Nómine de aplication redirect_uri: URI de redirection + scopes: Scopes website: Situ web de aplication errors: models: @@ -29,6 +30,7 @@ ie: title: Modificar aplication help: redirect_uri: Usar un linea per URI + scopes: Separar scopes con intersticies. Lassar blanc por usar li scopes predefinit. index: application: Aplication callback_url: URL de retrovocada @@ -36,6 +38,7 @@ ie: empty: Tu have null aplicationes. name: Nómine new: Nov aplication + scopes: Scopes show: Monstrar title: Tui aplicationes new: @@ -44,6 +47,7 @@ ie: actions: Actiones application_id: Clave de client callback_urls: URLs de retrovocada + scopes: Scopes secret: Secrete de client title: 'Aplication: %{name}' authorizations: @@ -120,9 +124,13 @@ ie: admin: nav: applications: Aplicationes + oauth2_provider: Provisor OAuth2 + application: + title: Autorisation OAuth besonat scopes: admin:read: leer li tot data sur li servitor admin:read:accounts: leer sensitiv information de omni contos + admin:read:canonical_email_blocks: leer sensitiv information pri omni canonic bloccas de e-posta admin:read:domain_allows: leer sensitiv information pri omni permisses de dominia admin:read:domain_blocks: leer sensitiv information pri omni bloccas de dominia admin:read:email_domain_blocks: leer sensitiv information pri omni bloccas de dominia basat sur e-posta @@ -137,6 +145,7 @@ ie: admin:write:ip_blocks: fa moderatori actiones sur bloccas de IP admin:write:reports: far moderatori actiones sur raportes follow: modifica li relationes del conto + push: reciver tui pussa-notificationes read: lee omni datas de tui conto read:accounts: vide li informationes pri li conto read:blocks: vider tui bloccas diff --git a/config/locales/el.yml b/config/locales/el.yml index 4c58bfda0a..4c31bfdde0 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -962,6 +962,7 @@ el: notification_preferences: Αλλαγή προτιμήσεων email salutation: "%{name}," settings: 'Άλλαξε τις προτιμήσεις email: %{link}' + unsubscribe: Κατάργηση εγγραφής view: 'Προβολή:' view_profile: Προβολή προφίλ view_status: Προβολή ανάρτησης @@ -975,6 +976,8 @@ el: your_token: Το διακριτικό πρόσβασής σου auth: apply_for_account: Ζήτα έναν λογαριασμό + captcha_confirmation: + title: Ελεγχος ασφαλείας confirmations: wrong_email_hint: Εάν αυτή η διεύθυνση email δεν είναι σωστή, μπορείς να την αλλάξεις στις ρυθμίσεις λογαριασμού. delete_account: Διαγραφή λογαριασμού @@ -1238,6 +1241,8 @@ el: status: Κατάσταση success: Τα δεδομένα σου μεταφορτώθηκαν επιτυχώς και θα επεξεργαστούν σύντομα time_started: Ξεκίνησε στις + titles: + following: Εισαγωγή λογαριασμών που ακολουθείτε type: Τύπος εισαγωγής type_groups: destructive: Μπλοκ & σίγαση @@ -1245,7 +1250,7 @@ el: blocking: Λίστα αποκλεισμού bookmarks: Σελιδοδείκτες domain_blocking: Λίστα αποκλεισμένων τομέων - following: Λίστα ακολούθων + following: Λίστα ατόμων που ακολουθείτε muting: Λίστα αποσιωπήσεων upload: Μεταμόρφωση invites: @@ -1420,7 +1425,7 @@ el: follow_failure: Δεν ήταν δυνατή η παρακολούθηση ορισμένων από τους επιλεγμένους λογαριασμούς. follow_selected_followers: Ακολούθησε τους επιλεγμένους ακόλουθους followers: Ακόλουθοι - following: Ακολουθείς + following: Ακολουθείτε invited: Προσκεκλημένοι last_active: Τελευταία ενεργός most_recent: Πιο πρόσφατος diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 0000c297ad..f214c92d2a 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -425,6 +425,7 @@ es-AR: view: Ver bloqueo de dominio email_domain_blocks: add_new: Agregar nuevo + allow_registrations_with_approval: Permitir crear cuentas con aprobación attempts_over_week: one: "%{count} intento durante la última semana" other: "%{count} intentos durante la última semana" diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 424262ca19..7f5b282873 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -425,6 +425,7 @@ es-MX: view: Ver dominio bloqueado email_domain_blocks: add_new: Añadir nuevo + allow_registrations_with_approval: Permitir registros con aprobación attempts_over_week: one: "%{count} intentos durante la última semana" other: "%{count} intentos de registro en la última semana" diff --git a/config/locales/es.yml b/config/locales/es.yml index f4a70e5e57..a1e9401f5a 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -425,6 +425,7 @@ es: view: Ver dominio bloqueado email_domain_blocks: add_new: Añadir nuevo + allow_registrations_with_approval: Permitir registros con aprobación attempts_over_week: one: "%{count} intento durante la última semana" other: "%{count} intentos de registro durante la última semana" diff --git a/config/locales/eu.yml b/config/locales/eu.yml index bcf8540e74..0d253e9b3b 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -427,6 +427,7 @@ eu: view: Ikusi domeinuaren blokeoa email_domain_blocks: add_new: Gehitu berria + allow_registrations_with_approval: Baimendu izen-emateak onarpen bidez attempts_over_week: one: Izen-emateko saiakera %{count} azken astean other: Izen-emateko %{count} saiakera azken astean diff --git a/config/locales/fo.yml b/config/locales/fo.yml index 726c9607e2..00fb9c5560 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -425,6 +425,7 @@ fo: view: Vís navnaøkisblokering email_domain_blocks: add_new: Stovna + allow_registrations_with_approval: Loyv skrásetingum við góðkenning attempts_over_week: one: "%{count} roynd seinastu vikuna" other: "%{count} tilmeldingarroyndir seinastu vikuna" diff --git a/config/locales/fy.yml b/config/locales/fy.yml index a08b3a401e..9471c03b92 100644 --- a/config/locales/fy.yml +++ b/config/locales/fy.yml @@ -425,6 +425,7 @@ fy: view: Domeinblokkade besjen email_domain_blocks: add_new: Nije tafoegje + allow_registrations_with_approval: Ynskriuwingen mei tastimming tastean attempts_over_week: one: "%{count} registraasjebesykjen yn de ôfrûne wike" other: "%{count} registraasjebesykjen yn de ôfrûne wike" diff --git a/config/locales/gl.yml b/config/locales/gl.yml index c0e76842f7..cff9427c66 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -425,6 +425,7 @@ gl: view: Ollar dominios bloqueados email_domain_blocks: add_new: Engadir novo + allow_registrations_with_approval: Permitir crear contas con aprobación attempts_over_week: one: "%{count} intento na última semana" other: "%{count} intentos de conexión na última semana" diff --git a/config/locales/he.yml b/config/locales/he.yml index f2cc882141..23a4e0c3a6 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -439,6 +439,7 @@ he: view: צפייה בחסימת דומיינים email_domain_blocks: add_new: הוספת חדש + allow_registrations_with_approval: הרשאת הרשמה לאחר אישור attempts_over_week: many: "%{count} נסיונות הרשמה במשך השבוע שעבר" one: "%{count} נסיון במשך השבוע שעבר" diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 5da1a4e066..5c8d1cf9a4 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -425,6 +425,7 @@ hu: view: Domain tiltásának megtekintése email_domain_blocks: add_new: Új hozzáadása + allow_registrations_with_approval: Regisztráció engedélyezése jóváhagyással attempts_over_week: one: "%{count} próbálkozás a múlt héten" other: "%{count} próbálkozás feliratkozásra a múlt héten" diff --git a/config/locales/ia.yml b/config/locales/ia.yml index 64315d177f..795ed8cc94 100644 --- a/config/locales/ia.yml +++ b/config/locales/ia.yml @@ -50,3 +50,26 @@ ia: '15778476': 6 menses '2629746': 1 mense '86400': 1 die + statuses_cleanup: + min_age: + '1209600': 2 septimanas + '15778476': 6 menses + '2629746': 1 mense + '31556952': 1 anno + '5259492': 2 menses + '604800': 1 septimana + '63113904': 2 annos + '7889238': 3 menses + themes: + default: Mastodon (Obscur) + mastodon-light: Mastodon (Clar) + two_factor_authentication: + add: Adder + disable: Disactivar 2FA + user_mailer: + appeal_approved: + action: Vader a tu conto + welcome: + subject: Benvenite in Mastodon + webauthn_credentials: + delete: Deler diff --git a/config/locales/ie.yml b/config/locales/ie.yml index 87aa1c41cc..638205a7f4 100644 --- a/config/locales/ie.yml +++ b/config/locales/ie.yml @@ -424,6 +424,7 @@ ie: view: Vider dominia-blocca email_domain_blocks: add_new: Adjunter un nov + allow_registrations_with_approval: Permisser registrationes con aprobation attempts_over_week: one: "%{count} registration-prova durant li ultim semane" other: "%{count} registration-prova durant li ultim semane" @@ -439,6 +440,7 @@ ie: title: Bloccar nov email-dominia no_email_domain_block_selected: Null email-dominia-bloccas esset changeat pro que null esset selectet not_permitted: Ne permisset + resolved_dns_records_hint_html: Li dominia-nómine resolue se al seque dominias MX, queles es in fine responsabil por acceptar e-posta. Bloccar un dominia MX va bloccar inscriptiones de quelcunc e-posta quel usa li sam dominia MX, mem si li visibil dominia-nómine es diferent. Esse caut e ne blocca majori provisores de e-posta. resolved_through_html: Resoluet per %{domain} title: Bloccat email-dominias export_domain_allows: @@ -672,11 +674,13 @@ ie: description_html: Con roles por usatores, tu posse customisar li functiones e locs de Mastodon in queles tui usatores posse accesser. edit: Modificar rol '%{name}' everyone: Permissiones predefinit + everyone_full_description_html: Ti es li fundamental rol quel afecta omni usatores, mem tis sin un assignat rol. Omni altri roles hereda permissiones de it. permissions_count: one: "%{count} permission" other: "%{count} permissiones" privileges: administrator: Administrator + administrator_description: Usatores con ti permission va trapassar omni permission delete_user_data: Deleter Data de Usator delete_user_data_description: Possibilisa que usatores mey deleter li data de altri usatores strax invite_users: Invitar Usatores @@ -726,6 +730,8 @@ ie: settings: about: manage_rules: Gerer regules de servitor + preamble: Provider detalliat information pri qualmen li servitor es operat, moderat, payat. + rules_hint: Hay un dedicat area por regules queles vor usatores es expectat obedir. title: Pri appearance: preamble: Customisar li interfacie web de Mastodon. @@ -736,7 +742,10 @@ ie: desc_html: To ci usa extern scrites de hCaptcha, quel posse esser ínquietant pro rasones de securitá e privatie. In plu, it posse far li processu de registration mult plu desfacil (particularimen por tis con deshabilitás). Pro ti rasones, ples considerar alternativ mesuras, tales quam registration per aprobation o invitation. title: Exige que nov usatores solue un CAPTCHA por confirmar lor conto content_retention: + preamble: Decider qualmen usator-generat contenete es inmagasinat in Mastodon. title: Retention de contenete + default_noindex: + desc_html: Afecta omni usatores qui ne ha changeat ti parametre personalmen discovery: follow_recommendations: Seque-recomandationes preamble: Exposir interessant contenete es importantissim por incorporar nov usatores qui fórsan conosse nequi che Mastodon. Decider qualmen diferent utensiles de decovrition functiona che vor servitor. @@ -771,11 +780,13 @@ ie: critical_update: Critic — ples actualisar rapidmen description: On recomanda que vu actualisa vor Mastodon-servitor regularimen por profiter del max recent fixes e facultates. In plu, quelcvez it es critic actualisar Mastodon promptmen por evitar problemas de securitá. Pro ti rasones, Mastodon questiona chascun 30 minutes ca hay actualisationes, e va notificar vos secun vor parametres pri email-notificationes. documentation_link: Aprender plu + release_notes: Version-notas title: Actualisationes disponibil type: Specie types: major: Majori lansament minor: Minori lansament + patch: Lapp-version — bug-corectiones e changes facil a aplicar version: Version statuses: account: Autor @@ -967,6 +978,7 @@ ie: body: Nov versiones de Mastodon ha esset lansat, vu fórsan vole actualisar! subject: Nov versiones Mastodon es disponibil por %{instance}! new_trends: + body: 'Li sequent elementes besona un revision ante que on posse monstrar les publicmen:' new_trending_links: title: Populari ligamentes new_trending_statuses: @@ -1385,10 +1397,12 @@ ie: media_attachments: validations: images_and_video: On ne posse atachar un video a un posta quel ja contene images + not_ready: Ne posse atachar files ancor sub tractament. Prova denov pos ne long! too_many: Ne posse atachar plu quam 4 files migrations: acct: Translocat a cancel: Anullar redirection + cancel_explanation: Anullar li redirection va reactivisar tui actual conto, ma ne va restaurar sequitores queles ha esset movet a ti-ta conto. cancelled_msg: Anullat redirection con successe. errors: already_moved: es li sam conto a equel tu ha ja translocat @@ -1397,6 +1411,9 @@ ie: not_found: ne posset esser trovat followers_count: Sequitores al témpor de translocation incoming_migrations: Translocant de un conto diferent + incoming_migrations_html: Por mover de un altri conto a ti-ci, erstmen tu deve crear un alias de conto. + moved_msg: Tui conto nu redirecte a %{acct} e tui sequitores es in li processu de esser movet. + not_redirecting: Tui conto redirecte a null altri conto actualmen. on_cooldown: Tu ha recentmen migrat tui conto. Ti function va esser disponibil denov pos %{count} dies. past_migrations: Passat migrationes proceed_with_move: Translocar sequitores @@ -1406,7 +1423,12 @@ ie: warning: backreference_required: Li nov conto deve in prim esser configurat por retroreferentiar ti-ci conto before: 'Ante proceder, ples leer ti notas cuidosimen:' + cooldown: Pos mover se, hay un periode de atendida durant quel tu ne va posser mover te denov + disabled_account: Tui actual conto ne va esser completmen usabil pos to. Támen, tu va posser accesser li exportation de data, e anc reactivisation. + followers: Ti-ci action va mover omni sequitores del actual conto al nov conto + only_redirect_html: Alternativmen, tu posse solmen meter un redirection sur tui profil. other_data: Necun altri data va esser translocat automaticmen + redirect: Li profil de tui actual conto va esser actualisat con un anuncie de redirection e va esser excludet de serchas moderation: title: Moderation move_handler: @@ -1805,6 +1827,7 @@ ie: verification: extra_instructions_html: 'Nota: Li ligament in tui websitu posse esser ínvisibil. Li important parte es rel="me" quel prevente fals self-identification in websitus con contenete generat de usatores. Tu posse mem usar un link element in li cap-section del págine vice a, ma li HTML code deve esser accessibil sin executer JavaScript.' here_is_how: Vide qualmen + hint_html: "Verificar tui identitá che Mastodon es por omnes. Basat sur apert web-criteries, líber nu e sempre. Omno quel tu besona es un websitu personal per quel gente reconosse te. Quande tu fa un ligament a tui websitu de tui profil, on va controlar que li websitu have un ligament reciproc a tui profil e monstrar un visual indicator sur it." instructions_html: Copiar e collar li code ci infra in li HTML de tui web-situ. Poy adjunter li adresse de tui web-situ ad-in un del aditional campes sur tui profil ex li section "Modificar profil" e salvar li changes. verification: Verification verified_links: Tui verificat ligamentes @@ -1815,9 +1838,12 @@ ie: success: Tui clave de securitá esset adjuntet con successe. delete: Deleter delete_confirmation: Vole tu vermen deleter ti-ci clave de securitá? + description_html: Si tu activisa autentication per clave de securitá, aperter session va postular que tu usa un de tui claves de securitá. destroy: + error: Un problema evenit durant li deletion de tui clave de securitá. Ples provar denov. success: Tui clave de securitá esset successosimen deletet. invalid_credential: Ínvalid clave de securitá not_enabled: Tu ancor ne ha possibilisat WebAuthn not_supported: Ti-ci navigator ne subtene claves de securitá + otp_required: Por usar claves de securitá, ples activisar 2-factor autentication. registered_on: Adheret ye %{date} diff --git a/config/locales/it.yml b/config/locales/it.yml index 3637313c0d..16b327f3e1 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -425,6 +425,7 @@ it: view: Visualizza blocco di dominio email_domain_blocks: add_new: Aggiungi nuovo + allow_registrations_with_approval: Consenti registrazioni con approvazione attempts_over_week: one: "%{count} tentativo nell'ultima settimana" other: "%{count} tentativi di registrazione nell'ultima settimana" diff --git a/config/locales/ko.yml b/config/locales/ko.yml index e6187f4d83..76bb3bd9f1 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -420,6 +420,7 @@ ko: view: 도메인 차단 보기 email_domain_blocks: add_new: 새로 추가하기 + allow_registrations_with_approval: 승인을 통한 가입 허용 attempts_over_week: other: 지난 주 동안 %{count}건의 가입 시도가 있었습니다 created_msg: 이메일 도메인 차단 규칙을 생성했습니다 diff --git a/config/locales/lt.yml b/config/locales/lt.yml index b1d8772b6b..b194011a42 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -169,6 +169,7 @@ lt: undo: Atkurti domeno bloką email_domain_blocks: add_new: Pridėti naują + allow_registrations_with_approval: Leisti registracijas su patvirtinimu created_msg: El pašto domenas sėkmingai pridėtas į juodąjį sąrašą delete: Ištrinti domain: Domenas diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 44843b2198..b2894e4abb 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -425,6 +425,7 @@ nl: view: Domeinblokkade bekijken email_domain_blocks: add_new: Nieuwe toevoegen + allow_registrations_with_approval: Inschrijvingen met toestemming toestaan attempts_over_week: one: "%{count} registratiepoging tijdens de afgelopen week" other: "%{count} registratiepogingen tijdens de afgelopen week" diff --git a/config/locales/nn.yml b/config/locales/nn.yml index 3ee02863db..70cbc27d6d 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -425,6 +425,7 @@ nn: view: Vis domeneblokkering email_domain_blocks: add_new: Lag ny + allow_registrations_with_approval: Tillat registreringer med godkjenning attempts_over_week: one: "%{count} forsøk i løpet av den siste uken" other: "%{count} forsøk på å opprette konto i løpet av den siste uken" diff --git a/config/locales/no.yml b/config/locales/no.yml index f791c7151e..54f82550b7 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -425,6 +425,7 @@ view: Vis domeneblokkering email_domain_blocks: add_new: Lag ny + allow_registrations_with_approval: Tillat registreringer med godkjenning attempts_over_week: one: "%{count} forsøk i løpet av den siste uken" other: "%{count} forsøk på å opprette konto i løpet av den siste uken" diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 79de3b5196..15aefe5f74 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -439,6 +439,7 @@ pl: view: Zobacz blokadę domeny email_domain_blocks: add_new: Dodaj nową + allow_registrations_with_approval: Zezwól na rejestracje po zatwierdzeniu attempts_over_week: few: "%{count} próby w ciągu ostatniego tygodnia" many: "%{count} prób w ciągu ostatniego tygodnia" diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index c8060ad803..2c485283b1 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -425,6 +425,7 @@ pt-BR: view: Ver domínios bloqueados email_domain_blocks: add_new: Adicionar novo + allow_registrations_with_approval: Permitir inscrições com aprovação attempts_over_week: one: "%{count} tentativa na última semana" other: "%{count} tentativas de inscrição na última semana" diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 89da6b480e..111f0fa8ee 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -425,6 +425,7 @@ pt-PT: view: Ver domínios bloqueados email_domain_blocks: add_new: Adicionar novo + allow_registrations_with_approval: Permitir inscrições com aprovação attempts_over_week: one: "%{count} tentativa na última semana" other: "%{count} tentativas de inscrição na última semana" diff --git a/config/locales/simple_form.ia.yml b/config/locales/simple_form.ia.yml index 6ab26788bd..552abb2550 100644 --- a/config/locales/simple_form.ia.yml +++ b/config/locales/simple_form.ia.yml @@ -1 +1,46 @@ +--- ia: + simple_form: + labels: + account: + fields: + name: Etiquetta + value: Contento + admin_account_action: + type: Action + defaults: + avatar: Pictura de profilo + confirm_new_password: Confirmar nove contrasigno + confirm_password: Confirmar contrasigno + current_password: Contrasigno actual + new_password: Nove contrasigno + password: Contrasigno + setting_display_media_default: Predefinite + setting_display_media_hide_all: Celar toto + setting_display_media_show_all: Monstrar toto + setting_system_font_ui: Usar typo de litteras predefinite del systema + setting_theme: Thema de sito + setting_trends: Monstrar le tendentias de hodie + sign_in_token_attempt: Codice de securitate + title: Titulo + username: Nomine de usator + username_or_email: Nomine de usator o e-mail + form_admin_settings: + custom_css: CSS personalisate + profile_directory: Activar directorio de profilos + site_contact_email: Adresse de e-mail de contacto + site_contact_username: Nomine de usator de contacto + site_terms: Politica de confidentialitate + site_title: Nomine de servitor + theme: Thema predefinite + trends: Activar tendentias + notification_emails: + software_updates: + label: Un nove version de Mastodon es disponibile + user: + time_zone: Fuso horari + user_role: + name: Nomine + permissions_as_keys: Permissiones + position: Prioritate + 'yes': Si diff --git a/config/locales/simple_form.ie.yml b/config/locales/simple_form.ie.yml index bd055b1c9e..72797bde5e 100644 --- a/config/locales/simple_form.ie.yml +++ b/config/locales/simple_form.ie.yml @@ -8,6 +8,7 @@ ie: fields: Tui websitu, pronómines, etá, quocunc quel tu vole. indexable: Tui public postas posse aparir in sercha-resultates sur Mastodon. E in omni casu, tis qui ha interactet con tui postas va posser serchar e trovar les. note: 'Tu posse @mentionar altri persones o #hashtags.' + show_collections: Gente va posser navigar tra tui sequentes e sequitores. Gente quem tu seque va vider que tu seque les sin egarda. unlocked: Persones va posser sequer te sin petir aprobation. Desselecte si tu vole manualmen tractar petitiones de sequer e decider ca acceptar o rejecter nov sequitores. account_alias: acct: Specificar li usatornomine@dominia del conto ex quel tu vole translocar @@ -58,6 +59,14 @@ ie: setting_display_media_default: Celar medie marcat quam sensitiv setting_display_media_hide_all: Sempre celar medie setting_display_media_show_all: Sempre monstrar medie + setting_use_blurhash: Gradientes es basat sur li colores del celat visuales ma obscura omni detallies + setting_use_pending_items: Celar nov postas detra un clicc vice rular li témpor-linea automaticmen + username: Tu posse usar lítteres, númeres e sublineas + domain_allow: + domain: Ti dominia va posser obtener data de ti-ci servitor, e data venient de it va esser tractat e inmagasinat + email_domain_block: + domain: Ti posse esser li dominia-nómine quel apari in li email-adresse o li MX-registre quel it usa. Ili va esser controlat durant adhesion. + with_dns_records: On va far un prova resoluer li DNS-registres del specificat dominia, e li resultates anc va esser bloccat featured_tag: name: 'Vi quelc hashtags usat max recentmen de te:' filters: @@ -66,8 +75,12 @@ ie: hide: Celar completmen li contenete filtrat, quam si it ne existe warn: Celar li contenete filtrat detra un avise mentionant li titul del filtre form_admin_settings: + activity_api_enabled: Númeres de postas publicat localmen, activ usatores, e nov adhesiones in periodes semanal backups_retention_period: Mantener usator-generat archives por li specificat quantitá de dies. bootstrap_timeline_accounts: Ti-ci contos va esser pinglat al parte superiori del recomandationes por nov usatores. + closed_registrations_message: Monstrat quande adhesiones es cludet + content_cache_retention_period: Omni postas e boosts de altri servitores va esser deletet pos li specificat quantitá de dies. Quelc postas fórsan va esser ínrestaurabil. Omni pertinent marcatores, favorites e boosts anc va esser perdit e ínpossibil a restaurar. + custom_css: On posse aplicar customisat stiles al web-version de Mastodon. mascot: Substitue li ilustration in li avansat interfacie web. peers_api_enabled: Un liste de nómines de dominia queles ti-ci servitor ha incontrat in li fediverse. Ci null data es includet pri ca tu confedera con un cert servitor o ne; it indica solmen que tui servitor conosse it. Usat per servicies colectent general statisticas pri federation. profile_directory: Li profilarium monstra omni usatores volent esser decovribil. @@ -178,6 +191,7 @@ ie: setting_display_media_show_all: Monstrar omno setting_expand_spoilers: Sempre expander postas marcat con admonitiones de contenete setting_hide_network: Celar tui grafica social + setting_reduce_motion: Reducter motion in animationes setting_system_font_ui: Usar predefinit fonte de sistema setting_theme: Tema de situ setting_trends: Monstrar li hodial tendenties @@ -190,6 +204,8 @@ ie: username: Nómine de usator username_or_email: Usator-nómine o E-posta whole_word: Plen parol + email_domain_block: + with_dns_records: Includer archives MX e IPs del dominia featured_tag: name: Hashtag filters: @@ -197,10 +213,14 @@ ie: hide: Celar completmen warn: Celar con un admonition form_admin_settings: + activity_api_enabled: Publicar agregat statisticas pri usator-activitá in li API backups_retention_period: Periode de retener archives de usator bootstrap_timeline_accounts: Sempre recomandar ti-ci contos a nov usatores closed_registrations_message: Customisat missage quande registration ne disponibil + content_cache_retention_period: Periode de retention por cachat contenete custom_css: Custom CSS + media_cache_retention_period: Periode de retention por cachat medie + peers_api_enabled: Publicar liste de conosset servitores per li API profile_directory: Possibilisar profilarium registrations_mode: Qui posse registrar se require_invite_text: Exiger un rason por adherer se @@ -210,11 +230,19 @@ ie: site_contact_username: Usator-nómine de contact site_extended_description: Extendet descrition site_short_description: Descrition del servitor + site_terms: Politica pri Privatie site_title: Nómine de servitor + status_page_url: URL de statu-págine theme: Predefenit tema + thumbnail: Miniatura del servitor + timeline_preview: Permisser accesse ínautenticat al public témpor-lineas trendable_by_default: Possibilisar tendenties sin priori inspection trends: Possibilisar tendenties trends_as_landing_page: Usar tendenties quam frontispicie + interactions: + must_be_follower: Bloccar notificationes de tis qui ne seque te + must_be_following: Bloccar notificationes de tis quem tu ne seque + must_be_following_dm: Bloccar direct missages de tis quem tu ne seque invite: comment: Comentar invite_request: @@ -228,27 +256,38 @@ ie: sign_up_requires_approval: Limitar usator-registrationes severity: Regul notification_emails: + appeal: Alqui apella un decision moderatori + digest: Inviar compendies per email favourite: Alqui favoritisat tui posta follow: Alqui sequet te follow_request: Alqui petit sequer te mention: Alqui mentionat te pending_account: Nov conto besonant inspection + reblog: Alqui boostat tui posta report: Nov raporte es submisset software_updates: all: Notificar pri omni nov actualisationes critical: Notificar solmen pri critical actualisationes label: Un nov version de Mastodon es disponibil + none: Nequande notificar pri actualisationes (ne recomandat) + patch: Notificar pri problema-fixant actualisationes trending_tag: Nov tendentie besonant inspection rule: text: Regul + settings: + indexable: Includer profil-pagine in serchatores + show_application: Monstrar de quel aplication tu fat un posta tag: + listable: Permisser que ti hashtag apari in serchas e suggestiones name: Hashtag trendable: Permisse que ti-ci hashtag apari sub tendenties + usable: Permisser que postas usa ti hashtag user: role: Rol time_zone: Zone temporal user_role: color: Color del insignie + highlighted: Monstrar rol quam insigne sur usator-profiles name: Nómine permissions_as_keys: Permissiones position: Prioritá diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml index a89e1a4290..e13a05835f 100644 --- a/config/locales/simple_form.sk.yml +++ b/config/locales/simple_form.sk.yml @@ -149,6 +149,8 @@ sk: text: Prečo sa k nám chceš pridať? ip_block: comment: Komentár + severities: + sign_up_requires_approval: Obmedz registrácie severity: Pravidlo notification_emails: digest: Zasielať súhrnné emaily diff --git a/config/locales/sk.yml b/config/locales/sk.yml index feb84ea984..cfc5ee7087 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -374,6 +374,7 @@ sk: view: Ukáž blokovanie domén email_domain_blocks: add_new: Pridaj nový + allow_registrations_with_approval: Povoľ registrovanie so schválením created_msg: Emailová doména bola úspešne pridaná do zoznamu zakázaných delete: Vymaž dns: diff --git a/config/locales/sl.yml b/config/locales/sl.yml index ecff5a6672..83d52ae0e7 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -439,6 +439,7 @@ sl: view: Pokaži domenski blok email_domain_blocks: add_new: Dodaj novo + allow_registrations_with_approval: Dovoli registracije z odobritvijo attempts_over_week: few: "%{count} poskusi prijave zadnji teden" one: "%{count} poskus prijave zadnji teden" diff --git a/config/locales/sq.yml b/config/locales/sq.yml index af1bb4644d..9ab6e85361 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -425,6 +425,7 @@ sq: view: Shihni bllokim përkatësie email_domain_blocks: add_new: Shtoni të ri + allow_registrations_with_approval: Lejo regjistrim me miratim attempts_over_week: one: "%{count} përpjekje gjatë javës së shkuar" other: "%{count} përpjekje regjistrimi gjatë javës së kaluar" diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index e8760697e2..02f63ede71 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -432,6 +432,7 @@ sr-Latn: view: Pročitaj blok domena email_domain_blocks: add_new: Dodaj novi + allow_registrations_with_approval: Dozvoli registraciju uz odobrenje attempts_over_week: few: "%{count} pokušaja tokom prethodne nedelje" one: "%{count} pokušaj tokom prethodne nedelje" diff --git a/config/locales/sr.yml b/config/locales/sr.yml index b32d86f652..51613940bc 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -432,6 +432,7 @@ sr: view: Прочитај блок домена email_domain_blocks: add_new: Додај нови + allow_registrations_with_approval: Дозволи регистрацију уз одобрење attempts_over_week: few: "%{count} покушаја током претходне недеље" one: "%{count} покушај током претходне недеље" diff --git a/config/locales/th.yml b/config/locales/th.yml index 59a6b2c4fb..f553f6a41c 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -418,6 +418,7 @@ th: view: ดูการปิดกั้นโดเมน email_domain_blocks: add_new: เพิ่มใหม่ + allow_registrations_with_approval: อนุญาตการลงทะเบียนด้วยการอนุมัติ attempts_over_week: other: "%{count} ความพยายามในการลงทะเบียนในช่วงสัปดาห์ที่ผ่านมา" created_msg: ปิดกั้นโดเมนอีเมลสำเร็จ diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 568607e70d..da8935f6ca 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -425,6 +425,7 @@ tr: view: Alan adı bloğunu görüntüle email_domain_blocks: add_new: Yeni ekle + allow_registrations_with_approval: Onaylı kayıtlara izin ver attempts_over_week: one: Son haftada %{count} deneme other: Son haftada %{count} kayıt denemesi diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 139b8be30d..7a1957eba7 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -439,6 +439,7 @@ uk: view: Переглянути заблоковані домени email_domain_blocks: add_new: Додати + allow_registrations_with_approval: Дозволити реєстрації із затвердженням attempts_over_week: few: "%{count} спроби входу за останній тиждень" many: "%{count} спроб входу за останній тиждень" diff --git a/config/locales/vi.yml b/config/locales/vi.yml index c06a84b973..85aabe7176 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -418,6 +418,7 @@ vi: view: Xem máy chủ chặn email_domain_blocks: add_new: Thêm mới + allow_registrations_with_approval: Cho đăng ký nhưng duyệt thủ công attempts_over_week: other: "%{count} lần thử đăng ký vào tuần trước" created_msg: Đã chặn tên miền email này diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index ec4d714233..a573c8f99b 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -418,6 +418,7 @@ zh-CN: view: 查看域名屏蔽 email_domain_blocks: add_new: 添加新条目 + allow_registrations_with_approval: 注册时需要批准 attempts_over_week: other: 上周有 %{count} 次注册尝试 created_msg: 成功屏蔽电子邮件域名 diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index 01a0a026a7..61355a4c53 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -418,6 +418,7 @@ zh-HK: view: 顯示正被阻隔的網域 email_domain_blocks: add_new: 新增 + allow_registrations_with_approval: 允許經批准的註冊 attempts_over_week: other: 上週嘗試了註冊 %{count} 次 created_msg: 已新增電郵網域阻隔 From e1b49d3454a0c2d492d65e076700882272e982fc Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 5 Jan 2024 07:26:31 -0500 Subject: [PATCH 073/422] Regenerate rubocop todo with version 1.59.0 (#28597) --- .rubocop_todo.yml | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index d68832e85e..6ab8957055 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp` -# using RuboCop version 1.57.2. +# using RuboCop version 1.59.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -26,7 +26,7 @@ Lint/NonLocalExitFromIterator: # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: - Max: 100 + Max: 82 # Configuration parameters: CountBlocks, Max. Metrics/BlockNesting: @@ -50,7 +50,7 @@ RSpec/MultipleExpectations: # Configuration parameters: AllowSubject. RSpec/MultipleMemoizedHelpers: - Max: 21 + Max: 17 # Configuration parameters: AllowedGroups. RSpec/NestedGroups: @@ -66,7 +66,6 @@ Rails/ApplicationController: Rails/HasAndBelongsToMany: Exclude: - 'app/models/concerns/account/associations.rb' - - 'app/models/preview_card.rb' - 'app/models/status.rb' - 'app/models/tag.rb' @@ -144,7 +143,6 @@ Rails/WhereExists: Exclude: - 'app/controllers/activitypub/inboxes_controller.rb' - 'app/controllers/admin/email_domain_blocks_controller.rb' - - 'app/controllers/auth/registrations_controller.rb' - 'app/lib/activitypub/activity/create.rb' - 'app/lib/delivery_failure_tracker.rb' - 'app/lib/feed_manager.rb' @@ -160,7 +158,6 @@ Rails/WhereExists: - 'app/serializers/rest/announcement_serializer.rb' - 'app/serializers/rest/tag_serializer.rb' - 'app/services/activitypub/fetch_remote_status_service.rb' - - 'app/services/app_sign_up_service.rb' - 'app/services/vote_service.rb' - 'app/validators/reaction_validator.rb' - 'app/validators/vote_validator.rb' @@ -171,12 +168,6 @@ Rails/WhereExists: - 'spec/services/purge_domain_service_spec.rb' - 'spec/services/unallow_domain_service_spec.rb' -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowOnConstant, AllowOnSelfClass. -Style/CaseEquality: - Exclude: - - 'config/initializers/trusted_proxies.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowedMethods, AllowedPatterns. # AllowedMethods: ==, equal?, eql? @@ -204,8 +195,8 @@ Style/FetchEnvVar: - 'config/initializers/devise.rb' - 'config/initializers/paperclip.rb' - 'config/initializers/vapid.rb' - - 'lib/premailer_webpack_strategy.rb' - 'lib/mastodon/redis_config.rb' + - 'lib/premailer_webpack_strategy.rb' - 'lib/tasks/repo.rake' - 'spec/features/profile_spec.rb' @@ -222,7 +213,6 @@ Style/FormatStringToken: # This cop supports unsafe autocorrection (--autocorrect-all). Style/GlobalStdStream: Exclude: - - 'config/boot.rb' - 'config/environments/development.rb' - 'config/environments/production.rb' @@ -411,8 +401,8 @@ Style/TrailingCommaInHashLiteral: - 'config/environments/test.rb' # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, MinSize, WordRegex. +# Configuration parameters: WordRegex. # SupportedStyles: percent, brackets Style/WordArray: - Exclude: - - 'app/helpers/languages_helper.rb' + EnforcedStyle: percent + MinSize: 3 From b3dab17b586ef34bc8cd64f6b25e3ec661f7defd Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 5 Jan 2024 07:31:18 -0500 Subject: [PATCH 074/422] Remove deprecated `RSpec/FilePath` cop (#28601) --- .rubocop.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 8832e28f6e..bedd8f7850 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -118,15 +118,10 @@ Rails/UnusedIgnoredColumns: Rails/NegateInclude: Enabled: false -# Reason: Some single letter camel case files shouldn't be split +# Reason: Deprecated cop, will be removed in 3.0, replaced by SpecFilePathFormat # https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath RSpec/FilePath: - CustomTransform: - ActivityPub: activitypub - DeepL: deepl - FetchOEmbedService: fetch_oembed_service - OEmbedController: oembed_controller - OStatus: ostatus + Enabled: false # Reason: # https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnamedsubject From 12bed81187dd5b041a735af8e9cb5a5f96b4b75a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 5 Jan 2024 10:13:59 -0500 Subject: [PATCH 075/422] Add validation specs to `CustomFilter` model (#28600) --- app/models/custom_filter.rb | 6 +++++- spec/models/custom_filter_spec.rb | 35 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 spec/models/custom_filter_spec.rb diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb index 9c936fed39..0ee9e35328 100644 --- a/app/models/custom_filter.rb +++ b/app/models/custom_filter.rb @@ -143,6 +143,10 @@ class CustomFilter < ApplicationRecord end def context_must_be_valid - errors.add(:context, I18n.t('filters.errors.invalid_context')) if context.empty? || context.any? { |c| !VALID_CONTEXTS.include?(c) } + errors.add(:context, I18n.t('filters.errors.invalid_context')) if invalid_context_value? + end + + def invalid_context_value? + context.blank? || context.difference(VALID_CONTEXTS).any? end end diff --git a/spec/models/custom_filter_spec.rb b/spec/models/custom_filter_spec.rb new file mode 100644 index 0000000000..9404936337 --- /dev/null +++ b/spec/models/custom_filter_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe CustomFilter do + describe 'Validations' do + it 'requires presence of title' do + record = described_class.new(title: '') + record.valid? + + expect(record).to model_have_error_on_field(:title) + end + + it 'requires presence of context' do + record = described_class.new(context: nil) + record.valid? + + expect(record).to model_have_error_on_field(:context) + end + + it 'requires non-empty of context' do + record = described_class.new(context: []) + record.valid? + + expect(record).to model_have_error_on_field(:context) + end + + it 'requires valid context value' do + record = described_class.new(context: ['invalid']) + record.valid? + + expect(record).to model_have_error_on_field(:context) + end + end +end From 5a6d533c5390832f86c3352af0f6023f9ad07156 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Fri, 5 Jan 2024 22:57:47 +0100 Subject: [PATCH 076/422] Enable Rails 7.1 Marshalling format (#28609) --- app/controllers/concerns/cache_concern.rb | 155 +--------------------- app/models/custom_filter.rb | 19 +-- app/models/custom_filter_keyword.rb | 10 +- config/application.rb | 2 + lib/mastodon/redis_config.rb | 2 +- 5 files changed, 8 insertions(+), 180 deletions(-) diff --git a/app/controllers/concerns/cache_concern.rb b/app/controllers/concerns/cache_concern.rb index 2dfe5e263a..62f763fe2f 100644 --- a/app/controllers/concerns/cache_concern.rb +++ b/app/controllers/concerns/cache_concern.rb @@ -3,150 +3,6 @@ module CacheConcern extend ActiveSupport::Concern - module ActiveRecordCoder - EMPTY_HASH = {}.freeze - - class << self - def dump(record) - instances = InstanceTracker.new - serialized_associations = serialize_associations(record, instances) - serialized_records = instances.map { |r| serialize_record(r) } - [serialized_associations, *serialized_records] - end - - def load(payload) - instances = InstanceTracker.new - serialized_associations, *serialized_records = payload - serialized_records.each { |attrs| instances.push(deserialize_record(*attrs)) } - deserialize_associations(serialized_associations, instances) - end - - private - - # Records without associations, or which have already been visited before, - # are serialized by their id alone. - # - # Records with associations are serialized as a two-element array including - # their id and the record's association cache. - # - def serialize_associations(record, instances) - return unless record - - if (id = instances.lookup(record)) - payload = id - else - payload = instances.push(record) - - cached_associations = record.class.reflect_on_all_associations.select do |reflection| - record.association_cached?(reflection.name) - end - - unless cached_associations.empty? - serialized_associations = cached_associations.map do |reflection| - association = record.association(reflection.name) - - serialized_target = if reflection.collection? - association.target.map { |target_record| serialize_associations(target_record, instances) } - else - serialize_associations(association.target, instances) - end - - [reflection.name, serialized_target] - end - - payload = [payload, serialized_associations] - end - end - - payload - end - - def deserialize_associations(payload, instances) - return unless payload - - id, associations = payload - record = instances.fetch(id) - - associations&.each do |name, serialized_target| - begin - association = record.association(name) - rescue ActiveRecord::AssociationNotFoundError - raise AssociationMissingError, "undefined association: #{name}" - end - - target = if association.reflection.collection? - serialized_target.map! { |serialized_record| deserialize_associations(serialized_record, instances) } - else - deserialize_associations(serialized_target, instances) - end - - association.target = target - end - - record - end - - def serialize_record(record) - arguments = [record.class.name, attributes_for_database(record)] - arguments << true if record.new_record? - arguments - end - - def attributes_for_database(record) - attributes = record.attributes_for_database - attributes.transform_values! { |attr| attr.is_a?(::ActiveModel::Type::Binary::Data) ? attr.to_s : attr } - attributes - end - - def deserialize_record(class_name, attributes_from_database, new_record = false) # rubocop:disable Style/OptionalBooleanParameter - begin - klass = Object.const_get(class_name) - rescue NameError - raise ClassMissingError, "undefined class: #{class_name}" - end - - # Ideally we'd like to call `klass.instantiate`, however it doesn't allow to pass - # wether the record was persisted or not. - attributes = klass.attributes_builder.build_from_database(attributes_from_database, EMPTY_HASH) - klass.allocate.init_with_attributes(attributes, new_record) - end - end - - class Error < StandardError - end - - class ClassMissingError < Error - end - - class AssociationMissingError < Error - end - - class InstanceTracker - def initialize - @instances = [] - @ids = {}.compare_by_identity - end - - def map(&block) - @instances.map(&block) - end - - def fetch(...) - @instances.fetch(...) - end - - def push(instance) - id = @ids[instance] = @instances.size - @instances << instance - id - end - - def lookup(instance) - @ids[instance] - end - end - end - class_methods do def vary_by(value, **kwargs) before_action(**kwargs) do |controller| @@ -196,11 +52,7 @@ module CacheConcern raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation) return [] if raw.empty? - cached_keys_with_value = begin - Rails.cache.read_multi(*raw).transform_keys(&:id).transform_values { |r| ActiveRecordCoder.load(r) } - rescue ActiveRecordCoder::Error - {} # The serialization format may have changed, let's pretend it's a cache miss. - end + cached_keys_with_value = Rails.cache.read_multi(*raw).transform_keys(&:id) uncached_ids = raw.map(&:id) - cached_keys_with_value.keys @@ -208,10 +60,7 @@ module CacheConcern unless uncached_ids.empty? uncached = klass.where(id: uncached_ids).with_includes.index_by(&:id) - - uncached.each_value do |item| - Rails.cache.write(item, ActiveRecordCoder.dump(item)) - end + Rails.cache.write_multi(uncached.values.to_h { |i| [i, i] }) end raw.filter_map { |item| cached_keys_with_value[item.id] || uncached[item.id] } diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb index 0ee9e35328..371267fc28 100644 --- a/app/models/custom_filter.rb +++ b/app/models/custom_filter.rb @@ -17,23 +17,8 @@ class CustomFilter < ApplicationRecord self.ignored_columns += %w(whole_word irreversible) - # NOTE: We previously used `alias_attribute` but this does not play nicely - # with cache - def title - phrase - end - - def title=(value) - self.phrase = value - end - - def filter_action - action - end - - def filter_action=(value) - self.action = value - end + alias_attribute :title, :phrase + alias_attribute :filter_action, :action VALID_CONTEXTS = %w( home diff --git a/app/models/custom_filter_keyword.rb b/app/models/custom_filter_keyword.rb index 1812a43081..3158b3b79a 100644 --- a/app/models/custom_filter_keyword.rb +++ b/app/models/custom_filter_keyword.rb @@ -17,15 +17,7 @@ class CustomFilterKeyword < ApplicationRecord validates :keyword, presence: true - # NOTE: We previously used `alias_attribute` but this does not play nicely - # with cache - def phrase - keyword - end - - def phrase=(value) - self.keyword = value - end + alias_attribute :phrase, :keyword before_save :prepare_cache_invalidation! before_destroy :prepare_cache_invalidation! diff --git a/config/application.rb b/config/application.rb index 990a89383e..bab1b46cb0 100644 --- a/config/application.rb +++ b/config/application.rb @@ -63,6 +63,8 @@ module Mastodon # Initialize configuration defaults for originally generated Rails version. config.load_defaults 7.0 + config.active_record.marshalling_format_version = 7.1 + # Please, add to the `ignore` list any other `lib` subdirectories that do # not contain `.rb` files, or that should not be reloaded or eager loaded. # Common ones are `templates`, `generators`, or `middleware`, for example. diff --git a/lib/mastodon/redis_config.rb b/lib/mastodon/redis_config.rb index e885712f89..10672a5358 100644 --- a/lib/mastodon/redis_config.rb +++ b/lib/mastodon/redis_config.rb @@ -34,7 +34,7 @@ REDIS_CACHE_PARAMS = { driver: :hiredis, url: ENV['CACHE_REDIS_URL'], expires_in: 10.minutes, - namespace: cache_namespace, + namespace: "#{cache_namespace}:7.1", connect_timeout: 5, pool: { size: Sidekiq.server? ? Sidekiq[:concurrency] : Integer(ENV['MAX_THREADS'] || 5), From 8a312ad79bb756d92b5ca4c9a176bd96c702e73e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 10:57:12 +0100 Subject: [PATCH 077/422] Update dependency puma to v6.4.2 (#28640) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 009293167f..45d228e48f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -544,7 +544,7 @@ GEM psych (5.1.2) stringio public_suffix (5.0.4) - puma (6.4.1) + puma (6.4.2) nio4r (~> 2.0) pundit (2.3.1) activesupport (>= 3.0.0) From 352625c49107e2e25c802e24a1631e173432832b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 10:59:06 +0100 Subject: [PATCH 078/422] Update libretranslate/libretranslate Docker tag to v1.5.3 (#28639) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 40dc72c12d..21ee078d60 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -70,7 +70,7 @@ services: hard: -1 libretranslate: - image: libretranslate/libretranslate:v1.5.2 + image: libretranslate/libretranslate:v1.5.3 restart: unless-stopped volumes: - lt-data:/home/libretranslate/.local From a27a82939dffe06134327468a192b2badf4aee46 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 05:16:33 -0500 Subject: [PATCH 079/422] Remove the 7.1 marshalling format "todo" from new_framework_defaults (#28625) --- config/initializers/new_framework_defaults_7_1.rb | 9 --------- 1 file changed, 9 deletions(-) diff --git a/config/initializers/new_framework_defaults_7_1.rb b/config/initializers/new_framework_defaults_7_1.rb index 2fa0e42746..1475fe2fd9 100644 --- a/config/initializers/new_framework_defaults_7_1.rb +++ b/config/initializers/new_framework_defaults_7_1.rb @@ -158,15 +158,6 @@ Rails.application.config.add_autoload_paths_to_load_path = false # rather than to rely on a global default. # Rails.application.config.active_record.default_column_serializer = nil -# Enable a performance optimization that serializes Active Record models -# in a faster and more compact way. -# -# To perform a rolling deploy of a Rails 7.1 upgrade, wherein servers that have -# not yet been upgraded must be able to read caches from upgraded servers, -# leave this optimization off on the first deploy, then enable it on a -# subsequent deploy. -# Rails.application.config.active_record.marshalling_format_version = 7.1 - # Run `after_commit` and `after_*_commit` callbacks in the order they are defined in a model. # This matches the behaviour of all other callbacks. # In previous versions of Rails, they ran in the inverse order. From e09419f22a98266be029c5121b7302ab439c0a3a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 05:17:38 -0500 Subject: [PATCH 080/422] Move old framework defaults file to regular config value (#28623) --- config/initializers/new_framework_defaults_7_0.rb | 10 ---------- config/initializers/open_redirects.rb | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 config/initializers/new_framework_defaults_7_0.rb create mode 100644 config/initializers/open_redirects.rb diff --git a/config/initializers/new_framework_defaults_7_0.rb b/config/initializers/new_framework_defaults_7_0.rb deleted file mode 100644 index edaf819447..0000000000 --- a/config/initializers/new_framework_defaults_7_0.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -# TODO -# The Rails 7.0 framework default here is to set this true. However, we have a -# location in devise that redirects where we don't have an easy ability to -# override a method or set a config option, but where the redirect does not -# provide this option. -# https://github.com/heartcombo/devise/blob/v4.9.2/app/controllers/devise/confirmations_controller.rb#L28 -# Once a solution is found, this line can be removed. -Rails.application.config.action_controller.raise_on_open_redirects = false diff --git a/config/initializers/open_redirects.rb b/config/initializers/open_redirects.rb new file mode 100644 index 0000000000..c953a990c6 --- /dev/null +++ b/config/initializers/open_redirects.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# TODO +# Starting with Rails 7.0, the framework default here is to set this true. +# However, we have a location in devise that redirects where we don't have an +# easy ability to override the method or set a config option, and where the +# redirect does not supply this option itself. +# https://github.com/heartcombo/devise/blob/v4.9.2/app/controllers/devise/confirmations_controller.rb#L28 +# Once a solution is found, this line can be removed. +Rails.application.config.action_controller.raise_on_open_redirects = false From 8d06baf8127d453c889279ab413f2ecfac4192aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 10:17:53 +0000 Subject: [PATCH 081/422] Update dependency strong_migrations to v1.7.0 (#28621) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index cfcbcc0d3c..a56702fad2 100644 --- a/Gemfile +++ b/Gemfile @@ -90,7 +90,7 @@ gem 'sidekiq-bulk', '~> 0.2.0' gem 'simple-navigation', '~> 4.4' gem 'simple_form', '~> 5.2' gem 'stoplight', '~> 3.0.1' -gem 'strong_migrations', '1.6.4' +gem 'strong_migrations', '1.7.0' gem 'tty-prompt', '~> 0.23', require: false gem 'twitter-text', '~> 3.1.0' gem 'tzinfo-data', '~> 1.2023' diff --git a/Gemfile.lock b/Gemfile.lock index 45d228e48f..fd6fa563c2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -748,7 +748,7 @@ GEM stoplight (3.0.2) redlock (~> 1.0) stringio (3.1.0) - strong_migrations (1.6.4) + strong_migrations (1.7.0) activerecord (>= 5.2) swd (1.3.0) activesupport (>= 3) @@ -952,7 +952,7 @@ DEPENDENCIES simplecov-lcov (~> 0.8) stackprof stoplight (~> 3.0.1) - strong_migrations (= 1.6.4) + strong_migrations (= 1.7.0) test-prof thor (~> 1.2) tty-prompt (~> 0.23) From c9e67521583ac0e393c8dafef561e9eff528bf58 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 11:18:57 +0100 Subject: [PATCH 082/422] Update dependency rubocop-rspec to v2.26.1 (#28611) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index fd6fa563c2..f032850eb8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -688,7 +688,7 @@ GEM rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rspec (2.26.0) + rubocop-rspec (2.26.1) rubocop (~> 1.40) rubocop-capybara (~> 2.17) rubocop-factory_bot (~> 2.22) From fe2667bb0d3487a32b9da5250402a90482a85fe2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 11:19:33 +0100 Subject: [PATCH 083/422] Update dependency rubocop-performance to v1.20.2 (#28641) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index f032850eb8..e694dce0fb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -680,7 +680,7 @@ GEM rubocop (~> 1.41) rubocop-factory_bot (2.25.0) rubocop (~> 1.33) - rubocop-performance (1.20.1) + rubocop-performance (1.20.2) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.30.0, < 2.0) rubocop-rails (2.23.1) From a0e237a96fca2774d3c9ed43063a45e395bb7f40 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Mon, 8 Jan 2024 11:57:40 +0100 Subject: [PATCH 084/422] Upgrade Redux packages (#28585) --- .eslintrc.js | 11 +- .../emoji_picker_dropdown_container.js | 3 +- .../containers/language_dropdown_container.js | 3 +- .../containers/announcements_container.js | 3 +- .../mastodon/features/home_timeline/index.jsx | 2 +- .../mastodon/features/list_adder/index.jsx | 2 +- .../mastodon/features/lists/index.jsx | 2 +- .../mastodon/features/notifications/index.jsx | 2 +- .../mastodon/features/report/comment.jsx | 2 +- .../mastodon/features/status/index.jsx | 2 +- .../subscribed_languages_modal/index.jsx | 2 +- .../features/ui/components/list_panel.jsx | 2 +- .../ui/containers/status_list_container.js | 2 +- app/javascript/mastodon/reducers/accounts.ts | 3 +- app/javascript/mastodon/reducers/modal.ts | 3 +- .../mastodon/reducers/relationships.ts | 5 +- app/javascript/mastodon/selectors/accounts.ts | 2 +- app/javascript/mastodon/selectors/index.js | 2 +- .../mastodon/store/middlewares/errors.ts | 32 ++++-- .../mastodon/store/middlewares/loading_bar.ts | 24 +++- .../mastodon/store/middlewares/sounds.ts | 35 ++++-- .../mastodon/store/typed_functions.ts | 6 +- config/webpack/rules/babel.js | 8 +- package.json | 9 +- yarn.lock | 104 +++++++++--------- 25 files changed, 167 insertions(+), 104 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index e2d16a54a8..1b36bcee25 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -245,7 +245,7 @@ module.exports = defineConfig({ }, // Immutable / Redux / data store { - pattern: '{immutable,react-redux,react-immutable-proptypes,react-immutable-pure-component,reselect}', + pattern: '{immutable,@reduxjs/toolkit,react-redux,react-immutable-proptypes,react-immutable-pure-component}', group: 'external', position: 'before', }, @@ -353,7 +353,14 @@ module.exports = defineConfig({ '@typescript-eslint/consistent-type-exports': 'error', '@typescript-eslint/consistent-type-imports': 'error', "@typescript-eslint/prefer-nullish-coalescing": ['error', { ignorePrimitives: { boolean: true } }], - + "@typescript-eslint/no-restricted-imports": [ + "warn", + { + "name": "react-redux", + "importNames": ["useSelector", "useDispatch"], + "message": "Use typed hooks `useAppDispatch` and `useAppSelector` instead." + } + ], 'jsdoc/require-jsdoc': 'off', // Those rules set stricter rules for TS files diff --git a/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js b/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js index a0e50029df..8cf906b20a 100644 --- a/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js +++ b/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js @@ -1,6 +1,7 @@ +import { createSelector } from '@reduxjs/toolkit'; import { Map as ImmutableMap } from 'immutable'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; + import { useEmoji } from '../../../actions/emojis'; import { changeSetting } from '../../../actions/settings'; diff --git a/app/javascript/mastodon/features/compose/containers/language_dropdown_container.js b/app/javascript/mastodon/features/compose/containers/language_dropdown_container.js index e1e2f04024..ba4b5f05a5 100644 --- a/app/javascript/mastodon/features/compose/containers/language_dropdown_container.js +++ b/app/javascript/mastodon/features/compose/containers/language_dropdown_container.js @@ -1,6 +1,7 @@ +import { createSelector } from '@reduxjs/toolkit'; import { Map as ImmutableMap } from 'immutable'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; + import { changeComposeLanguage } from 'mastodon/actions/compose'; import { useLanguage } from 'mastodon/actions/languages'; diff --git a/app/javascript/mastodon/features/getting_started/containers/announcements_container.js b/app/javascript/mastodon/features/getting_started/containers/announcements_container.js index c33e624324..3bb1b8e8d1 100644 --- a/app/javascript/mastodon/features/getting_started/containers/announcements_container.js +++ b/app/javascript/mastodon/features/getting_started/containers/announcements_container.js @@ -1,6 +1,7 @@ +import { createSelector } from '@reduxjs/toolkit'; import { Map as ImmutableMap } from 'immutable'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; + import { addReaction, removeReaction, dismissAnnouncement } from 'mastodon/actions/announcements'; diff --git a/app/javascript/mastodon/features/home_timeline/index.jsx b/app/javascript/mastodon/features/home_timeline/index.jsx index 7c9c7a4e52..613eb4b896 100644 --- a/app/javascript/mastodon/features/home_timeline/index.jsx +++ b/app/javascript/mastodon/features/home_timeline/index.jsx @@ -6,9 +6,9 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; import { Helmet } from 'react-helmet'; +import { createSelector } from '@reduxjs/toolkit'; import { List as ImmutableList } from 'immutable'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as CampaignIcon } from '@material-symbols/svg-600/outlined/campaign.svg'; import { ReactComponent as HomeIcon } from '@material-symbols/svg-600/outlined/home-fill.svg'; diff --git a/app/javascript/mastodon/features/list_adder/index.jsx b/app/javascript/mastodon/features/list_adder/index.jsx index 1ba9972e00..4e7bd46bdf 100644 --- a/app/javascript/mastodon/features/list_adder/index.jsx +++ b/app/javascript/mastodon/features/list_adder/index.jsx @@ -2,10 +2,10 @@ import PropTypes from 'prop-types'; import { injectIntl } from 'react-intl'; +import { createSelector } from '@reduxjs/toolkit'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { setupListAdder, resetListAdder } from '../../actions/lists'; import NewListForm from '../lists/components/new_list_form'; diff --git a/app/javascript/mastodon/features/lists/index.jsx b/app/javascript/mastodon/features/lists/index.jsx index 58e85b4d28..9014394351 100644 --- a/app/javascript/mastodon/features/lists/index.jsx +++ b/app/javascript/mastodon/features/lists/index.jsx @@ -4,10 +4,10 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { Helmet } from 'react-helmet'; +import { createSelector } from '@reduxjs/toolkit'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as ListAltIcon } from '@material-symbols/svg-600/outlined/list_alt.svg'; diff --git a/app/javascript/mastodon/features/notifications/index.jsx b/app/javascript/mastodon/features/notifications/index.jsx index 379932b7b7..762c96ccca 100644 --- a/app/javascript/mastodon/features/notifications/index.jsx +++ b/app/javascript/mastodon/features/notifications/index.jsx @@ -5,10 +5,10 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { Helmet } from 'react-helmet'; +import { createSelector } from '@reduxjs/toolkit'; import { List as ImmutableList } from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as DoneAllIcon } from '@material-symbols/svg-600/outlined/done_all.svg'; import { ReactComponent as NotificationsIcon } from '@material-symbols/svg-600/outlined/notifications-fill.svg'; diff --git a/app/javascript/mastodon/features/report/comment.jsx b/app/javascript/mastodon/features/report/comment.jsx index ec59746923..b80c14fcb9 100644 --- a/app/javascript/mastodon/features/report/comment.jsx +++ b/app/javascript/mastodon/features/report/comment.jsx @@ -3,10 +3,10 @@ import { useCallback, useEffect, useRef } from 'react'; import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; +import { createSelector } from '@reduxjs/toolkit'; import { OrderedSet, List as ImmutableList } from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { shallowEqual } from 'react-redux'; -import { createSelector } from 'reselect'; import Toggle from 'react-toggle'; diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index c581255c99..3832489764 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -6,11 +6,11 @@ import classNames from 'classnames'; import { Helmet } from 'react-helmet'; import { withRouter } from 'react-router-dom'; +import { createSelector } from '@reduxjs/toolkit'; import Immutable from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as VisibilityIcon } from '@material-symbols/svg-600/outlined/visibility.svg'; import { ReactComponent as VisibilityOffIcon } from '@material-symbols/svg-600/outlined/visibility_off.svg'; diff --git a/app/javascript/mastodon/features/subscribed_languages_modal/index.jsx b/app/javascript/mastodon/features/subscribed_languages_modal/index.jsx index 147e11d1be..ac34f7986c 100644 --- a/app/javascript/mastodon/features/subscribed_languages_modal/index.jsx +++ b/app/javascript/mastodon/features/subscribed_languages_modal/index.jsx @@ -2,11 +2,11 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; +import { createSelector } from '@reduxjs/toolkit'; import { is, List as ImmutableList, Set as ImmutableSet } from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg'; diff --git a/app/javascript/mastodon/features/ui/components/list_panel.jsx b/app/javascript/mastodon/features/ui/components/list_panel.jsx index 8dbd28f094..ff600730a0 100644 --- a/app/javascript/mastodon/features/ui/components/list_panel.jsx +++ b/app/javascript/mastodon/features/ui/components/list_panel.jsx @@ -1,9 +1,9 @@ import PropTypes from 'prop-types'; +import { createSelector } from '@reduxjs/toolkit'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { ReactComponent as ListAltIcon } from '@material-symbols/svg-600/outlined/list_alt.svg'; diff --git a/app/javascript/mastodon/features/ui/containers/status_list_container.js b/app/javascript/mastodon/features/ui/containers/status_list_container.js index 36a8f58f8b..3e7ae2add0 100644 --- a/app/javascript/mastodon/features/ui/containers/status_list_container.js +++ b/app/javascript/mastodon/features/ui/containers/status_list_container.js @@ -1,6 +1,6 @@ +import { createSelector } from '@reduxjs/toolkit'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; import { debounce } from 'lodash'; diff --git a/app/javascript/mastodon/reducers/accounts.ts b/app/javascript/mastodon/reducers/accounts.ts index f7270eb60a..e6f07340c0 100644 --- a/app/javascript/mastodon/reducers/accounts.ts +++ b/app/javascript/mastodon/reducers/accounts.ts @@ -1,7 +1,6 @@ +import type { Reducer } from '@reduxjs/toolkit'; import { Map as ImmutableMap } from 'immutable'; -import type { Reducer } from 'redux'; - import { followAccountSuccess, unfollowAccountSuccess, diff --git a/app/javascript/mastodon/reducers/modal.ts b/app/javascript/mastodon/reducers/modal.ts index 73a2afb916..368f26542c 100644 --- a/app/javascript/mastodon/reducers/modal.ts +++ b/app/javascript/mastodon/reducers/modal.ts @@ -1,6 +1,5 @@ -import { Record as ImmutableRecord, Stack } from 'immutable'; - import type { Reducer } from '@reduxjs/toolkit'; +import { Record as ImmutableRecord, Stack } from 'immutable'; import { COMPOSE_UPLOAD_CHANGE_SUCCESS } from '../actions/compose'; import type { ModalType } from '../actions/modal'; diff --git a/app/javascript/mastodon/reducers/relationships.ts b/app/javascript/mastodon/reducers/relationships.ts index 2ba61839c7..dcca11b203 100644 --- a/app/javascript/mastodon/reducers/relationships.ts +++ b/app/javascript/mastodon/reducers/relationships.ts @@ -1,7 +1,6 @@ -import { Map as ImmutableMap } from 'immutable'; - import { isFulfilled } from '@reduxjs/toolkit'; -import type { Reducer } from 'redux'; +import type { Reducer } from '@reduxjs/toolkit'; +import { Map as ImmutableMap } from 'immutable'; import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships'; import type { Account } from 'mastodon/models/account'; diff --git a/app/javascript/mastodon/selectors/accounts.ts b/app/javascript/mastodon/selectors/accounts.ts index 66193136c4..cee3a87bca 100644 --- a/app/javascript/mastodon/selectors/accounts.ts +++ b/app/javascript/mastodon/selectors/accounts.ts @@ -1,5 +1,5 @@ +import { createSelector } from '@reduxjs/toolkit'; import { Record as ImmutableRecord } from 'immutable'; -import { createSelector } from 'reselect'; import { accountDefaultValues } from 'mastodon/models/account'; import type { Account, AccountShape } from 'mastodon/models/account'; diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js index 8a07ba774d..b1c60403e9 100644 --- a/app/javascript/mastodon/selectors/index.js +++ b/app/javascript/mastodon/selectors/index.js @@ -1,5 +1,5 @@ +import { createSelector } from '@reduxjs/toolkit'; import { List as ImmutableList, Map as ImmutableMap } from 'immutable'; -import { createSelector } from 'reselect'; import { toServerSideType } from 'mastodon/utils/filters'; diff --git a/app/javascript/mastodon/store/middlewares/errors.ts b/app/javascript/mastodon/store/middlewares/errors.ts index 9f28f5ff53..e11aa78178 100644 --- a/app/javascript/mastodon/store/middlewares/errors.ts +++ b/app/javascript/mastodon/store/middlewares/errors.ts @@ -1,20 +1,34 @@ -import type { AnyAction, Middleware } from 'redux'; +import { isAction } from '@reduxjs/toolkit'; +import type { Action, Middleware } from '@reduxjs/toolkit'; import type { RootState } from '..'; import { showAlertForError } from '../../actions/alerts'; const defaultFailSuffix = 'FAIL'; +const isFailedAction = new RegExp(`${defaultFailSuffix}$`, 'g'); -export const errorsMiddleware: Middleware = +interface ActionWithMaybeAlertParams extends Action { + skipAlert?: boolean; + skipNotFound?: boolean; + error?: unknown; +} + +function isActionWithmaybeAlertParams( + action: unknown, +): action is ActionWithMaybeAlertParams { + return isAction(action); +} + +export const errorsMiddleware: Middleware, RootState> = ({ dispatch }) => (next) => - (action: AnyAction & { skipAlert?: boolean; skipNotFound?: boolean }) => { - if (action.type && !action.skipAlert) { - const isFail = new RegExp(`${defaultFailSuffix}$`, 'g'); - - if (typeof action.type === 'string' && action.type.match(isFail)) { - dispatch(showAlertForError(action.error, action.skipNotFound)); - } + (action) => { + if ( + isActionWithmaybeAlertParams(action) && + !action.skipAlert && + action.type.match(isFailedAction) + ) { + dispatch(showAlertForError(action.error, action.skipNotFound)); } return next(action); diff --git a/app/javascript/mastodon/store/middlewares/loading_bar.ts b/app/javascript/mastodon/store/middlewares/loading_bar.ts index 83056ee49f..d259be899b 100644 --- a/app/javascript/mastodon/store/middlewares/loading_bar.ts +++ b/app/javascript/mastodon/store/middlewares/loading_bar.ts @@ -3,9 +3,11 @@ import { isPending as isThunkActionPending, isFulfilled as isThunkActionFulfilled, isRejected as isThunkActionRejected, + isAction, } from '@reduxjs/toolkit'; +import type { Middleware, UnknownAction } from '@reduxjs/toolkit'; + import { showLoading, hideLoading } from 'react-redux-loading-bar'; -import type { AnyAction, Middleware } from 'redux'; import type { RootState } from '..'; @@ -19,14 +21,28 @@ const defaultTypeSuffixes: Config['promiseTypeSuffixes'] = [ 'REJECTED', ]; +interface ActionWithSkipLoading extends UnknownAction { + skipLoading: boolean; +} + +function isActionWithSkipLoading( + action: unknown, +): action is ActionWithSkipLoading { + return ( + isAction(action) && + 'skipLoading' in action && + typeof action.skipLoading === 'boolean' + ); +} + export const loadingBarMiddleware = ( config: Config = {}, -): Middleware => { +): Middleware<{ skipLoading?: boolean }, RootState> => { const promiseTypeSuffixes = config.promiseTypeSuffixes ?? defaultTypeSuffixes; return ({ dispatch }) => (next) => - (action: AnyAction) => { + (action) => { let isPending = false; let isFulfilled = false; let isRejected = false; @@ -39,7 +55,7 @@ export const loadingBarMiddleware = ( else if (isThunkActionFulfilled(action)) isFulfilled = true; else if (isThunkActionRejected(action)) isRejected = true; } else if ( - action.type && + isActionWithSkipLoading(action) && !action.skipLoading && typeof action.type === 'string' ) { diff --git a/app/javascript/mastodon/store/middlewares/sounds.ts b/app/javascript/mastodon/store/middlewares/sounds.ts index 09ade7d753..51839f427a 100644 --- a/app/javascript/mastodon/store/middlewares/sounds.ts +++ b/app/javascript/mastodon/store/middlewares/sounds.ts @@ -1,4 +1,5 @@ -import type { Middleware, AnyAction } from 'redux'; +import { isAction } from '@reduxjs/toolkit'; +import type { Middleware, UnknownAction } from '@reduxjs/toolkit'; import ready from 'mastodon/ready'; import { assetHost } from 'mastodon/utils/config'; @@ -10,6 +11,21 @@ interface AudioSource { type: string; } +interface ActionWithMetaSound extends UnknownAction { + meta: { sound: string }; +} + +function isActionWithMetaSound(action: unknown): action is ActionWithMetaSound { + return ( + isAction(action) && + 'meta' in action && + typeof action.meta === 'object' && + !!action.meta && + 'sound' in action.meta && + typeof action.meta.sound === 'string' + ); +} + const createAudio = (sources: AudioSource[]) => { const audio = new Audio(); sources.forEach(({ type, src }) => { @@ -34,7 +50,10 @@ const play = (audio: HTMLAudioElement) => { void audio.play(); }; -export const soundsMiddleware = (): Middleware => { +export const soundsMiddleware = (): Middleware< + Record, + RootState +> => { const soundCache: Record = {}; void ready(() => { @@ -50,15 +69,15 @@ export const soundsMiddleware = (): Middleware => { ]); }); - return () => - (next) => - (action: AnyAction & { meta?: { sound?: string } }) => { - const sound = action.meta?.sound; + return () => (next) => (action) => { + if (isActionWithMetaSound(action)) { + const sound = action.meta.sound; if (sound && Object.hasOwn(soundCache, sound)) { play(soundCache[sound]); } + } - return next(action); - }; + return next(action); + }; }; diff --git a/app/javascript/mastodon/store/typed_functions.ts b/app/javascript/mastodon/store/typed_functions.ts index f1e71385a8..46a10b8b47 100644 --- a/app/javascript/mastodon/store/typed_functions.ts +++ b/app/javascript/mastodon/store/typed_functions.ts @@ -1,7 +1,7 @@ -import type { TypedUseSelectorHook } from 'react-redux'; -import { useDispatch, useSelector } from 'react-redux'; - import { createAsyncThunk } from '@reduxjs/toolkit'; +import type { TypedUseSelectorHook } from 'react-redux'; +// eslint-disable-next-line @typescript-eslint/no-restricted-imports +import { useDispatch, useSelector } from 'react-redux'; import type { AppDispatch, RootState } from './store'; diff --git a/config/webpack/rules/babel.js b/config/webpack/rules/babel.js index 2811a1674d..c7bf886e79 100644 --- a/config/webpack/rules/babel.js +++ b/config/webpack/rules/babel.js @@ -7,8 +7,14 @@ module.exports = { include: [ settings.source_path, ...settings.resolved_paths, + 'node_modules/@reduxjs' ].map(p => resolve(p)), - exclude: /node_modules/, + exclude: function(modulePath) { + return ( + /node_modules/.test(modulePath) && + !/@reduxjs/.test(modulePath) + ); + }, use: [ { loader: 'babel-loader', diff --git a/package.json b/package.json index a5b6a228ca..16ed4decaa 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@github/webauthn-json": "^2.1.1", "@material-symbols/svg-600": "^0.14.0", "@rails/ujs": "^7.1.1", - "@reduxjs/toolkit": "^1.9.5", + "@reduxjs/toolkit": "^2.0.1", "@svgr/webpack": "^5.5.0", "arrow-key-navigation": "^1.2.0", "async-mutex": "^0.4.0", @@ -106,8 +106,8 @@ "react-motion": "^0.5.2", "react-notification": "^6.8.5", "react-overlays": "^5.2.1", - "react-redux": "^8.0.4", - "react-redux-loading-bar": "^5.0.4", + "react-redux": "^9.0.4", + "react-redux-loading-bar": "^5.0.8", "react-router": "^5.3.4", "react-router-dom": "^5.3.4", "react-router-scroll-4": "^1.0.0-beta.1", @@ -116,12 +116,9 @@ "react-swipeable-views": "^0.14.0", "react-textarea-autosize": "^8.4.1", "react-toggle": "^4.1.3", - "redux": "^4.2.1", "redux-immutable": "^4.0.0", - "redux-thunk": "^2.4.2", "regenerator-runtime": "^0.14.0", "requestidlecallback": "^0.3.0", - "reselect": "^4.1.8", "rimraf": "^5.0.1", "sass": "^1.62.1", "sass-loader": "^10.2.0", diff --git a/yarn.lock b/yarn.lock index 70d98332ad..71ed44a446 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1483,7 +1483,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.22.3, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.22.3, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": version: 7.23.7 resolution: "@babel/runtime@npm:7.23.7" dependencies: @@ -2302,7 +2302,7 @@ __metadata: "@github/webauthn-json": "npm:^2.1.1" "@material-symbols/svg-600": "npm:^0.14.0" "@rails/ujs": "npm:^7.1.1" - "@reduxjs/toolkit": "npm:^1.9.5" + "@reduxjs/toolkit": "npm:^2.0.1" "@svgr/webpack": "npm:^5.5.0" "@testing-library/jest-dom": "npm:^6.0.0" "@testing-library/react": "npm:^14.0.0" @@ -2410,8 +2410,8 @@ __metadata: react-motion: "npm:^0.5.2" react-notification: "npm:^6.8.5" react-overlays: "npm:^5.2.1" - react-redux: "npm:^8.0.4" - react-redux-loading-bar: "npm:^5.0.4" + react-redux: "npm:^9.0.4" + react-redux-loading-bar: "npm:^5.0.8" react-router: "npm:^5.3.4" react-router-dom: "npm:^5.3.4" react-router-scroll-4: "npm:^1.0.0-beta.1" @@ -2421,12 +2421,9 @@ __metadata: react-test-renderer: "npm:^18.2.0" react-textarea-autosize: "npm:^8.4.1" react-toggle: "npm:^4.1.3" - redux: "npm:^4.2.1" redux-immutable: "npm:^4.0.0" - redux-thunk: "npm:^2.4.2" regenerator-runtime: "npm:^0.14.0" requestidlecallback: "npm:^0.3.0" - reselect: "npm:^4.1.8" rimraf: "npm:^5.0.1" sass: "npm:^1.62.1" sass-loader: "npm:^10.2.0" @@ -2622,23 +2619,23 @@ __metadata: languageName: node linkType: hard -"@reduxjs/toolkit@npm:^1.9.5": - version: 1.9.7 - resolution: "@reduxjs/toolkit@npm:1.9.7" +"@reduxjs/toolkit@npm:^2.0.1": + version: 2.0.1 + resolution: "@reduxjs/toolkit@npm:2.0.1" dependencies: - immer: "npm:^9.0.21" - redux: "npm:^4.2.1" - redux-thunk: "npm:^2.4.2" - reselect: "npm:^4.1.8" + immer: "npm:^10.0.3" + redux: "npm:^5.0.0" + redux-thunk: "npm:^3.1.0" + reselect: "npm:^5.0.1" peerDependencies: react: ^16.9.0 || ^17.0.0 || ^18 - react-redux: ^7.2.1 || ^8.0.2 + react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0 peerDependenciesMeta: react: optional: true react-redux: optional: true - checksum: fa0aa4b7c6973ac87ce0ac7e45faa02c73b66c4ee0bc950d178494539a42a1bb908d109297102458b7ea14d5e7dae356e7a7ce9a1b9849b0e8451e6dd70fca9c + checksum: 161b9b8e11d9688890ab97b604a4c10c0d41b1369425a5fa821586932db4cd5a391d15799732b3612e6120a6336458ff577ff254219315c05ecd68da5d15fd79 languageName: node linkType: hard @@ -9128,10 +9125,10 @@ __metadata: languageName: node linkType: hard -"immer@npm:^9.0.21": - version: 9.0.21 - resolution: "immer@npm:9.0.21" - checksum: 03ea3ed5d4d72e8bd428df4a38ad7e483ea8308e9a113d3b42e0ea2cc0cc38340eb0a6aca69592abbbf047c685dbda04e3d34bf2ff438ab57339ed0a34cc0a05 +"immer@npm:^10.0.3": + version: 10.0.3 + resolution: "immer@npm:10.0.3" + checksum: 282a4f8479a40f7d12b2b3243c095e3e892bf99058e2ffcdd6b8e9fd143e6a90f2717ab9b6c8b97c927ffb8054465c8f647056f41660dbfd672e240cf1063503 languageName: node linkType: hard @@ -13104,7 +13101,17 @@ __metadata: languageName: node linkType: hard -"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.13, postcss-selector-parser@npm:^6.0.15, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4": +"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.13, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4": + version: 6.0.13 + resolution: "postcss-selector-parser@npm:6.0.13" + dependencies: + cssesc: "npm:^3.0.0" + util-deprecate: "npm:^1.0.2" + checksum: 51f099b27f7c7198ea1826470ef0adfa58b3bd3f59b390fda123baa0134880a5fa9720137b6009c4c1373357b144f700b0edac73335d0067422063129371444e + languageName: node + linkType: hard + +"postcss-selector-parser@npm:^6.0.15": version: 6.0.15 resolution: "postcss-selector-parser@npm:6.0.15" dependencies: @@ -13693,7 +13700,7 @@ __metadata: languageName: node linkType: hard -"react-redux-loading-bar@npm:^5.0.4": +"react-redux-loading-bar@npm:^5.0.8": version: 5.0.8 resolution: "react-redux-loading-bar@npm:5.0.8" dependencies: @@ -13708,35 +13715,25 @@ __metadata: languageName: node linkType: hard -"react-redux@npm:^8.0.4": - version: 8.1.3 - resolution: "react-redux@npm:8.1.3" +"react-redux@npm:^9.0.4": + version: 9.0.4 + resolution: "react-redux@npm:9.0.4" dependencies: - "@babel/runtime": "npm:^7.12.1" - "@types/hoist-non-react-statics": "npm:^3.3.1" "@types/use-sync-external-store": "npm:^0.0.3" - hoist-non-react-statics: "npm:^3.3.2" - react-is: "npm:^18.0.0" use-sync-external-store: "npm:^1.0.0" peerDependencies: - "@types/react": ^16.8 || ^17.0 || ^18.0 - "@types/react-dom": ^16.8 || ^17.0 || ^18.0 - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - react-native: ">=0.59" - redux: ^4 || ^5.0.0-beta.0 + "@types/react": ^18.2.25 + react: ^18.0 + react-native: ">=0.69" + redux: ^5.0.0 peerDependenciesMeta: "@types/react": optional: true - "@types/react-dom": - optional: true - react-dom: - optional: true react-native: optional: true redux: optional: true - checksum: 64c8be2765568dc66a3c442a41dd0ed74fe048d5ceb7a4fe72e5bac3d3687996a7115f57b5156af7406521087065a0e60f9194318c8ca99c55e9ce48558980ce + checksum: 23af10014b129aeb051de729bde01de21175170b860deefb7ad83483feab5816253f770a4cea93333fc22a53ac9ac699b27f5c3705c388dab53dbcb2906a571a languageName: node linkType: hard @@ -14039,16 +14036,16 @@ __metadata: languageName: node linkType: hard -"redux-thunk@npm:^2.4.2": - version: 2.4.2 - resolution: "redux-thunk@npm:2.4.2" +"redux-thunk@npm:^3.1.0": + version: 3.1.0 + resolution: "redux-thunk@npm:3.1.0" peerDependencies: - redux: ^4 - checksum: e202d6ef7dfa7df08ed24cb221aa89d6c84dbaa7d65fe90dbd8e826d0c10d801f48388f9a7598a4fd970ecbc93d335014570a61ca7bc8bf569eab5de77b31a3c + redux: ^5.0.0 + checksum: 21557f6a30e1b2e3e470933247e51749be7f1d5a9620069a3125778675ce4d178d84bdee3e2a0903427a5c429e3aeec6d4df57897faf93eb83455bc1ef7b66fd languageName: node linkType: hard -"redux@npm:^4.0.0, redux@npm:^4.2.1": +"redux@npm:^4.0.0": version: 4.2.1 resolution: "redux@npm:4.2.1" dependencies: @@ -14057,6 +14054,13 @@ __metadata: languageName: node linkType: hard +"redux@npm:^5.0.0": + version: 5.0.1 + resolution: "redux@npm:5.0.1" + checksum: b10c28357194f38e7d53b760ed5e64faa317cc63de1fb95bc5d9e127fab956392344368c357b8e7a9bedb0c35b111e7efa522210cfdc3b3c75e5074718e9069c + languageName: node + linkType: hard + "reflect.getprototypeof@npm:^1.0.4": version: 1.0.4 resolution: "reflect.getprototypeof@npm:1.0.4" @@ -14226,10 +14230,10 @@ __metadata: languageName: node linkType: hard -"reselect@npm:^4.1.8": - version: 4.1.8 - resolution: "reselect@npm:4.1.8" - checksum: 06a305a504affcbb67dd0561ddc8306b35796199c7e15b38934c80606938a021eadcf68cfd58e7bb5e17786601c37602a3362a4665c7bf0a96c1041ceee9d0b7 +"reselect@npm:^5.0.1": + version: 5.0.1 + resolution: "reselect@npm:5.0.1" + checksum: 0724b4555cd6411849de334a75177780f127af849eb71c4b709966d07ade8090d125c0c926dc6cf936866d23ebadda6aad1da93cd8340525323b889f25d56d51 languageName: node linkType: hard From 4ed663a94fc53e5bd352e92afaff55f187218078 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 11:02:55 +0000 Subject: [PATCH 085/422] Update DefinitelyTyped types (non-major) (#28638) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 71ed44a446..da8ddf214a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3027,11 +3027,11 @@ __metadata: linkType: hard "@types/cors@npm:^2.8.16": - version: 2.8.16 - resolution: "@types/cors@npm:2.8.16" + version: 2.8.17 + resolution: "@types/cors@npm:2.8.17" dependencies: "@types/node": "npm:*" - checksum: ebcfb325b102739249bbaa4845cf1cf4830baf5490a32bcd1a85cd9b8c4d4b9eaaaea94423e454b5b7c9da77e46a64db80d2381d3bc3f940d15d13814e87b70a + checksum: 457364c28c89f3d9ed34800e1de5c6eaaf344d1bb39af122f013322a50bc606eb2aa6f63de4e41a7a08ba7ef454473926c94a830636723da45bf786df032696d languageName: node linkType: hard @@ -3490,13 +3490,13 @@ __metadata: linkType: hard "@types/react@npm:*, @types/react@npm:16 || 17 || 18, @types/react@npm:>=16.9.11, @types/react@npm:^18.2.7": - version: 18.2.46 - resolution: "@types/react@npm:18.2.46" + version: 18.2.47 + resolution: "@types/react@npm:18.2.47" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 814cc67107e5e69501d65bfc371cc2c716665d2a3608d395a2f81e24c3a2875db28e2cad717dfb17017eabcffd1d68ee2c9e09ecaba3f7108d5b7fbb9888ebab + checksum: e98ea1827fe60636d0f7ce206397159a29fc30613fae43e349e32c10ad3c0b7e0ed2ded2f3239e07bd5a3cba8736b6114ba196acccc39905ca4a06f56a8d2841 languageName: node linkType: hard From 8a44b182e8c4890517ba978393a65a0a8f2a3579 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 12:03:04 +0100 Subject: [PATCH 086/422] Update dependency axios to v1.6.5 (#28620) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index da8ddf214a..f50fa76d1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4686,13 +4686,13 @@ __metadata: linkType: hard "axios@npm:^1.4.0": - version: 1.6.4 - resolution: "axios@npm:1.6.4" + version: 1.6.5 + resolution: "axios@npm:1.6.5" dependencies: follow-redirects: "npm:^1.15.4" form-data: "npm:^4.0.0" proxy-from-env: "npm:^1.1.0" - checksum: daac697fa1ea9865cb48e9edb7eacd99e8a9214997f2d8e886cb61c380a613e5c270078bfc153ac96206680106c223f005f0e4bf2f3b2ddd88e559ecf970521f + checksum: aeb9acf87590d8aa67946072ced38e01ca71f5dfe043782c0ccea667e5dd5c45830c08afac9be3d7c894f09684b8ab2a458f497d197b73621233bcf202d9d468 languageName: node linkType: hard From 2ae53e655c3431336ce685c091e212b70db7792c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 12:04:25 +0100 Subject: [PATCH 087/422] Update dependency jsdom to v23.2.0 (#28612) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/yarn.lock b/yarn.lock index f50fa76d1a..bec7709804 100644 --- a/yarn.lock +++ b/yarn.lock @@ -42,6 +42,17 @@ __metadata: languageName: node linkType: hard +"@asamuzakjp/dom-selector@npm:^2.0.1": + version: 2.0.1 + resolution: "@asamuzakjp/dom-selector@npm:2.0.1" + dependencies: + bidi-js: "npm:^1.0.3" + css-tree: "npm:^2.3.1" + is-potential-custom-element-name: "npm:^1.0.1" + checksum: 232895f16f2f9dfc637764df2529084d16e1c122057766a79b16e1d40808e09fffae28c0f0cc8376f8a1564a85dba9d4b2f140a9a0b65f4f95c960192b797037 + languageName: node + linkType: hard + "@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.5": version: 7.23.5 resolution: "@babel/code-frame@npm:7.23.5" @@ -4950,6 +4961,15 @@ __metadata: languageName: node linkType: hard +"bidi-js@npm:^1.0.3": + version: 1.0.3 + resolution: "bidi-js@npm:1.0.3" + dependencies: + require-from-string: "npm:^2.0.2" + checksum: fdddea4aa4120a34285486f2267526cd9298b6e8b773ad25e765d4f104b6d7437ab4ba542e6939e3ac834a7570bcf121ee2cf6d3ae7cd7082c4b5bedc8f271e1 + languageName: node + linkType: hard + "big-integer@npm:^1.6.44": version: 1.6.51 resolution: "big-integer@npm:1.6.51" @@ -6376,12 +6396,12 @@ __metadata: languageName: node linkType: hard -"cssstyle@npm:^3.0.0": - version: 3.0.0 - resolution: "cssstyle@npm:3.0.0" +"cssstyle@npm:^4.0.1": + version: 4.0.1 + resolution: "cssstyle@npm:4.0.1" dependencies: rrweb-cssom: "npm:^0.6.0" - checksum: 23acee092c1cec670fb7b8110e48abd740dc4e574d3b74848743067cb3377a86a1f64cf02606aabd7bb153785e68c2c1e09ce53295ddf7a4b470b3c7c55ec807 + checksum: cadf9a8b23e11f4c6d63f21291096a0b0be868bd4ab9c799daa2c5b18330e39e5281605f01da906e901b42f742df0f3b3645af6465e83377ff7d15a88ee432a0 languageName: node linkType: hard @@ -10637,10 +10657,11 @@ __metadata: linkType: hard "jsdom@npm:^23.0.0": - version: 23.0.1 - resolution: "jsdom@npm:23.0.1" + version: 23.2.0 + resolution: "jsdom@npm:23.2.0" dependencies: - cssstyle: "npm:^3.0.0" + "@asamuzakjp/dom-selector": "npm:^2.0.1" + cssstyle: "npm:^4.0.1" data-urls: "npm:^5.0.0" decimal.js: "npm:^10.4.3" form-data: "npm:^4.0.0" @@ -10648,7 +10669,6 @@ __metadata: http-proxy-agent: "npm:^7.0.0" https-proxy-agent: "npm:^7.0.2" is-potential-custom-element-name: "npm:^1.0.1" - nwsapi: "npm:^2.2.7" parse5: "npm:^7.1.2" rrweb-cssom: "npm:^0.6.0" saxes: "npm:^6.0.0" @@ -10659,14 +10679,14 @@ __metadata: whatwg-encoding: "npm:^3.1.1" whatwg-mimetype: "npm:^4.0.0" whatwg-url: "npm:^14.0.0" - ws: "npm:^8.14.2" + ws: "npm:^8.16.0" xml-name-validator: "npm:^5.0.0" peerDependencies: canvas: ^2.11.2 peerDependenciesMeta: canvas: optional: true - checksum: 13b2b3693ccb40215d1cce77bac7a295414ee4c0a06e30167f8087c9867145ba23dbd592bd95a801cadd7b3698bfd20b9c3f2c26fd8422607f22609ed2e404ef + checksum: b062af50f7be59d914ba75236b7817c848ef3cd007aea1d6b8020a41eb263b7d5bd2652298106e9756b56892f773d990598778d02adab7d0d0d8e58726fc41d3 languageName: node linkType: hard @@ -11964,7 +11984,7 @@ __metadata: languageName: node linkType: hard -"nwsapi@npm:^2.2.2, nwsapi@npm:^2.2.7": +"nwsapi@npm:^2.2.2": version: 2.2.7 resolution: "nwsapi@npm:2.2.7" checksum: 44be198adae99208487a1c886c0a3712264f7bbafa44368ad96c003512fed2753d4e22890ca1e6edb2690c3456a169f2a3c33bfacde1905cf3bf01c7722464db @@ -17577,7 +17597,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.14.2": +"ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.16.0": version: 8.16.0 resolution: "ws@npm:8.16.0" peerDependencies: From 832b92ac3eebb5d65f5c6a6a3d90129e26f2d59f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 06:05:10 -0500 Subject: [PATCH 088/422] Add attachment check to spec/service/suspend_account_service spec (#28619) --- spec/services/suspend_account_service_spec.rb | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/spec/services/suspend_account_service_spec.rb b/spec/services/suspend_account_service_spec.rb index b309ce511e..dcc8dbfd37 100644 --- a/spec/services/suspend_account_service_spec.rb +++ b/spec/services/suspend_account_service_spec.rb @@ -16,17 +16,24 @@ RSpec.describe SuspendAccountService, type: :service do list.accounts << account account.suspend! + + Fabricate(:media_attachment, file: attachment_fixture('boop.ogg'), account: account) end - it 'unmerges from feeds of local followers and preserves suspended flag' do + it 'unmerges from feeds of local followers and changes file mode and preserves suspended flag' do expect { subject } - .to_not change_suspended_flag + .to change_file_mode + .and not_change_suspended_flag expect(FeedManager.instance).to have_received(:unmerge_from_home).with(account, local_follower) expect(FeedManager.instance).to have_received(:unmerge_from_list).with(account, list) end - def change_suspended_flag - change(account, :suspended?) + def change_file_mode + change { File.stat(account.media_attachments.first.file.path).mode } + end + + def not_change_suspended_flag + not_change(account, :suspended?) end end From 57f49c819184d7ecb6d789889671d5d6c7b4167a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 06:09:50 -0500 Subject: [PATCH 089/422] Use Arel `nulls_first` method in ordering CustomEmojiFilter scope (#28614) --- app/models/custom_emoji_filter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/custom_emoji_filter.rb b/app/models/custom_emoji_filter.rb index ed7a8dda15..870cc71974 100644 --- a/app/models/custom_emoji_filter.rb +++ b/app/models/custom_emoji_filter.rb @@ -31,7 +31,7 @@ class CustomEmojiFilter def scope_for(key, value) case key.to_s when 'local' - CustomEmoji.local.left_joins(:category).reorder(Arel.sql('custom_emoji_categories.name ASC NULLS FIRST, custom_emojis.shortcode ASC')) + CustomEmoji.local.left_joins(:category).reorder(CustomEmojiCategory.arel_table[:name].asc.nulls_first).order(shortcode: :asc) when 'remote' CustomEmoji.remote when 'by_domain' From 202951e6d97e808a487499b1e680887309fab61a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 06:15:36 -0500 Subject: [PATCH 090/422] Use Arel `in_order_of` method to generate CASE for `DomainBlock.by_severity` (#28617) --- app/models/domain_block.rb | 2 +- lib/mastodon/cli/maintenance.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb index ff23f8fcc4..f8058324a3 100644 --- a/app/models/domain_block.rb +++ b/app/models/domain_block.rb @@ -31,7 +31,7 @@ class DomainBlock < ApplicationRecord scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) } scope :with_user_facing_limitations, -> { where(severity: [:silence, :suspend]) } scope :with_limitations, -> { where(severity: [:silence, :suspend]).or(where(reject_media: true)) } - scope :by_severity, -> { order(Arel.sql('(CASE severity WHEN 0 THEN 1 WHEN 1 THEN 2 WHEN 2 THEN 0 END), domain')) } + scope :by_severity, -> { in_order_of(:severity, %w(noop silence suspend)).order(:domain) } def to_log_human_identifier domain diff --git a/lib/mastodon/cli/maintenance.rb b/lib/mastodon/cli/maintenance.rb index 7b3a9852a6..f37662aa06 100644 --- a/lib/mastodon/cli/maintenance.rb +++ b/lib/mastodon/cli/maintenance.rb @@ -41,7 +41,8 @@ module Mastodon::CLI class SoftwareUpdate < ApplicationRecord; end class DomainBlock < ApplicationRecord - scope :by_severity, -> { order(Arel.sql('(CASE severity WHEN 0 THEN 1 WHEN 1 THEN 2 WHEN 2 THEN 0 END), domain')) } + enum severity: { silence: 0, suspend: 1, noop: 2 } + scope :by_severity, -> { in_order_of(:severity, %w(noop silence suspend)).order(:domain) } end class PreviewCard < ApplicationRecord From aa6d07dbd9c9ae20e690c88f34d3764d91ee2cef Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 06:20:59 -0500 Subject: [PATCH 091/422] Use normalizes to prepare CustomEmoji `domain` value (#28624) --- app/models/custom_emoji.rb | 6 +----- spec/models/custom_emoji_spec.rb | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb index 97b1c63bf3..550f005d59 100644 --- a/app/models/custom_emoji.rb +++ b/app/models/custom_emoji.rb @@ -41,7 +41,7 @@ class CustomEmoji < ApplicationRecord has_attached_file :image, styles: { static: { format: 'png', convert_options: '-coalesce +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' } }, validate_media_type: false - before_validation :downcase_domain + normalizes :domain, with: ->(domain) { domain.downcase } validates_attachment :image, content_type: { content_type: IMAGE_MIME_TYPES }, presence: true, size: { less_than: LIMIT } validates :shortcode, uniqueness: { scope: :domain }, format: { with: SHORTCODE_ONLY_RE }, length: { minimum: 2 } @@ -95,8 +95,4 @@ class CustomEmoji < ApplicationRecord def remove_entity_cache Rails.cache.delete(EntityCache.instance.to_key(:emoji, shortcode, domain)) end - - def downcase_domain - self.domain = domain.downcase unless domain.nil? - end end diff --git a/spec/models/custom_emoji_spec.rb b/spec/models/custom_emoji_spec.rb index 06affd634a..a0903e5978 100644 --- a/spec/models/custom_emoji_spec.rb +++ b/spec/models/custom_emoji_spec.rb @@ -78,12 +78,23 @@ RSpec.describe CustomEmoji do end end - describe 'pre_validation' do - let(:custom_emoji) { Fabricate(:custom_emoji, domain: 'wWw.MaStOdOn.CoM') } + describe 'Normalizations' do + describe 'downcase domain value' do + context 'with a mixed case domain value' do + it 'normalizes the value to downcased' do + custom_emoji = Fabricate.build(:custom_emoji, domain: 'wWw.MaStOdOn.CoM') - it 'downcases' do - custom_emoji.valid? - expect(custom_emoji.domain).to eq('www.mastodon.com') + expect(custom_emoji.domain).to eq('www.mastodon.com') + end + end + + context 'with a nil domain value' do + it 'leaves the value as nil' do + custom_emoji = Fabricate.build(:custom_emoji, domain: nil) + + expect(custom_emoji.domain).to be_nil + end + end end end end From 1bc5a52139b4a33568c7c9bab96bd24a291fc482 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 06:22:16 -0500 Subject: [PATCH 092/422] Extract SQL heredoc method for Announcement scopes (#28613) --- app/models/announcement.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/models/announcement.rb b/app/models/announcement.rb index 83a8d3682c..00529766a4 100644 --- a/app/models/announcement.rb +++ b/app/models/announcement.rb @@ -21,8 +21,8 @@ class Announcement < ApplicationRecord scope :unpublished, -> { where(published: false) } scope :published, -> { where(published: true) } scope :without_muted, ->(account) { joins("LEFT OUTER JOIN announcement_mutes ON announcement_mutes.announcement_id = announcements.id AND announcement_mutes.account_id = #{account.id}").where(announcement_mutes: { id: nil }) } - scope :chronological, -> { order(Arel.sql('COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) ASC')) } - scope :reverse_chronological, -> { order(Arel.sql('COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) DESC')) } + scope :chronological, -> { order(coalesced_chronology_timestamps.asc) } + scope :reverse_chronological, -> { order(coalesced_chronology_timestamps.desc) } has_many :announcement_mutes, dependent: :destroy has_many :announcement_reactions, dependent: :destroy @@ -33,6 +33,16 @@ class Announcement < ApplicationRecord before_validation :set_published, on: :create + class << self + def coalesced_chronology_timestamps + Arel.sql( + <<~SQL.squish + COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) + SQL + ) + end + end + def to_log_human_identifier text end From 157fc699547e409a2849a1842456ce36d5d545b1 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 8 Jan 2024 13:29:05 +0100 Subject: [PATCH 093/422] Make request_pool_spec tests more robust (#28610) --- spec/lib/request_pool_spec.rb | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/spec/lib/request_pool_spec.rb b/spec/lib/request_pool_spec.rb index bdb0859d76..a31d078327 100644 --- a/spec/lib/request_pool_spec.rb +++ b/spec/lib/request_pool_spec.rb @@ -33,14 +33,12 @@ describe RequestPool do subject - threads = Array.new(3) do + threads = Array.new(5) do Thread.new do - 2.times do - subject.with('http://example.com') do |http_client| - http_client.get('/').flush - # Nudge scheduler to yield and exercise the full pool - sleep(0) - end + subject.with('http://example.com') do |http_client| + http_client.get('/').flush + # Nudge scheduler to yield and exercise the full pool + sleep(0.01) end end end From cc67943df293e3d3d721cc416e613ed3ac1cff7f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:46:25 +0100 Subject: [PATCH 094/422] New Crowdin Translations (automated) (#28627) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/br.json | 97 ++++++++++-- app/javascript/mastodon/locales/de.json | 2 +- app/javascript/mastodon/locales/ia.json | 193 ++++++++++++++++++++++- app/javascript/mastodon/locales/ja.json | 4 +- app/javascript/mastodon/locales/lad.json | 1 + app/javascript/mastodon/locales/vi.json | 38 ++--- config/locales/bg.yml | 1 + config/locales/br.yml | 30 +++- config/locales/de.yml | 1 + config/locales/devise.ia.yml | 6 + config/locales/devise.ie.yml | 24 +++ config/locales/doorkeeper.br.yml | 1 + config/locales/doorkeeper.ia.yml | 13 ++ config/locales/doorkeeper.ie.yml | 21 +++ config/locales/et.yml | 1 + config/locales/fr-QC.yml | 1 + config/locales/fr.yml | 1 + config/locales/ia.yml | 47 ++++++ config/locales/ie.yml | 18 +++ config/locales/is.yml | 1 + config/locales/ja.yml | 1 + config/locales/lad.yml | 1 + config/locales/nl.yml | 2 +- config/locales/nn.yml | 2 +- config/locales/simple_form.br.yml | 7 +- config/locales/simple_form.ie.yml | 27 ++++ config/locales/sk.yml | 2 + config/locales/sv.yml | 1 + config/locales/vi.yml | 4 +- config/locales/zh-TW.yml | 1 + 30 files changed, 510 insertions(+), 39 deletions(-) diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index bea8b27b77..462a5b3393 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -21,6 +21,7 @@ "account.blocked": "Stanket", "account.browse_more_on_origin_server": "Furchal pelloc'h war ar profil orin", "account.cancel_follow_request": "Nullañ ar reked heuliañ", + "account.copy": "Eilañ al liamm war-zu ho profil", "account.disable_notifications": "Paouez d'am c'hemenn pa vez embannet traoù gant @{name}", "account.domain_blocked": "Domani stanket", "account.edit_profile": "Kemmañ ar profil", @@ -28,8 +29,9 @@ "account.endorse": "Lakaat war-wel war ar profil", "account.featured_tags.last_status_at": "Toud diwezhañ : {date}", "account.featured_tags.last_status_never": "Toud ebet", - "account.featured_tags.title": "Penngerioù-klik {name}", + "account.featured_tags.title": "Hashtagoù pennañ {name}", "account.follow": "Heuliañ", + "account.follow_back": "Heuliañ d'ho tro", "account.followers": "Tud koumanantet", "account.followers.empty": "Den na heul an implijer·ez-mañ c'hoazh.", "account.followers_counter": "{count, plural, other{{counter} Heulier·ez}}", @@ -38,6 +40,7 @@ "account.follows.empty": "An implijer·ez-mañ na heul den ebet.", "account.go_to_profile": "Gwelet ar profil", "account.hide_reblogs": "Kuzh skignadennoù gant @{name}", + "account.in_memoriam": "E koun.", "account.joined_short": "Amañ abaoe", "account.languages": "Cheñch ar yezhoù koumanantet", "account.link_verified_on": "Gwiriet eo bet perc'hennidigezh al liamm d'an deiziad-mañ : {date}", @@ -49,11 +52,13 @@ "account.mute_notifications_short": "Kuzhat ar c'hemennoù", "account.mute_short": "Kuzhat", "account.muted": "Kuzhet", + "account.no_bio": "Deskrivadur ebet da gaout.", "account.open_original_page": "Digeriñ ar bajenn orin", - "account.posts": "Toudoù", - "account.posts_with_replies": "Toudoù ha respontoù", + "account.posts": "Embannadurioù", + "account.posts_with_replies": "Embannadurioù ha respontoù", "account.report": "Disklêriañ @{name}", "account.requested": "O c'hortoz an asant. Klikit evit nullañ ar goulenn heuliañ", + "account.requested_follow": "Gant {name} eo bet goulennet ho heuliañ", "account.share": "Skignañ profil @{name}", "account.show_reblogs": "Diskouez skignadennoù @{name}", "account.statuses_counter": "{count, plural, one {{counter} Toud} two {{counter} Doud} other {{counter} a Doudoù}}", @@ -102,6 +107,7 @@ "column.community": "Red-amzer lec'hel", "column.directory": "Mont a-dreuz ar profiloù", "column.domain_blocks": "Domani berzet", + "column.favourites": "Muiañ-karet", "column.follow_requests": "Rekedoù heuliañ", "column.home": "Degemer", "column.lists": "Listennoù", @@ -122,6 +128,9 @@ "community.column_settings.remote_only": "Nemet a-bell", "compose.language.change": "Cheñch yezh", "compose.language.search": "Klask yezhoù...", + "compose.published.body": "Embannet.", + "compose.published.open": "Digeriñ", + "compose.saved.body": "Enrollet.", "compose_form.direct_message_warning_learn_more": "Gouzout hiroc'h", "compose_form.encryption_warning": "Toudoù war Mastodon na vezont ket sifret penn-da-benn. Na rannit ket titouroù kizidik dre Mastodon.", "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", @@ -158,6 +167,7 @@ "confirmations.discard_edit_media.message": "Bez ez eus kemmoù n'int ket enrollet e deskrivadur ar media pe ar rakwel, nullañ anezho evelato?", "confirmations.domain_block.confirm": "Berzañ an domani a-bezh", "confirmations.domain_block.message": "Ha sur oc'h e fell deoc'h berzañ an {domain} a-bezh? Peurvuiañ eo trawalc'h berzañ pe mudañ un nebeud implijer·ezed·ien. Ne welot danvez ebet o tont eus an domani-mañ. Dilamet e vo ar c'houmanantoù war an domani-mañ.", + "confirmations.edit.confirm": "Kemmañ", "confirmations.logout.confirm": "Digevreañ", "confirmations.logout.message": "Ha sur oc'h e fell deoc'h digevreañ ?", "confirmations.mute.confirm": "Kuzhat", @@ -172,7 +182,9 @@ "conversation.mark_as_read": "Merkañ evel lennet", "conversation.open": "Gwelout ar gaozeadenn", "conversation.with": "Gant {names}", + "copy_icon_button.copied": "Eilet er golver", "copypaste.copied": "Eilet", + "copypaste.copy_to_clipboard": "Eilañ er golver", "directory.federated": "Eus ar fedibed anavezet", "directory.local": "Eus {domain} hepken", "directory.new_arrivals": "Degouezhet a-nevez", @@ -209,7 +221,8 @@ "empty_column.domain_blocks": "N'eus domani kuzh ebet c'hoazh.", "empty_column.explore_statuses": "N'eus tuadur ebet evit c'hoazh. Distroit diwezhatoc'h !", "empty_column.follow_requests": "N'ho peus reked heuliañ ebet c'hoazh. Pa vo resevet unan e teuio war wel amañ.", - "empty_column.hashtag": "N'eus netra er ger-klik-mañ c'hoazh.", + "empty_column.followed_tags": "N'emaoc'h oc'h heuliañ hashtag ebet evit poent. Pa vioc'h e vo d'o gwelet amañ.", + "empty_column.hashtag": "N'eus netra en hashtag-mañ c'hoazh.", "empty_column.home": "Goullo eo ho red-amzer degemer! Kit da weladenniñ {public} pe implijit ar c'hlask evit kregiñ ganti ha kejañ gant implijer·ien·ezed all.", "empty_column.list": "Goullo eo al listenn-mañ evit c'hoazh. Pa vo embannet toudoù nevez gant e izili e teuint war wel amañ.", "empty_column.lists": "N'ho peus roll ebet c'hoazh. Pa vo krouet unan ganeoc'h e vo diskouezet amañ.", @@ -223,7 +236,11 @@ "errors.unexpected_crash.copy_stacktrace": "Eilañ ar roudoù diveugañ er golver", "errors.unexpected_crash.report_issue": "Danevellañ ur fazi", "explore.search_results": "Disoc'hoù an enklask", + "explore.suggested_follows": "Tud", "explore.title": "Furchal", + "explore.trending_links": "Keleier", + "explore.trending_statuses": "Embannadurioù", + "explore.trending_tags": "Hashtagoù", "filter_modal.added.context_mismatch_title": "Kenarroud digenglotus !", "filter_modal.added.expired_title": "Sil deuet d'e dermen !", "filter_modal.added.review_and_configure_title": "Arventennoù ar sil", @@ -237,9 +254,13 @@ "filter_modal.select_filter.subtitle": "Implijout ur rummad a zo anezhañ pe krouiñ unan nevez", "filter_modal.select_filter.title": "Silañ an toud-mañ", "filter_modal.title.status": "Silañ un toud", + "firehose.all": "Pep tra", + "firehose.local": "Ar servijer-mañ", + "firehose.remote": "Servijerioù all", "follow_request.authorize": "Aotren", "follow_request.reject": "Nac'hañ", "follow_requests.unlocked_explanation": "Daoust ma n'eo ket ho kont prennet, skipailh {domain} a soñj e fellfe deoc'h gwiriekaat pedadennoù heuliañ deus ar c'hontoù-se diwar-zorn.", + "followed_tags": "Hashtagoù o heuliañ", "footer.about": "Diwar-benn", "footer.directory": "Kavlec'h ar profiloù", "footer.get_app": "Pellgargañ an arload", @@ -247,29 +268,40 @@ "footer.keyboard_shortcuts": "Berradennoù klavier", "footer.privacy_policy": "Reolennoù prevezded", "footer.source_code": "Gwelet kod mammenn", + "footer.status": "Statud", "generic.saved": "Enrollet", "getting_started.heading": "Loc'hañ", - "hashtag.column_header.tag_mode.all": "ha {additional}", + "hashtag.column_header.tag_mode.all": "ha(g) {additional}", "hashtag.column_header.tag_mode.any": "pe {additional}", "hashtag.column_header.tag_mode.none": "hep {additional}", "hashtag.column_settings.select.no_options_message": "N'eus bet kavet ali ebet", - "hashtag.column_settings.select.placeholder": "Ouzhpennañ gerioù-klik…", - "hashtag.column_settings.tag_mode.all": "An holl elfennoù-mañ", + "hashtag.column_settings.select.placeholder": "Ouzhpennañ hashtagoù…", + "hashtag.column_settings.tag_mode.all": "An holl anezho", "hashtag.column_settings.tag_mode.any": "Unan e mesk anezho", "hashtag.column_settings.tag_mode.none": "Hini ebet anezho", "hashtag.column_settings.tag_toggle": "Endelc'her gerioù-alc'hwez ouzhpenn evit ar bannad-mañ", + "hashtag.counter_by_uses": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}}", + "hashtag.counter_by_uses_today": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}} hiziv", "hashtag.follow": "Heuliañ ar ger-klik", - "hashtag.unfollow": "Diheuliañ ar ger-klik", + "hashtag.unfollow": "Paouez heuliañ an hashtag", + "hashtags.and_other": "…{count, plural, one {hag # all} other {ha # all}}", + "home.actions.go_to_explore": "Gwelet petra zo diouzh ar c'hiz", + "home.actions.go_to_suggestions": "Kavout tud da heuliañ", "home.column_settings.basic": "Diazez", "home.column_settings.show_reblogs": "Diskouez ar skignadennoù", "home.column_settings.show_replies": "Diskouez ar respontoù", + "home.explore_prompt.title": "Homañ eo ho pajenn degemer e-barzh Mastodon.", "home.hide_announcements": "Kuzhat ar c'hemennoù", + "home.pending_critical_update.body": "Hizivait ho servijer Mastodon kerkent ha ma c'hallit mar plij!", + "home.pending_critical_update.link": "Gwelet an hizivadennoù", "home.show_announcements": "Diskouez ar c'hemennoù", "interaction_modal.description.follow": "Gant ur gont Mastodon e c'hellit heuliañ {name} evit resev an toudoù a embann war ho red degemer.", "interaction_modal.description.reblog": "Gant ur gont Mastodon e c'hellit skignañ an toud-mañ evit rannañ anezhañ gant ho heulierien·ezed.", "interaction_modal.description.reply": "Gant ur gont Mastodon e c'hellit respont d'an toud-mañ.", + "interaction_modal.no_account_yet": "N'eo ket war vMastodon?", "interaction_modal.on_another_server": "War ur servijer all", "interaction_modal.on_this_server": "War ar servijer-mañ", + "interaction_modal.title.favourite": "Ouzhpennañ embannadur {name} d'ar re vuiañ-karet", "interaction_modal.title.follow": "Heuliañ {name}", "interaction_modal.title.reblog": "Skignañ toud {name}", "interaction_modal.title.reply": "Respont da doud {name}", @@ -285,6 +317,8 @@ "keyboard_shortcuts.direct": "to open direct messages column", "keyboard_shortcuts.down": "Diskennañ er roll", "keyboard_shortcuts.enter": "Digeriñ an toud", + "keyboard_shortcuts.favourite": "Ouzhpennañ an embannadur d'ar re vuiañ-karet", + "keyboard_shortcuts.favourites": "Digeriñ roll an embannadurioù muiañ-karet", "keyboard_shortcuts.federated": "Digeriñ ar red-amzer kevredet", "keyboard_shortcuts.heading": "Berradennoù klavier", "keyboard_shortcuts.home": "Digeriñ ho red-amzer degemer", @@ -314,6 +348,7 @@ "lightbox.next": "Da-heul", "lightbox.previous": "A-raok", "limited_account_hint.action": "Diskouez an aelad memes tra", + "link_preview.author": "Gant {name}", "lists.account.add": "Ouzhpennañ d'al listenn", "lists.account.remove": "Lemel kuit eus al listenn", "lists.delete": "Dilemel al listenn", @@ -328,6 +363,7 @@ "lists.search": "Klask e-touez tud heuliet ganeoc'h", "lists.subheading": "Ho listennoù", "load_pending": "{count, plural, one {# dra nevez} other {# dra nevez}}", + "loading_indicator.label": "O kargañ…", "media_gallery.toggle_visible": "{number, plural, one {Kuzhat ar skeudenn} other {Kuzhat ar skeudenn}}", "mute_modal.duration": "Padelezh", "mute_modal.hide_notifications": "Kuzhat kemenadennoù eus an implijer-se ?", @@ -341,8 +377,10 @@ "navigation_bar.domain_blocks": "Domanioù kuzhet", "navigation_bar.edit_profile": "Kemmañ ar profil", "navigation_bar.explore": "Furchal", + "navigation_bar.favourites": "Muiañ-karet", "navigation_bar.filters": "Gerioù kuzhet", "navigation_bar.follow_requests": "Pedadoù heuliañ", + "navigation_bar.followed_tags": "Hashtagoù o heuliañ", "navigation_bar.follows_and_followers": "Heuliadennoù ha heulier·ezed·ien", "navigation_bar.lists": "Listennoù", "navigation_bar.logout": "Digennaskañ", @@ -369,6 +407,7 @@ "notifications.column_settings.admin.report": "Disklêriadurioù nevez :", "notifications.column_settings.admin.sign_up": "Enskrivadurioù nevez :", "notifications.column_settings.alert": "Kemennoù war ar burev", + "notifications.column_settings.favourite": "Muiañ-karet:", "notifications.column_settings.filter_bar.advanced": "Skrammañ an-holl rummadoù", "notifications.column_settings.filter_bar.category": "Barrenn siloù prim", "notifications.column_settings.filter_bar.show_bar": "Diskouezh barrenn siloù", @@ -386,6 +425,7 @@ "notifications.column_settings.update": "Kemmoù :", "notifications.filter.all": "Pep tra", "notifications.filter.boosts": "Skignadennoù", + "notifications.filter.favourites": "Muiañ-karet", "notifications.filter.follows": "Heuliañ", "notifications.filter.mentions": "Menegoù", "notifications.filter.polls": "Disoc'hoù ar sontadegoù", @@ -399,15 +439,28 @@ "notifications_permission_banner.enable": "Lezel kemennoù war ar burev", "notifications_permission_banner.how_to_control": "Evit reseviñ kemennoù pa ne vez ket digoret Mastodon, lezelit kemennoù war ar burev. Gallout a rit kontrollañ peseurt eskemmoù a c'henel kemennoù war ar burev gant ar {icon} nozelenn a-us kentre ma'z int lezelet.", "notifications_permission_banner.title": "Na vankit netra morse", + "onboarding.action.back": "Distreiñ", + "onboarding.actions.back": "Distreiñ", "onboarding.actions.go_to_explore": "See what's trending", "onboarding.actions.go_to_home": "Go to your home feed", + "onboarding.compose.template": "Salud #Mastodon!", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Popular on Mastodon", + "onboarding.profile.display_name": "Anv diskouezet", + "onboarding.profile.display_name_hint": "Hoc'h anv klok pe hoc'h anv fentus…", + "onboarding.profile.note": "Berr-ha-berr", + "onboarding.profile.note_hint": "Gallout a rit @menegiñ tud all pe #hashtagoù…", + "onboarding.profile.save_and_continue": "Enrollañ ha kenderc'hel", + "onboarding.profile.upload_avatar": "Enporzhiañ ur skeudenn profil", + "onboarding.share.message": "Me a zo {username} war #Mastodon! Heuilhit ac'hanon war {url}", + "onboarding.share.title": "Skignañ ho profil", "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", "onboarding.start.skip": "Want to skip right ahead?", + "onboarding.start.title": "Deuet oc'h a-benn!", "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", "onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}", "onboarding.steps.publish_status.body": "Say hello to the world.", + "onboarding.steps.publish_status.title": "Grit hoc'h embannadur kentañ", "onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.", "onboarding.steps.setup_profile.title": "Customize your profile", "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", @@ -415,6 +468,7 @@ "picture_in_picture.restore": "Adlakaat", "poll.closed": "Serret", "poll.refresh": "Azbevaat", + "poll.reveal": "Gwelet an disoc'hoù", "poll.total_people": "{count, plural, one {# den} other {# a zen}}", "poll.total_votes": "{count, plural, one {# votadenn} other {# votadenn}}", "poll.vote": "Mouezhiañ", @@ -433,6 +487,7 @@ "privacy.unlisted.short": "Anlistennet", "privacy_policy.last_updated": "Hizivadenn ziwezhañ {date}", "privacy_policy.title": "Reolennoù Prevezded", + "recommended": "Erbedet", "refresh": "Freskaat", "regeneration_indicator.label": "O kargañ…", "regeneration_indicator.sublabel": "War brientiñ emañ ho red degemer!", @@ -450,6 +505,7 @@ "reply_indicator.cancel": "Nullañ", "report.block": "Stankañ", "report.block_explanation": "Ne vo ket gwelet toudoù ar gont-se ken. Ne welo ket ho toudoù ha ne c'hello ket ho heuliañ ken. Gouzout a raio eo bet stanket ganeoc'h.", + "report.categories.legal": "Lezennel", "report.categories.other": "All", "report.categories.spam": "Spam", "report.categories.violation": "Torret e vez gant an endalc'had unan pe meur a reolenn", @@ -467,6 +523,7 @@ "report.placeholder": "Askelennoù ouzhpenn", "report.reasons.dislike": "Ne blij ket din", "report.reasons.dislike_description": "An dra-se na fell ket deoc'h gwelet", + "report.reasons.legal": "Enep al lezenn eo", "report.reasons.other": "Un abeg all eo", "report.reasons.other_description": "Ar gudenn na glot ket gant ar rummadoù all", "report.reasons.spam": "Spam eo", @@ -482,16 +539,31 @@ "report.thanks.title": "Ne fell ket deoc'h gwelet an dra-se ?", "report.thanks.title_actionable": "Trugarez evit bezañ disklêriet, emaomp o vont da glask pelloc'h.", "report.unfollow": "Diheuliañ @{name}", - "report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached", + "report_notification.attached_statuses": "{count, plural, one {{count} embannadur} other {{count} embannadur}} stag", + "report_notification.categories.legal": "Lezennel", "report_notification.categories.other": "All", "report_notification.categories.spam": "Spam", "report_notification.categories.violation": "Torradur da reolennoù ar servijer", "report_notification.open": "Digeriñ an disklêriadur", "search.placeholder": "Klask", + "search.quick_action.account_search": "Profiloù a glot gant {x}", + "search.quick_action.go_to_account": "Mont d'ar profil {x}", + "search.quick_action.go_to_hashtag": "Mont d'an hashtag {x}", + "search.quick_action.open_url": "Digeriñ an URL e-barzh Mastodon", + "search.quick_action.status_search": "Embannadurioù a glot gant {x}", "search.search_or_paste": "Klask pe pegañ un URL", + "search_popout.full_text_search_disabled_message": "N'eo ket da gaout war {domain}.", + "search_popout.language_code": "Kod yezh ISO", + "search_popout.options": "Dibarzhioù klask", + "search_popout.quick_actions": "Oberoù prim", + "search_popout.recent": "Klaskoù nevesañ", + "search_popout.specific_date": "deiziad resis", + "search_popout.user": "implijer·ez", + "search_results.accounts": "Profiloù", "search_results.all": "Pep tra", - "search_results.hashtags": "Gerioù-klik", + "search_results.hashtags": "Hashtagoù", "search_results.nothing_found": "Disoc'h ebet gant ar gerioù-se", + "search_results.see_all": "Gwelet pep tra", "search_results.statuses": "Toudoù", "search_results.title": "Klask {q}", "server_banner.active_users": "implijerien·ezed oberiant", @@ -513,11 +585,15 @@ "status.edited": "Aozet {date}", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", "status.embed": "Enframmañ", + "status.favourite": "Muiañ-karet", "status.filter": "Silañ ar c'hannad-mañ", "status.filtered": "Silet", + "status.hide": "Kuzhat an embannadur", "status.history.created": "Krouet gant {name} {date}", "status.history.edited": "Kemmet gant {name} {date}", "status.load_more": "Kargañ muioc'h", + "status.media.open": "Klikit evit digeriñ", + "status.media.show": "Klikit evit diskouez", "status.media_hidden": "Media kuzhet", "status.mention": "Menegiñ @{name}", "status.more": "Muioc'h", @@ -592,6 +668,7 @@ "upload_modal.preview_label": "Rakwel ({ratio})", "upload_progress.label": "O pellgargañ...", "upload_progress.processing": "War ober…", + "username.taken": "Tapet eo an anv implijer-mañ dija. Klaskit skrivañ unan all", "video.close": "Serriñ ar video", "video.download": "Pellgargañ ar restr", "video.exit_fullscreen": "Kuitaat ar mod skramm leun", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index ddcbc58cee..2608b91563 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -62,7 +62,7 @@ "account.requested": "Die Genehmigung steht noch aus. Klicke hier, um die Follower-Anfrage zurückzuziehen", "account.requested_follow": "{name} möchte dir folgen", "account.share": "Profil von @{name} teilen", - "account.show_reblogs": "Geteilte Beiträge von @{name} wieder anzeigen", + "account.show_reblogs": "Geteilte Beiträge von @{name} anzeigen", "account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}", "account.unblock": "Blockierung von @{name} aufheben", "account.unblock_domain": "Blockierung von {domain} aufheben", diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index 00cafe260b..e790306e9c 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -2,6 +2,7 @@ "about.blocks": "Servitores moderate", "about.contact": "Contacto:", "about.disclaimer": "Mastodon es software libere, de codice aperte, e un marca de Mastodon gGmbH.", + "about.rules": "Regulas del servitor", "account.account_note_header": "Nota", "account.add_or_remove_from_list": "Adder o remover ab listas", "account.badges.group": "Gruppo", @@ -10,14 +11,43 @@ "account.blocked": "Blocate", "account.copy": "Copiar ligamine a profilo", "account.edit_profile": "Modificar profilo", + "account.endorse": "Evidentiar sur le profilo", + "account.featured_tags.last_status_at": "Ultime message in {date}", + "account.featured_tags.last_status_never": "Necun messages", + "account.follow": "Sequer", + "account.follow_back": "Sequer etiam", + "account.followers": "Sequitores", + "account.following": "Sequente", "account.go_to_profile": "Vader al profilo", + "account.hide_reblogs": "Celar boosts de @{name}", + "account.languages": "Cambiar le linguas subscribite", + "account.link_verified_on": "Le proprietate de iste ligamine esseva verificate le {date}", + "account.locked_info": "Le stato de confidentialitate de iste conto es definite a blocate. Le proprietario revisa manualmente qui pote sequer lo.", + "account.mention": "Mentionar @{name}", "account.moved_to": "{name} indicava que lor nove conto ora es:", + "account.mute": "Silentiar @{name}", + "account.mute_notifications_short": "Silentiar le notificationes", + "account.mute_short": "Silentiar", + "account.muted": "Silentiate", + "account.no_bio": "Nulle description fornite.", + "account.posts": "Messages", + "account.posts_with_replies": "Messages e responsas", "account.share": "Compartir profilo de @{name}", + "account.show_reblogs": "Monstrar responsas de @{name}", "account.unblock": "Disblocar @{name}", + "account.unblock_domain": "Disblocar dominio {domain}", "account.unblock_short": "Disblocar", "account.unendorse": "Non evidentiar sur le profilo", + "account.unmute": "Non plus silentiar @{name}", + "account.unmute_notifications_short": "Non plus silentiar le notificationes", + "account.unmute_short": "Non plus silentiar", "account_note.placeholder": "Clicca pro adder un nota", "admin.dashboard.retention.cohort_size": "Nove usatores", + "admin.impact_report.instance_followers": "Sequitores que nostre usatores poterea perder", + "admin.impact_report.instance_follows": "Sequitores que lor usatores poterea perder", + "alert.rate_limited.message": "Retenta depost {retry_time, time, medium}.", + "alert.unexpected.message": "Ocurreva un error inexpectate.", + "announcement.announcement": "Annuncio", "audio.hide": "Celar audio", "autosuggest_hashtag.per_week": "{count} per septimana", "bundle_column_error.network.title": "Error de rete", @@ -25,99 +55,260 @@ "bundle_column_error.return": "Retornar al initio", "bundle_modal_error.close": "Clauder", "bundle_modal_error.retry": "Tentar novemente", + "closed_registrations_modal.find_another_server": "Trovar altere servitor", "column.about": "A proposito de", "column.blocks": "Usatores blocate", "column.bookmarks": "Marcapaginas", + "column.community": "Chronologia local", + "column.direct": "Mentiones private", "column.directory": "Navigar profilos", + "column.domain_blocks": "Dominios blocate", "column.favourites": "Favoritos", "column.firehose": "Fluxos in directe", "column.home": "Initio", "column.lists": "Listas", + "column.mutes": "Usatores silentiate", "column.notifications": "Notificationes", + "column.public": "Chronologia federate", "column_header.hide_settings": "Celar le parametros", + "column_header.moveLeft_settings": "Mover columna al sinistra", + "column_header.moveRight_settings": "Mover columna al dextra", "column_header.show_settings": "Monstrar le parametros", "column_subheading.settings": "Parametros", "compose.language.change": "Cambiar le lingua", "compose.language.search": "Cercar linguas...", + "compose.published.body": "Message publicate.", "compose.published.open": "Aperir", + "compose.saved.body": "Message salvate.", "compose_form.direct_message_warning_learn_more": "Apprender plus", + "compose_form.lock_disclaimer": "Tu conto non es {locked}. Quicunque pote sequer te pro vider tu messages solo pro sequitores.", + "compose_form.lock_disclaimer.lock": "blocate", "compose_form.poll.add_option": "Adder un option", "compose_form.poll.remove_option": "Remover iste option", + "compose_form.publish": "Publicar", + "compose_form.publish_form": "Nove message", + "compose_form.publish_loud": "{publish}!", + "compose_form.save_changes": "Salvar le cambiamentos", + "compose_form.spoiler.marked": "Remover advertimento de contento", + "compose_form.spoiler.unmarked": "Adder advertimento de contento", + "compose_form.spoiler_placeholder": "Scribe tu advertimento hic", "confirmation_modal.cancel": "Cancellar", + "confirmations.block.confirm": "Blocar", "confirmations.delete.confirm": "Deler", + "confirmations.delete.message": "Es tu secur que tu vole deler iste message?", "confirmations.delete_list.confirm": "Deler", + "confirmations.delete_list.message": "Es tu secur que tu vole deler permanentemente iste lista?", + "confirmations.domain_block.confirm": "Blocar le dominio complete", "confirmations.edit.confirm": "Modificar", "confirmations.logout.confirm": "Clauder le session", + "confirmations.logout.message": "Es tu secur que tu vole clauder le session?", + "confirmations.mute.confirm": "Silentiar", + "confirmations.mute.message": "Es tu secur que tu vole silentiar {name}?", + "confirmations.reply.confirm": "Responder", + "conversation.delete": "Deler conversation", + "conversation.mark_as_read": "Marcar como legite", + "conversation.open": "Vider conversation", + "conversation.with": "Con {names}", "copy_icon_button.copied": "Copiate al area de transferentia", "copypaste.copied": "Copiate", "copypaste.copy_to_clipboard": "Copiar al area de transferentia", + "directory.federated": "Ab le fediverso cognoscite", + "directory.local": "Solmente ab {domain}", + "directory.recently_active": "Recentemente active", "disabled_account_banner.account_settings": "Parametros de conto", + "disabled_account_banner.text": "Tu conto {disabledAccount} es actualmente disactivate.", "dismissable_banner.dismiss": "Dimitter", "emoji_button.activity": "Activitate", "emoji_button.clear": "Rader", "emoji_button.custom": "Personalisate", + "emoji_button.recent": "Frequentemente usate", + "emoji_button.search": "Cercar...", "emoji_button.search_results": "Resultatos de recerca", + "empty_column.account_suspended": "Conto suspendite", + "empty_column.account_timeline": "Nulle messages hic!", "empty_column.account_unavailable": "Profilo non disponibile", + "empty_column.blocks": "Tu non ha blocate alcun usator ancora.", "errors.unexpected_crash.report_issue": "Signalar un defecto", "explore.search_results": "Resultatos de recerca", + "explore.title": "Explorar", "explore.trending_links": "Novas", + "explore.trending_statuses": "Messages", + "explore.trending_tags": "Hashtags", + "filter_modal.added.review_and_configure_title": "Parametros de filtro", + "filter_modal.added.settings_link": "pagina de parametros", + "filter_modal.added.short_explanation": "Iste message esseva addite al sequente categoria de filtros: {title}.", + "filter_modal.added.title": "Filtro addite!", "filter_modal.select_filter.prompt_new": "Nove categoria: {name}", + "filter_modal.select_filter.search": "Cercar o crear", + "filter_modal.select_filter.title": "Filtrar iste message", + "filter_modal.title.status": "Filtrar un message", "firehose.all": "Toto", "firehose.local": "Iste servitor", "firehose.remote": "Altere servitores", "footer.about": "A proposito de", "footer.directory": "Directorio de profilos", + "footer.get_app": "Obtene le application", + "footer.keyboard_shortcuts": "Accessos directe de claviero", "footer.privacy_policy": "Politica de confidentialitate", "footer.source_code": "Vider le codice fonte", "footer.status": "Stato", + "generic.saved": "Salvate", + "getting_started.heading": "Prime passos", + "hashtag.column_header.tag_mode.all": "e {additional}", + "hashtag.column_header.tag_mode.any": "o {additional}", + "hashtag.column_settings.select.no_options_message": "Nulle suggestiones trovate", + "hashtag.column_settings.select.placeholder": "Insere hashtags…", + "hashtag.follow": "Sequer hashtag", + "home.column_settings.show_reblogs": "Monstrar boosts", + "home.column_settings.show_replies": "Monstrar responsas", + "home.hide_announcements": "Celar annuncios", + "home.pending_critical_update.body": "Actualisa tu servitor de Mastodon le plus tosto possibile!", "home.pending_critical_update.link": "Vider actualisationes", + "home.show_announcements": "Monstrar annuncios", + "interaction_modal.no_account_yet": "Non sur Mstodon?", + "interaction_modal.on_another_server": "In un servitor differente", + "interaction_modal.on_this_server": "In iste servitor", + "interaction_modal.title.follow": "Sequer {name}", + "interaction_modal.title.reblog": "Facer boost al message de {name}", + "interaction_modal.title.reply": "Responder al message de {name}", + "keyboard_shortcuts.blocked": "Aperir lista de usatores blocate", + "keyboard_shortcuts.boost": "Facer boost al message", + "keyboard_shortcuts.description": "Description", + "keyboard_shortcuts.enter": "Aperir message", + "keyboard_shortcuts.favourites": "Aperir lista de favoritos", + "keyboard_shortcuts.federated": "Aperir le chronologia federate", + "keyboard_shortcuts.heading": "Accessos directe de claviero", + "keyboard_shortcuts.home": "Aperir le chronologia de initio", + "keyboard_shortcuts.local": "Aperir le chronologia local", + "keyboard_shortcuts.muted": "Aperir lista de usatores silentiate", "keyboard_shortcuts.my_profile": "Aperir tu profilo", + "keyboard_shortcuts.notifications": "Aperir columna de notificationes", + "keyboard_shortcuts.reply": "Responder al message", + "keyboard_shortcuts.spoilers": "Monstrar/celar le campo CW", + "keyboard_shortcuts.toot": "Initiar un nove message", "lightbox.close": "Clauder", "lightbox.next": "Sequente", "lightbox.previous": "Precedente", "link_preview.author": "Per {name}", "lists.account.add": "Adder al lista", + "lists.account.remove": "Remover ab le lista", "lists.delete": "Deler lista", "lists.edit": "Modificar lista", + "lists.edit.submit": "Cambiar titulo", + "lists.exclusive": "Celar iste messages ab le initio", "lists.new.create": "Adder lista", + "lists.new.title_placeholder": "Nove titulo del lista", + "lists.replies_policy.title": "Monstrar responsas a:", "lists.subheading": "Tu listas", "mute_modal.duration": "Duration", "mute_modal.hide_notifications": "Celar notificationes de iste usator?", "navigation_bar.about": "A proposito de", "navigation_bar.advanced_interface": "Aperir in un interfacie web avantiate", "navigation_bar.blocks": "Usatores blocate", + "navigation_bar.bookmarks": "Marcapaginas", + "navigation_bar.community_timeline": "Chronologia local", + "navigation_bar.direct": "Mentiones private", "navigation_bar.discover": "Discoperir", + "navigation_bar.domain_blocks": "Dominios blocate", "navigation_bar.edit_profile": "Modificar profilo", "navigation_bar.favourites": "Favoritos", + "navigation_bar.filters": "Parolas silentiate", "navigation_bar.lists": "Listas", "navigation_bar.logout": "Clauder le session", + "navigation_bar.mutes": "Usatores silentiate", "navigation_bar.preferences": "Preferentias", + "navigation_bar.public_timeline": "Chronologia federate", "navigation_bar.search": "Cercar", "navigation_bar.security": "Securitate", + "notification.update": "{name} modificava un message", + "notifications.clear": "Rader notificationes", "notifications.column_settings.alert": "Notificationes de scriptorio", "notifications.column_settings.filter_bar.advanced": "Monstrar tote le categorias", + "notifications.column_settings.follow": "Nove sequitores:", + "notifications.column_settings.mention": "Mentiones:", + "notifications.column_settings.push": "Notificationes push", "notifications.column_settings.sound": "Reproducer sono", + "notifications.column_settings.status": "Nove messages:", "notifications.filter.all": "Toto", "notifications.filter.favourites": "Favoritos", + "notifications.filter.mentions": "Mentiones", "notifications.grant_permission": "Conceder permission.", "notifications.group": "{count} notificationes", "onboarding.compose.template": "Salute #Mastodon!", "onboarding.profile.save_and_continue": "Salvar e continuar", + "onboarding.share.next_steps": "Sequente passos possibile:", "onboarding.share.title": "Compartir tu profilo", + "onboarding.steps.follow_people.title": "Personalisa tu fluxo de initio", + "onboarding.steps.publish_status.title": "Face tu prime message", + "onboarding.steps.setup_profile.title": "Personalisa tu profilo", "onboarding.steps.share_profile.title": "Compartir tu profilo de Mastodon", + "poll.closed": "Claudite", + "poll.reveal": "Vider le resultatos", + "privacy.change": "Cambiar privacitate del message", + "privacy.private.long": "Visibile solmente pro sequitores", + "privacy.public.long": "Visibile pro totos", + "privacy.public.short": "Public", + "privacy_policy.last_updated": "Ultime actualisation {date}", + "privacy_policy.title": "Politica de confidentialitate", "relative_time.just_now": "ora", "relative_time.today": "hodie", "reply_indicator.cancel": "Cancellar", + "report.block": "Blocar", + "report.categories.other": "Alteres", + "report.category.title_account": "profilo", + "report.category.title_status": "message", + "report.close": "Preste", + "report.mute": "Silentiar", "report.next": "Sequente", "report.placeholder": "Commentos additional", "report.reasons.dislike": "Non me place", + "report_notification.categories.other": "Alteres", "search.quick_action.go_to_account": "Vader al profilo {x}", + "search.quick_action.go_to_hashtag": "Vader al hashtag {x}", + "search.quick_action.open_url": "Aperir URL in Mastodon", + "search_popout.full_text_search_disabled_message": "Non disponibile sur {domain}.", + "search_popout.language_code": "Codice de lingua ISO", + "search_popout.options": "Optiones de recerca", + "search_popout.quick_actions": "Actiones rapide", + "search_popout.recent": "Recercas recente", + "search_popout.user": "usator", "search_results.accounts": "Profilos", + "search_results.hashtags": "Hashtags", "search_results.see_all": "Vider toto", + "search_results.statuses": "Messages", + "server_banner.learn_more": "Apprender plus", + "sign_in_banner.create_account": "Crear un conto", + "sign_in_banner.sign_in": "Initiar le session", + "status.block": "Blocar @{name}", + "status.copy": "Copiar ligamine a message", "status.delete": "Deler", + "status.direct_indicator": "Mention private", + "status.edit": "Modificar", + "status.filter": "Filtrar iste message", + "status.hide": "Celar le message", + "status.history.created": "create per {name} le {date}", + "status.history.edited": "modificate per {name} le {date}", + "status.media.open": "Clicca pro aperir", + "status.media.show": "Clicca pro monstrar", + "status.more": "Plus", + "status.mute_conversation": "Silentiar conversation", + "status.read_more": "Leger plus", "status.share": "Compartir", "status.translate": "Traducer", "status.translated_from_with": "Traducite ab {lang} usante {provider}", "tabs_bar.home": "Initio", - "tabs_bar.notifications": "Notificationes" + "tabs_bar.notifications": "Notificationes", + "timeline_hint.resources.statuses": "Messages ancian", + "trends.trending_now": "Ora in tendentias", + "upload_form.undo": "Deler", + "upload_modal.choose_image": "Seliger un imagine", + "upload_modal.detect_text": "Deteger texto ab un pictura", + "video.close": "Clauder le video", + "video.download": "Discargar le file", + "video.fullscreen": "Schermo plen", + "video.hide": "Celar video", + "video.mute": "Silentiar le sono", + "video.pause": "Pausa", + "video.play": "Reproducer", + "video.unmute": "Non plus silentiar le sono" } diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 3246415759..e7aafe852a 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -32,6 +32,7 @@ "account.featured_tags.last_status_never": "投稿がありません", "account.featured_tags.title": "{name}の注目ハッシュタグ", "account.follow": "フォロー", + "account.follow_back": "フォローバック", "account.followers": "フォロワー", "account.followers.empty": "まだ誰もフォローしていません。", "account.followers_counter": "{counter} フォロワー", @@ -52,6 +53,7 @@ "account.mute_notifications_short": "通知をオフにする", "account.mute_short": "ミュート", "account.muted": "ミュート済み", + "account.mutual": "相互フォロー中", "account.no_bio": "説明が提供されていません。", "account.open_original_page": "元のページを開く", "account.posts": "投稿", @@ -486,7 +488,7 @@ "onboarding.profile.display_name_hint": "フルネーム、あるいは面白い名前など", "onboarding.profile.lead": "あとでいつでも修正できますし、設定画面にはこれ以外のカスタマイズ項目もあります。", "onboarding.profile.note": "自己紹介", - "onboarding.profile.note_hint": "ほかの人に @言及 したり、#ハッシュタグ を付けたりできます", + "onboarding.profile.note_hint": "ほかのユーザーへのメンション (@mention) や、 #ハッシュタグ が使用できます", "onboarding.profile.save_and_continue": "保存して続ける", "onboarding.profile.title": "プロフィールの設定", "onboarding.profile.upload_avatar": "プロフィール画像をアップロード", diff --git a/app/javascript/mastodon/locales/lad.json b/app/javascript/mastodon/locales/lad.json index 2067edcc70..2a911483de 100644 --- a/app/javascript/mastodon/locales/lad.json +++ b/app/javascript/mastodon/locales/lad.json @@ -501,6 +501,7 @@ "onboarding.steps.setup_profile.title": "Personaliza tu profil", "onboarding.steps.share_profile.body": "Informe a tus amigos komo toparte en Mastodon", "onboarding.steps.share_profile.title": "Partaja tu profil de Mastodon", + "password_confirmation.exceeds_maxlength": "La konfirmasyon de kod es demaziado lunga", "password_confirmation.mismatching": "Los dos kodes son desferentes", "picture_in_picture.restore": "Restora", "poll.closed": "Serrado", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 03c6502651..9de043bb20 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -240,7 +240,7 @@ "empty_column.follow_requests": "Bạn chưa có yêu cầu theo dõi nào.", "empty_column.followed_tags": "Bạn chưa theo dõi hashtag nào. Khi bạn theo dõi, chúng sẽ hiện lên ở đây.", "empty_column.hashtag": "Chưa có tút nào dùng hashtag này.", - "empty_column.home": "Trang chính của bạn đang trống! Hãy theo dõi nhiều người hơn để lấp đầy.", + "empty_column.home": "Trang chủ của bạn đang trống! Hãy theo dõi nhiều người hơn để lấp đầy.", "empty_column.list": "Chưa có tút. Khi những người trong danh sách này đăng tút mới, chúng sẽ xuất hiện ở đây.", "empty_column.lists": "Bạn chưa tạo danh sách nào.", "empty_column.mutes": "Bạn chưa ẩn bất kỳ ai.", @@ -336,38 +336,38 @@ "intervals.full.days": "{number, plural, other {# ngày}}", "intervals.full.hours": "{number, plural, other {# giờ}}", "intervals.full.minutes": "{number, plural, other {# phút}}", - "keyboard_shortcuts.back": "trở lại", + "keyboard_shortcuts.back": "quay lại", "keyboard_shortcuts.blocked": "mở danh sách người đã chặn", "keyboard_shortcuts.boost": "đăng lại", - "keyboard_shortcuts.column": "mở các mục", + "keyboard_shortcuts.column": "mở các cột", "keyboard_shortcuts.compose": "mở khung soạn tút", "keyboard_shortcuts.description": "Mô tả", - "keyboard_shortcuts.direct": "mở mục nhắn riêng", + "keyboard_shortcuts.direct": "mở nhắn riêng", "keyboard_shortcuts.down": "di chuyển xuống dưới danh sách", - "keyboard_shortcuts.enter": "viết tút mới", + "keyboard_shortcuts.enter": "mở tút", "keyboard_shortcuts.favourite": "thích tút", "keyboard_shortcuts.favourites": "mở lượt thích", "keyboard_shortcuts.federated": "mở mạng liên hợp", "keyboard_shortcuts.heading": "Danh sách phím tắt", - "keyboard_shortcuts.home": "mở trang chính", + "keyboard_shortcuts.home": "mở trang chủ", "keyboard_shortcuts.hotkey": "Phím tắt", "keyboard_shortcuts.legend": "hiện bảng hướng dẫn này", "keyboard_shortcuts.local": "mở máy chủ của bạn", "keyboard_shortcuts.mention": "nhắc đến ai đó", "keyboard_shortcuts.muted": "mở danh sách người đã ẩn", "keyboard_shortcuts.my_profile": "mở hồ sơ của bạn", - "keyboard_shortcuts.notifications": "mở mục thông báo", + "keyboard_shortcuts.notifications": "mở thông báo", "keyboard_shortcuts.open_media": "mở ảnh hoặc video", - "keyboard_shortcuts.pinned": "mở danh sách tút ghim", - "keyboard_shortcuts.profile": "mở hồ sơ của người viết tút", + "keyboard_shortcuts.pinned": "mở những tút đã ghim", + "keyboard_shortcuts.profile": "mở trang của người đăng tút", "keyboard_shortcuts.reply": "trả lời", "keyboard_shortcuts.requests": "mở danh sách yêu cầu theo dõi", "keyboard_shortcuts.search": "mở tìm kiếm", "keyboard_shortcuts.spoilers": "hiện/ẩn nội dung nhạy cảm", - "keyboard_shortcuts.start": "mở mục \"Dành cho người mới\"", - "keyboard_shortcuts.toggle_hidden": "ẩn/hiện văn bản bên dưới spoil", + "keyboard_shortcuts.start": "mở \"Dành cho người mới\"", + "keyboard_shortcuts.toggle_hidden": "ẩn/hiện nội dung ẩn", "keyboard_shortcuts.toggle_sensitivity": "ẩn/hiện ảnh hoặc video", - "keyboard_shortcuts.toot": "viết tút mới", + "keyboard_shortcuts.toot": "soạn tút mới", "keyboard_shortcuts.unfocus": "đưa con trỏ ra khỏi ô soạn thảo hoặc ô tìm kiếm", "keyboard_shortcuts.up": "di chuyển lên trên danh sách", "lightbox.close": "Đóng", @@ -404,7 +404,7 @@ "navigation_bar.blocks": "Người đã chặn", "navigation_bar.bookmarks": "Đã lưu", "navigation_bar.community_timeline": "Cộng đồng", - "navigation_bar.compose": "Viết tút mới", + "navigation_bar.compose": "Soạn tút mới", "navigation_bar.direct": "Nhắn riêng", "navigation_bar.discover": "Khám phá", "navigation_bar.domain_blocks": "Máy chủ đã ẩn", @@ -436,7 +436,7 @@ "notification.poll": "Cuộc bình chọn đã kết thúc", "notification.reblog": "{name} đăng lại tút của bạn", "notification.status": "{name} đăng tút mới", - "notification.update": "{name} đã viết lại một tút", + "notification.update": "{name} đã sửa tút", "notifications.clear": "Xóa hết thông báo", "notifications.clear_confirmation": "Bạn thật sự muốn xóa vĩnh viễn tất cả thông báo của mình?", "notifications.column_settings.admin.report": "Báo cáo mới:", @@ -477,7 +477,7 @@ "onboarding.action.back": "Quay lại", "onboarding.actions.back": "Quay lại", "onboarding.actions.go_to_explore": "Xem những gì đang thịnh hành", - "onboarding.actions.go_to_home": "Đến trang chính", + "onboarding.actions.go_to_home": "Đến trang chủ", "onboarding.compose.template": "Xin chào #Mastodon!", "onboarding.follows.empty": "Không có kết quả có thể được hiển thị lúc này. Bạn có thể thử sử dụng tính năng tìm kiếm hoặc duyệt qua trang khám phá để tìm những người theo dõi hoặc thử lại sau.", "onboarding.follows.lead": "Bạn quản lý bảng tin của riêng bạn. Bạn càng theo dõi nhiều người, nó sẽ càng sôi động và thú vị. Để bắt đầu, đây là vài gợi ý:", @@ -501,7 +501,7 @@ "onboarding.start.skip": "Muốn bỏ qua luôn?", "onboarding.start.title": "Xong rồi bạn!", "onboarding.steps.follow_people.body": "Theo dõi những người thú vị trên Mastodon.", - "onboarding.steps.follow_people.title": "Cá nhân hóa trang chính", + "onboarding.steps.follow_people.title": "Cá nhân hóa trang chủ", "onboarding.steps.publish_status.body": "Chào cộng đồng bằng lời nói, ảnh hoặc video {emoji}", "onboarding.steps.publish_status.title": "Đăng tút đầu tiên", "onboarding.steps.setup_profile.body": "Tạo sự tương tác bằng một hồ sơ hoàn chỉnh.", @@ -539,7 +539,7 @@ "recommended": "Đề xuất", "refresh": "Làm mới", "regeneration_indicator.label": "Đang tải…", - "regeneration_indicator.sublabel": "Trang chính của bạn đang được cập nhật!", + "regeneration_indicator.sublabel": "Trang chủ của bạn đang được cập nhật!", "relative_time.days": "{number} ngày", "relative_time.full.days": "{number, plural, other {# ngày}}", "relative_time.full.hours": "{number, plural, other {# giờ}}", @@ -591,7 +591,7 @@ "report.thanks.title": "Không muốn xem thứ này?", "report.thanks.title_actionable": "Cảm ơn đã báo cáo, chúng tôi sẽ xem xét kỹ.", "report.unfollow": "Bỏ theo dõi @{name}", - "report.unfollow_explanation": "Bạn đang theo dõi người này. Để không thấy tút của họ trên trang chính nữa, hãy bỏ theo dõi.", + "report.unfollow_explanation": "Bạn đang theo dõi người này. Để không thấy tút của họ trên trang chủ nữa, hãy bỏ theo dõi.", "report_notification.attached_statuses": "{count, plural, other {{count} tút}} đính kèm", "report_notification.categories.legal": "Pháp lý", "report_notification.categories.other": "Khác", @@ -692,7 +692,7 @@ "subscribed_languages.lead": "Chỉ các tút đăng bằng các ngôn ngữ đã chọn mới được xuất hiện trên bảng tin của bạn. Không chọn gì cả để đọc tút đăng bằng mọi ngôn ngữ.", "subscribed_languages.save": "Lưu thay đổi", "subscribed_languages.target": "Đổi ngôn ngữ mong muốn cho {target}", - "tabs_bar.home": "Trang chính", + "tabs_bar.home": "Trang chủ", "tabs_bar.notifications": "Thông báo", "time_remaining.days": "{number, plural, other {# ngày}}", "time_remaining.hours": "{number, plural, other {# giờ}}", diff --git a/config/locales/bg.yml b/config/locales/bg.yml index b06c5404c7..1865aa5fca 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -425,6 +425,7 @@ bg: view: Преглед на блокиране на домейн email_domain_blocks: add_new: Добавяне на ново + allow_registrations_with_approval: Позволяване на регистрации с одобрение attempts_over_week: one: "%{count} опит за изминалата седмица" other: "%{count} опита за регистрация през изминалата седмица" diff --git a/config/locales/br.yml b/config/locales/br.yml index e869374573..8a70a90cfe 100644 --- a/config/locales/br.yml +++ b/config/locales/br.yml @@ -40,8 +40,10 @@ br: change_role: no_role: Roll ebet confirm: Kadarnaat + confirmed: Kadarnaet confirming: O kadarnaat custom: Personelaet + delete: Dilemel ar roadennoù deleted: Dilamet demote: Argilañ disable: Skornañ @@ -61,6 +63,7 @@ br: all: Pep tra local: Lec'hel remote: A-bell + media_attachments: Restroù media stag moderation: active: Oberiant all: Pep tra @@ -68,6 +71,7 @@ br: silenced: Bevennet suspended: Astalet title: Habaskadur + most_recent_activity: Obererezh nevesañ perform_full_suspension: Astalañ promote: Brudañ protocol: Komenad @@ -76,15 +80,19 @@ br: remove_header: Dilemel an talbenn reset: Adderaouekaat reset_password: Adderaouekaat ar ger-tremen + resubscribe: Adkoumanantiñ role: Roll search: Klask + security: Surentez silence: Bevenniñ silenced: Bevennet statuses: Toudoù + subscribe: Koumanantiñ suspend: Astalañ suspended: Astalet title: Kontoù undo_silenced: Dizober ar bevennañ + unsubscribe: Digoumanantiñ username: Anv warn: Diwall web: Web @@ -167,6 +175,7 @@ br: title: Habaskadur purge: Spurjañ title: Kevread + total_storage: Restroù media stag invites: filter: all: Pep tra @@ -265,6 +274,8 @@ br: tags: dashboard: tag_uses_measure: implijoù hollek + not_usable: N'haller ket en implijout + title: Hashtagoù diouzh ar c'hiz title: Luskadoù warning_presets: add_new: Ouzhpenniñ unan nevez @@ -281,6 +292,9 @@ br: new_appeal: actions: none: ur c'hemenn diwall + new_trends: + new_trending_tags: + title: Hashtagoù diouzh ar c'hiz appearance: discovery: Dizoloadur application_mailer: @@ -289,6 +303,8 @@ br: auth: delete_account: Dilemel ar gont delete_account_html: Ma fell deoc'h dilemel ho kont e c'hellit klikañ amañ. Goulennet e vo ganeoc'h kadarnaat an obererezh. + description: + prefix_invited_by_user: Pedet oc'h gant @%{name} da zont e-barzh ar servijer Mastodon-mañ! login: Mont tre logout: Digennaskañ migrate_account_html: Ma fell deoc'h adkas ar gont-mañ war-zu unan all e c'hellit arventenniñ an dra-se amañ. @@ -383,6 +399,10 @@ br: table: uses: Implijoù title: Pediñ tud + media_attachments: + validations: + images_and_video: N'haller stagañ ur video ouzh un embannadur a zo fotoioù gantañ dija + too_many: N'haller ket stagañ muioc'h eget 4 restr migrations: incoming_migrations_html: Evit dilojañ ur gont all da homañ e rankit sevel un alias da gentañ. moderation: @@ -417,13 +437,16 @@ br: next: Da-heul older: Koshoc'h prev: A-raok + polls: + errors: + self_vote: N'hallit ket votiñ en ho sontadegoù deoc'h-c'hwi preferences: other: All posting_defaults: Arventennoù embann dre ziouer relationships: dormant: O kousket followers: Heulier·ezed·ien - following: O heuliañ + following: Koumanantoù invited: Pedet moved: Dilojet mutual: Kenetre @@ -463,6 +486,7 @@ br: account_settings: Arventennoù ar gont development: Diorren edit_profile: Kemmañ ar profil + featured_tags: Hashtagoù pennañ import: Enporzhiañ import_and_export: Enporzhiañ hag ezporzhiañ preferences: Gwellvezioù @@ -475,6 +499,8 @@ br: one: "%{count} skeudenn" other: "%{count} skeudenn" two: "%{count} skeudenn" + pin_errors: + ownership: N'hallit ket spilhennañ embannadurioù ar re all poll: vote: Mouezhiañ show_more: Diskouez muioc'h @@ -483,6 +509,7 @@ br: public: Publik statuses_cleanup: keep_direct: Mirout ar c'hannadoù eeun + keep_media: Derc'hel an embannadurioù gant restroù stag min_age: '1209600': 2 sizhunvezh '2629746': 1 mizvezh @@ -514,6 +541,7 @@ br: subject: Donemat e Mastodoñ title: Degemer mat e bourzh, %{name}! users: + follow_limit_reached: N'hallit ket heulian muioc'h eget %{limit} a zen signed_in_as: 'Aet-tre evel:' verification: verification: Amprouadur diff --git a/config/locales/de.yml b/config/locales/de.yml index e084fdf702..4542871d80 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -425,6 +425,7 @@ de: view: Domain-Sperre ansehen email_domain_blocks: add_new: Neue hinzufügen + allow_registrations_with_approval: Registrierungen mit Genehmigung erlauben attempts_over_week: one: "%{count} Registrierungsversuch in der vergangenen Woche" other: "%{count} Registrierungsversuche in der vergangenen Woche" diff --git a/config/locales/devise.ia.yml b/config/locales/devise.ia.yml index 7b0ec29579..c45994160c 100644 --- a/config/locales/devise.ia.yml +++ b/config/locales/devise.ia.yml @@ -1,6 +1,8 @@ --- ia: devise: + failure: + locked: Tu conto es blocate. mailer: confirmation_instructions: action: Verificar adresse de e-mail @@ -8,6 +10,8 @@ ia: title: Verificar adresse de e-mail email_changed: title: Nove adresse de e-mail + password_change: + title: Contrasigno cambiate reconfirmation_instructions: title: Verificar adresse de e-mail reset_password_instructions: @@ -15,6 +19,8 @@ ia: title: Reinitialisar contrasigno two_factor_disabled: title: 2FA disactivate + two_factor_enabled: + title: 2FA activate registrations: updated: Tu conto ha essite actualisate con successo. unlocks: diff --git a/config/locales/devise.ie.yml b/config/locales/devise.ie.yml index c6468d34c2..05a41147d8 100644 --- a/config/locales/devise.ie.yml +++ b/config/locales/devise.ie.yml @@ -3,6 +3,8 @@ ie: devise: confirmations: confirmed: Tui e-mail adresse ha esset confirmat successosimen. + send_instructions: Pos quelc minutes tu va reciver un e-posta con instructiones pri qualmen confirmar tui adresse electronic. Ples confirmar tui spamiere si tu ne vide li e-posta. + send_paranoid_instructions: Si tui email-adresse existe in nor database, pos quelc minutes tu va reciver un e-posta con instructiones pri qualmen confirmar tui adresse electronic. Ples confirmar tui spamiere si tu ne recivet ti-ci email. failure: already_authenticated: Tu ha ja intrat. inactive: Tui conto ancor ne ha esset activat. @@ -20,6 +22,8 @@ ie: action_with_app: Confirma e retorna a%{app} explanation: Tu ha creat un conto sur %{host} con ti-ci e-posta, quel tu posse activar per un sol clicc. Si it ne esset tu qui creat li conto, ples ignorar ti-ci missage. explanation_when_pending: Tu ha demandat un invitation a %{host} con ti-ci e-posta. Pos confirmation de tui adresse, noi va inspecter tui aplication. Tu posse inloggar por changear detallies o deleter li conto, ma li pluparte del functiones va restar ínusabil til quande tui conto es aprobat. Tui data va esser deletet si tui conto es rejectet, e in ti casu tu ne besona far quelcunc cose. Si it ne esset tu qui creat li conto, ples ignorar ti-ci missage. + extra_html: Ples vider anc li regules del servitor e nor termines de servicie. + subject: 'Mastodon: Instructiones de confirmation por %{instance}' title: Verificar e-posta email_changed: explanation: 'Li e-mail adresse de tui es changeat a:' @@ -33,6 +37,7 @@ ie: title: Passa-parol changeat reconfirmation_instructions: explanation: Confirmar li nov adresse por changeat tui e-posta. + extra: Ples ignorar ti-ci e-posta si li change ne esset efectuat per te. Li adresse electronic por li conto Mastodon ne va changear se si tu ne accesse li ligament in supra. subject: 'Mastodon: E-posta de confirmation por %{instance}' title: Verificar e-posta reset_password_instructions: @@ -43,8 +48,11 @@ ie: title: Reiniciar passa-parol two_factor_disabled: explanation: 2-factor autentication por tui conto ha esset desactivisat. Aperter session nu es possibil solmen per email-adresse e passa-parol. + subject: 'Mastodon: 2-factor autentication desactivat' title: 2FA desvalidat two_factor_enabled: + explanation: 2-factor autentication ha esset activat por tui conto. Un gage generat per li acuplat apli TOTP va esser besonat por intrar. + subject: 'Mastodon: 2-factor autentication activat' title: 2FA permisset two_factor_recovery_codes_changed: explanation: Li anteyan codes de recuperation ha esset ínvalidat, e novis generat. @@ -54,14 +62,20 @@ ie: subject: 'Mastodon: Desserral instructiones' webauthn_credential: added: + explanation: Li sequent clave de securitá ha esset adjuntet a tui conto subject: 'Mastodon: Nov clave de securitá' title: Un nov clave de securitá ha esset adjuntet deleted: + explanation: Li sequent clave de securitá ha esset deletet de tui conto subject: 'Mastodon: Clave de securitá deletet' + title: Un ex tui claves de securitá ha esset deletet webauthn_disabled: + explanation: Autentication per claves de securitá ha esset desactivat por tui conto. Ja on posse intrar solmen con li gage generat per li acuplat apli TOTP. subject: 'Mastodon: Autentication con claves de securitá desactivisat' title: Claves de securitá desactivisat webauthn_enabled: + explanation: Autentication per clave de securitá ha esset activat por tui conto. Ja li clave de securitá posse esser usat por intrar. + subject: 'Mastodon: Autentication per clave de securitá activat' title: Claves de securitá activisat omniauth_callbacks: failure: Ne posset autenticar te de %{kind} pro "%{reason}". @@ -73,12 +87,22 @@ ie: updated: Tui passa-parol ha esset changeat successosimen. Tu nu ha apertet session. updated_not_active: Tui passa-parol ha esset changeat successosimen. registrations: + destroyed: Adío! Tui conto ha esset anullat con successe. Noi espera revider te pos ne long. signed_up: Benevenit! Tu ha successat registrar te. + signed_up_but_inactive: Tu ha registrat te con successe, támen noi ne posset far te intrar pro que tui conto ancor ne ha esset activat. + signed_up_but_locked: Tu ha registrat te con successe, támen noi ne posset far te intrar pro que tui conto es serrat. + signed_up_but_pending: Un missage con un ligament de confirmation ha esset inviat a tui adresse electronic. Pos har cliccat sur li ligament, noi va inspecter tui aplication. Tu va reciver un notification si it es aprobat. + signed_up_but_unconfirmed: Un missage con un ligament de confirmation ha esset inviat a tui adresse electronic. Ples sequer li ligament por activar tui conto, e confirmar tui spamiere si tu ne ha recivet li e-posta. + update_needs_confirmation: Tu ha actualisat tui conto con successe, ma noi deve verificar tui nov adresse electronic. Ples confirmar tui e-postas e sequer li ligament de confirmation por confirmar li nov adresse, e inspecter tui spamiere si tu ne ha recivet li e-posta. updated: Tui conto ha esset actualisat successosimen. sessions: already_signed_out: Exeat successosimen. signed_in: Intrat successosimen. signed_out: Exeat successosimen. + unlocks: + send_instructions: Pos quelc minutes tu va reciver un e-posta con instructiones pri qualmen desserrar tui adresse electronic. Ples confirmar tui spamiere si tu ne vide li e-posta. + send_paranoid_instructions: Si tui conto existe, pos quelc minutes tu va reciver un e-posta con instructiones pri qualmen desserrar it. Ples confirmar tui spamiere si tu ne recive li e-posta. + unlocked: Tui conto ha esset desserrat con successe. Ples intrar por continuar. errors: messages: already_confirmed: esset ja confirmat, ples prova intrar diff --git a/config/locales/doorkeeper.br.yml b/config/locales/doorkeeper.br.yml index 3de6230d4c..7b7f4155bd 100644 --- a/config/locales/doorkeeper.br.yml +++ b/config/locales/doorkeeper.br.yml @@ -102,6 +102,7 @@ br: bookmarks: Sinedoù filters: Siloù lists: Listennoù + media: Restroù media stag mutes: Kuzhet search: Klask statuses: Toudoù diff --git a/config/locales/doorkeeper.ia.yml b/config/locales/doorkeeper.ia.yml index 55f28634a5..ec85df24fc 100644 --- a/config/locales/doorkeeper.ia.yml +++ b/config/locales/doorkeeper.ia.yml @@ -10,6 +10,8 @@ ia: buttons: cancel: Cancellar edit: Modificar + confirmations: + destroy: Es tu secur? edit: title: Modificar application index: @@ -45,11 +47,22 @@ ia: title: accounts: Contos admin/accounts: Gestion de contos + bookmarks: Marcapaginas + conversations: Conversationes favourites: Favoritos lists: Listas notifications: Notificationes push: Notificationes push + search: Cercar + statuses: Messages layouts: admin: nav: applications: Applicationes + oauth2_provider: Fornitor OAuth2 + scopes: + write:accounts: modificar tu profilo + write:favourites: messages favorite + write:lists: crear listas + write:notifications: rader tu notificationes + write:statuses: publicar messages diff --git a/config/locales/doorkeeper.ie.yml b/config/locales/doorkeeper.ie.yml index f49eb1d968..0119f3573f 100644 --- a/config/locales/doorkeeper.ie.yml +++ b/config/locales/doorkeeper.ie.yml @@ -28,7 +28,10 @@ ie: destroy: Es tu cert? edit: title: Modificar aplication + form: + error: Ups! Ples inspecter tui formul por possibil erras help: + native_redirect_uri: Usar %{native_redirect_uri} por local provas redirect_uri: Usar un linea per URI scopes: Separar scopes con intersticies. Lassar blanc por usar li scopes predefinit. index: @@ -57,8 +60,11 @@ ie: error: title: Alquo ha errat new: + prompt_html: "%{client_name}, un aplication de triesim partise, vole permission por accesser tui conto. Si tu ne fide it, ne autorisa it." review_permissions: Inspecter permissiones title: Autorisation besonat + show: + title: Copiar ti-ci code de autorisation e glutinar it al demanda. authorized_applications: buttons: revoke: Revocar @@ -66,6 +72,7 @@ ie: revoke: Es tu cert? index: authorized_at: Autorisat ye %{date} + description_html: Hay aplicationes queles posse accesser tui conto tra li API. Si trova si aplicationes queles tu ne reconosse, o un aplication quel ha conduit se mal, tu posse revocar su accesse. last_used_at: Ultimmen usat ye %{date} never_used: Nequande usat scopes: Permissiones @@ -73,14 +80,25 @@ ie: title: Tui autorisat aplicationes errors: messages: + access_denied: Demanda negat per li proprietario del ressurse o servitor de autorisation. + credential_flow_not_configured: Falliment de flution Resource Owner Pasword Credentials pro ínconfigurat Doorkeeper.configure.resource_owner_from_credentials. invalid_client: Fallit autentification pro ínconosset client, manca de client-autentification, o ne subtenet metode de autentification. + invalid_grant: Li providet autorisation ó es ínvalid, expirat, revocat, ne acorda con li URI de redirection usat in li demanda de autorisation, ó ha esset emisset a un altri client. invalid_redirect_uri: Li uri de redirection includet ne es valid. invalid_request: + missing_param: 'Mancant postulat parametre: %{value}.' + request_not_authorized: Demanda besonant autorisation. Hay un mancant o ínvalid parametre besonat por autorisar li demanda. unknown: Li petition manca un postulat parametre, include un ne apoyat parametre-valore, o es altrimen mal format. + invalid_resource_owner: Sive li credentiales de ressurse-proprietario providet es ínvalid, sive li ressurse-proprietario ne posse esser trovat + invalid_scope: Li scope demandat es ínvalid, ínconosset, o malformat. invalid_token: expired: Li access-clave expirat revoked: Li access-clave esset revocat unknown: Li accesse-clave es ínvalid + resource_owner_authenticator_not_configured: Sercha por Proprietario de Ressurse fallit pro ínconfigurat Doorkeeper.configure.resource_owner_authenticator. + server_error: Li servitor de autorisation incontrat un ínexpectat condition quel impedit it a plenar li demanda. + temporarily_unavailable: Li servitor de autorisation actualmen ne posse tractar li demanda pro un temporari supercargada o mantention del servitor. + unauthorized_client: Li client ne es autorisat a efectuar li demanda con ti-ci metode. unsupported_grant_type: Li tip de autorisation concedet ne es subtenet per li autorisant servitor. unsupported_response_type: Li autorisant servitor ne subtene ti-ci tip de response. flash: @@ -108,6 +126,7 @@ ie: blocks: Bloccas bookmarks: Marcatores conversations: Conversationes + crypto: Incription del cap al fine favourites: Favorites filters: Filtres follow: Seques, silentias e bloccas @@ -144,6 +163,7 @@ ie: admin:write:email_domain_blocks: far actiones de moderation sur bloccas de dominia basat sur e-posta admin:write:ip_blocks: fa moderatori actiones sur bloccas de IP admin:write:reports: far moderatori actiones sur raportes + crypto: usar incription del cap al fine follow: modifica li relationes del conto push: reciver tui pussa-notificationes read: lee omni datas de tui conto @@ -162,6 +182,7 @@ ie: write: modificar li tot data de tui conto write:accounts: modifica tui profile write:blocks: bloccar contos e dominias + write:bookmarks: marcar postas write:conversations: silentiar e deleter conversationes write:favourites: favorit postas write:filters: crea filtres diff --git a/config/locales/et.yml b/config/locales/et.yml index 2d48edc295..806238431d 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -425,6 +425,7 @@ et: view: Vaata domeeniblokeeringut email_domain_blocks: add_new: Lisa uus + allow_registrations_with_approval: Luba kinnitamisega registreerimine attempts_over_week: one: "%{count} katse viimase nädala kestel" other: "%{count} liitumiskatset viimase nädala kestel" diff --git a/config/locales/fr-QC.yml b/config/locales/fr-QC.yml index 00a59463cd..3d85ced151 100644 --- a/config/locales/fr-QC.yml +++ b/config/locales/fr-QC.yml @@ -425,6 +425,7 @@ fr-QC: view: Afficher les blocages de domaines email_domain_blocks: add_new: Ajouter + allow_registrations_with_approval: Autoriser les inscriptions avec approbation attempts_over_week: one: "%{count} tentative au cours de la dernière semaine" other: "%{count} tentatives au cours de la dernière semaine" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 0a6601bbc1..5c6166ddc3 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -425,6 +425,7 @@ fr: view: Afficher les blocages de domaines email_domain_blocks: add_new: Ajouter + allow_registrations_with_approval: Autoriser les inscriptions avec approbation attempts_over_week: one: "%{count} tentative au cours de la dernière semaine" other: "%{count} tentatives au cours de la dernière semaine" diff --git a/config/locales/ia.yml b/config/locales/ia.yml index 795ed8cc94..c4f236881d 100644 --- a/config/locales/ia.yml +++ b/config/locales/ia.yml @@ -1,28 +1,61 @@ --- ia: + about: + contact_missing: Non definite admin: accounts: + are_you_sure: Es tu secur? + by_domain: Dominio + custom: Personalisate delete: Deler datos deleted: Delite + disable_two_factor_authentication: Disactivar 2FA display_name: Nomine visibile + domain: Dominio enabled: Activate location: all: Toto title: Location moderation: disabled: Disactivate + most_recent_activity: Activitate plus recente + most_recent_ip: IP plus recente + public: Public reset: Reinitialisar reset_password: Reinitialisar contrasigno search: Cercar security: Securitate + security_measures: + only_password: Solmente contrasigno + password_and_2fa: Contrasigno e 2FA + statuses: Messages + title: Contos username: Nomine de usator + action_logs: + action_types: + reset_password_user: Reinitialisar contrasigno + announcements: + new: + create: Crear annuncio + title: Nove annuncio + title: Annuncios custom_emojis: + by_domain: Dominio copy: Copiar create_new_category: Crear nove categoria delete: Deler + disable: Disactivar + disabled: Disactivate + dashboard: + active_users: usatores active + new_users: nove usatores + website: Sito web + domain_allows: + add_new: Permitter federation con dominio domain_blocks: confirm_suspension: cancel: Cancellar + domain: Dominio export: Exportar import: Importar email_domain_blocks: @@ -38,9 +71,11 @@ ia: instance_languages_dimension: Linguas principal delivery: unavailable: Non disponibile + empty: Necun dominios trovate. private_comment: Commento private public_comment: Commento public invites: + deactivate_all: Disactivar toto filter: available: Disponibile ip_blocks: @@ -50,6 +85,18 @@ ia: '15778476': 6 menses '2629746': 1 mense '86400': 1 die + new: + title: Crear un nove regula IP + title: Regulas IP + relays: + delete: Deler + disable: Disactivar + disabled: Disactivate + enable: Activar + enabled: Activate + reports: + are_you_sure: Es tu secur? + cancel: Cancellar statuses_cleanup: min_age: '1209600': 2 septimanas diff --git a/config/locales/ie.yml b/config/locales/ie.yml index 638205a7f4..c85e97b51d 100644 --- a/config/locales/ie.yml +++ b/config/locales/ie.yml @@ -288,6 +288,7 @@ ie: update_status_html: "%{name} actualisat posta de %{target}" update_user_role_html: "%{name} changeat li rol %{target}" deleted_account: deletet conto + empty: Null registres trovat. filter_by_action: Filtrar per action filter_by_user: Filtrar per usator title: Jurnale de audit @@ -468,6 +469,9 @@ ie: unsuppress: Restaurar seque-recomandation instances: availability: + description_html: + one: Si liveration al dominia falli por %{count} die sin successe, null provas in plu va esser efectuat til quande un liveration del dominia es recivet. + other: Si liveration al dominia falli por %{count} dies sin successe, null provas in plu va esser efectuat til quande un liveration del dominia es recivet. failure_threshold_reached: Límite de falliment atinget ye %{date}. failures_recorded: one: Fallit prova por %{count} die. @@ -523,6 +527,7 @@ ie: private_comment: Privat comenta public_comment: Public comenta purge: Purgar + purge_description_html: Si tu crede que ti-ci dominia es for linea por sempre, tu posse deleter omni archives de conto e associat data de ti-ci dominia de tui magasinage. Alquant témpor va esser possibilmen besonat. title: Federation total_blocked_by_us: Bloccat de nos total_followed_by_them: Sequet de les @@ -737,6 +742,7 @@ ie: preamble: Customisar li interfacie web de Mastodon. title: Aspecte branding: + preamble: Li reclamage de tui servitor diferentia it de altri servitores in li retage. Ti-ci information posse esser monstrat tra mult ambientes, tales quam li interfacie web de Mastodon, nativ aplicationes, previsiones de ligamentes sur altri web-situs, altri missage-aplicationes, etc. Pro to it es recomendat a mantener li information clar, curt, e concis. title: Marca captcha_enabled: desc_html: To ci usa extern scrites de hCaptcha, quel posse esser ínquietant pro rasones de securitá e privatie. In plu, it posse far li processu de registration mult plu desfacil (particularimen por tis con deshabilitás). Pro ti rasones, ples considerar alternativ mesuras, tales quam registration per aprobation o invitation. @@ -746,6 +752,7 @@ ie: title: Retention de contenete default_noindex: desc_html: Afecta omni usatores qui ne ha changeat ti parametre personalmen + title: Predefinir que usatores ne apari in índexes de serchatores discovery: follow_recommendations: Seque-recomandationes preamble: Exposir interessant contenete es importantissim por incorporar nov usatores qui fórsan conosse nequi che Mastodon. Decider qualmen diferent utensiles de decovrition functiona che vor servitor. @@ -832,12 +839,16 @@ ie: message_html: Li cluster Elasticsearch es ínsalubri (statu rubi), functiones por serchar ne disponibil elasticsearch_health_yellow: message_html: Li cluster Elasticsearch es ínsalubri (statu yelb); investigar li rason vell esser un bon idé + elasticsearch_index_mismatch: + message_html: Índex-mappamentes de Elasticsearch es oldijat. Ples executer tootctl search deploy --only=%{value} elasticsearch_preset: action: Vider li documentation message_html: Tui cluster Elasticsearch have plu quam un node, ma Mastodon ne es configurat por usar les. elasticsearch_preset_single_node: action: Vider li documentation message_html: Tui cluster Elasticsearch have solmen un node, ples configurar ES_PRESET quam single_node_cluster. + elasticsearch_reset_chewy: + message_html: Tui sistema-índex por Elasticsearch ha oldijat pro un change de parametres. Ples executer tootctl search deploy --reset-chewy por actualisar it. elasticsearch_running_check: message_html: Ne posset conexer a Elasticsearch. Ples confirmar que it ha esset executet, o desactivar serchada de plen textu elasticsearch_version_check: @@ -846,6 +857,8 @@ ie: rules_check: action: Gerer regules de servitor message_html: Tu ancor ne ha definit quelcunc regules de servitor. + sidekiq_process_check: + message_html: Null processe Sidekiq executet por li caude %{value}(s). Ples reviser tui configuration Sidekiq software_version_critical_check: action: Vider actualisationes disponibil message_html: Un critical actualisation por Mastodon es disposibil, ples actualisar tam rapidmen possibil. @@ -935,6 +948,7 @@ ie: webhooks: add_new: Adjunter punctu terminal delete: Deleter + description_html: Un webhook possibilisa que Mastodon pussa actual notificationes pri selectet evenimentes a tui propri aplication, por que it mey automaticmen activar reactiones. disable: Desactivisar disabled: Desactivisat edit: Redacter punctu terminal @@ -1409,6 +1423,7 @@ ie: missing_also_known_as: ne es un alias de ti-ci conto move_to_self: ne posse esser li conto actual not_found: ne posset esser trovat + on_cooldown: Tu es in un periode de refrigidation followers_count: Sequitores al témpor de translocation incoming_migrations: Translocant de un conto diferent incoming_migrations_html: Por mover de un altri conto a ti-ci, erstmen tu deve crear un alias de conto. @@ -1483,7 +1498,9 @@ ie: units: billion: B million: M + quadrillion: Q thousand: m + trillion: T otp_authentication: code_hint: Inmetter li code generat de tui aplication de autentication por confirmar description_html: Si tu activisa 2-factor autentication per un aplication de autentication, aperter un session va postular que tu have possession de tui telefon, quel va generar codes por que tu mey inmetter les. @@ -1843,6 +1860,7 @@ ie: error: Un problema evenit durant li deletion de tui clave de securitá. Ples provar denov. success: Tui clave de securitá esset successosimen deletet. invalid_credential: Ínvalid clave de securitá + nickname_hint: Scrir li moc-nómine de tui nov clave de securitá not_enabled: Tu ancor ne ha possibilisat WebAuthn not_supported: Ti-ci navigator ne subtene claves de securitá otp_required: Por usar claves de securitá, ples activisar 2-factor autentication. diff --git a/config/locales/is.yml b/config/locales/is.yml index bf16d877db..7083a226dd 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -425,6 +425,7 @@ is: view: Skoða útilokun á léni email_domain_blocks: add_new: Bæta við nýju + allow_registrations_with_approval: Leyfa skráningar með samþykki attempts_over_week: one: "%{count} tilraun síðustu viku" other: "%{count} tilraunir til nýskráningar í síðustu viku" diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 8682f37eec..97ec886112 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -418,6 +418,7 @@ ja: view: ドメインブロックを表示 email_domain_blocks: add_new: 新規追加 + allow_registrations_with_approval: 承認制での新規登録を可能にする attempts_over_week: other: 先週は%{count}回サインアップが試みられました created_msg: メールドメインブロックに追加しました diff --git a/config/locales/lad.yml b/config/locales/lad.yml index 323ade8ddb..550036b340 100644 --- a/config/locales/lad.yml +++ b/config/locales/lad.yml @@ -421,6 +421,7 @@ lad: view: Ve domeno blokado email_domain_blocks: add_new: Adjustar muevo + allow_registrations_with_approval: Permite enrejistrasyones kon aprovasyon attempts_over_week: one: "\"%{count} prova durante la ultima semana" other: "%{count} provas de enrejistrarse durante la ultima semana" diff --git a/config/locales/nl.yml b/config/locales/nl.yml index b2894e4abb..34769e08ec 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -425,7 +425,7 @@ nl: view: Domeinblokkade bekijken email_domain_blocks: add_new: Nieuwe toevoegen - allow_registrations_with_approval: Inschrijvingen met toestemming toestaan + allow_registrations_with_approval: Inschrijvingen met goedkeuring toestaan attempts_over_week: one: "%{count} registratiepoging tijdens de afgelopen week" other: "%{count} registratiepogingen tijdens de afgelopen week" diff --git a/config/locales/nn.yml b/config/locales/nn.yml index 70cbc27d6d..de23096ed1 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -425,7 +425,7 @@ nn: view: Vis domeneblokkering email_domain_blocks: add_new: Lag ny - allow_registrations_with_approval: Tillat registreringer med godkjenning + allow_registrations_with_approval: Tillat registreringar med godkjenning attempts_over_week: one: "%{count} forsøk i løpet av den siste uken" other: "%{count} forsøk på å opprette konto i løpet av den siste uken" diff --git a/config/locales/simple_form.br.yml b/config/locales/simple_form.br.yml index 09fe1f6d1d..9e8aefad49 100644 --- a/config/locales/simple_form.br.yml +++ b/config/locales/simple_form.br.yml @@ -54,9 +54,11 @@ br: username: Anv whole_word: Ger a-bezh featured_tag: - name: Ger-klik + name: Hashtag invite: comment: Evezhiadenn + invite_request: + text: Perak e fell deoc'h enskrivañ? ip_block: comment: Evezhiadenn ip: IP @@ -66,8 +68,9 @@ br: rule: text: Reolenn tag: - name: Ger-klik + name: Hashtag trendable: Aotren an hashtag-mañ da zont war wel dindan tuadurioù + usable: Aotren an embannadurioù da implijout an hashtag-mañ user: role: Roll user_role: diff --git a/config/locales/simple_form.ie.yml b/config/locales/simple_form.ie.yml index 72797bde5e..dfd0836412 100644 --- a/config/locales/simple_form.ie.yml +++ b/config/locales/simple_form.ie.yml @@ -62,6 +62,7 @@ ie: setting_use_blurhash: Gradientes es basat sur li colores del celat visuales ma obscura omni detallies setting_use_pending_items: Celar nov postas detra un clicc vice rular li témpor-linea automaticmen username: Tu posse usar lítteres, númeres e sublineas + whole_word: Quande li clave-parol o frase es solmen alfanumeric, it va esser aplicat solmen si it egala al tot parol domain_allow: domain: Ti dominia va posser obtener data de ti-ci servitor, e data venient de it va esser tractat e inmagasinat email_domain_block: @@ -82,20 +83,29 @@ ie: content_cache_retention_period: Omni postas e boosts de altri servitores va esser deletet pos li specificat quantitá de dies. Quelc postas fórsan va esser ínrestaurabil. Omni pertinent marcatores, favorites e boosts anc va esser perdit e ínpossibil a restaurar. custom_css: On posse aplicar customisat stiles al web-version de Mastodon. mascot: Substitue li ilustration in li avansat interfacie web. + media_cache_retention_period: Descargat files de media va esser deletet pos li specificat quantitá de dies quande li valore es positiv, e re-descargat sur demanda. peers_api_enabled: Un liste de nómines de dominia queles ti-ci servitor ha incontrat in li fediverse. Ci null data es includet pri ca tu confedera con un cert servitor o ne; it indica solmen que tui servitor conosse it. Usat per servicies colectent general statisticas pri federation. profile_directory: Li profilarium monstra omni usatores volent esser decovribil. + require_invite_text: Quande registrationes besona manual aprobation, fa que li textu "Pro quo tu vole registrar te?" es obligatori vice facultativ site_contact_email: Qualmen on posse contacter te por inquestes legal o de apoy. site_contact_username: Qualmen li gente posse atinger te sur Mastodon. + site_extended_description: Quelcunc information in plu quel posse esser util a visitores e a tui usatores. On posse structurar it con li sintaxe Markdown. site_short_description: Un curt descrition por auxiliar identificar tui servitor. Qui gere it, por qual persones it es? + site_terms: Usar tui propri politica de privatie, o lassar blanc por usar li predefinitiones. Posse esser structurat con li sintaxe Markdown. site_title: Quant persones posse aluder a tui servitor ultra su nómine de dominia. status_page_url: URL de un págine monstrant li statu de ti-ci servitor durant un ruptura de servicie theme: Li dessine quel ínregistrat visitantes e nov usatores vide. thumbnail: Un image de dimensiones circa 2:1 monstrat along tui servitor-information. timeline_preview: Ínregistrat visitantes va posser vider li max recent public postas disponibil che li servitor. + trendable_by_default: Pretersaltar un manual revision de contenete in tendentie. Mem pos to on posse remover índividual pezzes de tendentie. trends: Tendenties monstra quel postas, hashtags e novas es ganiant atention sur tui servitor. trends_as_landing_page: Monstrar populari contenete a ínregistrat visitantes vice un description del servitor. Besona que tendenties es activisat. form_challenge: current_password: Tu nu intra un area secur + imports: + data: File CSV exportat de un altri servitor Mastodon + invite_request: + text: To va auxiliar nos a reviser tui aplication ip_block: comment: Facultativ. Ne obliviar pro quo tu adjuntet ti-ci regul. expires_in: IP-adresses es un ressurse finit, quelcvez partit e transferet de manu a manu. Pro to, un índefinit bloccada de IP ne es recomandat. @@ -109,15 +119,21 @@ ie: text: Descrir un regul o postulation por usatores sur ti-ci servitor. Prova scrir un descrition curt e simplic sessions: otp: 'Intrar li 2-factor code generat del app sur tui portabile o usar un de tui codes de recuperation:' + webauthn: Si it es un clave USB, inserter it con certitá e, si necessi, tappa it. settings: + indexable: Tui págine de profil va posser aparir in sercha-resultates sur Google, Bing, e altres. show_application: Totvez, tu va sempre posser vider quel app ha publicat tui posta. + tag: + name: Tu posse changear solmen li minu/majusculitá del lítteres, por exemple, por far it plu leibil user: + chosen_languages: Quande selectet, solmen postas in ti lingues va esser monstrat in public témpor-lineas role: Permissiones de usator decidet per su rol user_role: color: Color a usar por li rol tra li UI, quam RGB (rubi-verdi-blu) in formate hex highlighted: Va far li rol publicmen visibil name: Public nómine del rol, si li rol va esser monstrat quam signe permissions_as_keys: Usatores con ti-ci rol va haver accesse a... + position: Plu alt roles decide un resolution de conflict in cert situationes. Cert actiones posse esser efectuat solmen a roles con plu bass prioritá webhook: events: Selecter evenimentes a misser template: Composir tui propri carga JSON usant interpolation de variabiles. Lassa blanc por JSON predefinit. @@ -129,6 +145,7 @@ ie: name: Etiquette value: Contenete indexable: Includer public postas in resultates de sercha + show_collections: Monstrar persones queles on seque e sequitores sur profil unlocked: Automaticmen acceptar nov sequitores account_alias: acct: Usator-nómine del anteyan conto @@ -138,6 +155,7 @@ ie: text: Textu prefigurat title: Titul admin_account_action: + include_statuses: Includer raportat postas in li e-posta send_email_notification: Notificar li usator per e-posta text: Admonition customisat type: Action @@ -172,6 +190,7 @@ ie: fields: Campes aditional header: Cap-image honeypot: "%{label} (ne plenar)" + inbox_url: URL del inbuxe de relé irreversible: Lassar cader vice celar locale: Lingue del interfacie max_uses: Max grand númere de usas @@ -181,10 +200,15 @@ ie: password: Passa-parol phrase: Clave-parol o frase setting_advanced_layout: Possibilisar web-interfacie avansat + setting_aggregate_reblogs: Gruppar boosts in témpor-lineas setting_always_send_emails: Sempre misser notificationes de e-posta + setting_auto_play_gif: Reproducter automaticmen animat GIFs + setting_boost_modal: Monstrar dialog de confirmation ante boostar setting_default_language: Lingue in quel postar setting_default_privacy: Privatie de postada setting_default_sensitive: Sempre marcar medie quam sensitiv + setting_delete_modal: Monstrar dialog de confirmation ante deleter un posta + setting_disable_swiping: Desactivar motiones de glissar setting_display_media: Exposition de medie setting_display_media_default: Predefinitiones setting_display_media_hide_all: Celar omno @@ -196,6 +220,7 @@ ie: setting_theme: Tema de situ setting_trends: Monstrar li hodial tendenties setting_unfollow_modal: Monstrar dialog de confirmation ante dessequer alquem + setting_use_blurhash: Monstrar colorosi gradientes por celat medie setting_use_pending_items: Mode lent severity: Severitá sign_in_token_attempt: Code de securitá @@ -219,6 +244,7 @@ ie: closed_registrations_message: Customisat missage quande registration ne disponibil content_cache_retention_period: Periode de retention por cachat contenete custom_css: Custom CSS + mascot: Customisat mascot (hereditat) media_cache_retention_period: Periode de retention por cachat medie peers_api_enabled: Publicar liste de conosset servitores per li API profile_directory: Possibilisar profilarium @@ -293,6 +319,7 @@ ie: position: Prioritá webhook: events: Evenimentes activisat + template: Modelle de carga url: URL de punctu terminal 'no': 'No' not_recommended: Ne recomandat diff --git a/config/locales/sk.yml b/config/locales/sk.yml index cfc5ee7087..89d41b4616 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -548,6 +548,7 @@ sk: delete_html: Vymaž pohoršujúce príspevky mark_as_sensitive_html: Označ médiá pohoršujúcich príspevkov za chúlostivé close_report: 'Označ hlásenie #%{id} za vyriešené' + target_origin: Pôvod nahláseného účtu title: Hlásenia unassign: Odober unknown_action_msg: 'Neznáma akcia: %{action}' @@ -636,6 +637,7 @@ sk: application: Aplikácia back_to_account: Späť na účet batch: + remove_from_report: Vymaž z hlásenia report: Hlásenie deleted: Vymazané favourites: Obľúbené diff --git a/config/locales/sv.yml b/config/locales/sv.yml index f7a6f33a08..9a2bedbdfe 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -425,6 +425,7 @@ sv: view: Visa domänblock email_domain_blocks: add_new: Lägg till ny + allow_registrations_with_approval: Tillåt registreringar med godkännande attempts_over_week: one: "%{count} försök under den senaste veckan" other: "%{count} registreringsförsök under den senaste veckan" diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 85aabe7176..f37132b6eb 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -1217,7 +1217,7 @@ vi: filters: contexts: account: Trang hồ sơ - home: Trang chính và danh sách + home: Trang chủ và danh sách notifications: Thông báo public: Tút công khai thread: Thảo luận @@ -1796,7 +1796,7 @@ vi: edit_profile_action: Cài đặt trang hồ sơ edit_profile_step: Bạn có thể chỉnh sửa trang hồ sơ của mình bằng cách tải lên ảnh đại diện, ảnh bìa, đổi biệt danh và hơn thế nữa. Bạn cũng có thể tự phê duyệt những người theo dõi mới. explanation: Dưới đây là một số mẹo để giúp bạn bắt đầu - final_action: Viết tút mới + final_action: Soạn tút mới final_step: 'Viết tút mới! Ngay cả khi chưa có người theo dõi, người khác vẫn có thể xem tút công khai của bạn trên bảng tin máy chủ và qua hashtag. Hãy giới thiệu bản thân với hashtag #introductions.' full_handle: Tên đầy đủ của bạn full_handle_hint: Đây cũng là địa chỉ được dùng để giao tiếp với tất cả mọi người. diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 61650f8943..3f3057cc05 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -418,6 +418,7 @@ zh-TW: view: 顯示已封鎖網域 email_domain_blocks: add_new: 加入新項目 + allow_registrations_with_approval: 經允許後可註冊 attempts_over_week: other: 上週共有 %{count} 次註冊嘗試 created_msg: 已成功將電子郵件網域加入黑名單 From e827c4692c251e60509d30350660244b403b5760 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 08:26:12 -0500 Subject: [PATCH 095/422] Use Arel `matches` method in CustomEmoji search (#28615) --- app/models/custom_emoji.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb index 550f005d59..1c9b443959 100644 --- a/app/models/custom_emoji.rb +++ b/app/models/custom_emoji.rb @@ -86,7 +86,7 @@ class CustomEmoji < ApplicationRecord end def search(shortcode) - where('"custom_emojis"."shortcode" ILIKE ?', "%#{shortcode}%") + where(arel_table[:shortcode].matches("%#{sanitize_sql_like(shortcode)}%")) end end From c52a593a3071d6a81e5ba00bc49c00f71a2aed6d Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 08:33:45 -0500 Subject: [PATCH 096/422] Remove unused scope `User.emailable` (#28647) --- app/models/user.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/user.rb b/app/models/user.rb index be1e84b49c..55f654137a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -117,7 +117,6 @@ class User < ApplicationRecord scope :active, -> { confirmed.where(arel_table[:current_sign_in_at].gteq(ACTIVE_DURATION.ago)).joins(:account).where(accounts: { suspended_at: nil }) } scope :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) } scope :matches_ip, ->(value) { left_joins(:ips).where('user_ips.ip <<= ?', value).group('users.id') } - scope :emailable, -> { confirmed.enabled.joins(:account).merge(Account.searchable) } before_validation :sanitize_languages before_validation :sanitize_role From 4ccba94489a0bb69b549b3c4356a390a1751854a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 08:35:53 -0500 Subject: [PATCH 097/422] Remove unused `*_silenced_accounts` scopes on Status (#28644) --- app/models/status.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/models/status.rb b/app/models/status.rb index 3faa507000..a498da288a 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -108,8 +108,6 @@ class Status < ApplicationRecord scope :without_reblogs, -> { where(statuses: { reblog_of_id: nil }) } scope :with_public_visibility, -> { where(visibility: :public) } scope :tagged_with, ->(tag_ids) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag_ids }) } - scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced_at: nil }) } - scope :including_silenced_accounts, -> { left_outer_joins(:account).where.not(accounts: { silenced_at: nil }) } scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) } scope :not_domain_blocked_by_account, ->(account) { account.excluded_from_timeline_domains.blank? ? left_outer_joins(:account) : left_outer_joins(:account).where('accounts.domain IS NULL OR accounts.domain NOT IN (?)', account.excluded_from_timeline_domains) } scope :tagged_with_all, lambda { |tag_ids| From 3e7a9266ea0d30960ef9ad537443bb66c64d1bb5 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 08:36:47 -0500 Subject: [PATCH 098/422] Remove unused `EmojiFormatter#count_tag_nesting` method (#28643) --- app/lib/emoji_formatter.rb | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/lib/emoji_formatter.rb b/app/lib/emoji_formatter.rb index 15b98dc57e..2a3683c499 100644 --- a/app/lib/emoji_formatter.rb +++ b/app/lib/emoji_formatter.rb @@ -66,16 +66,6 @@ class EmojiFormatter @emoji_map ||= custom_emojis.each_with_object({}) { |e, h| h[e.shortcode] = [full_asset_url(e.image.url), full_asset_url(e.image.url(:static))] } end - def count_tag_nesting(tag) - if tag[1] == '/' - -1 - elsif tag[-2] == '/' - 0 - else - 1 - end - end - def tag_for_emoji(shortcode, emoji) return content_tag(:span, ":#{shortcode}:", translate: 'no') if raw_shortcode? From cd58e37b25ae42aea55db2ed57c09c1263054fd0 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 08:38:52 -0500 Subject: [PATCH 099/422] Remove unused `DomainBlock#affected_accounts_count` method (#28642) --- app/models/domain_block.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb index f8058324a3..8da099256a 100644 --- a/app/models/domain_block.rb +++ b/app/models/domain_block.rb @@ -85,11 +85,6 @@ class DomainBlock < ApplicationRecord (reject_media || !other_block.reject_media) && (reject_reports || !other_block.reject_reports) end - def affected_accounts_count - scope = suspend? ? accounts.where(suspended_at: created_at) : accounts.where(silenced_at: created_at) - scope.count - end - def public_domain return domain unless obfuscate? From 9322396e58d9a715744d01d48fdb495c8d0e9037 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 08:48:31 -0500 Subject: [PATCH 100/422] Use normalizes to prepare `Account#username` value (#28646) --- app/models/account.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/models/account.rb b/app/models/account.rb index 2145cfcb64..886b29b873 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -108,6 +108,8 @@ class Account < ApplicationRecord validates :shared_inbox_url, absence: true, if: :local?, on: :create validates :followers_url, absence: true, if: :local?, on: :create + normalizes :username, with: ->(username) { username.squish } + scope :remote, -> { where.not(domain: nil) } scope :local, -> { where(domain: nil) } scope :partitioned, -> { order(Arel.sql('row_number() over (partition by domain)')) } @@ -475,7 +477,6 @@ class Account < ApplicationRecord end before_validation :prepare_contents, if: :local? - before_validation :prepare_username, on: :create before_create :generate_keys before_destroy :clean_feed_manager @@ -493,10 +494,6 @@ class Account < ApplicationRecord note&.strip! end - def prepare_username - username&.squish! - end - def generate_keys return unless local? && private_key.blank? && public_key.blank? From 3e43cd095c5e1ad20bbb70d0e8d2cc09fff776f1 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 10:26:14 -0500 Subject: [PATCH 101/422] Remove unused scope `Announcement.without_muted` (#28645) --- app/models/announcement.rb | 1 - spec/models/announcement_spec.rb | 16 ---------------- 2 files changed, 17 deletions(-) diff --git a/app/models/announcement.rb b/app/models/announcement.rb index 00529766a4..cbcaef3daa 100644 --- a/app/models/announcement.rb +++ b/app/models/announcement.rb @@ -20,7 +20,6 @@ class Announcement < ApplicationRecord scope :unpublished, -> { where(published: false) } scope :published, -> { where(published: true) } - scope :without_muted, ->(account) { joins("LEFT OUTER JOIN announcement_mutes ON announcement_mutes.announcement_id = announcements.id AND announcement_mutes.account_id = #{account.id}").where(announcement_mutes: { id: nil }) } scope :chronological, -> { order(coalesced_chronology_timestamps.asc) } scope :reverse_chronological, -> { order(coalesced_chronology_timestamps.desc) } diff --git a/spec/models/announcement_spec.rb b/spec/models/announcement_spec.rb index e37b81a52e..c016a316cd 100644 --- a/spec/models/announcement_spec.rb +++ b/spec/models/announcement_spec.rb @@ -25,22 +25,6 @@ describe Announcement do end end - describe '#without_muted' do - let!(:announcement) { Fabricate(:announcement) } - let(:account) { Fabricate(:account) } - let(:muted_announcement) { Fabricate(:announcement) } - - before do - Fabricate(:announcement_mute, account: account, announcement: muted_announcement) - end - - it 'returns the announcements not muted by the account' do - results = described_class.without_muted(account) - expect(results).to include(announcement) - expect(results).to_not include(muted_announcement) - end - end - context 'with timestamped announcements' do let!(:adam_announcement) { Fabricate(:announcement, starts_at: 100.days.ago, scheduled_at: 10.days.ago, published_at: 10.days.ago, ends_at: 5.days.from_now) } let!(:brenda_announcement) { Fabricate(:announcement, starts_at: 10.days.ago, scheduled_at: 100.days.ago, published_at: 10.days.ago, ends_at: 5.days.from_now) } From e677eb164cfb69c11692ca5cd2072c26ca1d9509 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 10:26:30 -0500 Subject: [PATCH 102/422] Remove unused `Announcement#time_range?` (#28648) --- app/models/announcement.rb | 4 ---- spec/models/announcement_spec.rb | 26 -------------------------- 2 files changed, 30 deletions(-) diff --git a/app/models/announcement.rb b/app/models/announcement.rb index cbcaef3daa..86f7037a56 100644 --- a/app/models/announcement.rb +++ b/app/models/announcement.rb @@ -54,10 +54,6 @@ class Announcement < ApplicationRecord update!(published: false, scheduled_at: nil) end - def time_range? - starts_at? && ends_at? - end - def mentions @mentions ||= Account.from_text(text) end diff --git a/spec/models/announcement_spec.rb b/spec/models/announcement_spec.rb index c016a316cd..612ba8bb0d 100644 --- a/spec/models/announcement_spec.rb +++ b/spec/models/announcement_spec.rb @@ -113,32 +113,6 @@ describe Announcement do end end - describe '#time_range?' do - it 'returns false when starts_at and ends_at are missing' do - record = Fabricate.build(:announcement, starts_at: nil, ends_at: nil) - - expect(record.time_range?).to be(false) - end - - it 'returns false when starts_at is present and ends_at is missing' do - record = Fabricate.build(:announcement, starts_at: 5.days.from_now, ends_at: nil) - - expect(record.time_range?).to be(false) - end - - it 'returns false when starts_at is missing and ends_at is present' do - record = Fabricate.build(:announcement, starts_at: nil, ends_at: 5.days.from_now) - - expect(record.time_range?).to be(false) - end - - it 'returns true when starts_at and ends_at are present' do - record = Fabricate.build(:announcement, starts_at: 5.days.from_now, ends_at: 10.days.from_now) - - expect(record.time_range?).to be(true) - end - end - describe '#reactions' do context 'with announcement_reactions present' do let!(:account) { Fabricate(:account) } From cd4b4d47346b4d874315fc2560f4cb1e0b1cb2a0 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 10:31:13 -0500 Subject: [PATCH 103/422] Replace unused `by_recent_sign_in` scope (#28616) --- app/models/account.rb | 10 +++++++++- app/models/account_filter.rb | 10 +--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/models/account.rb b/app/models/account.rb index 886b29b873..003b41b015 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -131,7 +131,7 @@ class Account < ApplicationRecord scope :discoverable, -> { searchable.without_silenced.where(discoverable: true).joins(:account_stat) } scope :followable_by, ->(account) { joins(arel_table.join(Follow.arel_table, Arel::Nodes::OuterJoin).on(arel_table[:id].eq(Follow.arel_table[:target_account_id]).and(Follow.arel_table[:account_id].eq(account.id))).join_sources).where(Follow.arel_table[:id].eq(nil)).joins(arel_table.join(FollowRequest.arel_table, Arel::Nodes::OuterJoin).on(arel_table[:id].eq(FollowRequest.arel_table[:target_account_id]).and(FollowRequest.arel_table[:account_id].eq(account.id))).join_sources).where(FollowRequest.arel_table[:id].eq(nil)) } scope :by_recent_status, -> { includes(:account_stat).merge(AccountStat.order('last_status_at DESC NULLS LAST')).references(:account_stat) } - scope :by_recent_sign_in, -> { order(Arel.sql('users.current_sign_in_at DESC NULLS LAST')) } + scope :by_recent_activity, -> { left_joins(:user, :account_stat).order(coalesced_activity_timestamps.desc).order(id: :desc) } scope :popular, -> { order('account_stats.followers_count desc') } scope :by_domain_and_subdomains, ->(domain) { where(domain: Instance.by_domain_and_subdomains(domain).select(:domain)) } scope :not_excluded_by_account, ->(account) { where.not(id: account.excluded_from_timeline_account_ids) } @@ -444,6 +444,14 @@ class Account < ApplicationRecord DeliveryFailureTracker.without_unavailable(urls) end + def coalesced_activity_timestamps + Arel.sql( + <<~SQL.squish + COALESCE(users.current_sign_in_at, account_stats.last_status_at, to_timestamp(0)) + SQL + ) + end + def from_text(text) return [] if text.blank? diff --git a/app/models/account_filter.rb b/app/models/account_filter.rb index 55d34e85c3..42b1c49538 100644 --- a/app/models/account_filter.rb +++ b/app/models/account_filter.rb @@ -104,15 +104,7 @@ class AccountFilter def order_scope(value) case value.to_s when 'active' - accounts_with_users - .left_joins(:account_stat) - .order( - Arel.sql( - <<~SQL.squish - COALESCE(users.current_sign_in_at, account_stats.last_status_at, to_timestamp(0)) DESC, accounts.id DESC - SQL - ) - ) + Account.by_recent_activity when 'recent' Account.recent else From 557c27e03b8a646644d1b1878d45d60931ace5a3 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 8 Jan 2024 11:43:38 -0500 Subject: [PATCH 104/422] Update haml_lint to version 0.53.0 (#28652) --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e694dce0fb..442022e81a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -336,8 +336,8 @@ GEM activesupport (>= 5.1) haml (>= 4.0.6) railties (>= 5.1) - haml_lint (0.52.0) - haml (>= 4.0) + haml_lint (0.53.0) + haml (>= 5.0) parallel (~> 1.10) rainbow rubocop (>= 1.0) From f7b61959cf932de6d1c0317b5b46a4b0a34a6b22 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 09:05:16 +0100 Subject: [PATCH 105/422] Update babel monorepo to v7.23.8 (#28656) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/yarn.lock b/yarn.lock index bec7709804..7bf70258be 100644 --- a/yarn.lock +++ b/yarn.lock @@ -746,22 +746,21 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.23.5": - version: 7.23.5 - resolution: "@babel/plugin-transform-classes@npm:7.23.5" +"@babel/plugin-transform-classes@npm:^7.23.8": + version: 7.23.8 + resolution: "@babel/plugin-transform-classes@npm:7.23.8" dependencies: "@babel/helper-annotate-as-pure": "npm:^7.22.5" - "@babel/helper-compilation-targets": "npm:^7.22.15" + "@babel/helper-compilation-targets": "npm:^7.23.6" "@babel/helper-environment-visitor": "npm:^7.22.20" "@babel/helper-function-name": "npm:^7.23.0" - "@babel/helper-optimise-call-expression": "npm:^7.22.5" "@babel/helper-plugin-utils": "npm:^7.22.5" "@babel/helper-replace-supers": "npm:^7.22.20" "@babel/helper-split-export-declaration": "npm:^7.22.6" globals: "npm:^11.1.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 07988f52b4893151887d1ea6ff79e5fe834078c5731bd09babd5659edbbae21ea4e2de326a02443a63fd776b4c945da6177f07875b56fe66e0b7899e830a9e92 + checksum: 227ac5166501e04d9e7fbd5eda6869b084ffa4af6830ac12544ac6ea14953ca00eb1762b0df9349c0f6c8d2a799385910f558066cd0fb85b9ca437b1131a6043 languageName: node linkType: hard @@ -1345,8 +1344,8 @@ __metadata: linkType: hard "@babel/preset-env@npm:^7.11.0, @babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.22.4": - version: 7.23.7 - resolution: "@babel/preset-env@npm:7.23.7" + version: 7.23.8 + resolution: "@babel/preset-env@npm:7.23.8" dependencies: "@babel/compat-data": "npm:^7.23.5" "@babel/helper-compilation-targets": "npm:^7.23.6" @@ -1381,7 +1380,7 @@ __metadata: "@babel/plugin-transform-block-scoping": "npm:^7.23.4" "@babel/plugin-transform-class-properties": "npm:^7.23.3" "@babel/plugin-transform-class-static-block": "npm:^7.23.4" - "@babel/plugin-transform-classes": "npm:^7.23.5" + "@babel/plugin-transform-classes": "npm:^7.23.8" "@babel/plugin-transform-computed-properties": "npm:^7.23.3" "@babel/plugin-transform-destructuring": "npm:^7.23.3" "@babel/plugin-transform-dotall-regex": "npm:^7.23.3" @@ -1430,7 +1429,7 @@ __metadata: semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: ac9def873cec52ee02a550bde6e22eced16d1ae331bb8ebc82c03e4c91c12ac17e3e4027647e61612937bcc25ac46e71370aaf99dc2e85dbd11f7777ffeed54e + checksum: e602ad954645f1a509644e3d2c72b3c63bdc2273c377e7a83b78f076eca215887ea3624ffc36aaad03deb9ac8acd89e247fd4562b96e0f2b679485e20d8ff25f languageName: node linkType: hard @@ -1495,11 +1494,11 @@ __metadata: linkType: hard "@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.22.3, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": - version: 7.23.7 - resolution: "@babel/runtime@npm:7.23.7" + version: 7.23.8 + resolution: "@babel/runtime@npm:7.23.8" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 3e304133ee55b0750e03e53cb4efb47fb2bdcdb5795f85bbffa10595196c34b9be60eb65bd6d833c87f49fc827f0365f86f95f51d85b188004d3128bb5129c93 + checksum: ba5e8fbb32ef04f6cab5e89c54a0497c2fde7b730595cc1af93496270314f13ff2c6a9360fdb2f0bdd4d6b376752ce3cf85642bd6b876969a6a62954934c2df8 languageName: node linkType: hard @@ -13121,17 +13120,7 @@ __metadata: languageName: node linkType: hard -"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.13, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4": - version: 6.0.13 - resolution: "postcss-selector-parser@npm:6.0.13" - dependencies: - cssesc: "npm:^3.0.0" - util-deprecate: "npm:^1.0.2" - checksum: 51f099b27f7c7198ea1826470ef0adfa58b3bd3f59b390fda123baa0134880a5fa9720137b6009c4c1373357b144f700b0edac73335d0067422063129371444e - languageName: node - linkType: hard - -"postcss-selector-parser@npm:^6.0.15": +"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.13, postcss-selector-parser@npm:^6.0.15, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4": version: 6.0.15 resolution: "postcss-selector-parser@npm:6.0.15" dependencies: From 8e7d5fe2acf7282b0284f3f598c630e5eb58d0eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 10:30:33 +0100 Subject: [PATCH 106/422] New Crowdin Translations (automated) (#28658) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/fi.json | 10 +++++----- config/locales/fi.yml | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 004898651b..00df0e537a 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -21,7 +21,7 @@ "account.blocked": "Estetty", "account.browse_more_on_origin_server": "Selaile lisää alkuperäisellä palvelimella", "account.cancel_follow_request": "Peruuta seurantapyyntö", - "account.copy": "Kopioi profiililinkki", + "account.copy": "Kopioi linkki profiiliin", "account.direct": "Mainitse @{name} yksityisesti", "account.disable_notifications": "Lopeta ilmoittamasta minulle, kun @{name} julkaisee", "account.domain_blocked": "Verkkotunnus estetty", @@ -53,7 +53,7 @@ "account.mute_notifications_short": "Mykistä ilmoitukset", "account.mute_short": "Mykistä", "account.muted": "Mykistetty", - "account.mutual": "Molemmat", + "account.mutual": "Seuraatte toisianne", "account.no_bio": "Kuvausta ei ole annettu.", "account.open_original_page": "Avaa alkuperäinen sivu", "account.posts": "Julkaisut", @@ -193,7 +193,7 @@ "conversation.mark_as_read": "Merkitse luetuksi", "conversation.open": "Näytä keskustelu", "conversation.with": "{names} kanssa", - "copy_icon_button.copied": "Kopioitiin leikepöydälle", + "copy_icon_button.copied": "Sisältö kopioitiin leikepöydälle", "copypaste.copied": "Kopioitu", "copypaste.copy_to_clipboard": "Kopioi leikepöydälle", "directory.federated": "Koko tunnettu fediversumi", @@ -483,10 +483,10 @@ "onboarding.follows.lead": "Kokoat oman kotisyötteesi itse. Mitä enemmän ihmisiä seuraat, sitä aktiivisempi ja kiinnostavampi syöte on. Nämä profiilit voivat olla alkuun hyvä lähtökohta — voit aina lopettaa niiden seuraamisen myöhemmin!", "onboarding.follows.title": "Mukauta kotisyötettäsi", "onboarding.profile.discoverable": "Aseta profiilini löydettäväksi", - "onboarding.profile.discoverable_hint": "Kun olet määrittänyt itsesi löydettäväksi Mastodonista, julkaisusi voivat näkyä hakutuloksissa ja suosituissa kohteissa ja profiiliasi voidaan ehdottaa käyttäjille, jotka ovat kiinnostuneet samoista aiheista kuin sinä.", + "onboarding.profile.discoverable_hint": "Kun olet määrittänyt itsesi löydettäväksi Mastodonista, julkaisusi voivat näkyä hakutuloksissa ja suosituissa kohteissa. Lisäksi profiiliasi voidaan ehdottaa käyttäjille, jotka ovat kiinnostuneita kanssasi samoista aiheista.", "onboarding.profile.display_name": "Näyttönimi", "onboarding.profile.display_name_hint": "Koko nimesi tai lempinimesi…", - "onboarding.profile.lead": "Voit viimeistellä tämän milloin tahansa asetuksista, jotka tarjoavat vielä enemmän mukautusvalintoja.", + "onboarding.profile.lead": "Voit viimeistellä tämän milloin tahansa asetuksista. Sieltä löydät myös lisää mukautusvaihtoehtoja.", "onboarding.profile.note": "Elämäkerta", "onboarding.profile.note_hint": "Voit @mainita muita käyttäjiä tai #aihetunnisteita…", "onboarding.profile.save_and_continue": "Tallenna ja jatka", diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 93545b6a1b..75052c949d 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -425,6 +425,7 @@ fi: view: Näytä verkkotunnuksen esto email_domain_blocks: add_new: Lisää uusi + allow_registrations_with_approval: Salli rekisteröitymiset hyväksynnällä attempts_over_week: one: "%{count} yritystä viimeisen viikon aikana" other: "%{count} rekisteröitymisyritystä viimeisen viikon aikana" From 68f06f1fd4ef6173c22b61f2ea7ce22b76f85076 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 9 Jan 2024 04:31:32 -0500 Subject: [PATCH 107/422] Fix haml-lint `LineLength` cop for `settings/preferences/notifications/show` (#28655) --- .haml-lint_todo.yml | 5 ++--- .../settings/preferences/notifications/show.html.haml | 8 +++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 29646f28e8..09764c2f30 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,13 +1,13 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2023-12-15 11:02:19 -0500 using Haml-Lint version 0.52.0. +# on 2024-01-08 14:02:57 -0500 using Haml-Lint version 0.53.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of Haml-Lint, may require this file to be generated again. linters: - # Offense count: 11 + # Offense count: 10 LineLength: exclude: - 'app/views/admin/roles/_form.html.haml' @@ -17,5 +17,4 @@ linters: - 'app/views/settings/applications/_fields.html.haml' - 'app/views/settings/imports/index.html.haml' - 'app/views/settings/preferences/appearance/show.html.haml' - - 'app/views/settings/preferences/notifications/show.html.haml' - 'app/views/settings/preferences/other/show.html.haml' diff --git a/app/views/settings/preferences/notifications/show.html.haml b/app/views/settings/preferences/notifications/show.html.haml index 5cc101069c..d9d496c7fa 100644 --- a/app/views/settings/preferences/notifications/show.html.haml +++ b/app/views/settings/preferences/notifications/show.html.haml @@ -33,7 +33,13 @@ - if SoftwareUpdate.check_enabled? && current_user.can?(:view_devops) .fields-group - = ff.input :'notification_emails.software_updates', wrapper: :with_label, label: I18n.t('simple_form.labels.notification_emails.software_updates.label'), collection: %w(none critical patch all), label_method: ->(setting) { I18n.t("simple_form.labels.notification_emails.software_updates.#{setting}") }, include_blank: false, hint: false + = ff.input :'notification_emails.software_updates', + collection: %w(none critical patch all), + hint: false, + include_blank: false, + label_method: ->(setting) { I18n.t("simple_form.labels.notification_emails.software_updates.#{setting}") }, + label: I18n.t('simple_form.labels.notification_emails.software_updates.label'), + wrapper: :with_label %h4= t 'notifications.other_settings' From 5dc634796aba951f6a085e1ed0e1b807e25d7d41 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 9 Jan 2024 04:40:08 -0500 Subject: [PATCH 108/422] Misc coverage improvements re: sidekiq/inline (#28651) --- spec/models/notification_spec.rb | 82 +++++++++++++++++++ .../services/fan_out_on_write_service_spec.rb | 3 + spec/services/remove_status_service_spec.rb | 11 ++- 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index d6e2282022..172d1c65b9 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -58,6 +58,88 @@ RSpec.describe Notification do end end + describe 'Setting account from activity_type' do + context 'when activity_type is a Status' do + it 'sets the notification from_account correctly' do + status = Fabricate(:status) + + notification = Fabricate.build(:notification, activity_type: 'Status', activity: status) + + expect(notification.from_account).to eq(status.account) + end + end + + context 'when activity_type is a Follow' do + it 'sets the notification from_account correctly' do + follow = Fabricate(:follow) + + notification = Fabricate.build(:notification, activity_type: 'Follow', activity: follow) + + expect(notification.from_account).to eq(follow.account) + end + end + + context 'when activity_type is a Favourite' do + it 'sets the notification from_account correctly' do + favourite = Fabricate(:favourite) + + notification = Fabricate.build(:notification, activity_type: 'Favourite', activity: favourite) + + expect(notification.from_account).to eq(favourite.account) + end + end + + context 'when activity_type is a FollowRequest' do + it 'sets the notification from_account correctly' do + follow_request = Fabricate(:follow_request) + + notification = Fabricate.build(:notification, activity_type: 'FollowRequest', activity: follow_request) + + expect(notification.from_account).to eq(follow_request.account) + end + end + + context 'when activity_type is a Poll' do + it 'sets the notification from_account correctly' do + poll = Fabricate(:poll) + + notification = Fabricate.build(:notification, activity_type: 'Poll', activity: poll) + + expect(notification.from_account).to eq(poll.account) + end + end + + context 'when activity_type is a Report' do + it 'sets the notification from_account correctly' do + report = Fabricate(:report) + + notification = Fabricate.build(:notification, activity_type: 'Report', activity: report) + + expect(notification.from_account).to eq(report.account) + end + end + + context 'when activity_type is a Mention' do + it 'sets the notification from_account correctly' do + mention = Fabricate(:mention) + + notification = Fabricate.build(:notification, activity_type: 'Mention', activity: mention) + + expect(notification.from_account).to eq(mention.status.account) + end + end + + context 'when activity_type is an Account' do + it 'sets the notification from_account correctly' do + account = Fabricate(:account) + + notification = Fabricate.build(:notification, activity_type: 'Account', account: account) + + expect(notification.account).to eq(account) + end + end + end + describe '.preload_cache_collection_target_statuses' do subject do described_class.preload_cache_collection_target_statuses(notifications) do |target_statuses| diff --git a/spec/services/fan_out_on_write_service_spec.rb b/spec/services/fan_out_on_write_service_spec.rb index f657f298de..6ad041193b 100644 --- a/spec/services/fan_out_on_write_service_spec.rb +++ b/spec/services/fan_out_on_write_service_spec.rb @@ -20,6 +20,8 @@ RSpec.describe FanOutOnWriteService, type: :service do ProcessMentionsService.new.call(status) ProcessHashtagsService.new.call(status) + Fabricate(:media_attachment, status: status, account: alice) + allow(redis).to receive(:publish) subject.call(status) @@ -49,6 +51,7 @@ RSpec.describe FanOutOnWriteService, type: :service do it 'is broadcast to the public stream' do expect(redis).to have_received(:publish).with('timeline:public', anything) expect(redis).to have_received(:publish).with('timeline:public:local', anything) + expect(redis).to have_received(:publish).with('timeline:public:media', anything) end end diff --git a/spec/services/remove_status_service_spec.rb b/spec/services/remove_status_service_spec.rb index 08ce0b0456..cd3224e028 100644 --- a/spec/services/remove_status_service_spec.rb +++ b/spec/services/remove_status_service_spec.rb @@ -20,7 +20,8 @@ RSpec.describe RemoveStatusService, type: :service do end context 'when removed status is not a reblog' do - let!(:status) { PostStatusService.new.call(alice, text: "Hello @#{bob.pretty_acct} ThisIsASecret") } + let!(:media_attachment) { Fabricate(:media_attachment, account: alice) } + let!(:status) { PostStatusService.new.call(alice, text: "Hello @#{bob.pretty_acct} ThisIsASecret", media_ids: [media_attachment.id]) } before do FavouriteService.new.call(jeff, status) @@ -37,6 +38,14 @@ RSpec.describe RemoveStatusService, type: :service do expect(HomeFeed.new(jeff).get(10).pluck(:id)).to_not include(status.id) end + it 'publishes to public media timeline' do + allow(redis).to receive(:publish).with(any_args) + + subject.call(status) + + expect(redis).to have_received(:publish).with('timeline:public:media', Oj.dump(event: :delete, payload: status.id.to_s)) + end + it 'sends Delete activity to followers' do subject.call(status) expect(a_request(:post, hank.inbox_url).with( From 173953c23e8a988679e48e098e825af5be374bbe Mon Sep 17 00:00:00 2001 From: gunchleoc Date: Tue, 9 Jan 2024 11:56:13 +0100 Subject: [PATCH 109/422] Fix ISO code for Canadian French (#26015) Co-authored-by: Claire --- app/helpers/languages_helper.rb | 2 +- .../locales/{fr-QC.json => fr-CA.json} | 0 config/initializers/i18n.rb | 2 +- ...ecord.fr-QC.yml => activerecord.fr-CA.yml} | 2 +- .../{devise.fr-QC.yml => devise.fr-CA.yml} | 2 +- ...rkeeper.fr-QC.yml => doorkeeper.fr-CA.yml} | 2 +- config/locales/{fr-QC.yml => fr-CA.yml} | 2 +- ...e_form.fr-QC.yml => simple_form.fr-CA.yml} | 2 +- ...240109103012_fix_canadian_french_locale.rb | 21 +++++++++++++++++++ db/schema.rb | 2 +- lib/tasks/tests.rake | 13 +++++++++++- 11 files changed, 41 insertions(+), 9 deletions(-) rename app/javascript/mastodon/locales/{fr-QC.json => fr-CA.json} (100%) rename config/locales/{activerecord.fr-QC.yml => activerecord.fr-CA.yml} (99%) rename config/locales/{devise.fr-QC.yml => devise.fr-CA.yml} (99%) rename config/locales/{doorkeeper.fr-QC.yml => doorkeeper.fr-CA.yml} (99%) rename config/locales/{fr-QC.yml => fr-CA.yml} (99%) rename config/locales/{simple_form.fr-QC.yml => simple_form.fr-CA.yml} (99%) create mode 100644 db/migrate/20240109103012_fix_canadian_french_locale.rb diff --git a/app/helpers/languages_helper.rb b/app/helpers/languages_helper.rb index 0d4edceb7b..87f0f288d3 100644 --- a/app/helpers/languages_helper.rb +++ b/app/helpers/languages_helper.rb @@ -224,7 +224,7 @@ module LanguagesHelper 'en-GB': 'English (British)', 'es-AR': 'Español (Argentina)', 'es-MX': 'Español (México)', - 'fr-QC': 'Français (Canadien)', + 'fr-CA': 'Français (Canadien)', 'pt-BR': 'Português (Brasil)', 'pt-PT': 'Português (Portugal)', 'sr-Latn': 'Srpski (latinica)', diff --git a/app/javascript/mastodon/locales/fr-QC.json b/app/javascript/mastodon/locales/fr-CA.json similarity index 100% rename from app/javascript/mastodon/locales/fr-QC.json rename to app/javascript/mastodon/locales/fr-CA.json diff --git a/config/initializers/i18n.rb b/config/initializers/i18n.rb index 39b7a3cc40..1c1cea1b94 100644 --- a/config/initializers/i18n.rb +++ b/config/initializers/i18n.rb @@ -31,7 +31,7 @@ Rails.application.configure do :fi, :fo, :fr, - :'fr-QC', + :'fr-CA', :fy, :ga, :gd, diff --git a/config/locales/activerecord.fr-QC.yml b/config/locales/activerecord.fr-CA.yml similarity index 99% rename from config/locales/activerecord.fr-QC.yml rename to config/locales/activerecord.fr-CA.yml index 607758add6..1a83a0e9e2 100644 --- a/config/locales/activerecord.fr-QC.yml +++ b/config/locales/activerecord.fr-CA.yml @@ -1,5 +1,5 @@ --- -fr-QC: +fr-CA: activerecord: attributes: poll: diff --git a/config/locales/devise.fr-QC.yml b/config/locales/devise.fr-CA.yml similarity index 99% rename from config/locales/devise.fr-QC.yml rename to config/locales/devise.fr-CA.yml index 8c1a94dab6..4c69360024 100644 --- a/config/locales/devise.fr-QC.yml +++ b/config/locales/devise.fr-CA.yml @@ -1,5 +1,5 @@ --- -fr-QC: +fr-CA: devise: confirmations: confirmed: Votre adresse de courriel a été validée avec succès. diff --git a/config/locales/doorkeeper.fr-QC.yml b/config/locales/doorkeeper.fr-CA.yml similarity index 99% rename from config/locales/doorkeeper.fr-QC.yml rename to config/locales/doorkeeper.fr-CA.yml index 043b4a6cda..9d671569f5 100644 --- a/config/locales/doorkeeper.fr-QC.yml +++ b/config/locales/doorkeeper.fr-CA.yml @@ -1,5 +1,5 @@ --- -fr-QC: +fr-CA: activerecord: attributes: doorkeeper/application: diff --git a/config/locales/fr-QC.yml b/config/locales/fr-CA.yml similarity index 99% rename from config/locales/fr-QC.yml rename to config/locales/fr-CA.yml index 3d85ced151..c43fa013c7 100644 --- a/config/locales/fr-QC.yml +++ b/config/locales/fr-CA.yml @@ -1,5 +1,5 @@ --- -fr-QC: +fr-CA: about: about_mastodon_html: 'Le réseau social de l''avenir : pas de publicité, pas de surveillance institutionnelle, conception éthique et décentralisation ! Gardez le contrôle de vos données avec Mastodon !' contact_missing: Non défini diff --git a/config/locales/simple_form.fr-QC.yml b/config/locales/simple_form.fr-CA.yml similarity index 99% rename from config/locales/simple_form.fr-QC.yml rename to config/locales/simple_form.fr-CA.yml index 7a95a1c882..f5a2a428e9 100644 --- a/config/locales/simple_form.fr-QC.yml +++ b/config/locales/simple_form.fr-CA.yml @@ -1,5 +1,5 @@ --- -fr-QC: +fr-CA: simple_form: hints: account: diff --git a/db/migrate/20240109103012_fix_canadian_french_locale.rb b/db/migrate/20240109103012_fix_canadian_french_locale.rb new file mode 100644 index 0000000000..1b8ef7a4af --- /dev/null +++ b/db/migrate/20240109103012_fix_canadian_french_locale.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class FixCanadianFrenchLocale < ActiveRecord::Migration[7.0] + class User < ApplicationRecord + # Dummy class, to make migration possible across version changes + end + + disable_ddl_transaction! + + def up + User.where(locale: 'fr-QC').in_batches do |users| + users.update_all(locale: 'fr-CA') + end + end + + def down + User.where(locale: 'fr-CA').in_batches do |users| + users.update_all(locale: 'fr-QC') + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4ea9744f40..cbe54c1db7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2023_12_22_100226) do +ActiveRecord::Schema[7.1].define(version: 2024_01_09_103012) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" diff --git a/lib/tasks/tests.rake b/lib/tasks/tests.rake index 209a73efa5..c3a9dbfd73 100644 --- a/lib/tasks/tests.rake +++ b/lib/tasks/tests.rake @@ -83,6 +83,11 @@ namespace :tests do puts 'Default posting language not migrated as expected for kmr users' exit(1) end + + unless Account.find_local('qcuser').user.locale == 'fr-CA' + puts 'Locale for fr-QC users not updated to fr-CA as expected' + exit(1) + end end desc 'Populate the database with test data for 2.4.3' @@ -142,13 +147,19 @@ namespace :tests do INSERT INTO "accounts" (id, username, domain, private_key, public_key, created_at, updated_at) VALUES - (10, 'kmruser', NULL, #{user_private_key}, #{user_public_key}, now(), now()); + (10, 'kmruser', NULL, #{user_private_key}, #{user_public_key}, now(), now()), + (11, 'qcuser', NULL, #{user_private_key}, #{user_public_key}, now(), now()); INSERT INTO "users" (id, account_id, email, created_at, updated_at, admin, locale, chosen_languages) VALUES (4, 10, 'kmruser@localhost', now(), now(), false, 'ku', '{en,kmr,ku,ckb}'); + INSERT INTO "users" + (id, account_id, email, created_at, updated_at, locale) + VALUES + (5, 11, 'qcuser@localhost', now(), now(), 'fr-QC'); + INSERT INTO "settings" (id, thing_type, thing_id, var, value, created_at, updated_at) VALUES From 01ca84e5418183af477a1a8317f367f46113657e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 12:48:19 +0100 Subject: [PATCH 110/422] New Crowdin Translations (automated) (#28660) Co-authored-by: GitHub Actions --- config/locales/devise.fr-CA.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/devise.fr-CA.yml b/config/locales/devise.fr-CA.yml index 4c69360024..e9f09a6980 100644 --- a/config/locales/devise.fr-CA.yml +++ b/config/locales/devise.fr-CA.yml @@ -20,8 +20,8 @@ fr-CA: confirmation_instructions: action: Vérifier l’adresse courriel action_with_app: Confirmer et retourner à %{app} - explanation: Vous avez créé un compte sur %{host} avec cette adresse courriel. Vous êtes à un clic de l’activer. Si ce n'était pas vous, veuiller ignorer ce courriel. - explanation_when_pending: Vous avez demandé à vous inscrire à %{host} avec cette adresse courriel. Une fois que vous aurez confirmé cette adresse, nous étudierons votre demande. Vous pouvez vous connecter pour changer vos détails ou supprimer votre compte, mais vous ne pouvez pas accéder à la plupart des fonctionalités du compte avant que votre compte ne soit approuvé. Si votre demande est rejetée, vos données seront supprimées, donc aucune action supplémentaire ne sera requise de votre part. Si ce n'était pas vous, veuiller ignorer ce courriel. + explanation: Vous avez créé un compte sur %{host} avec cette adresse courriel. Vous êtes à un clic de l’activer. Si ce n'était pas vous, veuillez ignorer ce courriel. + explanation_when_pending: Vous avez demandé à vous inscrire à %{host} avec cette adresse courriel. Une fois que vous aurez confirmé cette adresse, nous étudierons votre demande. Vous pouvez vous connecter pour changer vos détails ou supprimer votre compte, mais vous ne pouvez pas accéder à la plupart des fonctionnalités du compte avant que votre compte ne soit approuvé. Si votre demande est rejetée, vos données seront supprimées, donc aucune action supplémentaire ne sera requise de votre part. Si ce n'était pas vous, veuillez ignorer ce courriel. extra_html: Veuillez également consulter les règles du serveur et nos conditions d’utilisation. subject: 'Mastodon: Instructions de confirmation pour %{instance}' title: Vérifier l’adresse courriel From 17818498847c934a9a29f664c1e8fd0472061b38 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 9 Jan 2024 12:50:21 +0100 Subject: [PATCH 111/422] Inline what remains of the rails-settings-cached gem (#28618) Co-authored-by: Claire --- Gemfile | 1 - Gemfile.lock | 9 -- app/models/setting.rb | 153 +++++++++++++++++++------- spec/models/setting_spec.rb | 208 ++++++++---------------------------- 4 files changed, 157 insertions(+), 214 deletions(-) diff --git a/Gemfile b/Gemfile index a56702fad2..e0980c0720 100644 --- a/Gemfile +++ b/Gemfile @@ -75,7 +75,6 @@ gem 'premailer-rails' gem 'rack-attack', '~> 6.6' gem 'rack-cors', '~> 2.0', require: 'rack/cors' gem 'rails-i18n', '~> 7.0' -gem 'rails-settings-cached', '~> 0.6', git: 'https://github.com/mastodon/rails-settings-cached.git', branch: 'v0.6.6-aliases-true' gem 'redcarpet', '~> 3.6' gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis'] gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock' diff --git a/Gemfile.lock b/Gemfile.lock index 442022e81a..50a6412a1d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,14 +18,6 @@ GIT sidekiq (>= 3.5) statsd-ruby (~> 1.4, >= 1.4.0) -GIT - remote: https://github.com/mastodon/rails-settings-cached.git - revision: 86328ef0bd04ce21cc0504ff5e334591e8c2ccab - branch: v0.6.6-aliases-true - specs: - rails-settings-cached (0.6.6) - rails (>= 4.2.0) - GIT remote: https://github.com/stanhu/omniauth-cas.git revision: 4211e6d05941b4a981f9a36b49ec166cecd0e271 @@ -922,7 +914,6 @@ DEPENDENCIES rails (~> 7.1.1) rails-controller-testing (~> 1.0) rails-i18n (~> 7.0) - rails-settings-cached (~> 0.6)! rdf-normalize (~> 0.5) redcarpet (~> 3.6) redis (~> 4.5) diff --git a/app/models/setting.rb b/app/models/setting.rb index 3bdc6ffb40..ecd9d2d737 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -13,49 +13,120 @@ # thing_id :bigint(8) # -class Setting < RailsSettings::Base - source Rails.root.join('config', 'settings.yml') +# This file is derived from a fork of the `rails-settings-cached` gem available at +# https://github.com/mastodon/rails-settings-cached/tree/v0.6.6-aliases-true, with +# the original available at: +# https://github.com/huacnlee/rails-settings-cached/tree/0.x + +# It is licensed as follows: + +# Copyright (c) 2006 Alex Wayne +# Some additional features added 2009 by Georg Ledermann + +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: + +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND +# NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +class Setting < ApplicationRecord + after_commit :rewrite_cache, on: %i(create update) + after_commit :expire_cache, on: %i(destroy) + + # Settings are server-wide settings only, but they were previously + # used for users too. This can be dropped later with a database + # migration dropping any scoped setting. + default_scope { where(thing_type: nil, thing_id: nil) } + + class << self + # get or set a variable with the variable as the called method + # rubocop:disable Style/MissingRespondToMissing + def method_missing(method, *args) + # set a value for a variable + if method.end_with?('=') + var_name = method.to_s.chomp('=') + value = args.first + self[var_name] = value + else + # retrieve a value + self[method.to_s] + end + end + # rubocop:enable Style/MissingRespondToMissing + + def object(var_name) + find_by(var: var_name.to_s) + end + + def cache_prefix_by_startup + @cache_prefix_by_startup ||= Digest::MD5.hexdigest(default_settings.to_s) + end + + def cache_key(var_name) + "rails_settings_cached/#{cache_prefix_by_startup}/#{var_name}" + end + + def [](key) + Rails.cache.fetch(cache_key(key)) do + db_val = object(key) + db_val ? db_val.value : default_settings[key] + end + end + + # set a setting value by [] notation + def []=(var_name, value) + var_name = var_name.to_s + + record = object(var_name) || new(var: var_name) + record.value = value + record.save! + end + + def default_settings + return @default_settings if defined?(@default_settings) + + content = Rails.root.join('config', 'settings.yml').read + hash = content.empty? ? {} : YAML.safe_load(ERB.new(content).result, aliases: true).to_hash + @default_settings = hash[Rails.env] || {} + end + end + + # get the value field, YAML decoded + def value + YAML.safe_load(self[:value], permitted_classes: [ActiveSupport::HashWithIndifferentAccess, Symbol]) if self[:value].present? + end + + # set the value field, YAML encoded + def value=(new_value) + self[:value] = new_value.to_yaml + end + + def rewrite_cache + Rails.cache.write(cache_key, value) + end + + def expire_cache + Rails.cache.delete(cache_key) + end + + def cache_key + self.class.cache_key(var) + end def to_param var end - - class << self - def [](key) - return super(key) unless rails_initialized? - - Rails.cache.fetch(cache_key(key, nil)) do - db_val = object(key) - - if db_val - default_value = default_settings[key] - - return default_value.with_indifferent_access.merge!(db_val.value) if default_value.is_a?(Hash) - - db_val.value - else - default_settings[key] - end - end - end - - def all_as_records - vars = thing_scoped - records = vars.index_by(&:var) - - default_settings.each do |key, default_value| - next if records.key?(key) || default_value.is_a?(Hash) - - records[key] = Setting.new(var: key, value: default_value) - end - - records - end - - def default_settings - return {} unless RailsSettings::Default.enabled? - - RailsSettings::Default.instance - end - end end diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb index e98062810e..ca9c65511d 100644 --- a/spec/models/setting_spec.rb +++ b/spec/models/setting_spec.rb @@ -13,189 +13,71 @@ RSpec.describe Setting do end describe '.[]' do + let(:key) { 'key' } + let(:cache_key) { 'cache-key' } + let(:cache_value) { 'cache-value' } + before do - allow(described_class).to receive(:rails_initialized?).and_return(rails_initialized) + allow(described_class).to receive(:cache_key).with(key).and_return(cache_key) end - let(:key) { 'key' } - - context 'when rails_initialized? is falsey' do - let(:rails_initialized) { false } - - it 'calls RailsSettings::Base#[]' do - allow(RailsSettings::Base).to receive(:[]).with(key) - - described_class[key] - - expect(RailsSettings::Base).to have_received(:[]).with(key) - end - end - - context 'when rails_initialized? is truthy' do + context 'when Rails.cache does not exists' do before do - allow(RailsSettings::Base).to receive(:cache_key).with(key, nil).and_return(cache_key) + allow(described_class).to receive(:object).with(key).and_return(object) + allow(described_class).to receive(:default_settings).and_return(default_settings) + + Fabricate(:setting, var: key, value: nil) + + Rails.cache.delete(cache_key) end - let(:rails_initialized) { true } - let(:cache_key) { 'cache-key' } - let(:cache_value) { 'cache-value' } + let(:object) { nil } + let(:default_value) { 'default_value' } + let(:default_settings) { { key => default_value } } - it 'calls not RailsSettings::Base#[]' do - allow(RailsSettings::Base).to receive(:[]).with(key) + it 'calls Setting.object' do + allow(described_class).to receive(:object).with(key) described_class[key] - expect(RailsSettings::Base).to_not have_received(:[]).with(key) + expect(described_class).to have_received(:object).with(key) end - context 'when Rails.cache does not exists' do - before do - allow(RailsSettings::Settings).to receive(:object).with(key).and_return(object) - allow(described_class).to receive(:default_settings).and_return(default_settings) - settings_double = instance_double(Settings::ScopedSettings, thing_scoped: records) - allow(Settings::ScopedSettings).to receive(:new).and_return(settings_double) - Rails.cache.delete(cache_key) + context 'when Setting.object returns truthy' do + let(:object) { db_val } + let(:db_val) { instance_double(described_class, value: 'db_val') } + let(:default_value) { 'default_value' } + + it 'returns db_val.value' do + expect(described_class[key]).to be db_val.value end + end - let(:object) { nil } - let(:default_value) { 'default_value' } - let(:default_settings) { { key => default_value } } - let(:records) { [Fabricate(:setting, var: key, value: nil)] } + context 'when Setting.object returns falsey' do + let(:object) { nil } - it 'calls RailsSettings::Settings.object' do - allow(RailsSettings::Settings).to receive(:object).with(key) + it 'returns default_settings[key]' do + expect(described_class[key]).to be default_settings[key] + end + end + end + context 'when Rails.cache exists' do + before do + Rails.cache.write(cache_key, cache_value) + end + + it 'does not query the database' do + callback = double + allow(callback).to receive(:call) + ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do described_class[key] - - expect(RailsSettings::Settings).to have_received(:object).with(key) - end - - context 'when RailsSettings::Settings.object returns truthy' do - let(:object) { db_val } - let(:db_val) { instance_double(described_class, value: 'db_val') } - - context 'when default_value is a Hash' do - let(:default_value) { { default_value: 'default_value' } } - - it 'calls default_value.with_indifferent_access.merge!' do - indifferent_hash = instance_double(Hash, merge!: nil) - allow(default_value).to receive(:with_indifferent_access).and_return(indifferent_hash) - - described_class[key] - - expect(default_value).to have_received(:with_indifferent_access) - expect(indifferent_hash).to have_received(:merge!).with(db_val.value) - end - end - - context 'when default_value is not a Hash' do - let(:default_value) { 'default_value' } - - it 'returns db_val.value' do - expect(described_class[key]).to be db_val.value - end - end - end - - context 'when RailsSettings::Settings.object returns falsey' do - let(:object) { nil } - - it 'returns default_settings[key]' do - expect(described_class[key]).to be default_settings[key] - end end + expect(callback).to_not have_received(:call) end - context 'when Rails.cache exists' do - before do - Rails.cache.write(cache_key, cache_value) - end - - it 'does not query the database' do - callback = double - allow(callback).to receive(:call) - ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do - described_class[key] - end - expect(callback).to_not have_received(:call) - end - - it 'returns the cached value' do - expect(described_class[key]).to eq cache_value - end - end - end - end - - describe '.all_as_records' do - before do - settings_double = instance_double(Settings::ScopedSettings, thing_scoped: records) - allow(Settings::ScopedSettings).to receive(:new).and_return(settings_double) - allow(described_class).to receive(:default_settings).and_return(default_settings) - end - - let(:key) { 'key' } - let(:default_value) { 'default_value' } - let(:default_settings) { { key => default_value } } - let(:original_setting) { Fabricate(:setting, var: key, value: nil) } - let(:records) { [original_setting] } - - it 'returns a Hash' do - expect(described_class.all_as_records).to be_a Hash - end - - context 'when records includes Setting with var as the key' do - let(:records) { [original_setting] } - - it 'includes the original Setting' do - setting = described_class.all_as_records[key] - expect(setting).to eq original_setting - end - end - - context 'when records includes nothing' do - let(:records) { [] } - - context 'when default_value is not a Hash' do - it 'includes Setting with value of default_value' do - setting = described_class.all_as_records[key] - - expect(setting).to be_a described_class - expect(setting).to have_attributes(var: key) - expect(setting).to have_attributes(value: 'default_value') - end - end - - context 'when default_value is a Hash' do - let(:default_value) { { 'foo' => 'fuga' } } - - it 'returns {}' do - expect(described_class.all_as_records).to eq({}) - end - end - end - end - - describe '.default_settings' do - subject { described_class.default_settings } - - before do - allow(RailsSettings::Default).to receive(:enabled?).and_return(enabled) - end - - context 'when RailsSettings::Default.enabled? is false' do - let(:enabled) { false } - - it 'returns {}' do - expect(subject).to eq({}) - end - end - - context 'when RailsSettings::Settings.enabled? is true' do - let(:enabled) { true } - - it 'returns instance of RailsSettings::Default' do - expect(subject).to be_a RailsSettings::Default + it 'returns the cached value' do + expect(described_class[key]).to eq cache_value end end end From 1ad908e0c08c236389967d86b4f238f428de9fef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:06:19 +0100 Subject: [PATCH 112/422] Update dependency fog-core to v2.4.0 (#28582) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 50a6412a1d..2d54ac33ed 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -264,7 +264,7 @@ GEM erubi (1.12.0) et-orbi (1.2.7) tzinfo - excon (0.104.0) + excon (0.109.0) fabrication (2.31.0) faker (3.2.2) i18n (>= 1.8.11, < 2) @@ -299,7 +299,7 @@ GEM ffi-compiler (1.0.1) ffi (>= 1.0.0) rake - fog-core (2.3.0) + fog-core (2.4.0) builder excon (~> 0.71) formatador (>= 0.2, < 2.0) From 4e02838832a1b1dec9330c5c70b47529f1db256f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 9 Jan 2024 07:50:57 -0500 Subject: [PATCH 113/422] Enable "low risk" Rails 7.1 setting defaults (#28626) --- .../new_framework_defaults_7_1.rb | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/config/initializers/new_framework_defaults_7_1.rb b/config/initializers/new_framework_defaults_7_1.rb index 1475fe2fd9..bcc300c89f 100644 --- a/config/initializers/new_framework_defaults_7_1.rb +++ b/config/initializers/new_framework_defaults_7_1.rb @@ -29,7 +29,7 @@ Rails.application.config.add_autoload_paths_to_load_path = false # Do not treat an `ActionController::Parameters` instance # as equal to an equivalent `Hash` by default. -# Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality = false +Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality = false # Active Record Encryption now uses SHA-256 as its hash digest algorithm. Important: If you have # data encrypted with previous Rails versions, there are two scenarios to consider: @@ -50,7 +50,7 @@ Rails.application.config.add_autoload_paths_to_load_path = false # Instead, run these callbacks on the instance most likely to have internal # state which matches what was committed to the database, typically the last # instance to save. -# Rails.application.config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false +Rails.application.config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false # Configures SQLite with a strict strings mode, which disables double-quoted string literals. # @@ -59,10 +59,10 @@ Rails.application.config.add_autoload_paths_to_load_path = false # it then considers them as string literals. Because of this, typos can silently go unnoticed. # For example, it is possible to create an index for a non existing column. # See https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted for more details. -# Rails.application.config.active_record.sqlite3_adapter_strict_strings_by_default = true +Rails.application.config.active_record.sqlite3_adapter_strict_strings_by_default = true # Disable deprecated singular associations names -# Rails.application.config.active_record.allow_deprecated_singular_associations_name = false +Rails.application.config.active_record.allow_deprecated_singular_associations_name = false # Enable the Active Job `BigDecimal` argument serializer, which guarantees # roundtripping. Without this serializer, some queue adapters may serialize @@ -78,12 +78,12 @@ Rails.application.config.add_autoload_paths_to_load_path = false # `write` are given an invalid `expires_at` or `expires_in` time. # Options are `true`, and `false`. If `false`, the exception will be reported # as `handled` and logged instead. -# Rails.application.config.active_support.raise_on_invalid_cache_expiration_time = true +Rails.application.config.active_support.raise_on_invalid_cache_expiration_time = true # Specify whether Query Logs will format tags using the SQLCommenter format # (https://open-telemetry.github.io/opentelemetry-sqlcommenter/), or using the legacy format. # Options are `:legacy` and `:sqlcommenter`. -# Rails.application.config.active_record.query_log_tags_format = :sqlcommenter +Rails.application.config.active_record.query_log_tags_format = :sqlcommenter # Specify the default serializer used by `MessageEncryptor` and `MessageVerifier` # instances. @@ -129,39 +129,37 @@ Rails.application.config.add_autoload_paths_to_load_path = false # `config.load_defaults 7.1` does not set this value for environments other than # development and test. # -# if Rails.env.local? -# Rails.application.config.log_file_size = 100 * 1024 * 1024 -# end +Rails.application.config.log_file_size = 100 * 1024 * 1024 if Rails.env.local? # Enable raising on assignment to attr_readonly attributes. The previous # behavior would allow assignment but silently not persist changes to the # database. -# Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true +Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true # Enable validating only parent-related columns for presence when the parent is mandatory. # The previous behavior was to validate the presence of the parent record, which performed an extra query # to get the parent every time the child record was updated, even when parent has not changed. -# Rails.application.config.active_record.belongs_to_required_validates_foreign_key = false +Rails.application.config.active_record.belongs_to_required_validates_foreign_key = false # Enable precompilation of `config.filter_parameters`. Precompilation can # improve filtering performance, depending on the quantity and types of filters. -# Rails.application.config.precompile_filter_parameters = true +Rails.application.config.precompile_filter_parameters = true # Enable before_committed! callbacks on all enrolled records in a transaction. # The previous behavior was to only run the callbacks on the first copy of a record # if there were multiple copies of the same record enrolled in the transaction. -# Rails.application.config.active_record.before_committed_on_all_records = true +Rails.application.config.active_record.before_committed_on_all_records = true # Disable automatic column serialization into YAML. # To keep the historic behavior, you can set it to `YAML`, however it is # recommended to explicitly define the serialization method for each column # rather than to rely on a global default. -# Rails.application.config.active_record.default_column_serializer = nil +Rails.application.config.active_record.default_column_serializer = nil # Run `after_commit` and `after_*_commit` callbacks in the order they are defined in a model. # This matches the behaviour of all other callbacks. # In previous versions of Rails, they ran in the inverse order. -# Rails.application.config.active_record.run_after_transaction_callbacks_in_order_defined = true +Rails.application.config.active_record.run_after_transaction_callbacks_in_order_defined = true # Whether a `transaction` block is committed or rolled back when exited via `return`, `break` or `throw`. # @@ -169,7 +167,7 @@ Rails.application.config.add_autoload_paths_to_load_path = false # Controls when to generate a value for has_secure_token declarations. # -# Rails.application.config.active_record.generate_secure_token_on = :initialize +Rails.application.config.active_record.generate_secure_token_on = :initialize # ** Please read carefully, this must be configured in config/application.rb ** # Change the format of the cache entry. @@ -190,7 +188,7 @@ Rails.application.config.add_autoload_paths_to_load_path = false # # In previous versions of Rails, Action View always used `Rails::HTML4::Sanitizer` as its vendor. # -# Rails.application.config.action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor +Rails.application.config.action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor # Configure Action Text to use an HTML5 standards-compliant sanitizer when it is supported on your # platform. @@ -213,4 +211,4 @@ Rails.application.config.add_autoload_paths_to_load_path = false # # In previous versions of Rails, these test helpers always used an HTML4 parser. # -# Rails.application.config.dom_testing_default_html_version = :html5 +Rails.application.config.dom_testing_default_html_version = :html5 From 10203bd57a13b243b03491f107efbe9566e89ed6 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 9 Jan 2024 15:01:53 +0100 Subject: [PATCH 114/422] Clean up `Setting` model and remove dead code (#28661) --- app/lib/settings/scoped_settings.rb | 79 ----------------------------- app/models/setting.rb | 12 ++--- spec/models/setting_spec.rb | 30 +++++------ 3 files changed, 15 insertions(+), 106 deletions(-) delete mode 100644 app/lib/settings/scoped_settings.rb diff --git a/app/lib/settings/scoped_settings.rb b/app/lib/settings/scoped_settings.rb deleted file mode 100644 index 3ad57cc1ea..0000000000 --- a/app/lib/settings/scoped_settings.rb +++ /dev/null @@ -1,79 +0,0 @@ -# frozen_string_literal: true - -module Settings - class ScopedSettings - DEFAULTING_TO_UNSCOPED = %w( - theme - noindex - ).freeze - - def initialize(object) - @object = object - end - - def method_missing(method, *args) - method_name = method.to_s - # set a value for a variable - if method_name[-1] == '=' - var_name = method_name.sub('=', '') - value = args.first - self[var_name] = value - else - # retrieve a value - self[method_name] - end - end - - def respond_to_missing?(*) - true - end - - def all_as_records - vars = thing_scoped - records = vars.index_by(&:var) - - Setting.default_settings.each do |key, default_value| - next if records.key?(key) || default_value.is_a?(Hash) - - records[key] = Setting.new(var: key, value: default_value) - end - - records - end - - def []=(key, value) - key = key.to_s - record = thing_scoped.find_or_initialize_by(var: key) - record.update!(value: value) - - Rails.cache.write(Setting.cache_key(key, @object), value) - end - - def [](key) - Rails.cache.fetch(Setting.cache_key(key, @object)) do - db_val = thing_scoped.find_by(var: key.to_s) - if db_val - default_value = ScopedSettings.default_settings[key] - return default_value.with_indifferent_access.merge!(db_val.value) if default_value.is_a?(Hash) - - db_val.value - else - ScopedSettings.default_settings[key] - end - end - end - - class << self - def default_settings - defaulting = DEFAULTING_TO_UNSCOPED.index_with { |k| Setting[k] } - Setting.default_settings.merge!(defaulting) - end - end - - protected - - def thing_scoped - Setting.unscoped.where(thing_type: @object.class.base_class.to_s, thing_id: @object.id) - end - end -end diff --git a/app/models/setting.rb b/app/models/setting.rb index ecd9d2d737..6af7a98c6d 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -67,10 +67,6 @@ class Setting < ApplicationRecord end # rubocop:enable Style/MissingRespondToMissing - def object(var_name) - find_by(var: var_name.to_s) - end - def cache_prefix_by_startup @cache_prefix_by_startup ||= Digest::MD5.hexdigest(default_settings.to_s) end @@ -81,16 +77,14 @@ class Setting < ApplicationRecord def [](key) Rails.cache.fetch(cache_key(key)) do - db_val = object(key) + db_val = find_by(var: key) db_val ? db_val.value : default_settings[key] end end # set a setting value by [] notation def []=(var_name, value) - var_name = var_name.to_s - - record = object(var_name) || new(var: var_name) + record = find_or_initialize_by(var: var_name.to_s) record.value = value record.save! end @@ -100,7 +94,7 @@ class Setting < ApplicationRecord content = Rails.root.join('config', 'settings.yml').read hash = content.empty? ? {} : YAML.safe_load(ERB.new(content).result, aliases: true).to_hash - @default_settings = hash[Rails.env] || {} + @default_settings = (hash[Rails.env] || {}).freeze end end diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb index ca9c65511d..a1e24e8350 100644 --- a/spec/models/setting_spec.rb +++ b/spec/models/setting_spec.rb @@ -23,38 +23,32 @@ RSpec.describe Setting do context 'when Rails.cache does not exists' do before do - allow(described_class).to receive(:object).with(key).and_return(object) allow(described_class).to receive(:default_settings).and_return(default_settings) - Fabricate(:setting, var: key, value: nil) + Fabricate(:setting, var: key, value: 42) if save_setting Rails.cache.delete(cache_key) end - let(:object) { nil } let(:default_value) { 'default_value' } let(:default_settings) { { key => default_value } } + let(:save_setting) { true } - it 'calls Setting.object' do - allow(described_class).to receive(:object).with(key) + context 'when the setting has been saved to database' do + it 'returns the value from database' do + callback = double + allow(callback).to receive(:call) - described_class[key] + ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do + expect(described_class[key]).to eq 42 + end - expect(described_class).to have_received(:object).with(key) - end - - context 'when Setting.object returns truthy' do - let(:object) { db_val } - let(:db_val) { instance_double(described_class, value: 'db_val') } - let(:default_value) { 'default_value' } - - it 'returns db_val.value' do - expect(described_class[key]).to be db_val.value + expect(callback).to have_received(:call) end end - context 'when Setting.object returns falsey' do - let(:object) { nil } + context 'when the setting has not been saved to database' do + let(:save_setting) { false } it 'returns default_settings[key]' do expect(described_class[key]).to be default_settings[key] From 93938751eb34b194148236d3a3f907c3b71d0870 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:40:24 +0100 Subject: [PATCH 115/422] Update dependency ruby-prof to v1.7.0 (#28637) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2d54ac33ed..7b9d3579e5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -684,7 +684,7 @@ GEM rubocop (~> 1.40) rubocop-capybara (~> 2.17) rubocop-factory_bot (~> 2.22) - ruby-prof (1.6.3) + ruby-prof (1.7.0) ruby-progressbar (1.13.0) ruby-saml (1.15.0) nokogiri (>= 1.13.10) From 9a73a7dcaf2e383b2ec105d71bfcea2c48cbea10 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 16:17:18 +0100 Subject: [PATCH 116/422] Update dependency irb to v1.11.1 (#28662) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7b9d3579e5..549781aed4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -370,9 +370,9 @@ GEM terminal-table (>= 1.5.1) idn-ruby (0.1.5) io-console (0.7.1) - irb (1.11.0) + irb (1.11.1) rdoc - reline (>= 0.3.8) + reline (>= 0.4.2) jmespath (1.6.2) json (2.7.1) json-canonicalization (1.0.0) @@ -616,7 +616,7 @@ GEM redlock (1.3.2) redis (>= 3.0.0, < 6.0) regexp_parser (2.8.3) - reline (0.4.1) + reline (0.4.2) io-console (~> 0.5) request_store (1.5.1) rack (>= 1.4) From 09ab073f0cc5a8963c6d34fb76d3af84e0c0f40e Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 9 Jan 2024 10:28:56 -0500 Subject: [PATCH 117/422] Fix `LineLength` haml-lint in `app/views/settings` area (#28663) --- .haml-lint_todo.yml | 8 +--- .../settings/applications/_fields.html.haml | 25 ++++++++-- .../settings/featured_tags/index.html.haml | 4 +- app/views/settings/imports/index.html.haml | 22 +++++++-- .../migration/redirects/new.html.haml | 6 ++- .../preferences/appearance/show.html.haml | 46 ++++++++++++++++--- .../settings/preferences/other/show.html.haml | 39 ++++++++++++++-- app/views/settings/profiles/show.html.haml | 10 +++- .../confirmations/new.html.haml | 7 ++- 9 files changed, 137 insertions(+), 30 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 09764c2f30..13ee2baaab 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,20 +1,16 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2024-01-08 14:02:57 -0500 using Haml-Lint version 0.53.0. +# on 2024-01-09 10:00:31 -0500 using Haml-Lint version 0.53.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of Haml-Lint, may require this file to be generated again. linters: - # Offense count: 10 + # Offense count: 5 LineLength: exclude: - 'app/views/admin/roles/_form.html.haml' - 'app/views/auth/registrations/edit.html.haml' - 'app/views/auth/registrations/new.html.haml' - 'app/views/media/player.html.haml' - - 'app/views/settings/applications/_fields.html.haml' - - 'app/views/settings/imports/index.html.haml' - - 'app/views/settings/preferences/appearance/show.html.haml' - - 'app/views/settings/preferences/other/show.html.haml' diff --git a/app/views/settings/applications/_fields.html.haml b/app/views/settings/applications/_fields.html.haml index 29e2bcb5a3..ed97e880fc 100644 --- a/app/views/settings/applications/_fields.html.haml +++ b/app/views/settings/applications/_fields.html.haml @@ -1,11 +1,17 @@ .fields-group - = f.input :name, wrapper: :with_label, label: t('activerecord.attributes.doorkeeper/application.name') + = f.input :name, + label: t('activerecord.attributes.doorkeeper/application.name'), + wrapper: :with_label .fields-group - = f.input :website, wrapper: :with_label, label: t('activerecord.attributes.doorkeeper/application.website') + = f.input :website, + label: t('activerecord.attributes.doorkeeper/application.website'), + wrapper: :with_label .fields-group - = f.input :redirect_uri, wrapper: :with_block_label, label: t('activerecord.attributes.doorkeeper/application.redirect_uri'), hint: t('doorkeeper.applications.help.redirect_uri') + = f.input :redirect_uri, + label: t('activerecord.attributes.doorkeeper/application.redirect_uri'), hint: t('doorkeeper.applications.help.redirect_uri'), + wrapper: :with_block_label %p.hint= t('doorkeeper.applications.help.native_redirect_uri', native_redirect_uri: content_tag(:code, Doorkeeper.configuration.native_redirect_uri)).html_safe @@ -15,4 +21,15 @@ %span.hint= t('simple_form.hints.defaults.scopes') - Doorkeeper.configuration.scopes.group_by { |s| s.split(':').first }.each_value do |value| - = f.input :scopes, label: false, hint: false, collection: value.sort, wrapper: :with_block_label, include_blank: false, label_method: ->(scope) { safe_join([content_tag(:samp, scope, class: class_for_scope(scope)), content_tag(:span, t("doorkeeper.scopes.#{scope}"), class: 'hint')]) }, selected: f.object.scopes.all, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + = f.input :scopes, + as: :check_boxes, + collection_wrapper_tag: 'ul', + collection: value.sort, + hint: false, + include_blank: false, + item_wrapper_tag: 'li', + label_method: ->(scope) { safe_join([content_tag(:samp, scope, class: class_for_scope(scope)), content_tag(:span, t("doorkeeper.scopes.#{scope}"), class: 'hint')]) }, + label: false, + required: false, + selected: f.object.scopes.all, + wrapper: :with_block_label diff --git a/app/views/settings/featured_tags/index.html.haml b/app/views/settings/featured_tags/index.html.haml index 387eb290e3..22f9180129 100644 --- a/app/views/settings/featured_tags/index.html.haml +++ b/app/views/settings/featured_tags/index.html.haml @@ -11,7 +11,9 @@ %p.lead= t('featured_tags.hint_html') .fields-group - = f.input :name, wrapper: :with_block_label, hint: safe_join([t('simple_form.hints.featured_tag.name'), safe_join(@recently_used_tags.map { |tag| link_to("##{tag.display_name}", settings_featured_tags_path(featured_tag: { name: tag.name }), method: :post) }, ', ')], ' ') + = f.input :name, + hint: safe_join([t('simple_form.hints.featured_tag.name'), safe_join(@recently_used_tags.map { |tag| link_to("##{tag.display_name}", settings_featured_tags_path(featured_tag: { name: tag.name }), method: :post) }, ', ')], ' '), + wrapper: :with_block_label .actions = f.button :button, t('featured_tags.add_new'), type: :submit diff --git a/app/views/settings/imports/index.html.haml b/app/views/settings/imports/index.html.haml index 5f7950b598..d5ca252dc1 100644 --- a/app/views/settings/imports/index.html.haml +++ b/app/views/settings/imports/index.html.haml @@ -3,13 +3,29 @@ = simple_form_for @import, url: settings_imports_path do |f| .field-group - = f.input :type, as: :grouped_select, collection: { constructive: %i(following bookmarks lists), destructive: %i(muting blocking domain_blocking) }, wrapper: :with_block_label, include_blank: false, label_method: ->(type) { I18n.t("imports.types.#{type}") }, group_label_method: ->(group) { I18n.t("imports.type_groups.#{group.first}") }, group_method: :last, hint: t('imports.preface') + = f.input :type, + as: :grouped_select, + collection: { constructive: %i(following bookmarks lists), destructive: %i(muting blocking domain_blocking) }, + group_label_method: ->(group) { I18n.t("imports.type_groups.#{group.first}") }, + group_method: :last, + hint: t('imports.preface'), + include_blank: false, + label_method: ->(type) { I18n.t("imports.types.#{type}") }, + wrapper: :with_block_label .fields-row .fields-group.fields-row__column.fields-row__column-6 - = f.input :data, as: :file, wrapper: :with_block_label, hint: t('simple_form.hints.imports.data') + = f.input :data, + as: :file, + hint: t('simple_form.hints.imports.data'), + wrapper: :with_block_label .fields-group.fields-row__column.fields-row__column-6 - = f.input :mode, as: :radio_buttons, collection: Import::MODES, label_method: ->(mode) { safe_join([I18n.t("imports.modes.#{mode}"), content_tag(:span, I18n.t("imports.modes.#{mode}_long"), class: 'hint')]) }, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + = f.input :mode, + as: :radio_buttons, + collection_wrapper_tag: 'ul', + collection: Import::MODES, + item_wrapper_tag: 'li', + label_method: ->(mode) { safe_join([I18n.t("imports.modes.#{mode}"), content_tag(:span, I18n.t("imports.modes.#{mode}_long"), class: 'hint')]) } .actions = f.button :button, t('imports.upload'), type: :submit diff --git a/app/views/settings/migration/redirects/new.html.haml b/app/views/settings/migration/redirects/new.html.haml index 3700878799..731acb9dbc 100644 --- a/app/views/settings/migration/redirects/new.html.haml +++ b/app/views/settings/migration/redirects/new.html.haml @@ -15,7 +15,11 @@ .fields-row .fields-row__column.fields-group.fields-row__column-6 - = f.input :acct, wrapper: :with_block_label, input_html: { autocapitalize: 'none', autocorrect: 'off' }, label: t('simple_form.labels.account_migration.acct'), hint: t('simple_form.hints.account_migration.acct') + = f.input :acct, + hint: t('simple_form.hints.account_migration.acct'), + input_html: { autocapitalize: 'none', autocorrect: 'off' }, + label: t('simple_form.labels.account_migration.acct'), + wrapper: :with_block_label .fields-row__column.fields-group.fields-row__column-6 - if current_user.encrypted_password.present? diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index 11fa2bfc43..76cd4381d8 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -7,13 +7,28 @@ = simple_form_for current_user, url: settings_preferences_appearance_path, html: { method: :put, id: 'edit_user' } do |f| .fields-row .fields-group.fields-row__column.fields-row__column-6 - = f.input :locale, collection: ui_languages, wrapper: :with_label, include_blank: false, label_method: ->(locale) { native_locale_name(locale) }, selected: I18n.locale, hint: false + = f.input :locale, + collection: ui_languages, + hint: false, + include_blank: false, + label_method: ->(locale) { native_locale_name(locale) }, + selected: I18n.locale, + wrapper: :with_label .fields-group.fields-row__column.fields-row__column-6 - = f.input :time_zone, wrapper: :with_label, collection: ActiveSupport::TimeZone.all.map { |tz| ["(GMT#{tz.formatted_offset}) #{tz.name}", tz.tzinfo.name] }, hint: false + = f.input :time_zone, + collection: ActiveSupport::TimeZone.all.map { |tz| ["(GMT#{tz.formatted_offset}) #{tz.name}", tz.tzinfo.name] }, + hint: false, + wrapper: :with_label .fields-group = f.simple_fields_for :settings, current_user.settings do |ff| - = ff.input :theme, collection: Themes.instance.names, label_method: ->(theme) { I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_theme'), include_blank: false, hint: false + = ff.input :theme, + collection: Themes.instance.names, + hint: false, + include_blank: false, + label_method: ->(theme) { I18n.t("themes.#{theme}", default: theme) }, + label: I18n.t('simple_form.labels.defaults.setting_theme'), + wrapper: :with_label - unless I18n.locale == :en .flash-message.translation-prompt @@ -25,11 +40,17 @@ %p.hint= t 'appearance.advanced_web_interface_hint' .fields-group - = ff.input :'web.advanced_layout', wrapper: :with_label, hint: false, label: I18n.t('simple_form.labels.defaults.setting_advanced_layout') + = ff.input :'web.advanced_layout', + hint: false, + label: I18n.t('simple_form.labels.defaults.setting_advanced_layout'), + wrapper: :with_label %h4= t 'appearance.animations_and_accessibility' .fields-group - = ff.input :'web.use_pending_items', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_use_pending_items'), hint: I18n.t('simple_form.hints.defaults.setting_use_pending_items') + = ff.input :'web.use_pending_items', + hint: I18n.t('simple_form.hints.defaults.setting_use_pending_items'), + label: I18n.t('simple_form.labels.defaults.setting_use_pending_items'), + wrapper: :with_label .fields-group = ff.input :'web.auto_play', wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_auto_play_gif') @@ -52,10 +73,21 @@ %h4= t 'appearance.sensitive_content' .fields-group - = ff.input :'web.display_media', collection: %w(default show_all hide_all), label_method: ->(item) { t("simple_form.hints.defaults.setting_display_media_#{item}") }, hint: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', wrapper: :with_floating_label, label: I18n.t('simple_form.labels.defaults.setting_display_media') + = ff.input :'web.display_media', + as: :radio_buttons, + collection_wrapper_tag: 'ul', + collection: %w(default show_all hide_all), + hint: false, + item_wrapper_tag: 'li', + label_method: ->(item) { t("simple_form.hints.defaults.setting_display_media_#{item}") }, + label: I18n.t('simple_form.labels.defaults.setting_display_media'), + wrapper: :with_floating_label .fields-group - = ff.input :'web.use_blurhash', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_use_blurhash'), hint: I18n.t('simple_form.hints.defaults.setting_use_blurhash') + = ff.input :'web.use_blurhash', + hint: I18n.t('simple_form.hints.defaults.setting_use_blurhash'), + label: I18n.t('simple_form.labels.defaults.setting_use_blurhash'), + wrapper: :with_label .fields-group = ff.input :'web.expand_content_warnings', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_expand_spoilers') diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 5228ce1190..e2888f7212 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -9,24 +9,53 @@ = f.simple_fields_for :settings, current_user.settings do |ff| .fields-group - = ff.input :aggregate_reblogs, wrapper: :with_label, recommended: true, label: I18n.t('simple_form.labels.defaults.setting_aggregate_reblogs'), hint: I18n.t('simple_form.hints.defaults.setting_aggregate_reblogs') + = ff.input :aggregate_reblogs, + hint: I18n.t('simple_form.hints.defaults.setting_aggregate_reblogs'), + label: I18n.t('simple_form.labels.defaults.setting_aggregate_reblogs'), + recommended: true, + wrapper: :with_label %h4= t 'preferences.posting_defaults' .fields-row .fields-group.fields-row__column.fields-row__column-6 - = ff.input :default_privacy, collection: Status.selectable_visibilities, wrapper: :with_label, include_blank: false, label_method: ->(visibility) { safe_join([I18n.t("statuses.visibilities.#{visibility}"), I18n.t("statuses.visibilities.#{visibility}_long")], ' - ') }, required: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_privacy') + = ff.input :default_privacy, + collection: Status.selectable_visibilities, + hint: false, + include_blank: false, + label_method: ->(visibility) { safe_join([I18n.t("statuses.visibilities.#{visibility}"), I18n.t("statuses.visibilities.#{visibility}_long")], ' - ') }, + label: I18n.t('simple_form.labels.defaults.setting_default_privacy'), + required: false, + wrapper: :with_label .fields-group.fields-row__column.fields-row__column-6 - = ff.input :default_language, collection: [nil] + filterable_languages, wrapper: :with_label, label_method: ->(locale) { locale.nil? ? I18n.t('statuses.default_language') : native_locale_name(locale) }, required: false, include_blank: false, hint: false, label: I18n.t('simple_form.labels.defaults.setting_default_language') + = ff.input :default_language, + collection: [nil] + filterable_languages, + hint: false, + include_blank: false, + label_method: ->(locale) { locale.nil? ? I18n.t('statuses.default_language') : native_locale_name(locale) }, + label: I18n.t('simple_form.labels.defaults.setting_default_language'), + required: false, + wrapper: :with_label .fields-group - = ff.input :default_sensitive, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_default_sensitive'), hint: I18n.t('simple_form.hints.defaults.setting_default_sensitive') + = ff.input :default_sensitive, + hint: I18n.t('simple_form.hints.defaults.setting_default_sensitive'), + label: I18n.t('simple_form.labels.defaults.setting_default_sensitive'), + wrapper: :with_label %h4= t 'preferences.public_timelines' .fields-group - = f.input :chosen_languages, collection: filterable_languages, wrapper: :with_block_label, include_blank: false, label_method: ->(locale) { native_locale_name(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + = f.input :chosen_languages, + as: :check_boxes, + collection_wrapper_tag: 'ul', + collection: filterable_languages, + include_blank: false, + item_wrapper_tag: 'li', + label_method: ->(locale) { native_locale_name(locale) }, + required: false, + wrapper: :with_block_label .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml index 5f9613c939..b7b0a0da92 100644 --- a/app/views/settings/profiles/show.html.haml +++ b/app/views/settings/profiles/show.html.haml @@ -33,7 +33,10 @@ .fields-row .fields-row__column.fields-row__column-6 .fields-group - = f.input :avatar, wrapper: :with_block_label, input_html: { accept: Account::Avatar::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.avatar', dimensions: '400x400', size: number_to_human_size(Account::Avatar::LIMIT)) + = f.input :avatar, + hint: t('simple_form.hints.defaults.avatar', dimensions: '400x400', size: number_to_human_size(Account::Avatar::LIMIT)), + input_html: { accept: Account::Avatar::IMAGE_MIME_TYPES.join(',') }, + wrapper: :with_block_label .fields-row__column.fields-row__column-6 .fields-group @@ -46,7 +49,10 @@ .fields-row .fields-row__column.fields-row__column-6 .fields-group - = f.input :header, wrapper: :with_block_label, input_html: { accept: Account::Header::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.header', dimensions: '1500x500', size: number_to_human_size(Account::Header::LIMIT)) + = f.input :header, + hint: t('simple_form.hints.defaults.header', dimensions: '1500x500', size: number_to_human_size(Account::Header::LIMIT)), + input_html: { accept: Account::Header::IMAGE_MIME_TYPES.join(',') }, + wrapper: :with_block_label .fields-row__column.fields-row__column-6 .fields-group diff --git a/app/views/settings/two_factor_authentication/confirmations/new.html.haml b/app/views/settings/two_factor_authentication/confirmations/new.html.haml index 43830ac27f..0b8278a104 100644 --- a/app/views/settings/two_factor_authentication/confirmations/new.html.haml +++ b/app/views/settings/two_factor_authentication/confirmations/new.html.haml @@ -12,7 +12,12 @@ %samp.qr-alternative__code= @new_otp_secret.scan(/.{4}/).join(' ') .fields-group - = f.input :otp_attempt, wrapper: :with_label, hint: t('otp_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { autocomplete: 'off' }, required: true + = f.input :otp_attempt, + hint: t('otp_authentication.code_hint'), + input_html: { autocomplete: 'off' }, + label: t('simple_form.labels.defaults.otp_attempt'), + required: true, + wrapper: :with_label .actions = f.button :button, t('otp_authentication.enable'), type: :submit From eed4eef39a92464459496a476e5e3cccfbe084ab Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 9 Jan 2024 11:03:16 -0500 Subject: [PATCH 118/422] Fix `LineLength` haml-lint in `app/views/auth` area (#28664) --- .haml-lint_todo.yml | 6 +-- app/views/auth/challenges/new.html.haml | 6 ++- app/views/auth/confirmations/new.html.haml | 8 ++- app/views/auth/passwords/edit.html.haml | 13 ++++- app/views/auth/passwords/new.html.haml | 7 ++- .../registrations/_account_warning.html.haml | 4 +- .../auth/registrations/_session.html.haml | 4 +- app/views/auth/registrations/edit.html.haml | 26 ++++++++-- app/views/auth/registrations/new.html.haml | 52 ++++++++++++++++--- app/views/auth/sessions/new.html.haml | 20 +++++-- .../_otp_authentication_form.html.haml | 7 ++- app/views/auth/setup/show.html.haml | 5 +- 12 files changed, 130 insertions(+), 28 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 13ee2baaab..ac9f763758 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,16 +1,14 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2024-01-09 10:00:31 -0500 using Haml-Lint version 0.53.0. +# on 2024-01-09 10:48:44 -0500 using Haml-Lint version 0.53.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of Haml-Lint, may require this file to be generated again. linters: - # Offense count: 5 + # Offense count: 3 LineLength: exclude: - 'app/views/admin/roles/_form.html.haml' - - 'app/views/auth/registrations/edit.html.haml' - - 'app/views/auth/registrations/new.html.haml' - 'app/views/media/player.html.haml' diff --git a/app/views/auth/challenges/new.html.haml b/app/views/auth/challenges/new.html.haml index 4f21e4af6e..50dcebb00c 100644 --- a/app/views/auth/challenges/new.html.haml +++ b/app/views/auth/challenges/new.html.haml @@ -5,7 +5,11 @@ = f.input :return_to, as: :hidden .field-group - = f.input :current_password, wrapper: :with_block_label, input_html: { autocomplete: 'current-password', autofocus: true }, label: t('challenge.prompt'), required: true + = f.input :current_password, + input_html: { autocomplete: 'current-password', autofocus: true }, + label: t('challenge.prompt'), + required: true, + wrapper: :with_block_label .actions = f.button :button, t('challenge.confirm'), type: :submit diff --git a/app/views/auth/confirmations/new.html.haml b/app/views/auth/confirmations/new.html.haml index 0cb82a1f86..eaa9d9add0 100644 --- a/app/views/auth/confirmations/new.html.haml +++ b/app/views/auth/confirmations/new.html.haml @@ -21,7 +21,13 @@ = render 'shared/error_messages', object: resource .fields-group - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, readonly: current_user.present?, hint: current_user.present? && t('auth.confirmations.wrong_email_hint') + = f.input :email, + autofocus: true, + hint: current_user.present? && t('auth.confirmations.wrong_email_hint'), + input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, + label: t('simple_form.labels.defaults.email'), + readonly: current_user.present?, + wrapper: :with_label .actions = f.button :button, t('auth.resend_confirmation'), type: :submit diff --git a/app/views/auth/passwords/edit.html.haml b/app/views/auth/passwords/edit.html.haml index b95a9b676b..a75dc2d9fb 100644 --- a/app/views/auth/passwords/edit.html.haml +++ b/app/views/auth/passwords/edit.html.haml @@ -8,9 +8,18 @@ = f.input :reset_password_token, as: :hidden .fields-group - = f.input :password, wrapper: :with_label, autofocus: true, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, required: true + = f.input :password, + autofocus: true, + input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, + label: t('simple_form.labels.defaults.new_password'), + required: true, + wrapper: :with_label .fields-group - = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, required: true + = f.input :password_confirmation, + input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, + label: t('simple_form.labels.defaults.confirm_new_password'), + required: true, + wrapper: :with_label .actions = f.button :button, t('auth.set_new_password'), type: :submit diff --git a/app/views/auth/passwords/new.html.haml b/app/views/auth/passwords/new.html.haml index 10ad108eaf..8d5adaf3b9 100644 --- a/app/views/auth/passwords/new.html.haml +++ b/app/views/auth/passwords/new.html.haml @@ -5,7 +5,12 @@ = render 'shared/error_messages', object: resource .fields-group - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false + = f.input :email, + autofocus: true, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, + label: t('simple_form.labels.defaults.email'), + wrapper: :with_label .actions = f.button :button, t('auth.reset_password'), type: :submit diff --git a/app/views/auth/registrations/_account_warning.html.haml b/app/views/auth/registrations/_account_warning.html.haml index 40e7e12968..19e5746ff6 100644 --- a/app/views/auth/registrations/_account_warning.html.haml +++ b/app/views/auth/registrations/_account_warning.html.haml @@ -5,7 +5,9 @@ = fa_icon 'warning' .log-entry__content .log-entry__title - = t('disputes.strikes.title', action: t(account_warning.action, scope: 'disputes.strikes.title_actions'), date: l(account_warning.created_at.to_date)) + = t 'disputes.strikes.title', + action: t(account_warning.action, scope: 'disputes.strikes.title_actions'), + date: l(account_warning.created_at.to_date) .log-entry__timestamp %time.formatted{ datetime: account_warning.created_at.iso8601 }= l(account_warning.created_at) diff --git a/app/views/auth/registrations/_session.html.haml b/app/views/auth/registrations/_session.html.haml index 28499a7c91..2fa7db70c7 100644 --- a/app/views/auth/registrations/_session.html.haml +++ b/app/views/auth/registrations/_session.html.haml @@ -3,7 +3,9 @@ %span{ title: session.user_agent }< = fa_icon "#{session_device_icon(session)} fw", 'aria-label': session_device_icon(session)   - = t 'sessions.description', browser: t("sessions.browsers.#{session.browser}", default: session.browser.to_s), platform: t("sessions.platforms.#{session.platform}", default: session.platform.to_s) + = t 'sessions.description', + browser: t("sessions.browsers.#{session.browser}", default: session.browser.to_s), + platform: t("sessions.platforms.#{session.platform}", default: session.platform.to_s) %td %samp= session.ip %td diff --git a/app/views/auth/registrations/edit.html.haml b/app/views/auth/registrations/edit.html.haml index f5ef4e97e4..48350f478e 100644 --- a/app/views/auth/registrations/edit.html.haml +++ b/app/views/auth/registrations/edit.html.haml @@ -15,15 +15,33 @@ - if (!use_seamless_external_login? || resource.encrypted_password.present?) && !omniauth_only? .fields-row .fields-row__column.fields-group.fields-row__column-6 - = f.input :email, wrapper: :with_label, input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, required: true, disabled: current_account.suspended? + = f.input :email, + disabled: current_account.suspended?, + input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, + required: true, + wrapper: :with_label .fields-row__column.fields-group.fields-row__column-6 - = f.input :current_password, wrapper: :with_label, input_html: { 'aria-label': t('simple_form.labels.defaults.current_password'), autocomplete: 'current-password' }, required: true, disabled: current_account.suspended?, hint: false + = f.input :current_password, + disabled: current_account.suspended?, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.current_password'), autocomplete: 'current-password' }, + required: true, + wrapper: :with_label .fields-row .fields-row__column.fields-group.fields-row__column-6 - = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, hint: t('simple_form.hints.defaults.password'), disabled: current_account.suspended? + = f.input :password, + disabled: current_account.suspended?, + hint: t('simple_form.hints.defaults.password'), + input_html: { 'aria-label': t('simple_form.labels.defaults.new_password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, + label: t('simple_form.labels.defaults.new_password'), + wrapper: :with_label .fields-row__column.fields-group.fields-row__column-6 - = f.input :password_confirmation, wrapper: :with_label, label: t('simple_form.labels.defaults.confirm_new_password'), input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, disabled: current_account.suspended? + = f.input :password_confirmation, + disabled: current_account.suspended?, + input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_new_password'), autocomplete: 'new-password' }, + label: t('simple_form.labels.defaults.confirm_new_password'), + wrapper: :with_label .actions = f.button :button, t('generic.save_changes'), type: :submit, class: 'button', disabled: current_account.suspended? diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml index 4cac7b51bd..1e5aac2976 100644 --- a/app/views/auth/registrations/new.html.haml +++ b/app/views/auth/registrations/new.html.haml @@ -19,25 +19,61 @@ .fields-group = f.simple_fields_for :account do |ff| - = ff.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.username'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}" - = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'username' }, hint: false - = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, hint: false - = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_password'), autocomplete: 'new-password' }, hint: false - = f.input :confirm_password, as: :string, placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), autocomplete: 'off' }, hint: false - = f.input :website, as: :url, wrapper: :with_label, label: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: 'Website'), autocomplete: 'off' } + = ff.input :username, + append: "@#{site_hostname}", + input_html: { 'aria-label': t('simple_form.labels.defaults.username'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, + label: false, + required: true, + wrapper: :with_label + = f.input :email, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'username' }, + placeholder: t('simple_form.labels.defaults.email'), + required: true + = f.input :password, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, + placeholder: t('simple_form.labels.defaults.password'), + required: true + = f.input :password_confirmation, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_password'), autocomplete: 'new-password' }, + placeholder: t('simple_form.labels.defaults.confirm_password'), + required: true + = f.input :confirm_password, + as: :string, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), autocomplete: 'off' }, + placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), + required: false + = f.input :website, + as: :url, + input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: 'Website'), autocomplete: 'off' }, + label: t('simple_form.labels.defaults.honeypot', label: 'Website'), + required: false, + wrapper: :with_label - if approved_registrations? && @invite.blank? %p.lead= t('auth.sign_up.manual_review', domain: site_hostname) .fields-group = f.simple_fields_for :invite_request, resource.invite_request || resource.build_invite_request do |invite_request_fields| - = invite_request_fields.input :text, as: :text, wrapper: :with_block_label, required: Setting.require_invite_text, label: false, hint: false + = invite_request_fields.input :text, + as: :text, + hint: false, + label: false, + required: Setting.require_invite_text, + wrapper: :with_block_label = hidden_field_tag :accept, params[:accept] = f.input :invite_code, as: :hidden .fields-group - = f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.privacy_policy_agreement_html', rules_path: about_more_path, privacy_policy_path: privacy_policy_path), required: true + = f.input :agreement, + as: :boolean, + label: t('auth.privacy_policy_agreement_html', rules_path: about_more_path, privacy_policy_path: privacy_policy_path), + required: true, + wrapper: :with_label .actions = f.button :button, @invite.present? ? t('auth.register') : sign_up_message, type: :submit diff --git a/app/views/auth/sessions/new.html.haml b/app/views/auth/sessions/new.html.haml index 7914e0157f..89903581a2 100644 --- a/app/views/auth/sessions/new.html.haml +++ b/app/views/auth/sessions/new.html.haml @@ -10,11 +10,25 @@ %p.lead= t('auth.sign_in.preamble_html', domain: site_hostname) .fields-group - if use_seamless_external_login? - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.username_or_email'), input_html: { 'aria-label': t('simple_form.labels.defaults.username_or_email') }, hint: false + = f.input :email, + autofocus: true, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.username_or_email') }, + label: t('simple_form.labels.defaults.username_or_email'), + wrapper: :with_label - else - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, hint: false + = f.input :email, + autofocus: true, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, + label: t('simple_form.labels.defaults.email'), + wrapper: :with_label .fields-group - = f.input :password, wrapper: :with_label, label: t('simple_form.labels.defaults.password'), input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'current-password' }, hint: false + = f.input :password, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'current-password' }, + label: t('simple_form.labels.defaults.password'), + wrapper: :with_label .actions = f.button :button, t('auth.login'), type: :submit diff --git a/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml index 8cc2c85610..30e97a68c1 100644 --- a/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml +++ b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml @@ -5,7 +5,12 @@ %p.hint.authentication-hint= t('simple_form.hints.sessions.otp') .fields-group - = f.input :otp_attempt, type: :number, wrapper: :with_label, label: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label': t('simple_form.labels.defaults.otp_attempt'), autocomplete: 'one-time-code' }, autofocus: true + = f.input :otp_attempt, + autofocus: true, + input_html: { 'aria-label': t('simple_form.labels.defaults.otp_attempt'), autocomplete: 'one-time-code' }, + label: t('simple_form.labels.defaults.otp_attempt'), + type: :number, + wrapper: :with_label .actions = f.button :button, t('auth.login'), type: :submit diff --git a/app/views/auth/setup/show.html.haml b/app/views/auth/setup/show.html.haml index 97c826d704..713f77470d 100644 --- a/app/views/auth/setup/show.html.haml +++ b/app/views/auth/setup/show.html.haml @@ -16,7 +16,10 @@ %p.lead= t('auth.setup.email_below_hint_html') .fields-group - = f.input :email, required: true, hint: false, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'off' } + = f.input :email, + hint: false, + input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'off' }, + required: true .actions = f.button :button, t('auth.resend_confirmation'), type: :submit, class: 'button timer-button', disabled: true From 1f44903991168858d7cc00b3e3255617cd31154c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 22:08:02 +0100 Subject: [PATCH 119/422] Update dependency sidekiq-unique-jobs to v7.1.31 (#27818) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 549781aed4..91b3bf701f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -716,7 +716,7 @@ GEM rufus-scheduler (~> 3.2) sidekiq (>= 6, < 8) tilt (>= 1.4.0) - sidekiq-unique-jobs (7.1.30) + sidekiq-unique-jobs (7.1.31) brpoplpush-redis_script (> 0.1.1, <= 2.0.0) concurrent-ruby (~> 1.0, >= 1.0.5) redis (< 5.0) From 63d0b52cf3641a819853197bf837937b9f67ef8e Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Tue, 9 Jan 2024 22:58:19 +0100 Subject: [PATCH 120/422] Add a system spec for the `/share` endpoint (#28672) --- spec/system/share_entrypoint_spec.rb | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 spec/system/share_entrypoint_spec.rb diff --git a/spec/system/share_entrypoint_spec.rb b/spec/system/share_entrypoint_spec.rb new file mode 100644 index 0000000000..fd02d1120c --- /dev/null +++ b/spec/system/share_entrypoint_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'ShareEntrypoint' do + include ProfileStories + + subject { page } + + let(:email) { 'test@example.com' } + let(:password) { 'password' } + let(:confirmed_at) { Time.zone.now } + let(:finished_onboarding) { true } + + before do + as_a_logged_in_user + visit share_path + end + + it 'can be used to post a new status' do + expect(subject).to have_css('div#mastodon-compose') + expect(subject).to have_css('.compose-form__publish-button-wrapper > button') + + status_text = 'This is a new status!' + + within('.compose-form') do + fill_in "What's on your mind?", with: status_text + click_on 'Publish!' + end + + expect(subject).to have_css('.notification-bar-message', text: 'Post published.') + end +end From a71e918e958de85e8295212d1a48925e93fae4e0 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 04:35:01 -0500 Subject: [PATCH 121/422] Fix `LineLength` haml-lint in `media/player` view (#28667) --- .haml-lint_todo.yml | 5 ++--- app/views/media/player.html.haml | 31 ++++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index ac9f763758..af2d2e8f4e 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,14 +1,13 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2024-01-09 10:48:44 -0500 using Haml-Lint version 0.53.0. +# on 2024-01-09 11:30:07 -0500 using Haml-Lint version 0.53.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of Haml-Lint, may require this file to be generated again. linters: - # Offense count: 3 + # Offense count: 1 LineLength: exclude: - 'app/views/admin/roles/_form.html.haml' - - 'app/views/media/player.html.haml' diff --git a/app/views/media/player.html.haml b/app/views/media/player.html.haml index f00c8f040b..df02cc4110 100644 --- a/app/views/media/player.html.haml +++ b/app/views/media/player.html.haml @@ -6,14 +6,39 @@ meta = @media_attachment.file.meta || {} - if @media_attachment.video? - = react_component :video, src: @media_attachment.file.url(:original), preview: @media_attachment.thumbnail.present? ? @media_attachment.thumbnail.url : @media_attachment.file.url(:small), frameRate: meta.dig('original', 'frame_rate'), blurhash: @media_attachment.blurhash, width: 670, height: 380, editable: true, detailed: true, inline: true, alt: @media_attachment.description, media: [ActiveModelSerializers::SerializableResource.new(@media_attachment, serializer: REST::MediaAttachmentSerializer)].as_json do + = react_component :video, + alt: @media_attachment.description, + blurhash: @media_attachment.blurhash, + detailed: true, + editable: true, + frameRate: meta.dig('original', 'frame_rate'), + height: 380, + inline: true, + media: [ActiveModelSerializers::SerializableResource.new(@media_attachment, serializer: REST::MediaAttachmentSerializer)].as_json, + preview: @media_attachment.thumbnail.present? ? @media_attachment.thumbnail.url : @media_attachment.file.url(:small), + src: @media_attachment.file.url(:original), + width: 670 do %video{ controls: 'controls' } %source{ src: @media_attachment.file.url(:original) } - elsif @media_attachment.gifv? - = react_component :media_gallery, height: 380, standalone: true, autoplay: true, media: [ActiveModelSerializers::SerializableResource.new(@media_attachment, serializer: REST::MediaAttachmentSerializer).as_json] do + = react_component :media_gallery, + autoplay: true, + height: 380, + media: [ActiveModelSerializers::SerializableResource.new(@media_attachment, serializer: REST::MediaAttachmentSerializer).as_json], + standalone: true do %video{ autoplay: 'autoplay', muted: 'muted', loop: 'loop' } %source{ src: @media_attachment.file.url(:original) } - elsif @media_attachment.audio? - = react_component :audio, src: @media_attachment.file.url(:original), poster: @media_attachment.thumbnail.present? ? @media_attachment.thumbnail.url : @media_attachment.account.avatar_static_url, backgroundColor: meta.dig('colors', 'background'), foregroundColor: meta.dig('colors', 'foreground'), accentColor: meta.dig('colors', 'accent'), width: 670, height: 380, fullscreen: true, alt: @media_attachment.description, duration: meta.dig(:original, :duration) do + = react_component :audio, + accentColor: meta.dig('colors', 'accent'), + alt: @media_attachment.description, + backgroundColor: meta.dig('colors', 'background'), + duration: meta.dig(:original, :duration), + foregroundColor: meta.dig('colors', 'foreground'), + fullscreen: true, + height: 380, + poster: @media_attachment.thumbnail.present? ? @media_attachment.thumbnail.url : @media_attachment.account.avatar_static_url, + src: @media_attachment.file.url(:original), + width: 670 do %audio{ controls: 'controls' } %source{ src: @media_attachment.file.url(:original) } From 742d8d30e2bdbd2bb42676fc8ab7ebf0ecf21966 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 04:36:12 -0500 Subject: [PATCH 122/422] Add coverage for `--days` option to CLI `media refresh` command (#28669) --- spec/lib/mastodon/cli/media_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/lib/mastodon/cli/media_spec.rb b/spec/lib/mastodon/cli/media_spec.rb index 071bcd9e34..10005107aa 100644 --- a/spec/lib/mastodon/cli/media_spec.rb +++ b/spec/lib/mastodon/cli/media_spec.rb @@ -183,6 +183,21 @@ describe Mastodon::CLI::Media do .to output_results('Downloaded 1 media') end end + + context 'with --days option' do + before do + Fabricate(:media_attachment, remote_url: 'https://example.com/image.jpg', id: Mastodon::Snowflake.id_at(50.days.ago)) + Fabricate(:media_attachment, remote_url: 'https://example.com/image.jpg', id: Mastodon::Snowflake.id_at(5.days.ago)) + Fabricate(:media_attachment, remote_url: '', id: Mastodon::Snowflake.id_at(5.days.ago)) + end + + let(:options) { { days: 10 } } + + it 'redownloads the attachment file for the remote records more recent than the option' do + expect { subject } + .to output_results('Downloaded 1 media') + end + end end describe '#remove_orphans' do From 36b46ea3b5b4a4fb51cf1cd103b5a3c1103c300e Mon Sep 17 00:00:00 2001 From: zunda Date: Wed, 10 Jan 2024 09:37:31 +0000 Subject: [PATCH 123/422] bundle add csv (#28671) --- Gemfile | 1 + Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index e0980c0720..e096a5d685 100644 --- a/Gemfile +++ b/Gemfile @@ -48,6 +48,7 @@ gem 'omniauth', '~> 2.0' gem 'omniauth-rails_csrf_protection', '~> 1.0' gem 'color_diff', '~> 0.1' +gem 'csv', '~> 3.2' gem 'discard', '~> 1.2' gem 'doorkeeper', '~> 5.6' gem 'ed25519', '~> 1.3' diff --git a/Gemfile.lock b/Gemfile.lock index 91b3bf701f..595c9fd279 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -208,6 +208,7 @@ GEM crass (1.0.6) css_parser (1.14.0) addressable + csv (3.2.8) database_cleaner-active_record (2.1.0) activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) @@ -845,6 +846,7 @@ DEPENDENCIES color_diff (~> 0.1) concurrent-ruby connection_pool + csv (~> 3.2) database_cleaner-active_record debug (~> 1.8) devise (~> 4.9) From ea1c0feb86e3b1213b0808cef43446b5146d50da Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 05:35:06 -0500 Subject: [PATCH 124/422] Remove `add_column_with_default` migration helper (#28654) --- ...16191202_add_hide_notifications_to_mute.rb | 6 +-- ...005171936_add_disabled_to_custom_emojis.rb | 6 +-- .../20171028221157_add_reblogs_to_follows.rb | 8 +--- ...20171107143332_add_memorial_to_accounts.rb | 6 +-- .../20171107143624_add_disabled_to_users.rb | 6 +-- ...0171109012327_add_moderator_to_accounts.rb | 6 +-- ...30000000_add_embed_url_to_preview_cards.rb | 6 +-- ...0180615122121_add_autofollow_to_invites.rb | 6 +-- ...7154237_add_whole_word_to_custom_filter.rb | 6 +-- ..._confidential_to_doorkeeper_application.rb | 8 +--- .../20181010141500_add_silent_to_mentions.rb | 8 +--- ...937_add_reject_reports_to_domain_blocks.rb | 6 +-- ...649_add_unread_to_account_conversations.rb | 8 +--- ...0181127165847_add_show_replies_to_lists.rb | 8 +--- ...20190201012802_add_overwrite_to_imports.rb | 6 +-- ...0190306145741_add_lock_version_to_polls.rb | 8 +--- .../20190307234537_add_approved_to_users.rb | 8 +--- ...13028_add_lock_version_to_account_stats.rb | 6 +-- ...58_add_title_to_account_warning_presets.rb | 6 +-- .../20200917192924_add_notify_to_follows.rb | 8 +--- ...18054746_add_obfuscate_to_domain_blocks.rb | 6 +-- .../20211231080958_add_category_to_reports.rb | 6 +-- ...0613110834_add_action_to_custom_filters.rb | 6 +-- .../20230605085710_add_exclusive_to_lists.rb | 6 +-- ..._add_image_description_to_preview_cards.rb | 6 +-- ...0230814223300_add_indexable_to_accounts.rb | 6 +-- ...2_remove_whole_word_from_custom_filters.rb | 6 +-- ...remove_irreversible_from_custom_filters.rb | 6 +-- lib/mastodon/migration_helpers.rb | 41 +------------------ 29 files changed, 37 insertions(+), 188 deletions(-) diff --git a/db/migrate/20170716191202_add_hide_notifications_to_mute.rb b/db/migrate/20170716191202_add_hide_notifications_to_mute.rb index b817d512de..2ef5d25791 100644 --- a/db/migrate/20170716191202_add_hide_notifications_to_mute.rb +++ b/db/migrate/20170716191202_add_hide_notifications_to_mute.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddHideNotificationsToMute < ActiveRecord::Migration[5.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - add_column_with_default :mutes, :hide_notifications, :boolean, default: true, allow_null: false + add_column :mutes, :hide_notifications, :boolean, default: true, null: false end def down diff --git a/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb b/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb index d6fd228f95..eaf5f4ef2d 100644 --- a/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb +++ b/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddDisabledToCustomEmojis < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :custom_emojis, :disabled, :bool, default: false } + safety_assured { add_column :custom_emojis, :disabled, :bool, default: false, null: false } end def down diff --git a/db/migrate/20171028221157_add_reblogs_to_follows.rb b/db/migrate/20171028221157_add_reblogs_to_follows.rb index 0dab84c799..068d66d1da 100644 --- a/db/migrate/20171028221157_add_reblogs_to_follows.rb +++ b/db/migrate/20171028221157_add_reblogs_to_follows.rb @@ -1,16 +1,12 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddReblogsToFollows < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :follows, :show_reblogs, :boolean, default: true, allow_null: false - add_column_with_default :follow_requests, :show_reblogs, :boolean, default: true, allow_null: false + add_column :follows, :show_reblogs, :boolean, default: true, null: false + add_column :follow_requests, :show_reblogs, :boolean, default: true, null: false end end diff --git a/db/migrate/20171107143332_add_memorial_to_accounts.rb b/db/migrate/20171107143332_add_memorial_to_accounts.rb index 3cf782b81f..35a98f45e8 100644 --- a/db/migrate/20171107143332_add_memorial_to_accounts.rb +++ b/db/migrate/20171107143332_add_memorial_to_accounts.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddMemorialToAccounts < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :accounts, :memorial, :bool, default: false } + safety_assured { add_column :accounts, :memorial, :bool, default: false, null: false } end def down diff --git a/db/migrate/20171107143624_add_disabled_to_users.rb b/db/migrate/20171107143624_add_disabled_to_users.rb index 4ab4df7372..055d05b109 100644 --- a/db/migrate/20171107143624_add_disabled_to_users.rb +++ b/db/migrate/20171107143624_add_disabled_to_users.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddDisabledToUsers < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :users, :disabled, :bool, default: false } + safety_assured { add_column :users, :disabled, :bool, default: false, null: false } end def down diff --git a/db/migrate/20171109012327_add_moderator_to_accounts.rb b/db/migrate/20171109012327_add_moderator_to_accounts.rb index e8fc313c8c..6a29e5aafe 100644 --- a/db/migrate/20171109012327_add_moderator_to_accounts.rb +++ b/db/migrate/20171109012327_add_moderator_to_accounts.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddModeratorToAccounts < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :users, :moderator, :bool, default: false } + safety_assured { add_column :users, :moderator, :bool, default: false, null: false } end def down diff --git a/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb b/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb index e78373b24c..f2336e8e25 100644 --- a/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb +++ b/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddEmbedURLToPreviewCards < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :preview_cards, :embed_url, :string, default: '', allow_null: false + add_column :preview_cards, :embed_url, :string, default: '', null: false end end diff --git a/db/migrate/20180615122121_add_autofollow_to_invites.rb b/db/migrate/20180615122121_add_autofollow_to_invites.rb index ef129003a1..19a5f0d171 100644 --- a/db/migrate/20180615122121_add_autofollow_to_invites.rb +++ b/db/migrate/20180615122121_add_autofollow_to_invites.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddAutofollowToInvites < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :invites, :autofollow, :bool, default: false, allow_null: false + add_column :invites, :autofollow, :bool, default: false, null: false end end diff --git a/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb b/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb index 793c3e6cfb..519dfdfae1 100644 --- a/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb +++ b/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddWholeWordToCustomFilter < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def change safety_assured do - add_column_with_default :custom_filters, :whole_word, :boolean, default: true, allow_null: false + add_column :custom_filters, :whole_word, :boolean, default: true, null: false end end diff --git a/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb b/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb index 7360c71ac9..6544b81c8e 100644 --- a/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb +++ b/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddConfidentialToDoorkeeperApplication < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :oauth_applications, :confidential, :boolean, - allow_null: false, + null: false, default: true # maintaining backwards compatibility: require secrets ) end diff --git a/db/migrate/20181010141500_add_silent_to_mentions.rb b/db/migrate/20181010141500_add_silent_to_mentions.rb index f9bfc51694..029119e79b 100644 --- a/db/migrate/20181010141500_add_silent_to_mentions.rb +++ b/db/migrate/20181010141500_add_silent_to_mentions.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddSilentToMentions < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :mentions, :silent, :boolean, - allow_null: false, + null: false, default: false ) end diff --git a/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb b/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb index b6cfd31d25..49bd2b02f7 100644 --- a/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb +++ b/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddRejectReportsToDomainBlocks < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :domain_blocks, :reject_reports, :boolean, default: false, allow_null: false + add_column :domain_blocks, :reject_reports, :boolean, default: false, null: false end end diff --git a/db/migrate/20181018205649_add_unread_to_account_conversations.rb b/db/migrate/20181018205649_add_unread_to_account_conversations.rb index fec9476398..ae4576255d 100644 --- a/db/migrate/20181018205649_add_unread_to_account_conversations.rb +++ b/db/migrate/20181018205649_add_unread_to_account_conversations.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddUnreadToAccountConversations < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :account_conversations, :unread, :boolean, - allow_null: false, + null: false, default: false ) end diff --git a/db/migrate/20181127165847_add_show_replies_to_lists.rb b/db/migrate/20181127165847_add_show_replies_to_lists.rb index 45d457b748..a391d9f6f0 100644 --- a/db/migrate/20181127165847_add_show_replies_to_lists.rb +++ b/db/migrate/20181127165847_add_show_replies_to_lists.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddShowRepliesToLists < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :lists, :replies_policy, :integer, - allow_null: false, + null: false, default: 0 ) end diff --git a/db/migrate/20190201012802_add_overwrite_to_imports.rb b/db/migrate/20190201012802_add_overwrite_to_imports.rb index fe9423ed04..b497950eef 100644 --- a/db/migrate/20190201012802_add_overwrite_to_imports.rb +++ b/db/migrate/20190201012802_add_overwrite_to_imports.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddOverwriteToImports < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :imports, :overwrite, :boolean, default: false, allow_null: false + add_column :imports, :overwrite, :boolean, default: false, null: false end end diff --git a/db/migrate/20190306145741_add_lock_version_to_polls.rb b/db/migrate/20190306145741_add_lock_version_to_polls.rb index 760818d97b..ec4430ea94 100644 --- a/db/migrate/20190306145741_add_lock_version_to_polls.rb +++ b/db/migrate/20190306145741_add_lock_version_to_polls.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddLockVersionToPolls < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :polls, :lock_version, :integer, - allow_null: false, + null: false, default: 0 ) end diff --git a/db/migrate/20190307234537_add_approved_to_users.rb b/db/migrate/20190307234537_add_approved_to_users.rb index 9abab29c93..ffdc24716e 100644 --- a/db/migrate/20190307234537_add_approved_to_users.rb +++ b/db/migrate/20190307234537_add_approved_to_users.rb @@ -1,19 +1,15 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddApprovedToUsers < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default( + add_column( :users, :approved, :bool, - allow_null: false, + null: false, default: true ) end diff --git a/db/migrate/20191001213028_add_lock_version_to_account_stats.rb b/db/migrate/20191001213028_add_lock_version_to_account_stats.rb index 0dc1655596..3ffbacf25f 100644 --- a/db/migrate/20191001213028_add_lock_version_to_account_stats.rb +++ b/db/migrate/20191001213028_add_lock_version_to_account_stats.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddLockVersionToAccountStats < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :account_stats, :lock_version, :integer, allow_null: false, default: 0 } + safety_assured { add_column :account_stats, :lock_version, :integer, null: false, default: 0 } end def down diff --git a/db/migrate/20200312144258_add_title_to_account_warning_presets.rb b/db/migrate/20200312144258_add_title_to_account_warning_presets.rb index 78b854f82c..63d339c49c 100644 --- a/db/migrate/20200312144258_add_title_to_account_warning_presets.rb +++ b/db/migrate/20200312144258_add_title_to_account_warning_presets.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddTitleToAccountWarningPresets < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :account_warning_presets, :title, :string, default: '', allow_null: false } + safety_assured { add_column :account_warning_presets, :title, :string, default: '', null: false } end def down diff --git a/db/migrate/20200917192924_add_notify_to_follows.rb b/db/migrate/20200917192924_add_notify_to_follows.rb index a57bb36dc2..1dc831dc47 100644 --- a/db/migrate/20200917192924_add_notify_to_follows.rb +++ b/db/migrate/20200917192924_add_notify_to_follows.rb @@ -1,16 +1,12 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddNotifyToFollows < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :follows, :notify, :boolean, default: false, allow_null: false - add_column_with_default :follow_requests, :notify, :boolean, default: false, allow_null: false + add_column :follows, :notify, :boolean, default: false, null: false + add_column :follow_requests, :notify, :boolean, default: false, null: false end end diff --git a/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb b/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb index 91bba38c58..d7038c83dc 100644 --- a/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb +++ b/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddObfuscateToDomainBlocks < ActiveRecord::Migration[5.2] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :domain_blocks, :obfuscate, :boolean, default: false, allow_null: false } + safety_assured { add_column :domain_blocks, :obfuscate, :boolean, default: false, null: false } end def down diff --git a/db/migrate/20211231080958_add_category_to_reports.rb b/db/migrate/20211231080958_add_category_to_reports.rb index f114cda615..a20a3155d6 100644 --- a/db/migrate/20211231080958_add_category_to_reports.rb +++ b/db/migrate/20211231080958_add_category_to_reports.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddCategoryToReports < ActiveRecord::Migration[6.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :reports, :category, :int, default: 0, allow_null: false + add_column :reports, :category, :int, default: 0, null: false change_table(:reports, bulk: true) do |t| t.column :action_taken_at, :datetime t.column :rule_ids, :bigint, array: true diff --git a/db/migrate/20220613110834_add_action_to_custom_filters.rb b/db/migrate/20220613110834_add_action_to_custom_filters.rb index c1daf3c948..ab2f7c65e7 100644 --- a/db/migrate/20220613110834_add_action_to_custom_filters.rb +++ b/db/migrate/20220613110834_add_action_to_custom_filters.rb @@ -1,15 +1,11 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddActionToCustomFilters < ActiveRecord::Migration[6.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up safety_assured do - add_column_with_default :custom_filters, :action, :integer, allow_null: false, default: 0 + add_column :custom_filters, :action, :integer, null: false, default: 0 execute 'UPDATE custom_filters SET action = 1 WHERE irreversible IS TRUE' end end diff --git a/db/migrate/20230605085710_add_exclusive_to_lists.rb b/db/migrate/20230605085710_add_exclusive_to_lists.rb index 315c9d4872..abcb8fae1e 100644 --- a/db/migrate/20230605085710_add_exclusive_to_lists.rb +++ b/db/migrate/20230605085710_add_exclusive_to_lists.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddExclusiveToLists < ActiveRecord::Migration[6.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :lists, :exclusive, :boolean, default: false, allow_null: false } + safety_assured { add_column :lists, :exclusive, :boolean, default: false, null: false } end def down diff --git a/db/migrate/20230725213448_add_image_description_to_preview_cards.rb b/db/migrate/20230725213448_add_image_description_to_preview_cards.rb index 03020db655..7445a0e7fc 100644 --- a/db/migrate/20230725213448_add_image_description_to_preview_cards.rb +++ b/db/migrate/20230725213448_add_image_description_to_preview_cards.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddImageDescriptionToPreviewCards < ActiveRecord::Migration[7.0] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :preview_cards, :image_description, :string, default: '', allow_null: false } + safety_assured { add_column :preview_cards, :image_description, :string, default: '', null: false } end def down diff --git a/db/migrate/20230814223300_add_indexable_to_accounts.rb b/db/migrate/20230814223300_add_indexable_to_accounts.rb index 6729c05ef2..0544eb92fe 100644 --- a/db/migrate/20230814223300_add_indexable_to_accounts.rb +++ b/db/migrate/20230814223300_add_indexable_to_accounts.rb @@ -1,14 +1,10 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class AddIndexableToAccounts < ActiveRecord::Migration[7.0] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up - safety_assured { add_column_with_default :accounts, :indexable, :boolean, default: false, allow_null: false } + safety_assured { add_column :accounts, :indexable, :boolean, default: false, null: false } end def down diff --git a/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb b/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb index 99c3366a20..5e477d9b11 100644 --- a/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb +++ b/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb @@ -1,10 +1,6 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class RemoveWholeWordFromCustomFilters < ActiveRecord::Migration[6.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up @@ -15,7 +11,7 @@ class RemoveWholeWordFromCustomFilters < ActiveRecord::Migration[6.1] def down safety_assured do - add_column_with_default :custom_filters, :whole_word, :boolean, default: true, allow_null: false + add_column :custom_filters, :whole_word, :boolean, default: true, null: false end end end diff --git a/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb b/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb index 1c366ee53c..1ed009fe99 100644 --- a/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb +++ b/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb @@ -1,10 +1,6 @@ # frozen_string_literal: true -require Rails.root.join('lib', 'mastodon', 'migration_helpers') - class RemoveIrreversibleFromCustomFilters < ActiveRecord::Migration[6.1] - include Mastodon::MigrationHelpers - disable_ddl_transaction! def up @@ -15,7 +11,7 @@ class RemoveIrreversibleFromCustomFilters < ActiveRecord::Migration[6.1] def down safety_assured do - add_column_with_default :custom_filters, :irreversible, :boolean, allow_null: false, default: false + add_column :custom_filters, :irreversible, :boolean, null: false, default: false end end end diff --git a/lib/mastodon/migration_helpers.rb b/lib/mastodon/migration_helpers.rb index 7bc1298838..1a2ce6420f 100644 --- a/lib/mastodon/migration_helpers.rb +++ b/lib/mastodon/migration_helpers.rb @@ -104,18 +104,7 @@ module Mastodon 'in the body of your migration class' end - # If default value is presented, use `add_column_with_default` method instead. - if options[:default] - add_column_with_default( - table_name, - column_name, - :datetime_with_timezone, - default: options[:default], - allow_null: options[:null] - ) - else - add_column(table_name, column_name, :datetime_with_timezone, **options) - end + add_column(table_name, column_name, :datetime_with_timezone, **options) end end @@ -377,34 +366,6 @@ module Mastodon end end - # Adds a column with a default value without locking an entire table. - # - # This method runs the following steps: - # - # 1. Add the column with a default value of NULL. - # 2. Change the default value of the column to the specified value. - # 3. Update all existing rows in batches. - # 4. Set a `NOT NULL` constraint on the column if desired (the default). - # - # These steps ensure a column can be added to a large and commonly used - # table without locking the entire table for the duration of the table - # modification. - # - # table - The name of the table to update. - # column - The name of the column to add. - # type - The column type (e.g. `:integer`). - # default - The default value for the column. - # limit - Sets a column limit. For example, for :integer, the default is - # 4-bytes. Set `limit: 8` to allow 8-byte integers. - # allow_null - When set to `true` the column will allow NULL values, the - # default is to not allow NULL values. - # - # This method can also take a block which is passed directly to the - # `update_column_in_batches` method. - def add_column_with_default(table, column, type, default:, limit: nil, allow_null: false, &block) - add_column(table, column, type, default: default, limit: limit, null: allow_null) - end - # Renames a column without requiring downtime. # # Concurrent renames work by using database triggers to ensure both the From 00341c70ffea2cdef9d6e73f6897ffbab04401f0 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 06:06:58 -0500 Subject: [PATCH 125/422] Use Sidekiq `fake!` instead of `inline!` in specs (#25369) --- .../admin/disputes/appeals_controller_spec.rb | 4 ++-- .../admin/domain_blocks_controller_spec.rb | 2 +- spec/controllers/admin/resets_controller_spec.rb | 2 +- .../api/v1/conversations_controller_spec.rb | 2 +- .../api/v1/statuses/reblogs_controller_spec.rb | 4 ++-- spec/controllers/auth/sessions_controller_spec.rb | 2 +- .../concerns/user_tracking_concern_spec.rb | 2 +- spec/controllers/disputes/appeals_controller_spec.rb | 2 +- spec/controllers/settings/deletes_controller_spec.rb | 2 +- spec/controllers/settings/exports_controller_spec.rb | 2 +- spec/features/admin/accounts_spec.rb | 2 +- spec/lib/activitypub/activity/create_spec.rb | 2 +- spec/lib/activitypub/activity/delete_spec.rb | 2 +- spec/lib/activitypub/activity/move_spec.rb | 2 +- spec/models/admin/account_action_spec.rb | 2 +- spec/models/user_spec.rb | 4 ++-- spec/rails_helper.rb | 8 ++------ spec/requests/api/v1/featured_tags_spec.rb | 2 +- spec/requests/api/v1/notifications_spec.rb | 2 +- spec/requests/api/v1/statuses/favourites_spec.rb | 8 ++------ spec/requests/api/v1/timelines/home_spec.rb | 2 +- .../models/concerns/account/statuses_search_spec.rb | 2 +- .../activitypub/fetch_remote_status_service_spec.rb | 2 +- .../activitypub/process_account_service_spec.rb | 2 +- spec/services/authorize_follow_service_spec.rb | 2 +- spec/services/batched_remove_status_service_spec.rb | 2 +- spec/services/block_domain_service_spec.rb | 2 +- spec/services/block_service_spec.rb | 2 +- spec/services/bulk_import_service_spec.rb | 2 +- spec/services/delete_account_service_spec.rb | 4 ++-- spec/services/fan_out_on_write_service_spec.rb | 12 +++++------- spec/services/favourite_service_spec.rb | 2 +- spec/services/follow_service_spec.rb | 2 +- spec/services/import_service_spec.rb | 2 +- spec/services/mute_service_spec.rb | 2 +- spec/services/notify_service_spec.rb | 2 +- spec/services/reblog_service_spec.rb | 2 +- spec/services/reject_follow_service_spec.rb | 2 +- spec/services/remove_from_followers_service_spec.rb | 2 +- spec/services/remove_status_service_spec.rb | 2 +- spec/services/report_service_spec.rb | 2 +- spec/services/resolve_account_service_spec.rb | 2 +- spec/services/suspend_account_service_spec.rb | 2 +- spec/services/unallow_domain_service_spec.rb | 2 +- spec/services/unblock_service_spec.rb | 2 +- spec/services/unfollow_service_spec.rb | 4 ++-- spec/services/unsuspend_account_service_spec.rb | 2 +- spec/services/update_account_service_spec.rb | 2 +- spec/services/update_status_service_spec.rb | 2 +- spec/system/new_statuses_spec.rb | 2 +- spec/workers/backup_worker_spec.rb | 2 +- spec/workers/move_worker_spec.rb | 6 +++--- spec/workers/poll_expiration_notify_worker_spec.rb | 2 +- 53 files changed, 66 insertions(+), 76 deletions(-) diff --git a/spec/controllers/admin/disputes/appeals_controller_spec.rb b/spec/controllers/admin/disputes/appeals_controller_spec.rb index 4581d00d6f..f830c3b95c 100644 --- a/spec/controllers/admin/disputes/appeals_controller_spec.rb +++ b/spec/controllers/admin/disputes/appeals_controller_spec.rb @@ -44,7 +44,7 @@ RSpec.describe Admin::Disputes::AppealsController do expect(response).to redirect_to(disputes_strike_path(appeal.strike)) end - it 'notifies target account about approved appeal' do + it 'notifies target account about approved appeal', :sidekiq_inline do expect(UserMailer.deliveries.size).to eq(1) expect(UserMailer.deliveries.first.to.first).to eq(target_account.user.email) expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.appeal_approved.subject', date: I18n.l(appeal.created_at))) @@ -62,7 +62,7 @@ RSpec.describe Admin::Disputes::AppealsController do expect(response).to redirect_to(disputes_strike_path(appeal.strike)) end - it 'notifies target account about rejected appeal' do + it 'notifies target account about rejected appeal', :sidekiq_inline do expect(UserMailer.deliveries.size).to eq(1) expect(UserMailer.deliveries.first.to.first).to eq(target_account.user.email) expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.appeal_rejected.subject', date: I18n.l(appeal.created_at))) diff --git a/spec/controllers/admin/domain_blocks_controller_spec.rb b/spec/controllers/admin/domain_blocks_controller_spec.rb index 22960f5312..87b08323da 100644 --- a/spec/controllers/admin/domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/domain_blocks_controller_spec.rb @@ -176,7 +176,7 @@ RSpec.describe Admin::DomainBlocksController do end end - describe 'PUT #update' do + describe 'PUT #update', :sidekiq_inline do subject do post :update, params: { :id => domain_block.id, :domain_block => { domain: 'example.com', severity: new_severity }, 'confirm' => '' } end diff --git a/spec/controllers/admin/resets_controller_spec.rb b/spec/controllers/admin/resets_controller_spec.rb index 14826973c1..e82a3a6afa 100644 --- a/spec/controllers/admin/resets_controller_spec.rb +++ b/spec/controllers/admin/resets_controller_spec.rb @@ -11,7 +11,7 @@ describe Admin::ResetsController do sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end - describe 'POST #create' do + describe 'POST #create', :sidekiq_inline do it 'redirects to admin accounts page' do expect do post :create, params: { account_id: account.id } diff --git a/spec/controllers/api/v1/conversations_controller_spec.rb b/spec/controllers/api/v1/conversations_controller_spec.rb index 50e2a62efd..2734e4a07b 100644 --- a/spec/controllers/api/v1/conversations_controller_spec.rb +++ b/spec/controllers/api/v1/conversations_controller_spec.rb @@ -13,7 +13,7 @@ RSpec.describe Api::V1::ConversationsController do allow(controller).to receive(:doorkeeper_token) { token } end - describe 'GET #index' do + describe 'GET #index', :sidekiq_inline do let(:scopes) { 'read:statuses' } before do diff --git a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb index e3a9bdb502..014a03c1a2 100644 --- a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb +++ b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb @@ -9,7 +9,7 @@ describe Api::V1::Statuses::ReblogsController do let(:app) { Fabricate(:application, name: 'Test app', website: 'http://testapp.com') } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:statuses', application: app) } - context 'with an oauth token', :sidekiq_fake do + context 'with an oauth token' do before do allow(controller).to receive(:doorkeeper_token) { token } end @@ -46,7 +46,7 @@ describe Api::V1::Statuses::ReblogsController do end end - describe 'POST #destroy' do + describe 'POST #destroy', :sidekiq_inline do context 'with public status' do let(:status) { Fabricate(:status, account: user.account) } diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb index 212cc4d5e5..e3f2b278bd 100644 --- a/spec/controllers/auth/sessions_controller_spec.rb +++ b/spec/controllers/auth/sessions_controller_spec.rb @@ -138,7 +138,7 @@ RSpec.describe Auth::SessionsController do expect(controller.current_user).to eq user end - it 'sends a suspicious sign-in mail' do + it 'sends a suspicious sign-in mail', :sidekiq_inline do expect(UserMailer.deliveries.size).to eq(1) expect(UserMailer.deliveries.first.to.first).to eq(user.email) expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.suspicious_sign_in.subject')) diff --git a/spec/controllers/concerns/user_tracking_concern_spec.rb b/spec/controllers/concerns/user_tracking_concern_spec.rb index dd0b3c042a..b1de3cf4e2 100644 --- a/spec/controllers/concerns/user_tracking_concern_spec.rb +++ b/spec/controllers/concerns/user_tracking_concern_spec.rb @@ -75,7 +75,7 @@ describe UserTrackingConcern do expect(redis.ttl("account:#{user.account_id}:regeneration")).to be >= 0 end - it 'regenerates feed when sign in is older than two weeks' do + it 'regenerates feed when sign in is older than two weeks', :sidekiq_inline do get :show expect_updated_sign_in_at(user) diff --git a/spec/controllers/disputes/appeals_controller_spec.rb b/spec/controllers/disputes/appeals_controller_spec.rb index c8444a2a96..452bd60dc5 100644 --- a/spec/controllers/disputes/appeals_controller_spec.rb +++ b/spec/controllers/disputes/appeals_controller_spec.rb @@ -17,7 +17,7 @@ RSpec.describe Disputes::AppealsController do post :create, params: { strike_id: strike.id, appeal: { text: 'Foo' } } end - it 'notifies staff about new appeal' do + it 'notifies staff about new appeal', :sidekiq_inline do expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email]) end diff --git a/spec/controllers/settings/deletes_controller_spec.rb b/spec/controllers/settings/deletes_controller_spec.rb index 2c1532ecd8..ccca4564e7 100644 --- a/spec/controllers/settings/deletes_controller_spec.rb +++ b/spec/controllers/settings/deletes_controller_spec.rb @@ -50,7 +50,7 @@ describe Settings::DeletesController do delete :destroy, params: { form_delete_confirmation: { password: 'petsmoldoggos' } } end - it 'removes user record and redirects', :aggregate_failures do + it 'removes user record and redirects', :aggregate_failures, :sidekiq_inline do expect(response).to redirect_to '/auth/sign_in' expect(User.find_by(id: user.id)).to be_nil expect(user.account.reload).to be_suspended diff --git a/spec/controllers/settings/exports_controller_spec.rb b/spec/controllers/settings/exports_controller_spec.rb index 0bd1e80c3c..3399f78ac5 100644 --- a/spec/controllers/settings/exports_controller_spec.rb +++ b/spec/controllers/settings/exports_controller_spec.rb @@ -38,7 +38,7 @@ describe Settings::ExportsController do expect(response).to redirect_to(settings_export_path) end - it 'queues BackupWorker job by 1', :sidekiq_fake do + it 'queues BackupWorker job by 1' do expect do post :create end.to change(BackupWorker.jobs, :size).by(1) diff --git a/spec/features/admin/accounts_spec.rb b/spec/features/admin/accounts_spec.rb index 6d7bab1844..54d755b914 100644 --- a/spec/features/admin/accounts_spec.rb +++ b/spec/features/admin/accounts_spec.rb @@ -48,7 +48,7 @@ describe 'Admin::Accounts' do end end - context 'with action of `reject`' do + context 'with action of `reject`', :sidekiq_inline do it 'rejects and removes the account' do batch_checkbox_for(unapproved_user_account).check diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 8084427d06..3e3a4978c8 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -23,7 +23,7 @@ RSpec.describe ActivityPub::Activity::Create do stub_request(:get, 'http://example.com/emojib.png').to_return(body: attachment_fixture('emojo.png'), headers: { 'Content-Type' => 'application/octet-stream' }) end - describe 'processing posts received out of order', :sidekiq_fake do + describe 'processing posts received out of order' do let(:follower) { Fabricate(:account, username: 'bob') } let(:object_json) do diff --git a/spec/lib/activitypub/activity/delete_spec.rb b/spec/lib/activitypub/activity/delete_spec.rb index aec2c71e58..48421a1162 100644 --- a/spec/lib/activitypub/activity/delete_spec.rb +++ b/spec/lib/activitypub/activity/delete_spec.rb @@ -47,7 +47,7 @@ RSpec.describe ActivityPub::Activity::Delete do expect(Status.find_by(id: status.id)).to be_nil end - it 'sends delete activity to followers of rebloggers' do + it 'sends delete activity to followers of rebloggers', :sidekiq_inline do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end diff --git a/spec/lib/activitypub/activity/move_spec.rb b/spec/lib/activitypub/activity/move_spec.rb index f3973c70ce..4dda014a06 100644 --- a/spec/lib/activitypub/activity/move_spec.rb +++ b/spec/lib/activitypub/activity/move_spec.rb @@ -38,7 +38,7 @@ RSpec.describe ActivityPub::Activity::Move do subject.perform end - context 'when all conditions are met' do + context 'when all conditions are met', :sidekiq_inline do it 'sets moved account on old account' do expect(old_account.reload.moved_to_account_id).to eq new_account.id end diff --git a/spec/models/admin/account_action_spec.rb b/spec/models/admin/account_action_spec.rb index 5d64d565fc..9bc9f8061d 100644 --- a/spec/models/admin/account_action_spec.rb +++ b/spec/models/admin/account_action_spec.rb @@ -46,7 +46,7 @@ RSpec.describe Admin::AccountAction do expect(target_account).to be_suspended end - it 'queues Admin::SuspensionWorker by 1', :sidekiq_fake do + it 'queues Admin::SuspensionWorker by 1' do expect do subject end.to change { Admin::SuspensionWorker.jobs.size }.by 1 diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index ab5bd39b7b..c8415df92a 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -58,7 +58,7 @@ RSpec.describe User do end end - describe 'scopes' do + describe 'scopes', :sidekiq_inline do describe 'recent' do it 'returns an array of recent users ordered by id' do first_user = Fabricate(:user) @@ -452,7 +452,7 @@ RSpec.describe User do expect(user.confirmed_at).to be_present end - it 'delivers mails' do + it 'delivers mails', :sidekiq_inline do expect(ActionMailer::Base.deliveries.count).to eq 2 end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index e5d432b45f..783258b3af 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -26,7 +26,6 @@ Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f } ActiveRecord::Migration.maintain_test_schema! WebMock.disable_net_connect!(allow: Chewy.settings[:host], allow_localhost: RUN_SYSTEM_SPECS) -Sidekiq::Testing.inline! Sidekiq.logger = nil # System tests config @@ -96,11 +95,8 @@ RSpec.configure do |config| self.use_transactional_tests = true end - config.around(:each, :sidekiq_fake) do |example| - Sidekiq::Testing.fake! do - example.run - Sidekiq::Worker.clear_all - end + config.around(:each, :sidekiq_inline) do |example| + Sidekiq::Testing.inline!(&example) end config.before :each, type: :cli do diff --git a/spec/requests/api/v1/featured_tags_spec.rb b/spec/requests/api/v1/featured_tags_spec.rb index c4aa2c0a2d..f499dd1d09 100644 --- a/spec/requests/api/v1/featured_tags_spec.rb +++ b/spec/requests/api/v1/featured_tags_spec.rb @@ -147,7 +147,7 @@ RSpec.describe 'FeaturedTags' do expect(body).to be_empty end - it 'deletes the featured tag' do + it 'deletes the featured tag', :sidekiq_inline do delete "/api/v1/featured_tags/#{id}", headers: headers featured_tag = FeaturedTag.find_by(id: id) diff --git a/spec/requests/api/v1/notifications_spec.rb b/spec/requests/api/v1/notifications_spec.rb index 7a904816e0..222ff67fc8 100644 --- a/spec/requests/api/v1/notifications_spec.rb +++ b/spec/requests/api/v1/notifications_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'Notifications' do let(:scopes) { 'read:notifications write:notifications' } let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } - describe 'GET /api/v1/notifications' do + describe 'GET /api/v1/notifications', :sidekiq_inline do subject do get '/api/v1/notifications', headers: headers, params: params end diff --git a/spec/requests/api/v1/statuses/favourites_spec.rb b/spec/requests/api/v1/statuses/favourites_spec.rb index 8f3e6e5c42..033aed7e28 100644 --- a/spec/requests/api/v1/statuses/favourites_spec.rb +++ b/spec/requests/api/v1/statuses/favourites_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe 'Favourites' do +RSpec.describe 'Favourites', :sidekiq_inline do let(:user) { Fabricate(:user) } let(:scopes) { 'write:favourites' } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } @@ -70,7 +70,7 @@ RSpec.describe 'Favourites' do end end - describe 'POST /api/v1/statuses/:status_id/unfavourite', :sidekiq_fake do + describe 'POST /api/v1/statuses/:status_id/unfavourite' do subject do post "/api/v1/statuses/#{status.id}/unfavourite", headers: headers end @@ -88,9 +88,7 @@ RSpec.describe 'Favourites' do subject expect(response).to have_http_status(200) - expect(user.account.favourited?(status)).to be true - UnfavouriteWorker.drain expect(user.account.favourited?(status)).to be false end @@ -113,9 +111,7 @@ RSpec.describe 'Favourites' do subject expect(response).to have_http_status(200) - expect(user.account.favourited?(status)).to be true - UnfavouriteWorker.drain expect(user.account.favourited?(status)).to be false end diff --git a/spec/requests/api/v1/timelines/home_spec.rb b/spec/requests/api/v1/timelines/home_spec.rb index 5834b90955..e57e9643bf 100644 --- a/spec/requests/api/v1/timelines/home_spec.rb +++ b/spec/requests/api/v1/timelines/home_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe 'Home' do +describe 'Home', :sidekiq_inline do let(:user) { Fabricate(:user) } let(:scopes) { 'read:statuses' } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } diff --git a/spec/search/models/concerns/account/statuses_search_spec.rb b/spec/search/models/concerns/account/statuses_search_spec.rb index bf2606eece..915bc094cb 100644 --- a/spec/search/models/concerns/account/statuses_search_spec.rb +++ b/spec/search/models/concerns/account/statuses_search_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe Account::StatusesSearch do +describe Account::StatusesSearch, :sidekiq_inline do describe 'a non-indexable account becoming indexable' do let(:account) { Account.find_by(username: 'search_test_account_1') } diff --git a/spec/services/activitypub/fetch_remote_status_service_spec.rb b/spec/services/activitypub/fetch_remote_status_service_spec.rb index 3c64feaeec..0fb32d20b1 100644 --- a/spec/services/activitypub/fetch_remote_status_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_status_service_spec.rb @@ -225,7 +225,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do end end - context 'with statuses referencing other statuses' do + context 'with statuses referencing other statuses', :sidekiq_inline do before do stub_const 'ActivityPub::FetchRemoteStatusService::DISCOVERIES_PER_REQUEST', 5 end diff --git a/spec/services/activitypub/process_account_service_spec.rb b/spec/services/activitypub/process_account_service_spec.rb index 58dd2badbb..9abe03181e 100644 --- a/spec/services/activitypub/process_account_service_spec.rb +++ b/spec/services/activitypub/process_account_service_spec.rb @@ -193,7 +193,7 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do end end - it 'creates accounts without exceeding rate limit' do + it 'creates accounts without exceeding rate limit', :sidekiq_inline do expect { subject.call('user1', 'foo.test', payload) } .to create_some_remote_accounts .and create_fewer_than_rate_limit_accounts diff --git a/spec/services/authorize_follow_service_spec.rb b/spec/services/authorize_follow_service_spec.rb index d07645ab6b..602250ee96 100644 --- a/spec/services/authorize_follow_service_spec.rb +++ b/spec/services/authorize_follow_service_spec.rb @@ -41,7 +41,7 @@ RSpec.describe AuthorizeFollowService, type: :service do expect(bob.following?(sender)).to be true end - it 'sends an accept activity' do + it 'sends an accept activity', :sidekiq_inline do expect(a_request(:post, bob.inbox_url)).to have_been_made.once end end diff --git a/spec/services/batched_remove_status_service_spec.rb b/spec/services/batched_remove_status_service_spec.rb index 991a852f0e..1c59d5ed06 100644 --- a/spec/services/batched_remove_status_service_spec.rb +++ b/spec/services/batched_remove_status_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe BatchedRemoveStatusService, type: :service do +RSpec.describe BatchedRemoveStatusService, :sidekiq_inline, type: :service do subject { described_class.new } let!(:alice) { Fabricate(:account) } diff --git a/spec/services/block_domain_service_spec.rb b/spec/services/block_domain_service_spec.rb index fc3a1397d9..7ad00fff68 100644 --- a/spec/services/block_domain_service_spec.rb +++ b/spec/services/block_domain_service_spec.rb @@ -68,7 +68,7 @@ RSpec.describe BlockDomainService, type: :service do expect(already_banned_account.reload.silenced_at).to_not eq DomainBlock.find_by(domain: 'evil.org').created_at end - it 'leaves the domains status and attachments, but clears media' do + it 'leaves the domains status and attachments, but clears media', :sidekiq_inline do expect { bad_status_plain.reload }.to_not raise_error expect { bad_status_with_attachment.reload }.to_not raise_error expect { bad_attachment.reload }.to_not raise_error diff --git a/spec/services/block_service_spec.rb b/spec/services/block_service_spec.rb index 5f7c2e8da0..9e4ff8e598 100644 --- a/spec/services/block_service_spec.rb +++ b/spec/services/block_service_spec.rb @@ -31,7 +31,7 @@ RSpec.describe BlockService, type: :service do expect(sender.blocking?(bob)).to be true end - it 'sends a block activity' do + it 'sends a block activity', :sidekiq_inline do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/bulk_import_service_spec.rb b/spec/services/bulk_import_service_spec.rb index f703650c37..c3a7160580 100644 --- a/spec/services/bulk_import_service_spec.rb +++ b/spec/services/bulk_import_service_spec.rb @@ -12,7 +12,7 @@ RSpec.describe BulkImportService do import.update(total_items: import.rows.count) end - describe '#call', :sidekiq_fake do + describe '#call' do context 'when importing follows' do let(:import_type) { 'following' } let(:overwrite) { false } diff --git a/spec/services/delete_account_service_spec.rb b/spec/services/delete_account_service_spec.rb index f04ba9cf14..1965b7daab 100644 --- a/spec/services/delete_account_service_spec.rb +++ b/spec/services/delete_account_service_spec.rb @@ -62,7 +62,7 @@ RSpec.describe DeleteAccountService, type: :service do end end - describe '#call on local account' do + describe '#call on local account', :sidekiq_inline do before do stub_request(:post, remote_alice.inbox_url).to_return(status: 201) stub_request(:post, remote_bob.inbox_url).to_return(status: 201) @@ -83,7 +83,7 @@ RSpec.describe DeleteAccountService, type: :service do end end - describe '#call on remote account' do + describe '#call on remote account', :sidekiq_inline do before do stub_request(:post, account.inbox_url).to_return(status: 201) end diff --git a/spec/services/fan_out_on_write_service_spec.rb b/spec/services/fan_out_on_write_service_spec.rb index 6ad041193b..77237dffbd 100644 --- a/spec/services/fan_out_on_write_service_spec.rb +++ b/spec/services/fan_out_on_write_service_spec.rb @@ -38,7 +38,7 @@ RSpec.describe FanOutOnWriteService, type: :service do expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of a follower' do + it 'is added to the home feed of a follower', :sidekiq_inline do expect(home_feed_of(bob)).to include status.id expect(home_feed_of(tom)).to include status.id end @@ -62,7 +62,7 @@ RSpec.describe FanOutOnWriteService, type: :service do expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of the mentioned follower' do + it 'is added to the home feed of the mentioned follower', :sidekiq_inline do expect(home_feed_of(bob)).to include status.id end @@ -83,7 +83,7 @@ RSpec.describe FanOutOnWriteService, type: :service do expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of a follower' do + it 'is added to the home feed of a follower', :sidekiq_inline do expect(home_feed_of(bob)).to include status.id expect(home_feed_of(tom)).to include status.id end @@ -101,7 +101,7 @@ RSpec.describe FanOutOnWriteService, type: :service do expect(home_feed_of(alice)).to include status.id end - it 'is added to the home feed of the mentioned follower' do + it 'is added to the home feed of the mentioned follower', :sidekiq_inline do expect(home_feed_of(bob)).to include status.id end @@ -114,7 +114,7 @@ RSpec.describe FanOutOnWriteService, type: :service do expect(redis).to_not have_received(:publish).with('timeline:public', anything) end - context 'when handling status updates', :sidekiq_fake do + context 'when handling status updates' do before do subject.call(status) @@ -123,8 +123,6 @@ RSpec.describe FanOutOnWriteService, type: :service do status.snapshot!(account_id: status.account_id) redis.set("subscribed:timeline:#{eve.id}:notifications", '1') - - Sidekiq::Worker.clear_all end it 'pushes the update to mentioned users through the notifications streaming channel' do diff --git a/spec/services/favourite_service_spec.rb b/spec/services/favourite_service_spec.rb index 782c235c41..3143e7b669 100644 --- a/spec/services/favourite_service_spec.rb +++ b/spec/services/favourite_service_spec.rb @@ -33,7 +33,7 @@ RSpec.describe FavouriteService, type: :service do expect(status.favourites.first).to_not be_nil end - it 'sends a like activity' do + it 'sends a like activity', :sidekiq_inline do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/follow_service_spec.rb b/spec/services/follow_service_spec.rb index c2ad0d7173..cf4de34c89 100644 --- a/spec/services/follow_service_spec.rb +++ b/spec/services/follow_service_spec.rb @@ -150,7 +150,7 @@ RSpec.describe FollowService, type: :service do expect(FollowRequest.find_by(account: sender, target_account: bob)).to_not be_nil end - it 'sends a follow activity to the inbox' do + it 'sends a follow activity to the inbox', :sidekiq_inline do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/import_service_spec.rb b/spec/services/import_service_spec.rb index d67da66caf..7d005c8a11 100644 --- a/spec/services/import_service_spec.rb +++ b/spec/services/import_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe ImportService, type: :service do +RSpec.describe ImportService, :sidekiq_inline, type: :service do include RoutingHelper let!(:account) { Fabricate(:account, locked: false) } diff --git a/spec/services/mute_service_spec.rb b/spec/services/mute_service_spec.rb index 50f74ff277..a2ca2ffe13 100644 --- a/spec/services/mute_service_spec.rb +++ b/spec/services/mute_service_spec.rb @@ -17,7 +17,7 @@ RSpec.describe MuteService, type: :service do redis.del(home_timeline_key) end - it "clears account's statuses" do + it "clears account's statuses", :sidekiq_inline do FeedManager.instance.push_to_home(account, status) FeedManager.instance.push_to_home(account, other_account_status) diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb index 50055dafc7..38a33c522d 100644 --- a/spec/services/notify_service_spec.rb +++ b/spec/services/notify_service_spec.rb @@ -166,7 +166,7 @@ RSpec.describe NotifyService, type: :service do context 'when email notification is enabled' do let(:enabled) { true } - it 'sends email' do + it 'sends email', :sidekiq_inline do expect { subject }.to change(ActionMailer::Base.deliveries, :count).by(1) end end diff --git a/spec/services/reblog_service_spec.rb b/spec/services/reblog_service_spec.rb index 7b85e37ed8..c6d13e5a12 100644 --- a/spec/services/reblog_service_spec.rb +++ b/spec/services/reblog_service_spec.rb @@ -87,7 +87,7 @@ RSpec.describe ReblogService, type: :service do expect(ActivityPub::DistributionWorker).to have_received(:perform_async) end - it 'sends an announce activity to the author' do + it 'sends an announce activity to the author', :sidekiq_inline do expect(a_request(:post, bob.inbox_url)).to have_been_made.once end end diff --git a/spec/services/reject_follow_service_spec.rb b/spec/services/reject_follow_service_spec.rb index d28104b2c7..48316a6c4d 100644 --- a/spec/services/reject_follow_service_spec.rb +++ b/spec/services/reject_follow_service_spec.rb @@ -41,7 +41,7 @@ RSpec.describe RejectFollowService, type: :service do expect(bob.following?(sender)).to be false end - it 'sends a reject activity' do + it 'sends a reject activity', :sidekiq_inline do expect(a_request(:post, bob.inbox_url)).to have_been_made.once end end diff --git a/spec/services/remove_from_followers_service_spec.rb b/spec/services/remove_from_followers_service_spec.rb index 1b29cdcbea..21da38a97b 100644 --- a/spec/services/remove_from_followers_service_spec.rb +++ b/spec/services/remove_from_followers_service_spec.rb @@ -33,7 +33,7 @@ RSpec.describe RemoveFromFollowersService, type: :service do expect(bob.followed_by?(sender)).to be false end - it 'sends a reject activity' do + it 'sends a reject activity', :sidekiq_inline do expect(a_request(:post, sender.inbox_url)).to have_been_made.once end end diff --git a/spec/services/remove_status_service_spec.rb b/spec/services/remove_status_service_spec.rb index cd3224e028..63a9df548f 100644 --- a/spec/services/remove_status_service_spec.rb +++ b/spec/services/remove_status_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe RemoveStatusService, type: :service do +RSpec.describe RemoveStatusService, :sidekiq_inline, type: :service do subject { described_class.new } let!(:alice) { Fabricate(:account) } diff --git a/spec/services/report_service_spec.rb b/spec/services/report_service_spec.rb index 2a919f6405..39e14a6a1c 100644 --- a/spec/services/report_service_spec.rb +++ b/spec/services/report_service_spec.rb @@ -23,7 +23,7 @@ RSpec.describe ReportService, type: :service do stub_request(:post, 'http://example.com/inbox').to_return(status: 200) end - context 'when forward is true' do + context 'when forward is true', :sidekiq_inline do let(:forward) { true } it 'sends ActivityPub payload when forward is true' do diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb index 3c4b182e29..1c4c3b4016 100644 --- a/spec/services/resolve_account_service_spec.rb +++ b/spec/services/resolve_account_service_spec.rb @@ -195,7 +195,7 @@ RSpec.describe ResolveAccountService, type: :service do expect(account.uri).to eq 'https://ap.example.com/users/foo' end - it 'merges accounts' do + it 'merges accounts', :sidekiq_inline do account = subject.call('foo@ap.example.com') expect(status.reload.account_id).to eq account.id diff --git a/spec/services/suspend_account_service_spec.rb b/spec/services/suspend_account_service_spec.rb index dcc8dbfd37..4a5f8a0b6b 100644 --- a/spec/services/suspend_account_service_spec.rb +++ b/spec/services/suspend_account_service_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe SuspendAccountService, type: :service do +RSpec.describe SuspendAccountService, :sidekiq_inline, type: :service do shared_examples 'common behavior' do subject { described_class.new.call(account) } diff --git a/spec/services/unallow_domain_service_spec.rb b/spec/services/unallow_domain_service_spec.rb index d96e354187..6ac6bc4016 100644 --- a/spec/services/unallow_domain_service_spec.rb +++ b/spec/services/unallow_domain_service_spec.rb @@ -12,7 +12,7 @@ RSpec.describe UnallowDomainService, type: :service do let!(:already_banned_account) { Fabricate(:account, username: 'badguy', domain: 'evil.org', suspended: true, silenced: true) } let!(:domain_allow) { Fabricate(:domain_allow, domain: 'evil.org') } - context 'with limited federation mode' do + context 'with limited federation mode', :sidekiq_inline do before do allow(Rails.configuration.x).to receive(:limited_federation_mode).and_return(true) end diff --git a/spec/services/unblock_service_spec.rb b/spec/services/unblock_service_spec.rb index 86632c3938..9813c5e7fa 100644 --- a/spec/services/unblock_service_spec.rb +++ b/spec/services/unblock_service_spec.rb @@ -33,7 +33,7 @@ RSpec.describe UnblockService, type: :service do expect(sender.blocking?(bob)).to be false end - it 'sends an unblock activity' do + it 'sends an unblock activity', :sidekiq_inline do expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end diff --git a/spec/services/unfollow_service_spec.rb b/spec/services/unfollow_service_spec.rb index 3e65e610ba..18a25a676d 100644 --- a/spec/services/unfollow_service_spec.rb +++ b/spec/services/unfollow_service_spec.rb @@ -20,7 +20,7 @@ RSpec.describe UnfollowService, type: :service do end end - describe 'remote ActivityPub' do + describe 'remote ActivityPub', :sidekiq_inline do let(:bob) { Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } before do @@ -38,7 +38,7 @@ RSpec.describe UnfollowService, type: :service do end end - describe 'remote ActivityPub (reverse)' do + describe 'remote ActivityPub (reverse)', :sidekiq_inline do let(:bob) { Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } before do diff --git a/spec/services/unsuspend_account_service_spec.rb b/spec/services/unsuspend_account_service_spec.rb index 211c39e6c7..c848767cd1 100644 --- a/spec/services/unsuspend_account_service_spec.rb +++ b/spec/services/unsuspend_account_service_spec.rb @@ -45,7 +45,7 @@ RSpec.describe UnsuspendAccountService, type: :service do remote_follower.follow!(account) end - it 'merges back into feeds of local followers and sends update' do + it 'merges back into feeds of local followers and sends update', :sidekiq_inline do subject expect_feeds_merged diff --git a/spec/services/update_account_service_spec.rb b/spec/services/update_account_service_spec.rb index 6318cc95fb..9f4e36862d 100644 --- a/spec/services/update_account_service_spec.rb +++ b/spec/services/update_account_service_spec.rb @@ -5,7 +5,7 @@ require 'rails_helper' RSpec.describe UpdateAccountService, type: :service do subject { described_class.new } - describe 'switching form locked to unlocked accounts' do + describe 'switching form locked to unlocked accounts', :sidekiq_inline do let(:account) { Fabricate(:account, locked: true) } let(:alice) { Fabricate(:account) } let(:bob) { Fabricate(:account) } diff --git a/spec/services/update_status_service_spec.rb b/spec/services/update_status_service_spec.rb index 7f9f746c2a..55651c305d 100644 --- a/spec/services/update_status_service_spec.rb +++ b/spec/services/update_status_service_spec.rb @@ -111,7 +111,7 @@ RSpec.describe UpdateStatusService, type: :service do end end - context 'when poll changes', :sidekiq_fake do + context 'when poll changes' do let(:account) { Fabricate(:account) } let!(:status) { Fabricate(:status, text: 'Foo', account: account, poll_attributes: { options: %w(Foo Bar), account: account, multiple: false, hide_totals: false, expires_at: 7.days.from_now }) } let!(:poll) { status.poll } diff --git a/spec/system/new_statuses_spec.rb b/spec/system/new_statuses_spec.rb index 02f2e28393..a3b816b4d5 100644 --- a/spec/system/new_statuses_spec.rb +++ b/spec/system/new_statuses_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe 'NewStatuses' do +describe 'NewStatuses', :sidekiq_inline do include ProfileStories subject { page } diff --git a/spec/workers/backup_worker_spec.rb b/spec/workers/backup_worker_spec.rb index 1a169513e9..987cbc7d60 100644 --- a/spec/workers/backup_worker_spec.rb +++ b/spec/workers/backup_worker_spec.rb @@ -14,7 +14,7 @@ describe BackupWorker do let(:backup) { Fabricate(:backup) } let!(:other_backup) { Fabricate(:backup, user: backup.user) } - it 'sends the backup to the service and removes other backups' do + it 'sends the backup to the service and removes other backups', :sidekiq_inline do expect do worker.perform(backup.id) end.to change(UserMailer.deliveries, :size).by(1) diff --git a/spec/workers/move_worker_spec.rb b/spec/workers/move_worker_spec.rb index 34b342710b..0513dc42e5 100644 --- a/spec/workers/move_worker_spec.rb +++ b/spec/workers/move_worker_spec.rb @@ -104,7 +104,7 @@ describe MoveWorker do end shared_examples 'lists handling' do - it 'puts the new account on the list and makes valid lists', sidekiq: :inline do + it 'puts the new account on the list and makes valid lists', :sidekiq_inline do subject.perform(source_account.id, target_account.id) expect(list.accounts.include?(target_account)).to be true @@ -159,7 +159,7 @@ describe MoveWorker do describe '#perform' do context 'when both accounts are distant' do - it 'calls UnfollowFollowWorker', :sidekiq_fake do + it 'calls UnfollowFollowWorker' do subject.perform(source_account.id, target_account.id) expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, false) end @@ -170,7 +170,7 @@ describe MoveWorker do context 'when target account is local' do let(:target_account) { Fabricate(:account) } - it 'calls UnfollowFollowWorker', :sidekiq_fake do + it 'calls UnfollowFollowWorker' do subject.perform(source_account.id, target_account.id) expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, true) end diff --git a/spec/workers/poll_expiration_notify_worker_spec.rb b/spec/workers/poll_expiration_notify_worker_spec.rb index ca36a37590..4bd90270d8 100644 --- a/spec/workers/poll_expiration_notify_worker_spec.rb +++ b/spec/workers/poll_expiration_notify_worker_spec.rb @@ -10,7 +10,7 @@ describe PollExpirationNotifyWorker do let(:remote?) { false } let(:poll_vote) { Fabricate(:poll_vote, poll: poll) } - describe '#perform', :sidekiq_fake do + describe '#perform' do it 'runs without error for missing record' do expect { worker.perform(nil) }.to_not raise_error end From 543d7890fd818ed8871b0f8e6adbf19b605edf70 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 08:36:06 -0500 Subject: [PATCH 126/422] Use normalizes to prepare `User` values (#28650) Co-authored-by: Claire --- app/models/user.rb | 22 ++++-------------- spec/models/user_spec.rb | 50 ++++++++++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 55f654137a..0c589f8068 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -118,14 +118,15 @@ class User < ApplicationRecord scope :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) } scope :matches_ip, ->(value) { left_joins(:ips).where('user_ips.ip <<= ?', value).group('users.id') } - before_validation :sanitize_languages before_validation :sanitize_role - before_validation :sanitize_time_zone - before_validation :sanitize_locale before_create :set_approved after_commit :send_pending_devise_notifications after_create_commit :trigger_webhooks + normalizes :locale, with: ->(locale) { I18n.available_locales.exclude?(locale.to_sym) ? nil : locale } + normalizes :time_zone, with: ->(time_zone) { ActiveSupport::TimeZone[time_zone].nil? ? nil : time_zone } + normalizes :chosen_languages, with: ->(chosen_languages) { chosen_languages.compact_blank.presence } + # This avoids a deprecation warning from Rails 5.1 # It seems possible that a future release of devise-two-factor will # handle this itself, and this can be removed from our User class. @@ -447,25 +448,10 @@ class User < ApplicationRecord @bypass_invite_request_check end - def sanitize_languages - return if chosen_languages.nil? - - chosen_languages.compact_blank! - self.chosen_languages = nil if chosen_languages.empty? - end - def sanitize_role self.role = nil if role.present? && role.everyone? end - def sanitize_time_zone - self.time_zone = nil if time_zone.present? && ActiveSupport::TimeZone[time_zone].nil? - end - - def sanitize_locale - self.locale = nil if locale.present? && I18n.available_locales.exclude?(locale.to_sym) - end - def prepare_new_user! BootstrapTimelineWorker.perform_async(account_id) ActivityTracker.increment('activity:accounts:local') diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index c8415df92a..7f68671df4 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -38,23 +38,49 @@ RSpec.describe User do user.save(validate: false) expect(user.valid?).to be true end + end - it 'cleans out invalid locale' do - user = Fabricate.build(:user, locale: 'toto') - expect(user.valid?).to be true - expect(user.locale).to be_nil + describe 'Normalizations' do + describe 'locale' do + it 'preserves valid locale' do + user = Fabricate.build(:user, locale: 'en') + + expect(user.locale).to eq('en') + end + + it 'cleans out invalid locale' do + user = Fabricate.build(:user, locale: 'toto') + + expect(user.locale).to be_nil + end end - it 'cleans out invalid timezone' do - user = Fabricate.build(:user, time_zone: 'toto') - expect(user.valid?).to be true - expect(user.time_zone).to be_nil + describe 'time_zone' do + it 'preserves valid timezone' do + user = Fabricate.build(:user, time_zone: 'UTC') + + expect(user.time_zone).to eq('UTC') + end + + it 'cleans out invalid timezone' do + user = Fabricate.build(:user, time_zone: 'toto') + + expect(user.time_zone).to be_nil + end end - it 'cleans out empty string from languages' do - user = Fabricate.build(:user, chosen_languages: ['']) - user.valid? - expect(user.chosen_languages).to be_nil + describe 'languages' do + it 'preserves valid options for languages' do + user = Fabricate.build(:user, chosen_languages: ['en', 'fr', '']) + + expect(user.chosen_languages).to eq(['en', 'fr']) + end + + it 'cleans out empty string from languages' do + user = Fabricate.build(:user, chosen_languages: ['']) + + expect(user.chosen_languages).to be_nil + end end end From 8422b8ded0fa0ac1fdb70e6fb494ef5453b845d9 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 10 Jan 2024 09:54:11 -0500 Subject: [PATCH 127/422] Extract capybara config and improve headless_chrome driver config (#28681) --- spec/rails_helper.rb | 2 -- spec/support/capybara.rb | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 spec/support/capybara.rb diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 783258b3af..aabb121fc3 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -108,8 +108,6 @@ RSpec.configure do |config| end config.around :each, type: :system do |example| - driven_by :selenium, using: :headless_chrome, screen_size: [1600, 1200] - # The streaming server needs access to the database # but with use_transactional_tests every transaction # is rolled-back, so the streaming server never sees the data diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb new file mode 100644 index 0000000000..d4f27e209e --- /dev/null +++ b/spec/support/capybara.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +Capybara.server_host = 'localhost' +Capybara.server_port = 3000 +Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}" + +require 'selenium/webdriver' + +Capybara.register_driver :chrome do |app| + Capybara::Selenium::Driver.new(app, browser: :chrome) +end + +Capybara.register_driver :headless_chrome do |app| + options = Selenium::WebDriver::Chrome::Options.new + options.add_argument '--headless=new' + options.add_argument '--window-size=1680,1050' + + Capybara::Selenium::Driver.new( + app, + browser: :chrome, + options: options + ) +end + +Capybara.javascript_driver = :headless_chrome + +RSpec.configure do |config| + config.before(:each, type: :system) do + driven_by Capybara.javascript_driver + end +end From d7e13e248380704895674949bf870ac5e8d8387b Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 10 Jan 2024 16:05:46 +0100 Subject: [PATCH 128/422] Fix potential redirection loop of streaming endpoint (#28665) --- app/controllers/api/v1/streaming_controller.rb | 7 ++++++- spec/controllers/api/v1/streaming_controller_spec.rb | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/streaming_controller.rb b/app/controllers/api/v1/streaming_controller.rb index 0cb6e856f2..adb14676e1 100644 --- a/app/controllers/api/v1/streaming_controller.rb +++ b/app/controllers/api/v1/streaming_controller.rb @@ -2,7 +2,7 @@ class Api::V1::StreamingController < Api::BaseController def index - if Rails.configuration.x.streaming_api_base_url == request.host + if same_host? not_found else redirect_to streaming_api_url, status: 301, allow_other_host: true @@ -11,6 +11,11 @@ class Api::V1::StreamingController < Api::BaseController private + def same_host? + base_url = Addressable::URI.parse(Rails.configuration.x.streaming_api_base_url) + request.host == base_url.host && request.port == (base_url.port || 80) + end + def streaming_api_url Addressable::URI.parse(request.url).tap do |uri| base_url = Addressable::URI.parse(Rails.configuration.x.streaming_api_base_url) diff --git a/spec/controllers/api/v1/streaming_controller_spec.rb b/spec/controllers/api/v1/streaming_controller_spec.rb index c3e7153ce8..099f68a74e 100644 --- a/spec/controllers/api/v1/streaming_controller_spec.rb +++ b/spec/controllers/api/v1/streaming_controller_spec.rb @@ -5,7 +5,7 @@ require 'rails_helper' describe Api::V1::StreamingController do around do |example| before = Rails.configuration.x.streaming_api_base_url - Rails.configuration.x.streaming_api_base_url = Rails.configuration.x.web_domain + Rails.configuration.x.streaming_api_base_url = "wss://#{Rails.configuration.x.web_domain}" example.run Rails.configuration.x.streaming_api_base_url = before end From 0a7cff53c2577b3e79599e069eeb344f2613ad8d Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 04:30:29 -0500 Subject: [PATCH 129/422] Add coverage for `Account.followable_by` scope (#28689) --- spec/models/account_spec.rb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 87aa8bc754..b4fcb805a6 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -1009,4 +1009,27 @@ RSpec.describe Account do expect(subject.reload.followers_count).to eq 15 end end + + describe '.followable_by' do + context 'with follows and follow requests' do + let!(:account) { Fabricate(:account) } + let!(:eligible_account) { Fabricate(:account) } + let!(:following_account) { Fabricate(:account) } + let!(:follow_requested_account) { Fabricate(:account) } + + before do + Fabricate :follow, account: account, target_account: following_account + Fabricate :follow_request, account: account, target_account: follow_requested_account + end + + it 'returns accounts not already following or requested to follow' do + results = described_class.followable_by(account) + + expect(results) + .to include(eligible_account) + .and not_include(following_account) + .and not_include(follow_requested_account) + end + end + end end From 6daa69327b32a46cc36a03b18dede42154ca6ffa Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 04:32:32 -0500 Subject: [PATCH 130/422] Fix `LineLength` haml-lint in `t` usage (#28686) --- .../admin/account_warnings/_account_warning.html.haml | 5 ++++- app/views/admin/action_logs/_action_log.html.haml | 4 +++- app/views/mail_subscriptions/show.html.haml | 6 +++++- app/views/user_mailer/appeal_approved.html.haml | 4 +++- app/views/user_mailer/appeal_rejected.html.haml | 4 +++- app/views/user_mailer/suspicious_sign_in.html.haml | 8 ++++++-- 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/app/views/admin/account_warnings/_account_warning.html.haml b/app/views/admin/account_warnings/_account_warning.html.haml index 85bac789f7..5702e4f6d2 100644 --- a/app/views/admin/account_warnings/_account_warning.html.haml +++ b/app/views/admin/account_warnings/_account_warning.html.haml @@ -5,7 +5,10 @@ = fa_icon 'warning' .log-entry__content .log-entry__title - = t(account_warning.action, scope: 'admin.strikes.actions', name: content_tag(:span, account_warning.account ? account_warning.account.username : I18n.t('admin.action_logs.deleted_account'), class: 'username'), target: content_tag(:span, account_warning.target_account.pretty_acct, class: 'target')).html_safe + = t(account_warning.action, + scope: 'admin.strikes.actions', + name: content_tag(:span, account_warning.account ? account_warning.account.username : I18n.t('admin.action_logs.deleted_account'), class: 'username'), + target: content_tag(:span, account_warning.target_account.pretty_acct, class: 'target')).html_safe .log-entry__timestamp %time.formatted{ datetime: account_warning.created_at.iso8601 } = l(account_warning.created_at) diff --git a/app/views/admin/action_logs/_action_log.html.haml b/app/views/admin/action_logs/_action_log.html.haml index a2fce2d114..dcc3331809 100644 --- a/app/views/admin/action_logs/_action_log.html.haml +++ b/app/views/admin/action_logs/_action_log.html.haml @@ -4,6 +4,8 @@ = image_tag action_log.account.avatar.url(:original), alt: '', width: 40, height: 40, class: 'avatar' .log-entry__content .log-entry__title - = t("admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}_html", name: content_tag(:span, action_log.account.username, class: 'username'), target: content_tag(:span, log_target(action_log), class: 'target')) + = t "admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}_html", + name: content_tag(:span, action_log.account.username, class: 'username'), + target: content_tag(:span, log_target(action_log), class: 'target') .log-entry__timestamp %time.formatted{ datetime: action_log.created_at.iso8601 } diff --git a/app/views/mail_subscriptions/show.html.haml b/app/views/mail_subscriptions/show.html.haml index afa2ab6ed7..776d561d70 100644 --- a/app/views/mail_subscriptions/show.html.haml +++ b/app/views/mail_subscriptions/show.html.haml @@ -4,7 +4,11 @@ .simple_form %h1.title= t('mail_subscriptions.unsubscribe.title') %p.lead - = t('mail_subscriptions.unsubscribe.confirmation_html', domain: content_tag(:strong, site_hostname), type: content_tag(:strong, I18n.t(@type, scope: 'mail_subscriptions.unsubscribe.emails')), email: content_tag(:strong, @user.email), settings_path: settings_preferences_notifications_path) + = t 'mail_subscriptions.unsubscribe.confirmation_html', + domain: content_tag(:strong, site_hostname), + type: content_tag(:strong, I18n.t(@type, scope: 'mail_subscriptions.unsubscribe.emails')), + email: content_tag(:strong, @user.email), + settings_path: settings_preferences_notifications_path = form_tag unsubscribe_path, method: :post do = hidden_field_tag :token, params[:token] diff --git a/app/views/user_mailer/appeal_approved.html.haml b/app/views/user_mailer/appeal_approved.html.haml index 3a2de822f4..223ba7f0b8 100644 --- a/app/views/user_mailer/appeal_approved.html.haml +++ b/app/views/user_mailer/appeal_approved.html.haml @@ -36,7 +36,9 @@ %tbody %tr %td.column-cell.text-center - %p= t 'user_mailer.appeal_approved.explanation', appeal_date: l(@appeal.created_at.in_time_zone(@resource.time_zone.presence), format: :with_time_zone), strike_date: l(@appeal.strike.created_at.in_time_zone(@resource.time_zone.presence), format: :with_time_zone) + %p= t 'user_mailer.appeal_approved.explanation', + appeal_date: l(@appeal.created_at.in_time_zone(@resource.time_zone.presence), format: :with_time_zone), + strike_date: l(@appeal.strike.created_at.in_time_zone(@resource.time_zone.presence), format: :with_time_zone) %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/app/views/user_mailer/appeal_rejected.html.haml b/app/views/user_mailer/appeal_rejected.html.haml index ccbd1c4bad..59354f1d40 100644 --- a/app/views/user_mailer/appeal_rejected.html.haml +++ b/app/views/user_mailer/appeal_rejected.html.haml @@ -36,7 +36,9 @@ %tbody %tr %td.column-cell.text-center - %p= t 'user_mailer.appeal_rejected.explanation', appeal_date: l(@appeal.created_at.in_time_zone(@resource.time_zone.presence), format: :with_time_zone), strike_date: l(@appeal.strike.created_at.in_time_zone(@resource.time_zone.presence), format: :with_time_zone) + %p= t 'user_mailer.appeal_rejected.explanation', + appeal_date: l(@appeal.created_at.in_time_zone(@resource.time_zone.presence), format: :with_time_zone), + strike_date: l(@appeal.strike.created_at.in_time_zone(@resource.time_zone.presence), format: :with_time_zone) %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/app/views/user_mailer/suspicious_sign_in.html.haml b/app/views/user_mailer/suspicious_sign_in.html.haml index 5bafe9d1b2..0cd21b4e60 100644 --- a/app/views/user_mailer/suspicious_sign_in.html.haml +++ b/app/views/user_mailer/suspicious_sign_in.html.haml @@ -45,7 +45,10 @@ = @remote_ip %br/ %strong #{t('sessions.browser')}: - %span{ title: @user_agent }= t 'sessions.description', browser: t("sessions.browsers.#{@detection.id}", default: @detection.id.to_s), platform: t("sessions.platforms.#{@detection.platform.id}", default: @detection.platform.id.to_s) + %span{ title: @user_agent } + = t 'sessions.description', + browser: t("sessions.browsers.#{@detection.id}", default: @detection.id.to_s), + platform: t("sessions.platforms.#{@detection.platform.id}", default: @detection.platform.id.to_s) %br/ = l(@timestamp.in_time_zone(@resource.time_zone.presence), format: :with_time_zone) @@ -64,4 +67,5 @@ %tbody %tr %td.column-cell.text-center - %p= t 'user_mailer.suspicious_sign_in.further_actions_html', action: link_to(t('user_mailer.suspicious_sign_in.change_password'), edit_user_registration_url) + %p= t 'user_mailer.suspicious_sign_in.further_actions_html', + action: link_to(t('user_mailer.suspicious_sign_in.change_password'), edit_user_registration_url) From 204bbf49d20ff34ad6559aa0166db68340b72d29 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 11:08:49 +0100 Subject: [PATCH 131/422] New Crowdin Translations (automated) (#28692) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/br.json | 22 +++++++++++++++++++--- app/javascript/mastodon/locales/pl.json | 4 ++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index 462a5b3393..ad6e55c5e1 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -1,5 +1,5 @@ { - "about.blocks": "Servijerioù habaskaet", + "about.blocks": "Servijerioù evezhiet", "about.contact": "Darempred :", "about.disclaimer": "Mastodon zo ur meziant frank, open-source hag ur merk marilhet eus Mastodon gGmbH.", "about.domain_blocks.no_reason_available": "Abeg dihegerz", @@ -22,6 +22,7 @@ "account.browse_more_on_origin_server": "Furchal pelloc'h war ar profil orin", "account.cancel_follow_request": "Nullañ ar reked heuliañ", "account.copy": "Eilañ al liamm war-zu ho profil", + "account.direct": "Menegiñ @{name} ent-prevez", "account.disable_notifications": "Paouez d'am c'hemenn pa vez embannet traoù gant @{name}", "account.domain_blocked": "Domani stanket", "account.edit_profile": "Kemmañ ar profil", @@ -68,6 +69,7 @@ "account.unendorse": "Paouez da lakaat war-wel war ar profil", "account.unfollow": "Diheuliañ", "account.unmute": "Diguzhat @{name}", + "account.unmute_notifications_short": "Diguzhat ar c'hemennoù", "account.unmute_short": "Diguzhat", "account_note.placeholder": "Klikit evit ouzhpennañ un notenn", "admin.dashboard.daily_retention": "Feur azdalc'h an implijerien·ezed dre zeiz goude bezañ lakaet o anv", @@ -75,6 +77,9 @@ "admin.dashboard.retention.average": "Keidenn", "admin.dashboard.retention.cohort": "Miz an enrolladur", "admin.dashboard.retention.cohort_size": "Implijerien.erezed nevez", + "admin.impact_report.instance_accounts": "Profiloù kontoù a vefe dilamet", + "admin.impact_report.instance_followers": "Heulierien a gollfe hon implijerien", + "admin.impact_report.instance_follows": "Heulierien a gollfe o implijerien", "alert.rate_limited.message": "Klaskit en-dro a-benn {retry_time, time, medium}.", "alert.rate_limited.title": "Feur bevennet", "alert.unexpected.message": "Ur fazi dic'hortozet zo degouezhet.", @@ -105,6 +110,7 @@ "column.blocks": "Implijer·ezed·ien berzet", "column.bookmarks": "Sinedoù", "column.community": "Red-amzer lec'hel", + "column.direct": "Menegoù prevez", "column.directory": "Mont a-dreuz ar profiloù", "column.domain_blocks": "Domani berzet", "column.favourites": "Muiañ-karet", @@ -348,6 +354,7 @@ "lightbox.next": "Da-heul", "lightbox.previous": "A-raok", "limited_account_hint.action": "Diskouez an aelad memes tra", + "limited_account_hint.title": "Kuzhet eo bet ar profil-mañ gant an evezhierien eus {domain}.", "link_preview.author": "Gant {name}", "lists.account.add": "Ouzhpennañ d'al listenn", "lists.account.remove": "Lemel kuit eus al listenn", @@ -373,6 +380,7 @@ "navigation_bar.bookmarks": "Sinedoù", "navigation_bar.community_timeline": "Red-amzer lec'hel", "navigation_bar.compose": "Skrivañ un toud nevez", + "navigation_bar.direct": "Menegoù prevez", "navigation_bar.discover": "Dizoleiñ", "navigation_bar.domain_blocks": "Domanioù kuzhet", "navigation_bar.edit_profile": "Kemmañ ar profil", @@ -452,6 +460,7 @@ "onboarding.profile.note_hint": "Gallout a rit @menegiñ tud all pe #hashtagoù…", "onboarding.profile.save_and_continue": "Enrollañ ha kenderc'hel", "onboarding.profile.upload_avatar": "Enporzhiañ ur skeudenn profil", + "onboarding.share.lead": "Roit da c'houzout d'an dud e c'hallont ho kavout war vMastondon!", "onboarding.share.message": "Me a zo {username} war #Mastodon! Heuilhit ac'hanon war {url}", "onboarding.share.title": "Skignañ ho profil", "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", @@ -465,6 +474,7 @@ "onboarding.steps.setup_profile.title": "Customize your profile", "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", "onboarding.steps.share_profile.title": "Share your profile", + "password_confirmation.mismatching": "Disheñvel eo an daou c'her-termen-se", "picture_in_picture.restore": "Adlakaat", "poll.closed": "Serret", "poll.refresh": "Azbevaat", @@ -545,6 +555,7 @@ "report_notification.categories.spam": "Spam", "report_notification.categories.violation": "Torradur da reolennoù ar servijer", "report_notification.open": "Digeriñ an disklêriadur", + "search.no_recent_searches": "Klask nevez ebet", "search.placeholder": "Klask", "search.quick_action.account_search": "Profiloù a glot gant {x}", "search.quick_action.go_to_account": "Mont d'ar profil {x}", @@ -572,8 +583,10 @@ "server_banner.server_stats": "Stadegoù ar servijer :", "sign_in_banner.create_account": "Krouiñ ur gont", "sign_in_banner.sign_in": "Kevreañ", - "status.admin_account": "Digeriñ etrefas evezherezh evit @{name}", - "status.admin_status": "Digeriñ an toud e-barzh an etrefas evezherezh", + "sign_in_banner.sso_redirect": "Kennaskañ pe lakaat hoc'h anv", + "status.admin_account": "Digeriñ etrefas evezhiañ evit @{name}", + "status.admin_domain": "Digeriñ an etrefas evezhiañ evit {domain}", + "status.admin_status": "Digeriñ an embannadenn e-barzh an etrefas evezhiañ", "status.block": "Berzañ @{name}", "status.bookmark": "Ouzhpennañ d'ar sinedoù", "status.cancel_reblog_private": "Nac'hañ ar skignadenn", @@ -581,6 +594,8 @@ "status.copy": "Eilañ liamm ar c'hannad", "status.delete": "Dilemel", "status.detailed_status": "Gwel kaozeadenn munudek", + "status.direct": "Menegiñ @{name} ent-prevez", + "status.direct_indicator": "Meneg prevez", "status.edit": "Kemmañ", "status.edited": "Aozet {date}", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", @@ -624,6 +639,7 @@ "status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}", "status.translate": "Treiñ", "status.translated_from_with": "Troet diwar {lang} gant {provider}", + "status.uncached_media_warning": "Rakwel n'eo ket da gaout", "status.unmute_conversation": "Diguzhat ar gaozeadenn", "status.unpin": "Dispilhennañ eus ar profil", "subscribed_languages.save": "Enrollañ ar cheñchamantoù", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 9a3710da71..35dbc6661d 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -42,7 +42,7 @@ "account.go_to_profile": "Przejdź do profilu", "account.hide_reblogs": "Ukryj podbicia od @{name}", "account.in_memoriam": "Ku pamięci.", - "account.joined_short": "Dołączony", + "account.joined_short": "Dołączył(a)", "account.languages": "Zmień subskrybowane języki", "account.link_verified_on": "Własność tego odnośnika została potwierdzona {date}", "account.locked_info": "To konto jest prywatne. Właściciel ręcznie wybiera kto może go obserwować.", @@ -492,7 +492,7 @@ "onboarding.profile.save_and_continue": "Zapisz i kontynuuj", "onboarding.profile.title": "Ustawienia profilu", "onboarding.profile.upload_avatar": "Dodaj zdjęcie profilowe", - "onboarding.profile.upload_header": "Dodaj zdjęcie nagłówkowe", + "onboarding.profile.upload_header": "Dodaj banner profilu", "onboarding.share.lead": "Daj znać ludziom, jak mogą cię znaleźć na Mastodonie!", "onboarding.share.message": "Jestem {username} na #Mastodon! Śledź mnie tutaj {url}", "onboarding.share.next_steps": "Możliwe dalsze kroki:", From 55802242ce65dcea36b74fffcb3474e8254192f7 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 05:36:27 -0500 Subject: [PATCH 132/422] Refactor login activity partial (remove inline ruby) (#28687) --- app/helpers/admin/settings_helper.rb | 56 +++++++++++++++++++ .../_login_activity.html.haml | 10 +--- .../login_activities_controller_spec.rb | 5 ++ 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/app/helpers/admin/settings_helper.rb b/app/helpers/admin/settings_helper.rb index 552a3ee5a8..6937331e1a 100644 --- a/app/helpers/admin/settings_helper.rb +++ b/app/helpers/admin/settings_helper.rb @@ -4,4 +4,60 @@ module Admin::SettingsHelper def captcha_available? ENV['HCAPTCHA_SECRET_KEY'].present? && ENV['HCAPTCHA_SITE_KEY'].present? end + + def login_activity_title(activity) + t( + "login_activities.#{login_activity_key(activity)}", + method: login_activity_method(activity), + ip: login_activity_ip(activity), + browser: login_activity_browser(activity) + ) + end + + private + + def login_activity_key(activity) + activity.success? ? 'successful_sign_in_html' : 'failed_sign_in_html' + end + + def login_activity_method(activity) + content_tag( + :span, + login_activity_method_string(activity), + class: 'target' + ) + end + + def login_activity_ip(activity) + content_tag( + :span, + activity.ip, + class: 'target' + ) + end + + def login_activity_browser(activity) + content_tag( + :span, + login_activity_browser_description(activity), + class: 'target', + title: activity.user_agent + ) + end + + def login_activity_method_string(activity) + if activity.omniauth? + t("auth.providers.#{activity.provider}") + else + t("login_activities.authentication_methods.#{activity.authentication_method}") + end + end + + def login_activity_browser_description(activity) + t( + 'sessions.description', + browser: t(activity.browser, scope: 'sessions.browsers', default: activity.browser.to_s), + platform: t(activity.platform, scope: 'sessions.platforms', default: activity.platform.to_s) + ) + end end diff --git a/app/views/settings/login_activities/_login_activity.html.haml b/app/views/settings/login_activities/_login_activity.html.haml index 2e001cdcef..36314926a3 100644 --- a/app/views/settings/login_activities/_login_activity.html.haml +++ b/app/views/settings/login_activities/_login_activity.html.haml @@ -1,8 +1,3 @@ -:ruby - method_str = content_tag(:span, login_activity.omniauth? ? t(login_activity.provider, scope: 'auth.providers') : t(login_activity.authentication_method, scope: 'login_activities.authentication_methods'), class: 'target') - ip_str = content_tag(:span, login_activity.ip, class: 'target') - browser_str = content_tag(:span, t('sessions.description', browser: t("sessions.browsers.#{login_activity.browser}", default: login_activity.browser.to_s), platform: t("sessions.platforms.#{login_activity.platform}", default: login_activity.platform.to_s)), class: 'target', title: login_activity.user_agent) - .log-entry .log-entry__header .log-entry__avatar @@ -10,9 +5,6 @@ = fa_icon login_activity.success? ? 'check' : 'times' .log-entry__content .log-entry__title - - if login_activity.success? - = t('login_activities.successful_sign_in_html', method: method_str, ip: ip_str, browser: browser_str) - - else - = t('login_activities.failed_sign_in_html', method: method_str, ip: ip_str, browser: browser_str) + = login_activity_title(login_activity) .log-entry__timestamp %time.formatted{ datetime: login_activity.created_at.iso8601 }= l(login_activity.created_at) diff --git a/spec/controllers/settings/login_activities_controller_spec.rb b/spec/controllers/settings/login_activities_controller_spec.rb index 4f266e03dd..294bf85c97 100644 --- a/spec/controllers/settings/login_activities_controller_spec.rb +++ b/spec/controllers/settings/login_activities_controller_spec.rb @@ -6,6 +6,7 @@ describe Settings::LoginActivitiesController do render_views let!(:user) { Fabricate(:user) } + let!(:login_activity) { Fabricate :login_activity, user: user } before do sign_in user, scope: :user @@ -19,6 +20,10 @@ describe Settings::LoginActivitiesController do it 'returns http success with private cache control headers', :aggregate_failures do expect(response).to have_http_status(200) expect(response.headers['Cache-Control']).to include('private, no-store') + expect(response.body) + .to include(login_activity.user_agent) + .and include(login_activity.authentication_method) + .and include(login_activity.ip.to_s) end end end From 87097a227c2ab24f27b0d87ec6808c07cb13d93a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 05:45:26 -0500 Subject: [PATCH 133/422] Clean up `settings/featured_tags/index` view (#28688) --- app/helpers/settings_helper.rb | 27 +++++++++++++++++++ .../settings/featured_tags/index.html.haml | 2 +- .../settings/featured_tags_controller_spec.rb | 10 +++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index 3c72b22c66..10863a316c 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -9,6 +9,19 @@ module SettingsHelper LanguagesHelper.sorted_locale_keys(I18n.available_locales) end + def featured_tags_hint(recently_used_tags) + safe_join( + [ + t('simple_form.hints.featured_tag.name'), + safe_join( + links_for_featured_tags(recently_used_tags), + ', ' + ), + ], + ' ' + ) + end + def session_device_icon(session) device = session.detection.device @@ -28,4 +41,18 @@ module SettingsHelper safe_join([image_tag(account.avatar.url, width: 15, height: 15, alt: '', class: 'avatar'), content_tag(:span, account.acct, class: 'username')], ' ') end end + + private + + def links_for_featured_tags(tags) + tags.map { |tag| post_link_to_featured_tag(tag) } + end + + def post_link_to_featured_tag(tag) + link_to( + "##{tag.display_name}", + settings_featured_tags_path(featured_tag: { name: tag.name }), + method: :post + ) + end end diff --git a/app/views/settings/featured_tags/index.html.haml b/app/views/settings/featured_tags/index.html.haml index 22f9180129..c8c9ec4069 100644 --- a/app/views/settings/featured_tags/index.html.haml +++ b/app/views/settings/featured_tags/index.html.haml @@ -12,7 +12,7 @@ .fields-group = f.input :name, - hint: safe_join([t('simple_form.hints.featured_tag.name'), safe_join(@recently_used_tags.map { |tag| link_to("##{tag.display_name}", settings_featured_tags_path(featured_tag: { name: tag.name }), method: :post) }, ', ')], ' '), + hint: featured_tags_hint(@recently_used_tags), wrapper: :with_block_label .actions diff --git a/spec/controllers/settings/featured_tags_controller_spec.rb b/spec/controllers/settings/featured_tags_controller_spec.rb index fc25e7aa88..4e1dd52945 100644 --- a/spec/controllers/settings/featured_tags_controller_spec.rb +++ b/spec/controllers/settings/featured_tags_controller_spec.rb @@ -43,10 +43,20 @@ describe Settings::FeaturedTagsController do end describe 'GET to #index' do + let(:tag) { Fabricate(:tag) } + + before do + status = Fabricate :status, account: user.account + status.tags << tag + end + it 'responds with success' do get :index expect(response).to have_http_status(200) + expect(response.body).to include( + settings_featured_tags_path(featured_tag: { name: tag.name }) + ) end end From 4e08a4892f01188255e803b87f641ef019bdb883 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 05:54:42 -0500 Subject: [PATCH 134/422] Move streaming `around` config into manager class (#28684) --- spec/rails_helper.rb | 15 --------------- spec/support/streaming_server_manager.rb | 13 +++++++++++++ 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index aabb121fc3..aaf587f49b 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -107,21 +107,6 @@ RSpec.configure do |config| Capybara.current_driver = :rack_test end - config.around :each, type: :system do |example| - # The streaming server needs access to the database - # but with use_transactional_tests every transaction - # is rolled-back, so the streaming server never sees the data - # So we disable this feature for system tests, and use DatabaseCleaner to clean - # the database tables between each test - self.use_transactional_tests = false - - DatabaseCleaner.cleaning do - example.run - end - - self.use_transactional_tests = true - end - config.before do |example| allow(Resolv::DNS).to receive(:open).and_raise('Real DNS queries are disabled, stub Resolv::DNS as needed') unless example.metadata[:type] == :system end diff --git a/spec/support/streaming_server_manager.rb b/spec/support/streaming_server_manager.rb index 2c535767e2..39657586f2 100644 --- a/spec/support/streaming_server_manager.rb +++ b/spec/support/streaming_server_manager.rb @@ -95,6 +95,19 @@ RSpec.configure do |config| end end + config.around :each, type: :system do |example| + # Streaming server needs DB access but `use_transactional_tests` rolls back + # every transaction. Disable this feature for streaming tests, and use + # DatabaseCleaner to clean the database tables between each test. + self.use_transactional_tests = false + + DatabaseCleaner.cleaning do + example.run + end + + self.use_transactional_tests = true + end + private def streaming_server_manager From 3f3df9ab201c588a9a849a78f5cdccb9f16b5fac Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 05:57:52 -0500 Subject: [PATCH 135/422] Update omniauth-cas to version 3.0.0 (#28683) --- Gemfile | 5 ++--- Gemfile.lock | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index e096a5d685..a393b14471 100644 --- a/Gemfile +++ b/Gemfile @@ -39,9 +39,8 @@ end gem 'net-ldap', '~> 0.18' -# TODO: Point back at released omniauth-cas gem when PR merged -# https://github.com/dlindahl/omniauth-cas/pull/68 -gem 'omniauth-cas', github: 'stanhu/omniauth-cas', ref: '4211e6d05941b4a981f9a36b49ec166cecd0e271' +# TODO: Point back at released omniauth-cas gem when new version is released +gem 'omniauth-cas', github: 'dlindahl/omniauth-cas', ref: '9d9d3a91b316c55d49ab6e621977f2067010c5bf' gem 'omniauth-saml', '~> 2.0' gem 'omniauth_openid_connect', '~> 0.6.1' gem 'omniauth', '~> 2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 595c9fd279..ccb9f4b115 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,6 +7,16 @@ GIT hkdf (~> 0.2) jwt (~> 2.0) +GIT + remote: https://github.com/dlindahl/omniauth-cas.git + revision: 9d9d3a91b316c55d49ab6e621977f2067010c5bf + ref: 9d9d3a91b316c55d49ab6e621977f2067010c5bf + specs: + omniauth-cas (3.0.0) + addressable (~> 2.8) + nokogiri (~> 1.12) + omniauth (~> 2.1) + GIT remote: https://github.com/jhawthorn/nsa.git revision: e020fcc3a54d993ab45b7194d89ab720296c111b @@ -18,16 +28,6 @@ GIT sidekiq (>= 3.5) statsd-ruby (~> 1.4, >= 1.4.0) -GIT - remote: https://github.com/stanhu/omniauth-cas.git - revision: 4211e6d05941b4a981f9a36b49ec166cecd0e271 - ref: 4211e6d05941b4a981f9a36b49ec166cecd0e271 - specs: - omniauth-cas (2.0.0) - addressable (~> 2.3) - nokogiri (~> 1.5) - omniauth (>= 1.2, < 3) - GEM remote: https://rubygems.org/ specs: From 782a0165c700933840ba2297f8b67147979b8631 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:48:01 +0100 Subject: [PATCH 136/422] Update dependency node to 20.11 (#28670) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index d4c3d320cc..a3597ecbd1 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.10 +20.11 From b68f185573158dedabe4b78bdf86a0cfaa5abb96 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 08:14:24 -0500 Subject: [PATCH 137/422] Reduce `LineLength` for `react_component` helper in views/admin (#28694) --- .../admin/reports/_media_attachments.html.haml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/views/admin/reports/_media_attachments.html.haml b/app/views/admin/reports/_media_attachments.html.haml index 8ecd7444d2..3c52d69178 100644 --- a/app/views/admin/reports/_media_attachments.html.haml +++ b/app/views/admin/reports/_media_attachments.html.haml @@ -2,6 +2,16 @@ = render_video_component(status, visible: false) - elsif status.ordered_media_attachments.first.audio? - audio = status.ordered_media_attachments.first - = react_component :audio, src: audio.file.url(:original), height: 110, alt: audio.description, lang: status.language, duration: audio.file.meta.dig(:original, :duration) + = react_component :audio, + alt: audio.description, + duration: audio.file.meta.dig(:original, :duration), + height: 110, + lang: status.language, + src: audio.file.url(:original) - else - = react_component :media_gallery, height: 343, sensitive: status.sensitive?, visible: false, lang: status.language, media: status.ordered_media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } + = react_component :media_gallery, + height: 343, + lang: status.language, + media: status.ordered_media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }, + sensitive: status.sensitive?, + visible: false From 95bd46d32afaaccc78762f7fc9c6428c4880cbc0 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 10:11:57 -0500 Subject: [PATCH 138/422] Remove double subject call in `api/v1/admin/ip_blocks` spec (#28696) --- spec/requests/api/v1/admin/ip_blocks_spec.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/spec/requests/api/v1/admin/ip_blocks_spec.rb b/spec/requests/api/v1/admin/ip_blocks_spec.rb index fbcb39e3be..98b954dd49 100644 --- a/spec/requests/api/v1/admin/ip_blocks_spec.rb +++ b/spec/requests/api/v1/admin/ip_blocks_spec.rb @@ -177,7 +177,9 @@ RSpec.describe 'IP Blocks' do let(:params) { { severity: 'sign_up_requires_approval', comment: 'Decreasing severity' } } it 'returns the correct ip block', :aggregate_failures do - subject + expect { subject } + .to change_severity_level + .and change_comment_value expect(response).to have_http_status(200) expect(body_as_json).to match(hash_including({ @@ -187,12 +189,12 @@ RSpec.describe 'IP Blocks' do })) end - it 'updates the severity correctly' do - expect { subject }.to change { ip_block.reload.severity }.from('no_access').to('sign_up_requires_approval') + def change_severity_level + change { ip_block.reload.severity }.from('no_access').to('sign_up_requires_approval') end - it 'updates the comment correctly' do - expect { subject }.to change { ip_block.reload.comment }.from('Spam').to('Decreasing severity') + def change_comment_value + change { ip_block.reload.comment }.from('Spam').to('Decreasing severity') end context 'when ip block does not exist' do From 2954279e9c630a9d146575bf600978dc6c5279bd Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 10:13:11 -0500 Subject: [PATCH 139/422] Remove double subject call in `api/v1/admin/trends/links/links` spec (#28695) --- .../api/v1/admin/trends/links/links_spec.rb | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/spec/requests/api/v1/admin/trends/links/links_spec.rb b/spec/requests/api/v1/admin/trends/links/links_spec.rb index 05020b0fd0..48842828b3 100644 --- a/spec/requests/api/v1/admin/trends/links/links_spec.rb +++ b/spec/requests/api/v1/admin/trends/links/links_spec.rb @@ -32,18 +32,18 @@ describe 'Links' do it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do - subject + expect { subject } + .to change_link_trendable_to_true expect(response).to have_http_status(200) + expects_correct_link_data end - it 'sets the link as trendable' do - expect { subject }.to change { preview_card.reload.trendable }.from(false).to(true) + def change_link_trendable_to_true + change { preview_card.reload.trendable }.from(false).to(true) end - it 'returns the link data' do - subject - + def expects_correct_link_data expect(body_as_json).to match( a_hash_including( url: preview_card.url, @@ -85,13 +85,14 @@ describe 'Links' do it_behaves_like 'forbidden for wrong role', '' it 'returns http success' do - subject + expect { subject } + .to_not change_link_trendable expect(response).to have_http_status(200) end - it 'does not set the link as trendable' do - expect { subject }.to_not(change { preview_card.reload.trendable }) + def change_link_trendable + change { preview_card.reload.trendable } end it 'returns the link data' do From 22d866ee1b0ec70cb80ac953a0ca3783f4e858f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:43:45 +0100 Subject: [PATCH 140/422] Update dependency @material-symbols/svg-600 to v0.14.4 (#28603) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7bf70258be..feb2bed2b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2505,9 +2505,9 @@ __metadata: linkType: soft "@material-symbols/svg-600@npm:^0.14.0": - version: 0.14.3 - resolution: "@material-symbols/svg-600@npm:0.14.3" - checksum: b9d1942790ee420d3464786fc7e748b3925d20c50aa34f2b289807badb85e49d52b4dcb36bed14c45e544a7d25fda81b33dd40d52aa134a6dea74b76805ea863 + version: 0.14.4 + resolution: "@material-symbols/svg-600@npm:0.14.4" + checksum: 3522055022b6e062399c9da3c701f0306f9f1bd8d5839fbf638fd2e56d97564528ca409901d7599730bf2f67df50754da859a9f499cb7156ead83890511f9d1f languageName: node linkType: hard From b6e353537bf150c3aa0ed0777e8b53aff25303d9 Mon Sep 17 00:00:00 2001 From: Essem Date: Thu, 11 Jan 2024 10:15:08 -0600 Subject: [PATCH 141/422] Add new emojis from `jdecked/twemoji` 15.0 (#28404) --- .../mastodon/features/emoji/emoji.js | 4 ++-- .../mastodon/features/emoji/emoji_map.json | 2 +- lib/tasks/emojis.rake | 6 ++--- public/emoji/1f1f2-1f1fe.svg | 2 +- public/emoji/1f301.svg | 2 +- public/emoji/1f3e5.svg | 2 +- public/emoji/1f426-200d-2b1b.svg | 1 + public/emoji/1f426-200d-2b1b_border.svg | 23 +++++++++++++++++++ public/emoji/1f50f.svg | 2 +- public/emoji/1f510.svg | 2 +- public/emoji/1f512.svg | 2 +- public/emoji/1f513.svg | 2 +- public/emoji/1f691.svg | 2 +- public/emoji/1f6dc.svg | 1 + public/emoji/1f979.svg | 2 +- public/emoji/1f97a.svg | 2 +- public/emoji/1fa75.svg | 1 + public/emoji/1fa76.svg | 1 + public/emoji/1fa77.svg | 1 + public/emoji/1fa87.svg | 1 + public/emoji/1fa88.svg | 1 + public/emoji/1faad.svg | 1 + public/emoji/1faae.svg | 1 + public/emoji/1faae_border.svg | 9 ++++++++ public/emoji/1faaf.svg | 1 + public/emoji/1fabb.svg | 1 + public/emoji/1fabc.svg | 1 + public/emoji/1fabd.svg | 1 + public/emoji/1fabd_border.svg | 9 ++++++++ public/emoji/1fabf.svg | 1 + public/emoji/1fabf_border.svg | 17 ++++++++++++++ public/emoji/1face.svg | 1 + public/emoji/1facf.svg | 1 + public/emoji/1fada.svg | 1 + public/emoji/1fadb.svg | 1 + public/emoji/1fae8.svg | 1 + public/emoji/1faf7-1f3fb.svg | 1 + public/emoji/1faf7-1f3fc.svg | 1 + public/emoji/1faf7-1f3fd.svg | 1 + public/emoji/1faf7-1f3fe.svg | 1 + public/emoji/1faf7-1f3ff.svg | 1 + public/emoji/1faf7.svg | 1 + public/emoji/1faf8-1f3fb.svg | 1 + public/emoji/1faf8-1f3fc.svg | 1 + public/emoji/1faf8-1f3fd.svg | 1 + public/emoji/1faf8-1f3fe.svg | 1 + public/emoji/1faf8-1f3ff.svg | 1 + public/emoji/1faf8.svg | 1 + 48 files changed, 105 insertions(+), 16 deletions(-) create mode 100755 public/emoji/1f426-200d-2b1b.svg create mode 100644 public/emoji/1f426-200d-2b1b_border.svg create mode 100644 public/emoji/1f6dc.svg mode change 100755 => 100644 public/emoji/1f979.svg create mode 100755 public/emoji/1fa75.svg create mode 100755 public/emoji/1fa76.svg create mode 100755 public/emoji/1fa77.svg create mode 100644 public/emoji/1fa87.svg create mode 100755 public/emoji/1fa88.svg create mode 100644 public/emoji/1faad.svg create mode 100644 public/emoji/1faae.svg create mode 100644 public/emoji/1faae_border.svg create mode 100644 public/emoji/1faaf.svg create mode 100644 public/emoji/1fabb.svg create mode 100644 public/emoji/1fabc.svg create mode 100644 public/emoji/1fabd.svg create mode 100644 public/emoji/1fabd_border.svg create mode 100644 public/emoji/1fabf.svg create mode 100644 public/emoji/1fabf_border.svg create mode 100644 public/emoji/1face.svg create mode 100644 public/emoji/1facf.svg create mode 100644 public/emoji/1fada.svg create mode 100644 public/emoji/1fadb.svg create mode 100644 public/emoji/1fae8.svg create mode 100644 public/emoji/1faf7-1f3fb.svg create mode 100644 public/emoji/1faf7-1f3fc.svg create mode 100644 public/emoji/1faf7-1f3fd.svg create mode 100644 public/emoji/1faf7-1f3fe.svg create mode 100644 public/emoji/1faf7-1f3ff.svg create mode 100644 public/emoji/1faf7.svg create mode 100644 public/emoji/1faf8-1f3fb.svg create mode 100644 public/emoji/1faf8-1f3fc.svg create mode 100644 public/emoji/1faf8-1f3fd.svg create mode 100644 public/emoji/1faf8-1f3fe.svg create mode 100644 public/emoji/1faf8-1f3ff.svg create mode 100644 public/emoji/1faf8.svg diff --git a/app/javascript/mastodon/features/emoji/emoji.js b/app/javascript/mastodon/features/emoji/emoji.js index dd51dc621e..5918a65ed7 100644 --- a/app/javascript/mastodon/features/emoji/emoji.js +++ b/app/javascript/mastodon/features/emoji/emoji.js @@ -14,8 +14,8 @@ const emojiFilenames = (emojis) => { }; // Emoji requiring extra borders depending on theme -const darkEmoji = emojiFilenames(['🎱', '🐜', '⚫', '🖤', '⬛', '◼️', '◾', '◼️', '✒️', '▪️', '💣', '🎳', '📷', '📸', '♣️', '🕶️', '✴️', '🔌', '💂‍♀️', '📽️', '🍳', '🦍', '💂', '🔪', '🕳️', '🕹️', '🕋', '🖊️', '🖋️', '💂‍♂️', '🎤', '🎓', '🎥', '🎼', '♠️', '🎩', '🦃', '📼', '📹', '🎮', '🐃', '🏴', '🐞', '🕺', '📱', '📲', '🚲']); -const lightEmoji = emojiFilenames(['👽', '⚾', '🐔', '☁️', '💨', '🕊️', '👀', '🍥', '👻', '🐐', '❕', '❔', '⛸️', '🌩️', '🔊', '🔇', '📃', '🌧️', '🐏', '🍚', '🍙', '🐓', '🐑', '💀', '☠️', '🌨️', '🔉', '🔈', '💬', '💭', '🏐', '🏳️', '⚪', '⬜', '◽', '◻️', '▫️']); +const darkEmoji = emojiFilenames(['🎱', '🐜', '⚫', '🖤', '⬛', '◼️', '◾', '◼️', '✒️', '▪️', '💣', '🎳', '📷', '📸', '♣️', '🕶️', '✴️', '🔌', '💂‍♀️', '📽️', '🍳', '🦍', '💂', '🔪', '🕳️', '🕹️', '🕋', '🖊️', '🖋️', '💂‍♂️', '🎤', '🎓', '🎥', '🎼', '♠️', '🎩', '🦃', '📼', '📹', '🎮', '🐃', '🏴', '🐞', '🕺', '📱', '📲', '🚲', '🪮', '🐦‍⬛']); +const lightEmoji = emojiFilenames(['👽', '⚾', '🐔', '☁️', '💨', '🕊️', '👀', '🍥', '👻', '🐐', '❕', '❔', '⛸️', '🌩️', '🔊', '🔇', '📃', '🌧️', '🐏', '🍚', '🍙', '🐓', '🐑', '💀', '☠️', '🌨️', '🔉', '🔈', '💬', '💭', '🏐', '🏳️', '⚪', '⬜', '◽', '◻️', '▫️', '🪽', '🪿']); const emojiFilename = (filename) => { const borderedEmoji = (document.body && document.body.classList.contains('theme-mastodon-light')) ? lightEmoji : darkEmoji; diff --git a/app/javascript/mastodon/features/emoji/emoji_map.json b/app/javascript/mastodon/features/emoji/emoji_map.json index 64f6615b79..ddb863d1d4 100644 --- a/app/javascript/mastodon/features/emoji/emoji_map.json +++ b/app/javascript/mastodon/features/emoji/emoji_map.json @@ -1 +1 @@ -{"😀":"1f600","😃":"1f603","😄":"1f604","😁":"1f601","😆":"1f606","😅":"1f605","🤣":"1f923","😂":"1f602","🙂":"1f642","🙃":"1f643","🫠":"1fae0","😉":"1f609","😊":"1f60a","😇":"1f607","🥰":"1f970","😍":"1f60d","🤩":"1f929","😘":"1f618","😗":"1f617","☺":"263a","😚":"1f61a","😙":"1f619","🥲":"1f972","😋":"1f60b","😛":"1f61b","😜":"1f61c","🤪":"1f92a","😝":"1f61d","🤑":"1f911","🤗":"1f917","🤭":"1f92d","🫢":"1fae2","🫣":"1fae3","🤫":"1f92b","🤔":"1f914","🫡":"1fae1","🤐":"1f910","🤨":"1f928","😐":"1f610","😑":"1f611","😶":"1f636","🫥":"1fae5","😏":"1f60f","😒":"1f612","🙄":"1f644","😬":"1f62c","🤥":"1f925","😌":"1f60c","😔":"1f614","😪":"1f62a","🤤":"1f924","😴":"1f634","😷":"1f637","🤒":"1f912","🤕":"1f915","🤢":"1f922","🤮":"1f92e","🤧":"1f927","🥵":"1f975","🥶":"1f976","🥴":"1f974","😵":"1f635","🤯":"1f92f","🤠":"1f920","🥳":"1f973","🥸":"1f978","😎":"1f60e","🤓":"1f913","🧐":"1f9d0","😕":"1f615","🫤":"1fae4","😟":"1f61f","🙁":"1f641","☹":"2639","😮":"1f62e","😯":"1f62f","😲":"1f632","😳":"1f633","🥺":"1f97a","🥹":"1f979","😦":"1f626","😧":"1f627","😨":"1f628","😰":"1f630","😥":"1f625","😢":"1f622","😭":"1f62d","😱":"1f631","😖":"1f616","😣":"1f623","😞":"1f61e","😓":"1f613","😩":"1f629","😫":"1f62b","🥱":"1f971","😤":"1f624","😡":"1f621","😠":"1f620","🤬":"1f92c","😈":"1f608","👿":"1f47f","💀":"1f480","☠":"2620","💩":"1f4a9","🤡":"1f921","👹":"1f479","👺":"1f47a","👻":"1f47b","👽":"1f47d","👾":"1f47e","🤖":"1f916","😺":"1f63a","😸":"1f638","😹":"1f639","😻":"1f63b","😼":"1f63c","😽":"1f63d","🙀":"1f640","😿":"1f63f","😾":"1f63e","🙈":"1f648","🙉":"1f649","🙊":"1f64a","💋":"1f48b","💌":"1f48c","💘":"1f498","💝":"1f49d","💖":"1f496","💗":"1f497","💓":"1f493","💞":"1f49e","💕":"1f495","💟":"1f49f","❣":"2763","💔":"1f494","❤":"2764","🧡":"1f9e1","💛":"1f49b","💚":"1f49a","💙":"1f499","💜":"1f49c","🤎":"1f90e","🖤":"1f5a4","🤍":"1f90d","💯":"1f4af","💢":"1f4a2","💥":"1f4a5","💫":"1f4ab","💦":"1f4a6","💨":"1f4a8","🕳":"1f573","💣":"1f4a3","💬":"1f4ac","🗨":"1f5e8","🗯":"1f5ef","💭":"1f4ad","💤":"1f4a4","👋":"1f44b","🤚":"1f91a","🖐":"1f590","✋":"270b","🖖":"1f596","🫱":"1faf1","🫲":"1faf2","🫳":"1faf3","🫴":"1faf4","👌":"1f44c","🤌":"1f90c","🤏":"1f90f","✌":"270c","🤞":"1f91e","🫰":"1faf0","🤟":"1f91f","🤘":"1f918","🤙":"1f919","👈":"1f448","👉":"1f449","👆":"1f446","🖕":"1f595","👇":"1f447","☝":"261d","🫵":"1faf5","👍":"1f44d","👎":"1f44e","✊":"270a","👊":"1f44a","🤛":"1f91b","🤜":"1f91c","👏":"1f44f","🙌":"1f64c","🫶":"1faf6","👐":"1f450","🤲":"1f932","🤝":"1f91d","🙏":"1f64f","✍":"270d","💅":"1f485","🤳":"1f933","💪":"1f4aa","🦾":"1f9be","🦿":"1f9bf","🦵":"1f9b5","🦶":"1f9b6","👂":"1f442","🦻":"1f9bb","👃":"1f443","🧠":"1f9e0","🫀":"1fac0","🫁":"1fac1","🦷":"1f9b7","🦴":"1f9b4","👀":"1f440","👁":"1f441","👅":"1f445","👄":"1f444","🫦":"1fae6","👶":"1f476","🧒":"1f9d2","👦":"1f466","👧":"1f467","🧑":"1f9d1","👱":"1f471","👨":"1f468","🧔":"1f9d4","👩":"1f469","🧓":"1f9d3","👴":"1f474","👵":"1f475","🙍":"1f64d","🙎":"1f64e","🙅":"1f645","🙆":"1f646","💁":"1f481","🙋":"1f64b","🧏":"1f9cf","🙇":"1f647","🤦":"1f926","🤷":"1f937","👮":"1f46e","🕵":"1f575","💂":"1f482","🥷":"1f977","👷":"1f477","🫅":"1fac5","🤴":"1f934","👸":"1f478","👳":"1f473","👲":"1f472","🧕":"1f9d5","🤵":"1f935","👰":"1f470","🤰":"1f930","🫃":"1fac3","🫄":"1fac4","🤱":"1f931","👼":"1f47c","🎅":"1f385","🤶":"1f936","🦸":"1f9b8","🦹":"1f9b9","🧙":"1f9d9","🧚":"1f9da","🧛":"1f9db","🧜":"1f9dc","🧝":"1f9dd","🧞":"1f9de","🧟":"1f9df","🧌":"1f9cc","💆":"1f486","💇":"1f487","🚶":"1f6b6","🧍":"1f9cd","🧎":"1f9ce","🏃":"1f3c3","💃":"1f483","🕺":"1f57a","🕴":"1f574","👯":"1f46f","🧖":"1f9d6","🧗":"1f9d7","🤺":"1f93a","🏇":"1f3c7","⛷":"26f7","🏂":"1f3c2","🏌":"1f3cc","🏄":"1f3c4","🚣":"1f6a3","🏊":"1f3ca","⛹":"26f9","🏋":"1f3cb","🚴":"1f6b4","🚵":"1f6b5","🤸":"1f938","🤼":"1f93c","🤽":"1f93d","🤾":"1f93e","🤹":"1f939","🧘":"1f9d8","🛀":"1f6c0","🛌":"1f6cc","👭":"1f46d","👫":"1f46b","👬":"1f46c","💏":"1f48f","💑":"1f491","👪":"1f46a","🗣":"1f5e3","👤":"1f464","👥":"1f465","🫂":"1fac2","👣":"1f463","🏻":"1f463","🏼":"1f463","🏽":"1f463","🏾":"1f463","🏿":"1f463","🦰":"1f463","🦱":"1f463","🦳":"1f463","🦲":"1f463","🐵":"1f435","🐒":"1f412","🦍":"1f98d","🦧":"1f9a7","🐶":"1f436","🐕":"1f415","🦮":"1f9ae","🐩":"1f429","🐺":"1f43a","🦊":"1f98a","🦝":"1f99d","🐱":"1f431","🐈":"1f408","🦁":"1f981","🐯":"1f42f","🐅":"1f405","🐆":"1f406","🐴":"1f434","🐎":"1f40e","🦄":"1f984","🦓":"1f993","🦌":"1f98c","🦬":"1f9ac","🐮":"1f42e","🐂":"1f402","🐃":"1f403","🐄":"1f404","🐷":"1f437","🐖":"1f416","🐗":"1f417","🐽":"1f43d","🐏":"1f40f","🐑":"1f411","🐐":"1f410","🐪":"1f42a","🐫":"1f42b","🦙":"1f999","🦒":"1f992","🐘":"1f418","🦣":"1f9a3","🦏":"1f98f","🦛":"1f99b","🐭":"1f42d","🐁":"1f401","🐀":"1f400","🐹":"1f439","🐰":"1f430","🐇":"1f407","🐿":"1f43f","🦫":"1f9ab","🦔":"1f994","🦇":"1f987","🐻":"1f43b","🐨":"1f428","🐼":"1f43c","🦥":"1f9a5","🦦":"1f9a6","🦨":"1f9a8","🦘":"1f998","🦡":"1f9a1","🐾":"1f43e","🦃":"1f983","🐔":"1f414","🐓":"1f413","🐣":"1f423","🐤":"1f424","🐥":"1f425","🐦":"1f426","🐧":"1f427","🕊":"1f54a","🦅":"1f985","🦆":"1f986","🦢":"1f9a2","🦉":"1f989","🦤":"1f9a4","🪶":"1fab6","🦩":"1f9a9","🦚":"1f99a","🦜":"1f99c","🐸":"1f438","🐊":"1f40a","🐢":"1f422","🦎":"1f98e","🐍":"1f40d","🐲":"1f432","🐉":"1f409","🦕":"1f995","🦖":"1f996","🐳":"1f433","🐋":"1f40b","🐬":"1f42c","🦭":"1f9ad","🐟":"1f41f","🐠":"1f420","🐡":"1f421","🦈":"1f988","🐙":"1f419","🐚":"1f41a","🪸":"1fab8","🐌":"1f40c","🦋":"1f98b","🐛":"1f41b","🐜":"1f41c","🐝":"1f41d","🪲":"1fab2","🐞":"1f41e","🦗":"1f997","🪳":"1fab3","🕷":"1f577","🕸":"1f578","🦂":"1f982","🦟":"1f99f","🪰":"1fab0","🪱":"1fab1","🦠":"1f9a0","💐":"1f490","🌸":"1f338","💮":"1f4ae","🪷":"1fab7","🏵":"1f3f5","🌹":"1f339","🥀":"1f940","🌺":"1f33a","🌻":"1f33b","🌼":"1f33c","🌷":"1f337","🌱":"1f331","🪴":"1fab4","🌲":"1f332","🌳":"1f333","🌴":"1f334","🌵":"1f335","🌾":"1f33e","🌿":"1f33f","☘":"2618","🍀":"1f340","🍁":"1f341","🍂":"1f342","🍃":"1f343","🪹":"1fab9","🪺":"1faba","🍇":"1f347","🍈":"1f348","🍉":"1f349","🍊":"1f34a","🍋":"1f34b","🍌":"1f34c","🍍":"1f34d","🥭":"1f96d","🍎":"1f34e","🍏":"1f34f","🍐":"1f350","🍑":"1f351","🍒":"1f352","🍓":"1f353","🫐":"1fad0","🥝":"1f95d","🍅":"1f345","🫒":"1fad2","🥥":"1f965","🥑":"1f951","🍆":"1f346","🥔":"1f954","🥕":"1f955","🌽":"1f33d","🌶":"1f336","🫑":"1fad1","🥒":"1f952","🥬":"1f96c","🥦":"1f966","🧄":"1f9c4","🧅":"1f9c5","🍄":"1f344","🥜":"1f95c","🫘":"1fad8","🌰":"1f330","🍞":"1f35e","🥐":"1f950","🥖":"1f956","🫓":"1fad3","🥨":"1f968","🥯":"1f96f","🥞":"1f95e","🧇":"1f9c7","🧀":"1f9c0","🍖":"1f356","🍗":"1f357","🥩":"1f969","🥓":"1f953","🍔":"1f354","🍟":"1f35f","🍕":"1f355","🌭":"1f32d","🥪":"1f96a","🌮":"1f32e","🌯":"1f32f","🫔":"1fad4","🥙":"1f959","🧆":"1f9c6","🥚":"1f95a","🍳":"1f373","🥘":"1f958","🍲":"1f372","🫕":"1fad5","🥣":"1f963","🥗":"1f957","🍿":"1f37f","🧈":"1f9c8","🧂":"1f9c2","🥫":"1f96b","🍱":"1f371","🍘":"1f358","🍙":"1f359","🍚":"1f35a","🍛":"1f35b","🍜":"1f35c","🍝":"1f35d","🍠":"1f360","🍢":"1f362","🍣":"1f363","🍤":"1f364","🍥":"1f365","🥮":"1f96e","🍡":"1f361","🥟":"1f95f","🥠":"1f960","🥡":"1f961","🦀":"1f980","🦞":"1f99e","🦐":"1f990","🦑":"1f991","🦪":"1f9aa","🍦":"1f366","🍧":"1f367","🍨":"1f368","🍩":"1f369","🍪":"1f36a","🎂":"1f382","🍰":"1f370","🧁":"1f9c1","🥧":"1f967","🍫":"1f36b","🍬":"1f36c","🍭":"1f36d","🍮":"1f36e","🍯":"1f36f","🍼":"1f37c","🥛":"1f95b","☕":"2615","🫖":"1fad6","🍵":"1f375","🍶":"1f376","🍾":"1f37e","🍷":"1f377","🍸":"1f378","🍹":"1f379","🍺":"1f37a","🍻":"1f37b","🥂":"1f942","🥃":"1f943","🫗":"1fad7","🥤":"1f964","🧋":"1f9cb","🧃":"1f9c3","🧉":"1f9c9","🧊":"1f9ca","🥢":"1f962","🍽":"1f37d","🍴":"1f374","🥄":"1f944","🔪":"1f52a","🫙":"1fad9","🏺":"1f3fa","🌍":"1f30d","🌎":"1f30e","🌏":"1f30f","🌐":"1f310","🗺":"1f5fa","🗾":"1f5fe","🧭":"1f9ed","🏔":"1f3d4","⛰":"26f0","🌋":"1f30b","🗻":"1f5fb","🏕":"1f3d5","🏖":"1f3d6","🏜":"1f3dc","🏝":"1f3dd","🏞":"1f3de","🏟":"1f3df","🏛":"1f3db","🏗":"1f3d7","🧱":"1f9f1","🪨":"1faa8","🪵":"1fab5","🛖":"1f6d6","🏘":"1f3d8","🏚":"1f3da","🏠":"1f3e0","🏡":"1f3e1","🏢":"1f3e2","🏣":"1f3e3","🏤":"1f3e4","🏥":"1f3e5","🏦":"1f3e6","🏨":"1f3e8","🏩":"1f3e9","🏪":"1f3ea","🏫":"1f3eb","🏬":"1f3ec","🏭":"1f3ed","🏯":"1f3ef","🏰":"1f3f0","💒":"1f492","🗼":"1f5fc","🗽":"1f5fd","⛪":"26ea","🕌":"1f54c","🛕":"1f6d5","🕍":"1f54d","⛩":"26e9","🕋":"1f54b","⛲":"26f2","⛺":"26fa","🌁":"1f301","🌃":"1f303","🏙":"1f3d9","🌄":"1f304","🌅":"1f305","🌆":"1f306","🌇":"1f307","🌉":"1f309","♨":"2668","🎠":"1f3a0","🛝":"1f6dd","🎡":"1f3a1","🎢":"1f3a2","💈":"1f488","🎪":"1f3aa","🚂":"1f682","🚃":"1f683","🚄":"1f684","🚅":"1f685","🚆":"1f686","🚇":"1f687","🚈":"1f688","🚉":"1f689","🚊":"1f68a","🚝":"1f69d","🚞":"1f69e","🚋":"1f68b","🚌":"1f68c","🚍":"1f68d","🚎":"1f68e","🚐":"1f690","🚑":"1f691","🚒":"1f692","🚓":"1f693","🚔":"1f694","🚕":"1f695","🚖":"1f696","🚗":"1f697","🚘":"1f698","🚙":"1f699","🛻":"1f6fb","🚚":"1f69a","🚛":"1f69b","🚜":"1f69c","🏎":"1f3ce","🏍":"1f3cd","🛵":"1f6f5","🦽":"1f9bd","🦼":"1f9bc","🛺":"1f6fa","🚲":"1f6b2","🛴":"1f6f4","🛹":"1f6f9","🛼":"1f6fc","🚏":"1f68f","🛣":"1f6e3","🛤":"1f6e4","🛢":"1f6e2","⛽":"26fd","🛞":"1f6de","🚨":"1f6a8","🚥":"1f6a5","🚦":"1f6a6","🛑":"1f6d1","🚧":"1f6a7","⚓":"2693","🛟":"1f6df","⛵":"26f5","🛶":"1f6f6","🚤":"1f6a4","🛳":"1f6f3","⛴":"26f4","🛥":"1f6e5","🚢":"1f6a2","✈":"2708","🛩":"1f6e9","🛫":"1f6eb","🛬":"1f6ec","🪂":"1fa82","💺":"1f4ba","🚁":"1f681","🚟":"1f69f","🚠":"1f6a0","🚡":"1f6a1","🛰":"1f6f0","🚀":"1f680","🛸":"1f6f8","🛎":"1f6ce","🧳":"1f9f3","⌛":"231b","⏳":"23f3","⌚":"231a","⏰":"23f0","⏱":"23f1","⏲":"23f2","🕰":"1f570","🕛":"1f55b","🕧":"1f567","🕐":"1f550","🕜":"1f55c","🕑":"1f551","🕝":"1f55d","🕒":"1f552","🕞":"1f55e","🕓":"1f553","🕟":"1f55f","🕔":"1f554","🕠":"1f560","🕕":"1f555","🕡":"1f561","🕖":"1f556","🕢":"1f562","🕗":"1f557","🕣":"1f563","🕘":"1f558","🕤":"1f564","🕙":"1f559","🕥":"1f565","🕚":"1f55a","🕦":"1f566","🌑":"1f311","🌒":"1f312","🌓":"1f313","🌔":"1f314","🌕":"1f315","🌖":"1f316","🌗":"1f317","🌘":"1f318","🌙":"1f319","🌚":"1f31a","🌛":"1f31b","🌜":"1f31c","🌡":"1f321","☀":"2600","🌝":"1f31d","🌞":"1f31e","🪐":"1fa90","⭐":"2b50","🌟":"1f31f","🌠":"1f320","🌌":"1f30c","☁":"2601","⛅":"26c5","⛈":"26c8","🌤":"1f324","🌥":"1f325","🌦":"1f326","🌧":"1f327","🌨":"1f328","🌩":"1f329","🌪":"1f32a","🌫":"1f32b","🌬":"1f32c","🌀":"1f300","🌈":"1f308","🌂":"1f302","☂":"2602","☔":"2614","⛱":"26f1","⚡":"26a1","❄":"2744","☃":"2603","⛄":"26c4","☄":"2604","🔥":"1f525","💧":"1f4a7","🌊":"1f30a","🎃":"1f383","🎄":"1f384","🎆":"1f386","🎇":"1f387","🧨":"1f9e8","✨":"2728","🎈":"1f388","🎉":"1f389","🎊":"1f38a","🎋":"1f38b","🎍":"1f38d","🎎":"1f38e","🎏":"1f38f","🎐":"1f390","🎑":"1f391","🧧":"1f9e7","🎀":"1f380","🎁":"1f381","🎗":"1f397","🎟":"1f39f","🎫":"1f3ab","🎖":"1f396","🏆":"1f3c6","🏅":"1f3c5","🥇":"1f947","🥈":"1f948","🥉":"1f949","⚽":"26bd","⚾":"26be","🥎":"1f94e","🏀":"1f3c0","🏐":"1f3d0","🏈":"1f3c8","🏉":"1f3c9","🎾":"1f3be","🥏":"1f94f","🎳":"1f3b3","🏏":"1f3cf","🏑":"1f3d1","🏒":"1f3d2","🥍":"1f94d","🏓":"1f3d3","🏸":"1f3f8","🥊":"1f94a","🥋":"1f94b","🥅":"1f945","⛳":"26f3","⛸":"26f8","🎣":"1f3a3","🤿":"1f93f","🎽":"1f3bd","🎿":"1f3bf","🛷":"1f6f7","🥌":"1f94c","🎯":"1f3af","🪀":"1fa80","🪁":"1fa81","🎱":"1f3b1","🔮":"1f52e","🪄":"1fa84","🧿":"1f9ff","🪬":"1faac","🎮":"1f3ae","🕹":"1f579","🎰":"1f3b0","🎲":"1f3b2","🧩":"1f9e9","🧸":"1f9f8","🪅":"1fa85","🪩":"1faa9","🪆":"1fa86","♠":"2660","♥":"2665","♦":"2666","♣":"2663","♟":"265f","🃏":"1f0cf","🀄":"1f004","🎴":"1f3b4","🎭":"1f3ad","🖼":"1f5bc","🎨":"1f3a8","🧵":"1f9f5","🪡":"1faa1","🧶":"1f9f6","🪢":"1faa2","👓":"1f453","🕶":"1f576","🥽":"1f97d","🥼":"1f97c","🦺":"1f9ba","👔":"1f454","👕":"1f455","👖":"1f456","🧣":"1f9e3","🧤":"1f9e4","🧥":"1f9e5","🧦":"1f9e6","👗":"1f457","👘":"1f458","🥻":"1f97b","🩱":"1fa71","🩲":"1fa72","🩳":"1fa73","👙":"1f459","👚":"1f45a","👛":"1f45b","👜":"1f45c","👝":"1f45d","🛍":"1f6cd","🎒":"1f392","🩴":"1fa74","👞":"1f45e","👟":"1f45f","🥾":"1f97e","🥿":"1f97f","👠":"1f460","👡":"1f461","🩰":"1fa70","👢":"1f462","👑":"1f451","👒":"1f452","🎩":"1f3a9","🎓":"1f393","🧢":"1f9e2","🪖":"1fa96","⛑":"26d1","📿":"1f4ff","💄":"1f484","💍":"1f48d","💎":"1f48e","🔇":"1f507","🔈":"1f508","🔉":"1f509","🔊":"1f50a","📢":"1f4e2","📣":"1f4e3","📯":"1f4ef","🔔":"1f514","🔕":"1f515","🎼":"1f3bc","🎵":"1f3b5","🎶":"1f3b6","🎙":"1f399","🎚":"1f39a","🎛":"1f39b","🎤":"1f3a4","🎧":"1f3a7","📻":"1f4fb","🎷":"1f3b7","🪗":"1fa97","🎸":"1f3b8","🎹":"1f3b9","🎺":"1f3ba","🎻":"1f3bb","🪕":"1fa95","🥁":"1f941","🪘":"1fa98","📱":"1f4f1","📲":"1f4f2","☎":"260e","📞":"1f4de","📟":"1f4df","📠":"1f4e0","🔋":"1f50b","🪫":"1faab","🔌":"1f50c","💻":"1f4bb","🖥":"1f5a5","🖨":"1f5a8","⌨":"2328","🖱":"1f5b1","🖲":"1f5b2","💽":"1f4bd","💾":"1f4be","💿":"1f4bf","📀":"1f4c0","🧮":"1f9ee","🎥":"1f3a5","🎞":"1f39e","📽":"1f4fd","🎬":"1f3ac","📺":"1f4fa","📷":"1f4f7","📸":"1f4f8","📹":"1f4f9","📼":"1f4fc","🔍":"1f50d","🔎":"1f50e","🕯":"1f56f","💡":"1f4a1","🔦":"1f526","🏮":"1f3ee","🪔":"1fa94","📔":"1f4d4","📕":"1f4d5","📖":"1f4d6","📗":"1f4d7","📘":"1f4d8","📙":"1f4d9","📚":"1f4da","📓":"1f4d3","📒":"1f4d2","📃":"1f4c3","📜":"1f4dc","📄":"1f4c4","📰":"1f4f0","🗞":"1f5de","📑":"1f4d1","🔖":"1f516","🏷":"1f3f7","💰":"1f4b0","🪙":"1fa99","💴":"1f4b4","💵":"1f4b5","💶":"1f4b6","💷":"1f4b7","💸":"1f4b8","💳":"1f4b3","🧾":"1f9fe","💹":"1f4b9","✉":"2709","📧":"1f4e7","📨":"1f4e8","📩":"1f4e9","📤":"1f4e4","📥":"1f4e5","📦":"1f4e6","📫":"1f4eb","📪":"1f4ea","📬":"1f4ec","📭":"1f4ed","📮":"1f4ee","🗳":"1f5f3","✏":"270f","✒":"2712","🖋":"1f58b","🖊":"1f58a","🖌":"1f58c","🖍":"1f58d","📝":"1f4dd","💼":"1f4bc","📁":"1f4c1","📂":"1f4c2","🗂":"1f5c2","📅":"1f4c5","📆":"1f4c6","🗒":"1f5d2","🗓":"1f5d3","📇":"1f4c7","📈":"1f4c8","📉":"1f4c9","📊":"1f4ca","📋":"1f4cb","📌":"1f4cc","📍":"1f4cd","📎":"1f4ce","🖇":"1f587","📏":"1f4cf","📐":"1f4d0","✂":"2702","🗃":"1f5c3","🗄":"1f5c4","🗑":"1f5d1","🔒":"1f512","🔓":"1f513","🔏":"1f50f","🔐":"1f510","🔑":"1f511","🗝":"1f5dd","🔨":"1f528","🪓":"1fa93","⛏":"26cf","⚒":"2692","🛠":"1f6e0","🗡":"1f5e1","⚔":"2694","🔫":"1f52b","🪃":"1fa83","🏹":"1f3f9","🛡":"1f6e1","🪚":"1fa9a","🔧":"1f527","🪛":"1fa9b","🔩":"1f529","⚙":"2699","🗜":"1f5dc","⚖":"2696","🦯":"1f9af","🔗":"1f517","⛓":"26d3","🪝":"1fa9d","🧰":"1f9f0","🧲":"1f9f2","🪜":"1fa9c","⚗":"2697","🧪":"1f9ea","🧫":"1f9eb","🧬":"1f9ec","🔬":"1f52c","🔭":"1f52d","📡":"1f4e1","💉":"1f489","🩸":"1fa78","💊":"1f48a","🩹":"1fa79","🩼":"1fa7c","🩺":"1fa7a","🩻":"1fa7b","🚪":"1f6aa","🛗":"1f6d7","🪞":"1fa9e","🪟":"1fa9f","🛏":"1f6cf","🛋":"1f6cb","🪑":"1fa91","🚽":"1f6bd","🪠":"1faa0","🚿":"1f6bf","🛁":"1f6c1","🪤":"1faa4","🪒":"1fa92","🧴":"1f9f4","🧷":"1f9f7","🧹":"1f9f9","🧺":"1f9fa","🧻":"1f9fb","🪣":"1faa3","🧼":"1f9fc","🫧":"1fae7","🪥":"1faa5","🧽":"1f9fd","🧯":"1f9ef","🛒":"1f6d2","🚬":"1f6ac","⚰":"26b0","🪦":"1faa6","⚱":"26b1","🗿":"1f5ff","🪧":"1faa7","🪪":"1faaa","🏧":"1f3e7","🚮":"1f6ae","🚰":"1f6b0","♿":"267f","🚹":"1f6b9","🚺":"1f6ba","🚻":"1f6bb","🚼":"1f6bc","🚾":"1f6be","🛂":"1f6c2","🛃":"1f6c3","🛄":"1f6c4","🛅":"1f6c5","⚠":"26a0","🚸":"1f6b8","⛔":"26d4","🚫":"1f6ab","🚳":"1f6b3","🚭":"1f6ad","🚯":"1f6af","🚱":"1f6b1","🚷":"1f6b7","📵":"1f4f5","🔞":"1f51e","☢":"2622","☣":"2623","⬆":"2b06","↗":"2197","➡":"27a1","↘":"2198","⬇":"2b07","↙":"2199","⬅":"2b05","↖":"2196","↕":"2195","↔":"2194","↩":"21a9","↪":"21aa","⤴":"2934","⤵":"2935","🔃":"1f503","🔄":"1f504","🔙":"1f519","🔚":"1f51a","🔛":"1f51b","🔜":"1f51c","🔝":"1f51d","🛐":"1f6d0","⚛":"269b","🕉":"1f549","✡":"2721","☸":"2638","☯":"262f","✝":"271d","☦":"2626","☪":"262a","☮":"262e","🕎":"1f54e","🔯":"1f52f","♈":"2648","♉":"2649","♊":"264a","♋":"264b","♌":"264c","♍":"264d","♎":"264e","♏":"264f","♐":"2650","♑":"2651","♒":"2652","♓":"2653","⛎":"26ce","🔀":"1f500","🔁":"1f501","🔂":"1f502","▶":"25b6","⏩":"23e9","⏭":"23ed","⏯":"23ef","◀":"25c0","⏪":"23ea","⏮":"23ee","🔼":"1f53c","⏫":"23eb","🔽":"1f53d","⏬":"23ec","⏸":"23f8","⏹":"23f9","⏺":"23fa","⏏":"23cf","🎦":"1f3a6","🔅":"1f505","🔆":"1f506","📶":"1f4f6","📳":"1f4f3","📴":"1f4f4","♀":"2640","♂":"2642","⚧":"26a7","✖":"2716","➕":"2795","➖":"2796","➗":"2797","🟰":"1f7f0","♾":"267e","‼":"203c","⁉":"2049","❓":"2753","❔":"2754","❕":"2755","❗":"2757","〰":"3030","💱":"1f4b1","💲":"1f4b2","⚕":"2695","♻":"267b","⚜":"269c","🔱":"1f531","📛":"1f4db","🔰":"1f530","⭕":"2b55","✅":"2705","☑":"2611","✔":"2714","❌":"274c","❎":"274e","➰":"27b0","➿":"27bf","〽":"303d","✳":"2733","✴":"2734","❇":"2747","©":"a9","®":"ae","™":"2122","🔟":"1f51f","🔠":"1f520","🔡":"1f521","🔢":"1f522","🔣":"1f523","🔤":"1f524","🅰":"1f170","🆎":"1f18e","🅱":"1f171","🆑":"1f191","🆒":"1f192","🆓":"1f193","ℹ":"2139","🆔":"1f194","Ⓜ":"24c2","🆕":"1f195","🆖":"1f196","🅾":"1f17e","🆗":"1f197","🅿":"1f17f","🆘":"1f198","🆙":"1f199","🆚":"1f19a","🈁":"1f201","🈂":"1f202","🈷":"1f237","🈶":"1f236","🈯":"1f22f","🉐":"1f250","🈹":"1f239","🈚":"1f21a","🈲":"1f232","🉑":"1f251","🈸":"1f238","🈴":"1f234","🈳":"1f233","㊗":"3297","㊙":"3299","🈺":"1f23a","🈵":"1f235","🔴":"1f534","🟠":"1f7e0","🟡":"1f7e1","🟢":"1f7e2","🔵":"1f535","🟣":"1f7e3","🟤":"1f7e4","⚫":"26ab","⚪":"26aa","🟥":"1f7e5","🟧":"1f7e7","🟨":"1f7e8","🟩":"1f7e9","🟦":"1f7e6","🟪":"1f7ea","🟫":"1f7eb","⬛":"2b1b","⬜":"2b1c","◼":"25fc","◻":"25fb","◾":"25fe","◽":"25fd","▪":"25aa","▫":"25ab","🔶":"1f536","🔷":"1f537","🔸":"1f538","🔹":"1f539","🔺":"1f53a","🔻":"1f53b","💠":"1f4a0","🔘":"1f518","🔳":"1f533","🔲":"1f532","🏁":"1f3c1","🚩":"1f6a9","🎌":"1f38c","🏴":"1f3f4","🏳":"1f3f3","☺️":"263a","☹️":"2639","☠️":"2620","❣️":"2763","❤️":"2764","🕳️":"1f573","🗨️":"1f5e8","🗯️":"1f5ef","👋🏻":"1f44b-1f3fb","👋🏼":"1f44b-1f3fc","👋🏽":"1f44b-1f3fd","👋🏾":"1f44b-1f3fe","👋🏿":"1f44b-1f3ff","🤚🏻":"1f91a-1f3fb","🤚🏼":"1f91a-1f3fc","🤚🏽":"1f91a-1f3fd","🤚🏾":"1f91a-1f3fe","🤚🏿":"1f91a-1f3ff","🖐️":"1f590","🖐🏻":"1f590-1f3fb","🖐🏼":"1f590-1f3fc","🖐🏽":"1f590-1f3fd","🖐🏾":"1f590-1f3fe","🖐🏿":"1f590-1f3ff","✋🏻":"270b-1f3fb","✋🏼":"270b-1f3fc","✋🏽":"270b-1f3fd","✋🏾":"270b-1f3fe","✋🏿":"270b-1f3ff","🖖🏻":"1f596-1f3fb","🖖🏼":"1f596-1f3fc","🖖🏽":"1f596-1f3fd","🖖🏾":"1f596-1f3fe","🖖🏿":"1f596-1f3ff","🫱🏻":"1faf1-1f3fb","🫱🏼":"1faf1-1f3fc","🫱🏽":"1faf1-1f3fd","🫱🏾":"1faf1-1f3fe","🫱🏿":"1faf1-1f3ff","🫲🏻":"1faf2-1f3fb","🫲🏼":"1faf2-1f3fc","🫲🏽":"1faf2-1f3fd","🫲🏾":"1faf2-1f3fe","🫲🏿":"1faf2-1f3ff","🫳🏻":"1faf3-1f3fb","🫳🏼":"1faf3-1f3fc","🫳🏽":"1faf3-1f3fd","🫳🏾":"1faf3-1f3fe","🫳🏿":"1faf3-1f3ff","🫴🏻":"1faf4-1f3fb","🫴🏼":"1faf4-1f3fc","🫴🏽":"1faf4-1f3fd","🫴🏾":"1faf4-1f3fe","🫴🏿":"1faf4-1f3ff","👌🏻":"1f44c-1f3fb","👌🏼":"1f44c-1f3fc","👌🏽":"1f44c-1f3fd","👌🏾":"1f44c-1f3fe","👌🏿":"1f44c-1f3ff","🤌🏻":"1f90c-1f3fb","🤌🏼":"1f90c-1f3fc","🤌🏽":"1f90c-1f3fd","🤌🏾":"1f90c-1f3fe","🤌🏿":"1f90c-1f3ff","🤏🏻":"1f90f-1f3fb","🤏🏼":"1f90f-1f3fc","🤏🏽":"1f90f-1f3fd","🤏🏾":"1f90f-1f3fe","🤏🏿":"1f90f-1f3ff","✌️":"270c","✌🏻":"270c-1f3fb","✌🏼":"270c-1f3fc","✌🏽":"270c-1f3fd","✌🏾":"270c-1f3fe","✌🏿":"270c-1f3ff","🤞🏻":"1f91e-1f3fb","🤞🏼":"1f91e-1f3fc","🤞🏽":"1f91e-1f3fd","🤞🏾":"1f91e-1f3fe","🤞🏿":"1f91e-1f3ff","🫰🏻":"1faf0-1f3fb","🫰🏼":"1faf0-1f3fc","🫰🏽":"1faf0-1f3fd","🫰🏾":"1faf0-1f3fe","🫰🏿":"1faf0-1f3ff","🤟🏻":"1f91f-1f3fb","🤟🏼":"1f91f-1f3fc","🤟🏽":"1f91f-1f3fd","🤟🏾":"1f91f-1f3fe","🤟🏿":"1f91f-1f3ff","🤘🏻":"1f918-1f3fb","🤘🏼":"1f918-1f3fc","🤘🏽":"1f918-1f3fd","🤘🏾":"1f918-1f3fe","🤘🏿":"1f918-1f3ff","🤙🏻":"1f919-1f3fb","🤙🏼":"1f919-1f3fc","🤙🏽":"1f919-1f3fd","🤙🏾":"1f919-1f3fe","🤙🏿":"1f919-1f3ff","👈🏻":"1f448-1f3fb","👈🏼":"1f448-1f3fc","👈🏽":"1f448-1f3fd","👈🏾":"1f448-1f3fe","👈🏿":"1f448-1f3ff","👉🏻":"1f449-1f3fb","👉🏼":"1f449-1f3fc","👉🏽":"1f449-1f3fd","👉🏾":"1f449-1f3fe","👉🏿":"1f449-1f3ff","👆🏻":"1f446-1f3fb","👆🏼":"1f446-1f3fc","👆🏽":"1f446-1f3fd","👆🏾":"1f446-1f3fe","👆🏿":"1f446-1f3ff","🖕🏻":"1f595-1f3fb","🖕🏼":"1f595-1f3fc","🖕🏽":"1f595-1f3fd","🖕🏾":"1f595-1f3fe","🖕🏿":"1f595-1f3ff","👇🏻":"1f447-1f3fb","👇🏼":"1f447-1f3fc","👇🏽":"1f447-1f3fd","👇🏾":"1f447-1f3fe","👇🏿":"1f447-1f3ff","☝️":"261d","☝🏻":"261d-1f3fb","☝🏼":"261d-1f3fc","☝🏽":"261d-1f3fd","☝🏾":"261d-1f3fe","☝🏿":"261d-1f3ff","🫵🏻":"1faf5-1f3fb","🫵🏼":"1faf5-1f3fc","🫵🏽":"1faf5-1f3fd","🫵🏾":"1faf5-1f3fe","🫵🏿":"1faf5-1f3ff","👍🏻":"1f44d-1f3fb","👍🏼":"1f44d-1f3fc","👍🏽":"1f44d-1f3fd","👍🏾":"1f44d-1f3fe","👍🏿":"1f44d-1f3ff","👎🏻":"1f44e-1f3fb","👎🏼":"1f44e-1f3fc","👎🏽":"1f44e-1f3fd","👎🏾":"1f44e-1f3fe","👎🏿":"1f44e-1f3ff","✊🏻":"270a-1f3fb","✊🏼":"270a-1f3fc","✊🏽":"270a-1f3fd","✊🏾":"270a-1f3fe","✊🏿":"270a-1f3ff","👊🏻":"1f44a-1f3fb","👊🏼":"1f44a-1f3fc","👊🏽":"1f44a-1f3fd","👊🏾":"1f44a-1f3fe","👊🏿":"1f44a-1f3ff","🤛🏻":"1f91b-1f3fb","🤛🏼":"1f91b-1f3fc","🤛🏽":"1f91b-1f3fd","🤛🏾":"1f91b-1f3fe","🤛🏿":"1f91b-1f3ff","🤜🏻":"1f91c-1f3fb","🤜🏼":"1f91c-1f3fc","🤜🏽":"1f91c-1f3fd","🤜🏾":"1f91c-1f3fe","🤜🏿":"1f91c-1f3ff","👏🏻":"1f44f-1f3fb","👏🏼":"1f44f-1f3fc","👏🏽":"1f44f-1f3fd","👏🏾":"1f44f-1f3fe","👏🏿":"1f44f-1f3ff","🙌🏻":"1f64c-1f3fb","🙌🏼":"1f64c-1f3fc","🙌🏽":"1f64c-1f3fd","🙌🏾":"1f64c-1f3fe","🙌🏿":"1f64c-1f3ff","🫶🏻":"1faf6-1f3fb","🫶🏼":"1faf6-1f3fc","🫶🏽":"1faf6-1f3fd","🫶🏾":"1faf6-1f3fe","🫶🏿":"1faf6-1f3ff","👐🏻":"1f450-1f3fb","👐🏼":"1f450-1f3fc","👐🏽":"1f450-1f3fd","👐🏾":"1f450-1f3fe","👐🏿":"1f450-1f3ff","🤲🏻":"1f932-1f3fb","🤲🏼":"1f932-1f3fc","🤲🏽":"1f932-1f3fd","🤲🏾":"1f932-1f3fe","🤲🏿":"1f932-1f3ff","🤝🏻":"1f91d-1f3fb","🤝🏼":"1f91d-1f3fc","🤝🏽":"1f91d-1f3fd","🤝🏾":"1f91d-1f3fe","🤝🏿":"1f91d-1f3ff","🙏🏻":"1f64f-1f3fb","🙏🏼":"1f64f-1f3fc","🙏🏽":"1f64f-1f3fd","🙏🏾":"1f64f-1f3fe","🙏🏿":"1f64f-1f3ff","✍️":"270d","✍🏻":"270d-1f3fb","✍🏼":"270d-1f3fc","✍🏽":"270d-1f3fd","✍🏾":"270d-1f3fe","✍🏿":"270d-1f3ff","💅🏻":"1f485-1f3fb","💅🏼":"1f485-1f3fc","💅🏽":"1f485-1f3fd","💅🏾":"1f485-1f3fe","💅🏿":"1f485-1f3ff","🤳🏻":"1f933-1f3fb","🤳🏼":"1f933-1f3fc","🤳🏽":"1f933-1f3fd","🤳🏾":"1f933-1f3fe","🤳🏿":"1f933-1f3ff","💪🏻":"1f4aa-1f3fb","💪🏼":"1f4aa-1f3fc","💪🏽":"1f4aa-1f3fd","💪🏾":"1f4aa-1f3fe","💪🏿":"1f4aa-1f3ff","🦵🏻":"1f9b5-1f3fb","🦵🏼":"1f9b5-1f3fc","🦵🏽":"1f9b5-1f3fd","🦵🏾":"1f9b5-1f3fe","🦵🏿":"1f9b5-1f3ff","🦶🏻":"1f9b6-1f3fb","🦶🏼":"1f9b6-1f3fc","🦶🏽":"1f9b6-1f3fd","🦶🏾":"1f9b6-1f3fe","🦶🏿":"1f9b6-1f3ff","👂🏻":"1f442-1f3fb","👂🏼":"1f442-1f3fc","👂🏽":"1f442-1f3fd","👂🏾":"1f442-1f3fe","👂🏿":"1f442-1f3ff","🦻🏻":"1f9bb-1f3fb","🦻🏼":"1f9bb-1f3fc","🦻🏽":"1f9bb-1f3fd","🦻🏾":"1f9bb-1f3fe","🦻🏿":"1f9bb-1f3ff","👃🏻":"1f443-1f3fb","👃🏼":"1f443-1f3fc","👃🏽":"1f443-1f3fd","👃🏾":"1f443-1f3fe","👃🏿":"1f443-1f3ff","👁️":"1f441","👶🏻":"1f476-1f3fb","👶🏼":"1f476-1f3fc","👶🏽":"1f476-1f3fd","👶🏾":"1f476-1f3fe","👶🏿":"1f476-1f3ff","🧒🏻":"1f9d2-1f3fb","🧒🏼":"1f9d2-1f3fc","🧒🏽":"1f9d2-1f3fd","🧒🏾":"1f9d2-1f3fe","🧒🏿":"1f9d2-1f3ff","👦🏻":"1f466-1f3fb","👦🏼":"1f466-1f3fc","👦🏽":"1f466-1f3fd","👦🏾":"1f466-1f3fe","👦🏿":"1f466-1f3ff","👧🏻":"1f467-1f3fb","👧🏼":"1f467-1f3fc","👧🏽":"1f467-1f3fd","👧🏾":"1f467-1f3fe","👧🏿":"1f467-1f3ff","🧑🏻":"1f9d1-1f3fb","🧑🏼":"1f9d1-1f3fc","🧑🏽":"1f9d1-1f3fd","🧑🏾":"1f9d1-1f3fe","🧑🏿":"1f9d1-1f3ff","👱🏻":"1f471-1f3fb","👱🏼":"1f471-1f3fc","👱🏽":"1f471-1f3fd","👱🏾":"1f471-1f3fe","👱🏿":"1f471-1f3ff","👨🏻":"1f468-1f3fb","👨🏼":"1f468-1f3fc","👨🏽":"1f468-1f3fd","👨🏾":"1f468-1f3fe","👨🏿":"1f468-1f3ff","🧔🏻":"1f9d4-1f3fb","🧔🏼":"1f9d4-1f3fc","🧔🏽":"1f9d4-1f3fd","🧔🏾":"1f9d4-1f3fe","🧔🏿":"1f9d4-1f3ff","👩🏻":"1f469-1f3fb","👩🏼":"1f469-1f3fc","👩🏽":"1f469-1f3fd","👩🏾":"1f469-1f3fe","👩🏿":"1f469-1f3ff","🧓🏻":"1f9d3-1f3fb","🧓🏼":"1f9d3-1f3fc","🧓🏽":"1f9d3-1f3fd","🧓🏾":"1f9d3-1f3fe","🧓🏿":"1f9d3-1f3ff","👴🏻":"1f474-1f3fb","👴🏼":"1f474-1f3fc","👴🏽":"1f474-1f3fd","👴🏾":"1f474-1f3fe","👴🏿":"1f474-1f3ff","👵🏻":"1f475-1f3fb","👵🏼":"1f475-1f3fc","👵🏽":"1f475-1f3fd","👵🏾":"1f475-1f3fe","👵🏿":"1f475-1f3ff","🙍🏻":"1f64d-1f3fb","🙍🏼":"1f64d-1f3fc","🙍🏽":"1f64d-1f3fd","🙍🏾":"1f64d-1f3fe","🙍🏿":"1f64d-1f3ff","🙎🏻":"1f64e-1f3fb","🙎🏼":"1f64e-1f3fc","🙎🏽":"1f64e-1f3fd","🙎🏾":"1f64e-1f3fe","🙎🏿":"1f64e-1f3ff","🙅🏻":"1f645-1f3fb","🙅🏼":"1f645-1f3fc","🙅🏽":"1f645-1f3fd","🙅🏾":"1f645-1f3fe","🙅🏿":"1f645-1f3ff","🙆🏻":"1f646-1f3fb","🙆🏼":"1f646-1f3fc","🙆🏽":"1f646-1f3fd","🙆🏾":"1f646-1f3fe","🙆🏿":"1f646-1f3ff","💁🏻":"1f481-1f3fb","💁🏼":"1f481-1f3fc","💁🏽":"1f481-1f3fd","💁🏾":"1f481-1f3fe","💁🏿":"1f481-1f3ff","🙋🏻":"1f64b-1f3fb","🙋🏼":"1f64b-1f3fc","🙋🏽":"1f64b-1f3fd","🙋🏾":"1f64b-1f3fe","🙋🏿":"1f64b-1f3ff","🧏🏻":"1f9cf-1f3fb","🧏🏼":"1f9cf-1f3fc","🧏🏽":"1f9cf-1f3fd","🧏🏾":"1f9cf-1f3fe","🧏🏿":"1f9cf-1f3ff","🙇🏻":"1f647-1f3fb","🙇🏼":"1f647-1f3fc","🙇🏽":"1f647-1f3fd","🙇🏾":"1f647-1f3fe","🙇🏿":"1f647-1f3ff","🤦🏻":"1f926-1f3fb","🤦🏼":"1f926-1f3fc","🤦🏽":"1f926-1f3fd","🤦🏾":"1f926-1f3fe","🤦🏿":"1f926-1f3ff","🤷🏻":"1f937-1f3fb","🤷🏼":"1f937-1f3fc","🤷🏽":"1f937-1f3fd","🤷🏾":"1f937-1f3fe","🤷🏿":"1f937-1f3ff","👮🏻":"1f46e-1f3fb","👮🏼":"1f46e-1f3fc","👮🏽":"1f46e-1f3fd","👮🏾":"1f46e-1f3fe","👮🏿":"1f46e-1f3ff","🕵️":"1f575","🕵🏻":"1f575-1f3fb","🕵🏼":"1f575-1f3fc","🕵🏽":"1f575-1f3fd","🕵🏾":"1f575-1f3fe","🕵🏿":"1f575-1f3ff","💂🏻":"1f482-1f3fb","💂🏼":"1f482-1f3fc","💂🏽":"1f482-1f3fd","💂🏾":"1f482-1f3fe","💂🏿":"1f482-1f3ff","🥷🏻":"1f977-1f3fb","🥷🏼":"1f977-1f3fc","🥷🏽":"1f977-1f3fd","🥷🏾":"1f977-1f3fe","🥷🏿":"1f977-1f3ff","👷🏻":"1f477-1f3fb","👷🏼":"1f477-1f3fc","👷🏽":"1f477-1f3fd","👷🏾":"1f477-1f3fe","👷🏿":"1f477-1f3ff","🫅🏻":"1fac5-1f3fb","🫅🏼":"1fac5-1f3fc","🫅🏽":"1fac5-1f3fd","🫅🏾":"1fac5-1f3fe","🫅🏿":"1fac5-1f3ff","🤴🏻":"1f934-1f3fb","🤴🏼":"1f934-1f3fc","🤴🏽":"1f934-1f3fd","🤴🏾":"1f934-1f3fe","🤴🏿":"1f934-1f3ff","👸🏻":"1f478-1f3fb","👸🏼":"1f478-1f3fc","👸🏽":"1f478-1f3fd","👸🏾":"1f478-1f3fe","👸🏿":"1f478-1f3ff","👳🏻":"1f473-1f3fb","👳🏼":"1f473-1f3fc","👳🏽":"1f473-1f3fd","👳🏾":"1f473-1f3fe","👳🏿":"1f473-1f3ff","👲🏻":"1f472-1f3fb","👲🏼":"1f472-1f3fc","👲🏽":"1f472-1f3fd","👲🏾":"1f472-1f3fe","👲🏿":"1f472-1f3ff","🧕🏻":"1f9d5-1f3fb","🧕🏼":"1f9d5-1f3fc","🧕🏽":"1f9d5-1f3fd","🧕🏾":"1f9d5-1f3fe","🧕🏿":"1f9d5-1f3ff","🤵🏻":"1f935-1f3fb","🤵🏼":"1f935-1f3fc","🤵🏽":"1f935-1f3fd","🤵🏾":"1f935-1f3fe","🤵🏿":"1f935-1f3ff","👰🏻":"1f470-1f3fb","👰🏼":"1f470-1f3fc","👰🏽":"1f470-1f3fd","👰🏾":"1f470-1f3fe","👰🏿":"1f470-1f3ff","🤰🏻":"1f930-1f3fb","🤰🏼":"1f930-1f3fc","🤰🏽":"1f930-1f3fd","🤰🏾":"1f930-1f3fe","🤰🏿":"1f930-1f3ff","🫃🏻":"1fac3-1f3fb","🫃🏼":"1fac3-1f3fc","🫃🏽":"1fac3-1f3fd","🫃🏾":"1fac3-1f3fe","🫃🏿":"1fac3-1f3ff","🫄🏻":"1fac4-1f3fb","🫄🏼":"1fac4-1f3fc","🫄🏽":"1fac4-1f3fd","🫄🏾":"1fac4-1f3fe","🫄🏿":"1fac4-1f3ff","🤱🏻":"1f931-1f3fb","🤱🏼":"1f931-1f3fc","🤱🏽":"1f931-1f3fd","🤱🏾":"1f931-1f3fe","🤱🏿":"1f931-1f3ff","👼🏻":"1f47c-1f3fb","👼🏼":"1f47c-1f3fc","👼🏽":"1f47c-1f3fd","👼🏾":"1f47c-1f3fe","👼🏿":"1f47c-1f3ff","🎅🏻":"1f385-1f3fb","🎅🏼":"1f385-1f3fc","🎅🏽":"1f385-1f3fd","🎅🏾":"1f385-1f3fe","🎅🏿":"1f385-1f3ff","🤶🏻":"1f936-1f3fb","🤶🏼":"1f936-1f3fc","🤶🏽":"1f936-1f3fd","🤶🏾":"1f936-1f3fe","🤶🏿":"1f936-1f3ff","🦸🏻":"1f9b8-1f3fb","🦸🏼":"1f9b8-1f3fc","🦸🏽":"1f9b8-1f3fd","🦸🏾":"1f9b8-1f3fe","🦸🏿":"1f9b8-1f3ff","🦹🏻":"1f9b9-1f3fb","🦹🏼":"1f9b9-1f3fc","🦹🏽":"1f9b9-1f3fd","🦹🏾":"1f9b9-1f3fe","🦹🏿":"1f9b9-1f3ff","🧙🏻":"1f9d9-1f3fb","🧙🏼":"1f9d9-1f3fc","🧙🏽":"1f9d9-1f3fd","🧙🏾":"1f9d9-1f3fe","🧙🏿":"1f9d9-1f3ff","🧚🏻":"1f9da-1f3fb","🧚🏼":"1f9da-1f3fc","🧚🏽":"1f9da-1f3fd","🧚🏾":"1f9da-1f3fe","🧚🏿":"1f9da-1f3ff","🧛🏻":"1f9db-1f3fb","🧛🏼":"1f9db-1f3fc","🧛🏽":"1f9db-1f3fd","🧛🏾":"1f9db-1f3fe","🧛🏿":"1f9db-1f3ff","🧜🏻":"1f9dc-1f3fb","🧜🏼":"1f9dc-1f3fc","🧜🏽":"1f9dc-1f3fd","🧜🏾":"1f9dc-1f3fe","🧜🏿":"1f9dc-1f3ff","🧝🏻":"1f9dd-1f3fb","🧝🏼":"1f9dd-1f3fc","🧝🏽":"1f9dd-1f3fd","🧝🏾":"1f9dd-1f3fe","🧝🏿":"1f9dd-1f3ff","💆🏻":"1f486-1f3fb","💆🏼":"1f486-1f3fc","💆🏽":"1f486-1f3fd","💆🏾":"1f486-1f3fe","💆🏿":"1f486-1f3ff","💇🏻":"1f487-1f3fb","💇🏼":"1f487-1f3fc","💇🏽":"1f487-1f3fd","💇🏾":"1f487-1f3fe","💇🏿":"1f487-1f3ff","🚶🏻":"1f6b6-1f3fb","🚶🏼":"1f6b6-1f3fc","🚶🏽":"1f6b6-1f3fd","🚶🏾":"1f6b6-1f3fe","🚶🏿":"1f6b6-1f3ff","🧍🏻":"1f9cd-1f3fb","🧍🏼":"1f9cd-1f3fc","🧍🏽":"1f9cd-1f3fd","🧍🏾":"1f9cd-1f3fe","🧍🏿":"1f9cd-1f3ff","🧎🏻":"1f9ce-1f3fb","🧎🏼":"1f9ce-1f3fc","🧎🏽":"1f9ce-1f3fd","🧎🏾":"1f9ce-1f3fe","🧎🏿":"1f9ce-1f3ff","🏃🏻":"1f3c3-1f3fb","🏃🏼":"1f3c3-1f3fc","🏃🏽":"1f3c3-1f3fd","🏃🏾":"1f3c3-1f3fe","🏃🏿":"1f3c3-1f3ff","💃🏻":"1f483-1f3fb","💃🏼":"1f483-1f3fc","💃🏽":"1f483-1f3fd","💃🏾":"1f483-1f3fe","💃🏿":"1f483-1f3ff","🕺🏻":"1f57a-1f3fb","🕺🏼":"1f57a-1f3fc","🕺🏽":"1f57a-1f3fd","🕺🏾":"1f57a-1f3fe","🕺🏿":"1f57a-1f3ff","🕴️":"1f574","🕴🏻":"1f574-1f3fb","🕴🏼":"1f574-1f3fc","🕴🏽":"1f574-1f3fd","🕴🏾":"1f574-1f3fe","🕴🏿":"1f574-1f3ff","🧖🏻":"1f9d6-1f3fb","🧖🏼":"1f9d6-1f3fc","🧖🏽":"1f9d6-1f3fd","🧖🏾":"1f9d6-1f3fe","🧖🏿":"1f9d6-1f3ff","🧗🏻":"1f9d7-1f3fb","🧗🏼":"1f9d7-1f3fc","🧗🏽":"1f9d7-1f3fd","🧗🏾":"1f9d7-1f3fe","🧗🏿":"1f9d7-1f3ff","🏇🏻":"1f3c7-1f3fb","🏇🏼":"1f3c7-1f3fc","🏇🏽":"1f3c7-1f3fd","🏇🏾":"1f3c7-1f3fe","🏇🏿":"1f3c7-1f3ff","⛷️":"26f7","🏂🏻":"1f3c2-1f3fb","🏂🏼":"1f3c2-1f3fc","🏂🏽":"1f3c2-1f3fd","🏂🏾":"1f3c2-1f3fe","🏂🏿":"1f3c2-1f3ff","🏌️":"1f3cc","🏌🏻":"1f3cc-1f3fb","🏌🏼":"1f3cc-1f3fc","🏌🏽":"1f3cc-1f3fd","🏌🏾":"1f3cc-1f3fe","🏌🏿":"1f3cc-1f3ff","🏄🏻":"1f3c4-1f3fb","🏄🏼":"1f3c4-1f3fc","🏄🏽":"1f3c4-1f3fd","🏄🏾":"1f3c4-1f3fe","🏄🏿":"1f3c4-1f3ff","🚣🏻":"1f6a3-1f3fb","🚣🏼":"1f6a3-1f3fc","🚣🏽":"1f6a3-1f3fd","🚣🏾":"1f6a3-1f3fe","🚣🏿":"1f6a3-1f3ff","🏊🏻":"1f3ca-1f3fb","🏊🏼":"1f3ca-1f3fc","🏊🏽":"1f3ca-1f3fd","🏊🏾":"1f3ca-1f3fe","🏊🏿":"1f3ca-1f3ff","⛹️":"26f9","⛹🏻":"26f9-1f3fb","⛹🏼":"26f9-1f3fc","⛹🏽":"26f9-1f3fd","⛹🏾":"26f9-1f3fe","⛹🏿":"26f9-1f3ff","🏋️":"1f3cb","🏋🏻":"1f3cb-1f3fb","🏋🏼":"1f3cb-1f3fc","🏋🏽":"1f3cb-1f3fd","🏋🏾":"1f3cb-1f3fe","🏋🏿":"1f3cb-1f3ff","🚴🏻":"1f6b4-1f3fb","🚴🏼":"1f6b4-1f3fc","🚴🏽":"1f6b4-1f3fd","🚴🏾":"1f6b4-1f3fe","🚴🏿":"1f6b4-1f3ff","🚵🏻":"1f6b5-1f3fb","🚵🏼":"1f6b5-1f3fc","🚵🏽":"1f6b5-1f3fd","🚵🏾":"1f6b5-1f3fe","🚵🏿":"1f6b5-1f3ff","🤸🏻":"1f938-1f3fb","🤸🏼":"1f938-1f3fc","🤸🏽":"1f938-1f3fd","🤸🏾":"1f938-1f3fe","🤸🏿":"1f938-1f3ff","🤽🏻":"1f93d-1f3fb","🤽🏼":"1f93d-1f3fc","🤽🏽":"1f93d-1f3fd","🤽🏾":"1f93d-1f3fe","🤽🏿":"1f93d-1f3ff","🤾🏻":"1f93e-1f3fb","🤾🏼":"1f93e-1f3fc","🤾🏽":"1f93e-1f3fd","🤾🏾":"1f93e-1f3fe","🤾🏿":"1f93e-1f3ff","🤹🏻":"1f939-1f3fb","🤹🏼":"1f939-1f3fc","🤹🏽":"1f939-1f3fd","🤹🏾":"1f939-1f3fe","🤹🏿":"1f939-1f3ff","🧘🏻":"1f9d8-1f3fb","🧘🏼":"1f9d8-1f3fc","🧘🏽":"1f9d8-1f3fd","🧘🏾":"1f9d8-1f3fe","🧘🏿":"1f9d8-1f3ff","🛀🏻":"1f6c0-1f3fb","🛀🏼":"1f6c0-1f3fc","🛀🏽":"1f6c0-1f3fd","🛀🏾":"1f6c0-1f3fe","🛀🏿":"1f6c0-1f3ff","🛌🏻":"1f6cc-1f3fb","🛌🏼":"1f6cc-1f3fc","🛌🏽":"1f6cc-1f3fd","🛌🏾":"1f6cc-1f3fe","🛌🏿":"1f6cc-1f3ff","👭🏻":"1f46d-1f3fb","👭🏼":"1f46d-1f3fc","👭🏽":"1f46d-1f3fd","👭🏾":"1f46d-1f3fe","👭🏿":"1f46d-1f3ff","👫🏻":"1f46b-1f3fb","👫🏼":"1f46b-1f3fc","👫🏽":"1f46b-1f3fd","👫🏾":"1f46b-1f3fe","👫🏿":"1f46b-1f3ff","👬🏻":"1f46c-1f3fb","👬🏼":"1f46c-1f3fc","👬🏽":"1f46c-1f3fd","👬🏾":"1f46c-1f3fe","👬🏿":"1f46c-1f3ff","💏🏻":"1f48f-1f3fb","💏🏼":"1f48f-1f3fc","💏🏽":"1f48f-1f3fd","💏🏾":"1f48f-1f3fe","💏🏿":"1f48f-1f3ff","💑🏻":"1f491-1f3fb","💑🏼":"1f491-1f3fc","💑🏽":"1f491-1f3fd","💑🏾":"1f491-1f3fe","💑🏿":"1f491-1f3ff","🗣️":"1f5e3","🐿️":"1f43f","🕊️":"1f54a","🕷️":"1f577","🕸️":"1f578","🏵️":"1f3f5","☘️":"2618","🌶️":"1f336","🍽️":"1f37d","🗺️":"1f5fa","🏔️":"1f3d4","⛰️":"26f0","🏕️":"1f3d5","🏖️":"1f3d6","🏜️":"1f3dc","🏝️":"1f3dd","🏞️":"1f3de","🏟️":"1f3df","🏛️":"1f3db","🏗️":"1f3d7","🏘️":"1f3d8","🏚️":"1f3da","⛩️":"26e9","🏙️":"1f3d9","♨️":"2668","🏎️":"1f3ce","🏍️":"1f3cd","🛣️":"1f6e3","🛤️":"1f6e4","🛢️":"1f6e2","🛳️":"1f6f3","⛴️":"26f4","🛥️":"1f6e5","✈️":"2708","🛩️":"1f6e9","🛰️":"1f6f0","🛎️":"1f6ce","⏱️":"23f1","⏲️":"23f2","🕰️":"1f570","🌡️":"1f321","☀️":"2600","☁️":"2601","⛈️":"26c8","🌤️":"1f324","🌥️":"1f325","🌦️":"1f326","🌧️":"1f327","🌨️":"1f328","🌩️":"1f329","🌪️":"1f32a","🌫️":"1f32b","🌬️":"1f32c","☂️":"2602","⛱️":"26f1","❄️":"2744","☃️":"2603","☄️":"2604","🎗️":"1f397","🎟️":"1f39f","🎖️":"1f396","⛸️":"26f8","🕹️":"1f579","♠️":"2660","♥️":"2665","♦️":"2666","♣️":"2663","♟️":"265f","🖼️":"1f5bc","🕶️":"1f576","🛍️":"1f6cd","⛑️":"26d1","🎙️":"1f399","🎚️":"1f39a","🎛️":"1f39b","☎️":"260e","🖥️":"1f5a5","🖨️":"1f5a8","⌨️":"2328","🖱️":"1f5b1","🖲️":"1f5b2","🎞️":"1f39e","📽️":"1f4fd","🕯️":"1f56f","🗞️":"1f5de","🏷️":"1f3f7","✉️":"2709","🗳️":"1f5f3","✏️":"270f","✒️":"2712","🖋️":"1f58b","🖊️":"1f58a","🖌️":"1f58c","🖍️":"1f58d","🗂️":"1f5c2","🗒️":"1f5d2","🗓️":"1f5d3","🖇️":"1f587","✂️":"2702","🗃️":"1f5c3","🗄️":"1f5c4","🗑️":"1f5d1","🗝️":"1f5dd","⛏️":"26cf","⚒️":"2692","🛠️":"1f6e0","🗡️":"1f5e1","⚔️":"2694","🛡️":"1f6e1","⚙️":"2699","🗜️":"1f5dc","⚖️":"2696","⛓️":"26d3","⚗️":"2697","🛏️":"1f6cf","🛋️":"1f6cb","⚰️":"26b0","⚱️":"26b1","⚠️":"26a0","☢️":"2622","☣️":"2623","⬆️":"2b06","↗️":"2197","➡️":"27a1","↘️":"2198","⬇️":"2b07","↙️":"2199","⬅️":"2b05","↖️":"2196","↕️":"2195","↔️":"2194","↩️":"21a9","↪️":"21aa","⤴️":"2934","⤵️":"2935","⚛️":"269b","🕉️":"1f549","✡️":"2721","☸️":"2638","☯️":"262f","✝️":"271d","☦️":"2626","☪️":"262a","☮️":"262e","▶️":"25b6","⏭️":"23ed","⏯️":"23ef","◀️":"25c0","⏮️":"23ee","⏸️":"23f8","⏹️":"23f9","⏺️":"23fa","⏏️":"23cf","♀️":"2640","♂️":"2642","⚧️":"26a7","✖️":"2716","♾️":"267e","‼️":"203c","⁉️":"2049","〰️":"3030","⚕️":"2695","♻️":"267b","⚜️":"269c","☑️":"2611","✔️":"2714","〽️":"303d","✳️":"2733","✴️":"2734","❇️":"2747","©️":"a9","®️":"ae","™️":"2122","#⃣":"23-20e3","*⃣":"2a-20e3","0⃣":"30-20e3","1⃣":"31-20e3","2⃣":"32-20e3","3⃣":"33-20e3","4⃣":"34-20e3","5⃣":"35-20e3","6⃣":"36-20e3","7⃣":"37-20e3","8⃣":"38-20e3","9⃣":"39-20e3","🅰️":"1f170","🅱️":"1f171","ℹ️":"2139","Ⓜ️":"24c2","🅾️":"1f17e","🅿️":"1f17f","🈂️":"1f202","🈷️":"1f237","㊗️":"3297","㊙️":"3299","◼️":"25fc","◻️":"25fb","▪️":"25aa","▫️":"25ab","🏳️":"1f3f3","🇦🇨":"1f1e6-1f1e8","🇦🇩":"1f1e6-1f1e9","🇦🇪":"1f1e6-1f1ea","🇦🇫":"1f1e6-1f1eb","🇦🇬":"1f1e6-1f1ec","🇦🇮":"1f1e6-1f1ee","🇦🇱":"1f1e6-1f1f1","🇦🇲":"1f1e6-1f1f2","🇦🇴":"1f1e6-1f1f4","🇦🇶":"1f1e6-1f1f6","🇦🇷":"1f1e6-1f1f7","🇦🇸":"1f1e6-1f1f8","🇦🇹":"1f1e6-1f1f9","🇦🇺":"1f1e6-1f1fa","🇦🇼":"1f1e6-1f1fc","🇦🇽":"1f1e6-1f1fd","🇦🇿":"1f1e6-1f1ff","🇧🇦":"1f1e7-1f1e6","🇧🇧":"1f1e7-1f1e7","🇧🇩":"1f1e7-1f1e9","🇧🇪":"1f1e7-1f1ea","🇧🇫":"1f1e7-1f1eb","🇧🇬":"1f1e7-1f1ec","🇧🇭":"1f1e7-1f1ed","🇧🇮":"1f1e7-1f1ee","🇧🇯":"1f1e7-1f1ef","🇧🇱":"1f1e7-1f1f1","🇧🇲":"1f1e7-1f1f2","🇧🇳":"1f1e7-1f1f3","🇧🇴":"1f1e7-1f1f4","🇧🇶":"1f1e7-1f1f6","🇧🇷":"1f1e7-1f1f7","🇧🇸":"1f1e7-1f1f8","🇧🇹":"1f1e7-1f1f9","🇧🇻":"1f1e7-1f1fb","🇧🇼":"1f1e7-1f1fc","🇧🇾":"1f1e7-1f1fe","🇧🇿":"1f1e7-1f1ff","🇨🇦":"1f1e8-1f1e6","🇨🇨":"1f1e8-1f1e8","🇨🇩":"1f1e8-1f1e9","🇨🇫":"1f1e8-1f1eb","🇨🇬":"1f1e8-1f1ec","🇨🇭":"1f1e8-1f1ed","🇨🇮":"1f1e8-1f1ee","🇨🇰":"1f1e8-1f1f0","🇨🇱":"1f1e8-1f1f1","🇨🇲":"1f1e8-1f1f2","🇨🇳":"1f1e8-1f1f3","🇨🇴":"1f1e8-1f1f4","🇨🇵":"1f1e8-1f1f5","🇨🇷":"1f1e8-1f1f7","🇨🇺":"1f1e8-1f1fa","🇨🇻":"1f1e8-1f1fb","🇨🇼":"1f1e8-1f1fc","🇨🇽":"1f1e8-1f1fd","🇨🇾":"1f1e8-1f1fe","🇨🇿":"1f1e8-1f1ff","🇩🇪":"1f1e9-1f1ea","🇩🇬":"1f1e9-1f1ec","🇩🇯":"1f1e9-1f1ef","🇩🇰":"1f1e9-1f1f0","🇩🇲":"1f1e9-1f1f2","🇩🇴":"1f1e9-1f1f4","🇩🇿":"1f1e9-1f1ff","🇪🇦":"1f1ea-1f1e6","🇪🇨":"1f1ea-1f1e8","🇪🇪":"1f1ea-1f1ea","🇪🇬":"1f1ea-1f1ec","🇪🇭":"1f1ea-1f1ed","🇪🇷":"1f1ea-1f1f7","🇪🇸":"1f1ea-1f1f8","🇪🇹":"1f1ea-1f1f9","🇪🇺":"1f1ea-1f1fa","🇫🇮":"1f1eb-1f1ee","🇫🇯":"1f1eb-1f1ef","🇫🇰":"1f1eb-1f1f0","🇫🇲":"1f1eb-1f1f2","🇫🇴":"1f1eb-1f1f4","🇫🇷":"1f1eb-1f1f7","🇬🇦":"1f1ec-1f1e6","🇬🇧":"1f1ec-1f1e7","🇬🇩":"1f1ec-1f1e9","🇬🇪":"1f1ec-1f1ea","🇬🇫":"1f1ec-1f1eb","🇬🇬":"1f1ec-1f1ec","🇬🇭":"1f1ec-1f1ed","🇬🇮":"1f1ec-1f1ee","🇬🇱":"1f1ec-1f1f1","🇬🇲":"1f1ec-1f1f2","🇬🇳":"1f1ec-1f1f3","🇬🇵":"1f1ec-1f1f5","🇬🇶":"1f1ec-1f1f6","🇬🇷":"1f1ec-1f1f7","🇬🇸":"1f1ec-1f1f8","🇬🇹":"1f1ec-1f1f9","🇬🇺":"1f1ec-1f1fa","🇬🇼":"1f1ec-1f1fc","🇬🇾":"1f1ec-1f1fe","🇭🇰":"1f1ed-1f1f0","🇭🇲":"1f1ed-1f1f2","🇭🇳":"1f1ed-1f1f3","🇭🇷":"1f1ed-1f1f7","🇭🇹":"1f1ed-1f1f9","🇭🇺":"1f1ed-1f1fa","🇮🇨":"1f1ee-1f1e8","🇮🇩":"1f1ee-1f1e9","🇮🇪":"1f1ee-1f1ea","🇮🇱":"1f1ee-1f1f1","🇮🇲":"1f1ee-1f1f2","🇮🇳":"1f1ee-1f1f3","🇮🇴":"1f1ee-1f1f4","🇮🇶":"1f1ee-1f1f6","🇮🇷":"1f1ee-1f1f7","🇮🇸":"1f1ee-1f1f8","🇮🇹":"1f1ee-1f1f9","🇯🇪":"1f1ef-1f1ea","🇯🇲":"1f1ef-1f1f2","🇯🇴":"1f1ef-1f1f4","🇯🇵":"1f1ef-1f1f5","🇰🇪":"1f1f0-1f1ea","🇰🇬":"1f1f0-1f1ec","🇰🇭":"1f1f0-1f1ed","🇰🇮":"1f1f0-1f1ee","🇰🇲":"1f1f0-1f1f2","🇰🇳":"1f1f0-1f1f3","🇰🇵":"1f1f0-1f1f5","🇰🇷":"1f1f0-1f1f7","🇰🇼":"1f1f0-1f1fc","🇰🇾":"1f1f0-1f1fe","🇰🇿":"1f1f0-1f1ff","🇱🇦":"1f1f1-1f1e6","🇱🇧":"1f1f1-1f1e7","🇱🇨":"1f1f1-1f1e8","🇱🇮":"1f1f1-1f1ee","🇱🇰":"1f1f1-1f1f0","🇱🇷":"1f1f1-1f1f7","🇱🇸":"1f1f1-1f1f8","🇱🇹":"1f1f1-1f1f9","🇱🇺":"1f1f1-1f1fa","🇱🇻":"1f1f1-1f1fb","🇱🇾":"1f1f1-1f1fe","🇲🇦":"1f1f2-1f1e6","🇲🇨":"1f1f2-1f1e8","🇲🇩":"1f1f2-1f1e9","🇲🇪":"1f1f2-1f1ea","🇲🇫":"1f1f2-1f1eb","🇲🇬":"1f1f2-1f1ec","🇲🇭":"1f1f2-1f1ed","🇲🇰":"1f1f2-1f1f0","🇲🇱":"1f1f2-1f1f1","🇲🇲":"1f1f2-1f1f2","🇲🇳":"1f1f2-1f1f3","🇲🇴":"1f1f2-1f1f4","🇲🇵":"1f1f2-1f1f5","🇲🇶":"1f1f2-1f1f6","🇲🇷":"1f1f2-1f1f7","🇲🇸":"1f1f2-1f1f8","🇲🇹":"1f1f2-1f1f9","🇲🇺":"1f1f2-1f1fa","🇲🇻":"1f1f2-1f1fb","🇲🇼":"1f1f2-1f1fc","🇲🇽":"1f1f2-1f1fd","🇲🇾":"1f1f2-1f1fe","🇲🇿":"1f1f2-1f1ff","🇳🇦":"1f1f3-1f1e6","🇳🇨":"1f1f3-1f1e8","🇳🇪":"1f1f3-1f1ea","🇳🇫":"1f1f3-1f1eb","🇳🇬":"1f1f3-1f1ec","🇳🇮":"1f1f3-1f1ee","🇳🇱":"1f1f3-1f1f1","🇳🇴":"1f1f3-1f1f4","🇳🇵":"1f1f3-1f1f5","🇳🇷":"1f1f3-1f1f7","🇳🇺":"1f1f3-1f1fa","🇳🇿":"1f1f3-1f1ff","🇴🇲":"1f1f4-1f1f2","🇵🇦":"1f1f5-1f1e6","🇵🇪":"1f1f5-1f1ea","🇵🇫":"1f1f5-1f1eb","🇵🇬":"1f1f5-1f1ec","🇵🇭":"1f1f5-1f1ed","🇵🇰":"1f1f5-1f1f0","🇵🇱":"1f1f5-1f1f1","🇵🇲":"1f1f5-1f1f2","🇵🇳":"1f1f5-1f1f3","🇵🇷":"1f1f5-1f1f7","🇵🇸":"1f1f5-1f1f8","🇵🇹":"1f1f5-1f1f9","🇵🇼":"1f1f5-1f1fc","🇵🇾":"1f1f5-1f1fe","🇶🇦":"1f1f6-1f1e6","🇷🇪":"1f1f7-1f1ea","🇷🇴":"1f1f7-1f1f4","🇷🇸":"1f1f7-1f1f8","🇷🇺":"1f1f7-1f1fa","🇷🇼":"1f1f7-1f1fc","🇸🇦":"1f1f8-1f1e6","🇸🇧":"1f1f8-1f1e7","🇸🇨":"1f1f8-1f1e8","🇸🇩":"1f1f8-1f1e9","🇸🇪":"1f1f8-1f1ea","🇸🇬":"1f1f8-1f1ec","🇸🇭":"1f1f8-1f1ed","🇸🇮":"1f1f8-1f1ee","🇸🇯":"1f1f8-1f1ef","🇸🇰":"1f1f8-1f1f0","🇸🇱":"1f1f8-1f1f1","🇸🇲":"1f1f8-1f1f2","🇸🇳":"1f1f8-1f1f3","🇸🇴":"1f1f8-1f1f4","🇸🇷":"1f1f8-1f1f7","🇸🇸":"1f1f8-1f1f8","🇸🇹":"1f1f8-1f1f9","🇸🇻":"1f1f8-1f1fb","🇸🇽":"1f1f8-1f1fd","🇸🇾":"1f1f8-1f1fe","🇸🇿":"1f1f8-1f1ff","🇹🇦":"1f1f9-1f1e6","🇹🇨":"1f1f9-1f1e8","🇹🇩":"1f1f9-1f1e9","🇹🇫":"1f1f9-1f1eb","🇹🇬":"1f1f9-1f1ec","🇹🇭":"1f1f9-1f1ed","🇹🇯":"1f1f9-1f1ef","🇹🇰":"1f1f9-1f1f0","🇹🇱":"1f1f9-1f1f1","🇹🇲":"1f1f9-1f1f2","🇹🇳":"1f1f9-1f1f3","🇹🇴":"1f1f9-1f1f4","🇹🇷":"1f1f9-1f1f7","🇹🇹":"1f1f9-1f1f9","🇹🇻":"1f1f9-1f1fb","🇹🇼":"1f1f9-1f1fc","🇹🇿":"1f1f9-1f1ff","🇺🇦":"1f1fa-1f1e6","🇺🇬":"1f1fa-1f1ec","🇺🇲":"1f1fa-1f1f2","🇺🇳":"1f1fa-1f1f3","🇺🇸":"1f1fa-1f1f8","🇺🇾":"1f1fa-1f1fe","🇺🇿":"1f1fa-1f1ff","🇻🇦":"1f1fb-1f1e6","🇻🇨":"1f1fb-1f1e8","🇻🇪":"1f1fb-1f1ea","🇻🇬":"1f1fb-1f1ec","🇻🇮":"1f1fb-1f1ee","🇻🇳":"1f1fb-1f1f3","🇻🇺":"1f1fb-1f1fa","🇼🇫":"1f1fc-1f1eb","🇼🇸":"1f1fc-1f1f8","🇽🇰":"1f1fd-1f1f0","🇾🇪":"1f1fe-1f1ea","🇾🇹":"1f1fe-1f1f9","🇿🇦":"1f1ff-1f1e6","🇿🇲":"1f1ff-1f1f2","🇿🇼":"1f1ff-1f1fc","😶‍🌫":"1f636-200d-1f32b-fe0f","😮‍💨":"1f62e-200d-1f4a8","😵‍💫":"1f635-200d-1f4ab","❤‍🔥":"2764-fe0f-200d-1f525","❤‍🩹":"2764-fe0f-200d-1fa79","👁‍🗨":"1f441-200d-1f5e8","🧔‍♂":"1f9d4-200d-2642-fe0f","🧔‍♀":"1f9d4-200d-2640-fe0f","👨‍🦰":"1f468-200d-1f9b0","👨‍🦱":"1f468-200d-1f9b1","👨‍🦳":"1f468-200d-1f9b3","👨‍🦲":"1f468-200d-1f9b2","👩‍🦰":"1f469-200d-1f9b0","🧑‍🦰":"1f9d1-200d-1f9b0","👩‍🦱":"1f469-200d-1f9b1","🧑‍🦱":"1f9d1-200d-1f9b1","👩‍🦳":"1f469-200d-1f9b3","🧑‍🦳":"1f9d1-200d-1f9b3","👩‍🦲":"1f469-200d-1f9b2","🧑‍🦲":"1f9d1-200d-1f9b2","👱‍♀":"1f471-200d-2640-fe0f","👱‍♂":"1f471-200d-2642-fe0f","🙍‍♂":"1f64d-200d-2642-fe0f","🙍‍♀":"1f64d-200d-2640-fe0f","🙎‍♂":"1f64e-200d-2642-fe0f","🙎‍♀":"1f64e-200d-2640-fe0f","🙅‍♂":"1f645-200d-2642-fe0f","🙅‍♀":"1f645-200d-2640-fe0f","🙆‍♂":"1f646-200d-2642-fe0f","🙆‍♀":"1f646-200d-2640-fe0f","💁‍♂":"1f481-200d-2642-fe0f","💁‍♀":"1f481-200d-2640-fe0f","🙋‍♂":"1f64b-200d-2642-fe0f","🙋‍♀":"1f64b-200d-2640-fe0f","🧏‍♂":"1f9cf-200d-2642-fe0f","🧏‍♀":"1f9cf-200d-2640-fe0f","🙇‍♂":"1f647-200d-2642-fe0f","🙇‍♀":"1f647-200d-2640-fe0f","🤦‍♂":"1f926-200d-2642-fe0f","🤦‍♀":"1f926-200d-2640-fe0f","🤷‍♂":"1f937-200d-2642-fe0f","🤷‍♀":"1f937-200d-2640-fe0f","🧑‍⚕":"1f9d1-200d-2695-fe0f","👨‍⚕":"1f468-200d-2695-fe0f","👩‍⚕":"1f469-200d-2695-fe0f","🧑‍🎓":"1f9d1-200d-1f393","👨‍🎓":"1f468-200d-1f393","👩‍🎓":"1f469-200d-1f393","🧑‍🏫":"1f9d1-200d-1f3eb","👨‍🏫":"1f468-200d-1f3eb","👩‍🏫":"1f469-200d-1f3eb","🧑‍⚖":"1f9d1-200d-2696-fe0f","👨‍⚖":"1f468-200d-2696-fe0f","👩‍⚖":"1f469-200d-2696-fe0f","🧑‍🌾":"1f9d1-200d-1f33e","👨‍🌾":"1f468-200d-1f33e","👩‍🌾":"1f469-200d-1f33e","🧑‍🍳":"1f9d1-200d-1f373","👨‍🍳":"1f468-200d-1f373","👩‍🍳":"1f469-200d-1f373","🧑‍🔧":"1f9d1-200d-1f527","👨‍🔧":"1f468-200d-1f527","👩‍🔧":"1f469-200d-1f527","🧑‍🏭":"1f9d1-200d-1f3ed","👨‍🏭":"1f468-200d-1f3ed","👩‍🏭":"1f469-200d-1f3ed","🧑‍💼":"1f9d1-200d-1f4bc","👨‍💼":"1f468-200d-1f4bc","👩‍💼":"1f469-200d-1f4bc","🧑‍🔬":"1f9d1-200d-1f52c","👨‍🔬":"1f468-200d-1f52c","👩‍🔬":"1f469-200d-1f52c","🧑‍💻":"1f9d1-200d-1f4bb","👨‍💻":"1f468-200d-1f4bb","👩‍💻":"1f469-200d-1f4bb","🧑‍🎤":"1f9d1-200d-1f3a4","👨‍🎤":"1f468-200d-1f3a4","👩‍🎤":"1f469-200d-1f3a4","🧑‍🎨":"1f9d1-200d-1f3a8","👨‍🎨":"1f468-200d-1f3a8","👩‍🎨":"1f469-200d-1f3a8","🧑‍✈":"1f9d1-200d-2708-fe0f","👨‍✈":"1f468-200d-2708-fe0f","👩‍✈":"1f469-200d-2708-fe0f","🧑‍🚀":"1f9d1-200d-1f680","👨‍🚀":"1f468-200d-1f680","👩‍🚀":"1f469-200d-1f680","🧑‍🚒":"1f9d1-200d-1f692","👨‍🚒":"1f468-200d-1f692","👩‍🚒":"1f469-200d-1f692","👮‍♂":"1f46e-200d-2642-fe0f","👮‍♀":"1f46e-200d-2640-fe0f","🕵‍♂":"1f575-fe0f-200d-2642-fe0f","🕵‍♀":"1f575-fe0f-200d-2640-fe0f","💂‍♂":"1f482-200d-2642-fe0f","💂‍♀":"1f482-200d-2640-fe0f","👷‍♂":"1f477-200d-2642-fe0f","👷‍♀":"1f477-200d-2640-fe0f","👳‍♂":"1f473-200d-2642-fe0f","👳‍♀":"1f473-200d-2640-fe0f","🤵‍♂":"1f935-200d-2642-fe0f","🤵‍♀":"1f935-200d-2640-fe0f","👰‍♂":"1f470-200d-2642-fe0f","👰‍♀":"1f470-200d-2640-fe0f","👩‍🍼":"1f469-200d-1f37c","👨‍🍼":"1f468-200d-1f37c","🧑‍🍼":"1f9d1-200d-1f37c","🧑‍🎄":"1f9d1-200d-1f384","🦸‍♂":"1f9b8-200d-2642-fe0f","🦸‍♀":"1f9b8-200d-2640-fe0f","🦹‍♂":"1f9b9-200d-2642-fe0f","🦹‍♀":"1f9b9-200d-2640-fe0f","🧙‍♂":"1f9d9-200d-2642-fe0f","🧙‍♀":"1f9d9-200d-2640-fe0f","🧚‍♂":"1f9da-200d-2642-fe0f","🧚‍♀":"1f9da-200d-2640-fe0f","🧛‍♂":"1f9db-200d-2642-fe0f","🧛‍♀":"1f9db-200d-2640-fe0f","🧜‍♂":"1f9dc-200d-2642-fe0f","🧜‍♀":"1f9dc-200d-2640-fe0f","🧝‍♂":"1f9dd-200d-2642-fe0f","🧝‍♀":"1f9dd-200d-2640-fe0f","🧞‍♂":"1f9de-200d-2642-fe0f","🧞‍♀":"1f9de-200d-2640-fe0f","🧟‍♂":"1f9df-200d-2642-fe0f","🧟‍♀":"1f9df-200d-2640-fe0f","💆‍♂":"1f486-200d-2642-fe0f","💆‍♀":"1f486-200d-2640-fe0f","💇‍♂":"1f487-200d-2642-fe0f","💇‍♀":"1f487-200d-2640-fe0f","🚶‍♂":"1f6b6-200d-2642-fe0f","🚶‍♀":"1f6b6-200d-2640-fe0f","🧍‍♂":"1f9cd-200d-2642-fe0f","🧍‍♀":"1f9cd-200d-2640-fe0f","🧎‍♂":"1f9ce-200d-2642-fe0f","🧎‍♀":"1f9ce-200d-2640-fe0f","🧑‍🦯":"1f9d1-200d-1f9af","👨‍🦯":"1f468-200d-1f9af","👩‍🦯":"1f469-200d-1f9af","🧑‍🦼":"1f9d1-200d-1f9bc","👨‍🦼":"1f468-200d-1f9bc","👩‍🦼":"1f469-200d-1f9bc","🧑‍🦽":"1f9d1-200d-1f9bd","👨‍🦽":"1f468-200d-1f9bd","👩‍🦽":"1f469-200d-1f9bd","🏃‍♂":"1f3c3-200d-2642-fe0f","🏃‍♀":"1f3c3-200d-2640-fe0f","👯‍♂":"1f46f-200d-2642-fe0f","👯‍♀":"1f46f-200d-2640-fe0f","🧖‍♂":"1f9d6-200d-2642-fe0f","🧖‍♀":"1f9d6-200d-2640-fe0f","🧗‍♂":"1f9d7-200d-2642-fe0f","🧗‍♀":"1f9d7-200d-2640-fe0f","🏌‍♂":"1f3cc-fe0f-200d-2642-fe0f","🏌‍♀":"1f3cc-fe0f-200d-2640-fe0f","🏄‍♂":"1f3c4-200d-2642-fe0f","🏄‍♀":"1f3c4-200d-2640-fe0f","🚣‍♂":"1f6a3-200d-2642-fe0f","🚣‍♀":"1f6a3-200d-2640-fe0f","🏊‍♂":"1f3ca-200d-2642-fe0f","🏊‍♀":"1f3ca-200d-2640-fe0f","⛹‍♂":"26f9-fe0f-200d-2642-fe0f","⛹‍♀":"26f9-fe0f-200d-2640-fe0f","🏋‍♂":"1f3cb-fe0f-200d-2642-fe0f","🏋‍♀":"1f3cb-fe0f-200d-2640-fe0f","🚴‍♂":"1f6b4-200d-2642-fe0f","🚴‍♀":"1f6b4-200d-2640-fe0f","🚵‍♂":"1f6b5-200d-2642-fe0f","🚵‍♀":"1f6b5-200d-2640-fe0f","🤸‍♂":"1f938-200d-2642-fe0f","🤸‍♀":"1f938-200d-2640-fe0f","🤼‍♂":"1f93c-200d-2642-fe0f","🤼‍♀":"1f93c-200d-2640-fe0f","🤽‍♂":"1f93d-200d-2642-fe0f","🤽‍♀":"1f93d-200d-2640-fe0f","🤾‍♂":"1f93e-200d-2642-fe0f","🤾‍♀":"1f93e-200d-2640-fe0f","🤹‍♂":"1f939-200d-2642-fe0f","🤹‍♀":"1f939-200d-2640-fe0f","🧘‍♂":"1f9d8-200d-2642-fe0f","🧘‍♀":"1f9d8-200d-2640-fe0f","👨‍👦":"1f468-200d-1f466","👨‍👧":"1f468-200d-1f467","👩‍👦":"1f469-200d-1f466","👩‍👧":"1f469-200d-1f467","🐕‍🦺":"1f415-200d-1f9ba","🐈‍⬛":"1f408-200d-2b1b","🐻‍❄":"1f43b-200d-2744-fe0f","#️⃣":"23-20e3","*️⃣":"2a-20e3","0️⃣":"30-20e3","1️⃣":"31-20e3","2️⃣":"32-20e3","3️⃣":"33-20e3","4️⃣":"34-20e3","5️⃣":"35-20e3","6️⃣":"36-20e3","7️⃣":"37-20e3","8️⃣":"38-20e3","9️⃣":"39-20e3","🏳‍🌈":"1f3f3-fe0f-200d-1f308","🏳‍⚧":"1f3f3-fe0f-200d-26a7-fe0f","🏴‍☠":"1f3f4-200d-2620-fe0f","😶‍🌫️":"1f636-200d-1f32b-fe0f","❤️‍🔥":"2764-fe0f-200d-1f525","❤️‍🩹":"2764-fe0f-200d-1fa79","👁‍🗨️":"1f441-200d-1f5e8","👁️‍🗨":"1f441-200d-1f5e8","🧔‍♂️":"1f9d4-200d-2642-fe0f","🧔🏻‍♂":"1f9d4-1f3fb-200d-2642-fe0f","🧔🏼‍♂":"1f9d4-1f3fc-200d-2642-fe0f","🧔🏽‍♂":"1f9d4-1f3fd-200d-2642-fe0f","🧔🏾‍♂":"1f9d4-1f3fe-200d-2642-fe0f","🧔🏿‍♂":"1f9d4-1f3ff-200d-2642-fe0f","🧔‍♀️":"1f9d4-200d-2640-fe0f","🧔🏻‍♀":"1f9d4-1f3fb-200d-2640-fe0f","🧔🏼‍♀":"1f9d4-1f3fc-200d-2640-fe0f","🧔🏽‍♀":"1f9d4-1f3fd-200d-2640-fe0f","🧔🏾‍♀":"1f9d4-1f3fe-200d-2640-fe0f","🧔🏿‍♀":"1f9d4-1f3ff-200d-2640-fe0f","👨🏻‍🦰":"1f468-1f3fb-200d-1f9b0","👨🏼‍🦰":"1f468-1f3fc-200d-1f9b0","👨🏽‍🦰":"1f468-1f3fd-200d-1f9b0","👨🏾‍🦰":"1f468-1f3fe-200d-1f9b0","👨🏿‍🦰":"1f468-1f3ff-200d-1f9b0","👨🏻‍🦱":"1f468-1f3fb-200d-1f9b1","👨🏼‍🦱":"1f468-1f3fc-200d-1f9b1","👨🏽‍🦱":"1f468-1f3fd-200d-1f9b1","👨🏾‍🦱":"1f468-1f3fe-200d-1f9b1","👨🏿‍🦱":"1f468-1f3ff-200d-1f9b1","👨🏻‍🦳":"1f468-1f3fb-200d-1f9b3","👨🏼‍🦳":"1f468-1f3fc-200d-1f9b3","👨🏽‍🦳":"1f468-1f3fd-200d-1f9b3","👨🏾‍🦳":"1f468-1f3fe-200d-1f9b3","👨🏿‍🦳":"1f468-1f3ff-200d-1f9b3","👨🏻‍🦲":"1f468-1f3fb-200d-1f9b2","👨🏼‍🦲":"1f468-1f3fc-200d-1f9b2","👨🏽‍🦲":"1f468-1f3fd-200d-1f9b2","👨🏾‍🦲":"1f468-1f3fe-200d-1f9b2","👨🏿‍🦲":"1f468-1f3ff-200d-1f9b2","👩🏻‍🦰":"1f469-1f3fb-200d-1f9b0","👩🏼‍🦰":"1f469-1f3fc-200d-1f9b0","👩🏽‍🦰":"1f469-1f3fd-200d-1f9b0","👩🏾‍🦰":"1f469-1f3fe-200d-1f9b0","👩🏿‍🦰":"1f469-1f3ff-200d-1f9b0","🧑🏻‍🦰":"1f9d1-1f3fb-200d-1f9b0","🧑🏼‍🦰":"1f9d1-1f3fc-200d-1f9b0","🧑🏽‍🦰":"1f9d1-1f3fd-200d-1f9b0","🧑🏾‍🦰":"1f9d1-1f3fe-200d-1f9b0","🧑🏿‍🦰":"1f9d1-1f3ff-200d-1f9b0","👩🏻‍🦱":"1f469-1f3fb-200d-1f9b1","👩🏼‍🦱":"1f469-1f3fc-200d-1f9b1","👩🏽‍🦱":"1f469-1f3fd-200d-1f9b1","👩🏾‍🦱":"1f469-1f3fe-200d-1f9b1","👩🏿‍🦱":"1f469-1f3ff-200d-1f9b1","🧑🏻‍🦱":"1f9d1-1f3fb-200d-1f9b1","🧑🏼‍🦱":"1f9d1-1f3fc-200d-1f9b1","🧑🏽‍🦱":"1f9d1-1f3fd-200d-1f9b1","🧑🏾‍🦱":"1f9d1-1f3fe-200d-1f9b1","🧑🏿‍🦱":"1f9d1-1f3ff-200d-1f9b1","👩🏻‍🦳":"1f469-1f3fb-200d-1f9b3","👩🏼‍🦳":"1f469-1f3fc-200d-1f9b3","👩🏽‍🦳":"1f469-1f3fd-200d-1f9b3","👩🏾‍🦳":"1f469-1f3fe-200d-1f9b3","👩🏿‍🦳":"1f469-1f3ff-200d-1f9b3","🧑🏻‍🦳":"1f9d1-1f3fb-200d-1f9b3","🧑🏼‍🦳":"1f9d1-1f3fc-200d-1f9b3","🧑🏽‍🦳":"1f9d1-1f3fd-200d-1f9b3","🧑🏾‍🦳":"1f9d1-1f3fe-200d-1f9b3","🧑🏿‍🦳":"1f9d1-1f3ff-200d-1f9b3","👩🏻‍🦲":"1f469-1f3fb-200d-1f9b2","👩🏼‍🦲":"1f469-1f3fc-200d-1f9b2","👩🏽‍🦲":"1f469-1f3fd-200d-1f9b2","👩🏾‍🦲":"1f469-1f3fe-200d-1f9b2","👩🏿‍🦲":"1f469-1f3ff-200d-1f9b2","🧑🏻‍🦲":"1f9d1-1f3fb-200d-1f9b2","🧑🏼‍🦲":"1f9d1-1f3fc-200d-1f9b2","🧑🏽‍🦲":"1f9d1-1f3fd-200d-1f9b2","🧑🏾‍🦲":"1f9d1-1f3fe-200d-1f9b2","🧑🏿‍🦲":"1f9d1-1f3ff-200d-1f9b2","👱‍♀️":"1f471-200d-2640-fe0f","👱🏻‍♀":"1f471-1f3fb-200d-2640-fe0f","👱🏼‍♀":"1f471-1f3fc-200d-2640-fe0f","👱🏽‍♀":"1f471-1f3fd-200d-2640-fe0f","👱🏾‍♀":"1f471-1f3fe-200d-2640-fe0f","👱🏿‍♀":"1f471-1f3ff-200d-2640-fe0f","👱‍♂️":"1f471-200d-2642-fe0f","👱🏻‍♂":"1f471-1f3fb-200d-2642-fe0f","👱🏼‍♂":"1f471-1f3fc-200d-2642-fe0f","👱🏽‍♂":"1f471-1f3fd-200d-2642-fe0f","👱🏾‍♂":"1f471-1f3fe-200d-2642-fe0f","👱🏿‍♂":"1f471-1f3ff-200d-2642-fe0f","🙍‍♂️":"1f64d-200d-2642-fe0f","🙍🏻‍♂":"1f64d-1f3fb-200d-2642-fe0f","🙍🏼‍♂":"1f64d-1f3fc-200d-2642-fe0f","🙍🏽‍♂":"1f64d-1f3fd-200d-2642-fe0f","🙍🏾‍♂":"1f64d-1f3fe-200d-2642-fe0f","🙍🏿‍♂":"1f64d-1f3ff-200d-2642-fe0f","🙍‍♀️":"1f64d-200d-2640-fe0f","🙍🏻‍♀":"1f64d-1f3fb-200d-2640-fe0f","🙍🏼‍♀":"1f64d-1f3fc-200d-2640-fe0f","🙍🏽‍♀":"1f64d-1f3fd-200d-2640-fe0f","🙍🏾‍♀":"1f64d-1f3fe-200d-2640-fe0f","🙍🏿‍♀":"1f64d-1f3ff-200d-2640-fe0f","🙎‍♂️":"1f64e-200d-2642-fe0f","🙎🏻‍♂":"1f64e-1f3fb-200d-2642-fe0f","🙎🏼‍♂":"1f64e-1f3fc-200d-2642-fe0f","🙎🏽‍♂":"1f64e-1f3fd-200d-2642-fe0f","🙎🏾‍♂":"1f64e-1f3fe-200d-2642-fe0f","🙎🏿‍♂":"1f64e-1f3ff-200d-2642-fe0f","🙎‍♀️":"1f64e-200d-2640-fe0f","🙎🏻‍♀":"1f64e-1f3fb-200d-2640-fe0f","🙎🏼‍♀":"1f64e-1f3fc-200d-2640-fe0f","🙎🏽‍♀":"1f64e-1f3fd-200d-2640-fe0f","🙎🏾‍♀":"1f64e-1f3fe-200d-2640-fe0f","🙎🏿‍♀":"1f64e-1f3ff-200d-2640-fe0f","🙅‍♂️":"1f645-200d-2642-fe0f","🙅🏻‍♂":"1f645-1f3fb-200d-2642-fe0f","🙅🏼‍♂":"1f645-1f3fc-200d-2642-fe0f","🙅🏽‍♂":"1f645-1f3fd-200d-2642-fe0f","🙅🏾‍♂":"1f645-1f3fe-200d-2642-fe0f","🙅🏿‍♂":"1f645-1f3ff-200d-2642-fe0f","🙅‍♀️":"1f645-200d-2640-fe0f","🙅🏻‍♀":"1f645-1f3fb-200d-2640-fe0f","🙅🏼‍♀":"1f645-1f3fc-200d-2640-fe0f","🙅🏽‍♀":"1f645-1f3fd-200d-2640-fe0f","🙅🏾‍♀":"1f645-1f3fe-200d-2640-fe0f","🙅🏿‍♀":"1f645-1f3ff-200d-2640-fe0f","🙆‍♂️":"1f646-200d-2642-fe0f","🙆🏻‍♂":"1f646-1f3fb-200d-2642-fe0f","🙆🏼‍♂":"1f646-1f3fc-200d-2642-fe0f","🙆🏽‍♂":"1f646-1f3fd-200d-2642-fe0f","🙆🏾‍♂":"1f646-1f3fe-200d-2642-fe0f","🙆🏿‍♂":"1f646-1f3ff-200d-2642-fe0f","🙆‍♀️":"1f646-200d-2640-fe0f","🙆🏻‍♀":"1f646-1f3fb-200d-2640-fe0f","🙆🏼‍♀":"1f646-1f3fc-200d-2640-fe0f","🙆🏽‍♀":"1f646-1f3fd-200d-2640-fe0f","🙆🏾‍♀":"1f646-1f3fe-200d-2640-fe0f","🙆🏿‍♀":"1f646-1f3ff-200d-2640-fe0f","💁‍♂️":"1f481-200d-2642-fe0f","💁🏻‍♂":"1f481-1f3fb-200d-2642-fe0f","💁🏼‍♂":"1f481-1f3fc-200d-2642-fe0f","💁🏽‍♂":"1f481-1f3fd-200d-2642-fe0f","💁🏾‍♂":"1f481-1f3fe-200d-2642-fe0f","💁🏿‍♂":"1f481-1f3ff-200d-2642-fe0f","💁‍♀️":"1f481-200d-2640-fe0f","💁🏻‍♀":"1f481-1f3fb-200d-2640-fe0f","💁🏼‍♀":"1f481-1f3fc-200d-2640-fe0f","💁🏽‍♀":"1f481-1f3fd-200d-2640-fe0f","💁🏾‍♀":"1f481-1f3fe-200d-2640-fe0f","💁🏿‍♀":"1f481-1f3ff-200d-2640-fe0f","🙋‍♂️":"1f64b-200d-2642-fe0f","🙋🏻‍♂":"1f64b-1f3fb-200d-2642-fe0f","🙋🏼‍♂":"1f64b-1f3fc-200d-2642-fe0f","🙋🏽‍♂":"1f64b-1f3fd-200d-2642-fe0f","🙋🏾‍♂":"1f64b-1f3fe-200d-2642-fe0f","🙋🏿‍♂":"1f64b-1f3ff-200d-2642-fe0f","🙋‍♀️":"1f64b-200d-2640-fe0f","🙋🏻‍♀":"1f64b-1f3fb-200d-2640-fe0f","🙋🏼‍♀":"1f64b-1f3fc-200d-2640-fe0f","🙋🏽‍♀":"1f64b-1f3fd-200d-2640-fe0f","🙋🏾‍♀":"1f64b-1f3fe-200d-2640-fe0f","🙋🏿‍♀":"1f64b-1f3ff-200d-2640-fe0f","🧏‍♂️":"1f9cf-200d-2642-fe0f","🧏🏻‍♂":"1f9cf-1f3fb-200d-2642-fe0f","🧏🏼‍♂":"1f9cf-1f3fc-200d-2642-fe0f","🧏🏽‍♂":"1f9cf-1f3fd-200d-2642-fe0f","🧏🏾‍♂":"1f9cf-1f3fe-200d-2642-fe0f","🧏🏿‍♂":"1f9cf-1f3ff-200d-2642-fe0f","🧏‍♀️":"1f9cf-200d-2640-fe0f","🧏🏻‍♀":"1f9cf-1f3fb-200d-2640-fe0f","🧏🏼‍♀":"1f9cf-1f3fc-200d-2640-fe0f","🧏🏽‍♀":"1f9cf-1f3fd-200d-2640-fe0f","🧏🏾‍♀":"1f9cf-1f3fe-200d-2640-fe0f","🧏🏿‍♀":"1f9cf-1f3ff-200d-2640-fe0f","🙇‍♂️":"1f647-200d-2642-fe0f","🙇🏻‍♂":"1f647-1f3fb-200d-2642-fe0f","🙇🏼‍♂":"1f647-1f3fc-200d-2642-fe0f","🙇🏽‍♂":"1f647-1f3fd-200d-2642-fe0f","🙇🏾‍♂":"1f647-1f3fe-200d-2642-fe0f","🙇🏿‍♂":"1f647-1f3ff-200d-2642-fe0f","🙇‍♀️":"1f647-200d-2640-fe0f","🙇🏻‍♀":"1f647-1f3fb-200d-2640-fe0f","🙇🏼‍♀":"1f647-1f3fc-200d-2640-fe0f","🙇🏽‍♀":"1f647-1f3fd-200d-2640-fe0f","🙇🏾‍♀":"1f647-1f3fe-200d-2640-fe0f","🙇🏿‍♀":"1f647-1f3ff-200d-2640-fe0f","🤦‍♂️":"1f926-200d-2642-fe0f","🤦🏻‍♂":"1f926-1f3fb-200d-2642-fe0f","🤦🏼‍♂":"1f926-1f3fc-200d-2642-fe0f","🤦🏽‍♂":"1f926-1f3fd-200d-2642-fe0f","🤦🏾‍♂":"1f926-1f3fe-200d-2642-fe0f","🤦🏿‍♂":"1f926-1f3ff-200d-2642-fe0f","🤦‍♀️":"1f926-200d-2640-fe0f","🤦🏻‍♀":"1f926-1f3fb-200d-2640-fe0f","🤦🏼‍♀":"1f926-1f3fc-200d-2640-fe0f","🤦🏽‍♀":"1f926-1f3fd-200d-2640-fe0f","🤦🏾‍♀":"1f926-1f3fe-200d-2640-fe0f","🤦🏿‍♀":"1f926-1f3ff-200d-2640-fe0f","🤷‍♂️":"1f937-200d-2642-fe0f","🤷🏻‍♂":"1f937-1f3fb-200d-2642-fe0f","🤷🏼‍♂":"1f937-1f3fc-200d-2642-fe0f","🤷🏽‍♂":"1f937-1f3fd-200d-2642-fe0f","🤷🏾‍♂":"1f937-1f3fe-200d-2642-fe0f","🤷🏿‍♂":"1f937-1f3ff-200d-2642-fe0f","🤷‍♀️":"1f937-200d-2640-fe0f","🤷🏻‍♀":"1f937-1f3fb-200d-2640-fe0f","🤷🏼‍♀":"1f937-1f3fc-200d-2640-fe0f","🤷🏽‍♀":"1f937-1f3fd-200d-2640-fe0f","🤷🏾‍♀":"1f937-1f3fe-200d-2640-fe0f","🤷🏿‍♀":"1f937-1f3ff-200d-2640-fe0f","🧑‍⚕️":"1f9d1-200d-2695-fe0f","🧑🏻‍⚕":"1f9d1-1f3fb-200d-2695-fe0f","🧑🏼‍⚕":"1f9d1-1f3fc-200d-2695-fe0f","🧑🏽‍⚕":"1f9d1-1f3fd-200d-2695-fe0f","🧑🏾‍⚕":"1f9d1-1f3fe-200d-2695-fe0f","🧑🏿‍⚕":"1f9d1-1f3ff-200d-2695-fe0f","👨‍⚕️":"1f468-200d-2695-fe0f","👨🏻‍⚕":"1f468-1f3fb-200d-2695-fe0f","👨🏼‍⚕":"1f468-1f3fc-200d-2695-fe0f","👨🏽‍⚕":"1f468-1f3fd-200d-2695-fe0f","👨🏾‍⚕":"1f468-1f3fe-200d-2695-fe0f","👨🏿‍⚕":"1f468-1f3ff-200d-2695-fe0f","👩‍⚕️":"1f469-200d-2695-fe0f","👩🏻‍⚕":"1f469-1f3fb-200d-2695-fe0f","👩🏼‍⚕":"1f469-1f3fc-200d-2695-fe0f","👩🏽‍⚕":"1f469-1f3fd-200d-2695-fe0f","👩🏾‍⚕":"1f469-1f3fe-200d-2695-fe0f","👩🏿‍⚕":"1f469-1f3ff-200d-2695-fe0f","🧑🏻‍🎓":"1f9d1-1f3fb-200d-1f393","🧑🏼‍🎓":"1f9d1-1f3fc-200d-1f393","🧑🏽‍🎓":"1f9d1-1f3fd-200d-1f393","🧑🏾‍🎓":"1f9d1-1f3fe-200d-1f393","🧑🏿‍🎓":"1f9d1-1f3ff-200d-1f393","👨🏻‍🎓":"1f468-1f3fb-200d-1f393","👨🏼‍🎓":"1f468-1f3fc-200d-1f393","👨🏽‍🎓":"1f468-1f3fd-200d-1f393","👨🏾‍🎓":"1f468-1f3fe-200d-1f393","👨🏿‍🎓":"1f468-1f3ff-200d-1f393","👩🏻‍🎓":"1f469-1f3fb-200d-1f393","👩🏼‍🎓":"1f469-1f3fc-200d-1f393","👩🏽‍🎓":"1f469-1f3fd-200d-1f393","👩🏾‍🎓":"1f469-1f3fe-200d-1f393","👩🏿‍🎓":"1f469-1f3ff-200d-1f393","🧑🏻‍🏫":"1f9d1-1f3fb-200d-1f3eb","🧑🏼‍🏫":"1f9d1-1f3fc-200d-1f3eb","🧑🏽‍🏫":"1f9d1-1f3fd-200d-1f3eb","🧑🏾‍🏫":"1f9d1-1f3fe-200d-1f3eb","🧑🏿‍🏫":"1f9d1-1f3ff-200d-1f3eb","👨🏻‍🏫":"1f468-1f3fb-200d-1f3eb","👨🏼‍🏫":"1f468-1f3fc-200d-1f3eb","👨🏽‍🏫":"1f468-1f3fd-200d-1f3eb","👨🏾‍🏫":"1f468-1f3fe-200d-1f3eb","👨🏿‍🏫":"1f468-1f3ff-200d-1f3eb","👩🏻‍🏫":"1f469-1f3fb-200d-1f3eb","👩🏼‍🏫":"1f469-1f3fc-200d-1f3eb","👩🏽‍🏫":"1f469-1f3fd-200d-1f3eb","👩🏾‍🏫":"1f469-1f3fe-200d-1f3eb","👩🏿‍🏫":"1f469-1f3ff-200d-1f3eb","🧑‍⚖️":"1f9d1-200d-2696-fe0f","🧑🏻‍⚖":"1f9d1-1f3fb-200d-2696-fe0f","🧑🏼‍⚖":"1f9d1-1f3fc-200d-2696-fe0f","🧑🏽‍⚖":"1f9d1-1f3fd-200d-2696-fe0f","🧑🏾‍⚖":"1f9d1-1f3fe-200d-2696-fe0f","🧑🏿‍⚖":"1f9d1-1f3ff-200d-2696-fe0f","👨‍⚖️":"1f468-200d-2696-fe0f","👨🏻‍⚖":"1f468-1f3fb-200d-2696-fe0f","👨🏼‍⚖":"1f468-1f3fc-200d-2696-fe0f","👨🏽‍⚖":"1f468-1f3fd-200d-2696-fe0f","👨🏾‍⚖":"1f468-1f3fe-200d-2696-fe0f","👨🏿‍⚖":"1f468-1f3ff-200d-2696-fe0f","👩‍⚖️":"1f469-200d-2696-fe0f","👩🏻‍⚖":"1f469-1f3fb-200d-2696-fe0f","👩🏼‍⚖":"1f469-1f3fc-200d-2696-fe0f","👩🏽‍⚖":"1f469-1f3fd-200d-2696-fe0f","👩🏾‍⚖":"1f469-1f3fe-200d-2696-fe0f","👩🏿‍⚖":"1f469-1f3ff-200d-2696-fe0f","🧑🏻‍🌾":"1f9d1-1f3fb-200d-1f33e","🧑🏼‍🌾":"1f9d1-1f3fc-200d-1f33e","🧑🏽‍🌾":"1f9d1-1f3fd-200d-1f33e","🧑🏾‍🌾":"1f9d1-1f3fe-200d-1f33e","🧑🏿‍🌾":"1f9d1-1f3ff-200d-1f33e","👨🏻‍🌾":"1f468-1f3fb-200d-1f33e","👨🏼‍🌾":"1f468-1f3fc-200d-1f33e","👨🏽‍🌾":"1f468-1f3fd-200d-1f33e","👨🏾‍🌾":"1f468-1f3fe-200d-1f33e","👨🏿‍🌾":"1f468-1f3ff-200d-1f33e","👩🏻‍🌾":"1f469-1f3fb-200d-1f33e","👩🏼‍🌾":"1f469-1f3fc-200d-1f33e","👩🏽‍🌾":"1f469-1f3fd-200d-1f33e","👩🏾‍🌾":"1f469-1f3fe-200d-1f33e","👩🏿‍🌾":"1f469-1f3ff-200d-1f33e","🧑🏻‍🍳":"1f9d1-1f3fb-200d-1f373","🧑🏼‍🍳":"1f9d1-1f3fc-200d-1f373","🧑🏽‍🍳":"1f9d1-1f3fd-200d-1f373","🧑🏾‍🍳":"1f9d1-1f3fe-200d-1f373","🧑🏿‍🍳":"1f9d1-1f3ff-200d-1f373","👨🏻‍🍳":"1f468-1f3fb-200d-1f373","👨🏼‍🍳":"1f468-1f3fc-200d-1f373","👨🏽‍🍳":"1f468-1f3fd-200d-1f373","👨🏾‍🍳":"1f468-1f3fe-200d-1f373","👨🏿‍🍳":"1f468-1f3ff-200d-1f373","👩🏻‍🍳":"1f469-1f3fb-200d-1f373","👩🏼‍🍳":"1f469-1f3fc-200d-1f373","👩🏽‍🍳":"1f469-1f3fd-200d-1f373","👩🏾‍🍳":"1f469-1f3fe-200d-1f373","👩🏿‍🍳":"1f469-1f3ff-200d-1f373","🧑🏻‍🔧":"1f9d1-1f3fb-200d-1f527","🧑🏼‍🔧":"1f9d1-1f3fc-200d-1f527","🧑🏽‍🔧":"1f9d1-1f3fd-200d-1f527","🧑🏾‍🔧":"1f9d1-1f3fe-200d-1f527","🧑🏿‍🔧":"1f9d1-1f3ff-200d-1f527","👨🏻‍🔧":"1f468-1f3fb-200d-1f527","👨🏼‍🔧":"1f468-1f3fc-200d-1f527","👨🏽‍🔧":"1f468-1f3fd-200d-1f527","👨🏾‍🔧":"1f468-1f3fe-200d-1f527","👨🏿‍🔧":"1f468-1f3ff-200d-1f527","👩🏻‍🔧":"1f469-1f3fb-200d-1f527","👩🏼‍🔧":"1f469-1f3fc-200d-1f527","👩🏽‍🔧":"1f469-1f3fd-200d-1f527","👩🏾‍🔧":"1f469-1f3fe-200d-1f527","👩🏿‍🔧":"1f469-1f3ff-200d-1f527","🧑🏻‍🏭":"1f9d1-1f3fb-200d-1f3ed","🧑🏼‍🏭":"1f9d1-1f3fc-200d-1f3ed","🧑🏽‍🏭":"1f9d1-1f3fd-200d-1f3ed","🧑🏾‍🏭":"1f9d1-1f3fe-200d-1f3ed","🧑🏿‍🏭":"1f9d1-1f3ff-200d-1f3ed","👨🏻‍🏭":"1f468-1f3fb-200d-1f3ed","👨🏼‍🏭":"1f468-1f3fc-200d-1f3ed","👨🏽‍🏭":"1f468-1f3fd-200d-1f3ed","👨🏾‍🏭":"1f468-1f3fe-200d-1f3ed","👨🏿‍🏭":"1f468-1f3ff-200d-1f3ed","👩🏻‍🏭":"1f469-1f3fb-200d-1f3ed","👩🏼‍🏭":"1f469-1f3fc-200d-1f3ed","👩🏽‍🏭":"1f469-1f3fd-200d-1f3ed","👩🏾‍🏭":"1f469-1f3fe-200d-1f3ed","👩🏿‍🏭":"1f469-1f3ff-200d-1f3ed","🧑🏻‍💼":"1f9d1-1f3fb-200d-1f4bc","🧑🏼‍💼":"1f9d1-1f3fc-200d-1f4bc","🧑🏽‍💼":"1f9d1-1f3fd-200d-1f4bc","🧑🏾‍💼":"1f9d1-1f3fe-200d-1f4bc","🧑🏿‍💼":"1f9d1-1f3ff-200d-1f4bc","👨🏻‍💼":"1f468-1f3fb-200d-1f4bc","👨🏼‍💼":"1f468-1f3fc-200d-1f4bc","👨🏽‍💼":"1f468-1f3fd-200d-1f4bc","👨🏾‍💼":"1f468-1f3fe-200d-1f4bc","👨🏿‍💼":"1f468-1f3ff-200d-1f4bc","👩🏻‍💼":"1f469-1f3fb-200d-1f4bc","👩🏼‍💼":"1f469-1f3fc-200d-1f4bc","👩🏽‍💼":"1f469-1f3fd-200d-1f4bc","👩🏾‍💼":"1f469-1f3fe-200d-1f4bc","👩🏿‍💼":"1f469-1f3ff-200d-1f4bc","🧑🏻‍🔬":"1f9d1-1f3fb-200d-1f52c","🧑🏼‍🔬":"1f9d1-1f3fc-200d-1f52c","🧑🏽‍🔬":"1f9d1-1f3fd-200d-1f52c","🧑🏾‍🔬":"1f9d1-1f3fe-200d-1f52c","🧑🏿‍🔬":"1f9d1-1f3ff-200d-1f52c","👨🏻‍🔬":"1f468-1f3fb-200d-1f52c","👨🏼‍🔬":"1f468-1f3fc-200d-1f52c","👨🏽‍🔬":"1f468-1f3fd-200d-1f52c","👨🏾‍🔬":"1f468-1f3fe-200d-1f52c","👨🏿‍🔬":"1f468-1f3ff-200d-1f52c","👩🏻‍🔬":"1f469-1f3fb-200d-1f52c","👩🏼‍🔬":"1f469-1f3fc-200d-1f52c","👩🏽‍🔬":"1f469-1f3fd-200d-1f52c","👩🏾‍🔬":"1f469-1f3fe-200d-1f52c","👩🏿‍🔬":"1f469-1f3ff-200d-1f52c","🧑🏻‍💻":"1f9d1-1f3fb-200d-1f4bb","🧑🏼‍💻":"1f9d1-1f3fc-200d-1f4bb","🧑🏽‍💻":"1f9d1-1f3fd-200d-1f4bb","🧑🏾‍💻":"1f9d1-1f3fe-200d-1f4bb","🧑🏿‍💻":"1f9d1-1f3ff-200d-1f4bb","👨🏻‍💻":"1f468-1f3fb-200d-1f4bb","👨🏼‍💻":"1f468-1f3fc-200d-1f4bb","👨🏽‍💻":"1f468-1f3fd-200d-1f4bb","👨🏾‍💻":"1f468-1f3fe-200d-1f4bb","👨🏿‍💻":"1f468-1f3ff-200d-1f4bb","👩🏻‍💻":"1f469-1f3fb-200d-1f4bb","👩🏼‍💻":"1f469-1f3fc-200d-1f4bb","👩🏽‍💻":"1f469-1f3fd-200d-1f4bb","👩🏾‍💻":"1f469-1f3fe-200d-1f4bb","👩🏿‍💻":"1f469-1f3ff-200d-1f4bb","🧑🏻‍🎤":"1f9d1-1f3fb-200d-1f3a4","🧑🏼‍🎤":"1f9d1-1f3fc-200d-1f3a4","🧑🏽‍🎤":"1f9d1-1f3fd-200d-1f3a4","🧑🏾‍🎤":"1f9d1-1f3fe-200d-1f3a4","🧑🏿‍🎤":"1f9d1-1f3ff-200d-1f3a4","👨🏻‍🎤":"1f468-1f3fb-200d-1f3a4","👨🏼‍🎤":"1f468-1f3fc-200d-1f3a4","👨🏽‍🎤":"1f468-1f3fd-200d-1f3a4","👨🏾‍🎤":"1f468-1f3fe-200d-1f3a4","👨🏿‍🎤":"1f468-1f3ff-200d-1f3a4","👩🏻‍🎤":"1f469-1f3fb-200d-1f3a4","👩🏼‍🎤":"1f469-1f3fc-200d-1f3a4","👩🏽‍🎤":"1f469-1f3fd-200d-1f3a4","👩🏾‍🎤":"1f469-1f3fe-200d-1f3a4","👩🏿‍🎤":"1f469-1f3ff-200d-1f3a4","🧑🏻‍🎨":"1f9d1-1f3fb-200d-1f3a8","🧑🏼‍🎨":"1f9d1-1f3fc-200d-1f3a8","🧑🏽‍🎨":"1f9d1-1f3fd-200d-1f3a8","🧑🏾‍🎨":"1f9d1-1f3fe-200d-1f3a8","🧑🏿‍🎨":"1f9d1-1f3ff-200d-1f3a8","👨🏻‍🎨":"1f468-1f3fb-200d-1f3a8","👨🏼‍🎨":"1f468-1f3fc-200d-1f3a8","👨🏽‍🎨":"1f468-1f3fd-200d-1f3a8","👨🏾‍🎨":"1f468-1f3fe-200d-1f3a8","👨🏿‍🎨":"1f468-1f3ff-200d-1f3a8","👩🏻‍🎨":"1f469-1f3fb-200d-1f3a8","👩🏼‍🎨":"1f469-1f3fc-200d-1f3a8","👩🏽‍🎨":"1f469-1f3fd-200d-1f3a8","👩🏾‍🎨":"1f469-1f3fe-200d-1f3a8","👩🏿‍🎨":"1f469-1f3ff-200d-1f3a8","🧑‍✈️":"1f9d1-200d-2708-fe0f","🧑🏻‍✈":"1f9d1-1f3fb-200d-2708-fe0f","🧑🏼‍✈":"1f9d1-1f3fc-200d-2708-fe0f","🧑🏽‍✈":"1f9d1-1f3fd-200d-2708-fe0f","🧑🏾‍✈":"1f9d1-1f3fe-200d-2708-fe0f","🧑🏿‍✈":"1f9d1-1f3ff-200d-2708-fe0f","👨‍✈️":"1f468-200d-2708-fe0f","👨🏻‍✈":"1f468-1f3fb-200d-2708-fe0f","👨🏼‍✈":"1f468-1f3fc-200d-2708-fe0f","👨🏽‍✈":"1f468-1f3fd-200d-2708-fe0f","👨🏾‍✈":"1f468-1f3fe-200d-2708-fe0f","👨🏿‍✈":"1f468-1f3ff-200d-2708-fe0f","👩‍✈️":"1f469-200d-2708-fe0f","👩🏻‍✈":"1f469-1f3fb-200d-2708-fe0f","👩🏼‍✈":"1f469-1f3fc-200d-2708-fe0f","👩🏽‍✈":"1f469-1f3fd-200d-2708-fe0f","👩🏾‍✈":"1f469-1f3fe-200d-2708-fe0f","👩🏿‍✈":"1f469-1f3ff-200d-2708-fe0f","🧑🏻‍🚀":"1f9d1-1f3fb-200d-1f680","🧑🏼‍🚀":"1f9d1-1f3fc-200d-1f680","🧑🏽‍🚀":"1f9d1-1f3fd-200d-1f680","🧑🏾‍🚀":"1f9d1-1f3fe-200d-1f680","🧑🏿‍🚀":"1f9d1-1f3ff-200d-1f680","👨🏻‍🚀":"1f468-1f3fb-200d-1f680","👨🏼‍🚀":"1f468-1f3fc-200d-1f680","👨🏽‍🚀":"1f468-1f3fd-200d-1f680","👨🏾‍🚀":"1f468-1f3fe-200d-1f680","👨🏿‍🚀":"1f468-1f3ff-200d-1f680","👩🏻‍🚀":"1f469-1f3fb-200d-1f680","👩🏼‍🚀":"1f469-1f3fc-200d-1f680","👩🏽‍🚀":"1f469-1f3fd-200d-1f680","👩🏾‍🚀":"1f469-1f3fe-200d-1f680","👩🏿‍🚀":"1f469-1f3ff-200d-1f680","🧑🏻‍🚒":"1f9d1-1f3fb-200d-1f692","🧑🏼‍🚒":"1f9d1-1f3fc-200d-1f692","🧑🏽‍🚒":"1f9d1-1f3fd-200d-1f692","🧑🏾‍🚒":"1f9d1-1f3fe-200d-1f692","🧑🏿‍🚒":"1f9d1-1f3ff-200d-1f692","👨🏻‍🚒":"1f468-1f3fb-200d-1f692","👨🏼‍🚒":"1f468-1f3fc-200d-1f692","👨🏽‍🚒":"1f468-1f3fd-200d-1f692","👨🏾‍🚒":"1f468-1f3fe-200d-1f692","👨🏿‍🚒":"1f468-1f3ff-200d-1f692","👩🏻‍🚒":"1f469-1f3fb-200d-1f692","👩🏼‍🚒":"1f469-1f3fc-200d-1f692","👩🏽‍🚒":"1f469-1f3fd-200d-1f692","👩🏾‍🚒":"1f469-1f3fe-200d-1f692","👩🏿‍🚒":"1f469-1f3ff-200d-1f692","👮‍♂️":"1f46e-200d-2642-fe0f","👮🏻‍♂":"1f46e-1f3fb-200d-2642-fe0f","👮🏼‍♂":"1f46e-1f3fc-200d-2642-fe0f","👮🏽‍♂":"1f46e-1f3fd-200d-2642-fe0f","👮🏾‍♂":"1f46e-1f3fe-200d-2642-fe0f","👮🏿‍♂":"1f46e-1f3ff-200d-2642-fe0f","👮‍♀️":"1f46e-200d-2640-fe0f","👮🏻‍♀":"1f46e-1f3fb-200d-2640-fe0f","👮🏼‍♀":"1f46e-1f3fc-200d-2640-fe0f","👮🏽‍♀":"1f46e-1f3fd-200d-2640-fe0f","👮🏾‍♀":"1f46e-1f3fe-200d-2640-fe0f","👮🏿‍♀":"1f46e-1f3ff-200d-2640-fe0f","🕵‍♂️":"1f575-fe0f-200d-2642-fe0f","🕵️‍♂":"1f575-fe0f-200d-2642-fe0f","🕵🏻‍♂":"1f575-1f3fb-200d-2642-fe0f","🕵🏼‍♂":"1f575-1f3fc-200d-2642-fe0f","🕵🏽‍♂":"1f575-1f3fd-200d-2642-fe0f","🕵🏾‍♂":"1f575-1f3fe-200d-2642-fe0f","🕵🏿‍♂":"1f575-1f3ff-200d-2642-fe0f","🕵‍♀️":"1f575-fe0f-200d-2640-fe0f","🕵️‍♀":"1f575-fe0f-200d-2640-fe0f","🕵🏻‍♀":"1f575-1f3fb-200d-2640-fe0f","🕵🏼‍♀":"1f575-1f3fc-200d-2640-fe0f","🕵🏽‍♀":"1f575-1f3fd-200d-2640-fe0f","🕵🏾‍♀":"1f575-1f3fe-200d-2640-fe0f","🕵🏿‍♀":"1f575-1f3ff-200d-2640-fe0f","💂‍♂️":"1f482-200d-2642-fe0f","💂🏻‍♂":"1f482-1f3fb-200d-2642-fe0f","💂🏼‍♂":"1f482-1f3fc-200d-2642-fe0f","💂🏽‍♂":"1f482-1f3fd-200d-2642-fe0f","💂🏾‍♂":"1f482-1f3fe-200d-2642-fe0f","💂🏿‍♂":"1f482-1f3ff-200d-2642-fe0f","💂‍♀️":"1f482-200d-2640-fe0f","💂🏻‍♀":"1f482-1f3fb-200d-2640-fe0f","💂🏼‍♀":"1f482-1f3fc-200d-2640-fe0f","💂🏽‍♀":"1f482-1f3fd-200d-2640-fe0f","💂🏾‍♀":"1f482-1f3fe-200d-2640-fe0f","💂🏿‍♀":"1f482-1f3ff-200d-2640-fe0f","👷‍♂️":"1f477-200d-2642-fe0f","👷🏻‍♂":"1f477-1f3fb-200d-2642-fe0f","👷🏼‍♂":"1f477-1f3fc-200d-2642-fe0f","👷🏽‍♂":"1f477-1f3fd-200d-2642-fe0f","👷🏾‍♂":"1f477-1f3fe-200d-2642-fe0f","👷🏿‍♂":"1f477-1f3ff-200d-2642-fe0f","👷‍♀️":"1f477-200d-2640-fe0f","👷🏻‍♀":"1f477-1f3fb-200d-2640-fe0f","👷🏼‍♀":"1f477-1f3fc-200d-2640-fe0f","👷🏽‍♀":"1f477-1f3fd-200d-2640-fe0f","👷🏾‍♀":"1f477-1f3fe-200d-2640-fe0f","👷🏿‍♀":"1f477-1f3ff-200d-2640-fe0f","👳‍♂️":"1f473-200d-2642-fe0f","👳🏻‍♂":"1f473-1f3fb-200d-2642-fe0f","👳🏼‍♂":"1f473-1f3fc-200d-2642-fe0f","👳🏽‍♂":"1f473-1f3fd-200d-2642-fe0f","👳🏾‍♂":"1f473-1f3fe-200d-2642-fe0f","👳🏿‍♂":"1f473-1f3ff-200d-2642-fe0f","👳‍♀️":"1f473-200d-2640-fe0f","👳🏻‍♀":"1f473-1f3fb-200d-2640-fe0f","👳🏼‍♀":"1f473-1f3fc-200d-2640-fe0f","👳🏽‍♀":"1f473-1f3fd-200d-2640-fe0f","👳🏾‍♀":"1f473-1f3fe-200d-2640-fe0f","👳🏿‍♀":"1f473-1f3ff-200d-2640-fe0f","🤵‍♂️":"1f935-200d-2642-fe0f","🤵🏻‍♂":"1f935-1f3fb-200d-2642-fe0f","🤵🏼‍♂":"1f935-1f3fc-200d-2642-fe0f","🤵🏽‍♂":"1f935-1f3fd-200d-2642-fe0f","🤵🏾‍♂":"1f935-1f3fe-200d-2642-fe0f","🤵🏿‍♂":"1f935-1f3ff-200d-2642-fe0f","🤵‍♀️":"1f935-200d-2640-fe0f","🤵🏻‍♀":"1f935-1f3fb-200d-2640-fe0f","🤵🏼‍♀":"1f935-1f3fc-200d-2640-fe0f","🤵🏽‍♀":"1f935-1f3fd-200d-2640-fe0f","🤵🏾‍♀":"1f935-1f3fe-200d-2640-fe0f","🤵🏿‍♀":"1f935-1f3ff-200d-2640-fe0f","👰‍♂️":"1f470-200d-2642-fe0f","👰🏻‍♂":"1f470-1f3fb-200d-2642-fe0f","👰🏼‍♂":"1f470-1f3fc-200d-2642-fe0f","👰🏽‍♂":"1f470-1f3fd-200d-2642-fe0f","👰🏾‍♂":"1f470-1f3fe-200d-2642-fe0f","👰🏿‍♂":"1f470-1f3ff-200d-2642-fe0f","👰‍♀️":"1f470-200d-2640-fe0f","👰🏻‍♀":"1f470-1f3fb-200d-2640-fe0f","👰🏼‍♀":"1f470-1f3fc-200d-2640-fe0f","👰🏽‍♀":"1f470-1f3fd-200d-2640-fe0f","👰🏾‍♀":"1f470-1f3fe-200d-2640-fe0f","👰🏿‍♀":"1f470-1f3ff-200d-2640-fe0f","👩🏻‍🍼":"1f469-1f3fb-200d-1f37c","👩🏼‍🍼":"1f469-1f3fc-200d-1f37c","👩🏽‍🍼":"1f469-1f3fd-200d-1f37c","👩🏾‍🍼":"1f469-1f3fe-200d-1f37c","👩🏿‍🍼":"1f469-1f3ff-200d-1f37c","👨🏻‍🍼":"1f468-1f3fb-200d-1f37c","👨🏼‍🍼":"1f468-1f3fc-200d-1f37c","👨🏽‍🍼":"1f468-1f3fd-200d-1f37c","👨🏾‍🍼":"1f468-1f3fe-200d-1f37c","👨🏿‍🍼":"1f468-1f3ff-200d-1f37c","🧑🏻‍🍼":"1f9d1-1f3fb-200d-1f37c","🧑🏼‍🍼":"1f9d1-1f3fc-200d-1f37c","🧑🏽‍🍼":"1f9d1-1f3fd-200d-1f37c","🧑🏾‍🍼":"1f9d1-1f3fe-200d-1f37c","🧑🏿‍🍼":"1f9d1-1f3ff-200d-1f37c","🧑🏻‍🎄":"1f9d1-1f3fb-200d-1f384","🧑🏼‍🎄":"1f9d1-1f3fc-200d-1f384","🧑🏽‍🎄":"1f9d1-1f3fd-200d-1f384","🧑🏾‍🎄":"1f9d1-1f3fe-200d-1f384","🧑🏿‍🎄":"1f9d1-1f3ff-200d-1f384","🦸‍♂️":"1f9b8-200d-2642-fe0f","🦸🏻‍♂":"1f9b8-1f3fb-200d-2642-fe0f","🦸🏼‍♂":"1f9b8-1f3fc-200d-2642-fe0f","🦸🏽‍♂":"1f9b8-1f3fd-200d-2642-fe0f","🦸🏾‍♂":"1f9b8-1f3fe-200d-2642-fe0f","🦸🏿‍♂":"1f9b8-1f3ff-200d-2642-fe0f","🦸‍♀️":"1f9b8-200d-2640-fe0f","🦸🏻‍♀":"1f9b8-1f3fb-200d-2640-fe0f","🦸🏼‍♀":"1f9b8-1f3fc-200d-2640-fe0f","🦸🏽‍♀":"1f9b8-1f3fd-200d-2640-fe0f","🦸🏾‍♀":"1f9b8-1f3fe-200d-2640-fe0f","🦸🏿‍♀":"1f9b8-1f3ff-200d-2640-fe0f","🦹‍♂️":"1f9b9-200d-2642-fe0f","🦹🏻‍♂":"1f9b9-1f3fb-200d-2642-fe0f","🦹🏼‍♂":"1f9b9-1f3fc-200d-2642-fe0f","🦹🏽‍♂":"1f9b9-1f3fd-200d-2642-fe0f","🦹🏾‍♂":"1f9b9-1f3fe-200d-2642-fe0f","🦹🏿‍♂":"1f9b9-1f3ff-200d-2642-fe0f","🦹‍♀️":"1f9b9-200d-2640-fe0f","🦹🏻‍♀":"1f9b9-1f3fb-200d-2640-fe0f","🦹🏼‍♀":"1f9b9-1f3fc-200d-2640-fe0f","🦹🏽‍♀":"1f9b9-1f3fd-200d-2640-fe0f","🦹🏾‍♀":"1f9b9-1f3fe-200d-2640-fe0f","🦹🏿‍♀":"1f9b9-1f3ff-200d-2640-fe0f","🧙‍♂️":"1f9d9-200d-2642-fe0f","🧙🏻‍♂":"1f9d9-1f3fb-200d-2642-fe0f","🧙🏼‍♂":"1f9d9-1f3fc-200d-2642-fe0f","🧙🏽‍♂":"1f9d9-1f3fd-200d-2642-fe0f","🧙🏾‍♂":"1f9d9-1f3fe-200d-2642-fe0f","🧙🏿‍♂":"1f9d9-1f3ff-200d-2642-fe0f","🧙‍♀️":"1f9d9-200d-2640-fe0f","🧙🏻‍♀":"1f9d9-1f3fb-200d-2640-fe0f","🧙🏼‍♀":"1f9d9-1f3fc-200d-2640-fe0f","🧙🏽‍♀":"1f9d9-1f3fd-200d-2640-fe0f","🧙🏾‍♀":"1f9d9-1f3fe-200d-2640-fe0f","🧙🏿‍♀":"1f9d9-1f3ff-200d-2640-fe0f","🧚‍♂️":"1f9da-200d-2642-fe0f","🧚🏻‍♂":"1f9da-1f3fb-200d-2642-fe0f","🧚🏼‍♂":"1f9da-1f3fc-200d-2642-fe0f","🧚🏽‍♂":"1f9da-1f3fd-200d-2642-fe0f","🧚🏾‍♂":"1f9da-1f3fe-200d-2642-fe0f","🧚🏿‍♂":"1f9da-1f3ff-200d-2642-fe0f","🧚‍♀️":"1f9da-200d-2640-fe0f","🧚🏻‍♀":"1f9da-1f3fb-200d-2640-fe0f","🧚🏼‍♀":"1f9da-1f3fc-200d-2640-fe0f","🧚🏽‍♀":"1f9da-1f3fd-200d-2640-fe0f","🧚🏾‍♀":"1f9da-1f3fe-200d-2640-fe0f","🧚🏿‍♀":"1f9da-1f3ff-200d-2640-fe0f","🧛‍♂️":"1f9db-200d-2642-fe0f","🧛🏻‍♂":"1f9db-1f3fb-200d-2642-fe0f","🧛🏼‍♂":"1f9db-1f3fc-200d-2642-fe0f","🧛🏽‍♂":"1f9db-1f3fd-200d-2642-fe0f","🧛🏾‍♂":"1f9db-1f3fe-200d-2642-fe0f","🧛🏿‍♂":"1f9db-1f3ff-200d-2642-fe0f","🧛‍♀️":"1f9db-200d-2640-fe0f","🧛🏻‍♀":"1f9db-1f3fb-200d-2640-fe0f","🧛🏼‍♀":"1f9db-1f3fc-200d-2640-fe0f","🧛🏽‍♀":"1f9db-1f3fd-200d-2640-fe0f","🧛🏾‍♀":"1f9db-1f3fe-200d-2640-fe0f","🧛🏿‍♀":"1f9db-1f3ff-200d-2640-fe0f","🧜‍♂️":"1f9dc-200d-2642-fe0f","🧜🏻‍♂":"1f9dc-1f3fb-200d-2642-fe0f","🧜🏼‍♂":"1f9dc-1f3fc-200d-2642-fe0f","🧜🏽‍♂":"1f9dc-1f3fd-200d-2642-fe0f","🧜🏾‍♂":"1f9dc-1f3fe-200d-2642-fe0f","🧜🏿‍♂":"1f9dc-1f3ff-200d-2642-fe0f","🧜‍♀️":"1f9dc-200d-2640-fe0f","🧜🏻‍♀":"1f9dc-1f3fb-200d-2640-fe0f","🧜🏼‍♀":"1f9dc-1f3fc-200d-2640-fe0f","🧜🏽‍♀":"1f9dc-1f3fd-200d-2640-fe0f","🧜🏾‍♀":"1f9dc-1f3fe-200d-2640-fe0f","🧜🏿‍♀":"1f9dc-1f3ff-200d-2640-fe0f","🧝‍♂️":"1f9dd-200d-2642-fe0f","🧝🏻‍♂":"1f9dd-1f3fb-200d-2642-fe0f","🧝🏼‍♂":"1f9dd-1f3fc-200d-2642-fe0f","🧝🏽‍♂":"1f9dd-1f3fd-200d-2642-fe0f","🧝🏾‍♂":"1f9dd-1f3fe-200d-2642-fe0f","🧝🏿‍♂":"1f9dd-1f3ff-200d-2642-fe0f","🧝‍♀️":"1f9dd-200d-2640-fe0f","🧝🏻‍♀":"1f9dd-1f3fb-200d-2640-fe0f","🧝🏼‍♀":"1f9dd-1f3fc-200d-2640-fe0f","🧝🏽‍♀":"1f9dd-1f3fd-200d-2640-fe0f","🧝🏾‍♀":"1f9dd-1f3fe-200d-2640-fe0f","🧝🏿‍♀":"1f9dd-1f3ff-200d-2640-fe0f","🧞‍♂️":"1f9de-200d-2642-fe0f","🧞‍♀️":"1f9de-200d-2640-fe0f","🧟‍♂️":"1f9df-200d-2642-fe0f","🧟‍♀️":"1f9df-200d-2640-fe0f","💆‍♂️":"1f486-200d-2642-fe0f","💆🏻‍♂":"1f486-1f3fb-200d-2642-fe0f","💆🏼‍♂":"1f486-1f3fc-200d-2642-fe0f","💆🏽‍♂":"1f486-1f3fd-200d-2642-fe0f","💆🏾‍♂":"1f486-1f3fe-200d-2642-fe0f","💆🏿‍♂":"1f486-1f3ff-200d-2642-fe0f","💆‍♀️":"1f486-200d-2640-fe0f","💆🏻‍♀":"1f486-1f3fb-200d-2640-fe0f","💆🏼‍♀":"1f486-1f3fc-200d-2640-fe0f","💆🏽‍♀":"1f486-1f3fd-200d-2640-fe0f","💆🏾‍♀":"1f486-1f3fe-200d-2640-fe0f","💆🏿‍♀":"1f486-1f3ff-200d-2640-fe0f","💇‍♂️":"1f487-200d-2642-fe0f","💇🏻‍♂":"1f487-1f3fb-200d-2642-fe0f","💇🏼‍♂":"1f487-1f3fc-200d-2642-fe0f","💇🏽‍♂":"1f487-1f3fd-200d-2642-fe0f","💇🏾‍♂":"1f487-1f3fe-200d-2642-fe0f","💇🏿‍♂":"1f487-1f3ff-200d-2642-fe0f","💇‍♀️":"1f487-200d-2640-fe0f","💇🏻‍♀":"1f487-1f3fb-200d-2640-fe0f","💇🏼‍♀":"1f487-1f3fc-200d-2640-fe0f","💇🏽‍♀":"1f487-1f3fd-200d-2640-fe0f","💇🏾‍♀":"1f487-1f3fe-200d-2640-fe0f","💇🏿‍♀":"1f487-1f3ff-200d-2640-fe0f","🚶‍♂️":"1f6b6-200d-2642-fe0f","🚶🏻‍♂":"1f6b6-1f3fb-200d-2642-fe0f","🚶🏼‍♂":"1f6b6-1f3fc-200d-2642-fe0f","🚶🏽‍♂":"1f6b6-1f3fd-200d-2642-fe0f","🚶🏾‍♂":"1f6b6-1f3fe-200d-2642-fe0f","🚶🏿‍♂":"1f6b6-1f3ff-200d-2642-fe0f","🚶‍♀️":"1f6b6-200d-2640-fe0f","🚶🏻‍♀":"1f6b6-1f3fb-200d-2640-fe0f","🚶🏼‍♀":"1f6b6-1f3fc-200d-2640-fe0f","🚶🏽‍♀":"1f6b6-1f3fd-200d-2640-fe0f","🚶🏾‍♀":"1f6b6-1f3fe-200d-2640-fe0f","🚶🏿‍♀":"1f6b6-1f3ff-200d-2640-fe0f","🧍‍♂️":"1f9cd-200d-2642-fe0f","🧍🏻‍♂":"1f9cd-1f3fb-200d-2642-fe0f","🧍🏼‍♂":"1f9cd-1f3fc-200d-2642-fe0f","🧍🏽‍♂":"1f9cd-1f3fd-200d-2642-fe0f","🧍🏾‍♂":"1f9cd-1f3fe-200d-2642-fe0f","🧍🏿‍♂":"1f9cd-1f3ff-200d-2642-fe0f","🧍‍♀️":"1f9cd-200d-2640-fe0f","🧍🏻‍♀":"1f9cd-1f3fb-200d-2640-fe0f","🧍🏼‍♀":"1f9cd-1f3fc-200d-2640-fe0f","🧍🏽‍♀":"1f9cd-1f3fd-200d-2640-fe0f","🧍🏾‍♀":"1f9cd-1f3fe-200d-2640-fe0f","🧍🏿‍♀":"1f9cd-1f3ff-200d-2640-fe0f","🧎‍♂️":"1f9ce-200d-2642-fe0f","🧎🏻‍♂":"1f9ce-1f3fb-200d-2642-fe0f","🧎🏼‍♂":"1f9ce-1f3fc-200d-2642-fe0f","🧎🏽‍♂":"1f9ce-1f3fd-200d-2642-fe0f","🧎🏾‍♂":"1f9ce-1f3fe-200d-2642-fe0f","🧎🏿‍♂":"1f9ce-1f3ff-200d-2642-fe0f","🧎‍♀️":"1f9ce-200d-2640-fe0f","🧎🏻‍♀":"1f9ce-1f3fb-200d-2640-fe0f","🧎🏼‍♀":"1f9ce-1f3fc-200d-2640-fe0f","🧎🏽‍♀":"1f9ce-1f3fd-200d-2640-fe0f","🧎🏾‍♀":"1f9ce-1f3fe-200d-2640-fe0f","🧎🏿‍♀":"1f9ce-1f3ff-200d-2640-fe0f","🧑🏻‍🦯":"1f9d1-1f3fb-200d-1f9af","🧑🏼‍🦯":"1f9d1-1f3fc-200d-1f9af","🧑🏽‍🦯":"1f9d1-1f3fd-200d-1f9af","🧑🏾‍🦯":"1f9d1-1f3fe-200d-1f9af","🧑🏿‍🦯":"1f9d1-1f3ff-200d-1f9af","👨🏻‍🦯":"1f468-1f3fb-200d-1f9af","👨🏼‍🦯":"1f468-1f3fc-200d-1f9af","👨🏽‍🦯":"1f468-1f3fd-200d-1f9af","👨🏾‍🦯":"1f468-1f3fe-200d-1f9af","👨🏿‍🦯":"1f468-1f3ff-200d-1f9af","👩🏻‍🦯":"1f469-1f3fb-200d-1f9af","👩🏼‍🦯":"1f469-1f3fc-200d-1f9af","👩🏽‍🦯":"1f469-1f3fd-200d-1f9af","👩🏾‍🦯":"1f469-1f3fe-200d-1f9af","👩🏿‍🦯":"1f469-1f3ff-200d-1f9af","🧑🏻‍🦼":"1f9d1-1f3fb-200d-1f9bc","🧑🏼‍🦼":"1f9d1-1f3fc-200d-1f9bc","🧑🏽‍🦼":"1f9d1-1f3fd-200d-1f9bc","🧑🏾‍🦼":"1f9d1-1f3fe-200d-1f9bc","🧑🏿‍🦼":"1f9d1-1f3ff-200d-1f9bc","👨🏻‍🦼":"1f468-1f3fb-200d-1f9bc","👨🏼‍🦼":"1f468-1f3fc-200d-1f9bc","👨🏽‍🦼":"1f468-1f3fd-200d-1f9bc","👨🏾‍🦼":"1f468-1f3fe-200d-1f9bc","👨🏿‍🦼":"1f468-1f3ff-200d-1f9bc","👩🏻‍🦼":"1f469-1f3fb-200d-1f9bc","👩🏼‍🦼":"1f469-1f3fc-200d-1f9bc","👩🏽‍🦼":"1f469-1f3fd-200d-1f9bc","👩🏾‍🦼":"1f469-1f3fe-200d-1f9bc","👩🏿‍🦼":"1f469-1f3ff-200d-1f9bc","🧑🏻‍🦽":"1f9d1-1f3fb-200d-1f9bd","🧑🏼‍🦽":"1f9d1-1f3fc-200d-1f9bd","🧑🏽‍🦽":"1f9d1-1f3fd-200d-1f9bd","🧑🏾‍🦽":"1f9d1-1f3fe-200d-1f9bd","🧑🏿‍🦽":"1f9d1-1f3ff-200d-1f9bd","👨🏻‍🦽":"1f468-1f3fb-200d-1f9bd","👨🏼‍🦽":"1f468-1f3fc-200d-1f9bd","👨🏽‍🦽":"1f468-1f3fd-200d-1f9bd","👨🏾‍🦽":"1f468-1f3fe-200d-1f9bd","👨🏿‍🦽":"1f468-1f3ff-200d-1f9bd","👩🏻‍🦽":"1f469-1f3fb-200d-1f9bd","👩🏼‍🦽":"1f469-1f3fc-200d-1f9bd","👩🏽‍🦽":"1f469-1f3fd-200d-1f9bd","👩🏾‍🦽":"1f469-1f3fe-200d-1f9bd","👩🏿‍🦽":"1f469-1f3ff-200d-1f9bd","🏃‍♂️":"1f3c3-200d-2642-fe0f","🏃🏻‍♂":"1f3c3-1f3fb-200d-2642-fe0f","🏃🏼‍♂":"1f3c3-1f3fc-200d-2642-fe0f","🏃🏽‍♂":"1f3c3-1f3fd-200d-2642-fe0f","🏃🏾‍♂":"1f3c3-1f3fe-200d-2642-fe0f","🏃🏿‍♂":"1f3c3-1f3ff-200d-2642-fe0f","🏃‍♀️":"1f3c3-200d-2640-fe0f","🏃🏻‍♀":"1f3c3-1f3fb-200d-2640-fe0f","🏃🏼‍♀":"1f3c3-1f3fc-200d-2640-fe0f","🏃🏽‍♀":"1f3c3-1f3fd-200d-2640-fe0f","🏃🏾‍♀":"1f3c3-1f3fe-200d-2640-fe0f","🏃🏿‍♀":"1f3c3-1f3ff-200d-2640-fe0f","👯‍♂️":"1f46f-200d-2642-fe0f","👯‍♀️":"1f46f-200d-2640-fe0f","🧖‍♂️":"1f9d6-200d-2642-fe0f","🧖🏻‍♂":"1f9d6-1f3fb-200d-2642-fe0f","🧖🏼‍♂":"1f9d6-1f3fc-200d-2642-fe0f","🧖🏽‍♂":"1f9d6-1f3fd-200d-2642-fe0f","🧖🏾‍♂":"1f9d6-1f3fe-200d-2642-fe0f","🧖🏿‍♂":"1f9d6-1f3ff-200d-2642-fe0f","🧖‍♀️":"1f9d6-200d-2640-fe0f","🧖🏻‍♀":"1f9d6-1f3fb-200d-2640-fe0f","🧖🏼‍♀":"1f9d6-1f3fc-200d-2640-fe0f","🧖🏽‍♀":"1f9d6-1f3fd-200d-2640-fe0f","🧖🏾‍♀":"1f9d6-1f3fe-200d-2640-fe0f","🧖🏿‍♀":"1f9d6-1f3ff-200d-2640-fe0f","🧗‍♂️":"1f9d7-200d-2642-fe0f","🧗🏻‍♂":"1f9d7-1f3fb-200d-2642-fe0f","🧗🏼‍♂":"1f9d7-1f3fc-200d-2642-fe0f","🧗🏽‍♂":"1f9d7-1f3fd-200d-2642-fe0f","🧗🏾‍♂":"1f9d7-1f3fe-200d-2642-fe0f","🧗🏿‍♂":"1f9d7-1f3ff-200d-2642-fe0f","🧗‍♀️":"1f9d7-200d-2640-fe0f","🧗🏻‍♀":"1f9d7-1f3fb-200d-2640-fe0f","🧗🏼‍♀":"1f9d7-1f3fc-200d-2640-fe0f","🧗🏽‍♀":"1f9d7-1f3fd-200d-2640-fe0f","🧗🏾‍♀":"1f9d7-1f3fe-200d-2640-fe0f","🧗🏿‍♀":"1f9d7-1f3ff-200d-2640-fe0f","🏌‍♂️":"1f3cc-fe0f-200d-2642-fe0f","🏌️‍♂":"1f3cc-fe0f-200d-2642-fe0f","🏌🏻‍♂":"1f3cc-1f3fb-200d-2642-fe0f","🏌🏼‍♂":"1f3cc-1f3fc-200d-2642-fe0f","🏌🏽‍♂":"1f3cc-1f3fd-200d-2642-fe0f","🏌🏾‍♂":"1f3cc-1f3fe-200d-2642-fe0f","🏌🏿‍♂":"1f3cc-1f3ff-200d-2642-fe0f","🏌‍♀️":"1f3cc-fe0f-200d-2640-fe0f","🏌️‍♀":"1f3cc-fe0f-200d-2640-fe0f","🏌🏻‍♀":"1f3cc-1f3fb-200d-2640-fe0f","🏌🏼‍♀":"1f3cc-1f3fc-200d-2640-fe0f","🏌🏽‍♀":"1f3cc-1f3fd-200d-2640-fe0f","🏌🏾‍♀":"1f3cc-1f3fe-200d-2640-fe0f","🏌🏿‍♀":"1f3cc-1f3ff-200d-2640-fe0f","🏄‍♂️":"1f3c4-200d-2642-fe0f","🏄🏻‍♂":"1f3c4-1f3fb-200d-2642-fe0f","🏄🏼‍♂":"1f3c4-1f3fc-200d-2642-fe0f","🏄🏽‍♂":"1f3c4-1f3fd-200d-2642-fe0f","🏄🏾‍♂":"1f3c4-1f3fe-200d-2642-fe0f","🏄🏿‍♂":"1f3c4-1f3ff-200d-2642-fe0f","🏄‍♀️":"1f3c4-200d-2640-fe0f","🏄🏻‍♀":"1f3c4-1f3fb-200d-2640-fe0f","🏄🏼‍♀":"1f3c4-1f3fc-200d-2640-fe0f","🏄🏽‍♀":"1f3c4-1f3fd-200d-2640-fe0f","🏄🏾‍♀":"1f3c4-1f3fe-200d-2640-fe0f","🏄🏿‍♀":"1f3c4-1f3ff-200d-2640-fe0f","🚣‍♂️":"1f6a3-200d-2642-fe0f","🚣🏻‍♂":"1f6a3-1f3fb-200d-2642-fe0f","🚣🏼‍♂":"1f6a3-1f3fc-200d-2642-fe0f","🚣🏽‍♂":"1f6a3-1f3fd-200d-2642-fe0f","🚣🏾‍♂":"1f6a3-1f3fe-200d-2642-fe0f","🚣🏿‍♂":"1f6a3-1f3ff-200d-2642-fe0f","🚣‍♀️":"1f6a3-200d-2640-fe0f","🚣🏻‍♀":"1f6a3-1f3fb-200d-2640-fe0f","🚣🏼‍♀":"1f6a3-1f3fc-200d-2640-fe0f","🚣🏽‍♀":"1f6a3-1f3fd-200d-2640-fe0f","🚣🏾‍♀":"1f6a3-1f3fe-200d-2640-fe0f","🚣🏿‍♀":"1f6a3-1f3ff-200d-2640-fe0f","🏊‍♂️":"1f3ca-200d-2642-fe0f","🏊🏻‍♂":"1f3ca-1f3fb-200d-2642-fe0f","🏊🏼‍♂":"1f3ca-1f3fc-200d-2642-fe0f","🏊🏽‍♂":"1f3ca-1f3fd-200d-2642-fe0f","🏊🏾‍♂":"1f3ca-1f3fe-200d-2642-fe0f","🏊🏿‍♂":"1f3ca-1f3ff-200d-2642-fe0f","🏊‍♀️":"1f3ca-200d-2640-fe0f","🏊🏻‍♀":"1f3ca-1f3fb-200d-2640-fe0f","🏊🏼‍♀":"1f3ca-1f3fc-200d-2640-fe0f","🏊🏽‍♀":"1f3ca-1f3fd-200d-2640-fe0f","🏊🏾‍♀":"1f3ca-1f3fe-200d-2640-fe0f","🏊🏿‍♀":"1f3ca-1f3ff-200d-2640-fe0f","⛹‍♂️":"26f9-fe0f-200d-2642-fe0f","⛹️‍♂":"26f9-fe0f-200d-2642-fe0f","⛹🏻‍♂":"26f9-1f3fb-200d-2642-fe0f","⛹🏼‍♂":"26f9-1f3fc-200d-2642-fe0f","⛹🏽‍♂":"26f9-1f3fd-200d-2642-fe0f","⛹🏾‍♂":"26f9-1f3fe-200d-2642-fe0f","⛹🏿‍♂":"26f9-1f3ff-200d-2642-fe0f","⛹‍♀️":"26f9-fe0f-200d-2640-fe0f","⛹️‍♀":"26f9-fe0f-200d-2640-fe0f","⛹🏻‍♀":"26f9-1f3fb-200d-2640-fe0f","⛹🏼‍♀":"26f9-1f3fc-200d-2640-fe0f","⛹🏽‍♀":"26f9-1f3fd-200d-2640-fe0f","⛹🏾‍♀":"26f9-1f3fe-200d-2640-fe0f","⛹🏿‍♀":"26f9-1f3ff-200d-2640-fe0f","🏋‍♂️":"1f3cb-fe0f-200d-2642-fe0f","🏋️‍♂":"1f3cb-fe0f-200d-2642-fe0f","🏋🏻‍♂":"1f3cb-1f3fb-200d-2642-fe0f","🏋🏼‍♂":"1f3cb-1f3fc-200d-2642-fe0f","🏋🏽‍♂":"1f3cb-1f3fd-200d-2642-fe0f","🏋🏾‍♂":"1f3cb-1f3fe-200d-2642-fe0f","🏋🏿‍♂":"1f3cb-1f3ff-200d-2642-fe0f","🏋‍♀️":"1f3cb-fe0f-200d-2640-fe0f","🏋️‍♀":"1f3cb-fe0f-200d-2640-fe0f","🏋🏻‍♀":"1f3cb-1f3fb-200d-2640-fe0f","🏋🏼‍♀":"1f3cb-1f3fc-200d-2640-fe0f","🏋🏽‍♀":"1f3cb-1f3fd-200d-2640-fe0f","🏋🏾‍♀":"1f3cb-1f3fe-200d-2640-fe0f","🏋🏿‍♀":"1f3cb-1f3ff-200d-2640-fe0f","🚴‍♂️":"1f6b4-200d-2642-fe0f","🚴🏻‍♂":"1f6b4-1f3fb-200d-2642-fe0f","🚴🏼‍♂":"1f6b4-1f3fc-200d-2642-fe0f","🚴🏽‍♂":"1f6b4-1f3fd-200d-2642-fe0f","🚴🏾‍♂":"1f6b4-1f3fe-200d-2642-fe0f","🚴🏿‍♂":"1f6b4-1f3ff-200d-2642-fe0f","🚴‍♀️":"1f6b4-200d-2640-fe0f","🚴🏻‍♀":"1f6b4-1f3fb-200d-2640-fe0f","🚴🏼‍♀":"1f6b4-1f3fc-200d-2640-fe0f","🚴🏽‍♀":"1f6b4-1f3fd-200d-2640-fe0f","🚴🏾‍♀":"1f6b4-1f3fe-200d-2640-fe0f","🚴🏿‍♀":"1f6b4-1f3ff-200d-2640-fe0f","🚵‍♂️":"1f6b5-200d-2642-fe0f","🚵🏻‍♂":"1f6b5-1f3fb-200d-2642-fe0f","🚵🏼‍♂":"1f6b5-1f3fc-200d-2642-fe0f","🚵🏽‍♂":"1f6b5-1f3fd-200d-2642-fe0f","🚵🏾‍♂":"1f6b5-1f3fe-200d-2642-fe0f","🚵🏿‍♂":"1f6b5-1f3ff-200d-2642-fe0f","🚵‍♀️":"1f6b5-200d-2640-fe0f","🚵🏻‍♀":"1f6b5-1f3fb-200d-2640-fe0f","🚵🏼‍♀":"1f6b5-1f3fc-200d-2640-fe0f","🚵🏽‍♀":"1f6b5-1f3fd-200d-2640-fe0f","🚵🏾‍♀":"1f6b5-1f3fe-200d-2640-fe0f","🚵🏿‍♀":"1f6b5-1f3ff-200d-2640-fe0f","🤸‍♂️":"1f938-200d-2642-fe0f","🤸🏻‍♂":"1f938-1f3fb-200d-2642-fe0f","🤸🏼‍♂":"1f938-1f3fc-200d-2642-fe0f","🤸🏽‍♂":"1f938-1f3fd-200d-2642-fe0f","🤸🏾‍♂":"1f938-1f3fe-200d-2642-fe0f","🤸🏿‍♂":"1f938-1f3ff-200d-2642-fe0f","🤸‍♀️":"1f938-200d-2640-fe0f","🤸🏻‍♀":"1f938-1f3fb-200d-2640-fe0f","🤸🏼‍♀":"1f938-1f3fc-200d-2640-fe0f","🤸🏽‍♀":"1f938-1f3fd-200d-2640-fe0f","🤸🏾‍♀":"1f938-1f3fe-200d-2640-fe0f","🤸🏿‍♀":"1f938-1f3ff-200d-2640-fe0f","🤼‍♂️":"1f93c-200d-2642-fe0f","🤼‍♀️":"1f93c-200d-2640-fe0f","🤽‍♂️":"1f93d-200d-2642-fe0f","🤽🏻‍♂":"1f93d-1f3fb-200d-2642-fe0f","🤽🏼‍♂":"1f93d-1f3fc-200d-2642-fe0f","🤽🏽‍♂":"1f93d-1f3fd-200d-2642-fe0f","🤽🏾‍♂":"1f93d-1f3fe-200d-2642-fe0f","🤽🏿‍♂":"1f93d-1f3ff-200d-2642-fe0f","🤽‍♀️":"1f93d-200d-2640-fe0f","🤽🏻‍♀":"1f93d-1f3fb-200d-2640-fe0f","🤽🏼‍♀":"1f93d-1f3fc-200d-2640-fe0f","🤽🏽‍♀":"1f93d-1f3fd-200d-2640-fe0f","🤽🏾‍♀":"1f93d-1f3fe-200d-2640-fe0f","🤽🏿‍♀":"1f93d-1f3ff-200d-2640-fe0f","🤾‍♂️":"1f93e-200d-2642-fe0f","🤾🏻‍♂":"1f93e-1f3fb-200d-2642-fe0f","🤾🏼‍♂":"1f93e-1f3fc-200d-2642-fe0f","🤾🏽‍♂":"1f93e-1f3fd-200d-2642-fe0f","🤾🏾‍♂":"1f93e-1f3fe-200d-2642-fe0f","🤾🏿‍♂":"1f93e-1f3ff-200d-2642-fe0f","🤾‍♀️":"1f93e-200d-2640-fe0f","🤾🏻‍♀":"1f93e-1f3fb-200d-2640-fe0f","🤾🏼‍♀":"1f93e-1f3fc-200d-2640-fe0f","🤾🏽‍♀":"1f93e-1f3fd-200d-2640-fe0f","🤾🏾‍♀":"1f93e-1f3fe-200d-2640-fe0f","🤾🏿‍♀":"1f93e-1f3ff-200d-2640-fe0f","🤹‍♂️":"1f939-200d-2642-fe0f","🤹🏻‍♂":"1f939-1f3fb-200d-2642-fe0f","🤹🏼‍♂":"1f939-1f3fc-200d-2642-fe0f","🤹🏽‍♂":"1f939-1f3fd-200d-2642-fe0f","🤹🏾‍♂":"1f939-1f3fe-200d-2642-fe0f","🤹🏿‍♂":"1f939-1f3ff-200d-2642-fe0f","🤹‍♀️":"1f939-200d-2640-fe0f","🤹🏻‍♀":"1f939-1f3fb-200d-2640-fe0f","🤹🏼‍♀":"1f939-1f3fc-200d-2640-fe0f","🤹🏽‍♀":"1f939-1f3fd-200d-2640-fe0f","🤹🏾‍♀":"1f939-1f3fe-200d-2640-fe0f","🤹🏿‍♀":"1f939-1f3ff-200d-2640-fe0f","🧘‍♂️":"1f9d8-200d-2642-fe0f","🧘🏻‍♂":"1f9d8-1f3fb-200d-2642-fe0f","🧘🏼‍♂":"1f9d8-1f3fc-200d-2642-fe0f","🧘🏽‍♂":"1f9d8-1f3fd-200d-2642-fe0f","🧘🏾‍♂":"1f9d8-1f3fe-200d-2642-fe0f","🧘🏿‍♂":"1f9d8-1f3ff-200d-2642-fe0f","🧘‍♀️":"1f9d8-200d-2640-fe0f","🧘🏻‍♀":"1f9d8-1f3fb-200d-2640-fe0f","🧘🏼‍♀":"1f9d8-1f3fc-200d-2640-fe0f","🧘🏽‍♀":"1f9d8-1f3fd-200d-2640-fe0f","🧘🏾‍♀":"1f9d8-1f3fe-200d-2640-fe0f","🧘🏿‍♀":"1f9d8-1f3ff-200d-2640-fe0f","🐻‍❄️":"1f43b-200d-2744-fe0f","🏳️‍🌈":"1f3f3-fe0f-200d-1f308","🏳‍⚧️":"1f3f3-fe0f-200d-26a7-fe0f","🏳️‍⚧":"1f3f3-fe0f-200d-26a7-fe0f","🏴‍☠️":"1f3f4-200d-2620-fe0f","👁️‍🗨️":"1f441-200d-1f5e8","🫱🏻‍🫲🏼":"1faf1-1f3fb-200d-1faf2-1f3fc","🫱🏻‍🫲🏽":"1faf1-1f3fb-200d-1faf2-1f3fd","🫱🏻‍🫲🏾":"1faf1-1f3fb-200d-1faf2-1f3fe","🫱🏻‍🫲🏿":"1faf1-1f3fb-200d-1faf2-1f3ff","🫱🏼‍🫲🏻":"1faf1-1f3fc-200d-1faf2-1f3fb","🫱🏼‍🫲🏽":"1faf1-1f3fc-200d-1faf2-1f3fd","🫱🏼‍🫲🏾":"1faf1-1f3fc-200d-1faf2-1f3fe","🫱🏼‍🫲🏿":"1faf1-1f3fc-200d-1faf2-1f3ff","🫱🏽‍🫲🏻":"1faf1-1f3fd-200d-1faf2-1f3fb","🫱🏽‍🫲🏼":"1faf1-1f3fd-200d-1faf2-1f3fc","🫱🏽‍🫲🏾":"1faf1-1f3fd-200d-1faf2-1f3fe","🫱🏽‍🫲🏿":"1faf1-1f3fd-200d-1faf2-1f3ff","🫱🏾‍🫲🏻":"1faf1-1f3fe-200d-1faf2-1f3fb","🫱🏾‍🫲🏼":"1faf1-1f3fe-200d-1faf2-1f3fc","🫱🏾‍🫲🏽":"1faf1-1f3fe-200d-1faf2-1f3fd","🫱🏾‍🫲🏿":"1faf1-1f3fe-200d-1faf2-1f3ff","🫱🏿‍🫲🏻":"1faf1-1f3ff-200d-1faf2-1f3fb","🫱🏿‍🫲🏼":"1faf1-1f3ff-200d-1faf2-1f3fc","🫱🏿‍🫲🏽":"1faf1-1f3ff-200d-1faf2-1f3fd","🫱🏿‍🫲🏾":"1faf1-1f3ff-200d-1faf2-1f3fe","🧔🏻‍♂️":"1f9d4-1f3fb-200d-2642-fe0f","🧔🏼‍♂️":"1f9d4-1f3fc-200d-2642-fe0f","🧔🏽‍♂️":"1f9d4-1f3fd-200d-2642-fe0f","🧔🏾‍♂️":"1f9d4-1f3fe-200d-2642-fe0f","🧔🏿‍♂️":"1f9d4-1f3ff-200d-2642-fe0f","🧔🏻‍♀️":"1f9d4-1f3fb-200d-2640-fe0f","🧔🏼‍♀️":"1f9d4-1f3fc-200d-2640-fe0f","🧔🏽‍♀️":"1f9d4-1f3fd-200d-2640-fe0f","🧔🏾‍♀️":"1f9d4-1f3fe-200d-2640-fe0f","🧔🏿‍♀️":"1f9d4-1f3ff-200d-2640-fe0f","👱🏻‍♀️":"1f471-1f3fb-200d-2640-fe0f","👱🏼‍♀️":"1f471-1f3fc-200d-2640-fe0f","👱🏽‍♀️":"1f471-1f3fd-200d-2640-fe0f","👱🏾‍♀️":"1f471-1f3fe-200d-2640-fe0f","👱🏿‍♀️":"1f471-1f3ff-200d-2640-fe0f","👱🏻‍♂️":"1f471-1f3fb-200d-2642-fe0f","👱🏼‍♂️":"1f471-1f3fc-200d-2642-fe0f","👱🏽‍♂️":"1f471-1f3fd-200d-2642-fe0f","👱🏾‍♂️":"1f471-1f3fe-200d-2642-fe0f","👱🏿‍♂️":"1f471-1f3ff-200d-2642-fe0f","🙍🏻‍♂️":"1f64d-1f3fb-200d-2642-fe0f","🙍🏼‍♂️":"1f64d-1f3fc-200d-2642-fe0f","🙍🏽‍♂️":"1f64d-1f3fd-200d-2642-fe0f","🙍🏾‍♂️":"1f64d-1f3fe-200d-2642-fe0f","🙍🏿‍♂️":"1f64d-1f3ff-200d-2642-fe0f","🙍🏻‍♀️":"1f64d-1f3fb-200d-2640-fe0f","🙍🏼‍♀️":"1f64d-1f3fc-200d-2640-fe0f","🙍🏽‍♀️":"1f64d-1f3fd-200d-2640-fe0f","🙍🏾‍♀️":"1f64d-1f3fe-200d-2640-fe0f","🙍🏿‍♀️":"1f64d-1f3ff-200d-2640-fe0f","🙎🏻‍♂️":"1f64e-1f3fb-200d-2642-fe0f","🙎🏼‍♂️":"1f64e-1f3fc-200d-2642-fe0f","🙎🏽‍♂️":"1f64e-1f3fd-200d-2642-fe0f","🙎🏾‍♂️":"1f64e-1f3fe-200d-2642-fe0f","🙎🏿‍♂️":"1f64e-1f3ff-200d-2642-fe0f","🙎🏻‍♀️":"1f64e-1f3fb-200d-2640-fe0f","🙎🏼‍♀️":"1f64e-1f3fc-200d-2640-fe0f","🙎🏽‍♀️":"1f64e-1f3fd-200d-2640-fe0f","🙎🏾‍♀️":"1f64e-1f3fe-200d-2640-fe0f","🙎🏿‍♀️":"1f64e-1f3ff-200d-2640-fe0f","🙅🏻‍♂️":"1f645-1f3fb-200d-2642-fe0f","🙅🏼‍♂️":"1f645-1f3fc-200d-2642-fe0f","🙅🏽‍♂️":"1f645-1f3fd-200d-2642-fe0f","🙅🏾‍♂️":"1f645-1f3fe-200d-2642-fe0f","🙅🏿‍♂️":"1f645-1f3ff-200d-2642-fe0f","🙅🏻‍♀️":"1f645-1f3fb-200d-2640-fe0f","🙅🏼‍♀️":"1f645-1f3fc-200d-2640-fe0f","🙅🏽‍♀️":"1f645-1f3fd-200d-2640-fe0f","🙅🏾‍♀️":"1f645-1f3fe-200d-2640-fe0f","🙅🏿‍♀️":"1f645-1f3ff-200d-2640-fe0f","🙆🏻‍♂️":"1f646-1f3fb-200d-2642-fe0f","🙆🏼‍♂️":"1f646-1f3fc-200d-2642-fe0f","🙆🏽‍♂️":"1f646-1f3fd-200d-2642-fe0f","🙆🏾‍♂️":"1f646-1f3fe-200d-2642-fe0f","🙆🏿‍♂️":"1f646-1f3ff-200d-2642-fe0f","🙆🏻‍♀️":"1f646-1f3fb-200d-2640-fe0f","🙆🏼‍♀️":"1f646-1f3fc-200d-2640-fe0f","🙆🏽‍♀️":"1f646-1f3fd-200d-2640-fe0f","🙆🏾‍♀️":"1f646-1f3fe-200d-2640-fe0f","🙆🏿‍♀️":"1f646-1f3ff-200d-2640-fe0f","💁🏻‍♂️":"1f481-1f3fb-200d-2642-fe0f","💁🏼‍♂️":"1f481-1f3fc-200d-2642-fe0f","💁🏽‍♂️":"1f481-1f3fd-200d-2642-fe0f","💁🏾‍♂️":"1f481-1f3fe-200d-2642-fe0f","💁🏿‍♂️":"1f481-1f3ff-200d-2642-fe0f","💁🏻‍♀️":"1f481-1f3fb-200d-2640-fe0f","💁🏼‍♀️":"1f481-1f3fc-200d-2640-fe0f","💁🏽‍♀️":"1f481-1f3fd-200d-2640-fe0f","💁🏾‍♀️":"1f481-1f3fe-200d-2640-fe0f","💁🏿‍♀️":"1f481-1f3ff-200d-2640-fe0f","🙋🏻‍♂️":"1f64b-1f3fb-200d-2642-fe0f","🙋🏼‍♂️":"1f64b-1f3fc-200d-2642-fe0f","🙋🏽‍♂️":"1f64b-1f3fd-200d-2642-fe0f","🙋🏾‍♂️":"1f64b-1f3fe-200d-2642-fe0f","🙋🏿‍♂️":"1f64b-1f3ff-200d-2642-fe0f","🙋🏻‍♀️":"1f64b-1f3fb-200d-2640-fe0f","🙋🏼‍♀️":"1f64b-1f3fc-200d-2640-fe0f","🙋🏽‍♀️":"1f64b-1f3fd-200d-2640-fe0f","🙋🏾‍♀️":"1f64b-1f3fe-200d-2640-fe0f","🙋🏿‍♀️":"1f64b-1f3ff-200d-2640-fe0f","🧏🏻‍♂️":"1f9cf-1f3fb-200d-2642-fe0f","🧏🏼‍♂️":"1f9cf-1f3fc-200d-2642-fe0f","🧏🏽‍♂️":"1f9cf-1f3fd-200d-2642-fe0f","🧏🏾‍♂️":"1f9cf-1f3fe-200d-2642-fe0f","🧏🏿‍♂️":"1f9cf-1f3ff-200d-2642-fe0f","🧏🏻‍♀️":"1f9cf-1f3fb-200d-2640-fe0f","🧏🏼‍♀️":"1f9cf-1f3fc-200d-2640-fe0f","🧏🏽‍♀️":"1f9cf-1f3fd-200d-2640-fe0f","🧏🏾‍♀️":"1f9cf-1f3fe-200d-2640-fe0f","🧏🏿‍♀️":"1f9cf-1f3ff-200d-2640-fe0f","🙇🏻‍♂️":"1f647-1f3fb-200d-2642-fe0f","🙇🏼‍♂️":"1f647-1f3fc-200d-2642-fe0f","🙇🏽‍♂️":"1f647-1f3fd-200d-2642-fe0f","🙇🏾‍♂️":"1f647-1f3fe-200d-2642-fe0f","🙇🏿‍♂️":"1f647-1f3ff-200d-2642-fe0f","🙇🏻‍♀️":"1f647-1f3fb-200d-2640-fe0f","🙇🏼‍♀️":"1f647-1f3fc-200d-2640-fe0f","🙇🏽‍♀️":"1f647-1f3fd-200d-2640-fe0f","🙇🏾‍♀️":"1f647-1f3fe-200d-2640-fe0f","🙇🏿‍♀️":"1f647-1f3ff-200d-2640-fe0f","🤦🏻‍♂️":"1f926-1f3fb-200d-2642-fe0f","🤦🏼‍♂️":"1f926-1f3fc-200d-2642-fe0f","🤦🏽‍♂️":"1f926-1f3fd-200d-2642-fe0f","🤦🏾‍♂️":"1f926-1f3fe-200d-2642-fe0f","🤦🏿‍♂️":"1f926-1f3ff-200d-2642-fe0f","🤦🏻‍♀️":"1f926-1f3fb-200d-2640-fe0f","🤦🏼‍♀️":"1f926-1f3fc-200d-2640-fe0f","🤦🏽‍♀️":"1f926-1f3fd-200d-2640-fe0f","🤦🏾‍♀️":"1f926-1f3fe-200d-2640-fe0f","🤦🏿‍♀️":"1f926-1f3ff-200d-2640-fe0f","🤷🏻‍♂️":"1f937-1f3fb-200d-2642-fe0f","🤷🏼‍♂️":"1f937-1f3fc-200d-2642-fe0f","🤷🏽‍♂️":"1f937-1f3fd-200d-2642-fe0f","🤷🏾‍♂️":"1f937-1f3fe-200d-2642-fe0f","🤷🏿‍♂️":"1f937-1f3ff-200d-2642-fe0f","🤷🏻‍♀️":"1f937-1f3fb-200d-2640-fe0f","🤷🏼‍♀️":"1f937-1f3fc-200d-2640-fe0f","🤷🏽‍♀️":"1f937-1f3fd-200d-2640-fe0f","🤷🏾‍♀️":"1f937-1f3fe-200d-2640-fe0f","🤷🏿‍♀️":"1f937-1f3ff-200d-2640-fe0f","🧑🏻‍⚕️":"1f9d1-1f3fb-200d-2695-fe0f","🧑🏼‍⚕️":"1f9d1-1f3fc-200d-2695-fe0f","🧑🏽‍⚕️":"1f9d1-1f3fd-200d-2695-fe0f","🧑🏾‍⚕️":"1f9d1-1f3fe-200d-2695-fe0f","🧑🏿‍⚕️":"1f9d1-1f3ff-200d-2695-fe0f","👨🏻‍⚕️":"1f468-1f3fb-200d-2695-fe0f","👨🏼‍⚕️":"1f468-1f3fc-200d-2695-fe0f","👨🏽‍⚕️":"1f468-1f3fd-200d-2695-fe0f","👨🏾‍⚕️":"1f468-1f3fe-200d-2695-fe0f","👨🏿‍⚕️":"1f468-1f3ff-200d-2695-fe0f","👩🏻‍⚕️":"1f469-1f3fb-200d-2695-fe0f","👩🏼‍⚕️":"1f469-1f3fc-200d-2695-fe0f","👩🏽‍⚕️":"1f469-1f3fd-200d-2695-fe0f","👩🏾‍⚕️":"1f469-1f3fe-200d-2695-fe0f","👩🏿‍⚕️":"1f469-1f3ff-200d-2695-fe0f","🧑🏻‍⚖️":"1f9d1-1f3fb-200d-2696-fe0f","🧑🏼‍⚖️":"1f9d1-1f3fc-200d-2696-fe0f","🧑🏽‍⚖️":"1f9d1-1f3fd-200d-2696-fe0f","🧑🏾‍⚖️":"1f9d1-1f3fe-200d-2696-fe0f","🧑🏿‍⚖️":"1f9d1-1f3ff-200d-2696-fe0f","👨🏻‍⚖️":"1f468-1f3fb-200d-2696-fe0f","👨🏼‍⚖️":"1f468-1f3fc-200d-2696-fe0f","👨🏽‍⚖️":"1f468-1f3fd-200d-2696-fe0f","👨🏾‍⚖️":"1f468-1f3fe-200d-2696-fe0f","👨🏿‍⚖️":"1f468-1f3ff-200d-2696-fe0f","👩🏻‍⚖️":"1f469-1f3fb-200d-2696-fe0f","👩🏼‍⚖️":"1f469-1f3fc-200d-2696-fe0f","👩🏽‍⚖️":"1f469-1f3fd-200d-2696-fe0f","👩🏾‍⚖️":"1f469-1f3fe-200d-2696-fe0f","👩🏿‍⚖️":"1f469-1f3ff-200d-2696-fe0f","🧑🏻‍✈️":"1f9d1-1f3fb-200d-2708-fe0f","🧑🏼‍✈️":"1f9d1-1f3fc-200d-2708-fe0f","🧑🏽‍✈️":"1f9d1-1f3fd-200d-2708-fe0f","🧑🏾‍✈️":"1f9d1-1f3fe-200d-2708-fe0f","🧑🏿‍✈️":"1f9d1-1f3ff-200d-2708-fe0f","👨🏻‍✈️":"1f468-1f3fb-200d-2708-fe0f","👨🏼‍✈️":"1f468-1f3fc-200d-2708-fe0f","👨🏽‍✈️":"1f468-1f3fd-200d-2708-fe0f","👨🏾‍✈️":"1f468-1f3fe-200d-2708-fe0f","👨🏿‍✈️":"1f468-1f3ff-200d-2708-fe0f","👩🏻‍✈️":"1f469-1f3fb-200d-2708-fe0f","👩🏼‍✈️":"1f469-1f3fc-200d-2708-fe0f","👩🏽‍✈️":"1f469-1f3fd-200d-2708-fe0f","👩🏾‍✈️":"1f469-1f3fe-200d-2708-fe0f","👩🏿‍✈️":"1f469-1f3ff-200d-2708-fe0f","👮🏻‍♂️":"1f46e-1f3fb-200d-2642-fe0f","👮🏼‍♂️":"1f46e-1f3fc-200d-2642-fe0f","👮🏽‍♂️":"1f46e-1f3fd-200d-2642-fe0f","👮🏾‍♂️":"1f46e-1f3fe-200d-2642-fe0f","👮🏿‍♂️":"1f46e-1f3ff-200d-2642-fe0f","👮🏻‍♀️":"1f46e-1f3fb-200d-2640-fe0f","👮🏼‍♀️":"1f46e-1f3fc-200d-2640-fe0f","👮🏽‍♀️":"1f46e-1f3fd-200d-2640-fe0f","👮🏾‍♀️":"1f46e-1f3fe-200d-2640-fe0f","👮🏿‍♀️":"1f46e-1f3ff-200d-2640-fe0f","🕵️‍♂️":"1f575-fe0f-200d-2642-fe0f","🕵🏻‍♂️":"1f575-1f3fb-200d-2642-fe0f","🕵🏼‍♂️":"1f575-1f3fc-200d-2642-fe0f","🕵🏽‍♂️":"1f575-1f3fd-200d-2642-fe0f","🕵🏾‍♂️":"1f575-1f3fe-200d-2642-fe0f","🕵🏿‍♂️":"1f575-1f3ff-200d-2642-fe0f","🕵️‍♀️":"1f575-fe0f-200d-2640-fe0f","🕵🏻‍♀️":"1f575-1f3fb-200d-2640-fe0f","🕵🏼‍♀️":"1f575-1f3fc-200d-2640-fe0f","🕵🏽‍♀️":"1f575-1f3fd-200d-2640-fe0f","🕵🏾‍♀️":"1f575-1f3fe-200d-2640-fe0f","🕵🏿‍♀️":"1f575-1f3ff-200d-2640-fe0f","💂🏻‍♂️":"1f482-1f3fb-200d-2642-fe0f","💂🏼‍♂️":"1f482-1f3fc-200d-2642-fe0f","💂🏽‍♂️":"1f482-1f3fd-200d-2642-fe0f","💂🏾‍♂️":"1f482-1f3fe-200d-2642-fe0f","💂🏿‍♂️":"1f482-1f3ff-200d-2642-fe0f","💂🏻‍♀️":"1f482-1f3fb-200d-2640-fe0f","💂🏼‍♀️":"1f482-1f3fc-200d-2640-fe0f","💂🏽‍♀️":"1f482-1f3fd-200d-2640-fe0f","💂🏾‍♀️":"1f482-1f3fe-200d-2640-fe0f","💂🏿‍♀️":"1f482-1f3ff-200d-2640-fe0f","👷🏻‍♂️":"1f477-1f3fb-200d-2642-fe0f","👷🏼‍♂️":"1f477-1f3fc-200d-2642-fe0f","👷🏽‍♂️":"1f477-1f3fd-200d-2642-fe0f","👷🏾‍♂️":"1f477-1f3fe-200d-2642-fe0f","👷🏿‍♂️":"1f477-1f3ff-200d-2642-fe0f","👷🏻‍♀️":"1f477-1f3fb-200d-2640-fe0f","👷🏼‍♀️":"1f477-1f3fc-200d-2640-fe0f","👷🏽‍♀️":"1f477-1f3fd-200d-2640-fe0f","👷🏾‍♀️":"1f477-1f3fe-200d-2640-fe0f","👷🏿‍♀️":"1f477-1f3ff-200d-2640-fe0f","👳🏻‍♂️":"1f473-1f3fb-200d-2642-fe0f","👳🏼‍♂️":"1f473-1f3fc-200d-2642-fe0f","👳🏽‍♂️":"1f473-1f3fd-200d-2642-fe0f","👳🏾‍♂️":"1f473-1f3fe-200d-2642-fe0f","👳🏿‍♂️":"1f473-1f3ff-200d-2642-fe0f","👳🏻‍♀️":"1f473-1f3fb-200d-2640-fe0f","👳🏼‍♀️":"1f473-1f3fc-200d-2640-fe0f","👳🏽‍♀️":"1f473-1f3fd-200d-2640-fe0f","👳🏾‍♀️":"1f473-1f3fe-200d-2640-fe0f","👳🏿‍♀️":"1f473-1f3ff-200d-2640-fe0f","🤵🏻‍♂️":"1f935-1f3fb-200d-2642-fe0f","🤵🏼‍♂️":"1f935-1f3fc-200d-2642-fe0f","🤵🏽‍♂️":"1f935-1f3fd-200d-2642-fe0f","🤵🏾‍♂️":"1f935-1f3fe-200d-2642-fe0f","🤵🏿‍♂️":"1f935-1f3ff-200d-2642-fe0f","🤵🏻‍♀️":"1f935-1f3fb-200d-2640-fe0f","🤵🏼‍♀️":"1f935-1f3fc-200d-2640-fe0f","🤵🏽‍♀️":"1f935-1f3fd-200d-2640-fe0f","🤵🏾‍♀️":"1f935-1f3fe-200d-2640-fe0f","🤵🏿‍♀️":"1f935-1f3ff-200d-2640-fe0f","👰🏻‍♂️":"1f470-1f3fb-200d-2642-fe0f","👰🏼‍♂️":"1f470-1f3fc-200d-2642-fe0f","👰🏽‍♂️":"1f470-1f3fd-200d-2642-fe0f","👰🏾‍♂️":"1f470-1f3fe-200d-2642-fe0f","👰🏿‍♂️":"1f470-1f3ff-200d-2642-fe0f","👰🏻‍♀️":"1f470-1f3fb-200d-2640-fe0f","👰🏼‍♀️":"1f470-1f3fc-200d-2640-fe0f","👰🏽‍♀️":"1f470-1f3fd-200d-2640-fe0f","👰🏾‍♀️":"1f470-1f3fe-200d-2640-fe0f","👰🏿‍♀️":"1f470-1f3ff-200d-2640-fe0f","🦸🏻‍♂️":"1f9b8-1f3fb-200d-2642-fe0f","🦸🏼‍♂️":"1f9b8-1f3fc-200d-2642-fe0f","🦸🏽‍♂️":"1f9b8-1f3fd-200d-2642-fe0f","🦸🏾‍♂️":"1f9b8-1f3fe-200d-2642-fe0f","🦸🏿‍♂️":"1f9b8-1f3ff-200d-2642-fe0f","🦸🏻‍♀️":"1f9b8-1f3fb-200d-2640-fe0f","🦸🏼‍♀️":"1f9b8-1f3fc-200d-2640-fe0f","🦸🏽‍♀️":"1f9b8-1f3fd-200d-2640-fe0f","🦸🏾‍♀️":"1f9b8-1f3fe-200d-2640-fe0f","🦸🏿‍♀️":"1f9b8-1f3ff-200d-2640-fe0f","🦹🏻‍♂️":"1f9b9-1f3fb-200d-2642-fe0f","🦹🏼‍♂️":"1f9b9-1f3fc-200d-2642-fe0f","🦹🏽‍♂️":"1f9b9-1f3fd-200d-2642-fe0f","🦹🏾‍♂️":"1f9b9-1f3fe-200d-2642-fe0f","🦹🏿‍♂️":"1f9b9-1f3ff-200d-2642-fe0f","🦹🏻‍♀️":"1f9b9-1f3fb-200d-2640-fe0f","🦹🏼‍♀️":"1f9b9-1f3fc-200d-2640-fe0f","🦹🏽‍♀️":"1f9b9-1f3fd-200d-2640-fe0f","🦹🏾‍♀️":"1f9b9-1f3fe-200d-2640-fe0f","🦹🏿‍♀️":"1f9b9-1f3ff-200d-2640-fe0f","🧙🏻‍♂️":"1f9d9-1f3fb-200d-2642-fe0f","🧙🏼‍♂️":"1f9d9-1f3fc-200d-2642-fe0f","🧙🏽‍♂️":"1f9d9-1f3fd-200d-2642-fe0f","🧙🏾‍♂️":"1f9d9-1f3fe-200d-2642-fe0f","🧙🏿‍♂️":"1f9d9-1f3ff-200d-2642-fe0f","🧙🏻‍♀️":"1f9d9-1f3fb-200d-2640-fe0f","🧙🏼‍♀️":"1f9d9-1f3fc-200d-2640-fe0f","🧙🏽‍♀️":"1f9d9-1f3fd-200d-2640-fe0f","🧙🏾‍♀️":"1f9d9-1f3fe-200d-2640-fe0f","🧙🏿‍♀️":"1f9d9-1f3ff-200d-2640-fe0f","🧚🏻‍♂️":"1f9da-1f3fb-200d-2642-fe0f","🧚🏼‍♂️":"1f9da-1f3fc-200d-2642-fe0f","🧚🏽‍♂️":"1f9da-1f3fd-200d-2642-fe0f","🧚🏾‍♂️":"1f9da-1f3fe-200d-2642-fe0f","🧚🏿‍♂️":"1f9da-1f3ff-200d-2642-fe0f","🧚🏻‍♀️":"1f9da-1f3fb-200d-2640-fe0f","🧚🏼‍♀️":"1f9da-1f3fc-200d-2640-fe0f","🧚🏽‍♀️":"1f9da-1f3fd-200d-2640-fe0f","🧚🏾‍♀️":"1f9da-1f3fe-200d-2640-fe0f","🧚🏿‍♀️":"1f9da-1f3ff-200d-2640-fe0f","🧛🏻‍♂️":"1f9db-1f3fb-200d-2642-fe0f","🧛🏼‍♂️":"1f9db-1f3fc-200d-2642-fe0f","🧛🏽‍♂️":"1f9db-1f3fd-200d-2642-fe0f","🧛🏾‍♂️":"1f9db-1f3fe-200d-2642-fe0f","🧛🏿‍♂️":"1f9db-1f3ff-200d-2642-fe0f","🧛🏻‍♀️":"1f9db-1f3fb-200d-2640-fe0f","🧛🏼‍♀️":"1f9db-1f3fc-200d-2640-fe0f","🧛🏽‍♀️":"1f9db-1f3fd-200d-2640-fe0f","🧛🏾‍♀️":"1f9db-1f3fe-200d-2640-fe0f","🧛🏿‍♀️":"1f9db-1f3ff-200d-2640-fe0f","🧜🏻‍♂️":"1f9dc-1f3fb-200d-2642-fe0f","🧜🏼‍♂️":"1f9dc-1f3fc-200d-2642-fe0f","🧜🏽‍♂️":"1f9dc-1f3fd-200d-2642-fe0f","🧜🏾‍♂️":"1f9dc-1f3fe-200d-2642-fe0f","🧜🏿‍♂️":"1f9dc-1f3ff-200d-2642-fe0f","🧜🏻‍♀️":"1f9dc-1f3fb-200d-2640-fe0f","🧜🏼‍♀️":"1f9dc-1f3fc-200d-2640-fe0f","🧜🏽‍♀️":"1f9dc-1f3fd-200d-2640-fe0f","🧜🏾‍♀️":"1f9dc-1f3fe-200d-2640-fe0f","🧜🏿‍♀️":"1f9dc-1f3ff-200d-2640-fe0f","🧝🏻‍♂️":"1f9dd-1f3fb-200d-2642-fe0f","🧝🏼‍♂️":"1f9dd-1f3fc-200d-2642-fe0f","🧝🏽‍♂️":"1f9dd-1f3fd-200d-2642-fe0f","🧝🏾‍♂️":"1f9dd-1f3fe-200d-2642-fe0f","🧝🏿‍♂️":"1f9dd-1f3ff-200d-2642-fe0f","🧝🏻‍♀️":"1f9dd-1f3fb-200d-2640-fe0f","🧝🏼‍♀️":"1f9dd-1f3fc-200d-2640-fe0f","🧝🏽‍♀️":"1f9dd-1f3fd-200d-2640-fe0f","🧝🏾‍♀️":"1f9dd-1f3fe-200d-2640-fe0f","🧝🏿‍♀️":"1f9dd-1f3ff-200d-2640-fe0f","💆🏻‍♂️":"1f486-1f3fb-200d-2642-fe0f","💆🏼‍♂️":"1f486-1f3fc-200d-2642-fe0f","💆🏽‍♂️":"1f486-1f3fd-200d-2642-fe0f","💆🏾‍♂️":"1f486-1f3fe-200d-2642-fe0f","💆🏿‍♂️":"1f486-1f3ff-200d-2642-fe0f","💆🏻‍♀️":"1f486-1f3fb-200d-2640-fe0f","💆🏼‍♀️":"1f486-1f3fc-200d-2640-fe0f","💆🏽‍♀️":"1f486-1f3fd-200d-2640-fe0f","💆🏾‍♀️":"1f486-1f3fe-200d-2640-fe0f","💆🏿‍♀️":"1f486-1f3ff-200d-2640-fe0f","💇🏻‍♂️":"1f487-1f3fb-200d-2642-fe0f","💇🏼‍♂️":"1f487-1f3fc-200d-2642-fe0f","💇🏽‍♂️":"1f487-1f3fd-200d-2642-fe0f","💇🏾‍♂️":"1f487-1f3fe-200d-2642-fe0f","💇🏿‍♂️":"1f487-1f3ff-200d-2642-fe0f","💇🏻‍♀️":"1f487-1f3fb-200d-2640-fe0f","💇🏼‍♀️":"1f487-1f3fc-200d-2640-fe0f","💇🏽‍♀️":"1f487-1f3fd-200d-2640-fe0f","💇🏾‍♀️":"1f487-1f3fe-200d-2640-fe0f","💇🏿‍♀️":"1f487-1f3ff-200d-2640-fe0f","🚶🏻‍♂️":"1f6b6-1f3fb-200d-2642-fe0f","🚶🏼‍♂️":"1f6b6-1f3fc-200d-2642-fe0f","🚶🏽‍♂️":"1f6b6-1f3fd-200d-2642-fe0f","🚶🏾‍♂️":"1f6b6-1f3fe-200d-2642-fe0f","🚶🏿‍♂️":"1f6b6-1f3ff-200d-2642-fe0f","🚶🏻‍♀️":"1f6b6-1f3fb-200d-2640-fe0f","🚶🏼‍♀️":"1f6b6-1f3fc-200d-2640-fe0f","🚶🏽‍♀️":"1f6b6-1f3fd-200d-2640-fe0f","🚶🏾‍♀️":"1f6b6-1f3fe-200d-2640-fe0f","🚶🏿‍♀️":"1f6b6-1f3ff-200d-2640-fe0f","🧍🏻‍♂️":"1f9cd-1f3fb-200d-2642-fe0f","🧍🏼‍♂️":"1f9cd-1f3fc-200d-2642-fe0f","🧍🏽‍♂️":"1f9cd-1f3fd-200d-2642-fe0f","🧍🏾‍♂️":"1f9cd-1f3fe-200d-2642-fe0f","🧍🏿‍♂️":"1f9cd-1f3ff-200d-2642-fe0f","🧍🏻‍♀️":"1f9cd-1f3fb-200d-2640-fe0f","🧍🏼‍♀️":"1f9cd-1f3fc-200d-2640-fe0f","🧍🏽‍♀️":"1f9cd-1f3fd-200d-2640-fe0f","🧍🏾‍♀️":"1f9cd-1f3fe-200d-2640-fe0f","🧍🏿‍♀️":"1f9cd-1f3ff-200d-2640-fe0f","🧎🏻‍♂️":"1f9ce-1f3fb-200d-2642-fe0f","🧎🏼‍♂️":"1f9ce-1f3fc-200d-2642-fe0f","🧎🏽‍♂️":"1f9ce-1f3fd-200d-2642-fe0f","🧎🏾‍♂️":"1f9ce-1f3fe-200d-2642-fe0f","🧎🏿‍♂️":"1f9ce-1f3ff-200d-2642-fe0f","🧎🏻‍♀️":"1f9ce-1f3fb-200d-2640-fe0f","🧎🏼‍♀️":"1f9ce-1f3fc-200d-2640-fe0f","🧎🏽‍♀️":"1f9ce-1f3fd-200d-2640-fe0f","🧎🏾‍♀️":"1f9ce-1f3fe-200d-2640-fe0f","🧎🏿‍♀️":"1f9ce-1f3ff-200d-2640-fe0f","🏃🏻‍♂️":"1f3c3-1f3fb-200d-2642-fe0f","🏃🏼‍♂️":"1f3c3-1f3fc-200d-2642-fe0f","🏃🏽‍♂️":"1f3c3-1f3fd-200d-2642-fe0f","🏃🏾‍♂️":"1f3c3-1f3fe-200d-2642-fe0f","🏃🏿‍♂️":"1f3c3-1f3ff-200d-2642-fe0f","🏃🏻‍♀️":"1f3c3-1f3fb-200d-2640-fe0f","🏃🏼‍♀️":"1f3c3-1f3fc-200d-2640-fe0f","🏃🏽‍♀️":"1f3c3-1f3fd-200d-2640-fe0f","🏃🏾‍♀️":"1f3c3-1f3fe-200d-2640-fe0f","🏃🏿‍♀️":"1f3c3-1f3ff-200d-2640-fe0f","🧖🏻‍♂️":"1f9d6-1f3fb-200d-2642-fe0f","🧖🏼‍♂️":"1f9d6-1f3fc-200d-2642-fe0f","🧖🏽‍♂️":"1f9d6-1f3fd-200d-2642-fe0f","🧖🏾‍♂️":"1f9d6-1f3fe-200d-2642-fe0f","🧖🏿‍♂️":"1f9d6-1f3ff-200d-2642-fe0f","🧖🏻‍♀️":"1f9d6-1f3fb-200d-2640-fe0f","🧖🏼‍♀️":"1f9d6-1f3fc-200d-2640-fe0f","🧖🏽‍♀️":"1f9d6-1f3fd-200d-2640-fe0f","🧖🏾‍♀️":"1f9d6-1f3fe-200d-2640-fe0f","🧖🏿‍♀️":"1f9d6-1f3ff-200d-2640-fe0f","🧗🏻‍♂️":"1f9d7-1f3fb-200d-2642-fe0f","🧗🏼‍♂️":"1f9d7-1f3fc-200d-2642-fe0f","🧗🏽‍♂️":"1f9d7-1f3fd-200d-2642-fe0f","🧗🏾‍♂️":"1f9d7-1f3fe-200d-2642-fe0f","🧗🏿‍♂️":"1f9d7-1f3ff-200d-2642-fe0f","🧗🏻‍♀️":"1f9d7-1f3fb-200d-2640-fe0f","🧗🏼‍♀️":"1f9d7-1f3fc-200d-2640-fe0f","🧗🏽‍♀️":"1f9d7-1f3fd-200d-2640-fe0f","🧗🏾‍♀️":"1f9d7-1f3fe-200d-2640-fe0f","🧗🏿‍♀️":"1f9d7-1f3ff-200d-2640-fe0f","🏌️‍♂️":"1f3cc-fe0f-200d-2642-fe0f","🏌🏻‍♂️":"1f3cc-1f3fb-200d-2642-fe0f","🏌🏼‍♂️":"1f3cc-1f3fc-200d-2642-fe0f","🏌🏽‍♂️":"1f3cc-1f3fd-200d-2642-fe0f","🏌🏾‍♂️":"1f3cc-1f3fe-200d-2642-fe0f","🏌🏿‍♂️":"1f3cc-1f3ff-200d-2642-fe0f","🏌️‍♀️":"1f3cc-fe0f-200d-2640-fe0f","🏌🏻‍♀️":"1f3cc-1f3fb-200d-2640-fe0f","🏌🏼‍♀️":"1f3cc-1f3fc-200d-2640-fe0f","🏌🏽‍♀️":"1f3cc-1f3fd-200d-2640-fe0f","🏌🏾‍♀️":"1f3cc-1f3fe-200d-2640-fe0f","🏌🏿‍♀️":"1f3cc-1f3ff-200d-2640-fe0f","🏄🏻‍♂️":"1f3c4-1f3fb-200d-2642-fe0f","🏄🏼‍♂️":"1f3c4-1f3fc-200d-2642-fe0f","🏄🏽‍♂️":"1f3c4-1f3fd-200d-2642-fe0f","🏄🏾‍♂️":"1f3c4-1f3fe-200d-2642-fe0f","🏄🏿‍♂️":"1f3c4-1f3ff-200d-2642-fe0f","🏄🏻‍♀️":"1f3c4-1f3fb-200d-2640-fe0f","🏄🏼‍♀️":"1f3c4-1f3fc-200d-2640-fe0f","🏄🏽‍♀️":"1f3c4-1f3fd-200d-2640-fe0f","🏄🏾‍♀️":"1f3c4-1f3fe-200d-2640-fe0f","🏄🏿‍♀️":"1f3c4-1f3ff-200d-2640-fe0f","🚣🏻‍♂️":"1f6a3-1f3fb-200d-2642-fe0f","🚣🏼‍♂️":"1f6a3-1f3fc-200d-2642-fe0f","🚣🏽‍♂️":"1f6a3-1f3fd-200d-2642-fe0f","🚣🏾‍♂️":"1f6a3-1f3fe-200d-2642-fe0f","🚣🏿‍♂️":"1f6a3-1f3ff-200d-2642-fe0f","🚣🏻‍♀️":"1f6a3-1f3fb-200d-2640-fe0f","🚣🏼‍♀️":"1f6a3-1f3fc-200d-2640-fe0f","🚣🏽‍♀️":"1f6a3-1f3fd-200d-2640-fe0f","🚣🏾‍♀️":"1f6a3-1f3fe-200d-2640-fe0f","🚣🏿‍♀️":"1f6a3-1f3ff-200d-2640-fe0f","🏊🏻‍♂️":"1f3ca-1f3fb-200d-2642-fe0f","🏊🏼‍♂️":"1f3ca-1f3fc-200d-2642-fe0f","🏊🏽‍♂️":"1f3ca-1f3fd-200d-2642-fe0f","🏊🏾‍♂️":"1f3ca-1f3fe-200d-2642-fe0f","🏊🏿‍♂️":"1f3ca-1f3ff-200d-2642-fe0f","🏊🏻‍♀️":"1f3ca-1f3fb-200d-2640-fe0f","🏊🏼‍♀️":"1f3ca-1f3fc-200d-2640-fe0f","🏊🏽‍♀️":"1f3ca-1f3fd-200d-2640-fe0f","🏊🏾‍♀️":"1f3ca-1f3fe-200d-2640-fe0f","🏊🏿‍♀️":"1f3ca-1f3ff-200d-2640-fe0f","⛹️‍♂️":"26f9-fe0f-200d-2642-fe0f","⛹🏻‍♂️":"26f9-1f3fb-200d-2642-fe0f","⛹🏼‍♂️":"26f9-1f3fc-200d-2642-fe0f","⛹🏽‍♂️":"26f9-1f3fd-200d-2642-fe0f","⛹🏾‍♂️":"26f9-1f3fe-200d-2642-fe0f","⛹🏿‍♂️":"26f9-1f3ff-200d-2642-fe0f","⛹️‍♀️":"26f9-fe0f-200d-2640-fe0f","⛹🏻‍♀️":"26f9-1f3fb-200d-2640-fe0f","⛹🏼‍♀️":"26f9-1f3fc-200d-2640-fe0f","⛹🏽‍♀️":"26f9-1f3fd-200d-2640-fe0f","⛹🏾‍♀️":"26f9-1f3fe-200d-2640-fe0f","⛹🏿‍♀️":"26f9-1f3ff-200d-2640-fe0f","🏋️‍♂️":"1f3cb-fe0f-200d-2642-fe0f","🏋🏻‍♂️":"1f3cb-1f3fb-200d-2642-fe0f","🏋🏼‍♂️":"1f3cb-1f3fc-200d-2642-fe0f","🏋🏽‍♂️":"1f3cb-1f3fd-200d-2642-fe0f","🏋🏾‍♂️":"1f3cb-1f3fe-200d-2642-fe0f","🏋🏿‍♂️":"1f3cb-1f3ff-200d-2642-fe0f","🏋️‍♀️":"1f3cb-fe0f-200d-2640-fe0f","🏋🏻‍♀️":"1f3cb-1f3fb-200d-2640-fe0f","🏋🏼‍♀️":"1f3cb-1f3fc-200d-2640-fe0f","🏋🏽‍♀️":"1f3cb-1f3fd-200d-2640-fe0f","🏋🏾‍♀️":"1f3cb-1f3fe-200d-2640-fe0f","🏋🏿‍♀️":"1f3cb-1f3ff-200d-2640-fe0f","🚴🏻‍♂️":"1f6b4-1f3fb-200d-2642-fe0f","🚴🏼‍♂️":"1f6b4-1f3fc-200d-2642-fe0f","🚴🏽‍♂️":"1f6b4-1f3fd-200d-2642-fe0f","🚴🏾‍♂️":"1f6b4-1f3fe-200d-2642-fe0f","🚴🏿‍♂️":"1f6b4-1f3ff-200d-2642-fe0f","🚴🏻‍♀️":"1f6b4-1f3fb-200d-2640-fe0f","🚴🏼‍♀️":"1f6b4-1f3fc-200d-2640-fe0f","🚴🏽‍♀️":"1f6b4-1f3fd-200d-2640-fe0f","🚴🏾‍♀️":"1f6b4-1f3fe-200d-2640-fe0f","🚴🏿‍♀️":"1f6b4-1f3ff-200d-2640-fe0f","🚵🏻‍♂️":"1f6b5-1f3fb-200d-2642-fe0f","🚵🏼‍♂️":"1f6b5-1f3fc-200d-2642-fe0f","🚵🏽‍♂️":"1f6b5-1f3fd-200d-2642-fe0f","🚵🏾‍♂️":"1f6b5-1f3fe-200d-2642-fe0f","🚵🏿‍♂️":"1f6b5-1f3ff-200d-2642-fe0f","🚵🏻‍♀️":"1f6b5-1f3fb-200d-2640-fe0f","🚵🏼‍♀️":"1f6b5-1f3fc-200d-2640-fe0f","🚵🏽‍♀️":"1f6b5-1f3fd-200d-2640-fe0f","🚵🏾‍♀️":"1f6b5-1f3fe-200d-2640-fe0f","🚵🏿‍♀️":"1f6b5-1f3ff-200d-2640-fe0f","🤸🏻‍♂️":"1f938-1f3fb-200d-2642-fe0f","🤸🏼‍♂️":"1f938-1f3fc-200d-2642-fe0f","🤸🏽‍♂️":"1f938-1f3fd-200d-2642-fe0f","🤸🏾‍♂️":"1f938-1f3fe-200d-2642-fe0f","🤸🏿‍♂️":"1f938-1f3ff-200d-2642-fe0f","🤸🏻‍♀️":"1f938-1f3fb-200d-2640-fe0f","🤸🏼‍♀️":"1f938-1f3fc-200d-2640-fe0f","🤸🏽‍♀️":"1f938-1f3fd-200d-2640-fe0f","🤸🏾‍♀️":"1f938-1f3fe-200d-2640-fe0f","🤸🏿‍♀️":"1f938-1f3ff-200d-2640-fe0f","🤽🏻‍♂️":"1f93d-1f3fb-200d-2642-fe0f","🤽🏼‍♂️":"1f93d-1f3fc-200d-2642-fe0f","🤽🏽‍♂️":"1f93d-1f3fd-200d-2642-fe0f","🤽🏾‍♂️":"1f93d-1f3fe-200d-2642-fe0f","🤽🏿‍♂️":"1f93d-1f3ff-200d-2642-fe0f","🤽🏻‍♀️":"1f93d-1f3fb-200d-2640-fe0f","🤽🏼‍♀️":"1f93d-1f3fc-200d-2640-fe0f","🤽🏽‍♀️":"1f93d-1f3fd-200d-2640-fe0f","🤽🏾‍♀️":"1f93d-1f3fe-200d-2640-fe0f","🤽🏿‍♀️":"1f93d-1f3ff-200d-2640-fe0f","🤾🏻‍♂️":"1f93e-1f3fb-200d-2642-fe0f","🤾🏼‍♂️":"1f93e-1f3fc-200d-2642-fe0f","🤾🏽‍♂️":"1f93e-1f3fd-200d-2642-fe0f","🤾🏾‍♂️":"1f93e-1f3fe-200d-2642-fe0f","🤾🏿‍♂️":"1f93e-1f3ff-200d-2642-fe0f","🤾🏻‍♀️":"1f93e-1f3fb-200d-2640-fe0f","🤾🏼‍♀️":"1f93e-1f3fc-200d-2640-fe0f","🤾🏽‍♀️":"1f93e-1f3fd-200d-2640-fe0f","🤾🏾‍♀️":"1f93e-1f3fe-200d-2640-fe0f","🤾🏿‍♀️":"1f93e-1f3ff-200d-2640-fe0f","🤹🏻‍♂️":"1f939-1f3fb-200d-2642-fe0f","🤹🏼‍♂️":"1f939-1f3fc-200d-2642-fe0f","🤹🏽‍♂️":"1f939-1f3fd-200d-2642-fe0f","🤹🏾‍♂️":"1f939-1f3fe-200d-2642-fe0f","🤹🏿‍♂️":"1f939-1f3ff-200d-2642-fe0f","🤹🏻‍♀️":"1f939-1f3fb-200d-2640-fe0f","🤹🏼‍♀️":"1f939-1f3fc-200d-2640-fe0f","🤹🏽‍♀️":"1f939-1f3fd-200d-2640-fe0f","🤹🏾‍♀️":"1f939-1f3fe-200d-2640-fe0f","🤹🏿‍♀️":"1f939-1f3ff-200d-2640-fe0f","🧘🏻‍♂️":"1f9d8-1f3fb-200d-2642-fe0f","🧘🏼‍♂️":"1f9d8-1f3fc-200d-2642-fe0f","🧘🏽‍♂️":"1f9d8-1f3fd-200d-2642-fe0f","🧘🏾‍♂️":"1f9d8-1f3fe-200d-2642-fe0f","🧘🏿‍♂️":"1f9d8-1f3ff-200d-2642-fe0f","🧘🏻‍♀️":"1f9d8-1f3fb-200d-2640-fe0f","🧘🏼‍♀️":"1f9d8-1f3fc-200d-2640-fe0f","🧘🏽‍♀️":"1f9d8-1f3fd-200d-2640-fe0f","🧘🏾‍♀️":"1f9d8-1f3fe-200d-2640-fe0f","🧘🏿‍♀️":"1f9d8-1f3ff-200d-2640-fe0f","🧑‍🤝‍🧑":"1f9d1-200d-1f91d-200d-1f9d1","👩‍❤‍👨":"1f469-200d-2764-fe0f-200d-1f468","👨‍❤‍👨":"1f468-200d-2764-fe0f-200d-1f468","👩‍❤‍👩":"1f469-200d-2764-fe0f-200d-1f469","👨‍👩‍👦":"1f468-200d-1f469-200d-1f466","👨‍👩‍👧":"1f468-200d-1f469-200d-1f467","👨‍👨‍👦":"1f468-200d-1f468-200d-1f466","👨‍👨‍👧":"1f468-200d-1f468-200d-1f467","👩‍👩‍👦":"1f469-200d-1f469-200d-1f466","👩‍👩‍👧":"1f469-200d-1f469-200d-1f467","👨‍👦‍👦":"1f468-200d-1f466-200d-1f466","👨‍👧‍👦":"1f468-200d-1f467-200d-1f466","👨‍👧‍👧":"1f468-200d-1f467-200d-1f467","👩‍👦‍👦":"1f469-200d-1f466-200d-1f466","👩‍👧‍👦":"1f469-200d-1f467-200d-1f466","👩‍👧‍👧":"1f469-200d-1f467-200d-1f467","🏳️‍⚧️":"1f3f3-fe0f-200d-26a7-fe0f","👩‍❤️‍👨":"1f469-200d-2764-fe0f-200d-1f468","👨‍❤️‍👨":"1f468-200d-2764-fe0f-200d-1f468","👩‍❤️‍👩":"1f469-200d-2764-fe0f-200d-1f469","🧑🏻‍🤝‍🧑🏻":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fb","🧑🏻‍🤝‍🧑🏼":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fc","🧑🏻‍🤝‍🧑🏽":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fd","🧑🏻‍🤝‍🧑🏾":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fe","🧑🏻‍🤝‍🧑🏿":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3ff","🧑🏼‍🤝‍🧑🏻":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fb","🧑🏼‍🤝‍🧑🏼":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fc","🧑🏼‍🤝‍🧑🏽":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fd","🧑🏼‍🤝‍🧑🏾":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fe","🧑🏼‍🤝‍🧑🏿":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3ff","🧑🏽‍🤝‍🧑🏻":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fb","🧑🏽‍🤝‍🧑🏼":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fc","🧑🏽‍🤝‍🧑🏽":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fd","🧑🏽‍🤝‍🧑🏾":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fe","🧑🏽‍🤝‍🧑🏿":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3ff","🧑🏾‍🤝‍🧑🏻":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fb","🧑🏾‍🤝‍🧑🏼":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fc","🧑🏾‍🤝‍🧑🏽":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fd","🧑🏾‍🤝‍🧑🏾":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fe","🧑🏾‍🤝‍🧑🏿":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3ff","🧑🏿‍🤝‍🧑🏻":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fb","🧑🏿‍🤝‍🧑🏼":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fc","🧑🏿‍🤝‍🧑🏽":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fd","🧑🏿‍🤝‍🧑🏾":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fe","🧑🏿‍🤝‍🧑🏿":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3ff","👩🏻‍🤝‍👩🏼":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fc","👩🏻‍🤝‍👩🏽":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fd","👩🏻‍🤝‍👩🏾":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fe","👩🏻‍🤝‍👩🏿":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3ff","👩🏼‍🤝‍👩🏻":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fb","👩🏼‍🤝‍👩🏽":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fd","👩🏼‍🤝‍👩🏾":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fe","👩🏼‍🤝‍👩🏿":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3ff","👩🏽‍🤝‍👩🏻":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fb","👩🏽‍🤝‍👩🏼":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fc","👩🏽‍🤝‍👩🏾":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fe","👩🏽‍🤝‍👩🏿":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3ff","👩🏾‍🤝‍👩🏻":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fb","👩🏾‍🤝‍👩🏼":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fc","👩🏾‍🤝‍👩🏽":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fd","👩🏾‍🤝‍👩🏿":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3ff","👩🏿‍🤝‍👩🏻":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fb","👩🏿‍🤝‍👩🏼":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fc","👩🏿‍🤝‍👩🏽":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fd","👩🏿‍🤝‍👩🏾":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fe","👩🏻‍🤝‍👨🏼":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fc","👩🏻‍🤝‍👨🏽":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fd","👩🏻‍🤝‍👨🏾":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fe","👩🏻‍🤝‍👨🏿":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3ff","👩🏼‍🤝‍👨🏻":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fb","👩🏼‍🤝‍👨🏽":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fd","👩🏼‍🤝‍👨🏾":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fe","👩🏼‍🤝‍👨🏿":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3ff","👩🏽‍🤝‍👨🏻":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fb","👩🏽‍🤝‍👨🏼":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fc","👩🏽‍🤝‍👨🏾":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fe","👩🏽‍🤝‍👨🏿":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3ff","👩🏾‍🤝‍👨🏻":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fb","👩🏾‍🤝‍👨🏼":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fc","👩🏾‍🤝‍👨🏽":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fd","👩🏾‍🤝‍👨🏿":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3ff","👩🏿‍🤝‍👨🏻":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fb","👩🏿‍🤝‍👨🏼":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fc","👩🏿‍🤝‍👨🏽":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fd","👩🏿‍🤝‍👨🏾":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fe","👨🏻‍🤝‍👨🏼":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fc","👨🏻‍🤝‍👨🏽":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fd","👨🏻‍🤝‍👨🏾":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fe","👨🏻‍🤝‍👨🏿":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3ff","👨🏼‍🤝‍👨🏻":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fb","👨🏼‍🤝‍👨🏽":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fd","👨🏼‍🤝‍👨🏾":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fe","👨🏼‍🤝‍👨🏿":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3ff","👨🏽‍🤝‍👨🏻":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fb","👨🏽‍🤝‍👨🏼":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fc","👨🏽‍🤝‍👨🏾":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fe","👨🏽‍🤝‍👨🏿":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3ff","👨🏾‍🤝‍👨🏻":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fb","👨🏾‍🤝‍👨🏼":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fc","👨🏾‍🤝‍👨🏽":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fd","👨🏾‍🤝‍👨🏿":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3ff","👨🏿‍🤝‍👨🏻":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fb","👨🏿‍🤝‍👨🏼":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fc","👨🏿‍🤝‍👨🏽":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fd","👨🏿‍🤝‍👨🏾":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fe","👩‍❤‍💋‍👨":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468","👨‍❤‍💋‍👨":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468","👩‍❤‍💋‍👩":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469","🧑🏻‍❤‍🧑🏼":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏻‍❤‍🧑🏽":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏻‍❤‍🧑🏾":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏻‍❤‍🧑🏿":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏼‍❤‍🧑🏻":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏼‍❤‍🧑🏽":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏼‍❤‍🧑🏾":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏼‍❤‍🧑🏿":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏽‍❤‍🧑🏻":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏽‍❤‍🧑🏼":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏽‍❤‍🧑🏾":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏽‍❤‍🧑🏿":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏾‍❤‍🧑🏻":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏾‍❤‍🧑🏼":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏾‍❤‍🧑🏽":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏾‍❤‍🧑🏿":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏿‍❤‍🧑🏻":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏿‍❤‍🧑🏼":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏿‍❤‍🧑🏽":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏿‍❤‍🧑🏾":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fe","👩🏻‍❤‍👨🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb","👩🏻‍❤‍👨🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc","👩🏻‍❤‍👨🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd","👩🏻‍❤‍👨🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe","👩🏻‍❤‍👨🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff","👩🏼‍❤‍👨🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb","👩🏼‍❤‍👨🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc","👩🏼‍❤‍👨🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd","👩🏼‍❤‍👨🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe","👩🏼‍❤‍👨🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff","👩🏽‍❤‍👨🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb","👩🏽‍❤‍👨🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc","👩🏽‍❤‍👨🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd","👩🏽‍❤‍👨🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe","👩🏽‍❤‍👨🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff","👩🏾‍❤‍👨🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb","👩🏾‍❤‍👨🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc","👩🏾‍❤‍👨🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd","👩🏾‍❤‍👨🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe","👩🏾‍❤‍👨🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff","👩🏿‍❤‍👨🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb","👩🏿‍❤‍👨🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc","👩🏿‍❤‍👨🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd","👩🏿‍❤‍👨🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe","👩🏿‍❤‍👨🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff","👨🏻‍❤‍👨🏻":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb","👨🏻‍❤‍👨🏼":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc","👨🏻‍❤‍👨🏽":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd","👨🏻‍❤‍👨🏾":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe","👨🏻‍❤‍👨🏿":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff","👨🏼‍❤‍👨🏻":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb","👨🏼‍❤‍👨🏼":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc","👨🏼‍❤‍👨🏽":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd","👨🏼‍❤‍👨🏾":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe","👨🏼‍❤‍👨🏿":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff","👨🏽‍❤‍👨🏻":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb","👨🏽‍❤‍👨🏼":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc","👨🏽‍❤‍👨🏽":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd","👨🏽‍❤‍👨🏾":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe","👨🏽‍❤‍👨🏿":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff","👨🏾‍❤‍👨🏻":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb","👨🏾‍❤‍👨🏼":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc","👨🏾‍❤‍👨🏽":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd","👨🏾‍❤‍👨🏾":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe","👨🏾‍❤‍👨🏿":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff","👨🏿‍❤‍👨🏻":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb","👨🏿‍❤‍👨🏼":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc","👨🏿‍❤‍👨🏽":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd","👨🏿‍❤‍👨🏾":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe","👨🏿‍❤‍👨🏿":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff","👩🏻‍❤‍👩🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fb","👩🏻‍❤‍👩🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fc","👩🏻‍❤‍👩🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fd","👩🏻‍❤‍👩🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fe","👩🏻‍❤‍👩🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3ff","👩🏼‍❤‍👩🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fb","👩🏼‍❤‍👩🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fc","👩🏼‍❤‍👩🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fd","👩🏼‍❤‍👩🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fe","👩🏼‍❤‍👩🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3ff","👩🏽‍❤‍👩🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fb","👩🏽‍❤‍👩🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fc","👩🏽‍❤‍👩🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fd","👩🏽‍❤‍👩🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fe","👩🏽‍❤‍👩🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3ff","👩🏾‍❤‍👩🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fb","👩🏾‍❤‍👩🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fc","👩🏾‍❤‍👩🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fd","👩🏾‍❤‍👩🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fe","👩🏾‍❤‍👩🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3ff","👩🏿‍❤‍👩🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fb","👩🏿‍❤‍👩🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fc","👩🏿‍❤‍👩🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fd","👩🏿‍❤‍👩🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fe","👩🏿‍❤‍👩🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3ff","👨‍👩‍👧‍👦":"1f468-200d-1f469-200d-1f467-200d-1f466","👨‍👩‍👦‍👦":"1f468-200d-1f469-200d-1f466-200d-1f466","👨‍👩‍👧‍👧":"1f468-200d-1f469-200d-1f467-200d-1f467","👨‍👨‍👧‍👦":"1f468-200d-1f468-200d-1f467-200d-1f466","👨‍👨‍👦‍👦":"1f468-200d-1f468-200d-1f466-200d-1f466","👨‍👨‍👧‍👧":"1f468-200d-1f468-200d-1f467-200d-1f467","👩‍👩‍👧‍👦":"1f469-200d-1f469-200d-1f467-200d-1f466","👩‍👩‍👦‍👦":"1f469-200d-1f469-200d-1f466-200d-1f466","👩‍👩‍👧‍👧":"1f469-200d-1f469-200d-1f467-200d-1f467","🏴󠁧󠁢󠁥󠁮󠁧󠁿":"1f3f4-e0067-e0062-e0065-e006e-e0067-e007f","🏴󠁧󠁢󠁳󠁣󠁴󠁿":"1f3f4-e0067-e0062-e0073-e0063-e0074-e007f","🏴󠁧󠁢󠁷󠁬󠁳󠁿":"1f3f4-e0067-e0062-e0077-e006c-e0073-e007f","👩‍❤️‍💋‍👨":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468","👨‍❤️‍💋‍👨":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468","👩‍❤️‍💋‍👩":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469","🧑🏻‍❤️‍🧑🏼":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏻‍❤️‍🧑🏽":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏻‍❤️‍🧑🏾":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏻‍❤️‍🧑🏿":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏼‍❤️‍🧑🏻":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏼‍❤️‍🧑🏽":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏼‍❤️‍🧑🏾":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏼‍❤️‍🧑🏿":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏽‍❤️‍🧑🏻":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏽‍❤️‍🧑🏼":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏽‍❤️‍🧑🏾":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏽‍❤️‍🧑🏿":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏾‍❤️‍🧑🏻":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏾‍❤️‍🧑🏼":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏾‍❤️‍🧑🏽":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏾‍❤️‍🧑🏿":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏿‍❤️‍🧑🏻":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏿‍❤️‍🧑🏼":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏿‍❤️‍🧑🏽":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏿‍❤️‍🧑🏾":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fe","👩🏻‍❤️‍👨🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb","👩🏻‍❤️‍👨🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc","👩🏻‍❤️‍👨🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd","👩🏻‍❤️‍👨🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe","👩🏻‍❤️‍👨🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff","👩🏼‍❤️‍👨🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb","👩🏼‍❤️‍👨🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc","👩🏼‍❤️‍👨🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd","👩🏼‍❤️‍👨🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe","👩🏼‍❤️‍👨🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff","👩🏽‍❤️‍👨🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb","👩🏽‍❤️‍👨🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc","👩🏽‍❤️‍👨🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd","👩🏽‍❤️‍👨🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe","👩🏽‍❤️‍👨🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff","👩🏾‍❤️‍👨🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb","👩🏾‍❤️‍👨🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc","👩🏾‍❤️‍👨🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd","👩🏾‍❤️‍👨🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe","👩🏾‍❤️‍👨🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff","👩🏿‍❤️‍👨🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb","👩🏿‍❤️‍👨🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc","👩🏿‍❤️‍👨🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd","👩🏿‍❤️‍👨🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe","👩🏿‍❤️‍👨🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff","👨🏻‍❤️‍👨🏻":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb","👨🏻‍❤️‍👨🏼":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc","👨🏻‍❤️‍👨🏽":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd","👨🏻‍❤️‍👨🏾":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe","👨🏻‍❤️‍👨🏿":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff","👨🏼‍❤️‍👨🏻":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb","👨🏼‍❤️‍👨🏼":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc","👨🏼‍❤️‍👨🏽":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd","👨🏼‍❤️‍👨🏾":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe","👨🏼‍❤️‍👨🏿":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff","👨🏽‍❤️‍👨🏻":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb","👨🏽‍❤️‍👨🏼":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc","👨🏽‍❤️‍👨🏽":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd","👨🏽‍❤️‍👨🏾":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe","👨🏽‍❤️‍👨🏿":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff","👨🏾‍❤️‍👨🏻":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb","👨🏾‍❤️‍👨🏼":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc","👨🏾‍❤️‍👨🏽":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd","👨🏾‍❤️‍👨🏾":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe","👨🏾‍❤️‍👨🏿":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff","👨🏿‍❤️‍👨🏻":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb","👨🏿‍❤️‍👨🏼":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc","👨🏿‍❤️‍👨🏽":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd","👨🏿‍❤️‍👨🏾":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe","👨🏿‍❤️‍👨🏿":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff","👩🏻‍❤️‍👩🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fb","👩🏻‍❤️‍👩🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fc","👩🏻‍❤️‍👩🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fd","👩🏻‍❤️‍👩🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fe","👩🏻‍❤️‍👩🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3ff","👩🏼‍❤️‍👩🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fb","👩🏼‍❤️‍👩🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fc","👩🏼‍❤️‍👩🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fd","👩🏼‍❤️‍👩🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fe","👩🏼‍❤️‍👩🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3ff","👩🏽‍❤️‍👩🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fb","👩🏽‍❤️‍👩🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fc","👩🏽‍❤️‍👩🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fd","👩🏽‍❤️‍👩🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fe","👩🏽‍❤️‍👩🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3ff","👩🏾‍❤️‍👩🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fb","👩🏾‍❤️‍👩🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fc","👩🏾‍❤️‍👩🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fd","👩🏾‍❤️‍👩🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fe","👩🏾‍❤️‍👩🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3ff","👩🏿‍❤️‍👩🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fb","👩🏿‍❤️‍👩🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fc","👩🏿‍❤️‍👩🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fd","👩🏿‍❤️‍👩🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fe","👩🏿‍❤️‍👩🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3ff","🧑🏻‍❤‍💋‍🧑🏼":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏻‍❤‍💋‍🧑🏽":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏻‍❤‍💋‍🧑🏾":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏻‍❤‍💋‍🧑🏿":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏼‍❤‍💋‍🧑🏻":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏼‍❤‍💋‍🧑🏽":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏼‍❤‍💋‍🧑🏾":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏼‍❤‍💋‍🧑🏿":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏽‍❤‍💋‍🧑🏻":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏽‍❤‍💋‍🧑🏼":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏽‍❤‍💋‍🧑🏾":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏽‍❤‍💋‍🧑🏿":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏾‍❤‍💋‍🧑🏻":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏾‍❤‍💋‍🧑🏼":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏾‍❤‍💋‍🧑🏽":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏾‍❤‍💋‍🧑🏿":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏿‍❤‍💋‍🧑🏻":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏿‍❤‍💋‍🧑🏼":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏿‍❤‍💋‍🧑🏽":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏿‍❤‍💋‍🧑🏾":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","👩🏻‍❤‍💋‍👨🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏻‍❤‍💋‍👨🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏻‍❤‍💋‍👨🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏻‍❤‍💋‍👨🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏻‍❤‍💋‍👨🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏼‍❤‍💋‍👨🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏼‍❤‍💋‍👨🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏼‍❤‍💋‍👨🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏼‍❤‍💋‍👨🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏼‍❤‍💋‍👨🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏽‍❤‍💋‍👨🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏽‍❤‍💋‍👨🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏽‍❤‍💋‍👨🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏽‍❤‍💋‍👨🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏽‍❤‍💋‍👨🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏾‍❤‍💋‍👨🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏾‍❤‍💋‍👨🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏾‍❤‍💋‍👨🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏾‍❤‍💋‍👨🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏾‍❤‍💋‍👨🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏿‍❤‍💋‍👨🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏿‍❤‍💋‍👨🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏿‍❤‍💋‍👨🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏿‍❤‍💋‍👨🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏿‍❤‍💋‍👨🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏻‍❤‍💋‍👨🏻":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏻‍❤‍💋‍👨🏼":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏻‍❤‍💋‍👨🏽":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏻‍❤‍💋‍👨🏾":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏻‍❤‍💋‍👨🏿":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏼‍❤‍💋‍👨🏻":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏼‍❤‍💋‍👨🏼":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏼‍❤‍💋‍👨🏽":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏼‍❤‍💋‍👨🏾":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏼‍❤‍💋‍👨🏿":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏽‍❤‍💋‍👨🏻":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏽‍❤‍💋‍👨🏼":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏽‍❤‍💋‍👨🏽":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏽‍❤‍💋‍👨🏾":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏽‍❤‍💋‍👨🏿":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏾‍❤‍💋‍👨🏻":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏾‍❤‍💋‍👨🏼":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏾‍❤‍💋‍👨🏽":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏾‍❤‍💋‍👨🏾":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏾‍❤‍💋‍👨🏿":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏿‍❤‍💋‍👨🏻":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏿‍❤‍💋‍👨🏼":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏿‍❤‍💋‍👨🏽":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏿‍❤‍💋‍👨🏾":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏿‍❤‍💋‍👨🏿":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏻‍❤‍💋‍👩🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏻‍❤‍💋‍👩🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏻‍❤‍💋‍👩🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏻‍❤‍💋‍👩🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏻‍❤‍💋‍👩🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏼‍❤‍💋‍👩🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏼‍❤‍💋‍👩🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏼‍❤‍💋‍👩🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏼‍❤‍💋‍👩🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏼‍❤‍💋‍👩🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏽‍❤‍💋‍👩🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏽‍❤‍💋‍👩🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏽‍❤‍💋‍👩🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏽‍❤‍💋‍👩🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏽‍❤‍💋‍👩🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏾‍❤‍💋‍👩🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏾‍❤‍💋‍👩🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏾‍❤‍💋‍👩🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏾‍❤‍💋‍👩🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏾‍❤‍💋‍👩🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏿‍❤‍💋‍👩🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏿‍❤‍💋‍👩🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏿‍❤‍💋‍👩🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏿‍❤‍💋‍👩🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏿‍❤‍💋‍👩🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","🧑🏻‍❤️‍💋‍🧑🏼":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏻‍❤️‍💋‍🧑🏽":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏻‍❤️‍💋‍🧑🏾":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏻‍❤️‍💋‍🧑🏿":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏼‍❤️‍💋‍🧑🏻":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏼‍❤️‍💋‍🧑🏽":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏼‍❤️‍💋‍🧑🏾":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏼‍❤️‍💋‍🧑🏿":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏽‍❤️‍💋‍🧑🏻":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏽‍❤️‍💋‍🧑🏼":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏽‍❤️‍💋‍🧑🏾":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏽‍❤️‍💋‍🧑🏿":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏾‍❤️‍💋‍🧑🏻":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏾‍❤️‍💋‍🧑🏼":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏾‍❤️‍💋‍🧑🏽":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏾‍❤️‍💋‍🧑🏿":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏿‍❤️‍💋‍🧑🏻":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏿‍❤️‍💋‍🧑🏼":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏿‍❤️‍💋‍🧑🏽":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏿‍❤️‍💋‍🧑🏾":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","👩🏻‍❤️‍💋‍👨🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏻‍❤️‍💋‍👨🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏻‍❤️‍💋‍👨🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏻‍❤️‍💋‍👨🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏻‍❤️‍💋‍👨🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏼‍❤️‍💋‍👨🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏼‍❤️‍💋‍👨🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏼‍❤️‍💋‍👨🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏼‍❤️‍💋‍👨🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏼‍❤️‍💋‍👨🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏽‍❤️‍💋‍👨🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏽‍❤️‍💋‍👨🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏽‍❤️‍💋‍👨🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏽‍❤️‍💋‍👨🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏽‍❤️‍💋‍👨🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏾‍❤️‍💋‍👨🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏾‍❤️‍💋‍👨🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏾‍❤️‍💋‍👨🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏾‍❤️‍💋‍👨🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏾‍❤️‍💋‍👨🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏿‍❤️‍💋‍👨🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏿‍❤️‍💋‍👨🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏿‍❤️‍💋‍👨🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏿‍❤️‍💋‍👨🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏿‍❤️‍💋‍👨🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏻‍❤️‍💋‍👨🏻":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏻‍❤️‍💋‍👨🏼":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏻‍❤️‍💋‍👨🏽":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏻‍❤️‍💋‍👨🏾":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏻‍❤️‍💋‍👨🏿":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏼‍❤️‍💋‍👨🏻":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏼‍❤️‍💋‍👨🏼":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏼‍❤️‍💋‍👨🏽":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏼‍❤️‍💋‍👨🏾":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏼‍❤️‍💋‍👨🏿":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏽‍❤️‍💋‍👨🏻":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏽‍❤️‍💋‍👨🏼":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏽‍❤️‍💋‍👨🏽":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏽‍❤️‍💋‍👨🏾":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏽‍❤️‍💋‍👨🏿":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏾‍❤️‍💋‍👨🏻":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏾‍❤️‍💋‍👨🏼":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏾‍❤️‍💋‍👨🏽":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏾‍❤️‍💋‍👨🏾":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏾‍❤️‍💋‍👨🏿":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏿‍❤️‍💋‍👨🏻":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏿‍❤️‍💋‍👨🏼":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏿‍❤️‍💋‍👨🏽":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏿‍❤️‍💋‍👨🏾":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏿‍❤️‍💋‍👨🏿":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏻‍❤️‍💋‍👩🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏻‍❤️‍💋‍👩🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏻‍❤️‍💋‍👩🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏻‍❤️‍💋‍👩🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏻‍❤️‍💋‍👩🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏼‍❤️‍💋‍👩🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏼‍❤️‍💋‍👩🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏼‍❤️‍💋‍👩🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏼‍❤️‍💋‍👩🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏼‍❤️‍💋‍👩🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏽‍❤️‍💋‍👩🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏽‍❤️‍💋‍👩🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏽‍❤️‍💋‍👩🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏽‍❤️‍💋‍👩🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏽‍❤️‍💋‍👩🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏾‍❤️‍💋‍👩🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏾‍❤️‍💋‍👩🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏾‍❤️‍💋‍👩🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏾‍❤️‍💋‍👩🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏾‍❤️‍💋‍👩🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏿‍❤️‍💋‍👩🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏿‍❤️‍💋‍👩🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏿‍❤️‍💋‍👩🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏿‍❤️‍💋‍👩🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏿‍❤️‍💋‍👩🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff"} \ No newline at end of file +{"😀":"1f600","😃":"1f603","😄":"1f604","😁":"1f601","😆":"1f606","😅":"1f605","🤣":"1f923","😂":"1f602","🙂":"1f642","🙃":"1f643","🫠":"1fae0","😉":"1f609","😊":"1f60a","😇":"1f607","🥰":"1f970","😍":"1f60d","🤩":"1f929","😘":"1f618","😗":"1f617","☺":"263a","😚":"1f61a","😙":"1f619","🥲":"1f972","😋":"1f60b","😛":"1f61b","😜":"1f61c","🤪":"1f92a","😝":"1f61d","🤑":"1f911","🤗":"1f917","🤭":"1f92d","🫢":"1fae2","🫣":"1fae3","🤫":"1f92b","🤔":"1f914","🫡":"1fae1","🤐":"1f910","🤨":"1f928","😐":"1f610","😑":"1f611","😶":"1f636","🫥":"1fae5","😏":"1f60f","😒":"1f612","🙄":"1f644","😬":"1f62c","🤥":"1f925","🫨":"1fae8","😌":"1f60c","😔":"1f614","😪":"1f62a","🤤":"1f924","😴":"1f634","😷":"1f637","🤒":"1f912","🤕":"1f915","🤢":"1f922","🤮":"1f92e","🤧":"1f927","🥵":"1f975","🥶":"1f976","🥴":"1f974","😵":"1f635","🤯":"1f92f","🤠":"1f920","🥳":"1f973","🥸":"1f978","😎":"1f60e","🤓":"1f913","🧐":"1f9d0","😕":"1f615","🫤":"1fae4","😟":"1f61f","🙁":"1f641","☹":"2639","😮":"1f62e","😯":"1f62f","😲":"1f632","😳":"1f633","🥺":"1f97a","🥹":"1f979","😦":"1f626","😧":"1f627","😨":"1f628","😰":"1f630","😥":"1f625","😢":"1f622","😭":"1f62d","😱":"1f631","😖":"1f616","😣":"1f623","😞":"1f61e","😓":"1f613","😩":"1f629","😫":"1f62b","🥱":"1f971","😤":"1f624","😡":"1f621","😠":"1f620","🤬":"1f92c","😈":"1f608","👿":"1f47f","💀":"1f480","☠":"2620","💩":"1f4a9","🤡":"1f921","👹":"1f479","👺":"1f47a","👻":"1f47b","👽":"1f47d","👾":"1f47e","🤖":"1f916","😺":"1f63a","😸":"1f638","😹":"1f639","😻":"1f63b","😼":"1f63c","😽":"1f63d","🙀":"1f640","😿":"1f63f","😾":"1f63e","🙈":"1f648","🙉":"1f649","🙊":"1f64a","💌":"1f48c","💘":"1f498","💝":"1f49d","💖":"1f496","💗":"1f497","💓":"1f493","💞":"1f49e","💕":"1f495","💟":"1f49f","❣":"2763","💔":"1f494","❤":"2764","🩷":"1fa77","🧡":"1f9e1","💛":"1f49b","💚":"1f49a","💙":"1f499","🩵":"1fa75","💜":"1f49c","🤎":"1f90e","🖤":"1f5a4","🩶":"1fa76","🤍":"1f90d","💋":"1f48b","💯":"1f4af","💢":"1f4a2","💥":"1f4a5","💫":"1f4ab","💦":"1f4a6","💨":"1f4a8","🕳":"1f573","💬":"1f4ac","🗨":"1f5e8","🗯":"1f5ef","💭":"1f4ad","💤":"1f4a4","👋":"1f44b","🤚":"1f91a","🖐":"1f590","✋":"270b","🖖":"1f596","🫱":"1faf1","🫲":"1faf2","🫳":"1faf3","🫴":"1faf4","🫷":"1faf7","🫸":"1faf8","👌":"1f44c","🤌":"1f90c","🤏":"1f90f","✌":"270c","🤞":"1f91e","🫰":"1faf0","🤟":"1f91f","🤘":"1f918","🤙":"1f919","👈":"1f448","👉":"1f449","👆":"1f446","🖕":"1f595","👇":"1f447","☝":"261d","🫵":"1faf5","👍":"1f44d","👎":"1f44e","✊":"270a","👊":"1f44a","🤛":"1f91b","🤜":"1f91c","👏":"1f44f","🙌":"1f64c","🫶":"1faf6","👐":"1f450","🤲":"1f932","🤝":"1f91d","🙏":"1f64f","✍":"270d","💅":"1f485","🤳":"1f933","💪":"1f4aa","🦾":"1f9be","🦿":"1f9bf","🦵":"1f9b5","🦶":"1f9b6","👂":"1f442","🦻":"1f9bb","👃":"1f443","🧠":"1f9e0","🫀":"1fac0","🫁":"1fac1","🦷":"1f9b7","🦴":"1f9b4","👀":"1f440","👁":"1f441","👅":"1f445","👄":"1f444","🫦":"1fae6","👶":"1f476","🧒":"1f9d2","👦":"1f466","👧":"1f467","🧑":"1f9d1","👱":"1f471","👨":"1f468","🧔":"1f9d4","👩":"1f469","🧓":"1f9d3","👴":"1f474","👵":"1f475","🙍":"1f64d","🙎":"1f64e","🙅":"1f645","🙆":"1f646","💁":"1f481","🙋":"1f64b","🧏":"1f9cf","🙇":"1f647","🤦":"1f926","🤷":"1f937","👮":"1f46e","🕵":"1f575","💂":"1f482","🥷":"1f977","👷":"1f477","🫅":"1fac5","🤴":"1f934","👸":"1f478","👳":"1f473","👲":"1f472","🧕":"1f9d5","🤵":"1f935","👰":"1f470","🤰":"1f930","🫃":"1fac3","🫄":"1fac4","🤱":"1f931","👼":"1f47c","🎅":"1f385","🤶":"1f936","🦸":"1f9b8","🦹":"1f9b9","🧙":"1f9d9","🧚":"1f9da","🧛":"1f9db","🧜":"1f9dc","🧝":"1f9dd","🧞":"1f9de","🧟":"1f9df","🧌":"1f9cc","💆":"1f486","💇":"1f487","🚶":"1f6b6","🧍":"1f9cd","🧎":"1f9ce","🏃":"1f3c3","💃":"1f483","🕺":"1f57a","🕴":"1f574","👯":"1f46f","🧖":"1f9d6","🧗":"1f9d7","🤺":"1f93a","🏇":"1f3c7","⛷":"26f7","🏂":"1f3c2","🏌":"1f3cc","🏄":"1f3c4","🚣":"1f6a3","🏊":"1f3ca","⛹":"26f9","🏋":"1f3cb","🚴":"1f6b4","🚵":"1f6b5","🤸":"1f938","🤼":"1f93c","🤽":"1f93d","🤾":"1f93e","🤹":"1f939","🧘":"1f9d8","🛀":"1f6c0","🛌":"1f6cc","👭":"1f46d","👫":"1f46b","👬":"1f46c","💏":"1f48f","💑":"1f491","👪":"1f46a","🗣":"1f5e3","👤":"1f464","👥":"1f465","🫂":"1fac2","👣":"1f463","🏻":"1f463","🏼":"1f463","🏽":"1f463","🏾":"1f463","🏿":"1f463","🦰":"1f463","🦱":"1f463","🦳":"1f463","🦲":"1f463","🐵":"1f435","🐒":"1f412","🦍":"1f98d","🦧":"1f9a7","🐶":"1f436","🐕":"1f415","🦮":"1f9ae","🐩":"1f429","🐺":"1f43a","🦊":"1f98a","🦝":"1f99d","🐱":"1f431","🐈":"1f408","🦁":"1f981","🐯":"1f42f","🐅":"1f405","🐆":"1f406","🐴":"1f434","🫎":"1face","🫏":"1facf","🐎":"1f40e","🦄":"1f984","🦓":"1f993","🦌":"1f98c","🦬":"1f9ac","🐮":"1f42e","🐂":"1f402","🐃":"1f403","🐄":"1f404","🐷":"1f437","🐖":"1f416","🐗":"1f417","🐽":"1f43d","🐏":"1f40f","🐑":"1f411","🐐":"1f410","🐪":"1f42a","🐫":"1f42b","🦙":"1f999","🦒":"1f992","🐘":"1f418","🦣":"1f9a3","🦏":"1f98f","🦛":"1f99b","🐭":"1f42d","🐁":"1f401","🐀":"1f400","🐹":"1f439","🐰":"1f430","🐇":"1f407","🐿":"1f43f","🦫":"1f9ab","🦔":"1f994","🦇":"1f987","🐻":"1f43b","🐨":"1f428","🐼":"1f43c","🦥":"1f9a5","🦦":"1f9a6","🦨":"1f9a8","🦘":"1f998","🦡":"1f9a1","🐾":"1f43e","🦃":"1f983","🐔":"1f414","🐓":"1f413","🐣":"1f423","🐤":"1f424","🐥":"1f425","🐦":"1f426","🐧":"1f427","🕊":"1f54a","🦅":"1f985","🦆":"1f986","🦢":"1f9a2","🦉":"1f989","🦤":"1f9a4","🪶":"1fab6","🦩":"1f9a9","🦚":"1f99a","🦜":"1f99c","🪽":"1fabd","🪿":"1fabf","🐸":"1f438","🐊":"1f40a","🐢":"1f422","🦎":"1f98e","🐍":"1f40d","🐲":"1f432","🐉":"1f409","🦕":"1f995","🦖":"1f996","🐳":"1f433","🐋":"1f40b","🐬":"1f42c","🦭":"1f9ad","🐟":"1f41f","🐠":"1f420","🐡":"1f421","🦈":"1f988","🐙":"1f419","🐚":"1f41a","🪸":"1fab8","🪼":"1fabc","🐌":"1f40c","🦋":"1f98b","🐛":"1f41b","🐜":"1f41c","🐝":"1f41d","🪲":"1fab2","🐞":"1f41e","🦗":"1f997","🪳":"1fab3","🕷":"1f577","🕸":"1f578","🦂":"1f982","🦟":"1f99f","🪰":"1fab0","🪱":"1fab1","🦠":"1f9a0","💐":"1f490","🌸":"1f338","💮":"1f4ae","🪷":"1fab7","🏵":"1f3f5","🌹":"1f339","🥀":"1f940","🌺":"1f33a","🌻":"1f33b","🌼":"1f33c","🌷":"1f337","🪻":"1fabb","🌱":"1f331","🪴":"1fab4","🌲":"1f332","🌳":"1f333","🌴":"1f334","🌵":"1f335","🌾":"1f33e","🌿":"1f33f","☘":"2618","🍀":"1f340","🍁":"1f341","🍂":"1f342","🍃":"1f343","🪹":"1fab9","🪺":"1faba","🍄":"1f344","🍇":"1f347","🍈":"1f348","🍉":"1f349","🍊":"1f34a","🍋":"1f34b","🍌":"1f34c","🍍":"1f34d","🥭":"1f96d","🍎":"1f34e","🍏":"1f34f","🍐":"1f350","🍑":"1f351","🍒":"1f352","🍓":"1f353","🫐":"1fad0","🥝":"1f95d","🍅":"1f345","🫒":"1fad2","🥥":"1f965","🥑":"1f951","🍆":"1f346","🥔":"1f954","🥕":"1f955","🌽":"1f33d","🌶":"1f336","🫑":"1fad1","🥒":"1f952","🥬":"1f96c","🥦":"1f966","🧄":"1f9c4","🧅":"1f9c5","🥜":"1f95c","🫘":"1fad8","🌰":"1f330","🫚":"1fada","🫛":"1fadb","🍞":"1f35e","🥐":"1f950","🥖":"1f956","🫓":"1fad3","🥨":"1f968","🥯":"1f96f","🥞":"1f95e","🧇":"1f9c7","🧀":"1f9c0","🍖":"1f356","🍗":"1f357","🥩":"1f969","🥓":"1f953","🍔":"1f354","🍟":"1f35f","🍕":"1f355","🌭":"1f32d","🥪":"1f96a","🌮":"1f32e","🌯":"1f32f","🫔":"1fad4","🥙":"1f959","🧆":"1f9c6","🥚":"1f95a","🍳":"1f373","🥘":"1f958","🍲":"1f372","🫕":"1fad5","🥣":"1f963","🥗":"1f957","🍿":"1f37f","🧈":"1f9c8","🧂":"1f9c2","🥫":"1f96b","🍱":"1f371","🍘":"1f358","🍙":"1f359","🍚":"1f35a","🍛":"1f35b","🍜":"1f35c","🍝":"1f35d","🍠":"1f360","🍢":"1f362","🍣":"1f363","🍤":"1f364","🍥":"1f365","🥮":"1f96e","🍡":"1f361","🥟":"1f95f","🥠":"1f960","🥡":"1f961","🦀":"1f980","🦞":"1f99e","🦐":"1f990","🦑":"1f991","🦪":"1f9aa","🍦":"1f366","🍧":"1f367","🍨":"1f368","🍩":"1f369","🍪":"1f36a","🎂":"1f382","🍰":"1f370","🧁":"1f9c1","🥧":"1f967","🍫":"1f36b","🍬":"1f36c","🍭":"1f36d","🍮":"1f36e","🍯":"1f36f","🍼":"1f37c","🥛":"1f95b","☕":"2615","🫖":"1fad6","🍵":"1f375","🍶":"1f376","🍾":"1f37e","🍷":"1f377","🍸":"1f378","🍹":"1f379","🍺":"1f37a","🍻":"1f37b","🥂":"1f942","🥃":"1f943","🫗":"1fad7","🥤":"1f964","🧋":"1f9cb","🧃":"1f9c3","🧉":"1f9c9","🧊":"1f9ca","🥢":"1f962","🍽":"1f37d","🍴":"1f374","🥄":"1f944","🔪":"1f52a","🫙":"1fad9","🏺":"1f3fa","🌍":"1f30d","🌎":"1f30e","🌏":"1f30f","🌐":"1f310","🗺":"1f5fa","🗾":"1f5fe","🧭":"1f9ed","🏔":"1f3d4","⛰":"26f0","🌋":"1f30b","🗻":"1f5fb","🏕":"1f3d5","🏖":"1f3d6","🏜":"1f3dc","🏝":"1f3dd","🏞":"1f3de","🏟":"1f3df","🏛":"1f3db","🏗":"1f3d7","🧱":"1f9f1","🪨":"1faa8","🪵":"1fab5","🛖":"1f6d6","🏘":"1f3d8","🏚":"1f3da","🏠":"1f3e0","🏡":"1f3e1","🏢":"1f3e2","🏣":"1f3e3","🏤":"1f3e4","🏥":"1f3e5","🏦":"1f3e6","🏨":"1f3e8","🏩":"1f3e9","🏪":"1f3ea","🏫":"1f3eb","🏬":"1f3ec","🏭":"1f3ed","🏯":"1f3ef","🏰":"1f3f0","💒":"1f492","🗼":"1f5fc","🗽":"1f5fd","⛪":"26ea","🕌":"1f54c","🛕":"1f6d5","🕍":"1f54d","⛩":"26e9","🕋":"1f54b","⛲":"26f2","⛺":"26fa","🌁":"1f301","🌃":"1f303","🏙":"1f3d9","🌄":"1f304","🌅":"1f305","🌆":"1f306","🌇":"1f307","🌉":"1f309","♨":"2668","🎠":"1f3a0","🛝":"1f6dd","🎡":"1f3a1","🎢":"1f3a2","💈":"1f488","🎪":"1f3aa","🚂":"1f682","🚃":"1f683","🚄":"1f684","🚅":"1f685","🚆":"1f686","🚇":"1f687","🚈":"1f688","🚉":"1f689","🚊":"1f68a","🚝":"1f69d","🚞":"1f69e","🚋":"1f68b","🚌":"1f68c","🚍":"1f68d","🚎":"1f68e","🚐":"1f690","🚑":"1f691","🚒":"1f692","🚓":"1f693","🚔":"1f694","🚕":"1f695","🚖":"1f696","🚗":"1f697","🚘":"1f698","🚙":"1f699","🛻":"1f6fb","🚚":"1f69a","🚛":"1f69b","🚜":"1f69c","🏎":"1f3ce","🏍":"1f3cd","🛵":"1f6f5","🦽":"1f9bd","🦼":"1f9bc","🛺":"1f6fa","🚲":"1f6b2","🛴":"1f6f4","🛹":"1f6f9","🛼":"1f6fc","🚏":"1f68f","🛣":"1f6e3","🛤":"1f6e4","🛢":"1f6e2","⛽":"26fd","🛞":"1f6de","🚨":"1f6a8","🚥":"1f6a5","🚦":"1f6a6","🛑":"1f6d1","🚧":"1f6a7","⚓":"2693","🛟":"1f6df","⛵":"26f5","🛶":"1f6f6","🚤":"1f6a4","🛳":"1f6f3","⛴":"26f4","🛥":"1f6e5","🚢":"1f6a2","✈":"2708","🛩":"1f6e9","🛫":"1f6eb","🛬":"1f6ec","🪂":"1fa82","💺":"1f4ba","🚁":"1f681","🚟":"1f69f","🚠":"1f6a0","🚡":"1f6a1","🛰":"1f6f0","🚀":"1f680","🛸":"1f6f8","🛎":"1f6ce","🧳":"1f9f3","⌛":"231b","⏳":"23f3","⌚":"231a","⏰":"23f0","⏱":"23f1","⏲":"23f2","🕰":"1f570","🕛":"1f55b","🕧":"1f567","🕐":"1f550","🕜":"1f55c","🕑":"1f551","🕝":"1f55d","🕒":"1f552","🕞":"1f55e","🕓":"1f553","🕟":"1f55f","🕔":"1f554","🕠":"1f560","🕕":"1f555","🕡":"1f561","🕖":"1f556","🕢":"1f562","🕗":"1f557","🕣":"1f563","🕘":"1f558","🕤":"1f564","🕙":"1f559","🕥":"1f565","🕚":"1f55a","🕦":"1f566","🌑":"1f311","🌒":"1f312","🌓":"1f313","🌔":"1f314","🌕":"1f315","🌖":"1f316","🌗":"1f317","🌘":"1f318","🌙":"1f319","🌚":"1f31a","🌛":"1f31b","🌜":"1f31c","🌡":"1f321","☀":"2600","🌝":"1f31d","🌞":"1f31e","🪐":"1fa90","⭐":"2b50","🌟":"1f31f","🌠":"1f320","🌌":"1f30c","☁":"2601","⛅":"26c5","⛈":"26c8","🌤":"1f324","🌥":"1f325","🌦":"1f326","🌧":"1f327","🌨":"1f328","🌩":"1f329","🌪":"1f32a","🌫":"1f32b","🌬":"1f32c","🌀":"1f300","🌈":"1f308","🌂":"1f302","☂":"2602","☔":"2614","⛱":"26f1","⚡":"26a1","❄":"2744","☃":"2603","⛄":"26c4","☄":"2604","🔥":"1f525","💧":"1f4a7","🌊":"1f30a","🎃":"1f383","🎄":"1f384","🎆":"1f386","🎇":"1f387","🧨":"1f9e8","✨":"2728","🎈":"1f388","🎉":"1f389","🎊":"1f38a","🎋":"1f38b","🎍":"1f38d","🎎":"1f38e","🎏":"1f38f","🎐":"1f390","🎑":"1f391","🧧":"1f9e7","🎀":"1f380","🎁":"1f381","🎗":"1f397","🎟":"1f39f","🎫":"1f3ab","🎖":"1f396","🏆":"1f3c6","🏅":"1f3c5","🥇":"1f947","🥈":"1f948","🥉":"1f949","⚽":"26bd","⚾":"26be","🥎":"1f94e","🏀":"1f3c0","🏐":"1f3d0","🏈":"1f3c8","🏉":"1f3c9","🎾":"1f3be","🥏":"1f94f","🎳":"1f3b3","🏏":"1f3cf","🏑":"1f3d1","🏒":"1f3d2","🥍":"1f94d","🏓":"1f3d3","🏸":"1f3f8","🥊":"1f94a","🥋":"1f94b","🥅":"1f945","⛳":"26f3","⛸":"26f8","🎣":"1f3a3","🤿":"1f93f","🎽":"1f3bd","🎿":"1f3bf","🛷":"1f6f7","🥌":"1f94c","🎯":"1f3af","🪀":"1fa80","🪁":"1fa81","🔫":"1f52b","🎱":"1f3b1","🔮":"1f52e","🪄":"1fa84","🎮":"1f3ae","🕹":"1f579","🎰":"1f3b0","🎲":"1f3b2","🧩":"1f9e9","🧸":"1f9f8","🪅":"1fa85","🪩":"1faa9","🪆":"1fa86","♠":"2660","♥":"2665","♦":"2666","♣":"2663","♟":"265f","🃏":"1f0cf","🀄":"1f004","🎴":"1f3b4","🎭":"1f3ad","🖼":"1f5bc","🎨":"1f3a8","🧵":"1f9f5","🪡":"1faa1","🧶":"1f9f6","🪢":"1faa2","👓":"1f453","🕶":"1f576","🥽":"1f97d","🥼":"1f97c","🦺":"1f9ba","👔":"1f454","👕":"1f455","👖":"1f456","🧣":"1f9e3","🧤":"1f9e4","🧥":"1f9e5","🧦":"1f9e6","👗":"1f457","👘":"1f458","🥻":"1f97b","🩱":"1fa71","🩲":"1fa72","🩳":"1fa73","👙":"1f459","👚":"1f45a","🪭":"1faad","👛":"1f45b","👜":"1f45c","👝":"1f45d","🛍":"1f6cd","🎒":"1f392","🩴":"1fa74","👞":"1f45e","👟":"1f45f","🥾":"1f97e","🥿":"1f97f","👠":"1f460","👡":"1f461","🩰":"1fa70","👢":"1f462","🪮":"1faae","👑":"1f451","👒":"1f452","🎩":"1f3a9","🎓":"1f393","🧢":"1f9e2","🪖":"1fa96","⛑":"26d1","📿":"1f4ff","💄":"1f484","💍":"1f48d","💎":"1f48e","🔇":"1f507","🔈":"1f508","🔉":"1f509","🔊":"1f50a","📢":"1f4e2","📣":"1f4e3","📯":"1f4ef","🔔":"1f514","🔕":"1f515","🎼":"1f3bc","🎵":"1f3b5","🎶":"1f3b6","🎙":"1f399","🎚":"1f39a","🎛":"1f39b","🎤":"1f3a4","🎧":"1f3a7","📻":"1f4fb","🎷":"1f3b7","🪗":"1fa97","🎸":"1f3b8","🎹":"1f3b9","🎺":"1f3ba","🎻":"1f3bb","🪕":"1fa95","🥁":"1f941","🪘":"1fa98","🪇":"1fa87","🪈":"1fa88","📱":"1f4f1","📲":"1f4f2","☎":"260e","📞":"1f4de","📟":"1f4df","📠":"1f4e0","🔋":"1f50b","🪫":"1faab","🔌":"1f50c","💻":"1f4bb","🖥":"1f5a5","🖨":"1f5a8","⌨":"2328","🖱":"1f5b1","🖲":"1f5b2","💽":"1f4bd","💾":"1f4be","💿":"1f4bf","📀":"1f4c0","🧮":"1f9ee","🎥":"1f3a5","🎞":"1f39e","📽":"1f4fd","🎬":"1f3ac","📺":"1f4fa","📷":"1f4f7","📸":"1f4f8","📹":"1f4f9","📼":"1f4fc","🔍":"1f50d","🔎":"1f50e","🕯":"1f56f","💡":"1f4a1","🔦":"1f526","🏮":"1f3ee","🪔":"1fa94","📔":"1f4d4","📕":"1f4d5","📖":"1f4d6","📗":"1f4d7","📘":"1f4d8","📙":"1f4d9","📚":"1f4da","📓":"1f4d3","📒":"1f4d2","📃":"1f4c3","📜":"1f4dc","📄":"1f4c4","📰":"1f4f0","🗞":"1f5de","📑":"1f4d1","🔖":"1f516","🏷":"1f3f7","💰":"1f4b0","🪙":"1fa99","💴":"1f4b4","💵":"1f4b5","💶":"1f4b6","💷":"1f4b7","💸":"1f4b8","💳":"1f4b3","🧾":"1f9fe","💹":"1f4b9","✉":"2709","📧":"1f4e7","📨":"1f4e8","📩":"1f4e9","📤":"1f4e4","📥":"1f4e5","📦":"1f4e6","📫":"1f4eb","📪":"1f4ea","📬":"1f4ec","📭":"1f4ed","📮":"1f4ee","🗳":"1f5f3","✏":"270f","✒":"2712","🖋":"1f58b","🖊":"1f58a","🖌":"1f58c","🖍":"1f58d","📝":"1f4dd","💼":"1f4bc","📁":"1f4c1","📂":"1f4c2","🗂":"1f5c2","📅":"1f4c5","📆":"1f4c6","🗒":"1f5d2","🗓":"1f5d3","📇":"1f4c7","📈":"1f4c8","📉":"1f4c9","📊":"1f4ca","📋":"1f4cb","📌":"1f4cc","📍":"1f4cd","📎":"1f4ce","🖇":"1f587","📏":"1f4cf","📐":"1f4d0","✂":"2702","🗃":"1f5c3","🗄":"1f5c4","🗑":"1f5d1","🔒":"1f512","🔓":"1f513","🔏":"1f50f","🔐":"1f510","🔑":"1f511","🗝":"1f5dd","🔨":"1f528","🪓":"1fa93","⛏":"26cf","⚒":"2692","🛠":"1f6e0","🗡":"1f5e1","⚔":"2694","💣":"1f4a3","🪃":"1fa83","🏹":"1f3f9","🛡":"1f6e1","🪚":"1fa9a","🔧":"1f527","🪛":"1fa9b","🔩":"1f529","⚙":"2699","🗜":"1f5dc","⚖":"2696","🦯":"1f9af","🔗":"1f517","⛓":"26d3","🪝":"1fa9d","🧰":"1f9f0","🧲":"1f9f2","🪜":"1fa9c","⚗":"2697","🧪":"1f9ea","🧫":"1f9eb","🧬":"1f9ec","🔬":"1f52c","🔭":"1f52d","📡":"1f4e1","💉":"1f489","🩸":"1fa78","💊":"1f48a","🩹":"1fa79","🩼":"1fa7c","🩺":"1fa7a","🩻":"1fa7b","🚪":"1f6aa","🛗":"1f6d7","🪞":"1fa9e","🪟":"1fa9f","🛏":"1f6cf","🛋":"1f6cb","🪑":"1fa91","🚽":"1f6bd","🪠":"1faa0","🚿":"1f6bf","🛁":"1f6c1","🪤":"1faa4","🪒":"1fa92","🧴":"1f9f4","🧷":"1f9f7","🧹":"1f9f9","🧺":"1f9fa","🧻":"1f9fb","🪣":"1faa3","🧼":"1f9fc","🫧":"1fae7","🪥":"1faa5","🧽":"1f9fd","🧯":"1f9ef","🛒":"1f6d2","🚬":"1f6ac","⚰":"26b0","🪦":"1faa6","⚱":"26b1","🧿":"1f9ff","🪬":"1faac","🗿":"1f5ff","🪧":"1faa7","🪪":"1faaa","🏧":"1f3e7","🚮":"1f6ae","🚰":"1f6b0","♿":"267f","🚹":"1f6b9","🚺":"1f6ba","🚻":"1f6bb","🚼":"1f6bc","🚾":"1f6be","🛂":"1f6c2","🛃":"1f6c3","🛄":"1f6c4","🛅":"1f6c5","⚠":"26a0","🚸":"1f6b8","⛔":"26d4","🚫":"1f6ab","🚳":"1f6b3","🚭":"1f6ad","🚯":"1f6af","🚱":"1f6b1","🚷":"1f6b7","📵":"1f4f5","🔞":"1f51e","☢":"2622","☣":"2623","⬆":"2b06","↗":"2197","➡":"27a1","↘":"2198","⬇":"2b07","↙":"2199","⬅":"2b05","↖":"2196","↕":"2195","↔":"2194","↩":"21a9","↪":"21aa","⤴":"2934","⤵":"2935","🔃":"1f503","🔄":"1f504","🔙":"1f519","🔚":"1f51a","🔛":"1f51b","🔜":"1f51c","🔝":"1f51d","🛐":"1f6d0","⚛":"269b","🕉":"1f549","✡":"2721","☸":"2638","☯":"262f","✝":"271d","☦":"2626","☪":"262a","☮":"262e","🕎":"1f54e","🔯":"1f52f","🪯":"1faaf","♈":"2648","♉":"2649","♊":"264a","♋":"264b","♌":"264c","♍":"264d","♎":"264e","♏":"264f","♐":"2650","♑":"2651","♒":"2652","♓":"2653","⛎":"26ce","🔀":"1f500","🔁":"1f501","🔂":"1f502","▶":"25b6","⏩":"23e9","⏭":"23ed","⏯":"23ef","◀":"25c0","⏪":"23ea","⏮":"23ee","🔼":"1f53c","⏫":"23eb","🔽":"1f53d","⏬":"23ec","⏸":"23f8","⏹":"23f9","⏺":"23fa","⏏":"23cf","🎦":"1f3a6","🔅":"1f505","🔆":"1f506","📶":"1f4f6","🛜":"1f6dc","📳":"1f4f3","📴":"1f4f4","♀":"2640","♂":"2642","⚧":"26a7","✖":"2716","➕":"2795","➖":"2796","➗":"2797","🟰":"1f7f0","♾":"267e","‼":"203c","⁉":"2049","❓":"2753","❔":"2754","❕":"2755","❗":"2757","〰":"3030","💱":"1f4b1","💲":"1f4b2","⚕":"2695","♻":"267b","⚜":"269c","🔱":"1f531","📛":"1f4db","🔰":"1f530","⭕":"2b55","✅":"2705","☑":"2611","✔":"2714","❌":"274c","❎":"274e","➰":"27b0","➿":"27bf","〽":"303d","✳":"2733","✴":"2734","❇":"2747","©":"a9","®":"ae","™":"2122","🔟":"1f51f","🔠":"1f520","🔡":"1f521","🔢":"1f522","🔣":"1f523","🔤":"1f524","🅰":"1f170","🆎":"1f18e","🅱":"1f171","🆑":"1f191","🆒":"1f192","🆓":"1f193","ℹ":"2139","🆔":"1f194","Ⓜ":"24c2","🆕":"1f195","🆖":"1f196","🅾":"1f17e","🆗":"1f197","🅿":"1f17f","🆘":"1f198","🆙":"1f199","🆚":"1f19a","🈁":"1f201","🈂":"1f202","🈷":"1f237","🈶":"1f236","🈯":"1f22f","🉐":"1f250","🈹":"1f239","🈚":"1f21a","🈲":"1f232","🉑":"1f251","🈸":"1f238","🈴":"1f234","🈳":"1f233","㊗":"3297","㊙":"3299","🈺":"1f23a","🈵":"1f235","🔴":"1f534","🟠":"1f7e0","🟡":"1f7e1","🟢":"1f7e2","🔵":"1f535","🟣":"1f7e3","🟤":"1f7e4","⚫":"26ab","⚪":"26aa","🟥":"1f7e5","🟧":"1f7e7","🟨":"1f7e8","🟩":"1f7e9","🟦":"1f7e6","🟪":"1f7ea","🟫":"1f7eb","⬛":"2b1b","⬜":"2b1c","◼":"25fc","◻":"25fb","◾":"25fe","◽":"25fd","▪":"25aa","▫":"25ab","🔶":"1f536","🔷":"1f537","🔸":"1f538","🔹":"1f539","🔺":"1f53a","🔻":"1f53b","💠":"1f4a0","🔘":"1f518","🔳":"1f533","🔲":"1f532","🏁":"1f3c1","🚩":"1f6a9","🎌":"1f38c","🏴":"1f3f4","🏳":"1f3f3","☺️":"263a","☹️":"2639","☠️":"2620","❣️":"2763","❤️":"2764","🕳️":"1f573","🗨️":"1f5e8","🗯️":"1f5ef","👋🏻":"1f44b-1f3fb","👋🏼":"1f44b-1f3fc","👋🏽":"1f44b-1f3fd","👋🏾":"1f44b-1f3fe","👋🏿":"1f44b-1f3ff","🤚🏻":"1f91a-1f3fb","🤚🏼":"1f91a-1f3fc","🤚🏽":"1f91a-1f3fd","🤚🏾":"1f91a-1f3fe","🤚🏿":"1f91a-1f3ff","🖐️":"1f590","🖐🏻":"1f590-1f3fb","🖐🏼":"1f590-1f3fc","🖐🏽":"1f590-1f3fd","🖐🏾":"1f590-1f3fe","🖐🏿":"1f590-1f3ff","✋🏻":"270b-1f3fb","✋🏼":"270b-1f3fc","✋🏽":"270b-1f3fd","✋🏾":"270b-1f3fe","✋🏿":"270b-1f3ff","🖖🏻":"1f596-1f3fb","🖖🏼":"1f596-1f3fc","🖖🏽":"1f596-1f3fd","🖖🏾":"1f596-1f3fe","🖖🏿":"1f596-1f3ff","🫱🏻":"1faf1-1f3fb","🫱🏼":"1faf1-1f3fc","🫱🏽":"1faf1-1f3fd","🫱🏾":"1faf1-1f3fe","🫱🏿":"1faf1-1f3ff","🫲🏻":"1faf2-1f3fb","🫲🏼":"1faf2-1f3fc","🫲🏽":"1faf2-1f3fd","🫲🏾":"1faf2-1f3fe","🫲🏿":"1faf2-1f3ff","🫳🏻":"1faf3-1f3fb","🫳🏼":"1faf3-1f3fc","🫳🏽":"1faf3-1f3fd","🫳🏾":"1faf3-1f3fe","🫳🏿":"1faf3-1f3ff","🫴🏻":"1faf4-1f3fb","🫴🏼":"1faf4-1f3fc","🫴🏽":"1faf4-1f3fd","🫴🏾":"1faf4-1f3fe","🫴🏿":"1faf4-1f3ff","🫷🏻":"1faf7-1f3fb","🫷🏼":"1faf7-1f3fc","🫷🏽":"1faf7-1f3fd","🫷🏾":"1faf7-1f3fe","🫷🏿":"1faf7-1f3ff","🫸🏻":"1faf8-1f3fb","🫸🏼":"1faf8-1f3fc","🫸🏽":"1faf8-1f3fd","🫸🏾":"1faf8-1f3fe","🫸🏿":"1faf8-1f3ff","👌🏻":"1f44c-1f3fb","👌🏼":"1f44c-1f3fc","👌🏽":"1f44c-1f3fd","👌🏾":"1f44c-1f3fe","👌🏿":"1f44c-1f3ff","🤌🏻":"1f90c-1f3fb","🤌🏼":"1f90c-1f3fc","🤌🏽":"1f90c-1f3fd","🤌🏾":"1f90c-1f3fe","🤌🏿":"1f90c-1f3ff","🤏🏻":"1f90f-1f3fb","🤏🏼":"1f90f-1f3fc","🤏🏽":"1f90f-1f3fd","🤏🏾":"1f90f-1f3fe","🤏🏿":"1f90f-1f3ff","✌️":"270c","✌🏻":"270c-1f3fb","✌🏼":"270c-1f3fc","✌🏽":"270c-1f3fd","✌🏾":"270c-1f3fe","✌🏿":"270c-1f3ff","🤞🏻":"1f91e-1f3fb","🤞🏼":"1f91e-1f3fc","🤞🏽":"1f91e-1f3fd","🤞🏾":"1f91e-1f3fe","🤞🏿":"1f91e-1f3ff","🫰🏻":"1faf0-1f3fb","🫰🏼":"1faf0-1f3fc","🫰🏽":"1faf0-1f3fd","🫰🏾":"1faf0-1f3fe","🫰🏿":"1faf0-1f3ff","🤟🏻":"1f91f-1f3fb","🤟🏼":"1f91f-1f3fc","🤟🏽":"1f91f-1f3fd","🤟🏾":"1f91f-1f3fe","🤟🏿":"1f91f-1f3ff","🤘🏻":"1f918-1f3fb","🤘🏼":"1f918-1f3fc","🤘🏽":"1f918-1f3fd","🤘🏾":"1f918-1f3fe","🤘🏿":"1f918-1f3ff","🤙🏻":"1f919-1f3fb","🤙🏼":"1f919-1f3fc","🤙🏽":"1f919-1f3fd","🤙🏾":"1f919-1f3fe","🤙🏿":"1f919-1f3ff","👈🏻":"1f448-1f3fb","👈🏼":"1f448-1f3fc","👈🏽":"1f448-1f3fd","👈🏾":"1f448-1f3fe","👈🏿":"1f448-1f3ff","👉🏻":"1f449-1f3fb","👉🏼":"1f449-1f3fc","👉🏽":"1f449-1f3fd","👉🏾":"1f449-1f3fe","👉🏿":"1f449-1f3ff","👆🏻":"1f446-1f3fb","👆🏼":"1f446-1f3fc","👆🏽":"1f446-1f3fd","👆🏾":"1f446-1f3fe","👆🏿":"1f446-1f3ff","🖕🏻":"1f595-1f3fb","🖕🏼":"1f595-1f3fc","🖕🏽":"1f595-1f3fd","🖕🏾":"1f595-1f3fe","🖕🏿":"1f595-1f3ff","👇🏻":"1f447-1f3fb","👇🏼":"1f447-1f3fc","👇🏽":"1f447-1f3fd","👇🏾":"1f447-1f3fe","👇🏿":"1f447-1f3ff","☝️":"261d","☝🏻":"261d-1f3fb","☝🏼":"261d-1f3fc","☝🏽":"261d-1f3fd","☝🏾":"261d-1f3fe","☝🏿":"261d-1f3ff","🫵🏻":"1faf5-1f3fb","🫵🏼":"1faf5-1f3fc","🫵🏽":"1faf5-1f3fd","🫵🏾":"1faf5-1f3fe","🫵🏿":"1faf5-1f3ff","👍🏻":"1f44d-1f3fb","👍🏼":"1f44d-1f3fc","👍🏽":"1f44d-1f3fd","👍🏾":"1f44d-1f3fe","👍🏿":"1f44d-1f3ff","👎🏻":"1f44e-1f3fb","👎🏼":"1f44e-1f3fc","👎🏽":"1f44e-1f3fd","👎🏾":"1f44e-1f3fe","👎🏿":"1f44e-1f3ff","✊🏻":"270a-1f3fb","✊🏼":"270a-1f3fc","✊🏽":"270a-1f3fd","✊🏾":"270a-1f3fe","✊🏿":"270a-1f3ff","👊🏻":"1f44a-1f3fb","👊🏼":"1f44a-1f3fc","👊🏽":"1f44a-1f3fd","👊🏾":"1f44a-1f3fe","👊🏿":"1f44a-1f3ff","🤛🏻":"1f91b-1f3fb","🤛🏼":"1f91b-1f3fc","🤛🏽":"1f91b-1f3fd","🤛🏾":"1f91b-1f3fe","🤛🏿":"1f91b-1f3ff","🤜🏻":"1f91c-1f3fb","🤜🏼":"1f91c-1f3fc","🤜🏽":"1f91c-1f3fd","🤜🏾":"1f91c-1f3fe","🤜🏿":"1f91c-1f3ff","👏🏻":"1f44f-1f3fb","👏🏼":"1f44f-1f3fc","👏🏽":"1f44f-1f3fd","👏🏾":"1f44f-1f3fe","👏🏿":"1f44f-1f3ff","🙌🏻":"1f64c-1f3fb","🙌🏼":"1f64c-1f3fc","🙌🏽":"1f64c-1f3fd","🙌🏾":"1f64c-1f3fe","🙌🏿":"1f64c-1f3ff","🫶🏻":"1faf6-1f3fb","🫶🏼":"1faf6-1f3fc","🫶🏽":"1faf6-1f3fd","🫶🏾":"1faf6-1f3fe","🫶🏿":"1faf6-1f3ff","👐🏻":"1f450-1f3fb","👐🏼":"1f450-1f3fc","👐🏽":"1f450-1f3fd","👐🏾":"1f450-1f3fe","👐🏿":"1f450-1f3ff","🤲🏻":"1f932-1f3fb","🤲🏼":"1f932-1f3fc","🤲🏽":"1f932-1f3fd","🤲🏾":"1f932-1f3fe","🤲🏿":"1f932-1f3ff","🤝🏻":"1f91d-1f3fb","🤝🏼":"1f91d-1f3fc","🤝🏽":"1f91d-1f3fd","🤝🏾":"1f91d-1f3fe","🤝🏿":"1f91d-1f3ff","🙏🏻":"1f64f-1f3fb","🙏🏼":"1f64f-1f3fc","🙏🏽":"1f64f-1f3fd","🙏🏾":"1f64f-1f3fe","🙏🏿":"1f64f-1f3ff","✍️":"270d","✍🏻":"270d-1f3fb","✍🏼":"270d-1f3fc","✍🏽":"270d-1f3fd","✍🏾":"270d-1f3fe","✍🏿":"270d-1f3ff","💅🏻":"1f485-1f3fb","💅🏼":"1f485-1f3fc","💅🏽":"1f485-1f3fd","💅🏾":"1f485-1f3fe","💅🏿":"1f485-1f3ff","🤳🏻":"1f933-1f3fb","🤳🏼":"1f933-1f3fc","🤳🏽":"1f933-1f3fd","🤳🏾":"1f933-1f3fe","🤳🏿":"1f933-1f3ff","💪🏻":"1f4aa-1f3fb","💪🏼":"1f4aa-1f3fc","💪🏽":"1f4aa-1f3fd","💪🏾":"1f4aa-1f3fe","💪🏿":"1f4aa-1f3ff","🦵🏻":"1f9b5-1f3fb","🦵🏼":"1f9b5-1f3fc","🦵🏽":"1f9b5-1f3fd","🦵🏾":"1f9b5-1f3fe","🦵🏿":"1f9b5-1f3ff","🦶🏻":"1f9b6-1f3fb","🦶🏼":"1f9b6-1f3fc","🦶🏽":"1f9b6-1f3fd","🦶🏾":"1f9b6-1f3fe","🦶🏿":"1f9b6-1f3ff","👂🏻":"1f442-1f3fb","👂🏼":"1f442-1f3fc","👂🏽":"1f442-1f3fd","👂🏾":"1f442-1f3fe","👂🏿":"1f442-1f3ff","🦻🏻":"1f9bb-1f3fb","🦻🏼":"1f9bb-1f3fc","🦻🏽":"1f9bb-1f3fd","🦻🏾":"1f9bb-1f3fe","🦻🏿":"1f9bb-1f3ff","👃🏻":"1f443-1f3fb","👃🏼":"1f443-1f3fc","👃🏽":"1f443-1f3fd","👃🏾":"1f443-1f3fe","👃🏿":"1f443-1f3ff","👁️":"1f441","👶🏻":"1f476-1f3fb","👶🏼":"1f476-1f3fc","👶🏽":"1f476-1f3fd","👶🏾":"1f476-1f3fe","👶🏿":"1f476-1f3ff","🧒🏻":"1f9d2-1f3fb","🧒🏼":"1f9d2-1f3fc","🧒🏽":"1f9d2-1f3fd","🧒🏾":"1f9d2-1f3fe","🧒🏿":"1f9d2-1f3ff","👦🏻":"1f466-1f3fb","👦🏼":"1f466-1f3fc","👦🏽":"1f466-1f3fd","👦🏾":"1f466-1f3fe","👦🏿":"1f466-1f3ff","👧🏻":"1f467-1f3fb","👧🏼":"1f467-1f3fc","👧🏽":"1f467-1f3fd","👧🏾":"1f467-1f3fe","👧🏿":"1f467-1f3ff","🧑🏻":"1f9d1-1f3fb","🧑🏼":"1f9d1-1f3fc","🧑🏽":"1f9d1-1f3fd","🧑🏾":"1f9d1-1f3fe","🧑🏿":"1f9d1-1f3ff","👱🏻":"1f471-1f3fb","👱🏼":"1f471-1f3fc","👱🏽":"1f471-1f3fd","👱🏾":"1f471-1f3fe","👱🏿":"1f471-1f3ff","👨🏻":"1f468-1f3fb","👨🏼":"1f468-1f3fc","👨🏽":"1f468-1f3fd","👨🏾":"1f468-1f3fe","👨🏿":"1f468-1f3ff","🧔🏻":"1f9d4-1f3fb","🧔🏼":"1f9d4-1f3fc","🧔🏽":"1f9d4-1f3fd","🧔🏾":"1f9d4-1f3fe","🧔🏿":"1f9d4-1f3ff","👩🏻":"1f469-1f3fb","👩🏼":"1f469-1f3fc","👩🏽":"1f469-1f3fd","👩🏾":"1f469-1f3fe","👩🏿":"1f469-1f3ff","🧓🏻":"1f9d3-1f3fb","🧓🏼":"1f9d3-1f3fc","🧓🏽":"1f9d3-1f3fd","🧓🏾":"1f9d3-1f3fe","🧓🏿":"1f9d3-1f3ff","👴🏻":"1f474-1f3fb","👴🏼":"1f474-1f3fc","👴🏽":"1f474-1f3fd","👴🏾":"1f474-1f3fe","👴🏿":"1f474-1f3ff","👵🏻":"1f475-1f3fb","👵🏼":"1f475-1f3fc","👵🏽":"1f475-1f3fd","👵🏾":"1f475-1f3fe","👵🏿":"1f475-1f3ff","🙍🏻":"1f64d-1f3fb","🙍🏼":"1f64d-1f3fc","🙍🏽":"1f64d-1f3fd","🙍🏾":"1f64d-1f3fe","🙍🏿":"1f64d-1f3ff","🙎🏻":"1f64e-1f3fb","🙎🏼":"1f64e-1f3fc","🙎🏽":"1f64e-1f3fd","🙎🏾":"1f64e-1f3fe","🙎🏿":"1f64e-1f3ff","🙅🏻":"1f645-1f3fb","🙅🏼":"1f645-1f3fc","🙅🏽":"1f645-1f3fd","🙅🏾":"1f645-1f3fe","🙅🏿":"1f645-1f3ff","🙆🏻":"1f646-1f3fb","🙆🏼":"1f646-1f3fc","🙆🏽":"1f646-1f3fd","🙆🏾":"1f646-1f3fe","🙆🏿":"1f646-1f3ff","💁🏻":"1f481-1f3fb","💁🏼":"1f481-1f3fc","💁🏽":"1f481-1f3fd","💁🏾":"1f481-1f3fe","💁🏿":"1f481-1f3ff","🙋🏻":"1f64b-1f3fb","🙋🏼":"1f64b-1f3fc","🙋🏽":"1f64b-1f3fd","🙋🏾":"1f64b-1f3fe","🙋🏿":"1f64b-1f3ff","🧏🏻":"1f9cf-1f3fb","🧏🏼":"1f9cf-1f3fc","🧏🏽":"1f9cf-1f3fd","🧏🏾":"1f9cf-1f3fe","🧏🏿":"1f9cf-1f3ff","🙇🏻":"1f647-1f3fb","🙇🏼":"1f647-1f3fc","🙇🏽":"1f647-1f3fd","🙇🏾":"1f647-1f3fe","🙇🏿":"1f647-1f3ff","🤦🏻":"1f926-1f3fb","🤦🏼":"1f926-1f3fc","🤦🏽":"1f926-1f3fd","🤦🏾":"1f926-1f3fe","🤦🏿":"1f926-1f3ff","🤷🏻":"1f937-1f3fb","🤷🏼":"1f937-1f3fc","🤷🏽":"1f937-1f3fd","🤷🏾":"1f937-1f3fe","🤷🏿":"1f937-1f3ff","👮🏻":"1f46e-1f3fb","👮🏼":"1f46e-1f3fc","👮🏽":"1f46e-1f3fd","👮🏾":"1f46e-1f3fe","👮🏿":"1f46e-1f3ff","🕵️":"1f575","🕵🏻":"1f575-1f3fb","🕵🏼":"1f575-1f3fc","🕵🏽":"1f575-1f3fd","🕵🏾":"1f575-1f3fe","🕵🏿":"1f575-1f3ff","💂🏻":"1f482-1f3fb","💂🏼":"1f482-1f3fc","💂🏽":"1f482-1f3fd","💂🏾":"1f482-1f3fe","💂🏿":"1f482-1f3ff","🥷🏻":"1f977-1f3fb","🥷🏼":"1f977-1f3fc","🥷🏽":"1f977-1f3fd","🥷🏾":"1f977-1f3fe","🥷🏿":"1f977-1f3ff","👷🏻":"1f477-1f3fb","👷🏼":"1f477-1f3fc","👷🏽":"1f477-1f3fd","👷🏾":"1f477-1f3fe","👷🏿":"1f477-1f3ff","🫅🏻":"1fac5-1f3fb","🫅🏼":"1fac5-1f3fc","🫅🏽":"1fac5-1f3fd","🫅🏾":"1fac5-1f3fe","🫅🏿":"1fac5-1f3ff","🤴🏻":"1f934-1f3fb","🤴🏼":"1f934-1f3fc","🤴🏽":"1f934-1f3fd","🤴🏾":"1f934-1f3fe","🤴🏿":"1f934-1f3ff","👸🏻":"1f478-1f3fb","👸🏼":"1f478-1f3fc","👸🏽":"1f478-1f3fd","👸🏾":"1f478-1f3fe","👸🏿":"1f478-1f3ff","👳🏻":"1f473-1f3fb","👳🏼":"1f473-1f3fc","👳🏽":"1f473-1f3fd","👳🏾":"1f473-1f3fe","👳🏿":"1f473-1f3ff","👲🏻":"1f472-1f3fb","👲🏼":"1f472-1f3fc","👲🏽":"1f472-1f3fd","👲🏾":"1f472-1f3fe","👲🏿":"1f472-1f3ff","🧕🏻":"1f9d5-1f3fb","🧕🏼":"1f9d5-1f3fc","🧕🏽":"1f9d5-1f3fd","🧕🏾":"1f9d5-1f3fe","🧕🏿":"1f9d5-1f3ff","🤵🏻":"1f935-1f3fb","🤵🏼":"1f935-1f3fc","🤵🏽":"1f935-1f3fd","🤵🏾":"1f935-1f3fe","🤵🏿":"1f935-1f3ff","👰🏻":"1f470-1f3fb","👰🏼":"1f470-1f3fc","👰🏽":"1f470-1f3fd","👰🏾":"1f470-1f3fe","👰🏿":"1f470-1f3ff","🤰🏻":"1f930-1f3fb","🤰🏼":"1f930-1f3fc","🤰🏽":"1f930-1f3fd","🤰🏾":"1f930-1f3fe","🤰🏿":"1f930-1f3ff","🫃🏻":"1fac3-1f3fb","🫃🏼":"1fac3-1f3fc","🫃🏽":"1fac3-1f3fd","🫃🏾":"1fac3-1f3fe","🫃🏿":"1fac3-1f3ff","🫄🏻":"1fac4-1f3fb","🫄🏼":"1fac4-1f3fc","🫄🏽":"1fac4-1f3fd","🫄🏾":"1fac4-1f3fe","🫄🏿":"1fac4-1f3ff","🤱🏻":"1f931-1f3fb","🤱🏼":"1f931-1f3fc","🤱🏽":"1f931-1f3fd","🤱🏾":"1f931-1f3fe","🤱🏿":"1f931-1f3ff","👼🏻":"1f47c-1f3fb","👼🏼":"1f47c-1f3fc","👼🏽":"1f47c-1f3fd","👼🏾":"1f47c-1f3fe","👼🏿":"1f47c-1f3ff","🎅🏻":"1f385-1f3fb","🎅🏼":"1f385-1f3fc","🎅🏽":"1f385-1f3fd","🎅🏾":"1f385-1f3fe","🎅🏿":"1f385-1f3ff","🤶🏻":"1f936-1f3fb","🤶🏼":"1f936-1f3fc","🤶🏽":"1f936-1f3fd","🤶🏾":"1f936-1f3fe","🤶🏿":"1f936-1f3ff","🦸🏻":"1f9b8-1f3fb","🦸🏼":"1f9b8-1f3fc","🦸🏽":"1f9b8-1f3fd","🦸🏾":"1f9b8-1f3fe","🦸🏿":"1f9b8-1f3ff","🦹🏻":"1f9b9-1f3fb","🦹🏼":"1f9b9-1f3fc","🦹🏽":"1f9b9-1f3fd","🦹🏾":"1f9b9-1f3fe","🦹🏿":"1f9b9-1f3ff","🧙🏻":"1f9d9-1f3fb","🧙🏼":"1f9d9-1f3fc","🧙🏽":"1f9d9-1f3fd","🧙🏾":"1f9d9-1f3fe","🧙🏿":"1f9d9-1f3ff","🧚🏻":"1f9da-1f3fb","🧚🏼":"1f9da-1f3fc","🧚🏽":"1f9da-1f3fd","🧚🏾":"1f9da-1f3fe","🧚🏿":"1f9da-1f3ff","🧛🏻":"1f9db-1f3fb","🧛🏼":"1f9db-1f3fc","🧛🏽":"1f9db-1f3fd","🧛🏾":"1f9db-1f3fe","🧛🏿":"1f9db-1f3ff","🧜🏻":"1f9dc-1f3fb","🧜🏼":"1f9dc-1f3fc","🧜🏽":"1f9dc-1f3fd","🧜🏾":"1f9dc-1f3fe","🧜🏿":"1f9dc-1f3ff","🧝🏻":"1f9dd-1f3fb","🧝🏼":"1f9dd-1f3fc","🧝🏽":"1f9dd-1f3fd","🧝🏾":"1f9dd-1f3fe","🧝🏿":"1f9dd-1f3ff","💆🏻":"1f486-1f3fb","💆🏼":"1f486-1f3fc","💆🏽":"1f486-1f3fd","💆🏾":"1f486-1f3fe","💆🏿":"1f486-1f3ff","💇🏻":"1f487-1f3fb","💇🏼":"1f487-1f3fc","💇🏽":"1f487-1f3fd","💇🏾":"1f487-1f3fe","💇🏿":"1f487-1f3ff","🚶🏻":"1f6b6-1f3fb","🚶🏼":"1f6b6-1f3fc","🚶🏽":"1f6b6-1f3fd","🚶🏾":"1f6b6-1f3fe","🚶🏿":"1f6b6-1f3ff","🧍🏻":"1f9cd-1f3fb","🧍🏼":"1f9cd-1f3fc","🧍🏽":"1f9cd-1f3fd","🧍🏾":"1f9cd-1f3fe","🧍🏿":"1f9cd-1f3ff","🧎🏻":"1f9ce-1f3fb","🧎🏼":"1f9ce-1f3fc","🧎🏽":"1f9ce-1f3fd","🧎🏾":"1f9ce-1f3fe","🧎🏿":"1f9ce-1f3ff","🏃🏻":"1f3c3-1f3fb","🏃🏼":"1f3c3-1f3fc","🏃🏽":"1f3c3-1f3fd","🏃🏾":"1f3c3-1f3fe","🏃🏿":"1f3c3-1f3ff","💃🏻":"1f483-1f3fb","💃🏼":"1f483-1f3fc","💃🏽":"1f483-1f3fd","💃🏾":"1f483-1f3fe","💃🏿":"1f483-1f3ff","🕺🏻":"1f57a-1f3fb","🕺🏼":"1f57a-1f3fc","🕺🏽":"1f57a-1f3fd","🕺🏾":"1f57a-1f3fe","🕺🏿":"1f57a-1f3ff","🕴️":"1f574","🕴🏻":"1f574-1f3fb","🕴🏼":"1f574-1f3fc","🕴🏽":"1f574-1f3fd","🕴🏾":"1f574-1f3fe","🕴🏿":"1f574-1f3ff","🧖🏻":"1f9d6-1f3fb","🧖🏼":"1f9d6-1f3fc","🧖🏽":"1f9d6-1f3fd","🧖🏾":"1f9d6-1f3fe","🧖🏿":"1f9d6-1f3ff","🧗🏻":"1f9d7-1f3fb","🧗🏼":"1f9d7-1f3fc","🧗🏽":"1f9d7-1f3fd","🧗🏾":"1f9d7-1f3fe","🧗🏿":"1f9d7-1f3ff","🏇🏻":"1f3c7-1f3fb","🏇🏼":"1f3c7-1f3fc","🏇🏽":"1f3c7-1f3fd","🏇🏾":"1f3c7-1f3fe","🏇🏿":"1f3c7-1f3ff","⛷️":"26f7","🏂🏻":"1f3c2-1f3fb","🏂🏼":"1f3c2-1f3fc","🏂🏽":"1f3c2-1f3fd","🏂🏾":"1f3c2-1f3fe","🏂🏿":"1f3c2-1f3ff","🏌️":"1f3cc","🏌🏻":"1f3cc-1f3fb","🏌🏼":"1f3cc-1f3fc","🏌🏽":"1f3cc-1f3fd","🏌🏾":"1f3cc-1f3fe","🏌🏿":"1f3cc-1f3ff","🏄🏻":"1f3c4-1f3fb","🏄🏼":"1f3c4-1f3fc","🏄🏽":"1f3c4-1f3fd","🏄🏾":"1f3c4-1f3fe","🏄🏿":"1f3c4-1f3ff","🚣🏻":"1f6a3-1f3fb","🚣🏼":"1f6a3-1f3fc","🚣🏽":"1f6a3-1f3fd","🚣🏾":"1f6a3-1f3fe","🚣🏿":"1f6a3-1f3ff","🏊🏻":"1f3ca-1f3fb","🏊🏼":"1f3ca-1f3fc","🏊🏽":"1f3ca-1f3fd","🏊🏾":"1f3ca-1f3fe","🏊🏿":"1f3ca-1f3ff","⛹️":"26f9","⛹🏻":"26f9-1f3fb","⛹🏼":"26f9-1f3fc","⛹🏽":"26f9-1f3fd","⛹🏾":"26f9-1f3fe","⛹🏿":"26f9-1f3ff","🏋️":"1f3cb","🏋🏻":"1f3cb-1f3fb","🏋🏼":"1f3cb-1f3fc","🏋🏽":"1f3cb-1f3fd","🏋🏾":"1f3cb-1f3fe","🏋🏿":"1f3cb-1f3ff","🚴🏻":"1f6b4-1f3fb","🚴🏼":"1f6b4-1f3fc","🚴🏽":"1f6b4-1f3fd","🚴🏾":"1f6b4-1f3fe","🚴🏿":"1f6b4-1f3ff","🚵🏻":"1f6b5-1f3fb","🚵🏼":"1f6b5-1f3fc","🚵🏽":"1f6b5-1f3fd","🚵🏾":"1f6b5-1f3fe","🚵🏿":"1f6b5-1f3ff","🤸🏻":"1f938-1f3fb","🤸🏼":"1f938-1f3fc","🤸🏽":"1f938-1f3fd","🤸🏾":"1f938-1f3fe","🤸🏿":"1f938-1f3ff","🤽🏻":"1f93d-1f3fb","🤽🏼":"1f93d-1f3fc","🤽🏽":"1f93d-1f3fd","🤽🏾":"1f93d-1f3fe","🤽🏿":"1f93d-1f3ff","🤾🏻":"1f93e-1f3fb","🤾🏼":"1f93e-1f3fc","🤾🏽":"1f93e-1f3fd","🤾🏾":"1f93e-1f3fe","🤾🏿":"1f93e-1f3ff","🤹🏻":"1f939-1f3fb","🤹🏼":"1f939-1f3fc","🤹🏽":"1f939-1f3fd","🤹🏾":"1f939-1f3fe","🤹🏿":"1f939-1f3ff","🧘🏻":"1f9d8-1f3fb","🧘🏼":"1f9d8-1f3fc","🧘🏽":"1f9d8-1f3fd","🧘🏾":"1f9d8-1f3fe","🧘🏿":"1f9d8-1f3ff","🛀🏻":"1f6c0-1f3fb","🛀🏼":"1f6c0-1f3fc","🛀🏽":"1f6c0-1f3fd","🛀🏾":"1f6c0-1f3fe","🛀🏿":"1f6c0-1f3ff","🛌🏻":"1f6cc-1f3fb","🛌🏼":"1f6cc-1f3fc","🛌🏽":"1f6cc-1f3fd","🛌🏾":"1f6cc-1f3fe","🛌🏿":"1f6cc-1f3ff","👭🏻":"1f46d-1f3fb","👭🏼":"1f46d-1f3fc","👭🏽":"1f46d-1f3fd","👭🏾":"1f46d-1f3fe","👭🏿":"1f46d-1f3ff","👫🏻":"1f46b-1f3fb","👫🏼":"1f46b-1f3fc","👫🏽":"1f46b-1f3fd","👫🏾":"1f46b-1f3fe","👫🏿":"1f46b-1f3ff","👬🏻":"1f46c-1f3fb","👬🏼":"1f46c-1f3fc","👬🏽":"1f46c-1f3fd","👬🏾":"1f46c-1f3fe","👬🏿":"1f46c-1f3ff","💏🏻":"1f48f-1f3fb","💏🏼":"1f48f-1f3fc","💏🏽":"1f48f-1f3fd","💏🏾":"1f48f-1f3fe","💏🏿":"1f48f-1f3ff","💑🏻":"1f491-1f3fb","💑🏼":"1f491-1f3fc","💑🏽":"1f491-1f3fd","💑🏾":"1f491-1f3fe","💑🏿":"1f491-1f3ff","🗣️":"1f5e3","🐿️":"1f43f","🕊️":"1f54a","🕷️":"1f577","🕸️":"1f578","🏵️":"1f3f5","☘️":"2618","🌶️":"1f336","🍽️":"1f37d","🗺️":"1f5fa","🏔️":"1f3d4","⛰️":"26f0","🏕️":"1f3d5","🏖️":"1f3d6","🏜️":"1f3dc","🏝️":"1f3dd","🏞️":"1f3de","🏟️":"1f3df","🏛️":"1f3db","🏗️":"1f3d7","🏘️":"1f3d8","🏚️":"1f3da","⛩️":"26e9","🏙️":"1f3d9","♨️":"2668","🏎️":"1f3ce","🏍️":"1f3cd","🛣️":"1f6e3","🛤️":"1f6e4","🛢️":"1f6e2","🛳️":"1f6f3","⛴️":"26f4","🛥️":"1f6e5","✈️":"2708","🛩️":"1f6e9","🛰️":"1f6f0","🛎️":"1f6ce","⏱️":"23f1","⏲️":"23f2","🕰️":"1f570","🌡️":"1f321","☀️":"2600","☁️":"2601","⛈️":"26c8","🌤️":"1f324","🌥️":"1f325","🌦️":"1f326","🌧️":"1f327","🌨️":"1f328","🌩️":"1f329","🌪️":"1f32a","🌫️":"1f32b","🌬️":"1f32c","☂️":"2602","⛱️":"26f1","❄️":"2744","☃️":"2603","☄️":"2604","🎗️":"1f397","🎟️":"1f39f","🎖️":"1f396","⛸️":"26f8","🕹️":"1f579","♠️":"2660","♥️":"2665","♦️":"2666","♣️":"2663","♟️":"265f","🖼️":"1f5bc","🕶️":"1f576","🛍️":"1f6cd","⛑️":"26d1","🎙️":"1f399","🎚️":"1f39a","🎛️":"1f39b","☎️":"260e","🖥️":"1f5a5","🖨️":"1f5a8","⌨️":"2328","🖱️":"1f5b1","🖲️":"1f5b2","🎞️":"1f39e","📽️":"1f4fd","🕯️":"1f56f","🗞️":"1f5de","🏷️":"1f3f7","✉️":"2709","🗳️":"1f5f3","✏️":"270f","✒️":"2712","🖋️":"1f58b","🖊️":"1f58a","🖌️":"1f58c","🖍️":"1f58d","🗂️":"1f5c2","🗒️":"1f5d2","🗓️":"1f5d3","🖇️":"1f587","✂️":"2702","🗃️":"1f5c3","🗄️":"1f5c4","🗑️":"1f5d1","🗝️":"1f5dd","⛏️":"26cf","⚒️":"2692","🛠️":"1f6e0","🗡️":"1f5e1","⚔️":"2694","🛡️":"1f6e1","⚙️":"2699","🗜️":"1f5dc","⚖️":"2696","⛓️":"26d3","⚗️":"2697","🛏️":"1f6cf","🛋️":"1f6cb","⚰️":"26b0","⚱️":"26b1","⚠️":"26a0","☢️":"2622","☣️":"2623","⬆️":"2b06","↗️":"2197","➡️":"27a1","↘️":"2198","⬇️":"2b07","↙️":"2199","⬅️":"2b05","↖️":"2196","↕️":"2195","↔️":"2194","↩️":"21a9","↪️":"21aa","⤴️":"2934","⤵️":"2935","⚛️":"269b","🕉️":"1f549","✡️":"2721","☸️":"2638","☯️":"262f","✝️":"271d","☦️":"2626","☪️":"262a","☮️":"262e","▶️":"25b6","⏭️":"23ed","⏯️":"23ef","◀️":"25c0","⏮️":"23ee","⏸️":"23f8","⏹️":"23f9","⏺️":"23fa","⏏️":"23cf","♀️":"2640","♂️":"2642","⚧️":"26a7","✖️":"2716","♾️":"267e","‼️":"203c","⁉️":"2049","〰️":"3030","⚕️":"2695","♻️":"267b","⚜️":"269c","☑️":"2611","✔️":"2714","〽️":"303d","✳️":"2733","✴️":"2734","❇️":"2747","©️":"a9","®️":"ae","™️":"2122","#⃣":"23-20e3","*⃣":"2a-20e3","0⃣":"30-20e3","1⃣":"31-20e3","2⃣":"32-20e3","3⃣":"33-20e3","4⃣":"34-20e3","5⃣":"35-20e3","6⃣":"36-20e3","7⃣":"37-20e3","8⃣":"38-20e3","9⃣":"39-20e3","🅰️":"1f170","🅱️":"1f171","ℹ️":"2139","Ⓜ️":"24c2","🅾️":"1f17e","🅿️":"1f17f","🈂️":"1f202","🈷️":"1f237","㊗️":"3297","㊙️":"3299","◼️":"25fc","◻️":"25fb","▪️":"25aa","▫️":"25ab","🏳️":"1f3f3","🇦🇨":"1f1e6-1f1e8","🇦🇩":"1f1e6-1f1e9","🇦🇪":"1f1e6-1f1ea","🇦🇫":"1f1e6-1f1eb","🇦🇬":"1f1e6-1f1ec","🇦🇮":"1f1e6-1f1ee","🇦🇱":"1f1e6-1f1f1","🇦🇲":"1f1e6-1f1f2","🇦🇴":"1f1e6-1f1f4","🇦🇶":"1f1e6-1f1f6","🇦🇷":"1f1e6-1f1f7","🇦🇸":"1f1e6-1f1f8","🇦🇹":"1f1e6-1f1f9","🇦🇺":"1f1e6-1f1fa","🇦🇼":"1f1e6-1f1fc","🇦🇽":"1f1e6-1f1fd","🇦🇿":"1f1e6-1f1ff","🇧🇦":"1f1e7-1f1e6","🇧🇧":"1f1e7-1f1e7","🇧🇩":"1f1e7-1f1e9","🇧🇪":"1f1e7-1f1ea","🇧🇫":"1f1e7-1f1eb","🇧🇬":"1f1e7-1f1ec","🇧🇭":"1f1e7-1f1ed","🇧🇮":"1f1e7-1f1ee","🇧🇯":"1f1e7-1f1ef","🇧🇱":"1f1e7-1f1f1","🇧🇲":"1f1e7-1f1f2","🇧🇳":"1f1e7-1f1f3","🇧🇴":"1f1e7-1f1f4","🇧🇶":"1f1e7-1f1f6","🇧🇷":"1f1e7-1f1f7","🇧🇸":"1f1e7-1f1f8","🇧🇹":"1f1e7-1f1f9","🇧🇻":"1f1e7-1f1fb","🇧🇼":"1f1e7-1f1fc","🇧🇾":"1f1e7-1f1fe","🇧🇿":"1f1e7-1f1ff","🇨🇦":"1f1e8-1f1e6","🇨🇨":"1f1e8-1f1e8","🇨🇩":"1f1e8-1f1e9","🇨🇫":"1f1e8-1f1eb","🇨🇬":"1f1e8-1f1ec","🇨🇭":"1f1e8-1f1ed","🇨🇮":"1f1e8-1f1ee","🇨🇰":"1f1e8-1f1f0","🇨🇱":"1f1e8-1f1f1","🇨🇲":"1f1e8-1f1f2","🇨🇳":"1f1e8-1f1f3","🇨🇴":"1f1e8-1f1f4","🇨🇵":"1f1e8-1f1f5","🇨🇷":"1f1e8-1f1f7","🇨🇺":"1f1e8-1f1fa","🇨🇻":"1f1e8-1f1fb","🇨🇼":"1f1e8-1f1fc","🇨🇽":"1f1e8-1f1fd","🇨🇾":"1f1e8-1f1fe","🇨🇿":"1f1e8-1f1ff","🇩🇪":"1f1e9-1f1ea","🇩🇬":"1f1e9-1f1ec","🇩🇯":"1f1e9-1f1ef","🇩🇰":"1f1e9-1f1f0","🇩🇲":"1f1e9-1f1f2","🇩🇴":"1f1e9-1f1f4","🇩🇿":"1f1e9-1f1ff","🇪🇦":"1f1ea-1f1e6","🇪🇨":"1f1ea-1f1e8","🇪🇪":"1f1ea-1f1ea","🇪🇬":"1f1ea-1f1ec","🇪🇭":"1f1ea-1f1ed","🇪🇷":"1f1ea-1f1f7","🇪🇸":"1f1ea-1f1f8","🇪🇹":"1f1ea-1f1f9","🇪🇺":"1f1ea-1f1fa","🇫🇮":"1f1eb-1f1ee","🇫🇯":"1f1eb-1f1ef","🇫🇰":"1f1eb-1f1f0","🇫🇲":"1f1eb-1f1f2","🇫🇴":"1f1eb-1f1f4","🇫🇷":"1f1eb-1f1f7","🇬🇦":"1f1ec-1f1e6","🇬🇧":"1f1ec-1f1e7","🇬🇩":"1f1ec-1f1e9","🇬🇪":"1f1ec-1f1ea","🇬🇫":"1f1ec-1f1eb","🇬🇬":"1f1ec-1f1ec","🇬🇭":"1f1ec-1f1ed","🇬🇮":"1f1ec-1f1ee","🇬🇱":"1f1ec-1f1f1","🇬🇲":"1f1ec-1f1f2","🇬🇳":"1f1ec-1f1f3","🇬🇵":"1f1ec-1f1f5","🇬🇶":"1f1ec-1f1f6","🇬🇷":"1f1ec-1f1f7","🇬🇸":"1f1ec-1f1f8","🇬🇹":"1f1ec-1f1f9","🇬🇺":"1f1ec-1f1fa","🇬🇼":"1f1ec-1f1fc","🇬🇾":"1f1ec-1f1fe","🇭🇰":"1f1ed-1f1f0","🇭🇲":"1f1ed-1f1f2","🇭🇳":"1f1ed-1f1f3","🇭🇷":"1f1ed-1f1f7","🇭🇹":"1f1ed-1f1f9","🇭🇺":"1f1ed-1f1fa","🇮🇨":"1f1ee-1f1e8","🇮🇩":"1f1ee-1f1e9","🇮🇪":"1f1ee-1f1ea","🇮🇱":"1f1ee-1f1f1","🇮🇲":"1f1ee-1f1f2","🇮🇳":"1f1ee-1f1f3","🇮🇴":"1f1ee-1f1f4","🇮🇶":"1f1ee-1f1f6","🇮🇷":"1f1ee-1f1f7","🇮🇸":"1f1ee-1f1f8","🇮🇹":"1f1ee-1f1f9","🇯🇪":"1f1ef-1f1ea","🇯🇲":"1f1ef-1f1f2","🇯🇴":"1f1ef-1f1f4","🇯🇵":"1f1ef-1f1f5","🇰🇪":"1f1f0-1f1ea","🇰🇬":"1f1f0-1f1ec","🇰🇭":"1f1f0-1f1ed","🇰🇮":"1f1f0-1f1ee","🇰🇲":"1f1f0-1f1f2","🇰🇳":"1f1f0-1f1f3","🇰🇵":"1f1f0-1f1f5","🇰🇷":"1f1f0-1f1f7","🇰🇼":"1f1f0-1f1fc","🇰🇾":"1f1f0-1f1fe","🇰🇿":"1f1f0-1f1ff","🇱🇦":"1f1f1-1f1e6","🇱🇧":"1f1f1-1f1e7","🇱🇨":"1f1f1-1f1e8","🇱🇮":"1f1f1-1f1ee","🇱🇰":"1f1f1-1f1f0","🇱🇷":"1f1f1-1f1f7","🇱🇸":"1f1f1-1f1f8","🇱🇹":"1f1f1-1f1f9","🇱🇺":"1f1f1-1f1fa","🇱🇻":"1f1f1-1f1fb","🇱🇾":"1f1f1-1f1fe","🇲🇦":"1f1f2-1f1e6","🇲🇨":"1f1f2-1f1e8","🇲🇩":"1f1f2-1f1e9","🇲🇪":"1f1f2-1f1ea","🇲🇫":"1f1f2-1f1eb","🇲🇬":"1f1f2-1f1ec","🇲🇭":"1f1f2-1f1ed","🇲🇰":"1f1f2-1f1f0","🇲🇱":"1f1f2-1f1f1","🇲🇲":"1f1f2-1f1f2","🇲🇳":"1f1f2-1f1f3","🇲🇴":"1f1f2-1f1f4","🇲🇵":"1f1f2-1f1f5","🇲🇶":"1f1f2-1f1f6","🇲🇷":"1f1f2-1f1f7","🇲🇸":"1f1f2-1f1f8","🇲🇹":"1f1f2-1f1f9","🇲🇺":"1f1f2-1f1fa","🇲🇻":"1f1f2-1f1fb","🇲🇼":"1f1f2-1f1fc","🇲🇽":"1f1f2-1f1fd","🇲🇾":"1f1f2-1f1fe","🇲🇿":"1f1f2-1f1ff","🇳🇦":"1f1f3-1f1e6","🇳🇨":"1f1f3-1f1e8","🇳🇪":"1f1f3-1f1ea","🇳🇫":"1f1f3-1f1eb","🇳🇬":"1f1f3-1f1ec","🇳🇮":"1f1f3-1f1ee","🇳🇱":"1f1f3-1f1f1","🇳🇴":"1f1f3-1f1f4","🇳🇵":"1f1f3-1f1f5","🇳🇷":"1f1f3-1f1f7","🇳🇺":"1f1f3-1f1fa","🇳🇿":"1f1f3-1f1ff","🇴🇲":"1f1f4-1f1f2","🇵🇦":"1f1f5-1f1e6","🇵🇪":"1f1f5-1f1ea","🇵🇫":"1f1f5-1f1eb","🇵🇬":"1f1f5-1f1ec","🇵🇭":"1f1f5-1f1ed","🇵🇰":"1f1f5-1f1f0","🇵🇱":"1f1f5-1f1f1","🇵🇲":"1f1f5-1f1f2","🇵🇳":"1f1f5-1f1f3","🇵🇷":"1f1f5-1f1f7","🇵🇸":"1f1f5-1f1f8","🇵🇹":"1f1f5-1f1f9","🇵🇼":"1f1f5-1f1fc","🇵🇾":"1f1f5-1f1fe","🇶🇦":"1f1f6-1f1e6","🇷🇪":"1f1f7-1f1ea","🇷🇴":"1f1f7-1f1f4","🇷🇸":"1f1f7-1f1f8","🇷🇺":"1f1f7-1f1fa","🇷🇼":"1f1f7-1f1fc","🇸🇦":"1f1f8-1f1e6","🇸🇧":"1f1f8-1f1e7","🇸🇨":"1f1f8-1f1e8","🇸🇩":"1f1f8-1f1e9","🇸🇪":"1f1f8-1f1ea","🇸🇬":"1f1f8-1f1ec","🇸🇭":"1f1f8-1f1ed","🇸🇮":"1f1f8-1f1ee","🇸🇯":"1f1f8-1f1ef","🇸🇰":"1f1f8-1f1f0","🇸🇱":"1f1f8-1f1f1","🇸🇲":"1f1f8-1f1f2","🇸🇳":"1f1f8-1f1f3","🇸🇴":"1f1f8-1f1f4","🇸🇷":"1f1f8-1f1f7","🇸🇸":"1f1f8-1f1f8","🇸🇹":"1f1f8-1f1f9","🇸🇻":"1f1f8-1f1fb","🇸🇽":"1f1f8-1f1fd","🇸🇾":"1f1f8-1f1fe","🇸🇿":"1f1f8-1f1ff","🇹🇦":"1f1f9-1f1e6","🇹🇨":"1f1f9-1f1e8","🇹🇩":"1f1f9-1f1e9","🇹🇫":"1f1f9-1f1eb","🇹🇬":"1f1f9-1f1ec","🇹🇭":"1f1f9-1f1ed","🇹🇯":"1f1f9-1f1ef","🇹🇰":"1f1f9-1f1f0","🇹🇱":"1f1f9-1f1f1","🇹🇲":"1f1f9-1f1f2","🇹🇳":"1f1f9-1f1f3","🇹🇴":"1f1f9-1f1f4","🇹🇷":"1f1f9-1f1f7","🇹🇹":"1f1f9-1f1f9","🇹🇻":"1f1f9-1f1fb","🇹🇼":"1f1f9-1f1fc","🇹🇿":"1f1f9-1f1ff","🇺🇦":"1f1fa-1f1e6","🇺🇬":"1f1fa-1f1ec","🇺🇲":"1f1fa-1f1f2","🇺🇳":"1f1fa-1f1f3","🇺🇸":"1f1fa-1f1f8","🇺🇾":"1f1fa-1f1fe","🇺🇿":"1f1fa-1f1ff","🇻🇦":"1f1fb-1f1e6","🇻🇨":"1f1fb-1f1e8","🇻🇪":"1f1fb-1f1ea","🇻🇬":"1f1fb-1f1ec","🇻🇮":"1f1fb-1f1ee","🇻🇳":"1f1fb-1f1f3","🇻🇺":"1f1fb-1f1fa","🇼🇫":"1f1fc-1f1eb","🇼🇸":"1f1fc-1f1f8","🇽🇰":"1f1fd-1f1f0","🇾🇪":"1f1fe-1f1ea","🇾🇹":"1f1fe-1f1f9","🇿🇦":"1f1ff-1f1e6","🇿🇲":"1f1ff-1f1f2","🇿🇼":"1f1ff-1f1fc","😶‍🌫":"1f636-200d-1f32b-fe0f","😮‍💨":"1f62e-200d-1f4a8","😵‍💫":"1f635-200d-1f4ab","❤‍🔥":"2764-fe0f-200d-1f525","❤‍🩹":"2764-fe0f-200d-1fa79","👁‍🗨":"1f441-200d-1f5e8","🧔‍♂":"1f9d4-200d-2642-fe0f","🧔‍♀":"1f9d4-200d-2640-fe0f","👨‍🦰":"1f468-200d-1f9b0","👨‍🦱":"1f468-200d-1f9b1","👨‍🦳":"1f468-200d-1f9b3","👨‍🦲":"1f468-200d-1f9b2","👩‍🦰":"1f469-200d-1f9b0","🧑‍🦰":"1f9d1-200d-1f9b0","👩‍🦱":"1f469-200d-1f9b1","🧑‍🦱":"1f9d1-200d-1f9b1","👩‍🦳":"1f469-200d-1f9b3","🧑‍🦳":"1f9d1-200d-1f9b3","👩‍🦲":"1f469-200d-1f9b2","🧑‍🦲":"1f9d1-200d-1f9b2","👱‍♀":"1f471-200d-2640-fe0f","👱‍♂":"1f471-200d-2642-fe0f","🙍‍♂":"1f64d-200d-2642-fe0f","🙍‍♀":"1f64d-200d-2640-fe0f","🙎‍♂":"1f64e-200d-2642-fe0f","🙎‍♀":"1f64e-200d-2640-fe0f","🙅‍♂":"1f645-200d-2642-fe0f","🙅‍♀":"1f645-200d-2640-fe0f","🙆‍♂":"1f646-200d-2642-fe0f","🙆‍♀":"1f646-200d-2640-fe0f","💁‍♂":"1f481-200d-2642-fe0f","💁‍♀":"1f481-200d-2640-fe0f","🙋‍♂":"1f64b-200d-2642-fe0f","🙋‍♀":"1f64b-200d-2640-fe0f","🧏‍♂":"1f9cf-200d-2642-fe0f","🧏‍♀":"1f9cf-200d-2640-fe0f","🙇‍♂":"1f647-200d-2642-fe0f","🙇‍♀":"1f647-200d-2640-fe0f","🤦‍♂":"1f926-200d-2642-fe0f","🤦‍♀":"1f926-200d-2640-fe0f","🤷‍♂":"1f937-200d-2642-fe0f","🤷‍♀":"1f937-200d-2640-fe0f","🧑‍⚕":"1f9d1-200d-2695-fe0f","👨‍⚕":"1f468-200d-2695-fe0f","👩‍⚕":"1f469-200d-2695-fe0f","🧑‍🎓":"1f9d1-200d-1f393","👨‍🎓":"1f468-200d-1f393","👩‍🎓":"1f469-200d-1f393","🧑‍🏫":"1f9d1-200d-1f3eb","👨‍🏫":"1f468-200d-1f3eb","👩‍🏫":"1f469-200d-1f3eb","🧑‍⚖":"1f9d1-200d-2696-fe0f","👨‍⚖":"1f468-200d-2696-fe0f","👩‍⚖":"1f469-200d-2696-fe0f","🧑‍🌾":"1f9d1-200d-1f33e","👨‍🌾":"1f468-200d-1f33e","👩‍🌾":"1f469-200d-1f33e","🧑‍🍳":"1f9d1-200d-1f373","👨‍🍳":"1f468-200d-1f373","👩‍🍳":"1f469-200d-1f373","🧑‍🔧":"1f9d1-200d-1f527","👨‍🔧":"1f468-200d-1f527","👩‍🔧":"1f469-200d-1f527","🧑‍🏭":"1f9d1-200d-1f3ed","👨‍🏭":"1f468-200d-1f3ed","👩‍🏭":"1f469-200d-1f3ed","🧑‍💼":"1f9d1-200d-1f4bc","👨‍💼":"1f468-200d-1f4bc","👩‍💼":"1f469-200d-1f4bc","🧑‍🔬":"1f9d1-200d-1f52c","👨‍🔬":"1f468-200d-1f52c","👩‍🔬":"1f469-200d-1f52c","🧑‍💻":"1f9d1-200d-1f4bb","👨‍💻":"1f468-200d-1f4bb","👩‍💻":"1f469-200d-1f4bb","🧑‍🎤":"1f9d1-200d-1f3a4","👨‍🎤":"1f468-200d-1f3a4","👩‍🎤":"1f469-200d-1f3a4","🧑‍🎨":"1f9d1-200d-1f3a8","👨‍🎨":"1f468-200d-1f3a8","👩‍🎨":"1f469-200d-1f3a8","🧑‍✈":"1f9d1-200d-2708-fe0f","👨‍✈":"1f468-200d-2708-fe0f","👩‍✈":"1f469-200d-2708-fe0f","🧑‍🚀":"1f9d1-200d-1f680","👨‍🚀":"1f468-200d-1f680","👩‍🚀":"1f469-200d-1f680","🧑‍🚒":"1f9d1-200d-1f692","👨‍🚒":"1f468-200d-1f692","👩‍🚒":"1f469-200d-1f692","👮‍♂":"1f46e-200d-2642-fe0f","👮‍♀":"1f46e-200d-2640-fe0f","🕵‍♂":"1f575-fe0f-200d-2642-fe0f","🕵‍♀":"1f575-fe0f-200d-2640-fe0f","💂‍♂":"1f482-200d-2642-fe0f","💂‍♀":"1f482-200d-2640-fe0f","👷‍♂":"1f477-200d-2642-fe0f","👷‍♀":"1f477-200d-2640-fe0f","👳‍♂":"1f473-200d-2642-fe0f","👳‍♀":"1f473-200d-2640-fe0f","🤵‍♂":"1f935-200d-2642-fe0f","🤵‍♀":"1f935-200d-2640-fe0f","👰‍♂":"1f470-200d-2642-fe0f","👰‍♀":"1f470-200d-2640-fe0f","👩‍🍼":"1f469-200d-1f37c","👨‍🍼":"1f468-200d-1f37c","🧑‍🍼":"1f9d1-200d-1f37c","🧑‍🎄":"1f9d1-200d-1f384","🦸‍♂":"1f9b8-200d-2642-fe0f","🦸‍♀":"1f9b8-200d-2640-fe0f","🦹‍♂":"1f9b9-200d-2642-fe0f","🦹‍♀":"1f9b9-200d-2640-fe0f","🧙‍♂":"1f9d9-200d-2642-fe0f","🧙‍♀":"1f9d9-200d-2640-fe0f","🧚‍♂":"1f9da-200d-2642-fe0f","🧚‍♀":"1f9da-200d-2640-fe0f","🧛‍♂":"1f9db-200d-2642-fe0f","🧛‍♀":"1f9db-200d-2640-fe0f","🧜‍♂":"1f9dc-200d-2642-fe0f","🧜‍♀":"1f9dc-200d-2640-fe0f","🧝‍♂":"1f9dd-200d-2642-fe0f","🧝‍♀":"1f9dd-200d-2640-fe0f","🧞‍♂":"1f9de-200d-2642-fe0f","🧞‍♀":"1f9de-200d-2640-fe0f","🧟‍♂":"1f9df-200d-2642-fe0f","🧟‍♀":"1f9df-200d-2640-fe0f","💆‍♂":"1f486-200d-2642-fe0f","💆‍♀":"1f486-200d-2640-fe0f","💇‍♂":"1f487-200d-2642-fe0f","💇‍♀":"1f487-200d-2640-fe0f","🚶‍♂":"1f6b6-200d-2642-fe0f","🚶‍♀":"1f6b6-200d-2640-fe0f","🧍‍♂":"1f9cd-200d-2642-fe0f","🧍‍♀":"1f9cd-200d-2640-fe0f","🧎‍♂":"1f9ce-200d-2642-fe0f","🧎‍♀":"1f9ce-200d-2640-fe0f","🧑‍🦯":"1f9d1-200d-1f9af","👨‍🦯":"1f468-200d-1f9af","👩‍🦯":"1f469-200d-1f9af","🧑‍🦼":"1f9d1-200d-1f9bc","👨‍🦼":"1f468-200d-1f9bc","👩‍🦼":"1f469-200d-1f9bc","🧑‍🦽":"1f9d1-200d-1f9bd","👨‍🦽":"1f468-200d-1f9bd","👩‍🦽":"1f469-200d-1f9bd","🏃‍♂":"1f3c3-200d-2642-fe0f","🏃‍♀":"1f3c3-200d-2640-fe0f","👯‍♂":"1f46f-200d-2642-fe0f","👯‍♀":"1f46f-200d-2640-fe0f","🧖‍♂":"1f9d6-200d-2642-fe0f","🧖‍♀":"1f9d6-200d-2640-fe0f","🧗‍♂":"1f9d7-200d-2642-fe0f","🧗‍♀":"1f9d7-200d-2640-fe0f","🏌‍♂":"1f3cc-fe0f-200d-2642-fe0f","🏌‍♀":"1f3cc-fe0f-200d-2640-fe0f","🏄‍♂":"1f3c4-200d-2642-fe0f","🏄‍♀":"1f3c4-200d-2640-fe0f","🚣‍♂":"1f6a3-200d-2642-fe0f","🚣‍♀":"1f6a3-200d-2640-fe0f","🏊‍♂":"1f3ca-200d-2642-fe0f","🏊‍♀":"1f3ca-200d-2640-fe0f","⛹‍♂":"26f9-fe0f-200d-2642-fe0f","⛹‍♀":"26f9-fe0f-200d-2640-fe0f","🏋‍♂":"1f3cb-fe0f-200d-2642-fe0f","🏋‍♀":"1f3cb-fe0f-200d-2640-fe0f","🚴‍♂":"1f6b4-200d-2642-fe0f","🚴‍♀":"1f6b4-200d-2640-fe0f","🚵‍♂":"1f6b5-200d-2642-fe0f","🚵‍♀":"1f6b5-200d-2640-fe0f","🤸‍♂":"1f938-200d-2642-fe0f","🤸‍♀":"1f938-200d-2640-fe0f","🤼‍♂":"1f93c-200d-2642-fe0f","🤼‍♀":"1f93c-200d-2640-fe0f","🤽‍♂":"1f93d-200d-2642-fe0f","🤽‍♀":"1f93d-200d-2640-fe0f","🤾‍♂":"1f93e-200d-2642-fe0f","🤾‍♀":"1f93e-200d-2640-fe0f","🤹‍♂":"1f939-200d-2642-fe0f","🤹‍♀":"1f939-200d-2640-fe0f","🧘‍♂":"1f9d8-200d-2642-fe0f","🧘‍♀":"1f9d8-200d-2640-fe0f","👨‍👦":"1f468-200d-1f466","👨‍👧":"1f468-200d-1f467","👩‍👦":"1f469-200d-1f466","👩‍👧":"1f469-200d-1f467","🐕‍🦺":"1f415-200d-1f9ba","🐈‍⬛":"1f408-200d-2b1b","🐻‍❄":"1f43b-200d-2744-fe0f","🐦‍⬛":"1f426-200d-2b1b","#️⃣":"23-20e3","*️⃣":"2a-20e3","0️⃣":"30-20e3","1️⃣":"31-20e3","2️⃣":"32-20e3","3️⃣":"33-20e3","4️⃣":"34-20e3","5️⃣":"35-20e3","6️⃣":"36-20e3","7️⃣":"37-20e3","8️⃣":"38-20e3","9️⃣":"39-20e3","🏳‍🌈":"1f3f3-fe0f-200d-1f308","🏳‍⚧":"1f3f3-fe0f-200d-26a7-fe0f","🏴‍☠":"1f3f4-200d-2620-fe0f","😶‍🌫️":"1f636-200d-1f32b-fe0f","❤️‍🔥":"2764-fe0f-200d-1f525","❤️‍🩹":"2764-fe0f-200d-1fa79","👁‍🗨️":"1f441-200d-1f5e8","👁️‍🗨":"1f441-200d-1f5e8","🧔‍♂️":"1f9d4-200d-2642-fe0f","🧔🏻‍♂":"1f9d4-1f3fb-200d-2642-fe0f","🧔🏼‍♂":"1f9d4-1f3fc-200d-2642-fe0f","🧔🏽‍♂":"1f9d4-1f3fd-200d-2642-fe0f","🧔🏾‍♂":"1f9d4-1f3fe-200d-2642-fe0f","🧔🏿‍♂":"1f9d4-1f3ff-200d-2642-fe0f","🧔‍♀️":"1f9d4-200d-2640-fe0f","🧔🏻‍♀":"1f9d4-1f3fb-200d-2640-fe0f","🧔🏼‍♀":"1f9d4-1f3fc-200d-2640-fe0f","🧔🏽‍♀":"1f9d4-1f3fd-200d-2640-fe0f","🧔🏾‍♀":"1f9d4-1f3fe-200d-2640-fe0f","🧔🏿‍♀":"1f9d4-1f3ff-200d-2640-fe0f","👨🏻‍🦰":"1f468-1f3fb-200d-1f9b0","👨🏼‍🦰":"1f468-1f3fc-200d-1f9b0","👨🏽‍🦰":"1f468-1f3fd-200d-1f9b0","👨🏾‍🦰":"1f468-1f3fe-200d-1f9b0","👨🏿‍🦰":"1f468-1f3ff-200d-1f9b0","👨🏻‍🦱":"1f468-1f3fb-200d-1f9b1","👨🏼‍🦱":"1f468-1f3fc-200d-1f9b1","👨🏽‍🦱":"1f468-1f3fd-200d-1f9b1","👨🏾‍🦱":"1f468-1f3fe-200d-1f9b1","👨🏿‍🦱":"1f468-1f3ff-200d-1f9b1","👨🏻‍🦳":"1f468-1f3fb-200d-1f9b3","👨🏼‍🦳":"1f468-1f3fc-200d-1f9b3","👨🏽‍🦳":"1f468-1f3fd-200d-1f9b3","👨🏾‍🦳":"1f468-1f3fe-200d-1f9b3","👨🏿‍🦳":"1f468-1f3ff-200d-1f9b3","👨🏻‍🦲":"1f468-1f3fb-200d-1f9b2","👨🏼‍🦲":"1f468-1f3fc-200d-1f9b2","👨🏽‍🦲":"1f468-1f3fd-200d-1f9b2","👨🏾‍🦲":"1f468-1f3fe-200d-1f9b2","👨🏿‍🦲":"1f468-1f3ff-200d-1f9b2","👩🏻‍🦰":"1f469-1f3fb-200d-1f9b0","👩🏼‍🦰":"1f469-1f3fc-200d-1f9b0","👩🏽‍🦰":"1f469-1f3fd-200d-1f9b0","👩🏾‍🦰":"1f469-1f3fe-200d-1f9b0","👩🏿‍🦰":"1f469-1f3ff-200d-1f9b0","🧑🏻‍🦰":"1f9d1-1f3fb-200d-1f9b0","🧑🏼‍🦰":"1f9d1-1f3fc-200d-1f9b0","🧑🏽‍🦰":"1f9d1-1f3fd-200d-1f9b0","🧑🏾‍🦰":"1f9d1-1f3fe-200d-1f9b0","🧑🏿‍🦰":"1f9d1-1f3ff-200d-1f9b0","👩🏻‍🦱":"1f469-1f3fb-200d-1f9b1","👩🏼‍🦱":"1f469-1f3fc-200d-1f9b1","👩🏽‍🦱":"1f469-1f3fd-200d-1f9b1","👩🏾‍🦱":"1f469-1f3fe-200d-1f9b1","👩🏿‍🦱":"1f469-1f3ff-200d-1f9b1","🧑🏻‍🦱":"1f9d1-1f3fb-200d-1f9b1","🧑🏼‍🦱":"1f9d1-1f3fc-200d-1f9b1","🧑🏽‍🦱":"1f9d1-1f3fd-200d-1f9b1","🧑🏾‍🦱":"1f9d1-1f3fe-200d-1f9b1","🧑🏿‍🦱":"1f9d1-1f3ff-200d-1f9b1","👩🏻‍🦳":"1f469-1f3fb-200d-1f9b3","👩🏼‍🦳":"1f469-1f3fc-200d-1f9b3","👩🏽‍🦳":"1f469-1f3fd-200d-1f9b3","👩🏾‍🦳":"1f469-1f3fe-200d-1f9b3","👩🏿‍🦳":"1f469-1f3ff-200d-1f9b3","🧑🏻‍🦳":"1f9d1-1f3fb-200d-1f9b3","🧑🏼‍🦳":"1f9d1-1f3fc-200d-1f9b3","🧑🏽‍🦳":"1f9d1-1f3fd-200d-1f9b3","🧑🏾‍🦳":"1f9d1-1f3fe-200d-1f9b3","🧑🏿‍🦳":"1f9d1-1f3ff-200d-1f9b3","👩🏻‍🦲":"1f469-1f3fb-200d-1f9b2","👩🏼‍🦲":"1f469-1f3fc-200d-1f9b2","👩🏽‍🦲":"1f469-1f3fd-200d-1f9b2","👩🏾‍🦲":"1f469-1f3fe-200d-1f9b2","👩🏿‍🦲":"1f469-1f3ff-200d-1f9b2","🧑🏻‍🦲":"1f9d1-1f3fb-200d-1f9b2","🧑🏼‍🦲":"1f9d1-1f3fc-200d-1f9b2","🧑🏽‍🦲":"1f9d1-1f3fd-200d-1f9b2","🧑🏾‍🦲":"1f9d1-1f3fe-200d-1f9b2","🧑🏿‍🦲":"1f9d1-1f3ff-200d-1f9b2","👱‍♀️":"1f471-200d-2640-fe0f","👱🏻‍♀":"1f471-1f3fb-200d-2640-fe0f","👱🏼‍♀":"1f471-1f3fc-200d-2640-fe0f","👱🏽‍♀":"1f471-1f3fd-200d-2640-fe0f","👱🏾‍♀":"1f471-1f3fe-200d-2640-fe0f","👱🏿‍♀":"1f471-1f3ff-200d-2640-fe0f","👱‍♂️":"1f471-200d-2642-fe0f","👱🏻‍♂":"1f471-1f3fb-200d-2642-fe0f","👱🏼‍♂":"1f471-1f3fc-200d-2642-fe0f","👱🏽‍♂":"1f471-1f3fd-200d-2642-fe0f","👱🏾‍♂":"1f471-1f3fe-200d-2642-fe0f","👱🏿‍♂":"1f471-1f3ff-200d-2642-fe0f","🙍‍♂️":"1f64d-200d-2642-fe0f","🙍🏻‍♂":"1f64d-1f3fb-200d-2642-fe0f","🙍🏼‍♂":"1f64d-1f3fc-200d-2642-fe0f","🙍🏽‍♂":"1f64d-1f3fd-200d-2642-fe0f","🙍🏾‍♂":"1f64d-1f3fe-200d-2642-fe0f","🙍🏿‍♂":"1f64d-1f3ff-200d-2642-fe0f","🙍‍♀️":"1f64d-200d-2640-fe0f","🙍🏻‍♀":"1f64d-1f3fb-200d-2640-fe0f","🙍🏼‍♀":"1f64d-1f3fc-200d-2640-fe0f","🙍🏽‍♀":"1f64d-1f3fd-200d-2640-fe0f","🙍🏾‍♀":"1f64d-1f3fe-200d-2640-fe0f","🙍🏿‍♀":"1f64d-1f3ff-200d-2640-fe0f","🙎‍♂️":"1f64e-200d-2642-fe0f","🙎🏻‍♂":"1f64e-1f3fb-200d-2642-fe0f","🙎🏼‍♂":"1f64e-1f3fc-200d-2642-fe0f","🙎🏽‍♂":"1f64e-1f3fd-200d-2642-fe0f","🙎🏾‍♂":"1f64e-1f3fe-200d-2642-fe0f","🙎🏿‍♂":"1f64e-1f3ff-200d-2642-fe0f","🙎‍♀️":"1f64e-200d-2640-fe0f","🙎🏻‍♀":"1f64e-1f3fb-200d-2640-fe0f","🙎🏼‍♀":"1f64e-1f3fc-200d-2640-fe0f","🙎🏽‍♀":"1f64e-1f3fd-200d-2640-fe0f","🙎🏾‍♀":"1f64e-1f3fe-200d-2640-fe0f","🙎🏿‍♀":"1f64e-1f3ff-200d-2640-fe0f","🙅‍♂️":"1f645-200d-2642-fe0f","🙅🏻‍♂":"1f645-1f3fb-200d-2642-fe0f","🙅🏼‍♂":"1f645-1f3fc-200d-2642-fe0f","🙅🏽‍♂":"1f645-1f3fd-200d-2642-fe0f","🙅🏾‍♂":"1f645-1f3fe-200d-2642-fe0f","🙅🏿‍♂":"1f645-1f3ff-200d-2642-fe0f","🙅‍♀️":"1f645-200d-2640-fe0f","🙅🏻‍♀":"1f645-1f3fb-200d-2640-fe0f","🙅🏼‍♀":"1f645-1f3fc-200d-2640-fe0f","🙅🏽‍♀":"1f645-1f3fd-200d-2640-fe0f","🙅🏾‍♀":"1f645-1f3fe-200d-2640-fe0f","🙅🏿‍♀":"1f645-1f3ff-200d-2640-fe0f","🙆‍♂️":"1f646-200d-2642-fe0f","🙆🏻‍♂":"1f646-1f3fb-200d-2642-fe0f","🙆🏼‍♂":"1f646-1f3fc-200d-2642-fe0f","🙆🏽‍♂":"1f646-1f3fd-200d-2642-fe0f","🙆🏾‍♂":"1f646-1f3fe-200d-2642-fe0f","🙆🏿‍♂":"1f646-1f3ff-200d-2642-fe0f","🙆‍♀️":"1f646-200d-2640-fe0f","🙆🏻‍♀":"1f646-1f3fb-200d-2640-fe0f","🙆🏼‍♀":"1f646-1f3fc-200d-2640-fe0f","🙆🏽‍♀":"1f646-1f3fd-200d-2640-fe0f","🙆🏾‍♀":"1f646-1f3fe-200d-2640-fe0f","🙆🏿‍♀":"1f646-1f3ff-200d-2640-fe0f","💁‍♂️":"1f481-200d-2642-fe0f","💁🏻‍♂":"1f481-1f3fb-200d-2642-fe0f","💁🏼‍♂":"1f481-1f3fc-200d-2642-fe0f","💁🏽‍♂":"1f481-1f3fd-200d-2642-fe0f","💁🏾‍♂":"1f481-1f3fe-200d-2642-fe0f","💁🏿‍♂":"1f481-1f3ff-200d-2642-fe0f","💁‍♀️":"1f481-200d-2640-fe0f","💁🏻‍♀":"1f481-1f3fb-200d-2640-fe0f","💁🏼‍♀":"1f481-1f3fc-200d-2640-fe0f","💁🏽‍♀":"1f481-1f3fd-200d-2640-fe0f","💁🏾‍♀":"1f481-1f3fe-200d-2640-fe0f","💁🏿‍♀":"1f481-1f3ff-200d-2640-fe0f","🙋‍♂️":"1f64b-200d-2642-fe0f","🙋🏻‍♂":"1f64b-1f3fb-200d-2642-fe0f","🙋🏼‍♂":"1f64b-1f3fc-200d-2642-fe0f","🙋🏽‍♂":"1f64b-1f3fd-200d-2642-fe0f","🙋🏾‍♂":"1f64b-1f3fe-200d-2642-fe0f","🙋🏿‍♂":"1f64b-1f3ff-200d-2642-fe0f","🙋‍♀️":"1f64b-200d-2640-fe0f","🙋🏻‍♀":"1f64b-1f3fb-200d-2640-fe0f","🙋🏼‍♀":"1f64b-1f3fc-200d-2640-fe0f","🙋🏽‍♀":"1f64b-1f3fd-200d-2640-fe0f","🙋🏾‍♀":"1f64b-1f3fe-200d-2640-fe0f","🙋🏿‍♀":"1f64b-1f3ff-200d-2640-fe0f","🧏‍♂️":"1f9cf-200d-2642-fe0f","🧏🏻‍♂":"1f9cf-1f3fb-200d-2642-fe0f","🧏🏼‍♂":"1f9cf-1f3fc-200d-2642-fe0f","🧏🏽‍♂":"1f9cf-1f3fd-200d-2642-fe0f","🧏🏾‍♂":"1f9cf-1f3fe-200d-2642-fe0f","🧏🏿‍♂":"1f9cf-1f3ff-200d-2642-fe0f","🧏‍♀️":"1f9cf-200d-2640-fe0f","🧏🏻‍♀":"1f9cf-1f3fb-200d-2640-fe0f","🧏🏼‍♀":"1f9cf-1f3fc-200d-2640-fe0f","🧏🏽‍♀":"1f9cf-1f3fd-200d-2640-fe0f","🧏🏾‍♀":"1f9cf-1f3fe-200d-2640-fe0f","🧏🏿‍♀":"1f9cf-1f3ff-200d-2640-fe0f","🙇‍♂️":"1f647-200d-2642-fe0f","🙇🏻‍♂":"1f647-1f3fb-200d-2642-fe0f","🙇🏼‍♂":"1f647-1f3fc-200d-2642-fe0f","🙇🏽‍♂":"1f647-1f3fd-200d-2642-fe0f","🙇🏾‍♂":"1f647-1f3fe-200d-2642-fe0f","🙇🏿‍♂":"1f647-1f3ff-200d-2642-fe0f","🙇‍♀️":"1f647-200d-2640-fe0f","🙇🏻‍♀":"1f647-1f3fb-200d-2640-fe0f","🙇🏼‍♀":"1f647-1f3fc-200d-2640-fe0f","🙇🏽‍♀":"1f647-1f3fd-200d-2640-fe0f","🙇🏾‍♀":"1f647-1f3fe-200d-2640-fe0f","🙇🏿‍♀":"1f647-1f3ff-200d-2640-fe0f","🤦‍♂️":"1f926-200d-2642-fe0f","🤦🏻‍♂":"1f926-1f3fb-200d-2642-fe0f","🤦🏼‍♂":"1f926-1f3fc-200d-2642-fe0f","🤦🏽‍♂":"1f926-1f3fd-200d-2642-fe0f","🤦🏾‍♂":"1f926-1f3fe-200d-2642-fe0f","🤦🏿‍♂":"1f926-1f3ff-200d-2642-fe0f","🤦‍♀️":"1f926-200d-2640-fe0f","🤦🏻‍♀":"1f926-1f3fb-200d-2640-fe0f","🤦🏼‍♀":"1f926-1f3fc-200d-2640-fe0f","🤦🏽‍♀":"1f926-1f3fd-200d-2640-fe0f","🤦🏾‍♀":"1f926-1f3fe-200d-2640-fe0f","🤦🏿‍♀":"1f926-1f3ff-200d-2640-fe0f","🤷‍♂️":"1f937-200d-2642-fe0f","🤷🏻‍♂":"1f937-1f3fb-200d-2642-fe0f","🤷🏼‍♂":"1f937-1f3fc-200d-2642-fe0f","🤷🏽‍♂":"1f937-1f3fd-200d-2642-fe0f","🤷🏾‍♂":"1f937-1f3fe-200d-2642-fe0f","🤷🏿‍♂":"1f937-1f3ff-200d-2642-fe0f","🤷‍♀️":"1f937-200d-2640-fe0f","🤷🏻‍♀":"1f937-1f3fb-200d-2640-fe0f","🤷🏼‍♀":"1f937-1f3fc-200d-2640-fe0f","🤷🏽‍♀":"1f937-1f3fd-200d-2640-fe0f","🤷🏾‍♀":"1f937-1f3fe-200d-2640-fe0f","🤷🏿‍♀":"1f937-1f3ff-200d-2640-fe0f","🧑‍⚕️":"1f9d1-200d-2695-fe0f","🧑🏻‍⚕":"1f9d1-1f3fb-200d-2695-fe0f","🧑🏼‍⚕":"1f9d1-1f3fc-200d-2695-fe0f","🧑🏽‍⚕":"1f9d1-1f3fd-200d-2695-fe0f","🧑🏾‍⚕":"1f9d1-1f3fe-200d-2695-fe0f","🧑🏿‍⚕":"1f9d1-1f3ff-200d-2695-fe0f","👨‍⚕️":"1f468-200d-2695-fe0f","👨🏻‍⚕":"1f468-1f3fb-200d-2695-fe0f","👨🏼‍⚕":"1f468-1f3fc-200d-2695-fe0f","👨🏽‍⚕":"1f468-1f3fd-200d-2695-fe0f","👨🏾‍⚕":"1f468-1f3fe-200d-2695-fe0f","👨🏿‍⚕":"1f468-1f3ff-200d-2695-fe0f","👩‍⚕️":"1f469-200d-2695-fe0f","👩🏻‍⚕":"1f469-1f3fb-200d-2695-fe0f","👩🏼‍⚕":"1f469-1f3fc-200d-2695-fe0f","👩🏽‍⚕":"1f469-1f3fd-200d-2695-fe0f","👩🏾‍⚕":"1f469-1f3fe-200d-2695-fe0f","👩🏿‍⚕":"1f469-1f3ff-200d-2695-fe0f","🧑🏻‍🎓":"1f9d1-1f3fb-200d-1f393","🧑🏼‍🎓":"1f9d1-1f3fc-200d-1f393","🧑🏽‍🎓":"1f9d1-1f3fd-200d-1f393","🧑🏾‍🎓":"1f9d1-1f3fe-200d-1f393","🧑🏿‍🎓":"1f9d1-1f3ff-200d-1f393","👨🏻‍🎓":"1f468-1f3fb-200d-1f393","👨🏼‍🎓":"1f468-1f3fc-200d-1f393","👨🏽‍🎓":"1f468-1f3fd-200d-1f393","👨🏾‍🎓":"1f468-1f3fe-200d-1f393","👨🏿‍🎓":"1f468-1f3ff-200d-1f393","👩🏻‍🎓":"1f469-1f3fb-200d-1f393","👩🏼‍🎓":"1f469-1f3fc-200d-1f393","👩🏽‍🎓":"1f469-1f3fd-200d-1f393","👩🏾‍🎓":"1f469-1f3fe-200d-1f393","👩🏿‍🎓":"1f469-1f3ff-200d-1f393","🧑🏻‍🏫":"1f9d1-1f3fb-200d-1f3eb","🧑🏼‍🏫":"1f9d1-1f3fc-200d-1f3eb","🧑🏽‍🏫":"1f9d1-1f3fd-200d-1f3eb","🧑🏾‍🏫":"1f9d1-1f3fe-200d-1f3eb","🧑🏿‍🏫":"1f9d1-1f3ff-200d-1f3eb","👨🏻‍🏫":"1f468-1f3fb-200d-1f3eb","👨🏼‍🏫":"1f468-1f3fc-200d-1f3eb","👨🏽‍🏫":"1f468-1f3fd-200d-1f3eb","👨🏾‍🏫":"1f468-1f3fe-200d-1f3eb","👨🏿‍🏫":"1f468-1f3ff-200d-1f3eb","👩🏻‍🏫":"1f469-1f3fb-200d-1f3eb","👩🏼‍🏫":"1f469-1f3fc-200d-1f3eb","👩🏽‍🏫":"1f469-1f3fd-200d-1f3eb","👩🏾‍🏫":"1f469-1f3fe-200d-1f3eb","👩🏿‍🏫":"1f469-1f3ff-200d-1f3eb","🧑‍⚖️":"1f9d1-200d-2696-fe0f","🧑🏻‍⚖":"1f9d1-1f3fb-200d-2696-fe0f","🧑🏼‍⚖":"1f9d1-1f3fc-200d-2696-fe0f","🧑🏽‍⚖":"1f9d1-1f3fd-200d-2696-fe0f","🧑🏾‍⚖":"1f9d1-1f3fe-200d-2696-fe0f","🧑🏿‍⚖":"1f9d1-1f3ff-200d-2696-fe0f","👨‍⚖️":"1f468-200d-2696-fe0f","👨🏻‍⚖":"1f468-1f3fb-200d-2696-fe0f","👨🏼‍⚖":"1f468-1f3fc-200d-2696-fe0f","👨🏽‍⚖":"1f468-1f3fd-200d-2696-fe0f","👨🏾‍⚖":"1f468-1f3fe-200d-2696-fe0f","👨🏿‍⚖":"1f468-1f3ff-200d-2696-fe0f","👩‍⚖️":"1f469-200d-2696-fe0f","👩🏻‍⚖":"1f469-1f3fb-200d-2696-fe0f","👩🏼‍⚖":"1f469-1f3fc-200d-2696-fe0f","👩🏽‍⚖":"1f469-1f3fd-200d-2696-fe0f","👩🏾‍⚖":"1f469-1f3fe-200d-2696-fe0f","👩🏿‍⚖":"1f469-1f3ff-200d-2696-fe0f","🧑🏻‍🌾":"1f9d1-1f3fb-200d-1f33e","🧑🏼‍🌾":"1f9d1-1f3fc-200d-1f33e","🧑🏽‍🌾":"1f9d1-1f3fd-200d-1f33e","🧑🏾‍🌾":"1f9d1-1f3fe-200d-1f33e","🧑🏿‍🌾":"1f9d1-1f3ff-200d-1f33e","👨🏻‍🌾":"1f468-1f3fb-200d-1f33e","👨🏼‍🌾":"1f468-1f3fc-200d-1f33e","👨🏽‍🌾":"1f468-1f3fd-200d-1f33e","👨🏾‍🌾":"1f468-1f3fe-200d-1f33e","👨🏿‍🌾":"1f468-1f3ff-200d-1f33e","👩🏻‍🌾":"1f469-1f3fb-200d-1f33e","👩🏼‍🌾":"1f469-1f3fc-200d-1f33e","👩🏽‍🌾":"1f469-1f3fd-200d-1f33e","👩🏾‍🌾":"1f469-1f3fe-200d-1f33e","👩🏿‍🌾":"1f469-1f3ff-200d-1f33e","🧑🏻‍🍳":"1f9d1-1f3fb-200d-1f373","🧑🏼‍🍳":"1f9d1-1f3fc-200d-1f373","🧑🏽‍🍳":"1f9d1-1f3fd-200d-1f373","🧑🏾‍🍳":"1f9d1-1f3fe-200d-1f373","🧑🏿‍🍳":"1f9d1-1f3ff-200d-1f373","👨🏻‍🍳":"1f468-1f3fb-200d-1f373","👨🏼‍🍳":"1f468-1f3fc-200d-1f373","👨🏽‍🍳":"1f468-1f3fd-200d-1f373","👨🏾‍🍳":"1f468-1f3fe-200d-1f373","👨🏿‍🍳":"1f468-1f3ff-200d-1f373","👩🏻‍🍳":"1f469-1f3fb-200d-1f373","👩🏼‍🍳":"1f469-1f3fc-200d-1f373","👩🏽‍🍳":"1f469-1f3fd-200d-1f373","👩🏾‍🍳":"1f469-1f3fe-200d-1f373","👩🏿‍🍳":"1f469-1f3ff-200d-1f373","🧑🏻‍🔧":"1f9d1-1f3fb-200d-1f527","🧑🏼‍🔧":"1f9d1-1f3fc-200d-1f527","🧑🏽‍🔧":"1f9d1-1f3fd-200d-1f527","🧑🏾‍🔧":"1f9d1-1f3fe-200d-1f527","🧑🏿‍🔧":"1f9d1-1f3ff-200d-1f527","👨🏻‍🔧":"1f468-1f3fb-200d-1f527","👨🏼‍🔧":"1f468-1f3fc-200d-1f527","👨🏽‍🔧":"1f468-1f3fd-200d-1f527","👨🏾‍🔧":"1f468-1f3fe-200d-1f527","👨🏿‍🔧":"1f468-1f3ff-200d-1f527","👩🏻‍🔧":"1f469-1f3fb-200d-1f527","👩🏼‍🔧":"1f469-1f3fc-200d-1f527","👩🏽‍🔧":"1f469-1f3fd-200d-1f527","👩🏾‍🔧":"1f469-1f3fe-200d-1f527","👩🏿‍🔧":"1f469-1f3ff-200d-1f527","🧑🏻‍🏭":"1f9d1-1f3fb-200d-1f3ed","🧑🏼‍🏭":"1f9d1-1f3fc-200d-1f3ed","🧑🏽‍🏭":"1f9d1-1f3fd-200d-1f3ed","🧑🏾‍🏭":"1f9d1-1f3fe-200d-1f3ed","🧑🏿‍🏭":"1f9d1-1f3ff-200d-1f3ed","👨🏻‍🏭":"1f468-1f3fb-200d-1f3ed","👨🏼‍🏭":"1f468-1f3fc-200d-1f3ed","👨🏽‍🏭":"1f468-1f3fd-200d-1f3ed","👨🏾‍🏭":"1f468-1f3fe-200d-1f3ed","👨🏿‍🏭":"1f468-1f3ff-200d-1f3ed","👩🏻‍🏭":"1f469-1f3fb-200d-1f3ed","👩🏼‍🏭":"1f469-1f3fc-200d-1f3ed","👩🏽‍🏭":"1f469-1f3fd-200d-1f3ed","👩🏾‍🏭":"1f469-1f3fe-200d-1f3ed","👩🏿‍🏭":"1f469-1f3ff-200d-1f3ed","🧑🏻‍💼":"1f9d1-1f3fb-200d-1f4bc","🧑🏼‍💼":"1f9d1-1f3fc-200d-1f4bc","🧑🏽‍💼":"1f9d1-1f3fd-200d-1f4bc","🧑🏾‍💼":"1f9d1-1f3fe-200d-1f4bc","🧑🏿‍💼":"1f9d1-1f3ff-200d-1f4bc","👨🏻‍💼":"1f468-1f3fb-200d-1f4bc","👨🏼‍💼":"1f468-1f3fc-200d-1f4bc","👨🏽‍💼":"1f468-1f3fd-200d-1f4bc","👨🏾‍💼":"1f468-1f3fe-200d-1f4bc","👨🏿‍💼":"1f468-1f3ff-200d-1f4bc","👩🏻‍💼":"1f469-1f3fb-200d-1f4bc","👩🏼‍💼":"1f469-1f3fc-200d-1f4bc","👩🏽‍💼":"1f469-1f3fd-200d-1f4bc","👩🏾‍💼":"1f469-1f3fe-200d-1f4bc","👩🏿‍💼":"1f469-1f3ff-200d-1f4bc","🧑🏻‍🔬":"1f9d1-1f3fb-200d-1f52c","🧑🏼‍🔬":"1f9d1-1f3fc-200d-1f52c","🧑🏽‍🔬":"1f9d1-1f3fd-200d-1f52c","🧑🏾‍🔬":"1f9d1-1f3fe-200d-1f52c","🧑🏿‍🔬":"1f9d1-1f3ff-200d-1f52c","👨🏻‍🔬":"1f468-1f3fb-200d-1f52c","👨🏼‍🔬":"1f468-1f3fc-200d-1f52c","👨🏽‍🔬":"1f468-1f3fd-200d-1f52c","👨🏾‍🔬":"1f468-1f3fe-200d-1f52c","👨🏿‍🔬":"1f468-1f3ff-200d-1f52c","👩🏻‍🔬":"1f469-1f3fb-200d-1f52c","👩🏼‍🔬":"1f469-1f3fc-200d-1f52c","👩🏽‍🔬":"1f469-1f3fd-200d-1f52c","👩🏾‍🔬":"1f469-1f3fe-200d-1f52c","👩🏿‍🔬":"1f469-1f3ff-200d-1f52c","🧑🏻‍💻":"1f9d1-1f3fb-200d-1f4bb","🧑🏼‍💻":"1f9d1-1f3fc-200d-1f4bb","🧑🏽‍💻":"1f9d1-1f3fd-200d-1f4bb","🧑🏾‍💻":"1f9d1-1f3fe-200d-1f4bb","🧑🏿‍💻":"1f9d1-1f3ff-200d-1f4bb","👨🏻‍💻":"1f468-1f3fb-200d-1f4bb","👨🏼‍💻":"1f468-1f3fc-200d-1f4bb","👨🏽‍💻":"1f468-1f3fd-200d-1f4bb","👨🏾‍💻":"1f468-1f3fe-200d-1f4bb","👨🏿‍💻":"1f468-1f3ff-200d-1f4bb","👩🏻‍💻":"1f469-1f3fb-200d-1f4bb","👩🏼‍💻":"1f469-1f3fc-200d-1f4bb","👩🏽‍💻":"1f469-1f3fd-200d-1f4bb","👩🏾‍💻":"1f469-1f3fe-200d-1f4bb","👩🏿‍💻":"1f469-1f3ff-200d-1f4bb","🧑🏻‍🎤":"1f9d1-1f3fb-200d-1f3a4","🧑🏼‍🎤":"1f9d1-1f3fc-200d-1f3a4","🧑🏽‍🎤":"1f9d1-1f3fd-200d-1f3a4","🧑🏾‍🎤":"1f9d1-1f3fe-200d-1f3a4","🧑🏿‍🎤":"1f9d1-1f3ff-200d-1f3a4","👨🏻‍🎤":"1f468-1f3fb-200d-1f3a4","👨🏼‍🎤":"1f468-1f3fc-200d-1f3a4","👨🏽‍🎤":"1f468-1f3fd-200d-1f3a4","👨🏾‍🎤":"1f468-1f3fe-200d-1f3a4","👨🏿‍🎤":"1f468-1f3ff-200d-1f3a4","👩🏻‍🎤":"1f469-1f3fb-200d-1f3a4","👩🏼‍🎤":"1f469-1f3fc-200d-1f3a4","👩🏽‍🎤":"1f469-1f3fd-200d-1f3a4","👩🏾‍🎤":"1f469-1f3fe-200d-1f3a4","👩🏿‍🎤":"1f469-1f3ff-200d-1f3a4","🧑🏻‍🎨":"1f9d1-1f3fb-200d-1f3a8","🧑🏼‍🎨":"1f9d1-1f3fc-200d-1f3a8","🧑🏽‍🎨":"1f9d1-1f3fd-200d-1f3a8","🧑🏾‍🎨":"1f9d1-1f3fe-200d-1f3a8","🧑🏿‍🎨":"1f9d1-1f3ff-200d-1f3a8","👨🏻‍🎨":"1f468-1f3fb-200d-1f3a8","👨🏼‍🎨":"1f468-1f3fc-200d-1f3a8","👨🏽‍🎨":"1f468-1f3fd-200d-1f3a8","👨🏾‍🎨":"1f468-1f3fe-200d-1f3a8","👨🏿‍🎨":"1f468-1f3ff-200d-1f3a8","👩🏻‍🎨":"1f469-1f3fb-200d-1f3a8","👩🏼‍🎨":"1f469-1f3fc-200d-1f3a8","👩🏽‍🎨":"1f469-1f3fd-200d-1f3a8","👩🏾‍🎨":"1f469-1f3fe-200d-1f3a8","👩🏿‍🎨":"1f469-1f3ff-200d-1f3a8","🧑‍✈️":"1f9d1-200d-2708-fe0f","🧑🏻‍✈":"1f9d1-1f3fb-200d-2708-fe0f","🧑🏼‍✈":"1f9d1-1f3fc-200d-2708-fe0f","🧑🏽‍✈":"1f9d1-1f3fd-200d-2708-fe0f","🧑🏾‍✈":"1f9d1-1f3fe-200d-2708-fe0f","🧑🏿‍✈":"1f9d1-1f3ff-200d-2708-fe0f","👨‍✈️":"1f468-200d-2708-fe0f","👨🏻‍✈":"1f468-1f3fb-200d-2708-fe0f","👨🏼‍✈":"1f468-1f3fc-200d-2708-fe0f","👨🏽‍✈":"1f468-1f3fd-200d-2708-fe0f","👨🏾‍✈":"1f468-1f3fe-200d-2708-fe0f","👨🏿‍✈":"1f468-1f3ff-200d-2708-fe0f","👩‍✈️":"1f469-200d-2708-fe0f","👩🏻‍✈":"1f469-1f3fb-200d-2708-fe0f","👩🏼‍✈":"1f469-1f3fc-200d-2708-fe0f","👩🏽‍✈":"1f469-1f3fd-200d-2708-fe0f","👩🏾‍✈":"1f469-1f3fe-200d-2708-fe0f","👩🏿‍✈":"1f469-1f3ff-200d-2708-fe0f","🧑🏻‍🚀":"1f9d1-1f3fb-200d-1f680","🧑🏼‍🚀":"1f9d1-1f3fc-200d-1f680","🧑🏽‍🚀":"1f9d1-1f3fd-200d-1f680","🧑🏾‍🚀":"1f9d1-1f3fe-200d-1f680","🧑🏿‍🚀":"1f9d1-1f3ff-200d-1f680","👨🏻‍🚀":"1f468-1f3fb-200d-1f680","👨🏼‍🚀":"1f468-1f3fc-200d-1f680","👨🏽‍🚀":"1f468-1f3fd-200d-1f680","👨🏾‍🚀":"1f468-1f3fe-200d-1f680","👨🏿‍🚀":"1f468-1f3ff-200d-1f680","👩🏻‍🚀":"1f469-1f3fb-200d-1f680","👩🏼‍🚀":"1f469-1f3fc-200d-1f680","👩🏽‍🚀":"1f469-1f3fd-200d-1f680","👩🏾‍🚀":"1f469-1f3fe-200d-1f680","👩🏿‍🚀":"1f469-1f3ff-200d-1f680","🧑🏻‍🚒":"1f9d1-1f3fb-200d-1f692","🧑🏼‍🚒":"1f9d1-1f3fc-200d-1f692","🧑🏽‍🚒":"1f9d1-1f3fd-200d-1f692","🧑🏾‍🚒":"1f9d1-1f3fe-200d-1f692","🧑🏿‍🚒":"1f9d1-1f3ff-200d-1f692","👨🏻‍🚒":"1f468-1f3fb-200d-1f692","👨🏼‍🚒":"1f468-1f3fc-200d-1f692","👨🏽‍🚒":"1f468-1f3fd-200d-1f692","👨🏾‍🚒":"1f468-1f3fe-200d-1f692","👨🏿‍🚒":"1f468-1f3ff-200d-1f692","👩🏻‍🚒":"1f469-1f3fb-200d-1f692","👩🏼‍🚒":"1f469-1f3fc-200d-1f692","👩🏽‍🚒":"1f469-1f3fd-200d-1f692","👩🏾‍🚒":"1f469-1f3fe-200d-1f692","👩🏿‍🚒":"1f469-1f3ff-200d-1f692","👮‍♂️":"1f46e-200d-2642-fe0f","👮🏻‍♂":"1f46e-1f3fb-200d-2642-fe0f","👮🏼‍♂":"1f46e-1f3fc-200d-2642-fe0f","👮🏽‍♂":"1f46e-1f3fd-200d-2642-fe0f","👮🏾‍♂":"1f46e-1f3fe-200d-2642-fe0f","👮🏿‍♂":"1f46e-1f3ff-200d-2642-fe0f","👮‍♀️":"1f46e-200d-2640-fe0f","👮🏻‍♀":"1f46e-1f3fb-200d-2640-fe0f","👮🏼‍♀":"1f46e-1f3fc-200d-2640-fe0f","👮🏽‍♀":"1f46e-1f3fd-200d-2640-fe0f","👮🏾‍♀":"1f46e-1f3fe-200d-2640-fe0f","👮🏿‍♀":"1f46e-1f3ff-200d-2640-fe0f","🕵‍♂️":"1f575-fe0f-200d-2642-fe0f","🕵️‍♂":"1f575-fe0f-200d-2642-fe0f","🕵🏻‍♂":"1f575-1f3fb-200d-2642-fe0f","🕵🏼‍♂":"1f575-1f3fc-200d-2642-fe0f","🕵🏽‍♂":"1f575-1f3fd-200d-2642-fe0f","🕵🏾‍♂":"1f575-1f3fe-200d-2642-fe0f","🕵🏿‍♂":"1f575-1f3ff-200d-2642-fe0f","🕵‍♀️":"1f575-fe0f-200d-2640-fe0f","🕵️‍♀":"1f575-fe0f-200d-2640-fe0f","🕵🏻‍♀":"1f575-1f3fb-200d-2640-fe0f","🕵🏼‍♀":"1f575-1f3fc-200d-2640-fe0f","🕵🏽‍♀":"1f575-1f3fd-200d-2640-fe0f","🕵🏾‍♀":"1f575-1f3fe-200d-2640-fe0f","🕵🏿‍♀":"1f575-1f3ff-200d-2640-fe0f","💂‍♂️":"1f482-200d-2642-fe0f","💂🏻‍♂":"1f482-1f3fb-200d-2642-fe0f","💂🏼‍♂":"1f482-1f3fc-200d-2642-fe0f","💂🏽‍♂":"1f482-1f3fd-200d-2642-fe0f","💂🏾‍♂":"1f482-1f3fe-200d-2642-fe0f","💂🏿‍♂":"1f482-1f3ff-200d-2642-fe0f","💂‍♀️":"1f482-200d-2640-fe0f","💂🏻‍♀":"1f482-1f3fb-200d-2640-fe0f","💂🏼‍♀":"1f482-1f3fc-200d-2640-fe0f","💂🏽‍♀":"1f482-1f3fd-200d-2640-fe0f","💂🏾‍♀":"1f482-1f3fe-200d-2640-fe0f","💂🏿‍♀":"1f482-1f3ff-200d-2640-fe0f","👷‍♂️":"1f477-200d-2642-fe0f","👷🏻‍♂":"1f477-1f3fb-200d-2642-fe0f","👷🏼‍♂":"1f477-1f3fc-200d-2642-fe0f","👷🏽‍♂":"1f477-1f3fd-200d-2642-fe0f","👷🏾‍♂":"1f477-1f3fe-200d-2642-fe0f","👷🏿‍♂":"1f477-1f3ff-200d-2642-fe0f","👷‍♀️":"1f477-200d-2640-fe0f","👷🏻‍♀":"1f477-1f3fb-200d-2640-fe0f","👷🏼‍♀":"1f477-1f3fc-200d-2640-fe0f","👷🏽‍♀":"1f477-1f3fd-200d-2640-fe0f","👷🏾‍♀":"1f477-1f3fe-200d-2640-fe0f","👷🏿‍♀":"1f477-1f3ff-200d-2640-fe0f","👳‍♂️":"1f473-200d-2642-fe0f","👳🏻‍♂":"1f473-1f3fb-200d-2642-fe0f","👳🏼‍♂":"1f473-1f3fc-200d-2642-fe0f","👳🏽‍♂":"1f473-1f3fd-200d-2642-fe0f","👳🏾‍♂":"1f473-1f3fe-200d-2642-fe0f","👳🏿‍♂":"1f473-1f3ff-200d-2642-fe0f","👳‍♀️":"1f473-200d-2640-fe0f","👳🏻‍♀":"1f473-1f3fb-200d-2640-fe0f","👳🏼‍♀":"1f473-1f3fc-200d-2640-fe0f","👳🏽‍♀":"1f473-1f3fd-200d-2640-fe0f","👳🏾‍♀":"1f473-1f3fe-200d-2640-fe0f","👳🏿‍♀":"1f473-1f3ff-200d-2640-fe0f","🤵‍♂️":"1f935-200d-2642-fe0f","🤵🏻‍♂":"1f935-1f3fb-200d-2642-fe0f","🤵🏼‍♂":"1f935-1f3fc-200d-2642-fe0f","🤵🏽‍♂":"1f935-1f3fd-200d-2642-fe0f","🤵🏾‍♂":"1f935-1f3fe-200d-2642-fe0f","🤵🏿‍♂":"1f935-1f3ff-200d-2642-fe0f","🤵‍♀️":"1f935-200d-2640-fe0f","🤵🏻‍♀":"1f935-1f3fb-200d-2640-fe0f","🤵🏼‍♀":"1f935-1f3fc-200d-2640-fe0f","🤵🏽‍♀":"1f935-1f3fd-200d-2640-fe0f","🤵🏾‍♀":"1f935-1f3fe-200d-2640-fe0f","🤵🏿‍♀":"1f935-1f3ff-200d-2640-fe0f","👰‍♂️":"1f470-200d-2642-fe0f","👰🏻‍♂":"1f470-1f3fb-200d-2642-fe0f","👰🏼‍♂":"1f470-1f3fc-200d-2642-fe0f","👰🏽‍♂":"1f470-1f3fd-200d-2642-fe0f","👰🏾‍♂":"1f470-1f3fe-200d-2642-fe0f","👰🏿‍♂":"1f470-1f3ff-200d-2642-fe0f","👰‍♀️":"1f470-200d-2640-fe0f","👰🏻‍♀":"1f470-1f3fb-200d-2640-fe0f","👰🏼‍♀":"1f470-1f3fc-200d-2640-fe0f","👰🏽‍♀":"1f470-1f3fd-200d-2640-fe0f","👰🏾‍♀":"1f470-1f3fe-200d-2640-fe0f","👰🏿‍♀":"1f470-1f3ff-200d-2640-fe0f","👩🏻‍🍼":"1f469-1f3fb-200d-1f37c","👩🏼‍🍼":"1f469-1f3fc-200d-1f37c","👩🏽‍🍼":"1f469-1f3fd-200d-1f37c","👩🏾‍🍼":"1f469-1f3fe-200d-1f37c","👩🏿‍🍼":"1f469-1f3ff-200d-1f37c","👨🏻‍🍼":"1f468-1f3fb-200d-1f37c","👨🏼‍🍼":"1f468-1f3fc-200d-1f37c","👨🏽‍🍼":"1f468-1f3fd-200d-1f37c","👨🏾‍🍼":"1f468-1f3fe-200d-1f37c","👨🏿‍🍼":"1f468-1f3ff-200d-1f37c","🧑🏻‍🍼":"1f9d1-1f3fb-200d-1f37c","🧑🏼‍🍼":"1f9d1-1f3fc-200d-1f37c","🧑🏽‍🍼":"1f9d1-1f3fd-200d-1f37c","🧑🏾‍🍼":"1f9d1-1f3fe-200d-1f37c","🧑🏿‍🍼":"1f9d1-1f3ff-200d-1f37c","🧑🏻‍🎄":"1f9d1-1f3fb-200d-1f384","🧑🏼‍🎄":"1f9d1-1f3fc-200d-1f384","🧑🏽‍🎄":"1f9d1-1f3fd-200d-1f384","🧑🏾‍🎄":"1f9d1-1f3fe-200d-1f384","🧑🏿‍🎄":"1f9d1-1f3ff-200d-1f384","🦸‍♂️":"1f9b8-200d-2642-fe0f","🦸🏻‍♂":"1f9b8-1f3fb-200d-2642-fe0f","🦸🏼‍♂":"1f9b8-1f3fc-200d-2642-fe0f","🦸🏽‍♂":"1f9b8-1f3fd-200d-2642-fe0f","🦸🏾‍♂":"1f9b8-1f3fe-200d-2642-fe0f","🦸🏿‍♂":"1f9b8-1f3ff-200d-2642-fe0f","🦸‍♀️":"1f9b8-200d-2640-fe0f","🦸🏻‍♀":"1f9b8-1f3fb-200d-2640-fe0f","🦸🏼‍♀":"1f9b8-1f3fc-200d-2640-fe0f","🦸🏽‍♀":"1f9b8-1f3fd-200d-2640-fe0f","🦸🏾‍♀":"1f9b8-1f3fe-200d-2640-fe0f","🦸🏿‍♀":"1f9b8-1f3ff-200d-2640-fe0f","🦹‍♂️":"1f9b9-200d-2642-fe0f","🦹🏻‍♂":"1f9b9-1f3fb-200d-2642-fe0f","🦹🏼‍♂":"1f9b9-1f3fc-200d-2642-fe0f","🦹🏽‍♂":"1f9b9-1f3fd-200d-2642-fe0f","🦹🏾‍♂":"1f9b9-1f3fe-200d-2642-fe0f","🦹🏿‍♂":"1f9b9-1f3ff-200d-2642-fe0f","🦹‍♀️":"1f9b9-200d-2640-fe0f","🦹🏻‍♀":"1f9b9-1f3fb-200d-2640-fe0f","🦹🏼‍♀":"1f9b9-1f3fc-200d-2640-fe0f","🦹🏽‍♀":"1f9b9-1f3fd-200d-2640-fe0f","🦹🏾‍♀":"1f9b9-1f3fe-200d-2640-fe0f","🦹🏿‍♀":"1f9b9-1f3ff-200d-2640-fe0f","🧙‍♂️":"1f9d9-200d-2642-fe0f","🧙🏻‍♂":"1f9d9-1f3fb-200d-2642-fe0f","🧙🏼‍♂":"1f9d9-1f3fc-200d-2642-fe0f","🧙🏽‍♂":"1f9d9-1f3fd-200d-2642-fe0f","🧙🏾‍♂":"1f9d9-1f3fe-200d-2642-fe0f","🧙🏿‍♂":"1f9d9-1f3ff-200d-2642-fe0f","🧙‍♀️":"1f9d9-200d-2640-fe0f","🧙🏻‍♀":"1f9d9-1f3fb-200d-2640-fe0f","🧙🏼‍♀":"1f9d9-1f3fc-200d-2640-fe0f","🧙🏽‍♀":"1f9d9-1f3fd-200d-2640-fe0f","🧙🏾‍♀":"1f9d9-1f3fe-200d-2640-fe0f","🧙🏿‍♀":"1f9d9-1f3ff-200d-2640-fe0f","🧚‍♂️":"1f9da-200d-2642-fe0f","🧚🏻‍♂":"1f9da-1f3fb-200d-2642-fe0f","🧚🏼‍♂":"1f9da-1f3fc-200d-2642-fe0f","🧚🏽‍♂":"1f9da-1f3fd-200d-2642-fe0f","🧚🏾‍♂":"1f9da-1f3fe-200d-2642-fe0f","🧚🏿‍♂":"1f9da-1f3ff-200d-2642-fe0f","🧚‍♀️":"1f9da-200d-2640-fe0f","🧚🏻‍♀":"1f9da-1f3fb-200d-2640-fe0f","🧚🏼‍♀":"1f9da-1f3fc-200d-2640-fe0f","🧚🏽‍♀":"1f9da-1f3fd-200d-2640-fe0f","🧚🏾‍♀":"1f9da-1f3fe-200d-2640-fe0f","🧚🏿‍♀":"1f9da-1f3ff-200d-2640-fe0f","🧛‍♂️":"1f9db-200d-2642-fe0f","🧛🏻‍♂":"1f9db-1f3fb-200d-2642-fe0f","🧛🏼‍♂":"1f9db-1f3fc-200d-2642-fe0f","🧛🏽‍♂":"1f9db-1f3fd-200d-2642-fe0f","🧛🏾‍♂":"1f9db-1f3fe-200d-2642-fe0f","🧛🏿‍♂":"1f9db-1f3ff-200d-2642-fe0f","🧛‍♀️":"1f9db-200d-2640-fe0f","🧛🏻‍♀":"1f9db-1f3fb-200d-2640-fe0f","🧛🏼‍♀":"1f9db-1f3fc-200d-2640-fe0f","🧛🏽‍♀":"1f9db-1f3fd-200d-2640-fe0f","🧛🏾‍♀":"1f9db-1f3fe-200d-2640-fe0f","🧛🏿‍♀":"1f9db-1f3ff-200d-2640-fe0f","🧜‍♂️":"1f9dc-200d-2642-fe0f","🧜🏻‍♂":"1f9dc-1f3fb-200d-2642-fe0f","🧜🏼‍♂":"1f9dc-1f3fc-200d-2642-fe0f","🧜🏽‍♂":"1f9dc-1f3fd-200d-2642-fe0f","🧜🏾‍♂":"1f9dc-1f3fe-200d-2642-fe0f","🧜🏿‍♂":"1f9dc-1f3ff-200d-2642-fe0f","🧜‍♀️":"1f9dc-200d-2640-fe0f","🧜🏻‍♀":"1f9dc-1f3fb-200d-2640-fe0f","🧜🏼‍♀":"1f9dc-1f3fc-200d-2640-fe0f","🧜🏽‍♀":"1f9dc-1f3fd-200d-2640-fe0f","🧜🏾‍♀":"1f9dc-1f3fe-200d-2640-fe0f","🧜🏿‍♀":"1f9dc-1f3ff-200d-2640-fe0f","🧝‍♂️":"1f9dd-200d-2642-fe0f","🧝🏻‍♂":"1f9dd-1f3fb-200d-2642-fe0f","🧝🏼‍♂":"1f9dd-1f3fc-200d-2642-fe0f","🧝🏽‍♂":"1f9dd-1f3fd-200d-2642-fe0f","🧝🏾‍♂":"1f9dd-1f3fe-200d-2642-fe0f","🧝🏿‍♂":"1f9dd-1f3ff-200d-2642-fe0f","🧝‍♀️":"1f9dd-200d-2640-fe0f","🧝🏻‍♀":"1f9dd-1f3fb-200d-2640-fe0f","🧝🏼‍♀":"1f9dd-1f3fc-200d-2640-fe0f","🧝🏽‍♀":"1f9dd-1f3fd-200d-2640-fe0f","🧝🏾‍♀":"1f9dd-1f3fe-200d-2640-fe0f","🧝🏿‍♀":"1f9dd-1f3ff-200d-2640-fe0f","🧞‍♂️":"1f9de-200d-2642-fe0f","🧞‍♀️":"1f9de-200d-2640-fe0f","🧟‍♂️":"1f9df-200d-2642-fe0f","🧟‍♀️":"1f9df-200d-2640-fe0f","💆‍♂️":"1f486-200d-2642-fe0f","💆🏻‍♂":"1f486-1f3fb-200d-2642-fe0f","💆🏼‍♂":"1f486-1f3fc-200d-2642-fe0f","💆🏽‍♂":"1f486-1f3fd-200d-2642-fe0f","💆🏾‍♂":"1f486-1f3fe-200d-2642-fe0f","💆🏿‍♂":"1f486-1f3ff-200d-2642-fe0f","💆‍♀️":"1f486-200d-2640-fe0f","💆🏻‍♀":"1f486-1f3fb-200d-2640-fe0f","💆🏼‍♀":"1f486-1f3fc-200d-2640-fe0f","💆🏽‍♀":"1f486-1f3fd-200d-2640-fe0f","💆🏾‍♀":"1f486-1f3fe-200d-2640-fe0f","💆🏿‍♀":"1f486-1f3ff-200d-2640-fe0f","💇‍♂️":"1f487-200d-2642-fe0f","💇🏻‍♂":"1f487-1f3fb-200d-2642-fe0f","💇🏼‍♂":"1f487-1f3fc-200d-2642-fe0f","💇🏽‍♂":"1f487-1f3fd-200d-2642-fe0f","💇🏾‍♂":"1f487-1f3fe-200d-2642-fe0f","💇🏿‍♂":"1f487-1f3ff-200d-2642-fe0f","💇‍♀️":"1f487-200d-2640-fe0f","💇🏻‍♀":"1f487-1f3fb-200d-2640-fe0f","💇🏼‍♀":"1f487-1f3fc-200d-2640-fe0f","💇🏽‍♀":"1f487-1f3fd-200d-2640-fe0f","💇🏾‍♀":"1f487-1f3fe-200d-2640-fe0f","💇🏿‍♀":"1f487-1f3ff-200d-2640-fe0f","🚶‍♂️":"1f6b6-200d-2642-fe0f","🚶🏻‍♂":"1f6b6-1f3fb-200d-2642-fe0f","🚶🏼‍♂":"1f6b6-1f3fc-200d-2642-fe0f","🚶🏽‍♂":"1f6b6-1f3fd-200d-2642-fe0f","🚶🏾‍♂":"1f6b6-1f3fe-200d-2642-fe0f","🚶🏿‍♂":"1f6b6-1f3ff-200d-2642-fe0f","🚶‍♀️":"1f6b6-200d-2640-fe0f","🚶🏻‍♀":"1f6b6-1f3fb-200d-2640-fe0f","🚶🏼‍♀":"1f6b6-1f3fc-200d-2640-fe0f","🚶🏽‍♀":"1f6b6-1f3fd-200d-2640-fe0f","🚶🏾‍♀":"1f6b6-1f3fe-200d-2640-fe0f","🚶🏿‍♀":"1f6b6-1f3ff-200d-2640-fe0f","🧍‍♂️":"1f9cd-200d-2642-fe0f","🧍🏻‍♂":"1f9cd-1f3fb-200d-2642-fe0f","🧍🏼‍♂":"1f9cd-1f3fc-200d-2642-fe0f","🧍🏽‍♂":"1f9cd-1f3fd-200d-2642-fe0f","🧍🏾‍♂":"1f9cd-1f3fe-200d-2642-fe0f","🧍🏿‍♂":"1f9cd-1f3ff-200d-2642-fe0f","🧍‍♀️":"1f9cd-200d-2640-fe0f","🧍🏻‍♀":"1f9cd-1f3fb-200d-2640-fe0f","🧍🏼‍♀":"1f9cd-1f3fc-200d-2640-fe0f","🧍🏽‍♀":"1f9cd-1f3fd-200d-2640-fe0f","🧍🏾‍♀":"1f9cd-1f3fe-200d-2640-fe0f","🧍🏿‍♀":"1f9cd-1f3ff-200d-2640-fe0f","🧎‍♂️":"1f9ce-200d-2642-fe0f","🧎🏻‍♂":"1f9ce-1f3fb-200d-2642-fe0f","🧎🏼‍♂":"1f9ce-1f3fc-200d-2642-fe0f","🧎🏽‍♂":"1f9ce-1f3fd-200d-2642-fe0f","🧎🏾‍♂":"1f9ce-1f3fe-200d-2642-fe0f","🧎🏿‍♂":"1f9ce-1f3ff-200d-2642-fe0f","🧎‍♀️":"1f9ce-200d-2640-fe0f","🧎🏻‍♀":"1f9ce-1f3fb-200d-2640-fe0f","🧎🏼‍♀":"1f9ce-1f3fc-200d-2640-fe0f","🧎🏽‍♀":"1f9ce-1f3fd-200d-2640-fe0f","🧎🏾‍♀":"1f9ce-1f3fe-200d-2640-fe0f","🧎🏿‍♀":"1f9ce-1f3ff-200d-2640-fe0f","🧑🏻‍🦯":"1f9d1-1f3fb-200d-1f9af","🧑🏼‍🦯":"1f9d1-1f3fc-200d-1f9af","🧑🏽‍🦯":"1f9d1-1f3fd-200d-1f9af","🧑🏾‍🦯":"1f9d1-1f3fe-200d-1f9af","🧑🏿‍🦯":"1f9d1-1f3ff-200d-1f9af","👨🏻‍🦯":"1f468-1f3fb-200d-1f9af","👨🏼‍🦯":"1f468-1f3fc-200d-1f9af","👨🏽‍🦯":"1f468-1f3fd-200d-1f9af","👨🏾‍🦯":"1f468-1f3fe-200d-1f9af","👨🏿‍🦯":"1f468-1f3ff-200d-1f9af","👩🏻‍🦯":"1f469-1f3fb-200d-1f9af","👩🏼‍🦯":"1f469-1f3fc-200d-1f9af","👩🏽‍🦯":"1f469-1f3fd-200d-1f9af","👩🏾‍🦯":"1f469-1f3fe-200d-1f9af","👩🏿‍🦯":"1f469-1f3ff-200d-1f9af","🧑🏻‍🦼":"1f9d1-1f3fb-200d-1f9bc","🧑🏼‍🦼":"1f9d1-1f3fc-200d-1f9bc","🧑🏽‍🦼":"1f9d1-1f3fd-200d-1f9bc","🧑🏾‍🦼":"1f9d1-1f3fe-200d-1f9bc","🧑🏿‍🦼":"1f9d1-1f3ff-200d-1f9bc","👨🏻‍🦼":"1f468-1f3fb-200d-1f9bc","👨🏼‍🦼":"1f468-1f3fc-200d-1f9bc","👨🏽‍🦼":"1f468-1f3fd-200d-1f9bc","👨🏾‍🦼":"1f468-1f3fe-200d-1f9bc","👨🏿‍🦼":"1f468-1f3ff-200d-1f9bc","👩🏻‍🦼":"1f469-1f3fb-200d-1f9bc","👩🏼‍🦼":"1f469-1f3fc-200d-1f9bc","👩🏽‍🦼":"1f469-1f3fd-200d-1f9bc","👩🏾‍🦼":"1f469-1f3fe-200d-1f9bc","👩🏿‍🦼":"1f469-1f3ff-200d-1f9bc","🧑🏻‍🦽":"1f9d1-1f3fb-200d-1f9bd","🧑🏼‍🦽":"1f9d1-1f3fc-200d-1f9bd","🧑🏽‍🦽":"1f9d1-1f3fd-200d-1f9bd","🧑🏾‍🦽":"1f9d1-1f3fe-200d-1f9bd","🧑🏿‍🦽":"1f9d1-1f3ff-200d-1f9bd","👨🏻‍🦽":"1f468-1f3fb-200d-1f9bd","👨🏼‍🦽":"1f468-1f3fc-200d-1f9bd","👨🏽‍🦽":"1f468-1f3fd-200d-1f9bd","👨🏾‍🦽":"1f468-1f3fe-200d-1f9bd","👨🏿‍🦽":"1f468-1f3ff-200d-1f9bd","👩🏻‍🦽":"1f469-1f3fb-200d-1f9bd","👩🏼‍🦽":"1f469-1f3fc-200d-1f9bd","👩🏽‍🦽":"1f469-1f3fd-200d-1f9bd","👩🏾‍🦽":"1f469-1f3fe-200d-1f9bd","👩🏿‍🦽":"1f469-1f3ff-200d-1f9bd","🏃‍♂️":"1f3c3-200d-2642-fe0f","🏃🏻‍♂":"1f3c3-1f3fb-200d-2642-fe0f","🏃🏼‍♂":"1f3c3-1f3fc-200d-2642-fe0f","🏃🏽‍♂":"1f3c3-1f3fd-200d-2642-fe0f","🏃🏾‍♂":"1f3c3-1f3fe-200d-2642-fe0f","🏃🏿‍♂":"1f3c3-1f3ff-200d-2642-fe0f","🏃‍♀️":"1f3c3-200d-2640-fe0f","🏃🏻‍♀":"1f3c3-1f3fb-200d-2640-fe0f","🏃🏼‍♀":"1f3c3-1f3fc-200d-2640-fe0f","🏃🏽‍♀":"1f3c3-1f3fd-200d-2640-fe0f","🏃🏾‍♀":"1f3c3-1f3fe-200d-2640-fe0f","🏃🏿‍♀":"1f3c3-1f3ff-200d-2640-fe0f","👯‍♂️":"1f46f-200d-2642-fe0f","👯‍♀️":"1f46f-200d-2640-fe0f","🧖‍♂️":"1f9d6-200d-2642-fe0f","🧖🏻‍♂":"1f9d6-1f3fb-200d-2642-fe0f","🧖🏼‍♂":"1f9d6-1f3fc-200d-2642-fe0f","🧖🏽‍♂":"1f9d6-1f3fd-200d-2642-fe0f","🧖🏾‍♂":"1f9d6-1f3fe-200d-2642-fe0f","🧖🏿‍♂":"1f9d6-1f3ff-200d-2642-fe0f","🧖‍♀️":"1f9d6-200d-2640-fe0f","🧖🏻‍♀":"1f9d6-1f3fb-200d-2640-fe0f","🧖🏼‍♀":"1f9d6-1f3fc-200d-2640-fe0f","🧖🏽‍♀":"1f9d6-1f3fd-200d-2640-fe0f","🧖🏾‍♀":"1f9d6-1f3fe-200d-2640-fe0f","🧖🏿‍♀":"1f9d6-1f3ff-200d-2640-fe0f","🧗‍♂️":"1f9d7-200d-2642-fe0f","🧗🏻‍♂":"1f9d7-1f3fb-200d-2642-fe0f","🧗🏼‍♂":"1f9d7-1f3fc-200d-2642-fe0f","🧗🏽‍♂":"1f9d7-1f3fd-200d-2642-fe0f","🧗🏾‍♂":"1f9d7-1f3fe-200d-2642-fe0f","🧗🏿‍♂":"1f9d7-1f3ff-200d-2642-fe0f","🧗‍♀️":"1f9d7-200d-2640-fe0f","🧗🏻‍♀":"1f9d7-1f3fb-200d-2640-fe0f","🧗🏼‍♀":"1f9d7-1f3fc-200d-2640-fe0f","🧗🏽‍♀":"1f9d7-1f3fd-200d-2640-fe0f","🧗🏾‍♀":"1f9d7-1f3fe-200d-2640-fe0f","🧗🏿‍♀":"1f9d7-1f3ff-200d-2640-fe0f","🏌‍♂️":"1f3cc-fe0f-200d-2642-fe0f","🏌️‍♂":"1f3cc-fe0f-200d-2642-fe0f","🏌🏻‍♂":"1f3cc-1f3fb-200d-2642-fe0f","🏌🏼‍♂":"1f3cc-1f3fc-200d-2642-fe0f","🏌🏽‍♂":"1f3cc-1f3fd-200d-2642-fe0f","🏌🏾‍♂":"1f3cc-1f3fe-200d-2642-fe0f","🏌🏿‍♂":"1f3cc-1f3ff-200d-2642-fe0f","🏌‍♀️":"1f3cc-fe0f-200d-2640-fe0f","🏌️‍♀":"1f3cc-fe0f-200d-2640-fe0f","🏌🏻‍♀":"1f3cc-1f3fb-200d-2640-fe0f","🏌🏼‍♀":"1f3cc-1f3fc-200d-2640-fe0f","🏌🏽‍♀":"1f3cc-1f3fd-200d-2640-fe0f","🏌🏾‍♀":"1f3cc-1f3fe-200d-2640-fe0f","🏌🏿‍♀":"1f3cc-1f3ff-200d-2640-fe0f","🏄‍♂️":"1f3c4-200d-2642-fe0f","🏄🏻‍♂":"1f3c4-1f3fb-200d-2642-fe0f","🏄🏼‍♂":"1f3c4-1f3fc-200d-2642-fe0f","🏄🏽‍♂":"1f3c4-1f3fd-200d-2642-fe0f","🏄🏾‍♂":"1f3c4-1f3fe-200d-2642-fe0f","🏄🏿‍♂":"1f3c4-1f3ff-200d-2642-fe0f","🏄‍♀️":"1f3c4-200d-2640-fe0f","🏄🏻‍♀":"1f3c4-1f3fb-200d-2640-fe0f","🏄🏼‍♀":"1f3c4-1f3fc-200d-2640-fe0f","🏄🏽‍♀":"1f3c4-1f3fd-200d-2640-fe0f","🏄🏾‍♀":"1f3c4-1f3fe-200d-2640-fe0f","🏄🏿‍♀":"1f3c4-1f3ff-200d-2640-fe0f","🚣‍♂️":"1f6a3-200d-2642-fe0f","🚣🏻‍♂":"1f6a3-1f3fb-200d-2642-fe0f","🚣🏼‍♂":"1f6a3-1f3fc-200d-2642-fe0f","🚣🏽‍♂":"1f6a3-1f3fd-200d-2642-fe0f","🚣🏾‍♂":"1f6a3-1f3fe-200d-2642-fe0f","🚣🏿‍♂":"1f6a3-1f3ff-200d-2642-fe0f","🚣‍♀️":"1f6a3-200d-2640-fe0f","🚣🏻‍♀":"1f6a3-1f3fb-200d-2640-fe0f","🚣🏼‍♀":"1f6a3-1f3fc-200d-2640-fe0f","🚣🏽‍♀":"1f6a3-1f3fd-200d-2640-fe0f","🚣🏾‍♀":"1f6a3-1f3fe-200d-2640-fe0f","🚣🏿‍♀":"1f6a3-1f3ff-200d-2640-fe0f","🏊‍♂️":"1f3ca-200d-2642-fe0f","🏊🏻‍♂":"1f3ca-1f3fb-200d-2642-fe0f","🏊🏼‍♂":"1f3ca-1f3fc-200d-2642-fe0f","🏊🏽‍♂":"1f3ca-1f3fd-200d-2642-fe0f","🏊🏾‍♂":"1f3ca-1f3fe-200d-2642-fe0f","🏊🏿‍♂":"1f3ca-1f3ff-200d-2642-fe0f","🏊‍♀️":"1f3ca-200d-2640-fe0f","🏊🏻‍♀":"1f3ca-1f3fb-200d-2640-fe0f","🏊🏼‍♀":"1f3ca-1f3fc-200d-2640-fe0f","🏊🏽‍♀":"1f3ca-1f3fd-200d-2640-fe0f","🏊🏾‍♀":"1f3ca-1f3fe-200d-2640-fe0f","🏊🏿‍♀":"1f3ca-1f3ff-200d-2640-fe0f","⛹‍♂️":"26f9-fe0f-200d-2642-fe0f","⛹️‍♂":"26f9-fe0f-200d-2642-fe0f","⛹🏻‍♂":"26f9-1f3fb-200d-2642-fe0f","⛹🏼‍♂":"26f9-1f3fc-200d-2642-fe0f","⛹🏽‍♂":"26f9-1f3fd-200d-2642-fe0f","⛹🏾‍♂":"26f9-1f3fe-200d-2642-fe0f","⛹🏿‍♂":"26f9-1f3ff-200d-2642-fe0f","⛹‍♀️":"26f9-fe0f-200d-2640-fe0f","⛹️‍♀":"26f9-fe0f-200d-2640-fe0f","⛹🏻‍♀":"26f9-1f3fb-200d-2640-fe0f","⛹🏼‍♀":"26f9-1f3fc-200d-2640-fe0f","⛹🏽‍♀":"26f9-1f3fd-200d-2640-fe0f","⛹🏾‍♀":"26f9-1f3fe-200d-2640-fe0f","⛹🏿‍♀":"26f9-1f3ff-200d-2640-fe0f","🏋‍♂️":"1f3cb-fe0f-200d-2642-fe0f","🏋️‍♂":"1f3cb-fe0f-200d-2642-fe0f","🏋🏻‍♂":"1f3cb-1f3fb-200d-2642-fe0f","🏋🏼‍♂":"1f3cb-1f3fc-200d-2642-fe0f","🏋🏽‍♂":"1f3cb-1f3fd-200d-2642-fe0f","🏋🏾‍♂":"1f3cb-1f3fe-200d-2642-fe0f","🏋🏿‍♂":"1f3cb-1f3ff-200d-2642-fe0f","🏋‍♀️":"1f3cb-fe0f-200d-2640-fe0f","🏋️‍♀":"1f3cb-fe0f-200d-2640-fe0f","🏋🏻‍♀":"1f3cb-1f3fb-200d-2640-fe0f","🏋🏼‍♀":"1f3cb-1f3fc-200d-2640-fe0f","🏋🏽‍♀":"1f3cb-1f3fd-200d-2640-fe0f","🏋🏾‍♀":"1f3cb-1f3fe-200d-2640-fe0f","🏋🏿‍♀":"1f3cb-1f3ff-200d-2640-fe0f","🚴‍♂️":"1f6b4-200d-2642-fe0f","🚴🏻‍♂":"1f6b4-1f3fb-200d-2642-fe0f","🚴🏼‍♂":"1f6b4-1f3fc-200d-2642-fe0f","🚴🏽‍♂":"1f6b4-1f3fd-200d-2642-fe0f","🚴🏾‍♂":"1f6b4-1f3fe-200d-2642-fe0f","🚴🏿‍♂":"1f6b4-1f3ff-200d-2642-fe0f","🚴‍♀️":"1f6b4-200d-2640-fe0f","🚴🏻‍♀":"1f6b4-1f3fb-200d-2640-fe0f","🚴🏼‍♀":"1f6b4-1f3fc-200d-2640-fe0f","🚴🏽‍♀":"1f6b4-1f3fd-200d-2640-fe0f","🚴🏾‍♀":"1f6b4-1f3fe-200d-2640-fe0f","🚴🏿‍♀":"1f6b4-1f3ff-200d-2640-fe0f","🚵‍♂️":"1f6b5-200d-2642-fe0f","🚵🏻‍♂":"1f6b5-1f3fb-200d-2642-fe0f","🚵🏼‍♂":"1f6b5-1f3fc-200d-2642-fe0f","🚵🏽‍♂":"1f6b5-1f3fd-200d-2642-fe0f","🚵🏾‍♂":"1f6b5-1f3fe-200d-2642-fe0f","🚵🏿‍♂":"1f6b5-1f3ff-200d-2642-fe0f","🚵‍♀️":"1f6b5-200d-2640-fe0f","🚵🏻‍♀":"1f6b5-1f3fb-200d-2640-fe0f","🚵🏼‍♀":"1f6b5-1f3fc-200d-2640-fe0f","🚵🏽‍♀":"1f6b5-1f3fd-200d-2640-fe0f","🚵🏾‍♀":"1f6b5-1f3fe-200d-2640-fe0f","🚵🏿‍♀":"1f6b5-1f3ff-200d-2640-fe0f","🤸‍♂️":"1f938-200d-2642-fe0f","🤸🏻‍♂":"1f938-1f3fb-200d-2642-fe0f","🤸🏼‍♂":"1f938-1f3fc-200d-2642-fe0f","🤸🏽‍♂":"1f938-1f3fd-200d-2642-fe0f","🤸🏾‍♂":"1f938-1f3fe-200d-2642-fe0f","🤸🏿‍♂":"1f938-1f3ff-200d-2642-fe0f","🤸‍♀️":"1f938-200d-2640-fe0f","🤸🏻‍♀":"1f938-1f3fb-200d-2640-fe0f","🤸🏼‍♀":"1f938-1f3fc-200d-2640-fe0f","🤸🏽‍♀":"1f938-1f3fd-200d-2640-fe0f","🤸🏾‍♀":"1f938-1f3fe-200d-2640-fe0f","🤸🏿‍♀":"1f938-1f3ff-200d-2640-fe0f","🤼‍♂️":"1f93c-200d-2642-fe0f","🤼‍♀️":"1f93c-200d-2640-fe0f","🤽‍♂️":"1f93d-200d-2642-fe0f","🤽🏻‍♂":"1f93d-1f3fb-200d-2642-fe0f","🤽🏼‍♂":"1f93d-1f3fc-200d-2642-fe0f","🤽🏽‍♂":"1f93d-1f3fd-200d-2642-fe0f","🤽🏾‍♂":"1f93d-1f3fe-200d-2642-fe0f","🤽🏿‍♂":"1f93d-1f3ff-200d-2642-fe0f","🤽‍♀️":"1f93d-200d-2640-fe0f","🤽🏻‍♀":"1f93d-1f3fb-200d-2640-fe0f","🤽🏼‍♀":"1f93d-1f3fc-200d-2640-fe0f","🤽🏽‍♀":"1f93d-1f3fd-200d-2640-fe0f","🤽🏾‍♀":"1f93d-1f3fe-200d-2640-fe0f","🤽🏿‍♀":"1f93d-1f3ff-200d-2640-fe0f","🤾‍♂️":"1f93e-200d-2642-fe0f","🤾🏻‍♂":"1f93e-1f3fb-200d-2642-fe0f","🤾🏼‍♂":"1f93e-1f3fc-200d-2642-fe0f","🤾🏽‍♂":"1f93e-1f3fd-200d-2642-fe0f","🤾🏾‍♂":"1f93e-1f3fe-200d-2642-fe0f","🤾🏿‍♂":"1f93e-1f3ff-200d-2642-fe0f","🤾‍♀️":"1f93e-200d-2640-fe0f","🤾🏻‍♀":"1f93e-1f3fb-200d-2640-fe0f","🤾🏼‍♀":"1f93e-1f3fc-200d-2640-fe0f","🤾🏽‍♀":"1f93e-1f3fd-200d-2640-fe0f","🤾🏾‍♀":"1f93e-1f3fe-200d-2640-fe0f","🤾🏿‍♀":"1f93e-1f3ff-200d-2640-fe0f","🤹‍♂️":"1f939-200d-2642-fe0f","🤹🏻‍♂":"1f939-1f3fb-200d-2642-fe0f","🤹🏼‍♂":"1f939-1f3fc-200d-2642-fe0f","🤹🏽‍♂":"1f939-1f3fd-200d-2642-fe0f","🤹🏾‍♂":"1f939-1f3fe-200d-2642-fe0f","🤹🏿‍♂":"1f939-1f3ff-200d-2642-fe0f","🤹‍♀️":"1f939-200d-2640-fe0f","🤹🏻‍♀":"1f939-1f3fb-200d-2640-fe0f","🤹🏼‍♀":"1f939-1f3fc-200d-2640-fe0f","🤹🏽‍♀":"1f939-1f3fd-200d-2640-fe0f","🤹🏾‍♀":"1f939-1f3fe-200d-2640-fe0f","🤹🏿‍♀":"1f939-1f3ff-200d-2640-fe0f","🧘‍♂️":"1f9d8-200d-2642-fe0f","🧘🏻‍♂":"1f9d8-1f3fb-200d-2642-fe0f","🧘🏼‍♂":"1f9d8-1f3fc-200d-2642-fe0f","🧘🏽‍♂":"1f9d8-1f3fd-200d-2642-fe0f","🧘🏾‍♂":"1f9d8-1f3fe-200d-2642-fe0f","🧘🏿‍♂":"1f9d8-1f3ff-200d-2642-fe0f","🧘‍♀️":"1f9d8-200d-2640-fe0f","🧘🏻‍♀":"1f9d8-1f3fb-200d-2640-fe0f","🧘🏼‍♀":"1f9d8-1f3fc-200d-2640-fe0f","🧘🏽‍♀":"1f9d8-1f3fd-200d-2640-fe0f","🧘🏾‍♀":"1f9d8-1f3fe-200d-2640-fe0f","🧘🏿‍♀":"1f9d8-1f3ff-200d-2640-fe0f","🐻‍❄️":"1f43b-200d-2744-fe0f","🏳️‍🌈":"1f3f3-fe0f-200d-1f308","🏳‍⚧️":"1f3f3-fe0f-200d-26a7-fe0f","🏳️‍⚧":"1f3f3-fe0f-200d-26a7-fe0f","🏴‍☠️":"1f3f4-200d-2620-fe0f","👁️‍🗨️":"1f441-200d-1f5e8","🫱🏻‍🫲🏼":"1faf1-1f3fb-200d-1faf2-1f3fc","🫱🏻‍🫲🏽":"1faf1-1f3fb-200d-1faf2-1f3fd","🫱🏻‍🫲🏾":"1faf1-1f3fb-200d-1faf2-1f3fe","🫱🏻‍🫲🏿":"1faf1-1f3fb-200d-1faf2-1f3ff","🫱🏼‍🫲🏻":"1faf1-1f3fc-200d-1faf2-1f3fb","🫱🏼‍🫲🏽":"1faf1-1f3fc-200d-1faf2-1f3fd","🫱🏼‍🫲🏾":"1faf1-1f3fc-200d-1faf2-1f3fe","🫱🏼‍🫲🏿":"1faf1-1f3fc-200d-1faf2-1f3ff","🫱🏽‍🫲🏻":"1faf1-1f3fd-200d-1faf2-1f3fb","🫱🏽‍🫲🏼":"1faf1-1f3fd-200d-1faf2-1f3fc","🫱🏽‍🫲🏾":"1faf1-1f3fd-200d-1faf2-1f3fe","🫱🏽‍🫲🏿":"1faf1-1f3fd-200d-1faf2-1f3ff","🫱🏾‍🫲🏻":"1faf1-1f3fe-200d-1faf2-1f3fb","🫱🏾‍🫲🏼":"1faf1-1f3fe-200d-1faf2-1f3fc","🫱🏾‍🫲🏽":"1faf1-1f3fe-200d-1faf2-1f3fd","🫱🏾‍🫲🏿":"1faf1-1f3fe-200d-1faf2-1f3ff","🫱🏿‍🫲🏻":"1faf1-1f3ff-200d-1faf2-1f3fb","🫱🏿‍🫲🏼":"1faf1-1f3ff-200d-1faf2-1f3fc","🫱🏿‍🫲🏽":"1faf1-1f3ff-200d-1faf2-1f3fd","🫱🏿‍🫲🏾":"1faf1-1f3ff-200d-1faf2-1f3fe","🧔🏻‍♂️":"1f9d4-1f3fb-200d-2642-fe0f","🧔🏼‍♂️":"1f9d4-1f3fc-200d-2642-fe0f","🧔🏽‍♂️":"1f9d4-1f3fd-200d-2642-fe0f","🧔🏾‍♂️":"1f9d4-1f3fe-200d-2642-fe0f","🧔🏿‍♂️":"1f9d4-1f3ff-200d-2642-fe0f","🧔🏻‍♀️":"1f9d4-1f3fb-200d-2640-fe0f","🧔🏼‍♀️":"1f9d4-1f3fc-200d-2640-fe0f","🧔🏽‍♀️":"1f9d4-1f3fd-200d-2640-fe0f","🧔🏾‍♀️":"1f9d4-1f3fe-200d-2640-fe0f","🧔🏿‍♀️":"1f9d4-1f3ff-200d-2640-fe0f","👱🏻‍♀️":"1f471-1f3fb-200d-2640-fe0f","👱🏼‍♀️":"1f471-1f3fc-200d-2640-fe0f","👱🏽‍♀️":"1f471-1f3fd-200d-2640-fe0f","👱🏾‍♀️":"1f471-1f3fe-200d-2640-fe0f","👱🏿‍♀️":"1f471-1f3ff-200d-2640-fe0f","👱🏻‍♂️":"1f471-1f3fb-200d-2642-fe0f","👱🏼‍♂️":"1f471-1f3fc-200d-2642-fe0f","👱🏽‍♂️":"1f471-1f3fd-200d-2642-fe0f","👱🏾‍♂️":"1f471-1f3fe-200d-2642-fe0f","👱🏿‍♂️":"1f471-1f3ff-200d-2642-fe0f","🙍🏻‍♂️":"1f64d-1f3fb-200d-2642-fe0f","🙍🏼‍♂️":"1f64d-1f3fc-200d-2642-fe0f","🙍🏽‍♂️":"1f64d-1f3fd-200d-2642-fe0f","🙍🏾‍♂️":"1f64d-1f3fe-200d-2642-fe0f","🙍🏿‍♂️":"1f64d-1f3ff-200d-2642-fe0f","🙍🏻‍♀️":"1f64d-1f3fb-200d-2640-fe0f","🙍🏼‍♀️":"1f64d-1f3fc-200d-2640-fe0f","🙍🏽‍♀️":"1f64d-1f3fd-200d-2640-fe0f","🙍🏾‍♀️":"1f64d-1f3fe-200d-2640-fe0f","🙍🏿‍♀️":"1f64d-1f3ff-200d-2640-fe0f","🙎🏻‍♂️":"1f64e-1f3fb-200d-2642-fe0f","🙎🏼‍♂️":"1f64e-1f3fc-200d-2642-fe0f","🙎🏽‍♂️":"1f64e-1f3fd-200d-2642-fe0f","🙎🏾‍♂️":"1f64e-1f3fe-200d-2642-fe0f","🙎🏿‍♂️":"1f64e-1f3ff-200d-2642-fe0f","🙎🏻‍♀️":"1f64e-1f3fb-200d-2640-fe0f","🙎🏼‍♀️":"1f64e-1f3fc-200d-2640-fe0f","🙎🏽‍♀️":"1f64e-1f3fd-200d-2640-fe0f","🙎🏾‍♀️":"1f64e-1f3fe-200d-2640-fe0f","🙎🏿‍♀️":"1f64e-1f3ff-200d-2640-fe0f","🙅🏻‍♂️":"1f645-1f3fb-200d-2642-fe0f","🙅🏼‍♂️":"1f645-1f3fc-200d-2642-fe0f","🙅🏽‍♂️":"1f645-1f3fd-200d-2642-fe0f","🙅🏾‍♂️":"1f645-1f3fe-200d-2642-fe0f","🙅🏿‍♂️":"1f645-1f3ff-200d-2642-fe0f","🙅🏻‍♀️":"1f645-1f3fb-200d-2640-fe0f","🙅🏼‍♀️":"1f645-1f3fc-200d-2640-fe0f","🙅🏽‍♀️":"1f645-1f3fd-200d-2640-fe0f","🙅🏾‍♀️":"1f645-1f3fe-200d-2640-fe0f","🙅🏿‍♀️":"1f645-1f3ff-200d-2640-fe0f","🙆🏻‍♂️":"1f646-1f3fb-200d-2642-fe0f","🙆🏼‍♂️":"1f646-1f3fc-200d-2642-fe0f","🙆🏽‍♂️":"1f646-1f3fd-200d-2642-fe0f","🙆🏾‍♂️":"1f646-1f3fe-200d-2642-fe0f","🙆🏿‍♂️":"1f646-1f3ff-200d-2642-fe0f","🙆🏻‍♀️":"1f646-1f3fb-200d-2640-fe0f","🙆🏼‍♀️":"1f646-1f3fc-200d-2640-fe0f","🙆🏽‍♀️":"1f646-1f3fd-200d-2640-fe0f","🙆🏾‍♀️":"1f646-1f3fe-200d-2640-fe0f","🙆🏿‍♀️":"1f646-1f3ff-200d-2640-fe0f","💁🏻‍♂️":"1f481-1f3fb-200d-2642-fe0f","💁🏼‍♂️":"1f481-1f3fc-200d-2642-fe0f","💁🏽‍♂️":"1f481-1f3fd-200d-2642-fe0f","💁🏾‍♂️":"1f481-1f3fe-200d-2642-fe0f","💁🏿‍♂️":"1f481-1f3ff-200d-2642-fe0f","💁🏻‍♀️":"1f481-1f3fb-200d-2640-fe0f","💁🏼‍♀️":"1f481-1f3fc-200d-2640-fe0f","💁🏽‍♀️":"1f481-1f3fd-200d-2640-fe0f","💁🏾‍♀️":"1f481-1f3fe-200d-2640-fe0f","💁🏿‍♀️":"1f481-1f3ff-200d-2640-fe0f","🙋🏻‍♂️":"1f64b-1f3fb-200d-2642-fe0f","🙋🏼‍♂️":"1f64b-1f3fc-200d-2642-fe0f","🙋🏽‍♂️":"1f64b-1f3fd-200d-2642-fe0f","🙋🏾‍♂️":"1f64b-1f3fe-200d-2642-fe0f","🙋🏿‍♂️":"1f64b-1f3ff-200d-2642-fe0f","🙋🏻‍♀️":"1f64b-1f3fb-200d-2640-fe0f","🙋🏼‍♀️":"1f64b-1f3fc-200d-2640-fe0f","🙋🏽‍♀️":"1f64b-1f3fd-200d-2640-fe0f","🙋🏾‍♀️":"1f64b-1f3fe-200d-2640-fe0f","🙋🏿‍♀️":"1f64b-1f3ff-200d-2640-fe0f","🧏🏻‍♂️":"1f9cf-1f3fb-200d-2642-fe0f","🧏🏼‍♂️":"1f9cf-1f3fc-200d-2642-fe0f","🧏🏽‍♂️":"1f9cf-1f3fd-200d-2642-fe0f","🧏🏾‍♂️":"1f9cf-1f3fe-200d-2642-fe0f","🧏🏿‍♂️":"1f9cf-1f3ff-200d-2642-fe0f","🧏🏻‍♀️":"1f9cf-1f3fb-200d-2640-fe0f","🧏🏼‍♀️":"1f9cf-1f3fc-200d-2640-fe0f","🧏🏽‍♀️":"1f9cf-1f3fd-200d-2640-fe0f","🧏🏾‍♀️":"1f9cf-1f3fe-200d-2640-fe0f","🧏🏿‍♀️":"1f9cf-1f3ff-200d-2640-fe0f","🙇🏻‍♂️":"1f647-1f3fb-200d-2642-fe0f","🙇🏼‍♂️":"1f647-1f3fc-200d-2642-fe0f","🙇🏽‍♂️":"1f647-1f3fd-200d-2642-fe0f","🙇🏾‍♂️":"1f647-1f3fe-200d-2642-fe0f","🙇🏿‍♂️":"1f647-1f3ff-200d-2642-fe0f","🙇🏻‍♀️":"1f647-1f3fb-200d-2640-fe0f","🙇🏼‍♀️":"1f647-1f3fc-200d-2640-fe0f","🙇🏽‍♀️":"1f647-1f3fd-200d-2640-fe0f","🙇🏾‍♀️":"1f647-1f3fe-200d-2640-fe0f","🙇🏿‍♀️":"1f647-1f3ff-200d-2640-fe0f","🤦🏻‍♂️":"1f926-1f3fb-200d-2642-fe0f","🤦🏼‍♂️":"1f926-1f3fc-200d-2642-fe0f","🤦🏽‍♂️":"1f926-1f3fd-200d-2642-fe0f","🤦🏾‍♂️":"1f926-1f3fe-200d-2642-fe0f","🤦🏿‍♂️":"1f926-1f3ff-200d-2642-fe0f","🤦🏻‍♀️":"1f926-1f3fb-200d-2640-fe0f","🤦🏼‍♀️":"1f926-1f3fc-200d-2640-fe0f","🤦🏽‍♀️":"1f926-1f3fd-200d-2640-fe0f","🤦🏾‍♀️":"1f926-1f3fe-200d-2640-fe0f","🤦🏿‍♀️":"1f926-1f3ff-200d-2640-fe0f","🤷🏻‍♂️":"1f937-1f3fb-200d-2642-fe0f","🤷🏼‍♂️":"1f937-1f3fc-200d-2642-fe0f","🤷🏽‍♂️":"1f937-1f3fd-200d-2642-fe0f","🤷🏾‍♂️":"1f937-1f3fe-200d-2642-fe0f","🤷🏿‍♂️":"1f937-1f3ff-200d-2642-fe0f","🤷🏻‍♀️":"1f937-1f3fb-200d-2640-fe0f","🤷🏼‍♀️":"1f937-1f3fc-200d-2640-fe0f","🤷🏽‍♀️":"1f937-1f3fd-200d-2640-fe0f","🤷🏾‍♀️":"1f937-1f3fe-200d-2640-fe0f","🤷🏿‍♀️":"1f937-1f3ff-200d-2640-fe0f","🧑🏻‍⚕️":"1f9d1-1f3fb-200d-2695-fe0f","🧑🏼‍⚕️":"1f9d1-1f3fc-200d-2695-fe0f","🧑🏽‍⚕️":"1f9d1-1f3fd-200d-2695-fe0f","🧑🏾‍⚕️":"1f9d1-1f3fe-200d-2695-fe0f","🧑🏿‍⚕️":"1f9d1-1f3ff-200d-2695-fe0f","👨🏻‍⚕️":"1f468-1f3fb-200d-2695-fe0f","👨🏼‍⚕️":"1f468-1f3fc-200d-2695-fe0f","👨🏽‍⚕️":"1f468-1f3fd-200d-2695-fe0f","👨🏾‍⚕️":"1f468-1f3fe-200d-2695-fe0f","👨🏿‍⚕️":"1f468-1f3ff-200d-2695-fe0f","👩🏻‍⚕️":"1f469-1f3fb-200d-2695-fe0f","👩🏼‍⚕️":"1f469-1f3fc-200d-2695-fe0f","👩🏽‍⚕️":"1f469-1f3fd-200d-2695-fe0f","👩🏾‍⚕️":"1f469-1f3fe-200d-2695-fe0f","👩🏿‍⚕️":"1f469-1f3ff-200d-2695-fe0f","🧑🏻‍⚖️":"1f9d1-1f3fb-200d-2696-fe0f","🧑🏼‍⚖️":"1f9d1-1f3fc-200d-2696-fe0f","🧑🏽‍⚖️":"1f9d1-1f3fd-200d-2696-fe0f","🧑🏾‍⚖️":"1f9d1-1f3fe-200d-2696-fe0f","🧑🏿‍⚖️":"1f9d1-1f3ff-200d-2696-fe0f","👨🏻‍⚖️":"1f468-1f3fb-200d-2696-fe0f","👨🏼‍⚖️":"1f468-1f3fc-200d-2696-fe0f","👨🏽‍⚖️":"1f468-1f3fd-200d-2696-fe0f","👨🏾‍⚖️":"1f468-1f3fe-200d-2696-fe0f","👨🏿‍⚖️":"1f468-1f3ff-200d-2696-fe0f","👩🏻‍⚖️":"1f469-1f3fb-200d-2696-fe0f","👩🏼‍⚖️":"1f469-1f3fc-200d-2696-fe0f","👩🏽‍⚖️":"1f469-1f3fd-200d-2696-fe0f","👩🏾‍⚖️":"1f469-1f3fe-200d-2696-fe0f","👩🏿‍⚖️":"1f469-1f3ff-200d-2696-fe0f","🧑🏻‍✈️":"1f9d1-1f3fb-200d-2708-fe0f","🧑🏼‍✈️":"1f9d1-1f3fc-200d-2708-fe0f","🧑🏽‍✈️":"1f9d1-1f3fd-200d-2708-fe0f","🧑🏾‍✈️":"1f9d1-1f3fe-200d-2708-fe0f","🧑🏿‍✈️":"1f9d1-1f3ff-200d-2708-fe0f","👨🏻‍✈️":"1f468-1f3fb-200d-2708-fe0f","👨🏼‍✈️":"1f468-1f3fc-200d-2708-fe0f","👨🏽‍✈️":"1f468-1f3fd-200d-2708-fe0f","👨🏾‍✈️":"1f468-1f3fe-200d-2708-fe0f","👨🏿‍✈️":"1f468-1f3ff-200d-2708-fe0f","👩🏻‍✈️":"1f469-1f3fb-200d-2708-fe0f","👩🏼‍✈️":"1f469-1f3fc-200d-2708-fe0f","👩🏽‍✈️":"1f469-1f3fd-200d-2708-fe0f","👩🏾‍✈️":"1f469-1f3fe-200d-2708-fe0f","👩🏿‍✈️":"1f469-1f3ff-200d-2708-fe0f","👮🏻‍♂️":"1f46e-1f3fb-200d-2642-fe0f","👮🏼‍♂️":"1f46e-1f3fc-200d-2642-fe0f","👮🏽‍♂️":"1f46e-1f3fd-200d-2642-fe0f","👮🏾‍♂️":"1f46e-1f3fe-200d-2642-fe0f","👮🏿‍♂️":"1f46e-1f3ff-200d-2642-fe0f","👮🏻‍♀️":"1f46e-1f3fb-200d-2640-fe0f","👮🏼‍♀️":"1f46e-1f3fc-200d-2640-fe0f","👮🏽‍♀️":"1f46e-1f3fd-200d-2640-fe0f","👮🏾‍♀️":"1f46e-1f3fe-200d-2640-fe0f","👮🏿‍♀️":"1f46e-1f3ff-200d-2640-fe0f","🕵️‍♂️":"1f575-fe0f-200d-2642-fe0f","🕵🏻‍♂️":"1f575-1f3fb-200d-2642-fe0f","🕵🏼‍♂️":"1f575-1f3fc-200d-2642-fe0f","🕵🏽‍♂️":"1f575-1f3fd-200d-2642-fe0f","🕵🏾‍♂️":"1f575-1f3fe-200d-2642-fe0f","🕵🏿‍♂️":"1f575-1f3ff-200d-2642-fe0f","🕵️‍♀️":"1f575-fe0f-200d-2640-fe0f","🕵🏻‍♀️":"1f575-1f3fb-200d-2640-fe0f","🕵🏼‍♀️":"1f575-1f3fc-200d-2640-fe0f","🕵🏽‍♀️":"1f575-1f3fd-200d-2640-fe0f","🕵🏾‍♀️":"1f575-1f3fe-200d-2640-fe0f","🕵🏿‍♀️":"1f575-1f3ff-200d-2640-fe0f","💂🏻‍♂️":"1f482-1f3fb-200d-2642-fe0f","💂🏼‍♂️":"1f482-1f3fc-200d-2642-fe0f","💂🏽‍♂️":"1f482-1f3fd-200d-2642-fe0f","💂🏾‍♂️":"1f482-1f3fe-200d-2642-fe0f","💂🏿‍♂️":"1f482-1f3ff-200d-2642-fe0f","💂🏻‍♀️":"1f482-1f3fb-200d-2640-fe0f","💂🏼‍♀️":"1f482-1f3fc-200d-2640-fe0f","💂🏽‍♀️":"1f482-1f3fd-200d-2640-fe0f","💂🏾‍♀️":"1f482-1f3fe-200d-2640-fe0f","💂🏿‍♀️":"1f482-1f3ff-200d-2640-fe0f","👷🏻‍♂️":"1f477-1f3fb-200d-2642-fe0f","👷🏼‍♂️":"1f477-1f3fc-200d-2642-fe0f","👷🏽‍♂️":"1f477-1f3fd-200d-2642-fe0f","👷🏾‍♂️":"1f477-1f3fe-200d-2642-fe0f","👷🏿‍♂️":"1f477-1f3ff-200d-2642-fe0f","👷🏻‍♀️":"1f477-1f3fb-200d-2640-fe0f","👷🏼‍♀️":"1f477-1f3fc-200d-2640-fe0f","👷🏽‍♀️":"1f477-1f3fd-200d-2640-fe0f","👷🏾‍♀️":"1f477-1f3fe-200d-2640-fe0f","👷🏿‍♀️":"1f477-1f3ff-200d-2640-fe0f","👳🏻‍♂️":"1f473-1f3fb-200d-2642-fe0f","👳🏼‍♂️":"1f473-1f3fc-200d-2642-fe0f","👳🏽‍♂️":"1f473-1f3fd-200d-2642-fe0f","👳🏾‍♂️":"1f473-1f3fe-200d-2642-fe0f","👳🏿‍♂️":"1f473-1f3ff-200d-2642-fe0f","👳🏻‍♀️":"1f473-1f3fb-200d-2640-fe0f","👳🏼‍♀️":"1f473-1f3fc-200d-2640-fe0f","👳🏽‍♀️":"1f473-1f3fd-200d-2640-fe0f","👳🏾‍♀️":"1f473-1f3fe-200d-2640-fe0f","👳🏿‍♀️":"1f473-1f3ff-200d-2640-fe0f","🤵🏻‍♂️":"1f935-1f3fb-200d-2642-fe0f","🤵🏼‍♂️":"1f935-1f3fc-200d-2642-fe0f","🤵🏽‍♂️":"1f935-1f3fd-200d-2642-fe0f","🤵🏾‍♂️":"1f935-1f3fe-200d-2642-fe0f","🤵🏿‍♂️":"1f935-1f3ff-200d-2642-fe0f","🤵🏻‍♀️":"1f935-1f3fb-200d-2640-fe0f","🤵🏼‍♀️":"1f935-1f3fc-200d-2640-fe0f","🤵🏽‍♀️":"1f935-1f3fd-200d-2640-fe0f","🤵🏾‍♀️":"1f935-1f3fe-200d-2640-fe0f","🤵🏿‍♀️":"1f935-1f3ff-200d-2640-fe0f","👰🏻‍♂️":"1f470-1f3fb-200d-2642-fe0f","👰🏼‍♂️":"1f470-1f3fc-200d-2642-fe0f","👰🏽‍♂️":"1f470-1f3fd-200d-2642-fe0f","👰🏾‍♂️":"1f470-1f3fe-200d-2642-fe0f","👰🏿‍♂️":"1f470-1f3ff-200d-2642-fe0f","👰🏻‍♀️":"1f470-1f3fb-200d-2640-fe0f","👰🏼‍♀️":"1f470-1f3fc-200d-2640-fe0f","👰🏽‍♀️":"1f470-1f3fd-200d-2640-fe0f","👰🏾‍♀️":"1f470-1f3fe-200d-2640-fe0f","👰🏿‍♀️":"1f470-1f3ff-200d-2640-fe0f","🦸🏻‍♂️":"1f9b8-1f3fb-200d-2642-fe0f","🦸🏼‍♂️":"1f9b8-1f3fc-200d-2642-fe0f","🦸🏽‍♂️":"1f9b8-1f3fd-200d-2642-fe0f","🦸🏾‍♂️":"1f9b8-1f3fe-200d-2642-fe0f","🦸🏿‍♂️":"1f9b8-1f3ff-200d-2642-fe0f","🦸🏻‍♀️":"1f9b8-1f3fb-200d-2640-fe0f","🦸🏼‍♀️":"1f9b8-1f3fc-200d-2640-fe0f","🦸🏽‍♀️":"1f9b8-1f3fd-200d-2640-fe0f","🦸🏾‍♀️":"1f9b8-1f3fe-200d-2640-fe0f","🦸🏿‍♀️":"1f9b8-1f3ff-200d-2640-fe0f","🦹🏻‍♂️":"1f9b9-1f3fb-200d-2642-fe0f","🦹🏼‍♂️":"1f9b9-1f3fc-200d-2642-fe0f","🦹🏽‍♂️":"1f9b9-1f3fd-200d-2642-fe0f","🦹🏾‍♂️":"1f9b9-1f3fe-200d-2642-fe0f","🦹🏿‍♂️":"1f9b9-1f3ff-200d-2642-fe0f","🦹🏻‍♀️":"1f9b9-1f3fb-200d-2640-fe0f","🦹🏼‍♀️":"1f9b9-1f3fc-200d-2640-fe0f","🦹🏽‍♀️":"1f9b9-1f3fd-200d-2640-fe0f","🦹🏾‍♀️":"1f9b9-1f3fe-200d-2640-fe0f","🦹🏿‍♀️":"1f9b9-1f3ff-200d-2640-fe0f","🧙🏻‍♂️":"1f9d9-1f3fb-200d-2642-fe0f","🧙🏼‍♂️":"1f9d9-1f3fc-200d-2642-fe0f","🧙🏽‍♂️":"1f9d9-1f3fd-200d-2642-fe0f","🧙🏾‍♂️":"1f9d9-1f3fe-200d-2642-fe0f","🧙🏿‍♂️":"1f9d9-1f3ff-200d-2642-fe0f","🧙🏻‍♀️":"1f9d9-1f3fb-200d-2640-fe0f","🧙🏼‍♀️":"1f9d9-1f3fc-200d-2640-fe0f","🧙🏽‍♀️":"1f9d9-1f3fd-200d-2640-fe0f","🧙🏾‍♀️":"1f9d9-1f3fe-200d-2640-fe0f","🧙🏿‍♀️":"1f9d9-1f3ff-200d-2640-fe0f","🧚🏻‍♂️":"1f9da-1f3fb-200d-2642-fe0f","🧚🏼‍♂️":"1f9da-1f3fc-200d-2642-fe0f","🧚🏽‍♂️":"1f9da-1f3fd-200d-2642-fe0f","🧚🏾‍♂️":"1f9da-1f3fe-200d-2642-fe0f","🧚🏿‍♂️":"1f9da-1f3ff-200d-2642-fe0f","🧚🏻‍♀️":"1f9da-1f3fb-200d-2640-fe0f","🧚🏼‍♀️":"1f9da-1f3fc-200d-2640-fe0f","🧚🏽‍♀️":"1f9da-1f3fd-200d-2640-fe0f","🧚🏾‍♀️":"1f9da-1f3fe-200d-2640-fe0f","🧚🏿‍♀️":"1f9da-1f3ff-200d-2640-fe0f","🧛🏻‍♂️":"1f9db-1f3fb-200d-2642-fe0f","🧛🏼‍♂️":"1f9db-1f3fc-200d-2642-fe0f","🧛🏽‍♂️":"1f9db-1f3fd-200d-2642-fe0f","🧛🏾‍♂️":"1f9db-1f3fe-200d-2642-fe0f","🧛🏿‍♂️":"1f9db-1f3ff-200d-2642-fe0f","🧛🏻‍♀️":"1f9db-1f3fb-200d-2640-fe0f","🧛🏼‍♀️":"1f9db-1f3fc-200d-2640-fe0f","🧛🏽‍♀️":"1f9db-1f3fd-200d-2640-fe0f","🧛🏾‍♀️":"1f9db-1f3fe-200d-2640-fe0f","🧛🏿‍♀️":"1f9db-1f3ff-200d-2640-fe0f","🧜🏻‍♂️":"1f9dc-1f3fb-200d-2642-fe0f","🧜🏼‍♂️":"1f9dc-1f3fc-200d-2642-fe0f","🧜🏽‍♂️":"1f9dc-1f3fd-200d-2642-fe0f","🧜🏾‍♂️":"1f9dc-1f3fe-200d-2642-fe0f","🧜🏿‍♂️":"1f9dc-1f3ff-200d-2642-fe0f","🧜🏻‍♀️":"1f9dc-1f3fb-200d-2640-fe0f","🧜🏼‍♀️":"1f9dc-1f3fc-200d-2640-fe0f","🧜🏽‍♀️":"1f9dc-1f3fd-200d-2640-fe0f","🧜🏾‍♀️":"1f9dc-1f3fe-200d-2640-fe0f","🧜🏿‍♀️":"1f9dc-1f3ff-200d-2640-fe0f","🧝🏻‍♂️":"1f9dd-1f3fb-200d-2642-fe0f","🧝🏼‍♂️":"1f9dd-1f3fc-200d-2642-fe0f","🧝🏽‍♂️":"1f9dd-1f3fd-200d-2642-fe0f","🧝🏾‍♂️":"1f9dd-1f3fe-200d-2642-fe0f","🧝🏿‍♂️":"1f9dd-1f3ff-200d-2642-fe0f","🧝🏻‍♀️":"1f9dd-1f3fb-200d-2640-fe0f","🧝🏼‍♀️":"1f9dd-1f3fc-200d-2640-fe0f","🧝🏽‍♀️":"1f9dd-1f3fd-200d-2640-fe0f","🧝🏾‍♀️":"1f9dd-1f3fe-200d-2640-fe0f","🧝🏿‍♀️":"1f9dd-1f3ff-200d-2640-fe0f","💆🏻‍♂️":"1f486-1f3fb-200d-2642-fe0f","💆🏼‍♂️":"1f486-1f3fc-200d-2642-fe0f","💆🏽‍♂️":"1f486-1f3fd-200d-2642-fe0f","💆🏾‍♂️":"1f486-1f3fe-200d-2642-fe0f","💆🏿‍♂️":"1f486-1f3ff-200d-2642-fe0f","💆🏻‍♀️":"1f486-1f3fb-200d-2640-fe0f","💆🏼‍♀️":"1f486-1f3fc-200d-2640-fe0f","💆🏽‍♀️":"1f486-1f3fd-200d-2640-fe0f","💆🏾‍♀️":"1f486-1f3fe-200d-2640-fe0f","💆🏿‍♀️":"1f486-1f3ff-200d-2640-fe0f","💇🏻‍♂️":"1f487-1f3fb-200d-2642-fe0f","💇🏼‍♂️":"1f487-1f3fc-200d-2642-fe0f","💇🏽‍♂️":"1f487-1f3fd-200d-2642-fe0f","💇🏾‍♂️":"1f487-1f3fe-200d-2642-fe0f","💇🏿‍♂️":"1f487-1f3ff-200d-2642-fe0f","💇🏻‍♀️":"1f487-1f3fb-200d-2640-fe0f","💇🏼‍♀️":"1f487-1f3fc-200d-2640-fe0f","💇🏽‍♀️":"1f487-1f3fd-200d-2640-fe0f","💇🏾‍♀️":"1f487-1f3fe-200d-2640-fe0f","💇🏿‍♀️":"1f487-1f3ff-200d-2640-fe0f","🚶🏻‍♂️":"1f6b6-1f3fb-200d-2642-fe0f","🚶🏼‍♂️":"1f6b6-1f3fc-200d-2642-fe0f","🚶🏽‍♂️":"1f6b6-1f3fd-200d-2642-fe0f","🚶🏾‍♂️":"1f6b6-1f3fe-200d-2642-fe0f","🚶🏿‍♂️":"1f6b6-1f3ff-200d-2642-fe0f","🚶🏻‍♀️":"1f6b6-1f3fb-200d-2640-fe0f","🚶🏼‍♀️":"1f6b6-1f3fc-200d-2640-fe0f","🚶🏽‍♀️":"1f6b6-1f3fd-200d-2640-fe0f","🚶🏾‍♀️":"1f6b6-1f3fe-200d-2640-fe0f","🚶🏿‍♀️":"1f6b6-1f3ff-200d-2640-fe0f","🧍🏻‍♂️":"1f9cd-1f3fb-200d-2642-fe0f","🧍🏼‍♂️":"1f9cd-1f3fc-200d-2642-fe0f","🧍🏽‍♂️":"1f9cd-1f3fd-200d-2642-fe0f","🧍🏾‍♂️":"1f9cd-1f3fe-200d-2642-fe0f","🧍🏿‍♂️":"1f9cd-1f3ff-200d-2642-fe0f","🧍🏻‍♀️":"1f9cd-1f3fb-200d-2640-fe0f","🧍🏼‍♀️":"1f9cd-1f3fc-200d-2640-fe0f","🧍🏽‍♀️":"1f9cd-1f3fd-200d-2640-fe0f","🧍🏾‍♀️":"1f9cd-1f3fe-200d-2640-fe0f","🧍🏿‍♀️":"1f9cd-1f3ff-200d-2640-fe0f","🧎🏻‍♂️":"1f9ce-1f3fb-200d-2642-fe0f","🧎🏼‍♂️":"1f9ce-1f3fc-200d-2642-fe0f","🧎🏽‍♂️":"1f9ce-1f3fd-200d-2642-fe0f","🧎🏾‍♂️":"1f9ce-1f3fe-200d-2642-fe0f","🧎🏿‍♂️":"1f9ce-1f3ff-200d-2642-fe0f","🧎🏻‍♀️":"1f9ce-1f3fb-200d-2640-fe0f","🧎🏼‍♀️":"1f9ce-1f3fc-200d-2640-fe0f","🧎🏽‍♀️":"1f9ce-1f3fd-200d-2640-fe0f","🧎🏾‍♀️":"1f9ce-1f3fe-200d-2640-fe0f","🧎🏿‍♀️":"1f9ce-1f3ff-200d-2640-fe0f","🏃🏻‍♂️":"1f3c3-1f3fb-200d-2642-fe0f","🏃🏼‍♂️":"1f3c3-1f3fc-200d-2642-fe0f","🏃🏽‍♂️":"1f3c3-1f3fd-200d-2642-fe0f","🏃🏾‍♂️":"1f3c3-1f3fe-200d-2642-fe0f","🏃🏿‍♂️":"1f3c3-1f3ff-200d-2642-fe0f","🏃🏻‍♀️":"1f3c3-1f3fb-200d-2640-fe0f","🏃🏼‍♀️":"1f3c3-1f3fc-200d-2640-fe0f","🏃🏽‍♀️":"1f3c3-1f3fd-200d-2640-fe0f","🏃🏾‍♀️":"1f3c3-1f3fe-200d-2640-fe0f","🏃🏿‍♀️":"1f3c3-1f3ff-200d-2640-fe0f","🧖🏻‍♂️":"1f9d6-1f3fb-200d-2642-fe0f","🧖🏼‍♂️":"1f9d6-1f3fc-200d-2642-fe0f","🧖🏽‍♂️":"1f9d6-1f3fd-200d-2642-fe0f","🧖🏾‍♂️":"1f9d6-1f3fe-200d-2642-fe0f","🧖🏿‍♂️":"1f9d6-1f3ff-200d-2642-fe0f","🧖🏻‍♀️":"1f9d6-1f3fb-200d-2640-fe0f","🧖🏼‍♀️":"1f9d6-1f3fc-200d-2640-fe0f","🧖🏽‍♀️":"1f9d6-1f3fd-200d-2640-fe0f","🧖🏾‍♀️":"1f9d6-1f3fe-200d-2640-fe0f","🧖🏿‍♀️":"1f9d6-1f3ff-200d-2640-fe0f","🧗🏻‍♂️":"1f9d7-1f3fb-200d-2642-fe0f","🧗🏼‍♂️":"1f9d7-1f3fc-200d-2642-fe0f","🧗🏽‍♂️":"1f9d7-1f3fd-200d-2642-fe0f","🧗🏾‍♂️":"1f9d7-1f3fe-200d-2642-fe0f","🧗🏿‍♂️":"1f9d7-1f3ff-200d-2642-fe0f","🧗🏻‍♀️":"1f9d7-1f3fb-200d-2640-fe0f","🧗🏼‍♀️":"1f9d7-1f3fc-200d-2640-fe0f","🧗🏽‍♀️":"1f9d7-1f3fd-200d-2640-fe0f","🧗🏾‍♀️":"1f9d7-1f3fe-200d-2640-fe0f","🧗🏿‍♀️":"1f9d7-1f3ff-200d-2640-fe0f","🏌️‍♂️":"1f3cc-fe0f-200d-2642-fe0f","🏌🏻‍♂️":"1f3cc-1f3fb-200d-2642-fe0f","🏌🏼‍♂️":"1f3cc-1f3fc-200d-2642-fe0f","🏌🏽‍♂️":"1f3cc-1f3fd-200d-2642-fe0f","🏌🏾‍♂️":"1f3cc-1f3fe-200d-2642-fe0f","🏌🏿‍♂️":"1f3cc-1f3ff-200d-2642-fe0f","🏌️‍♀️":"1f3cc-fe0f-200d-2640-fe0f","🏌🏻‍♀️":"1f3cc-1f3fb-200d-2640-fe0f","🏌🏼‍♀️":"1f3cc-1f3fc-200d-2640-fe0f","🏌🏽‍♀️":"1f3cc-1f3fd-200d-2640-fe0f","🏌🏾‍♀️":"1f3cc-1f3fe-200d-2640-fe0f","🏌🏿‍♀️":"1f3cc-1f3ff-200d-2640-fe0f","🏄🏻‍♂️":"1f3c4-1f3fb-200d-2642-fe0f","🏄🏼‍♂️":"1f3c4-1f3fc-200d-2642-fe0f","🏄🏽‍♂️":"1f3c4-1f3fd-200d-2642-fe0f","🏄🏾‍♂️":"1f3c4-1f3fe-200d-2642-fe0f","🏄🏿‍♂️":"1f3c4-1f3ff-200d-2642-fe0f","🏄🏻‍♀️":"1f3c4-1f3fb-200d-2640-fe0f","🏄🏼‍♀️":"1f3c4-1f3fc-200d-2640-fe0f","🏄🏽‍♀️":"1f3c4-1f3fd-200d-2640-fe0f","🏄🏾‍♀️":"1f3c4-1f3fe-200d-2640-fe0f","🏄🏿‍♀️":"1f3c4-1f3ff-200d-2640-fe0f","🚣🏻‍♂️":"1f6a3-1f3fb-200d-2642-fe0f","🚣🏼‍♂️":"1f6a3-1f3fc-200d-2642-fe0f","🚣🏽‍♂️":"1f6a3-1f3fd-200d-2642-fe0f","🚣🏾‍♂️":"1f6a3-1f3fe-200d-2642-fe0f","🚣🏿‍♂️":"1f6a3-1f3ff-200d-2642-fe0f","🚣🏻‍♀️":"1f6a3-1f3fb-200d-2640-fe0f","🚣🏼‍♀️":"1f6a3-1f3fc-200d-2640-fe0f","🚣🏽‍♀️":"1f6a3-1f3fd-200d-2640-fe0f","🚣🏾‍♀️":"1f6a3-1f3fe-200d-2640-fe0f","🚣🏿‍♀️":"1f6a3-1f3ff-200d-2640-fe0f","🏊🏻‍♂️":"1f3ca-1f3fb-200d-2642-fe0f","🏊🏼‍♂️":"1f3ca-1f3fc-200d-2642-fe0f","🏊🏽‍♂️":"1f3ca-1f3fd-200d-2642-fe0f","🏊🏾‍♂️":"1f3ca-1f3fe-200d-2642-fe0f","🏊🏿‍♂️":"1f3ca-1f3ff-200d-2642-fe0f","🏊🏻‍♀️":"1f3ca-1f3fb-200d-2640-fe0f","🏊🏼‍♀️":"1f3ca-1f3fc-200d-2640-fe0f","🏊🏽‍♀️":"1f3ca-1f3fd-200d-2640-fe0f","🏊🏾‍♀️":"1f3ca-1f3fe-200d-2640-fe0f","🏊🏿‍♀️":"1f3ca-1f3ff-200d-2640-fe0f","⛹️‍♂️":"26f9-fe0f-200d-2642-fe0f","⛹🏻‍♂️":"26f9-1f3fb-200d-2642-fe0f","⛹🏼‍♂️":"26f9-1f3fc-200d-2642-fe0f","⛹🏽‍♂️":"26f9-1f3fd-200d-2642-fe0f","⛹🏾‍♂️":"26f9-1f3fe-200d-2642-fe0f","⛹🏿‍♂️":"26f9-1f3ff-200d-2642-fe0f","⛹️‍♀️":"26f9-fe0f-200d-2640-fe0f","⛹🏻‍♀️":"26f9-1f3fb-200d-2640-fe0f","⛹🏼‍♀️":"26f9-1f3fc-200d-2640-fe0f","⛹🏽‍♀️":"26f9-1f3fd-200d-2640-fe0f","⛹🏾‍♀️":"26f9-1f3fe-200d-2640-fe0f","⛹🏿‍♀️":"26f9-1f3ff-200d-2640-fe0f","🏋️‍♂️":"1f3cb-fe0f-200d-2642-fe0f","🏋🏻‍♂️":"1f3cb-1f3fb-200d-2642-fe0f","🏋🏼‍♂️":"1f3cb-1f3fc-200d-2642-fe0f","🏋🏽‍♂️":"1f3cb-1f3fd-200d-2642-fe0f","🏋🏾‍♂️":"1f3cb-1f3fe-200d-2642-fe0f","🏋🏿‍♂️":"1f3cb-1f3ff-200d-2642-fe0f","🏋️‍♀️":"1f3cb-fe0f-200d-2640-fe0f","🏋🏻‍♀️":"1f3cb-1f3fb-200d-2640-fe0f","🏋🏼‍♀️":"1f3cb-1f3fc-200d-2640-fe0f","🏋🏽‍♀️":"1f3cb-1f3fd-200d-2640-fe0f","🏋🏾‍♀️":"1f3cb-1f3fe-200d-2640-fe0f","🏋🏿‍♀️":"1f3cb-1f3ff-200d-2640-fe0f","🚴🏻‍♂️":"1f6b4-1f3fb-200d-2642-fe0f","🚴🏼‍♂️":"1f6b4-1f3fc-200d-2642-fe0f","🚴🏽‍♂️":"1f6b4-1f3fd-200d-2642-fe0f","🚴🏾‍♂️":"1f6b4-1f3fe-200d-2642-fe0f","🚴🏿‍♂️":"1f6b4-1f3ff-200d-2642-fe0f","🚴🏻‍♀️":"1f6b4-1f3fb-200d-2640-fe0f","🚴🏼‍♀️":"1f6b4-1f3fc-200d-2640-fe0f","🚴🏽‍♀️":"1f6b4-1f3fd-200d-2640-fe0f","🚴🏾‍♀️":"1f6b4-1f3fe-200d-2640-fe0f","🚴🏿‍♀️":"1f6b4-1f3ff-200d-2640-fe0f","🚵🏻‍♂️":"1f6b5-1f3fb-200d-2642-fe0f","🚵🏼‍♂️":"1f6b5-1f3fc-200d-2642-fe0f","🚵🏽‍♂️":"1f6b5-1f3fd-200d-2642-fe0f","🚵🏾‍♂️":"1f6b5-1f3fe-200d-2642-fe0f","🚵🏿‍♂️":"1f6b5-1f3ff-200d-2642-fe0f","🚵🏻‍♀️":"1f6b5-1f3fb-200d-2640-fe0f","🚵🏼‍♀️":"1f6b5-1f3fc-200d-2640-fe0f","🚵🏽‍♀️":"1f6b5-1f3fd-200d-2640-fe0f","🚵🏾‍♀️":"1f6b5-1f3fe-200d-2640-fe0f","🚵🏿‍♀️":"1f6b5-1f3ff-200d-2640-fe0f","🤸🏻‍♂️":"1f938-1f3fb-200d-2642-fe0f","🤸🏼‍♂️":"1f938-1f3fc-200d-2642-fe0f","🤸🏽‍♂️":"1f938-1f3fd-200d-2642-fe0f","🤸🏾‍♂️":"1f938-1f3fe-200d-2642-fe0f","🤸🏿‍♂️":"1f938-1f3ff-200d-2642-fe0f","🤸🏻‍♀️":"1f938-1f3fb-200d-2640-fe0f","🤸🏼‍♀️":"1f938-1f3fc-200d-2640-fe0f","🤸🏽‍♀️":"1f938-1f3fd-200d-2640-fe0f","🤸🏾‍♀️":"1f938-1f3fe-200d-2640-fe0f","🤸🏿‍♀️":"1f938-1f3ff-200d-2640-fe0f","🤽🏻‍♂️":"1f93d-1f3fb-200d-2642-fe0f","🤽🏼‍♂️":"1f93d-1f3fc-200d-2642-fe0f","🤽🏽‍♂️":"1f93d-1f3fd-200d-2642-fe0f","🤽🏾‍♂️":"1f93d-1f3fe-200d-2642-fe0f","🤽🏿‍♂️":"1f93d-1f3ff-200d-2642-fe0f","🤽🏻‍♀️":"1f93d-1f3fb-200d-2640-fe0f","🤽🏼‍♀️":"1f93d-1f3fc-200d-2640-fe0f","🤽🏽‍♀️":"1f93d-1f3fd-200d-2640-fe0f","🤽🏾‍♀️":"1f93d-1f3fe-200d-2640-fe0f","🤽🏿‍♀️":"1f93d-1f3ff-200d-2640-fe0f","🤾🏻‍♂️":"1f93e-1f3fb-200d-2642-fe0f","🤾🏼‍♂️":"1f93e-1f3fc-200d-2642-fe0f","🤾🏽‍♂️":"1f93e-1f3fd-200d-2642-fe0f","🤾🏾‍♂️":"1f93e-1f3fe-200d-2642-fe0f","🤾🏿‍♂️":"1f93e-1f3ff-200d-2642-fe0f","🤾🏻‍♀️":"1f93e-1f3fb-200d-2640-fe0f","🤾🏼‍♀️":"1f93e-1f3fc-200d-2640-fe0f","🤾🏽‍♀️":"1f93e-1f3fd-200d-2640-fe0f","🤾🏾‍♀️":"1f93e-1f3fe-200d-2640-fe0f","🤾🏿‍♀️":"1f93e-1f3ff-200d-2640-fe0f","🤹🏻‍♂️":"1f939-1f3fb-200d-2642-fe0f","🤹🏼‍♂️":"1f939-1f3fc-200d-2642-fe0f","🤹🏽‍♂️":"1f939-1f3fd-200d-2642-fe0f","🤹🏾‍♂️":"1f939-1f3fe-200d-2642-fe0f","🤹🏿‍♂️":"1f939-1f3ff-200d-2642-fe0f","🤹🏻‍♀️":"1f939-1f3fb-200d-2640-fe0f","🤹🏼‍♀️":"1f939-1f3fc-200d-2640-fe0f","🤹🏽‍♀️":"1f939-1f3fd-200d-2640-fe0f","🤹🏾‍♀️":"1f939-1f3fe-200d-2640-fe0f","🤹🏿‍♀️":"1f939-1f3ff-200d-2640-fe0f","🧘🏻‍♂️":"1f9d8-1f3fb-200d-2642-fe0f","🧘🏼‍♂️":"1f9d8-1f3fc-200d-2642-fe0f","🧘🏽‍♂️":"1f9d8-1f3fd-200d-2642-fe0f","🧘🏾‍♂️":"1f9d8-1f3fe-200d-2642-fe0f","🧘🏿‍♂️":"1f9d8-1f3ff-200d-2642-fe0f","🧘🏻‍♀️":"1f9d8-1f3fb-200d-2640-fe0f","🧘🏼‍♀️":"1f9d8-1f3fc-200d-2640-fe0f","🧘🏽‍♀️":"1f9d8-1f3fd-200d-2640-fe0f","🧘🏾‍♀️":"1f9d8-1f3fe-200d-2640-fe0f","🧘🏿‍♀️":"1f9d8-1f3ff-200d-2640-fe0f","🧑‍🤝‍🧑":"1f9d1-200d-1f91d-200d-1f9d1","👩‍❤‍👨":"1f469-200d-2764-fe0f-200d-1f468","👨‍❤‍👨":"1f468-200d-2764-fe0f-200d-1f468","👩‍❤‍👩":"1f469-200d-2764-fe0f-200d-1f469","👨‍👩‍👦":"1f468-200d-1f469-200d-1f466","👨‍👩‍👧":"1f468-200d-1f469-200d-1f467","👨‍👨‍👦":"1f468-200d-1f468-200d-1f466","👨‍👨‍👧":"1f468-200d-1f468-200d-1f467","👩‍👩‍👦":"1f469-200d-1f469-200d-1f466","👩‍👩‍👧":"1f469-200d-1f469-200d-1f467","👨‍👦‍👦":"1f468-200d-1f466-200d-1f466","👨‍👧‍👦":"1f468-200d-1f467-200d-1f466","👨‍👧‍👧":"1f468-200d-1f467-200d-1f467","👩‍👦‍👦":"1f469-200d-1f466-200d-1f466","👩‍👧‍👦":"1f469-200d-1f467-200d-1f466","👩‍👧‍👧":"1f469-200d-1f467-200d-1f467","🏳️‍⚧️":"1f3f3-fe0f-200d-26a7-fe0f","👩‍❤️‍👨":"1f469-200d-2764-fe0f-200d-1f468","👨‍❤️‍👨":"1f468-200d-2764-fe0f-200d-1f468","👩‍❤️‍👩":"1f469-200d-2764-fe0f-200d-1f469","🧑🏻‍🤝‍🧑🏻":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fb","🧑🏻‍🤝‍🧑🏼":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fc","🧑🏻‍🤝‍🧑🏽":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fd","🧑🏻‍🤝‍🧑🏾":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fe","🧑🏻‍🤝‍🧑🏿":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3ff","🧑🏼‍🤝‍🧑🏻":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fb","🧑🏼‍🤝‍🧑🏼":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fc","🧑🏼‍🤝‍🧑🏽":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fd","🧑🏼‍🤝‍🧑🏾":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fe","🧑🏼‍🤝‍🧑🏿":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3ff","🧑🏽‍🤝‍🧑🏻":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fb","🧑🏽‍🤝‍🧑🏼":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fc","🧑🏽‍🤝‍🧑🏽":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fd","🧑🏽‍🤝‍🧑🏾":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fe","🧑🏽‍🤝‍🧑🏿":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3ff","🧑🏾‍🤝‍🧑🏻":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fb","🧑🏾‍🤝‍🧑🏼":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fc","🧑🏾‍🤝‍🧑🏽":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fd","🧑🏾‍🤝‍🧑🏾":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fe","🧑🏾‍🤝‍🧑🏿":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3ff","🧑🏿‍🤝‍🧑🏻":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fb","🧑🏿‍🤝‍🧑🏼":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fc","🧑🏿‍🤝‍🧑🏽":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fd","🧑🏿‍🤝‍🧑🏾":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fe","🧑🏿‍🤝‍🧑🏿":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3ff","👩🏻‍🤝‍👩🏼":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fc","👩🏻‍🤝‍👩🏽":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fd","👩🏻‍🤝‍👩🏾":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fe","👩🏻‍🤝‍👩🏿":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3ff","👩🏼‍🤝‍👩🏻":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fb","👩🏼‍🤝‍👩🏽":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fd","👩🏼‍🤝‍👩🏾":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fe","👩🏼‍🤝‍👩🏿":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3ff","👩🏽‍🤝‍👩🏻":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fb","👩🏽‍🤝‍👩🏼":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fc","👩🏽‍🤝‍👩🏾":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fe","👩🏽‍🤝‍👩🏿":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3ff","👩🏾‍🤝‍👩🏻":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fb","👩🏾‍🤝‍👩🏼":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fc","👩🏾‍🤝‍👩🏽":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fd","👩🏾‍🤝‍👩🏿":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3ff","👩🏿‍🤝‍👩🏻":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fb","👩🏿‍🤝‍👩🏼":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fc","👩🏿‍🤝‍👩🏽":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fd","👩🏿‍🤝‍👩🏾":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fe","👩🏻‍🤝‍👨🏼":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fc","👩🏻‍🤝‍👨🏽":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fd","👩🏻‍🤝‍👨🏾":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fe","👩🏻‍🤝‍👨🏿":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3ff","👩🏼‍🤝‍👨🏻":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fb","👩🏼‍🤝‍👨🏽":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fd","👩🏼‍🤝‍👨🏾":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fe","👩🏼‍🤝‍👨🏿":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3ff","👩🏽‍🤝‍👨🏻":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fb","👩🏽‍🤝‍👨🏼":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fc","👩🏽‍🤝‍👨🏾":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fe","👩🏽‍🤝‍👨🏿":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3ff","👩🏾‍🤝‍👨🏻":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fb","👩🏾‍🤝‍👨🏼":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fc","👩🏾‍🤝‍👨🏽":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fd","👩🏾‍🤝‍👨🏿":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3ff","👩🏿‍🤝‍👨🏻":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fb","👩🏿‍🤝‍👨🏼":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fc","👩🏿‍🤝‍👨🏽":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fd","👩🏿‍🤝‍👨🏾":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fe","👨🏻‍🤝‍👨🏼":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fc","👨🏻‍🤝‍👨🏽":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fd","👨🏻‍🤝‍👨🏾":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fe","👨🏻‍🤝‍👨🏿":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3ff","👨🏼‍🤝‍👨🏻":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fb","👨🏼‍🤝‍👨🏽":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fd","👨🏼‍🤝‍👨🏾":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fe","👨🏼‍🤝‍👨🏿":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3ff","👨🏽‍🤝‍👨🏻":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fb","👨🏽‍🤝‍👨🏼":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fc","👨🏽‍🤝‍👨🏾":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fe","👨🏽‍🤝‍👨🏿":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3ff","👨🏾‍🤝‍👨🏻":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fb","👨🏾‍🤝‍👨🏼":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fc","👨🏾‍🤝‍👨🏽":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fd","👨🏾‍🤝‍👨🏿":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3ff","👨🏿‍🤝‍👨🏻":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fb","👨🏿‍🤝‍👨🏼":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fc","👨🏿‍🤝‍👨🏽":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fd","👨🏿‍🤝‍👨🏾":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fe","👩‍❤‍💋‍👨":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468","👨‍❤‍💋‍👨":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468","👩‍❤‍💋‍👩":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469","🧑🏻‍❤‍🧑🏼":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏻‍❤‍🧑🏽":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏻‍❤‍🧑🏾":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏻‍❤‍🧑🏿":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏼‍❤‍🧑🏻":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏼‍❤‍🧑🏽":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏼‍❤‍🧑🏾":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏼‍❤‍🧑🏿":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏽‍❤‍🧑🏻":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏽‍❤‍🧑🏼":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏽‍❤‍🧑🏾":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏽‍❤‍🧑🏿":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏾‍❤‍🧑🏻":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏾‍❤‍🧑🏼":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏾‍❤‍🧑🏽":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏾‍❤‍🧑🏿":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏿‍❤‍🧑🏻":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏿‍❤‍🧑🏼":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏿‍❤‍🧑🏽":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏿‍❤‍🧑🏾":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fe","👩🏻‍❤‍👨🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb","👩🏻‍❤‍👨🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc","👩🏻‍❤‍👨🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd","👩🏻‍❤‍👨🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe","👩🏻‍❤‍👨🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff","👩🏼‍❤‍👨🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb","👩🏼‍❤‍👨🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc","👩🏼‍❤‍👨🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd","👩🏼‍❤‍👨🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe","👩🏼‍❤‍👨🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff","👩🏽‍❤‍👨🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb","👩🏽‍❤‍👨🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc","👩🏽‍❤‍👨🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd","👩🏽‍❤‍👨🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe","👩🏽‍❤‍👨🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff","👩🏾‍❤‍👨🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb","👩🏾‍❤‍👨🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc","👩🏾‍❤‍👨🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd","👩🏾‍❤‍👨🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe","👩🏾‍❤‍👨🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff","👩🏿‍❤‍👨🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb","👩🏿‍❤‍👨🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc","👩🏿‍❤‍👨🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd","👩🏿‍❤‍👨🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe","👩🏿‍❤‍👨🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff","👨🏻‍❤‍👨🏻":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb","👨🏻‍❤‍👨🏼":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc","👨🏻‍❤‍👨🏽":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd","👨🏻‍❤‍👨🏾":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe","👨🏻‍❤‍👨🏿":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff","👨🏼‍❤‍👨🏻":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb","👨🏼‍❤‍👨🏼":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc","👨🏼‍❤‍👨🏽":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd","👨🏼‍❤‍👨🏾":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe","👨🏼‍❤‍👨🏿":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff","👨🏽‍❤‍👨🏻":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb","👨🏽‍❤‍👨🏼":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc","👨🏽‍❤‍👨🏽":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd","👨🏽‍❤‍👨🏾":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe","👨🏽‍❤‍👨🏿":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff","👨🏾‍❤‍👨🏻":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb","👨🏾‍❤‍👨🏼":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc","👨🏾‍❤‍👨🏽":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd","👨🏾‍❤‍👨🏾":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe","👨🏾‍❤‍👨🏿":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff","👨🏿‍❤‍👨🏻":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb","👨🏿‍❤‍👨🏼":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc","👨🏿‍❤‍👨🏽":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd","👨🏿‍❤‍👨🏾":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe","👨🏿‍❤‍👨🏿":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff","👩🏻‍❤‍👩🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fb","👩🏻‍❤‍👩🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fc","👩🏻‍❤‍👩🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fd","👩🏻‍❤‍👩🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fe","👩🏻‍❤‍👩🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3ff","👩🏼‍❤‍👩🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fb","👩🏼‍❤‍👩🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fc","👩🏼‍❤‍👩🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fd","👩🏼‍❤‍👩🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fe","👩🏼‍❤‍👩🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3ff","👩🏽‍❤‍👩🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fb","👩🏽‍❤‍👩🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fc","👩🏽‍❤‍👩🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fd","👩🏽‍❤‍👩🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fe","👩🏽‍❤‍👩🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3ff","👩🏾‍❤‍👩🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fb","👩🏾‍❤‍👩🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fc","👩🏾‍❤‍👩🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fd","👩🏾‍❤‍👩🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fe","👩🏾‍❤‍👩🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3ff","👩🏿‍❤‍👩🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fb","👩🏿‍❤‍👩🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fc","👩🏿‍❤‍👩🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fd","👩🏿‍❤‍👩🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fe","👩🏿‍❤‍👩🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3ff","👨‍👩‍👧‍👦":"1f468-200d-1f469-200d-1f467-200d-1f466","👨‍👩‍👦‍👦":"1f468-200d-1f469-200d-1f466-200d-1f466","👨‍👩‍👧‍👧":"1f468-200d-1f469-200d-1f467-200d-1f467","👨‍👨‍👧‍👦":"1f468-200d-1f468-200d-1f467-200d-1f466","👨‍👨‍👦‍👦":"1f468-200d-1f468-200d-1f466-200d-1f466","👨‍👨‍👧‍👧":"1f468-200d-1f468-200d-1f467-200d-1f467","👩‍👩‍👧‍👦":"1f469-200d-1f469-200d-1f467-200d-1f466","👩‍👩‍👦‍👦":"1f469-200d-1f469-200d-1f466-200d-1f466","👩‍👩‍👧‍👧":"1f469-200d-1f469-200d-1f467-200d-1f467","🏴󠁧󠁢󠁥󠁮󠁧󠁿":"1f3f4-e0067-e0062-e0065-e006e-e0067-e007f","🏴󠁧󠁢󠁳󠁣󠁴󠁿":"1f3f4-e0067-e0062-e0073-e0063-e0074-e007f","🏴󠁧󠁢󠁷󠁬󠁳󠁿":"1f3f4-e0067-e0062-e0077-e006c-e0073-e007f","👩‍❤️‍💋‍👨":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468","👨‍❤️‍💋‍👨":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468","👩‍❤️‍💋‍👩":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469","🧑🏻‍❤️‍🧑🏼":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏻‍❤️‍🧑🏽":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏻‍❤️‍🧑🏾":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏻‍❤️‍🧑🏿":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏼‍❤️‍🧑🏻":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏼‍❤️‍🧑🏽":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏼‍❤️‍🧑🏾":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏼‍❤️‍🧑🏿":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏽‍❤️‍🧑🏻":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏽‍❤️‍🧑🏼":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏽‍❤️‍🧑🏾":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fe","🧑🏽‍❤️‍🧑🏿":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏾‍❤️‍🧑🏻":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏾‍❤️‍🧑🏼":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏾‍❤️‍🧑🏽":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏾‍❤️‍🧑🏿":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3ff","🧑🏿‍❤️‍🧑🏻":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fb","🧑🏿‍❤️‍🧑🏼":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fc","🧑🏿‍❤️‍🧑🏽":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fd","🧑🏿‍❤️‍🧑🏾":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fe","👩🏻‍❤️‍👨🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb","👩🏻‍❤️‍👨🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc","👩🏻‍❤️‍👨🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd","👩🏻‍❤️‍👨🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe","👩🏻‍❤️‍👨🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff","👩🏼‍❤️‍👨🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb","👩🏼‍❤️‍👨🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc","👩🏼‍❤️‍👨🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd","👩🏼‍❤️‍👨🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe","👩🏼‍❤️‍👨🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff","👩🏽‍❤️‍👨🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb","👩🏽‍❤️‍👨🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc","👩🏽‍❤️‍👨🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd","👩🏽‍❤️‍👨🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe","👩🏽‍❤️‍👨🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff","👩🏾‍❤️‍👨🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb","👩🏾‍❤️‍👨🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc","👩🏾‍❤️‍👨🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd","👩🏾‍❤️‍👨🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe","👩🏾‍❤️‍👨🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff","👩🏿‍❤️‍👨🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb","👩🏿‍❤️‍👨🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc","👩🏿‍❤️‍👨🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd","👩🏿‍❤️‍👨🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe","👩🏿‍❤️‍👨🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff","👨🏻‍❤️‍👨🏻":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb","👨🏻‍❤️‍👨🏼":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc","👨🏻‍❤️‍👨🏽":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd","👨🏻‍❤️‍👨🏾":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe","👨🏻‍❤️‍👨🏿":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff","👨🏼‍❤️‍👨🏻":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb","👨🏼‍❤️‍👨🏼":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc","👨🏼‍❤️‍👨🏽":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd","👨🏼‍❤️‍👨🏾":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe","👨🏼‍❤️‍👨🏿":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff","👨🏽‍❤️‍👨🏻":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb","👨🏽‍❤️‍👨🏼":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc","👨🏽‍❤️‍👨🏽":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd","👨🏽‍❤️‍👨🏾":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe","👨🏽‍❤️‍👨🏿":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff","👨🏾‍❤️‍👨🏻":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb","👨🏾‍❤️‍👨🏼":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc","👨🏾‍❤️‍👨🏽":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd","👨🏾‍❤️‍👨🏾":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe","👨🏾‍❤️‍👨🏿":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff","👨🏿‍❤️‍👨🏻":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb","👨🏿‍❤️‍👨🏼":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc","👨🏿‍❤️‍👨🏽":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd","👨🏿‍❤️‍👨🏾":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe","👨🏿‍❤️‍👨🏿":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff","👩🏻‍❤️‍👩🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fb","👩🏻‍❤️‍👩🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fc","👩🏻‍❤️‍👩🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fd","👩🏻‍❤️‍👩🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fe","👩🏻‍❤️‍👩🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3ff","👩🏼‍❤️‍👩🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fb","👩🏼‍❤️‍👩🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fc","👩🏼‍❤️‍👩🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fd","👩🏼‍❤️‍👩🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fe","👩🏼‍❤️‍👩🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3ff","👩🏽‍❤️‍👩🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fb","👩🏽‍❤️‍👩🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fc","👩🏽‍❤️‍👩🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fd","👩🏽‍❤️‍👩🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fe","👩🏽‍❤️‍👩🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3ff","👩🏾‍❤️‍👩🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fb","👩🏾‍❤️‍👩🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fc","👩🏾‍❤️‍👩🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fd","👩🏾‍❤️‍👩🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fe","👩🏾‍❤️‍👩🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3ff","👩🏿‍❤️‍👩🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fb","👩🏿‍❤️‍👩🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fc","👩🏿‍❤️‍👩🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fd","👩🏿‍❤️‍👩🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fe","👩🏿‍❤️‍👩🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3ff","🧑🏻‍❤‍💋‍🧑🏼":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏻‍❤‍💋‍🧑🏽":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏻‍❤‍💋‍🧑🏾":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏻‍❤‍💋‍🧑🏿":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏼‍❤‍💋‍🧑🏻":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏼‍❤‍💋‍🧑🏽":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏼‍❤‍💋‍🧑🏾":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏼‍❤‍💋‍🧑🏿":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏽‍❤‍💋‍🧑🏻":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏽‍❤‍💋‍🧑🏼":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏽‍❤‍💋‍🧑🏾":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏽‍❤‍💋‍🧑🏿":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏾‍❤‍💋‍🧑🏻":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏾‍❤‍💋‍🧑🏼":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏾‍❤‍💋‍🧑🏽":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏾‍❤‍💋‍🧑🏿":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏿‍❤‍💋‍🧑🏻":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏿‍❤‍💋‍🧑🏼":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏿‍❤‍💋‍🧑🏽":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏿‍❤‍💋‍🧑🏾":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","👩🏻‍❤‍💋‍👨🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏻‍❤‍💋‍👨🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏻‍❤‍💋‍👨🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏻‍❤‍💋‍👨🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏻‍❤‍💋‍👨🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏼‍❤‍💋‍👨🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏼‍❤‍💋‍👨🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏼‍❤‍💋‍👨🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏼‍❤‍💋‍👨🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏼‍❤‍💋‍👨🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏽‍❤‍💋‍👨🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏽‍❤‍💋‍👨🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏽‍❤‍💋‍👨🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏽‍❤‍💋‍👨🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏽‍❤‍💋‍👨🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏾‍❤‍💋‍👨🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏾‍❤‍💋‍👨🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏾‍❤‍💋‍👨🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏾‍❤‍💋‍👨🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏾‍❤‍💋‍👨🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏿‍❤‍💋‍👨🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏿‍❤‍💋‍👨🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏿‍❤‍💋‍👨🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏿‍❤‍💋‍👨🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏿‍❤‍💋‍👨🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏻‍❤‍💋‍👨🏻":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏻‍❤‍💋‍👨🏼":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏻‍❤‍💋‍👨🏽":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏻‍❤‍💋‍👨🏾":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏻‍❤‍💋‍👨🏿":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏼‍❤‍💋‍👨🏻":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏼‍❤‍💋‍👨🏼":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏼‍❤‍💋‍👨🏽":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏼‍❤‍💋‍👨🏾":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏼‍❤‍💋‍👨🏿":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏽‍❤‍💋‍👨🏻":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏽‍❤‍💋‍👨🏼":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏽‍❤‍💋‍👨🏽":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏽‍❤‍💋‍👨🏾":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏽‍❤‍💋‍👨🏿":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏾‍❤‍💋‍👨🏻":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏾‍❤‍💋‍👨🏼":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏾‍❤‍💋‍👨🏽":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏾‍❤‍💋‍👨🏾":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏾‍❤‍💋‍👨🏿":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏿‍❤‍💋‍👨🏻":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏿‍❤‍💋‍👨🏼":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏿‍❤‍💋‍👨🏽":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏿‍❤‍💋‍👨🏾":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏿‍❤‍💋‍👨🏿":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏻‍❤‍💋‍👩🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏻‍❤‍💋‍👩🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏻‍❤‍💋‍👩🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏻‍❤‍💋‍👩🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏻‍❤‍💋‍👩🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏼‍❤‍💋‍👩🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏼‍❤‍💋‍👩🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏼‍❤‍💋‍👩🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏼‍❤‍💋‍👩🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏼‍❤‍💋‍👩🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏽‍❤‍💋‍👩🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏽‍❤‍💋‍👩🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏽‍❤‍💋‍👩🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏽‍❤‍💋‍👩🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏽‍❤‍💋‍👩🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏾‍❤‍💋‍👩🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏾‍❤‍💋‍👩🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏾‍❤‍💋‍👩🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏾‍❤‍💋‍👩🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏾‍❤‍💋‍👩🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏿‍❤‍💋‍👩🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏿‍❤‍💋‍👩🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏿‍❤‍💋‍👩🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏿‍❤‍💋‍👩🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏿‍❤‍💋‍👩🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","🧑🏻‍❤️‍💋‍🧑🏼":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏻‍❤️‍💋‍🧑🏽":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏻‍❤️‍💋‍🧑🏾":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏻‍❤️‍💋‍🧑🏿":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏼‍❤️‍💋‍🧑🏻":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏼‍❤️‍💋‍🧑🏽":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏼‍❤️‍💋‍🧑🏾":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏼‍❤️‍💋‍🧑🏿":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏽‍❤️‍💋‍🧑🏻":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏽‍❤️‍💋‍🧑🏼":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏽‍❤️‍💋‍🧑🏾":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","🧑🏽‍❤️‍💋‍🧑🏿":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏾‍❤️‍💋‍🧑🏻":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏾‍❤️‍💋‍🧑🏼":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏾‍❤️‍💋‍🧑🏽":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏾‍❤️‍💋‍🧑🏿":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff","🧑🏿‍❤️‍💋‍🧑🏻":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb","🧑🏿‍❤️‍💋‍🧑🏼":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc","🧑🏿‍❤️‍💋‍🧑🏽":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd","🧑🏿‍❤️‍💋‍🧑🏾":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe","👩🏻‍❤️‍💋‍👨🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏻‍❤️‍💋‍👨🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏻‍❤️‍💋‍👨🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏻‍❤️‍💋‍👨🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏻‍❤️‍💋‍👨🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏼‍❤️‍💋‍👨🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏼‍❤️‍💋‍👨🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏼‍❤️‍💋‍👨🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏼‍❤️‍💋‍👨🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏼‍❤️‍💋‍👨🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏽‍❤️‍💋‍👨🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏽‍❤️‍💋‍👨🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏽‍❤️‍💋‍👨🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏽‍❤️‍💋‍👨🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏽‍❤️‍💋‍👨🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏾‍❤️‍💋‍👨🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏾‍❤️‍💋‍👨🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏾‍❤️‍💋‍👨🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏾‍❤️‍💋‍👨🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏾‍❤️‍💋‍👨🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏿‍❤️‍💋‍👨🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👩🏿‍❤️‍💋‍👨🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👩🏿‍❤️‍💋‍👨🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👩🏿‍❤️‍💋‍👨🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👩🏿‍❤️‍💋‍👨🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏻‍❤️‍💋‍👨🏻":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏻‍❤️‍💋‍👨🏼":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏻‍❤️‍💋‍👨🏽":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏻‍❤️‍💋‍👨🏾":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏻‍❤️‍💋‍👨🏿":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏼‍❤️‍💋‍👨🏻":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏼‍❤️‍💋‍👨🏼":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏼‍❤️‍💋‍👨🏽":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏼‍❤️‍💋‍👨🏾":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏼‍❤️‍💋‍👨🏿":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏽‍❤️‍💋‍👨🏻":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏽‍❤️‍💋‍👨🏼":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏽‍❤️‍💋‍👨🏽":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏽‍❤️‍💋‍👨🏾":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏽‍❤️‍💋‍👨🏿":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏾‍❤️‍💋‍👨🏻":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏾‍❤️‍💋‍👨🏼":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏾‍❤️‍💋‍👨🏽":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏾‍❤️‍💋‍👨🏾":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏾‍❤️‍💋‍👨🏿":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👨🏿‍❤️‍💋‍👨🏻":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb","👨🏿‍❤️‍💋‍👨🏼":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc","👨🏿‍❤️‍💋‍👨🏽":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd","👨🏿‍❤️‍💋‍👨🏾":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe","👨🏿‍❤️‍💋‍👨🏿":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff","👩🏻‍❤️‍💋‍👩🏻":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏻‍❤️‍💋‍👩🏼":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏻‍❤️‍💋‍👩🏽":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏻‍❤️‍💋‍👩🏾":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏻‍❤️‍💋‍👩🏿":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏼‍❤️‍💋‍👩🏻":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏼‍❤️‍💋‍👩🏼":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏼‍❤️‍💋‍👩🏽":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏼‍❤️‍💋‍👩🏾":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏼‍❤️‍💋‍👩🏿":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏽‍❤️‍💋‍👩🏻":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏽‍❤️‍💋‍👩🏼":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏽‍❤️‍💋‍👩🏽":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏽‍❤️‍💋‍👩🏾":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏽‍❤️‍💋‍👩🏿":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏾‍❤️‍💋‍👩🏻":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏾‍❤️‍💋‍👩🏼":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏾‍❤️‍💋‍👩🏽":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏾‍❤️‍💋‍👩🏾":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏾‍❤️‍💋‍👩🏿":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff","👩🏿‍❤️‍💋‍👩🏻":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb","👩🏿‍❤️‍💋‍👩🏼":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc","👩🏿‍❤️‍💋‍👩🏽":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd","👩🏿‍❤️‍💋‍👩🏾":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe","👩🏿‍❤️‍💋‍👩🏿":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff"} \ No newline at end of file diff --git a/lib/tasks/emojis.rake b/lib/tasks/emojis.rake index c24ea42e7d..e9fea2deea 100644 --- a/lib/tasks/emojis.rake +++ b/lib/tasks/emojis.rake @@ -45,7 +45,7 @@ end namespace :emojis do desc 'Generate a unicode to filename mapping' task :generate do - source = 'http://www.unicode.org/Public/emoji/14.0/emoji-test.txt' + source = 'http://www.unicode.org/Public/emoji/15.0/emoji-test.txt' codes = [] dest = Rails.root.join('app', 'javascript', 'mastodon', 'features', 'emoji', 'emoji_map.json') @@ -91,8 +91,8 @@ namespace :emojis do desc 'Generate emoji variants with white borders' task :generate_borders do src = Rails.root.join('app', 'javascript', 'mastodon', 'features', 'emoji', 'emoji_map.json') - emojis_light = '👽⚾🐔☁️💨🕊️👀🍥👻🐐❕❔⛸️🌩️🔊🔇📃🌧️🐏🍚🍙🐓🐑💀☠️🌨️🔉🔈💬💭🏐🏳️⚪⬜◽◻️▫️' - emojis_dark = '🎱🐜⚫🖤⬛◼️◾◼️✒️▪️💣🎳📷📸♣️🕶️✴️🔌💂‍♀️📽️🍳🦍💂🔪🕳️🕹️🕋🖊️🖋️💂‍♂️🎤🎓🎥🎼♠️🎩🦃📼📹🎮🐃🏴🐞🕺📱📲🚲' + emojis_light = '👽⚾🐔☁️💨🕊️👀🍥👻🐐❕❔⛸️🌩️🔊🔇📃🌧️🐏🍚🍙🐓🐑💀☠️🌨️🔉🔈💬💭🏐🏳️⚪⬜◽◻️▫️🪽🪿' + emojis_dark = '🎱🐜⚫🖤⬛◼️◾◼️✒️▪️💣🎳📷📸♣️🕶️✴️🔌💂‍♀️📽️🍳🦍💂🔪🕳️🕹️🕋🖊️🖋️💂‍♂️🎤🎓🎥🎼♠️🎩🦃📼📹🎮🐃🏴🐞🕺📱📲🚲🪮🐦‍⬛' map = Oj.load(File.read(src)) diff --git a/public/emoji/1f1f2-1f1fe.svg b/public/emoji/1f1f2-1f1fe.svg index 0480330cd0..29a3e3f794 100644 --- a/public/emoji/1f1f2-1f1fe.svg +++ b/public/emoji/1f1f2-1f1fe.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/emoji/1f301.svg b/public/emoji/1f301.svg index d6298de42d..dfec948364 100644 --- a/public/emoji/1f301.svg +++ b/public/emoji/1f301.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/emoji/1f3e5.svg b/public/emoji/1f3e5.svg index 0b2748a523..33884c8ceb 100644 --- a/public/emoji/1f3e5.svg +++ b/public/emoji/1f3e5.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/emoji/1f426-200d-2b1b.svg b/public/emoji/1f426-200d-2b1b.svg new file mode 100755 index 0000000000..07908724aa --- /dev/null +++ b/public/emoji/1f426-200d-2b1b.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1f426-200d-2b1b_border.svg b/public/emoji/1f426-200d-2b1b_border.svg new file mode 100644 index 0000000000..f0be16a32b --- /dev/null +++ b/public/emoji/1f426-200d-2b1b_border.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/emoji/1f50f.svg b/public/emoji/1f50f.svg index d2ae4863c4..d4e864daae 100644 --- a/public/emoji/1f50f.svg +++ b/public/emoji/1f50f.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/emoji/1f510.svg b/public/emoji/1f510.svg index 014079e8b1..45f288f106 100644 --- a/public/emoji/1f510.svg +++ b/public/emoji/1f510.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/emoji/1f512.svg b/public/emoji/1f512.svg index 378fabf403..4cd1facae8 100644 --- a/public/emoji/1f512.svg +++ b/public/emoji/1f512.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/emoji/1f513.svg b/public/emoji/1f513.svg index cd82ec8e3f..b9ffd7b936 100644 --- a/public/emoji/1f513.svg +++ b/public/emoji/1f513.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/emoji/1f691.svg b/public/emoji/1f691.svg index 844dd40f0b..e6b1cc7bae 100644 --- a/public/emoji/1f691.svg +++ b/public/emoji/1f691.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/emoji/1f6dc.svg b/public/emoji/1f6dc.svg new file mode 100644 index 0000000000..364a68e74e --- /dev/null +++ b/public/emoji/1f6dc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1f979.svg b/public/emoji/1f979.svg old mode 100755 new mode 100644 index 1944a5463a..fff9243190 --- a/public/emoji/1f979.svg +++ b/public/emoji/1f979.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/emoji/1f97a.svg b/public/emoji/1f97a.svg index fe9336084a..3240471fbd 100644 --- a/public/emoji/1f97a.svg +++ b/public/emoji/1f97a.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/public/emoji/1fa75.svg b/public/emoji/1fa75.svg new file mode 100755 index 0000000000..5a72101acb --- /dev/null +++ b/public/emoji/1fa75.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fa76.svg b/public/emoji/1fa76.svg new file mode 100755 index 0000000000..56e3ef1ae9 --- /dev/null +++ b/public/emoji/1fa76.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fa77.svg b/public/emoji/1fa77.svg new file mode 100755 index 0000000000..a372dcce63 --- /dev/null +++ b/public/emoji/1fa77.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fa87.svg b/public/emoji/1fa87.svg new file mode 100644 index 0000000000..fd8c53a663 --- /dev/null +++ b/public/emoji/1fa87.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fa88.svg b/public/emoji/1fa88.svg new file mode 100755 index 0000000000..633fa4c62c --- /dev/null +++ b/public/emoji/1fa88.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faad.svg b/public/emoji/1faad.svg new file mode 100644 index 0000000000..503632391d --- /dev/null +++ b/public/emoji/1faad.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faae.svg b/public/emoji/1faae.svg new file mode 100644 index 0000000000..e8ad033fb1 --- /dev/null +++ b/public/emoji/1faae.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faae_border.svg b/public/emoji/1faae_border.svg new file mode 100644 index 0000000000..6b59fee57b --- /dev/null +++ b/public/emoji/1faae_border.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/emoji/1faaf.svg b/public/emoji/1faaf.svg new file mode 100644 index 0000000000..bfaceb5395 --- /dev/null +++ b/public/emoji/1faaf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fabb.svg b/public/emoji/1fabb.svg new file mode 100644 index 0000000000..3cae81a662 --- /dev/null +++ b/public/emoji/1fabb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fabc.svg b/public/emoji/1fabc.svg new file mode 100644 index 0000000000..cb8c4eef40 --- /dev/null +++ b/public/emoji/1fabc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fabd.svg b/public/emoji/1fabd.svg new file mode 100644 index 0000000000..9effe33338 --- /dev/null +++ b/public/emoji/1fabd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fabd_border.svg b/public/emoji/1fabd_border.svg new file mode 100644 index 0000000000..30184ea09a --- /dev/null +++ b/public/emoji/1fabd_border.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/emoji/1fabf.svg b/public/emoji/1fabf.svg new file mode 100644 index 0000000000..7c0f6a6b8b --- /dev/null +++ b/public/emoji/1fabf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fabf_border.svg b/public/emoji/1fabf_border.svg new file mode 100644 index 0000000000..42b1f98013 --- /dev/null +++ b/public/emoji/1fabf_border.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/public/emoji/1face.svg b/public/emoji/1face.svg new file mode 100644 index 0000000000..f419d66350 --- /dev/null +++ b/public/emoji/1face.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1facf.svg b/public/emoji/1facf.svg new file mode 100644 index 0000000000..030b0bd8d2 --- /dev/null +++ b/public/emoji/1facf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fada.svg b/public/emoji/1fada.svg new file mode 100644 index 0000000000..2094a77023 --- /dev/null +++ b/public/emoji/1fada.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fadb.svg b/public/emoji/1fadb.svg new file mode 100644 index 0000000000..e68a96d9f1 --- /dev/null +++ b/public/emoji/1fadb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1fae8.svg b/public/emoji/1fae8.svg new file mode 100644 index 0000000000..02ab52d88e --- /dev/null +++ b/public/emoji/1fae8.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf7-1f3fb.svg b/public/emoji/1faf7-1f3fb.svg new file mode 100644 index 0000000000..5df3bd18c4 --- /dev/null +++ b/public/emoji/1faf7-1f3fb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf7-1f3fc.svg b/public/emoji/1faf7-1f3fc.svg new file mode 100644 index 0000000000..6633504ee3 --- /dev/null +++ b/public/emoji/1faf7-1f3fc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf7-1f3fd.svg b/public/emoji/1faf7-1f3fd.svg new file mode 100644 index 0000000000..752c49b4f1 --- /dev/null +++ b/public/emoji/1faf7-1f3fd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf7-1f3fe.svg b/public/emoji/1faf7-1f3fe.svg new file mode 100644 index 0000000000..d4aaefc739 --- /dev/null +++ b/public/emoji/1faf7-1f3fe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf7-1f3ff.svg b/public/emoji/1faf7-1f3ff.svg new file mode 100644 index 0000000000..6735ce300a --- /dev/null +++ b/public/emoji/1faf7-1f3ff.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf7.svg b/public/emoji/1faf7.svg new file mode 100644 index 0000000000..1237887922 --- /dev/null +++ b/public/emoji/1faf7.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf8-1f3fb.svg b/public/emoji/1faf8-1f3fb.svg new file mode 100644 index 0000000000..3a28a11716 --- /dev/null +++ b/public/emoji/1faf8-1f3fb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf8-1f3fc.svg b/public/emoji/1faf8-1f3fc.svg new file mode 100644 index 0000000000..544719ebc8 --- /dev/null +++ b/public/emoji/1faf8-1f3fc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf8-1f3fd.svg b/public/emoji/1faf8-1f3fd.svg new file mode 100644 index 0000000000..607bcf2037 --- /dev/null +++ b/public/emoji/1faf8-1f3fd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf8-1f3fe.svg b/public/emoji/1faf8-1f3fe.svg new file mode 100644 index 0000000000..378fa2e3c5 --- /dev/null +++ b/public/emoji/1faf8-1f3fe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf8-1f3ff.svg b/public/emoji/1faf8-1f3ff.svg new file mode 100644 index 0000000000..b3cccfc6a0 --- /dev/null +++ b/public/emoji/1faf8-1f3ff.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/emoji/1faf8.svg b/public/emoji/1faf8.svg new file mode 100644 index 0000000000..fadecd83f0 --- /dev/null +++ b/public/emoji/1faf8.svg @@ -0,0 +1 @@ + \ No newline at end of file From 185c806d69efef28b8ec6b1431e53d01effed192 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 11:17:21 -0500 Subject: [PATCH 142/422] Extract spec helper for verifing to/from public AP collection namespace (#28472) --- .../activitypub/outboxes_controller_spec.rb | 22 ++++++++++++++++--- .../activitypub/replies_controller_spec.rb | 15 ++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/spec/controllers/activitypub/outboxes_controller_spec.rb b/spec/controllers/activitypub/outboxes_controller_spec.rb index 53c4f0c09c..ead231f29f 100644 --- a/spec/controllers/activitypub/outboxes_controller_spec.rb +++ b/spec/controllers/activitypub/outboxes_controller_spec.rb @@ -79,7 +79,7 @@ RSpec.describe ActivityPub::OutboxesController do it 'returns orderedItems with public or unlisted statuses' do expect(body[:orderedItems]).to be_an Array expect(body[:orderedItems].size).to eq 2 - expect(body[:orderedItems].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true + expect(body[:orderedItems].all? { |item| targets_public_collection?(item) }).to be true end it_behaves_like 'cacheable response' @@ -132,7 +132,7 @@ RSpec.describe ActivityPub::OutboxesController do json = body_as_json expect(json[:orderedItems]).to be_an Array expect(json[:orderedItems].size).to eq 2 - expect(json[:orderedItems].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true + expect(json[:orderedItems].all? { |item| targets_public_collection?(item) }).to be true end it 'returns private Cache-Control header' do @@ -158,7 +158,7 @@ RSpec.describe ActivityPub::OutboxesController do json = body_as_json expect(json[:orderedItems]).to be_an Array expect(json[:orderedItems].size).to eq 3 - expect(json[:orderedItems].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:to].include?(account_followers_url(account, ActionMailer::Base.default_url_options)) }).to be true + expect(json[:orderedItems].all? { |item| targets_public_collection?(item) || targets_followers_collection?(item, account) }).to be true end it 'returns private Cache-Control header' do @@ -217,4 +217,20 @@ RSpec.describe ActivityPub::OutboxesController do end end end + + private + + def ap_public_collection + ActivityPub::TagManager::COLLECTIONS[:public] + end + + def targets_public_collection?(item) + item[:to].include?(ap_public_collection) || item[:cc].include?(ap_public_collection) + end + + def targets_followers_collection?(item, account) + item[:to].include?( + account_followers_url(account, ActionMailer::Base.default_url_options) + ) + end end diff --git a/spec/controllers/activitypub/replies_controller_spec.rb b/spec/controllers/activitypub/replies_controller_spec.rb index 5fc9698a32..6b5a69d42a 100644 --- a/spec/controllers/activitypub/replies_controller_spec.rb +++ b/spec/controllers/activitypub/replies_controller_spec.rb @@ -84,7 +84,7 @@ RSpec.describe ActivityPub::RepliesController do expect(page_json).to be_a Hash expect(page_json[:items]).to be_an Array expect(page_json[:items].size).to eq 1 - expect(page_json[:items].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true + expect(page_json[:items].all? { |item| targets_public_collection?(item) }).to be true end context 'when there are few self-replies' do @@ -117,8 +117,7 @@ RSpec.describe ActivityPub::RepliesController do it 'only inlines items that are local and public or unlisted replies' do inlined_replies = page_json[:items].select { |x| x.is_a?(Hash) } - public_collection = ActivityPub::TagManager::COLLECTIONS[:public] - expect(inlined_replies.all? { |item| item[:to].include?(public_collection) || item[:cc].include?(public_collection) }).to be true + expect(inlined_replies.all? { |item| targets_public_collection?(item) }).to be true expect(inlined_replies.all? { |item| ActivityPub::TagManager.instance.local_uri?(item[:id]) }).to be true end @@ -194,4 +193,14 @@ RSpec.describe ActivityPub::RepliesController do end end end + + private + + def ap_public_collection + ActivityPub::TagManager::COLLECTIONS[:public] + end + + def targets_public_collection?(item) + item[:to].include?(ap_public_collection) || item[:cc].include?(ap_public_collection) + end end From 8b26614fa7fce5db7c9e4402679df0c8a833dfcf Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 11 Jan 2024 11:17:45 -0500 Subject: [PATCH 143/422] Combine results include check in spec/models/account (#28471) --- spec/models/account_spec.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index b4fcb805a6..1a4c14c45c 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -339,9 +339,11 @@ RSpec.describe Account do results = account.excluded_from_timeline_account_ids expect(results.size).to eq 3 - expect(results).to include(block.target_account.id) - expect(results).to include(mute.target_account.id) - expect(results).to include(block_by.account.id) + expect(results).to include( + block.target_account.id, + mute.target_account.id, + block_by.account.id + ) end end From 383be173afacae35130855fb7d625ff7565ac804 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Fri, 12 Jan 2024 04:39:11 +0100 Subject: [PATCH 144/422] Add a version comment to the emoji preval-ed file so it is regenerated (#28700) --- app/javascript/mastodon/features/emoji/emoji_compressed.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/emoji/emoji_compressed.js b/app/javascript/mastodon/features/emoji/emoji_compressed.js index 883bf21a4a..a4863566da 100644 --- a/app/javascript/mastodon/features/emoji/emoji_compressed.js +++ b/app/javascript/mastodon/features/emoji/emoji_compressed.js @@ -7,6 +7,10 @@ // It's designed to be emitted in an array format to take up less space // over the wire. +// This version comment should be bumped each time the emoji data is changed +// to ensure that the prevaled file is regenerated by Babel +// version: 2 + const { emojiIndex } = require('emoji-mart'); let data = require('emoji-mart/data/all.json'); const { uncompress: emojiMartUncompress } = require('emoji-mart/dist/utils/data'); @@ -15,7 +19,6 @@ const emojiMap = require('./emoji_map.json'); const { unicodeToFilename } = require('./unicode_to_filename'); const { unicodeToUnifiedName } = require('./unicode_to_unified_name'); - if(data.compressed) { data = emojiMartUncompress(data); } From 575ab085bec5730835330970e771db69a4758a7c Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:08:17 -0500 Subject: [PATCH 145/422] Disable `Rails/ApplicationController` for `HealthController` (#28705) --- .rubocop_todo.yml | 5 ----- app/controllers/health_controller.rb | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 6ab8957055..bf4a9a09fe 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -56,11 +56,6 @@ RSpec/MultipleMemoizedHelpers: RSpec/NestedGroups: Max: 6 -# This cop supports unsafe autocorrection (--autocorrect-all). -Rails/ApplicationController: - Exclude: - - 'app/controllers/health_controller.rb' - # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/HasAndBelongsToMany: diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb index 2a22a05570..7bc424d0a4 100644 --- a/app/controllers/health_controller.rb +++ b/app/controllers/health_controller.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class HealthController < ActionController::Base +class HealthController < ActionController::Base # rubocop:disable Rails/ApplicationController def show render plain: 'OK' end From 923fc831903c11ae5cc885c9454403007c77d734 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Fri, 12 Jan 2024 10:09:57 +0100 Subject: [PATCH 146/422] Improve `lint-staged` config (#28704) --- .prettierignore | 2 ++ lint-staged.config.js | 11 +++++++++++ package.json | 6 ------ streaming/package.json | 2 +- streaming/tsconfig.json | 1 + tsconfig.json | 2 ++ 6 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 lint-staged.config.js diff --git a/.prettierignore b/.prettierignore index 305f0fd753..51850b2b28 100644 --- a/.prettierignore +++ b/.prettierignore @@ -73,3 +73,5 @@ app/javascript/styles/mastodon/reset.scss # Ignore the generated AUTHORS.md AUTHORS.md + +!lint-staged.config.js diff --git a/lint-staged.config.js b/lint-staged.config.js new file mode 100644 index 0000000000..06fe66d11e --- /dev/null +++ b/lint-staged.config.js @@ -0,0 +1,11 @@ +const config = { + '*': 'prettier --ignore-unknown --write', + 'Capfile|Gemfile|*.{rb,ruby,ru,rake}': + 'bundle exec rubocop --force-exclusion -a', + '*.{js,jsx,ts,tsx}': 'eslint --fix', + '*.{css,scss}': 'stylelint --fix', + '*.haml': 'bundle exec haml-lint -a', + '**/*.ts?(x)': () => 'tsc -p tsconfig.json --noEmit', +}; + +module.exports = config; diff --git a/package.json b/package.json index 16ed4decaa..e3ba91f45c 100644 --- a/package.json +++ b/package.json @@ -218,11 +218,5 @@ "react-router-dom": { "optional": true } - }, - "lint-staged": { - "*": "prettier --ignore-unknown --write", - "Capfile|Gemfile|*.{rb,ruby,ru,rake}": "bundle exec rubocop --force-exclusion -a", - "*.{js,jsx,ts,tsx}": "eslint --fix", - "*.{css,scss}": "stylelint --fix" } } diff --git a/streaming/package.json b/streaming/package.json index 2d70acb829..149055ca1b 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -13,7 +13,7 @@ }, "scripts": { "start": "node ./index.js", - "check:types": "tsc --noEmit" + "typecheck": "tsc --noEmit" }, "dependencies": { "cors": "^2.8.5", diff --git a/streaming/tsconfig.json b/streaming/tsconfig.json index 032274d856..f7bb711b9b 100644 --- a/streaming/tsconfig.json +++ b/streaming/tsconfig.json @@ -5,6 +5,7 @@ "module": "CommonJS", "moduleResolution": "node", "noUnusedParameters": false, + "tsBuildInfoFile": "../tmp/cache/streaming/tsconfig.tsbuildinfo", "paths": {} }, "include": ["./*.js", "./.eslintrc.js"] diff --git a/tsconfig.json b/tsconfig.json index ff9da29497..d1a77e5493 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,8 @@ "esModuleInterop": true, "skipLibCheck": true, "baseUrl": "./", + "incremental": true, + "tsBuildInfoFile": "tmp/cache/tsconfig.tsbuildinfo", "paths": { "mastodon": ["app/javascript/mastodon"], "mastodon/*": ["app/javascript/mastodon/*"] From 32eeca9c7b59c156425c6b16c0014dcdcd7fb739 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:10:37 -0500 Subject: [PATCH 147/422] Refresh instance counts in spec (fixes intermittent failure) (#28698) --- spec/controllers/admin/instances_controller_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/controllers/admin/instances_controller_spec.rb b/spec/controllers/admin/instances_controller_spec.rb index 74d69d1aaa..e6fa0b9def 100644 --- a/spec/controllers/admin/instances_controller_spec.rb +++ b/spec/controllers/admin/instances_controller_spec.rb @@ -12,6 +12,8 @@ RSpec.describe Admin::InstancesController do before do _account_less_popular = Fabricate(:account, domain: 'less.popular') _account_popular_other = Fabricate(:account, domain: 'popular') + Instance.refresh + sign_in current_user, scope: :user end From cd37048439f9b324f48e6af1f426a7894c54b4da Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:11:34 -0500 Subject: [PATCH 148/422] Move followable_by coverage to suggestions (#28697) --- .../follow_recommendation_mute_fabricator.rb | 6 ++ spec/models/account_spec.rb | 23 -------- .../models/account_suggestions/source_spec.rb | 57 +++++++++++++++++++ 3 files changed, 63 insertions(+), 23 deletions(-) create mode 100644 spec/fabricators/follow_recommendation_mute_fabricator.rb create mode 100644 spec/models/account_suggestions/source_spec.rb diff --git a/spec/fabricators/follow_recommendation_mute_fabricator.rb b/spec/fabricators/follow_recommendation_mute_fabricator.rb new file mode 100644 index 0000000000..0f924386e9 --- /dev/null +++ b/spec/fabricators/follow_recommendation_mute_fabricator.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +Fabricator(:follow_recommendation_mute) do + account { Fabricate.build(:account) } + target_account { Fabricate.build(:account) } +end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 1a4c14c45c..ab74579624 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -1011,27 +1011,4 @@ RSpec.describe Account do expect(subject.reload.followers_count).to eq 15 end end - - describe '.followable_by' do - context 'with follows and follow requests' do - let!(:account) { Fabricate(:account) } - let!(:eligible_account) { Fabricate(:account) } - let!(:following_account) { Fabricate(:account) } - let!(:follow_requested_account) { Fabricate(:account) } - - before do - Fabricate :follow, account: account, target_account: following_account - Fabricate :follow_request, account: account, target_account: follow_requested_account - end - - it 'returns accounts not already following or requested to follow' do - results = described_class.followable_by(account) - - expect(results) - .to include(eligible_account) - .and not_include(following_account) - .and not_include(follow_requested_account) - end - end - end end diff --git a/spec/models/account_suggestions/source_spec.rb b/spec/models/account_suggestions/source_spec.rb new file mode 100644 index 0000000000..d8227e01bc --- /dev/null +++ b/spec/models/account_suggestions/source_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe AccountSuggestions::Source do + describe '#base_account_scope' do + subject { FakeSource.new } + + before do + stub_const 'FakeSource', fake_source_class + end + + context 'with follows and follow requests' do + let!(:account_domain_blocked_account) { Fabricate(:account, domain: 'blocked.host') } + let!(:account) { Fabricate(:account) } + let!(:blocked_account) { Fabricate(:account) } + let!(:eligible_account) { Fabricate(:account) } + let!(:follow_recommendation_muted_account) { Fabricate(:account) } + let!(:follow_requested_account) { Fabricate(:account) } + let!(:following_account) { Fabricate(:account) } + let!(:moved_account) { Fabricate(:account, moved_to_account: Fabricate(:account)) } + + before do + Fabricate :account_domain_block, account: account, domain: account_domain_blocked_account.domain + Fabricate :block, account: account, target_account: blocked_account + Fabricate :follow_recommendation_mute, account: account, target_account: follow_recommendation_muted_account + Fabricate :follow_request, account: account, target_account: follow_requested_account + Fabricate :follow, account: account, target_account: following_account + end + + it 'returns eligible accounts' do + results = subject.get(account) + + expect(results) + .to include(eligible_account) + .and not_include(account_domain_blocked_account) + .and not_include(account) + .and not_include(blocked_account) + .and not_include(follow_recommendation_muted_account) + .and not_include(follow_requested_account) + .and not_include(following_account) + .and not_include(moved_account) + end + end + end + + private + + def fake_source_class + Class.new described_class do + def get(account, limit: 10) + base_account_scope(account) + .limit(limit) + end + end + end +end From df9e220364484acccdb3f51b71a7081dfa0bec2f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:12:31 -0500 Subject: [PATCH 149/422] Add JS console errors check (#28682) --- lib/tasks/spec.rake | 2 ++ spec/support/javascript_errors.rb | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 spec/support/javascript_errors.rb diff --git a/lib/tasks/spec.rake b/lib/tasks/spec.rake index 8f2cbeea35..d505a47195 100644 --- a/lib/tasks/spec.rake +++ b/lib/tasks/spec.rake @@ -3,6 +3,8 @@ if Rake::Task.task_defined?('spec:system') namespace :spec do task :enable_system_specs do # rubocop:disable Rails/RakeEnvironment + ENV['LOCAL_DOMAIN'] = 'localhost:3000' + ENV['LOCAL_HTTPS'] = 'false' ENV['RUN_SYSTEM_SPECS'] = 'true' end end diff --git a/spec/support/javascript_errors.rb b/spec/support/javascript_errors.rb new file mode 100644 index 0000000000..bdce1cc76d --- /dev/null +++ b/spec/support/javascript_errors.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +RSpec.configure do |config| + config.after(:each, type: :system) do + errors = page.driver.browser.logs.get(:browser) + if errors.present? + aggregate_failures 'javascript errrors' do + errors.each do |error| + expect(error.level).to_not eq('SEVERE'), error.message + next unless error.level == 'WARNING' + + $stderr.warn 'WARN: javascript warning' + $stderr.warn error.message + end + end + end + end +end From b86083f0dc22e68451aaee5b2a01a8c69de60334 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 10:17:10 +0100 Subject: [PATCH 150/422] New Crowdin Translations (automated) (#28708) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/de.json | 2 +- config/locales/eu.yml | 2 +- config/locales/ro.yml | 1 + config/locales/sk.yml | 2 ++ 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 2608b91563..462352750c 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -489,7 +489,7 @@ "onboarding.profile.lead": "Du kannst das später in den Einstellungen vervollständigen, wo noch mehr Anpassungsmöglichkeiten zur Verfügung stehen.", "onboarding.profile.note": "Über mich", "onboarding.profile.note_hint": "Du kannst andere @Profile erwähnen oder #Hashtags verwenden …", - "onboarding.profile.save_and_continue": "Speichern und fortsetzen", + "onboarding.profile.save_and_continue": "Speichern und fortfahren", "onboarding.profile.title": "Profil einrichten", "onboarding.profile.upload_avatar": "Profilbild hochladen", "onboarding.profile.upload_header": "Titelbild hochladen", diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 0d253e9b3b..9174b83b43 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -1445,7 +1445,7 @@ eu: cooldown: Migratu eta gero egonaldi tarte bat egongo da eta bitartean ezin izango duzu berriro migratu disabled_account: Zure uneko kontua ezin izango da gero erabili. Hala ere, datua exporatu ahal izango dituzu, eta berriro aktibatu. followers: Ekintza honek jarraitzaile guztiak eramango ditu uneko kontutik kontu berrira - only_redirect_html: Bestela, zure profilean birbideratze soil bat jarri dezakezu. + only_redirect_html: Bestela, zure profilean birbideratze bat jar dezakezu. other_data: Ez da beste daturik migratuko automatikoki redirect: Zure uneko kontuaren profila eguneratuko da birbideratze ohar batekin eta bilaketetatik kenduko da moderation: diff --git a/config/locales/ro.yml b/config/locales/ro.yml index a0f20d57dc..12c06505b8 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -93,6 +93,7 @@ ro: moderation: active: Activ all: Toate + disabled: Dezactivat pending: În așteptare silenced: Limitat suspended: Suspendate diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 89d41b4616..a91f1d620e 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -184,6 +184,7 @@ sk: create_domain_block: Vytvor zákaz domény create_email_domain_block: Vytvor zákaz emailovej domény create_ip_block: Vytvor IP pravidlo + create_unavailable_domain: Vytvor nedostupnú doménu create_user_role: Vytvoriť rolu demote_user: Zniž užívateľskú rolu destroy_announcement: Vymaž oboznámenie @@ -245,6 +246,7 @@ sk: destroy_email_domain_block_html: "%{name} odblokoval/a e-mailovú doménu %{target}" destroy_ip_block_html: "%{name} vymazal/a pravidlo pre IP %{target}" destroy_status_html: "%{name} zmazal/a príspevok od %{target}" + destroy_unavailable_domain_html: "%{name} znova spustil/a doručovanie pre doménu %{target}" destroy_user_role_html: "%{name} vymazal/a rolu pre %{target}" enable_user_html: "%{name} povolil/a prihlásenie pre používateľa %{target}" memorialize_account_html: "%{name} zmenil/a účet %{target} na pamätnú stránku" From 7801db7ba463a71b8a11a2867486b012a2ec3972 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:19:25 -0500 Subject: [PATCH 151/422] Spec coverage for custom css endpoint (#28706) --- app/controllers/custom_css_controller.rb | 13 +++++ app/views/custom_css/show.css.erb | 6 +-- spec/requests/custom_css_spec.rb | 60 ++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 spec/requests/custom_css_spec.rb diff --git a/app/controllers/custom_css_controller.rb b/app/controllers/custom_css_controller.rb index e7a02ea89c..62f8e0d772 100644 --- a/app/controllers/custom_css_controller.rb +++ b/app/controllers/custom_css_controller.rb @@ -1,8 +1,21 @@ # frozen_string_literal: true class CustomCssController < ActionController::Base # rubocop:disable Rails/ApplicationController + before_action :set_user_roles + def show expires_in 3.minutes, public: true render content_type: 'text/css' end + + private + + def custom_css_styles + Setting.custom_css + end + helper_method :custom_css_styles + + def set_user_roles + @user_roles = UserRole.where(highlighted: true).where.not(color: [nil, '']) + end end diff --git a/app/views/custom_css/show.css.erb b/app/views/custom_css/show.css.erb index 9cd38fb371..78da809ed6 100644 --- a/app/views/custom_css/show.css.erb +++ b/app/views/custom_css/show.css.erb @@ -1,8 +1,8 @@ -<%- if Setting.custom_css.present? %> -<%= raw Setting.custom_css %> +<%- if custom_css_styles.present? %> +<%= raw custom_css_styles %> <%- end %> -<%- UserRole.where(highlighted: true).select { |role| role.color.present? }.each do |role| %> +<%- @user_roles.each do |role| %> .user-role-<%= role.id %> { --user-role-accent: <%= role.color %>; } diff --git a/spec/requests/custom_css_spec.rb b/spec/requests/custom_css_spec.rb new file mode 100644 index 0000000000..5271ed4a5a --- /dev/null +++ b/spec/requests/custom_css_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Custom CSS' do + include RoutingHelper + + describe 'GET /custom.css' do + context 'without any CSS or User Roles' do + it 'returns empty stylesheet' do + get '/custom.css' + + expect(response.content_type).to include('text/css') + expect(response.body.presence).to be_nil + end + end + + context 'with CSS settings' do + before do + Setting.custom_css = expected_css + end + + it 'returns stylesheet from settings' do + get '/custom.css' + + expect(response.content_type).to include('text/css') + expect(response.body.strip).to eq(expected_css) + end + + def expected_css + <<~CSS.strip + body { background-color: red; } + CSS + end + end + + context 'with highlighted colored UserRole records' do + before do + _highlighted_colored = Fabricate :user_role, highlighted: true, color: '#336699', id: '123_123_123' + _highlighted_no_color = Fabricate :user_role, highlighted: true, color: '' + _no_highlight_with_color = Fabricate :user_role, highlighted: false, color: '' + end + + it 'returns stylesheet from settings' do + get '/custom.css' + + expect(response.content_type).to include('text/css') + expect(response.body.strip).to eq(expected_css) + end + + def expected_css + <<~CSS.strip + .user-role-123123123 { + --user-role-accent: #336699; + } + CSS + end + end + end +end From a90696011e563e62100cba56e2d52f6babbaff00 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 12 Jan 2024 04:21:00 -0500 Subject: [PATCH 152/422] Add coverage/bugfix for invalid appeal submission (#28703) --- app/views/disputes/strikes/show.html.haml | 2 +- .../disputes/appeals_controller_spec.rb | 37 ++++++++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/app/views/disputes/strikes/show.html.haml b/app/views/disputes/strikes/show.html.haml index 62695b155e..5f72138821 100644 --- a/app/views/disputes/strikes/show.html.haml +++ b/app/views/disputes/strikes/show.html.haml @@ -21,7 +21,7 @@ .report-header .report-header__card - = render 'card', strike: @strike + = render 'disputes/strikes/card', strike: @strike .report-header__details .report-header__details__item diff --git a/spec/controllers/disputes/appeals_controller_spec.rb b/spec/controllers/disputes/appeals_controller_spec.rb index 452bd60dc5..da2f86ade5 100644 --- a/spec/controllers/disputes/appeals_controller_spec.rb +++ b/spec/controllers/disputes/appeals_controller_spec.rb @@ -10,19 +10,38 @@ RSpec.describe Disputes::AppealsController do let!(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } describe '#create' do - let(:current_user) { Fabricate(:user) } - let(:strike) { Fabricate(:account_warning, target_account: current_user.account) } + context 'with valid params' do + let(:current_user) { Fabricate(:user) } + let(:strike) { Fabricate(:account_warning, target_account: current_user.account) } - before do - post :create, params: { strike_id: strike.id, appeal: { text: 'Foo' } } + before do + post :create, params: { strike_id: strike.id, appeal: { text: 'Foo' } } + end + + it 'notifies staff about new appeal', :sidekiq_inline do + expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email]) + end + + it 'redirects back to the strike page' do + expect(response).to redirect_to(disputes_strike_path(strike.id)) + end end - it 'notifies staff about new appeal', :sidekiq_inline do - expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email]) - end + context 'with invalid params' do + let(:current_user) { Fabricate(:user) } + let(:strike) { Fabricate(:account_warning, target_account: current_user.account) } - it 'redirects back to the strike page' do - expect(response).to redirect_to(disputes_strike_path(strike.id)) + before do + post :create, params: { strike_id: strike.id, appeal: { text: '' } } + end + + it 'does not send email', :sidekiq_inline do + expect(ActionMailer::Base.deliveries.size).to eq(0) + end + + it 'renders the strike show page' do + expect(response).to render_template('disputes/strikes/show') + end end end end From c6684aa1e392f2dd86af4362b4259809549abaad Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Fri, 12 Jan 2024 10:32:45 +0100 Subject: [PATCH 153/422] Use the assets pipeline to load `inert.css` (#28701) --- app/javascript/packs/inert.js | 4 ++++ public/inert.css => app/javascript/styles/inert.scss | 2 ++ app/views/layouts/application.html.haml | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 app/javascript/packs/inert.js rename public/inert.css => app/javascript/styles/inert.scss (78%) diff --git a/app/javascript/packs/inert.js b/app/javascript/packs/inert.js new file mode 100644 index 0000000000..7c04a97faf --- /dev/null +++ b/app/javascript/packs/inert.js @@ -0,0 +1,4 @@ +/* Placeholder file to have `inert.scss` compiled by Webpack + This is used by the `wicg-inert` polyfill */ + +import '../styles/inert.scss'; diff --git a/public/inert.css b/app/javascript/styles/inert.scss similarity index 78% rename from public/inert.css rename to app/javascript/styles/inert.scss index 54e10616d2..a60045d7be 100644 --- a/public/inert.css +++ b/app/javascript/styles/inert.scss @@ -1,3 +1,5 @@ +/* This is needed for the wicg-inert polyfill */ + [inert] { pointer-events: none; cursor: default; diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 1244fd5eb3..6f6b1825f6 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -28,12 +28,14 @@ = stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous' = stylesheet_pack_tag current_theme, media: 'all', crossorigin: 'anonymous' + -# Needed for the wicg-inert polyfill. It needs to be on it's own