Compare commits

...

61 Commits

Author SHA1 Message Date
Aakansha Doshi 09daff487a Merge remote-tracking branch 'origin/master' into aakansha-sm 2021-01-21 13:15:32 +05:30
Aakansha Doshi 49bd683401 fix(analytics.ts): add safe check for process so Excalidraw can be loaded via script (#2824)
* fix(analytics.ts): add safe check for process so Excalidraw can be loaded via script

* fix
2021-01-20 21:27:33 +05:30
Aakansha Doshi 17330c4c03 fix 2021-01-20 21:21:50 +05:30
Aakansha Doshi 2a4ad6fc41 upload sourcemaps to cdn 2021-01-20 21:20:28 +05:30
Aakansha Doshi ec6999554a build(webpack): attach sourcemaps so it helps in debugging 2021-01-20 01:58:45 +05:30
Aakansha Doshi 3922ee8c11 docs: update changelog and readme and release 0.2.1 (#2821) 2021-01-19 17:38:04 +01:00
Aakansha Doshi 8c2bc94336 build(webpack): bundle css files with js (#2819) 2021-01-19 15:29:05 +01:00
Luc Leray fb4d97ef78 fix: Use VERCEL_GIT_COMMIT_SHA env variable (#2816) 2021-01-18 19:22:02 +02:00
Lipis a8e28afbad chore: Update translations from Crowdin (#2790)
Co-authored-by: Kostas Bariotis <konmpar@gmail.com>
2021-01-18 17:00:42 +02:00
Aakansha Doshi 68347ba476 docs(changelog): add about extra api's in changelog and separate package and library updates (#2813) 2021-01-17 18:48:19 +01:00
Victor Massé ce2c341910 feat: Change shortcuts menu to help menu (#2812)
Co-authored-by: Panayiotis Lipiridis <lipiridis@gmail.com>
2021-01-17 18:46:23 +02:00
dependabot[bot] 07cc858926 chore(deps-dev): bump husky from 4.3.7 to 4.3.8 (#2804)
Bumps [husky](https://github.com/typicode/husky) from 4.3.7 to 4.3.8.
- [Release notes](https://github.com/typicode/husky/releases)
- [Commits](https://github.com/typicode/husky/compare/v4.3.7...v4.3.8)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 11:33:24 +02:00
dependabot[bot] a7a2936f7c chore(deps): bump @sentry/integrations from 5.29.2 to 5.30.0 (#2807)
Bumps [@sentry/integrations](https://github.com/getsentry/sentry-javascript) from 5.29.2 to 5.30.0.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/5.29.2...5.30.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 11:33:15 +02:00
dependabot[bot] e72ff6be66 chore(deps-dev): bump webpack from 5.12.3 to 5.15.0 in /src/packages/utils (#2803)
Bumps [webpack](https://github.com/webpack/webpack) from 5.12.3 to 5.15.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.12.3...v5.15.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 11:33:02 +02:00
dependabot[bot] 0ea29675df chore(deps-dev): bump webpack from 5.12.3 to 5.15.0 in /src/packages/excalidraw (#2800)
Bumps [webpack](https://github.com/webpack/webpack) from 5.12.3 to 5.15.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.12.3...v5.15.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 11:31:59 +02:00
dependabot[bot] da2ad4f37c chore(deps-dev): bump sass-loader from 10.1.0 to 10.1.1 in /src/packages/excalidraw (#2801)
Bumps [sass-loader](https://github.com/webpack-contrib/sass-loader) from 10.1.0 to 10.1.1.
- [Release notes](https://github.com/webpack-contrib/sass-loader/releases)
- [Changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/sass-loader/compare/v10.1.0...v10.1.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 11:31:45 +02:00
dependabot[bot] 33a7cf0d3f chore(deps): bump firebase from 8.2.2 to 8.2.3 (#2810)
Bumps [firebase](https://github.com/firebase/firebase-js-sdk) from 8.2.2 to 8.2.3.
- [Release notes](https://github.com/firebase/firebase-js-sdk/releases)
- [Changelog](https://github.com/firebase/firebase-js-sdk/blob/master/CHANGELOG.md)
- [Commits](https://github.com/firebase/firebase-js-sdk/commits/firebase@8.2.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 11:31:17 +02:00
dependabot[bot] f8e890df7b chore(deps-dev): bump mini-css-extract-plugin from 1.3.3 to 1.3.4 in /src/packages/excalidraw (#2802)
Bumps [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) from 1.3.3 to 1.3.4.
- [Release notes](https://github.com/webpack-contrib/mini-css-extract-plugin/releases)
- [Changelog](https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v1.3.3...v1.3.4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 11:28:23 +02:00
dependabot[bot] 12337a54a3 chore(deps): bump @testing-library/jest-dom from 5.11.8 to 5.11.9 (#2805)
Bumps [@testing-library/jest-dom](https://github.com/testing-library/jest-dom) from 5.11.8 to 5.11.9.
- [Release notes](https://github.com/testing-library/jest-dom/releases)
- [Changelog](https://github.com/testing-library/jest-dom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/testing-library/jest-dom/compare/v5.11.8...v5.11.9)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 11:27:38 +02:00
dependabot[bot] 7a9ed2cfa1 chore(deps-dev): bump firebase-tools from 9.1.2 to 9.2.1 (#2808)
Bumps [firebase-tools](https://github.com/firebase/firebase-tools) from 9.1.2 to 9.2.1.
- [Release notes](https://github.com/firebase/firebase-tools/releases)
- [Commits](https://github.com/firebase/firebase-tools/compare/v9.1.2...v9.2.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 11:27:12 +02:00
dependabot[bot] 553bf2956f chore(deps): bump @sentry/browser from 5.29.2 to 5.30.0 (#2809)
Bumps [@sentry/browser](https://github.com/getsentry/sentry-javascript) from 5.29.2 to 5.30.0.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/5.29.2...5.30.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 11:27:01 +02:00
dependabot[bot] 1e16a6e5bd chore(deps): bump @types/socket.io-client from 1.4.34 to 1.4.35 (#2811)
Bumps [@types/socket.io-client](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/socket.io-client) from 1.4.34 to 1.4.35.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/socket.io-client)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-17 11:26:44 +02:00
João Forja e26f374ca6 improvement: Enhance resize for non generic elements (#2720) 2021-01-16 19:49:13 +01:00
Lipis c799b28a0e fix: Count all versions (#2798) 2021-01-16 18:59:26 +01:00
Aakansha Doshi ee703206b0 docs: update changelog and release 0.2.0 (#2725)
* docs(changelog): update changelog and release 0.2.0

* fix

* Add missing API's

* update

* fix

* fix

* Apply suggestions from code review

* remove

* fix

* fix
2021-01-16 22:20:46 +05:30
Arun 543c624405 feat: Add toast (#2772)
Co-authored-by: Lipis <lipiridis@gmail.com>
Co-authored-by: dwelle <luzar.david@gmail.com>
2021-01-15 16:02:46 +01:00
Lipis 0bf6830373 docs: Update readme with documentation (#2788) 2021-01-14 18:31:52 +02:00
Rafi af79461f41 fix: allow text-selecting in dialogs & reset cursor (#2783)
Co-authored-by: dwelle <luzar.david@gmail.com>
2021-01-14 14:42:15 +01:00
Lipis fd699c0447 chore: Update translations from Crowdin (#2742)
Co-authored-by: Kostas Bariotis <konmpar@gmail.com>
2021-01-14 12:09:05 +02:00
Shahzeb Parkar 6a16caf13c fix: broken Individuals link (#2782) 2021-01-14 09:24:50 +02:00
Rafi 511eb62228 refactor: Converting span to kbd tag (#2774) 2021-01-14 09:24:32 +02:00
David Luzar 04c46fc01a fix: don't render due to zoom after unmount (#2779)
* fix: don't render due to zoom after unmount

* update changelog

* remove unnecessary flush
2021-01-13 17:42:42 +01:00
Lipis 49e792649d fix: Track the chart type correctly (#2773) 2021-01-13 15:23:14 +02:00
dependabot[bot] 4e1caf2417 chore(deps-dev): bump terser-webpack-plugin in /src/packages/excalidraw (#2750)
Bumps [terser-webpack-plugin](https://github.com/webpack-contrib/terser-webpack-plugin) from 5.0.3 to 5.1.1.
- [Release notes](https://github.com/webpack-contrib/terser-webpack-plugin/releases)
- [Changelog](https://github.com/webpack-contrib/terser-webpack-plugin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v5.0.3...v5.1.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-13 00:44:32 +05:30
dependabot[bot] 034f2e470b chore(deps-dev): bump webpack in /src/packages/utils (#2768)
Bumps [webpack](https://github.com/webpack/webpack) from 5.11.1 to 5.12.3.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.11.1...v5.12.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-13 00:44:11 +05:30
David Luzar adcd28f348 fix: delay version logging & prevent duplicates (#2770) 2021-01-12 18:47:31 +02:00
dependabot[bot] 62f1ed74f1 chore(deps-dev): bump webpack in /src/packages/excalidraw (#2769)
Bumps [webpack](https://github.com/webpack/webpack) from 5.11.1 to 5.12.3.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.11.1...v5.12.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-12 02:03:31 +05:30
dependabot[bot] 8fa4273969 chore(deps-dev): bump ts-loader in /src/packages/excalidraw (#2749)
Bumps [ts-loader](https://github.com/TypeStrong/ts-loader) from 8.0.13 to 8.0.14.
- [Release notes](https://github.com/TypeStrong/ts-loader/releases)
- [Changelog](https://github.com/TypeStrong/ts-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TypeStrong/ts-loader/compare/v8.0.13...v8.0.14)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-12 01:43:13 +05:30
dependabot[bot] 672068ce7e chore(deps-dev): bump ts-loader in /src/packages/utils (#2753)
Bumps [ts-loader](https://github.com/TypeStrong/ts-loader) from 8.0.13 to 8.0.14.
- [Release notes](https://github.com/TypeStrong/ts-loader/releases)
- [Changelog](https://github.com/TypeStrong/ts-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TypeStrong/ts-loader/compare/v8.0.13...v8.0.14)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-12 01:42:42 +05:30
dependabot[bot] f1fc308a5d chore(deps): bump nanoid from 2.1.11 to 3.1.20 (#2581)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Panayiotis Lipiridis <lipiridis@gmail.com>
2021-01-11 12:47:10 +02:00
Lipis 001880ba88 feat: Track current version (#2731) 2021-01-10 20:48:12 +02:00
Arun 3a130cb102 chore(actions): Use cancel workflow action (#2763) 2021-01-10 20:09:44 +02:00
dependabot[bot] e682cf9bf6 chore(deps): bump @testing-library/react from 11.2.2 to 11.2.3 (#2755)
Bumps [@testing-library/react](https://github.com/testing-library/react-testing-library) from 11.2.2 to 11.2.3.
- [Release notes](https://github.com/testing-library/react-testing-library/releases)
- [Changelog](https://github.com/testing-library/react-testing-library/blob/master/CHANGELOG.md)
- [Commits](https://github.com/testing-library/react-testing-library/compare/v11.2.2...v11.2.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-10 12:39:44 +02:00
dependabot[bot] 2a169924d0 chore(deps-dev): bump firebase-tools from 9.1.0 to 9.1.2 (#2761)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-10 12:39:29 +02:00
dependabot[bot] eb6e75b806 chore(deps-dev): bump eslint-plugin-prettier from 3.3.0 to 3.3.1 (#2754)
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v3.3.0...v3.3.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-10 12:34:37 +02:00
dependabot[bot] 38857b9e9d chore(deps): bump firebase from 8.2.1 to 8.2.2 (#2758)
Bumps [firebase](https://github.com/firebase/firebase-js-sdk) from 8.2.1 to 8.2.2.
- [Release notes](https://github.com/firebase/firebase-js-sdk/releases)
- [Changelog](https://github.com/firebase/firebase-js-sdk/blob/master/CHANGELOG.md)
- [Commits](https://github.com/firebase/firebase-js-sdk/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-10 12:34:05 +02:00
dependabot[bot] 342289f261 chore(deps-dev): bump husky from 4.3.6 to 4.3.7 (#2757)
Bumps [husky](https://github.com/typicode/husky) from 4.3.6 to 4.3.7.
- [Release notes](https://github.com/typicode/husky/releases)
- [Commits](https://github.com/typicode/husky/compare/v4.3.6...v4.3.7)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-10 12:33:47 +02:00
dependabot[bot] 095d7de618 chore(deps): bump open-color from 1.7.0 to 1.8.0 (#2756)
Bumps [open-color](https://github.com/yeun/open-color) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/yeun/open-color/releases)
- [Changelog](https://github.com/yeun/open-color/blob/master/build_release)
- [Commits](https://github.com/yeun/open-color/compare/v1.7.0...v1.8.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-10 12:33:25 +02:00
dependabot[bot] f57d52028a chore(deps): bump @types/jest from 26.0.19 to 26.0.20 (#2759)
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 26.0.19 to 26.0.20.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-01-10 12:33:02 +02:00
Aakansha Doshi 60557df23a ci(semantic-pr-title.yml): update version to 3.0.0 so that action doesn't run twice (#2741)
* ci(semantic-pr-title.yml): don't run this action twice

* Update semantic-pr-title.yml

Co-authored-by: Lipis <lipiridis@gmail.com>
2021-01-08 20:12:48 +05:30
Lipis bafbe9bbc8 feat: Add language separator and list English twice (#2739) 2021-01-07 21:39:57 +02:00
Arun eb71e571e0 improvement: Perform lossless compression on all PNG images (#2740) 2021-01-07 18:04:28 +02:00
Lipis b608ab74cc chore: New Crowdin updates (#2681)
Co-authored-by: Kostas Bariotis <konmpar@gmail.com>
Co-authored-by: dwelle <luzar.david@gmail.com>
2021-01-07 11:30:22 +02:00
Carl Sverre a13c4f72f5 docs: adding PR guidelines for contributors (#2736) 2021-01-06 22:53:12 +02:00
Carl Sverre 629341da4d improvement: adding zen mode to context menu (#2734) 2021-01-06 17:23:05 +01:00
David Luzar 778e4b08af feat: Add cmd+o shortcut to load scene (#2732) 2021-01-06 13:36:55 +01:00
Thomas Steiner e16266ce5d Fix translation of Catalan to read Català 2021-01-06 00:46:42 +01:00
Arun b6708fb73f improvement: Make arrowheads keybinds color accessible on dark mode (#2724) 2021-01-05 22:35:03 +02:00
Aakansha Doshi cdffed285d fix(readme): fix typo for initialData and point all links to master (#2707)
* fix(readme): fix typo for initialData

* Update src/packages/excalidraw/README.md

* fix lint

* Update src/packages/excalidraw/README.md

* point all links to master

Co-authored-by: Lipis <lipiridis@gmail.com>
2021-01-06 00:00:18 +05:30
Lipis 3aa01ad272 chore: Remove tracking (#2722)
* chore: Remove tracking

* process

* rename

* remove

* prod

* Update public/index.html

Co-authored-by: David Luzar <luzar.david@gmail.com>

* Update public/index.html

* eol

* more

* stats

Co-authored-by: David Luzar <luzar.david@gmail.com>
2021-01-05 19:06:14 +01:00
Jaiwanth 4acdc47ef0 improvement: do not reset to selection for draw tool (#2721)
Co-authored-by: Lipis <lipiridis@gmail.com>
Co-authored-by: dwelle <luzar.david@gmail.com>
2021-01-05 14:04:06 +01:00
125 changed files with 3722 additions and 6201 deletions
+1 -1
View File
@@ -1 +1 @@
REACT_APP_INCLUDE_GTAG=true
REACT_APP_GOOGLE_ANALYTICS_ID=UA-387204-13
Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 20 KiB

+12
View File
@@ -0,0 +1,12 @@
name: Cancel
on: [push]
jobs:
cancel:
name: "Cancel Previous Runs"
runs-on: ubuntu-latest
timeout-minutes: 3
steps:
- uses: styfle/cancel-workflow-action@0.6.0
with:
workflow_id: 400555, 400556, 905313, 1451724, 1710116, 3185001, 3438604
access_token: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -43,5 +43,5 @@ jobs:
uses: kt3k/update-pr-description@v1.0.1
with:
pr_body: ${{ steps.getCommentBody.outputs.body }}
pr_title: "chore: New Crowdin updates"
pr_title: "chore: Update translations from Crowdin"
github_token: ${{ secrets.PUSH_TRANSLATIONS_COVERAGE_PAT }}
+1 -1
View File
@@ -11,6 +11,6 @@ jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v2.1.0
- uses: amannn/action-semantic-pull-request@v3.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+1
View File
@@ -1,3 +1,4 @@
{
"proseWrap": "never",
"trailingComma": "all"
}
+39 -2
View File
@@ -8,8 +8,7 @@
1. Run `npm install` to install dependencies
1. Create a branch for your PR with `git checkout -b your-branch-name`
> To keep `master` branch pointing to remote repository and make
> pull requests from branches on your fork. To do this, run:
> To keep `master` branch pointing to remote repository and make pull requests from branches on your fork. To do this, run:
>
> ```sh
> git remote add upstream https://github.com/excalidraw/excalidraw.git
@@ -25,3 +24,41 @@
1. Tap on `Fork Sandbox`
1. Write your code
1. Commit and PR automatically
## Pull Request Guidelines
Don't worry if you get any of the below wrong, or if you don't know how. We'll gladly help out.
### Title
Make sure the title starts with a semantic prefix:
- **feat**: A new feature
- **fix**: A bug fix
- **improvement**: An improvement to a current feature
- **docs**: Documentation only changes
- **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
- **refactor**: A code change that neither fixes a bug nor adds a feature
- **perf**: A code change that improves performance
- **test**: Adding missing tests or correcting existing tests
- **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
- **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
- **chore**: Other changes that don't modify src or test files
- **revert**: Reverts a previous commit
### Changelog
Add a brief description of your pull request to the changelog located here: [`src/packages/excalidraw/CHANGELOG.md`](src/packages/excalidraw/CHANGELOG.md)
Notes:
- Make sure to prepend to the section corresponding with the semantic prefix you selected in the title
- Link to your pull request - this will require updating the CHANGELOG _after_ creating the pull request
### Testing
Once you submit your pull request it will automatically be tested. Be sure to check the results of the test and fix any issues that arise.
It's also a good idea to consider if your change should include additional tests. This is highly recommended for new features or bug-fixes. For example, it's good practice to create a test for each bug you fix which ensures that we don't regress the code in the future.
Finally - always manually test your changes using the convenient staging environment deployed for each pull request. As much as local development attempts to replicate production, there can still be subtle differences in behavior. For larger features consider testing your change in multiple browsers as well.
-1
View File
@@ -5,7 +5,6 @@ WORKDIR /opt/node_app
COPY package.json package-lock.json ./
RUN npm i --no-optional
ARG REACT_APP_INCLUDE_GTAG=false
ARG NODE_ENV=production
COPY . .
+45 -56
View File
@@ -1,8 +1,8 @@
<div align="center" style="display:flex;flex-direction:column;">
<a href="https://excalidraw.com">
<img src="./public/og-image.png" alt="Excalidraw logo: Sketch handrawn like diagrams." />
<img width="540" src="./public/og-image-sm.png" alt="Excalidraw logo: Sketch handrawn like diagrams." />
</a>
<h3>Virtual whiteboard for sketching hand-drawn like diagrams.</h3>
<h3>Virtual whiteboard for sketching hand-drawn like diagrams.<br>Collaborative and end to end encrypted.</h3>
<p>
<a href="https://twitter.com/Excalidraw">
<img alt="Follow Excalidraw on Twitter" src="https://img.shields.io/twitter/follow/excalidraw.svg?label=follow+excalidraw&style=social&logo=twitter">
@@ -10,9 +10,6 @@
<a target="_blank" href="https://crowdin.com/project/excalidraw">
<img src="https://badges.crowdin.net/excalidraw/localized.svg">
</a>
<a target="_blank" href="https://hub.docker.com/r/excalidraw/excalidraw">
<img src="https://img.shields.io/docker/pulls/excalidraw/excalidraw">
</a>
</p>
</div>
@@ -20,13 +17,51 @@
Go to [excalidraw.com](https://excalidraw.com) to start sketching.
Read our [blog](https://blog.excalidraw.com) and follow the [guides](https://howto.excalidraw.com) to learn more about Excalidraw and how to use it effectively.
Read the latest news and updates on our [blog](https://blog.excalidraw.com). A good start is to see all the updates of [One Year of Excalidraw](https://blog.excalidraw.com/one-year-of-excalidraw/).
## Documentation
### Shortcuts
You can almost do anything with shortcuts. Click on the help icon on the bottom right corner to see them all.
### Curved lines and arrows
Choose line or arrow and click click click instead of drag.
### Charts
You can easily create charts by copy pasting data from Excel or just plain comma separated text.
### Translating
To translate Excalidraw into other languages, please visit [our Crowdin page](https://crowdin.com/project/excalidraw). To add a new language, [open an issue](https://github.com/excalidraw/excalidraw/issues/new) so we can get things set up on our end first.
Translations will be available on the app if they exceed a certain threshold of completion (currently 85%).
### Create a collaboration session manually
In order to create a session manually you just need to generate a link of this form:
```
https://excalidraw.com/#room=[0-9a-f]{20},[a-zA-Z0-9_-]{22}
```
#### Example
```
https://excalidraw.com/#room=91bd46ae3aa84dff9d20,pfLqgEoY1c2ioq8LmGwsFA
```
The first set of digits is the room. This is visible from the server thats going to dispatch messages to everyone that knows this number.
The second set of digits is the encryption key. The Excalidraw server doesnt know about it. This is what all the participants use to encrypt/decrypt the messages.
## Shape libraries
Find a growing list of libraries containing assets for your drawings at [libraries.excalidraw.com](https://libraries.excalidraw.com).
## Run the code
## Developement
### Code Sandbox
@@ -63,7 +98,7 @@ You can use docker-compose to work on excalidraw locally if you don't want to se
docker-compose up --build -d
```
## Self hosting
### Self hosting
We publish a Docker image with the Excalidraw client at [excalidraw/excalidraw](https://hub.docker.com/r/excalidraw/excalidraw). You can use it to self host your own client under your own domain, on Kubernetes, AWS ECS, etc.
@@ -82,57 +117,11 @@ We are working towards providing a full-fledged solution for self hosting your o
Pull requests are welcome. For major changes, please [open an issue](https://github.com/excalidraw/excalidraw/issues/new) first to discuss what you would like to change.
## Translating
## Notable used tools
To translate Excalidraw into other languages, please visit [our Crowdin page](https://crowdin.com/project/excalidraw). To add a new language, [open an issue](https://github.com/excalidraw/excalidraw/issues/new) so we can get things set up on our end first.
Translations will be available on the app if they exceed a certain threshold of completion (currently 85%).
## Excalidraw is built using these awesome tools
- [React](https://reactjs.org)
- [Create React App](https://github.com/facebook/create-react-app)
- [Rough.js](https://roughjs.com)
- [TypeScript](https://www.typescriptlang.org)
- [Vercel](https://vercel.com)
And the main source of inspiration for starting the project is the awesome [Zwibbler](https://zwibbler.com/demo/) app.
## Testimonials
<a href="https://twitter.com/Lissy_Sykes/status/1213813117177729026"><img width="398" src="https://user-images.githubusercontent.com/197597/71783813-dbf8a600-2fa0-11ea-9c0d-bb3cc45969e6.png"></a>
<a href="https://twitter.com/dan_abramov/status/1213762494428262400"><img width="398" src="https://user-images.githubusercontent.com/197597/71783990-4d395880-2fa3-11ea-9ad7-186138db5003.png"></a>
<a href="https://twitter.com/kyehohenberger/status/1214288572037025792"><img width="423" src="https://user-images.githubusercontent.com/197597/71851802-34f13880-308c-11ea-9416-191099e6349c.png"></a>
<a href="https://twitter.com/lucasazzola/status/1215126440330416128"><img width="429" src="https://user-images.githubusercontent.com/197597/72039003-48e99580-3258-11ea-8daa-85dd055f2a82.png">
<a href="https://twitter.com/jordwalke/status/1214858186789806080"><img width="434" src="https://user-images.githubusercontent.com/197597/72036874-07a1b780-3251-11ea-99e8-6bafd93483a0.png"></a>
## Contributors
### Code Contributors
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
<a href="https://github.com/excalidraw/excalidraw/graphs/contributors"><img src="https://opencollective.com/excalidraw/contributors.svg?width=890&button=false" /></a>
### Financial Contributors
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/excalidraw/contribute)]
#### Individuals
<a href="https://opencollective.com/excalidraw"><img src="https://opencollective.com/excalidraw/individuals.svg?width=890"></a>
#### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/excalidraw/contribute)]
<a href="https://opencollective.com/excalidraw/organization/0/website"><img src="https://opencollective.com/excalidraw/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/excalidraw/organization/1/website"><img src="https://opencollective.com/excalidraw/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/excalidraw/organization/2/website"><img src="https://opencollective.com/excalidraw/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/excalidraw/organization/3/website"><img src="https://opencollective.com/excalidraw/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/excalidraw/organization/4/website"><img src="https://opencollective.com/excalidraw/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/excalidraw/organization/5/website"><img src="https://opencollective.com/excalidraw/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/excalidraw/organization/6/website"><img src="https://opencollective.com/excalidraw/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/excalidraw/organization/7/website"><img src="https://opencollective.com/excalidraw/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/excalidraw/organization/8/website"><img src="https://opencollective.com/excalidraw/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/excalidraw/organization/9/website"><img src="https://opencollective.com/excalidraw/organization/9/avatar.svg"></a>
-64
View File
@@ -1,64 +0,0 @@
| Excalidraw | Category | Name | Label | Value |
| ----------------------- | -------- | ---------------------------------- | ------------------------------- | --------- |
| Shape / Selection | shape | selection, rectangle, diamond, etc | `toolbar` or `shortcut` |
| Text on double click | shape | text | `double-click` |
| Lock selection | shape | lock | `on` or `off` |
| Clear canvas | action | clear canvas |
| Zoom in | action | zoom | in | `zoom` |
| Zoom out | action | zoom | out | `zoom` |
| Zoom fit | action | zoom | fit | `zoom` |
| Zoom reset | action | zoom | reset | `zoom` |
| Scroll back to content | action | scroll to content |
| Load file | io | load | `MIME type` |
| Import from URL | io | import |
| Save | io | save |
| Save as | io | save as |
| Export to backend | io | export | backend |
| Export as SVG | io | export | `svg` or `clipboard-svg` |
| Export to PNG | io | export | `png` or `clipboard-png` |
| Canvas color | change | canvas color | `color` |
| Background color | change | background color | `color` |
| Stroke color | change | stroke color | `color` |
| Stroke width | change | stroke | width | `width` |
| Stroke style | change | style | `solid` or `dashed` or `dotted` |
| Stroke sloppiness | change | stroke | sloppiness | `value` |
| Fill | change | fill | `value` |
| Edge | change | edge | `value` |
| Opacity | change | opacity | value | `opacity` |
| Project name | change | title |
| Theme | change | theme | `light` or `dark` |
| Change language | change | language | `language` |
| Send to back | layer | move | `back` |
| Send backward | layer | move | `down` |
| Bring to front | layer | move | `front` |
| Bring forward | layer | move | `up` |
| Align left | align | align | `left` |
| Align right | align | align | `right` |
| Align top | align | align | `top` |
| Align bottom | align | align | `bottom` |
| Center horizontally | align | horizontally | `center` |
| Center vertically | align | vertically | `center` |
| Distribute horizontally | align | distribute | `horizontally` |
| Distribute vertically | align | distribute | `vertically` |
| Start session | share | session start |
| Join session | share | session join |
| Start end | share | session end |
| Copy room link | share | copy link |
| Go to collaborator | share | go to collaborator |
| Change name | share | name |
| Add to library | library | add |
| Remove from library | library | remove |
| Load library | library | load |
| Save library | library | save |
| Import library | library | import |
| Shortcuts dialog | dialog | shortcuts |
| Collaboration dialog | dialog | collaboration |
| Export dialog | dialog | export |
| Library dialog | dialog | library |
| E2EE shield | exit | e2ee shield |
| GitHub corner | exit | github |
| Excalidraw blog | exit | blog |
| Excalidraw guides | exit | guides |
| File issues | exit | issues |
| First load | load | first load |
| Load from stroage | load | storage | size | `bytes` |
+500 -3458
View File
File diff suppressed because it is too large Load Diff
+14 -15
View File
@@ -19,23 +19,22 @@
]
},
"dependencies": {
"@sentry/browser": "5.29.2",
"@sentry/integrations": "5.29.2",
"@testing-library/jest-dom": "5.11.8",
"@testing-library/react": "11.2.2",
"@types/jest": "26.0.19",
"@types/nanoid": "2.1.0",
"@sentry/browser": "5.30.0",
"@sentry/integrations": "5.30.0",
"@testing-library/jest-dom": "5.11.9",
"@testing-library/react": "11.2.3",
"@types/jest": "26.0.20",
"@types/react": "17.0.0",
"@types/react-dom": "17.0.0",
"@types/socket.io-client": "1.4.34",
"@types/socket.io-client": "1.4.35",
"browser-nativefs": "0.12.0",
"clsx": "1.1.1",
"firebase": "8.2.1",
"firebase": "8.2.3",
"i18next-browser-languagedetector": "6.0.1",
"lodash.throttle": "4.1.1",
"nanoid": "2.1.11",
"nanoid": "3.1.20",
"node-sass": "4.14.1",
"open-color": "1.7.0",
"open-color": "1.8.0",
"pako": "1.0.11",
"png-chunk-text": "1.0.0",
"png-chunks-encode": "1.0.0",
@@ -53,9 +52,9 @@
"@types/lodash.throttle": "4.1.6",
"@types/pako": "1.0.1",
"eslint-config-prettier": "7.1.0",
"eslint-plugin-prettier": "3.3.0",
"firebase-tools": "9.1.0",
"husky": "4.3.6",
"eslint-plugin-prettier": "3.3.1",
"firebase-tools": "9.2.1",
"husky": "4.3.8",
"jest-canvas-mock": "2.3.0",
"lint-staged": "10.5.3",
"pepjs": "0.5.3",
@@ -81,8 +80,8 @@
"private": true,
"scripts": {
"build-node": "node ./scripts/build-node.js",
"build:app:docker": "REACT_APP_INCLUDE_GTAG=false REACT_APP_DISABLE_SENTRY=true react-scripts build",
"build:app": "REACT_APP_INCLUDE_GTAG=true REACT_APP_GIT_SHA=$NOW_GITHUB_COMMIT_SHA react-scripts build",
"build:app:docker": "REACT_APP_DISABLE_SENTRY=true react-scripts build",
"build:app": "REACT_APP_GIT_SHA=$VERCEL_GIT_COMMIT_SHA react-scripts build",
"build:version": "node ./scripts/build-version.js",
"build": "npm run build:app && npm run build:version",
"eject": "react-scripts eject",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

+3 -3
View File
@@ -86,10 +86,10 @@
<link rel="stylesheet" href="fonts.css" type="text/css" />
<% if (process.env.REACT_APP_INCLUDE_GTAG === 'true') { %>
<% if (process.env.REACT_APP_GOOGLE_ANALYTICS_ID) { %>
<script
async
src="https://www.googletagmanager.com/gtag/js?id=UA-387204-13"
src="https://www.googletagmanager.com/gtag/js?id=%REACT_APP_GOOGLE_ANALYTICS_ID%"
></script>
<script>
window.dataLayer = window.dataLayer || [];
@@ -97,7 +97,7 @@
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "UA-387204-13");
gtag("config", "%REACT_APP_GOOGLE_ANALYTICS_ID%");
</script>
<% } %>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 70 KiB

+29 -12
View File
@@ -5,23 +5,40 @@ const path = require("path");
const versionFile = path.join("build", "version.json");
const indexFile = path.join("build", "index.html");
const zero = (digit) => `0${digit}`.slice(-2);
const versionDate = (date) => date.toISOString().replace(".000", "");
const versionDate = (date) => {
const date_ = `${date.getFullYear()}-${zero(date.getMonth() + 1)}-${zero(
date.getDate(),
)}`;
const time = `${zero(date.getHours())}-${zero(date.getMinutes())}-${zero(
date.getSeconds(),
)}`;
return `${date_}-${time}`;
const commitHash = () => {
try {
return require("child_process")
.execSync("git rev-parse --short HEAD")
.toString()
.trim();
} catch {
return "none";
}
};
const now = new Date();
const commitDate = (hash) => {
try {
const unix = require("child_process")
.execSync(`git show -s --format=%ct ${hash}`)
.toString()
.trim();
const date = new Date(parseInt(unix) * 1000);
return versionDate(date);
} catch {
return versionDate(new Date());
}
};
const getFullVersion = () => {
const hash = commitHash();
return `${commitDate(hash)}-${hash}`;
};
const data = JSON.stringify(
{
version: versionDate(now),
version: getFullVersion(),
},
undefined,
2,
@@ -34,7 +51,7 @@ fs.readFile(indexFile, "utf8", (error, data) => {
if (error) {
return console.error(error);
}
const result = data.replace(/{version}/g, versionDate(now));
const result = data.replace(/{version}/g, getFullVersion());
fs.writeFile(indexFile, result, "utf8", (error) => {
if (error) {
+8 -5
View File
@@ -4,25 +4,26 @@ const THRESSHOLD = 85;
const crowdinMap = {
"ar-SA": "en-ar",
"el-GR": "en-el",
"fi-FI": "en-fi",
"ja-JP": "en-ja",
"bg-BG": "en-bg",
"ca-ES": "en-ca",
"de-DE": "en-de",
"el-GR": "en-el",
"es-ES": "en-es",
"fa-IR": "en-fa",
"fi-FI": "en-fi",
"fr-FR": "en-fr",
"he-IL": "en-he",
"hi-IN": "en-hi",
"hu-HU": "en-hu",
"id-ID": "en-id",
"it-IT": "en-it",
"ja-JP": "en-ja",
"ko-KR": "en-ko",
"my-MM": "en-my",
"nb-NO": "en-nb",
"nl-NL": "en-nl",
"nn-NO": "en-nnno",
"pa-IN": "en-pain",
"pl-PL": "en-pl",
"pt-BR": "en-ptbr",
"pt-PT": "en-pt",
@@ -57,6 +58,7 @@ const flags = {
"nb-NO": "🇳🇴",
"nl-NL": "🇳🇱",
"nn-NO": "🇳🇴",
"pa-IN": "🇮🇳",
"pl-PL": "🇵🇱",
"pt-BR": "🇧🇷",
"pt-PT": "🇵🇹",
@@ -73,7 +75,7 @@ const flags = {
const languages = {
"ar-SA": "العربية",
"bg-BG": "Български",
"ca-ES": "Catalan",
"ca-ES": "Català",
"de-DE": "Deutsch",
"el-GR": "Ελληνικά",
"es-ES": "Español",
@@ -91,6 +93,7 @@ const languages = {
"nb-NO": "Norsk bokmål",
"nl-NL": "Nederlands",
"nn-NO": "Norsk nynorsk",
"pa-IN": "ਪੰਜਾਬੀ",
"pl-PL": "Polski",
"pt-BR": "Português Brasileiro",
"pt-PT": "Português",
@@ -134,7 +137,7 @@ const printRow = (id, locale, coverage) => {
} else {
result += `${boldIf(language, isOver)} | `;
}
result += `${coverage === 100 ? "" : boldIf(coverage, isOver)} |`;
result += `${coverage === 100 ? "💯" : boldIf(coverage, isOver)} |`;
return result;
};
-2
View File
@@ -3,7 +3,6 @@ import { getSelectedElements } from "../scene";
import { getNonDeletedElements } from "../element";
import { deepCopyElement } from "../element/newElement";
import { Library } from "../data/library";
import { EVENT_LIBRARY, trackEvent } from "../analytics";
export const actionAddToLibrary = register({
name: "addToLibrary",
@@ -16,7 +15,6 @@ export const actionAddToLibrary = register({
Library.loadLibrary().then((items) => {
Library.saveLibrary([...items, selectedElements.map(deepCopyElement)]);
});
trackEvent(EVENT_LIBRARY, "add");
return false;
},
contextMenuOrder: 6,
+6 -13
View File
@@ -1,7 +1,5 @@
import React from "react";
import { KEYS } from "../keys";
import { t } from "../i18n";
import { register } from "./register";
import { alignElements, Alignment } from "../align";
import {
AlignBottomIcon,
AlignLeftIcon,
@@ -10,14 +8,15 @@ import {
CenterHorizontallyIcon,
CenterVerticallyIcon,
} from "../components/icons";
import { getSelectedElements, isSomeElementSelected } from "../scene";
import { getElementMap, getNonDeletedElements } from "../element";
import { ToolButton } from "../components/ToolButton";
import { getElementMap, getNonDeletedElements } from "../element";
import { ExcalidrawElement } from "../element/types";
import { t } from "../i18n";
import { KEYS } from "../keys";
import { getSelectedElements, isSomeElementSelected } from "../scene";
import { AppState } from "../types";
import { alignElements, Alignment } from "../align";
import { getShortcutKey } from "../utils";
import { trackEvent, EVENT_ALIGN } from "../analytics";
import { register } from "./register";
const enableActionGroup = (
elements: readonly ExcalidrawElement[],
@@ -44,7 +43,6 @@ const alignSelectedElements = (
export const actionAlignTop = register({
name: "alignTop",
perform: (elements, appState) => {
trackEvent(EVENT_ALIGN, "align", "top");
return {
appState,
elements: alignSelectedElements(elements, appState, {
@@ -74,7 +72,6 @@ export const actionAlignTop = register({
export const actionAlignBottom = register({
name: "alignBottom",
perform: (elements, appState) => {
trackEvent(EVENT_ALIGN, "align", "bottom");
return {
appState,
elements: alignSelectedElements(elements, appState, {
@@ -104,7 +101,6 @@ export const actionAlignBottom = register({
export const actionAlignLeft = register({
name: "alignLeft",
perform: (elements, appState) => {
trackEvent(EVENT_ALIGN, "align", "left");
return {
appState,
elements: alignSelectedElements(elements, appState, {
@@ -134,7 +130,6 @@ export const actionAlignLeft = register({
export const actionAlignRight = register({
name: "alignRight",
perform: (elements, appState) => {
trackEvent(EVENT_ALIGN, "align", "right");
return {
appState,
elements: alignSelectedElements(elements, appState, {
@@ -164,7 +159,6 @@ export const actionAlignRight = register({
export const actionAlignVerticallyCentered = register({
name: "alignVerticallyCentered",
perform: (elements, appState) => {
trackEvent(EVENT_ALIGN, "vertically", "center");
return {
appState,
elements: alignSelectedElements(elements, appState, {
@@ -190,7 +184,6 @@ export const actionAlignVerticallyCentered = register({
export const actionAlignHorizontallyCentered = register({
name: "alignHorizontallyCentered",
perform: (elements, appState) => {
trackEvent(EVENT_ALIGN, "horizontally", "center");
return {
appState,
elements: alignSelectedElements(elements, appState, {
-17
View File
@@ -1,7 +1,5 @@
import React from "react";
import { EVENT_ACTION, EVENT_CHANGE, trackEvent } from "../analytics";
import { getDefaultAppState } from "../appState";
import colors from "../colors";
import { ColorPicker } from "../components/ColorPicker";
import { resetZoom, trash, zoomIn, zoomOut } from "../components/icons";
import { ToolButton } from "../components/ToolButton";
@@ -21,15 +19,6 @@ import { register } from "./register";
export const actionChangeViewBackgroundColor = register({
name: "changeViewBackgroundColor",
perform: (_, appState, value) => {
if (value !== appState.viewBackgroundColor) {
trackEvent(
EVENT_CHANGE,
"canvas color",
colors.canvasBackground.includes(value)
? `${value} (picker ${colors.canvasBackground.indexOf(value)})`
: value,
);
}
return {
appState: { ...appState, viewBackgroundColor: value },
commitToHistory: true,
@@ -52,7 +41,6 @@ export const actionChangeViewBackgroundColor = register({
export const actionClearCanvas = register({
name: "clearCanvas",
perform: (elements, appState: AppState) => {
trackEvent(EVENT_ACTION, "clear canvas");
return {
elements: elements.map((element) =>
newElementWith(element, { isDeleted: true }),
@@ -98,7 +86,6 @@ export const actionZoomIn = register({
{ left: appState.offsetLeft, top: appState.offsetTop },
{ x: appState.width / 2, y: appState.height / 2 },
);
trackEvent(EVENT_ACTION, "zoom", "in", zoom.value * 100);
return {
appState: {
...appState,
@@ -133,7 +120,6 @@ export const actionZoomOut = register({
{ x: appState.width / 2, y: appState.height / 2 },
);
trackEvent(EVENT_ACTION, "zoom", "out", zoom.value * 100);
return {
appState: {
...appState,
@@ -161,7 +147,6 @@ export const actionZoomOut = register({
export const actionResetZoom = register({
name: "resetZoom",
perform: (_elements, appState) => {
trackEvent(EVENT_ACTION, "zoom", "reset", 100);
return {
appState: {
...appState,
@@ -234,12 +219,10 @@ const zoomToFitElements = (
left: appState.offsetLeft,
top: appState.offsetTop,
});
const action = zoomToSelection ? "selection" : "fit";
const [x1, y1, x2, y2] = commonBounds;
const centerX = (x1 + x2) / 2;
const centerY = (y1 + y2) / 2;
trackEvent(EVENT_ACTION, "zoom", action, newZoom.value * 100);
return {
appState: {
...appState,
+7 -10
View File
@@ -1,19 +1,18 @@
import React from "react";
import { CODES } from "../keys";
import { t } from "../i18n";
import { register } from "./register";
import {
DistributeHorizontallyIcon,
DistributeVerticallyIcon,
} from "../components/icons";
import { getSelectedElements, isSomeElementSelected } from "../scene";
import { getElementMap, getNonDeletedElements } from "../element";
import { ToolButton } from "../components/ToolButton";
import { ExcalidrawElement } from "../element/types";
import { AppState } from "../types";
import { distributeElements, Distribution } from "../disitrubte";
import { getElementMap, getNonDeletedElements } from "../element";
import { ExcalidrawElement } from "../element/types";
import { t } from "../i18n";
import { CODES } from "../keys";
import { getSelectedElements, isSomeElementSelected } from "../scene";
import { AppState } from "../types";
import { getShortcutKey } from "../utils";
import { EVENT_ALIGN, trackEvent } from "../analytics";
import { register } from "./register";
const enableActionGroup = (
elements: readonly ExcalidrawElement[],
@@ -40,7 +39,6 @@ const distributeSelectedElements = (
export const distributeHorizontally = register({
name: "distributeHorizontally",
perform: (elements, appState) => {
trackEvent(EVENT_ALIGN, "distribute", "horizontally");
return {
appState,
elements: distributeSelectedElements(elements, appState, {
@@ -69,7 +67,6 @@ export const distributeHorizontally = register({
export const distributeVertically = register({
name: "distributeVertically",
perform: (elements, appState) => {
trackEvent(EVENT_ALIGN, "distribute", "vertically");
return {
appState,
elements: distributeSelectedElements(elements, appState, {
+28 -30
View File
@@ -1,22 +1,20 @@
import React from "react";
import { EVENT_CHANGE, EVENT_IO, trackEvent } from "../analytics";
import { load, save, saveAs } from "../components/icons";
import { trackEvent } from "../analytics";
import { load, questionCircle, save, saveAs } from "../components/icons";
import { ProjectName } from "../components/ProjectName";
import { ToolButton } from "../components/ToolButton";
import "../components/ToolIcon.scss";
import { Tooltip } from "../components/Tooltip";
import { questionCircle } from "../components/icons";
import { loadFromJSON, saveAsJSON } from "../data";
import { t } from "../i18n";
import useIsMobile from "../is-mobile";
import { KEYS } from "../keys";
import { muteFSAbortError } from "../utils";
import { register } from "./register";
import "../components/ToolIcon.scss";
export const actionChangeProjectName = register({
name: "changeProjectName",
perform: (_elements, appState, value) => {
trackEvent(EVENT_CHANGE, "title");
trackEvent("change", "title");
return { appState: { ...appState, name: value }, commitToHistory: false };
},
PanelComponent: ({ appState, updateData }) => (
@@ -100,7 +98,6 @@ export const actionSaveScene = register({
perform: async (elements, appState, value) => {
try {
const { fileHandle } = await saveAsJSON(elements, appState);
trackEvent(EVENT_IO, "save");
return { commitToHistory: false, appState: { ...appState, fileHandle } };
} catch (error) {
if (error?.name !== "AbortError") {
@@ -131,7 +128,6 @@ export const actionSaveAsScene = register({
...appState,
fileHandle: null,
});
trackEvent(EVENT_IO, "save as");
return { commitToHistory: false, appState: { ...appState, fileHandle } };
} catch (error) {
if (error?.name !== "AbortError") {
@@ -159,18 +155,29 @@ export const actionSaveAsScene = register({
export const actionLoadScene = register({
name: "loadScene",
perform: (
elements,
appState,
{ elements: loadedElements, appState: loadedAppState, error },
) => ({
elements: loadedElements,
appState: {
...loadedAppState,
errorMessage: error,
},
commitToHistory: true,
}),
perform: async (elements, appState) => {
try {
const {
elements: loadedElements,
appState: loadedAppState,
} = await loadFromJSON(appState);
return {
elements: loadedElements,
appState: loadedAppState,
commitToHistory: true,
};
} catch (error) {
if (error?.name === "AbortError") {
return false;
}
return {
elements,
appState: { ...appState, errorMessage: error.message },
commitToHistory: false,
};
}
},
keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.key === KEYS.O,
PanelComponent: ({ updateData, appState }) => (
<ToolButton
type="button"
@@ -178,16 +185,7 @@ export const actionLoadScene = register({
title={t("buttons.load")}
aria-label={t("buttons.load")}
showAriaLabel={useIsMobile()}
onClick={() => {
loadFromJSON(appState)
.then(({ elements, appState }) => {
updateData({ elements, appState });
})
.catch(muteFSAbortError)
.catch((error) => {
updateData({ error: error.message });
});
}}
onClick={updateData}
/>
),
});
+10 -4
View File
@@ -118,11 +118,14 @@ export const actionFinalize = register({
);
}
if (!appState.elementLocked) {
if (!appState.elementLocked && appState.elementType !== "draw") {
appState.selectedElementIds[multiPointElement.id] = true;
}
}
if (!appState.elementLocked || !multiPointElement) {
if (
(!appState.elementLocked && appState.elementType !== "draw") ||
!multiPointElement
) {
resetCursor();
}
return {
@@ -130,7 +133,8 @@ export const actionFinalize = register({
appState: {
...appState,
elementType:
appState.elementLocked && multiPointElement
(appState.elementLocked || appState.elementType === "draw") &&
multiPointElement
? appState.elementType
: "selection",
draggingElement: null,
@@ -139,7 +143,9 @@ export const actionFinalize = register({
startBoundElement: null,
suggestedBindings: [],
selectedElementIds:
multiPointElement && !appState.elementLocked
multiPointElement &&
!appState.elementLocked &&
appState.elementType !== "draw"
? {
...appState.selectedElementIds,
[multiPointElement.id]: true,
+2 -4
View File
@@ -7,7 +7,6 @@ import { register } from "./register";
import { allowFullScreen, exitFullScreen, isFullScreen } from "../utils";
import { CODES, KEYS } from "../keys";
import { HelpIcon } from "../components/HelpIcon";
import { EVENT_DIALOG, trackEvent } from "../analytics";
export const actionToggleCanvasMenu = register({
name: "toggleCanvasMenu",
@@ -72,17 +71,16 @@ export const actionFullScreen = register({
export const actionShortcuts = register({
name: "toggleShortcuts",
perform: (_elements, appState) => {
trackEvent(EVENT_DIALOG, "shortcuts");
return {
appState: {
...appState,
showShortcutsDialog: true,
showHelpDialog: true,
},
commitToHistory: false,
};
},
PanelComponent: ({ updateData }) => (
<HelpIcon title={t("shortcutsDialog.title")} onClick={updateData} />
<HelpIcon title={t("helpDialog.title")} onClick={updateData} />
),
keyTest: (event) => event.key === KEYS.QUESTION_MARK,
});
+3 -5
View File
@@ -1,16 +1,14 @@
import React from "react";
import { Avatar } from "../components/Avatar";
import { register } from "./register";
import { getClientColors, getClientInitials } from "../clients";
import { Collaborator } from "../types";
import { Avatar } from "../components/Avatar";
import { centerScrollOn } from "../scene/scroll";
import { EVENT_SHARE, trackEvent } from "../analytics";
import { Collaborator } from "../types";
import { register } from "./register";
export const actionGoToCollaborator = register({
name: "goToCollaborator",
perform: (_elements, appState, value) => {
const point = value as Collaborator["pointer"];
trackEvent(EVENT_SHARE, "go to collaborator");
if (!point) {
return { appState, commitToHistory: false };
}
+41 -75
View File
@@ -1,56 +1,53 @@
import React from "react";
import { getLanguage } from "../i18n";
import {
ExcalidrawElement,
ExcalidrawTextElement,
TextAlign,
FontFamily,
ExcalidrawLinearElement,
Arrowhead,
} from "../element/types";
import {
getCommonAttributeOfSelectedElements,
isSomeElementSelected,
getTargetElements,
canChangeSharpness,
canHaveArrowheads,
} from "../scene";
import { ButtonSelect } from "../components/ButtonSelect";
import { AppState } from "../../src/types";
import { ButtonIconSelect } from "../components/ButtonIconSelect";
import { ButtonSelect } from "../components/ButtonSelect";
import { ColorPicker } from "../components/ColorPicker";
import { IconPicker } from "../components/IconPicker";
import {
isTextElement,
redrawTextBoundingBox,
getNonDeletedElements,
} from "../element";
import { isLinearElement, isLinearElementType } from "../element/typeChecks";
import { ColorPicker } from "../components/ColorPicker";
import { AppState } from "../../src/types";
import { t } from "../i18n";
import { register } from "./register";
import { newElementWith } from "../element/mutateElement";
import { DEFAULT_FONT_SIZE, DEFAULT_FONT_FAMILY } from "../constants";
import { randomInteger } from "../random";
import {
FillHachureIcon,
FillCrossHatchIcon,
FillSolidIcon,
StrokeWidthIcon,
StrokeStyleSolidIcon,
StrokeStyleDashedIcon,
StrokeStyleDottedIcon,
EdgeSharpIcon,
EdgeRoundIcon,
SloppinessArchitectIcon,
SloppinessArtistIcon,
SloppinessCartoonistIcon,
ArrowheadArrowIcon,
ArrowheadBarIcon,
ArrowheadDotIcon,
ArrowheadNoneIcon,
EdgeRoundIcon,
EdgeSharpIcon,
FillCrossHatchIcon,
FillHachureIcon,
FillSolidIcon,
SloppinessArchitectIcon,
SloppinessArtistIcon,
SloppinessCartoonistIcon,
StrokeStyleDashedIcon,
StrokeStyleDottedIcon,
StrokeStyleSolidIcon,
StrokeWidthIcon,
} from "../components/icons";
import { EVENT_CHANGE, trackEvent } from "../analytics";
import colors from "../colors";
import { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE } from "../constants";
import {
getNonDeletedElements,
isTextElement,
redrawTextBoundingBox,
} from "../element";
import { newElementWith } from "../element/mutateElement";
import { isLinearElement, isLinearElementType } from "../element/typeChecks";
import {
Arrowhead,
ExcalidrawElement,
ExcalidrawLinearElement,
ExcalidrawTextElement,
FontFamily,
TextAlign,
} from "../element/types";
import { getLanguage, t } from "../i18n";
import { randomInteger } from "../random";
import {
canChangeSharpness,
canHaveArrowheads,
getCommonAttributeOfSelectedElements,
getTargetElements,
isSomeElementSelected,
} from "../scene";
import { register } from "./register";
const changeProperty = (
elements: readonly ExcalidrawElement[],
@@ -92,15 +89,6 @@ const getFormValue = function <T>(
export const actionChangeStrokeColor = register({
name: "changeStrokeColor",
perform: (elements, appState, value) => {
if (value !== appState.currentItemStrokeColor) {
trackEvent(
EVENT_CHANGE,
"stroke color",
colors.elementStroke.includes(value)
? `${value} (picker ${colors.elementStroke.indexOf(value)})`
: value,
);
}
return {
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
@@ -132,16 +120,6 @@ export const actionChangeStrokeColor = register({
export const actionChangeBackgroundColor = register({
name: "changeBackgroundColor",
perform: (elements, appState, value) => {
if (value !== appState.currentItemBackgroundColor) {
trackEvent(
EVENT_CHANGE,
"background color",
colors.elementBackground.includes(value)
? `${value} (picker ${colors.elementBackground.indexOf(value)})`
: value,
);
}
return {
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
@@ -173,7 +151,6 @@ export const actionChangeBackgroundColor = register({
export const actionChangeFillStyle = register({
name: "changeFillStyle",
perform: (elements, appState, value) => {
trackEvent(EVENT_CHANGE, "fill", value);
return {
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
@@ -223,7 +200,6 @@ export const actionChangeFillStyle = register({
export const actionChangeStrokeWidth = register({
name: "changeStrokeWidth",
perform: (elements, appState, value) => {
trackEvent(EVENT_CHANGE, "stroke", "width", value);
return {
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
@@ -286,7 +262,6 @@ export const actionChangeStrokeWidth = register({
export const actionChangeSloppiness = register({
name: "changeSloppiness",
perform: (elements, appState, value) => {
trackEvent(EVENT_CHANGE, "stroke", "sloppiness", value);
return {
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
@@ -335,7 +310,6 @@ export const actionChangeSloppiness = register({
export const actionChangeStrokeStyle = register({
name: "changeStrokeStyle",
perform: (elements, appState, value) => {
trackEvent(EVENT_CHANGE, "style", value);
return {
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
@@ -383,7 +357,6 @@ export const actionChangeStrokeStyle = register({
export const actionChangeOpacity = register({
name: "changeOpacity",
perform: (elements, appState, value) => {
trackEvent(EVENT_CHANGE, "opacity", "value", value);
return {
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
@@ -580,7 +553,6 @@ export const actionChangeSharpness = register({
const shouldUpdateForLinearElements = targetElements.length
? targetElements.every(isLinearElement)
: isLinearElementType(appState.elementType);
trackEvent(EVENT_CHANGE, "edge", value);
return {
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
@@ -642,12 +614,6 @@ export const actionChangeArrowhead = register({
return {
elements: changeProperty(elements, appState, (el) => {
if (isLinearElement(el)) {
trackEvent(
EVENT_CHANGE,
`arrowhead ${value.position}`,
value.type || "none",
);
const { position, type } = value;
if (position === "start") {
+5
View File
@@ -4,6 +4,7 @@ import {
redrawTextBoundingBox,
} from "../element";
import { CODES, KEYS } from "../keys";
import { t } from "../i18n";
import { register } from "./register";
import { mutateElement, newElementWith } from "../element/mutateElement";
import {
@@ -23,6 +24,10 @@ export const actionCopyStyles = register({
copiedStyles = JSON.stringify(element);
}
return {
appState: {
...appState,
toastMessage: t("toast.copyStyles"),
},
commitToHistory: false,
};
},
+3 -1
View File
@@ -20,6 +20,7 @@ export type ShortcutName =
| "group"
| "ungroup"
| "gridMode"
| "zenMode"
| "stats"
| "addToLibrary";
@@ -33,7 +34,7 @@ const shortcutMap: Record<ShortcutName, string[]> = {
delete: [getShortcutKey("Del")],
duplicateSelection: [
getShortcutKey("CtrlOrCmd+D"),
getShortcutKey(`Alt+${t("shortcutsDialog.drag")}`),
getShortcutKey(`Alt+${t("helpDialog.drag")}`),
],
sendBackward: [getShortcutKey("CtrlOrCmd+[")],
bringForward: [getShortcutKey("CtrlOrCmd+]")],
@@ -52,6 +53,7 @@ const shortcutMap: Record<ShortcutName, string[]> = {
group: [getShortcutKey("CtrlOrCmd+G")],
ungroup: [getShortcutKey("CtrlOrCmd+Shift+G")],
gridMode: [getShortcutKey("CtrlOrCmd+'")],
zenMode: [getShortcutKey("Alt+Z")],
stats: [],
addToLibrary: [],
};
+7 -16
View File
@@ -1,18 +1,8 @@
export const EVENT_ACTION = "action";
export const EVENT_ALIGN = "align";
export const EVENT_CHANGE = "change";
export const EVENT_DIALOG = "dialog";
export const EVENT_EXIT = "exit";
export const EVENT_IO = "io";
export const EVENT_LAYER = "layer";
export const EVENT_LIBRARY = "library";
export const EVENT_LOAD = "load";
export const EVENT_SHAPE = "shape";
export const EVENT_SHARE = "share";
export const EVENT_MAGIC = "magic";
export const trackEvent =
typeof window !== "undefined" && window.gtag
typeof process !== "undefined" &&
process.env?.REACT_APP_GOOGLE_ANALYTICS_ID &&
typeof window !== "undefined" &&
window.gtag
? (category: string, name: string, label?: string, value?: number) => {
window.gtag("event", name, {
event_category: category,
@@ -20,8 +10,9 @@ export const trackEvent =
value,
});
}
: typeof process !== "undefined" && process?.env?.JEST_WORKER_ID
: typeof process !== "undefined" && process.env?.JEST_WORKER_ID
? (category: string, name: string, label?: string, value?: number) => {}
: (category: string, name: string, label?: string, value?: number) => {
console.info("Track Event", category, name, label, value);
// Uncomment the next line to track locally
// console.info("Track Event", category, name, label, value);
};
+4 -2
View File
@@ -63,10 +63,11 @@ export const getDefaultAppState = (): Omit<
selectionElement: null,
shouldAddWatermark: false,
shouldCacheIgnoreZoom: false,
showShortcutsDialog: false,
showHelpDialog: false,
showStats: false,
startBoundElement: null,
suggestedBindings: [],
toastMessage: null,
viewBackgroundColor: oc.white,
width: window.innerWidth,
zenModeEnabled: false,
@@ -141,10 +142,11 @@ const APP_STATE_STORAGE_CONF = (<
selectionElement: { browser: false, export: false },
shouldAddWatermark: { browser: true, export: false },
shouldCacheIgnoreZoom: { browser: true, export: false },
showShortcutsDialog: { browser: false, export: false },
showHelpDialog: { browser: false, export: false },
showStats: { browser: true, export: false },
startBoundElement: { browser: false, export: false },
suggestedBindings: { browser: false, export: false },
toastMessage: { browser: false, export: false },
viewBackgroundColor: { browser: true, export: true },
width: { browser: false, export: false },
zenModeEnabled: { browser: true, export: false },
-2
View File
@@ -1,4 +1,3 @@
import { EVENT_MAGIC, trackEvent } from "./analytics";
import colors from "./colors";
import { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, ENV } from "./constants";
import { newElement, newLinearElement, newTextElement } from "./element";
@@ -473,7 +472,6 @@ export const renderSpreadsheet = (
x: number,
y: number,
): ChartElements => {
trackEvent(EVENT_MAGIC, "chart", chartType, spreadsheet.values.length);
if (chartType === "line") {
return chartTypeLine(spreadsheet, x, y);
}
+12 -17
View File
@@ -1,23 +1,22 @@
import React from "react";
import { AppState, Zoom } from "../types";
import { ExcalidrawElement } from "../element/types";
import { ActionManager } from "../actions/manager";
import { getNonDeletedElements } from "../element";
import { ExcalidrawElement } from "../element/types";
import { t } from "../i18n";
import useIsMobile from "../is-mobile";
import {
hasBackground,
hasStroke,
canChangeSharpness,
hasText,
canHaveArrowheads,
getTargetElements,
hasBackground,
hasStroke,
hasText,
} from "../scene";
import { t } from "../i18n";
import { SHAPES } from "../shapes";
import { ToolButton } from "./ToolButton";
import { AppState, Zoom } from "../types";
import { capitalizeString, isTransparent, setCursorForShape } from "../utils";
import Stack from "./Stack";
import useIsMobile from "../is-mobile";
import { getNonDeletedElements } from "../element";
import { trackEvent, EVENT_SHAPE, EVENT_DIALOG } from "../analytics";
import { ToolButton } from "./ToolButton";
export const SelectedShapeActions = ({
appState,
@@ -164,9 +163,9 @@ export const ShapesSwitcher = ({
{SHAPES.map(({ value, icon, key }, index) => {
const label = t(`toolBar.${value}`);
const letter = typeof key === "string" ? key : key[0];
const shortcut = `${capitalizeString(letter)} ${t(
"shortcutsDialog.or",
)} ${index + 1}`;
const shortcut = `${capitalizeString(letter)} ${t("helpDialog.or")} ${
index + 1
}`;
return (
<ToolButton
className="Shape"
@@ -181,7 +180,6 @@ export const ShapesSwitcher = ({
aria-keyshortcuts={shortcut}
data-testid={value}
onChange={() => {
trackEvent(EVENT_SHAPE, value, "toolbar");
setAppState({
elementType: value,
multiElement: null,
@@ -203,9 +201,6 @@ export const ShapesSwitcher = ({
title={`${capitalizeString(t("toolBar.library"))} — 9`}
aria-label={capitalizeString(t("toolBar.library"))}
onClick={() => {
if (!isLibraryOpen) {
trackEvent(EVENT_DIALOG, "library");
}
setAppState({ isLibraryOpen: !isLibraryOpen });
}}
/>
+28 -23
View File
@@ -8,12 +8,7 @@ import { createRedoAction, createUndoAction } from "../actions/actionHistory";
import { ActionManager } from "../actions/manager";
import { actions } from "../actions/register";
import { ActionResult } from "../actions/types";
import {
EVENT_DIALOG,
EVENT_LIBRARY,
EVENT_SHAPE,
trackEvent,
} from "../analytics";
import { trackEvent } from "../analytics";
import { getDefaultAppState } from "../appState";
import {
copyToClipboard,
@@ -111,7 +106,7 @@ import {
selectGroupsForSelectedElements,
} from "../groups";
import { createHistory, SceneHistory } from "../history";
import { t, getLanguage, setLanguage, languages, defaultLang } from "../i18n";
import { defaultLang, getLanguage, languages, setLanguage, t } from "../i18n";
import {
CODES,
getResizeCenterPointKey,
@@ -163,6 +158,7 @@ import {
import ContextMenu from "./ContextMenu";
import LayerUI from "./LayerUI";
import { Stats } from "./Stats";
import { Toast } from "./Toast";
const { history } = createHistory();
@@ -381,6 +377,12 @@ class App extends React.Component<ExcalidrawProps, AppState> {
onClose={this.toggleStats}
/>
)}
{this.state.toastMessage !== null && (
<Toast
message={this.state.toastMessage}
clearToast={this.clearToast}
/>
)}
<main>
<canvas
id="canvas"
@@ -504,7 +506,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
)
) {
await Library.importLibrary(blob);
trackEvent(EVENT_LIBRARY, "import");
this.setState({
isLibraryOpen: true,
});
@@ -917,6 +918,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
this.canvas!,
this.state,
);
this.setState({ toastMessage: t("toast.copyToClipboardAsPng") });
} catch (error) {
console.error(error);
this.setState({ errorMessage: error.message });
@@ -1134,7 +1136,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
toggleLock = () => {
this.setState((prevState) => {
trackEvent(EVENT_SHAPE, "lock", !prevState.elementLocked ? "on" : "off");
return {
elementLocked: !prevState.elementLocked,
elementType: prevState.elementLocked
@@ -1158,7 +1159,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
toggleStats = () => {
if (!this.state.showStats) {
trackEvent(EVENT_DIALOG, "stats");
trackEvent("dialog", "stats");
}
this.setState({
showStats: !this.state.showStats,
@@ -1175,6 +1176,10 @@ class App extends React.Component<ExcalidrawProps, AppState> {
});
};
clearToast = () => {
this.setState({ toastMessage: null });
};
public updateScene = withBatchedUpdates((sceneData: SceneData) => {
if (sceneData.commitToHistory) {
history.resumeRecording();
@@ -1244,7 +1249,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
if (event.key === KEYS.QUESTION_MARK) {
this.setState({
showShortcutsDialog: true,
showHelpDialog: true,
});
}
@@ -1270,9 +1275,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
}
if (event.code === CODES.NINE) {
if (!this.state.isLibraryOpen) {
trackEvent(EVENT_DIALOG, "library");
}
this.setState({ isLibraryOpen: !this.state.isLibraryOpen });
}
@@ -1357,7 +1359,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
) {
const shape = findShapeByKey(event.key);
if (shape) {
trackEvent(EVENT_SHAPE, shape, "shortcut");
this.selectShapeTool(shape);
} else if (event.key === KEYS.Q) {
this.toggleLock();
@@ -1741,7 +1742,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
resetCursor();
if (!event[KEYS.CTRL_OR_CMD]) {
trackEvent(EVENT_SHAPE, "text", "double-click");
this.startTextEditing({
sceneX,
sceneY,
@@ -3141,7 +3141,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
);
}
this.setState({ suggestedBindings: [], startBoundElement: null });
if (!elementLocked) {
if (!elementLocked && elementType !== "draw") {
resetCursor();
this.setState((prevState) => ({
draggingElement: null,
@@ -3288,7 +3288,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
return;
}
if (!elementLocked && draggingElement) {
if (!elementLocked && elementType !== "draw" && draggingElement) {
this.setState((prevState) => ({
selectedElementIds: {
...prevState.selectedElementIds,
@@ -3312,7 +3312,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
);
}
if (!elementLocked) {
if (!elementLocked && elementType !== "draw") {
resetCursor();
this.setState({
draggingElement: null,
@@ -3587,9 +3587,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
transformElements(
pointerDownState,
transformHandleType,
(newTransformHandle) => {
pointerDownState.resize.handleType = newTransformHandle;
},
selectedElements,
pointerDownState.resize.arrowDirection,
getRotateWithDiscreteAngleKey(event),
@@ -3650,6 +3647,12 @@ class App extends React.Component<ExcalidrawProps, AppState> {
label: t("labels.gridMode"),
action: this.toggleGridMode,
},
{
checked: this.state.zenModeEnabled,
shortcutName: "zenMode",
label: t("buttons.zenMode"),
action: this.toggleZenMode,
},
{
checked: this.state.showStats,
shortcutName: "stats",
@@ -3822,7 +3825,9 @@ class App extends React.Component<ExcalidrawProps, AppState> {
};
private resetShouldCacheIgnoreZoomDebounced = debounce(() => {
this.setState({ shouldCacheIgnoreZoom: false });
if (!this.unmounted) {
this.setState({ shouldCacheIgnoreZoom: false });
}
}, 300);
private getCanvasOffsets(offsets?: {
@@ -1,6 +1,5 @@
import React from "react";
import { ActionManager } from "../actions/manager";
import { EVENT_CHANGE, trackEvent } from "../analytics";
import { AppState } from "../types";
import { DarkModeToggle } from "./DarkModeToggle";
@@ -19,8 +18,6 @@ export const BackgroundPickerAndDarkModeToggle = ({
<DarkModeToggle
value={appState.appearance}
onChange={(appearance) => {
// TODO: track the theme on the first load too
trackEvent(EVENT_CHANGE, "theme", appearance);
setAppState({ appearance });
}}
/>
+1 -5
View File
@@ -6,7 +6,6 @@ import useIsMobile from "../is-mobile";
import { users } from "./icons";
import "./CollabButton.scss";
import { EVENT_DIALOG, trackEvent } from "../analytics";
const CollabButton = ({
isCollaborating,
@@ -23,10 +22,7 @@ const CollabButton = ({
className={clsx("CollabButton", {
"is-collaborating": isCollaborating,
})}
onClick={() => {
trackEvent(EVENT_DIALOG, "collaboration");
onClick();
}}
onClick={onClick}
icon={users}
type="button"
title={t("buttons.roomDialog")}
+1
View File
@@ -54,6 +54,7 @@
.context-menu-option__shortcut {
justify-self: end;
opacity: 0.6;
font-family: inherit;
font-size: 0.7rem;
}
}
+2 -2
View File
@@ -52,11 +52,11 @@ const ContextMenu = ({ options, onCloseRequest, top, left }: Props) => {
onClick={action}
>
<div className="context-menu-option__label">{label}</div>
<div className="context-menu-option__shortcut">
<kbd className="context-menu-option__shortcut">
{shortcutName
? getShortcutFromShortcutName(shortcutName)
: ""}
</div>
</kbd>
</button>
</li>
))}
+6
View File
@@ -1,6 +1,11 @@
@import "../css/_variables";
.excalidraw {
.Dialog {
user-select: text;
cursor: auto;
}
.Dialog__title {
display: grid;
align-items: center;
@@ -10,6 +15,7 @@
padding: calc(var(--space-factor) * 2);
text-align: center;
font-variant: small-caps;
font-size: 1.2em;
}
.Dialog__titleContent {
+2 -2
View File
@@ -80,7 +80,7 @@ export const Dialog = (props: {
onCloseRequest={props.onCloseRequest}
>
<Island ref={setIslandNode}>
<h3 id="dialog-title" className="Dialog__title">
<h2 id="dialog-title" className="Dialog__title">
<span className="Dialog__titleContent">{props.title}</span>
<button
className="Modal__close"
@@ -89,7 +89,7 @@ export const Dialog = (props: {
>
{useIsMobile() ? back : close}
</button>
</h3>
</h2>
<div className="Dialog__content">{props.children}</div>
</Island>
</Modal>
-2
View File
@@ -1,7 +1,6 @@
import React, { useEffect, useRef, useState } from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { ActionsManagerInterface } from "../actions/types";
import { EVENT_DIALOG, trackEvent } from "../analytics";
import { probablySupportsClipboardBlob } from "../clipboard";
import { canvasToBlob } from "../data/blob";
import { NonDeletedExcalidrawElement } from "../element/types";
@@ -251,7 +250,6 @@ export const ExportDialog = ({
<>
<ToolButton
onClick={() => {
trackEvent(EVENT_DIALOG, "export");
setModalIsShown(true);
}}
icon={exportFile}
+1 -5
View File
@@ -1,6 +1,5 @@
import React from "react";
import oc from "open-color";
import { EVENT_EXIT, trackEvent } from "../analytics";
import React from "react";
// https://github.com/tholman/github-corners
export const GitHubCorner = React.memo(
@@ -17,9 +16,6 @@ export const GitHubCorner = React.memo(
target="_blank"
rel="noopener noreferrer"
aria-label="GitHub repository"
onClick={() => {
trackEvent(EVENT_EXIT, "github");
}}
>
<path
d="M0 0l115 115h15l12 27 108 108V0z"
@@ -1,23 +1,28 @@
@import "../css/_variables";
.excalidraw {
.ShortcutsDialog-island {
.HelpDialog h3 {
border-bottom: 1px solid var(--button-gray-2);
padding-bottom: 4px;
}
.HelpDialog--island {
border: 1px solid var(--button-gray-2);
margin-bottom: 16px;
}
.ShortcutsDialog-island-title {
.HelpDialog--island-title {
margin: 0;
padding: 4px;
background-color: var(--button-gray-1);
text-align: center;
}
.ShorcutsDialog-shortcut {
.HelpDialog--shortcut {
border-top: 1px solid var(--button-gray-2);
}
.ShorcutsDialog-key {
.HelpDialog--key {
word-break: keep-all;
border: 1px solid var(--button-gray-2);
padding: 2px 8px;
@@ -29,14 +34,23 @@
box-sizing: border-box;
display: flex;
align-items: center;
font-family: inherit;
}
.ShortcutsDialog-footer {
.HelpDialog--header {
display: flex;
flex-direction: row;
justify-content: space-evenly;
border-top: 1px solid var(--button-gray-2);
margin-top: 8px;
padding-top: 16px;
margin-bottom: 32px;
padding-bottom: 16px;
}
.HelpDialog--btn {
border: 1px solid var(--link-color);
padding: 8px 32px;
border-radius: 4px;
}
.HelpDialog--btn:hover {
text-decoration: none;
}
}
+348
View File
@@ -0,0 +1,348 @@
import React from "react";
import { t } from "../i18n";
import { isDarwin } from "../keys";
import { Dialog } from "./Dialog";
import { getShortcutKey } from "../utils";
import "./HelpDialog.scss";
const Header = () => (
<div className="HelpDialog--header">
<a
className="HelpDialog--btn"
href="https://github.com/excalidraw/excalidraw#documentation"
target="_blank"
rel="noopener noreferrer"
>
{t("helpDialog.documentation")}
</a>
<a
className="HelpDialog--btn"
href="https://blog.excalidraw.com"
target="_blank"
rel="noopener noreferrer"
>
{t("helpDialog.blog")}
</a>
<a
className="HelpDialog--btn"
href="https://github.com/excalidraw/excalidraw/issues"
target="_blank"
rel="noopener noreferrer"
>
{t("helpDialog.github")}
</a>
</div>
);
const Section = (props: { title: string; children: React.ReactNode }) => (
<>
<h3>{props.title}</h3>
{props.children}
</>
);
const Columns = (props: { children: React.ReactNode }) => (
<div
style={{
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
justifyContent: "space-between",
}}
>
{props.children}
</div>
);
const Column = (props: { children: React.ReactNode }) => (
<div style={{ width: "49%" }}>{props.children}</div>
);
const ShortcutIsland = (props: {
caption: string;
children: React.ReactNode;
}) => (
<div className="HelpDialog--island">
<h3 className="HelpDialog--island-title">{props.caption}</h3>
{props.children}
</div>
);
const Shortcut = (props: {
label: string;
shortcuts: string[];
isOr: boolean;
}) => {
return (
<div className="HelpDialog--shortcut">
<div
style={{
display: "flex",
margin: "0",
padding: "4px 8px",
alignItems: "center",
}}
>
<div
style={{
lineHeight: 1.4,
}}
>
{props.label}
</div>
<div
style={{
display: "flex",
flex: "0 0 auto",
justifyContent: "flex-end",
marginInlineStart: "auto",
minWidth: "30%",
}}
>
{props.shortcuts.map((shortcut, index) => (
<React.Fragment key={index}>
<ShortcutKey>{shortcut}</ShortcutKey>
{props.isOr &&
index !== props.shortcuts.length - 1 &&
t("helpDialog.or")}
</React.Fragment>
))}
</div>
</div>
</div>
);
};
Shortcut.defaultProps = {
isOr: true,
};
const ShortcutKey = (props: { children: React.ReactNode }) => (
<kbd className="HelpDialog--key" {...props} />
);
export const HelpDialog = ({ onClose }: { onClose?: () => void }) => {
const handleClose = React.useCallback(() => {
if (onClose) {
onClose();
}
}, [onClose]);
return (
<>
<Dialog
onCloseRequest={handleClose}
title={t("helpDialog.title")}
className={"HelpDialog"}
>
<Header />
<Section title={t("helpDialog.shortcuts")}>
<Columns>
<Column>
<ShortcutIsland caption={t("helpDialog.shapes")}>
<Shortcut
label={t("toolBar.selection")}
shortcuts={["V", "1"]}
/>
<Shortcut
label={t("toolBar.rectangle")}
shortcuts={["R", "2"]}
/>
<Shortcut label={t("toolBar.diamond")} shortcuts={["D", "3"]} />
<Shortcut label={t("toolBar.ellipse")} shortcuts={["E", "4"]} />
<Shortcut label={t("toolBar.arrow")} shortcuts={["A", "5"]} />
<Shortcut label={t("toolBar.line")} shortcuts={["P", "6"]} />
<Shortcut
label={t("toolBar.draw")}
shortcuts={["Shift+P", "7"]}
/>
<Shortcut label={t("toolBar.text")} shortcuts={["T", "8"]} />
<Shortcut
label={t("helpDialog.textNewLine")}
shortcuts={[
getShortcutKey("Enter"),
getShortcutKey("Shift+Enter"),
]}
/>
<Shortcut
label={t("helpDialog.textFinish")}
shortcuts={[
getShortcutKey("Esc"),
getShortcutKey("CtrlOrCmd+Enter"),
]}
/>
<Shortcut
label={t("helpDialog.curvedArrow")}
shortcuts={[
"A",
t("helpDialog.click"),
t("helpDialog.click"),
t("helpDialog.click"),
]}
isOr={false}
/>
<Shortcut
label={t("helpDialog.curvedLine")}
shortcuts={[
"L",
t("helpDialog.click"),
t("helpDialog.click"),
t("helpDialog.click"),
]}
isOr={false}
/>
<Shortcut label={t("toolBar.lock")} shortcuts={["Q"]} />
<Shortcut
label={t("helpDialog.preventBinding")}
shortcuts={[getShortcutKey("CtrlOrCmd")]}
/>
</ShortcutIsland>
<ShortcutIsland caption={t("helpDialog.view")}>
<Shortcut
label={t("buttons.zoomIn")}
shortcuts={[getShortcutKey("CtrlOrCmd++")]}
/>
<Shortcut
label={t("buttons.zoomOut")}
shortcuts={[getShortcutKey("CtrlOrCmd+-")]}
/>
<Shortcut
label={t("buttons.resetZoom")}
shortcuts={[getShortcutKey("CtrlOrCmd+0")]}
/>
<Shortcut
label={t("helpDialog.zoomToFit")}
shortcuts={["Shift+1"]}
/>
<Shortcut
label={t("helpDialog.zoomToSelection")}
shortcuts={["Shift+2"]}
/>
<Shortcut label={t("buttons.fullScreen")} shortcuts={["F"]} />
<Shortcut
label={t("buttons.zenMode")}
shortcuts={[getShortcutKey("Alt+Z")]}
/>
<Shortcut
label={t("labels.gridMode")}
shortcuts={[getShortcutKey("CtrlOrCmd+'")]}
/>
</ShortcutIsland>
</Column>
<Column>
<ShortcutIsland caption={t("helpDialog.editor")}>
<Shortcut
label={t("labels.selectAll")}
shortcuts={[getShortcutKey("CtrlOrCmd+A")]}
/>
<Shortcut
label={t("labels.multiSelect")}
shortcuts={[getShortcutKey(`Shift+${t("helpDialog.click")}`)]}
/>
<Shortcut
label={t("labels.moveCanvas")}
shortcuts={[
getShortcutKey(`Space+${t("helpDialog.drag")}`),
getShortcutKey(`Wheel+${t("helpDialog.drag")}`),
]}
isOr={true}
/>
<Shortcut
label={t("labels.cut")}
shortcuts={[getShortcutKey("CtrlOrCmd+X")]}
/>
<Shortcut
label={t("labels.copy")}
shortcuts={[getShortcutKey("CtrlOrCmd+C")]}
/>
<Shortcut
label={t("labels.paste")}
shortcuts={[getShortcutKey("CtrlOrCmd+V")]}
/>
<Shortcut
label={t("labels.copyAsPng")}
shortcuts={[getShortcutKey("Shift+Alt+C")]}
/>
<Shortcut
label={t("labels.copyStyles")}
shortcuts={[getShortcutKey("CtrlOrCmd+Alt+C")]}
/>
<Shortcut
label={t("labels.pasteStyles")}
shortcuts={[getShortcutKey("CtrlOrCmd+Alt+V")]}
/>
<Shortcut
label={t("labels.delete")}
shortcuts={[getShortcutKey("Del")]}
/>
<Shortcut
label={t("labels.sendToBack")}
shortcuts={[
isDarwin
? getShortcutKey("CtrlOrCmd+Alt+[")
: getShortcutKey("CtrlOrCmd+Shift+["),
]}
/>
<Shortcut
label={t("labels.bringToFront")}
shortcuts={[
isDarwin
? getShortcutKey("CtrlOrCmd+Alt+]")
: getShortcutKey("CtrlOrCmd+Shift+]"),
]}
/>
<Shortcut
label={t("labels.sendBackward")}
shortcuts={[getShortcutKey("CtrlOrCmd+[")]}
/>
<Shortcut
label={t("labels.bringForward")}
shortcuts={[getShortcutKey("CtrlOrCmd+]")]}
/>
<Shortcut
label={t("labels.alignTop")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Up")]}
/>
<Shortcut
label={t("labels.alignBottom")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Down")]}
/>
<Shortcut
label={t("labels.alignLeft")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Left")]}
/>
<Shortcut
label={t("labels.alignRight")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Right")]}
/>
<Shortcut
label={t("labels.duplicateSelection")}
shortcuts={[
getShortcutKey("CtrlOrCmd+D"),
getShortcutKey(`Alt+${t("helpDialog.drag")}`),
]}
/>
<Shortcut
label={t("buttons.undo")}
shortcuts={[getShortcutKey("CtrlOrCmd+Z")]}
/>
<Shortcut
label={t("buttons.redo")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Z")]}
/>
<Shortcut
label={t("labels.group")}
shortcuts={[getShortcutKey("CtrlOrCmd+G")]}
/>
<Shortcut
label={t("labels.ungroup")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+G")]}
/>
</ShortcutIsland>
</Column>
</Columns>
</Section>
</Dialog>
</>
);
};
+2 -12
View File
@@ -1,4 +1,5 @@
import React from "react";
import { questionCircle } from "../components/icons";
type HelpIconProps = {
title?: string;
@@ -7,19 +8,8 @@ type HelpIconProps = {
onClick?(): void;
};
const ICON = (
<svg
width="30"
height="22"
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M528 448H48c-26.51 0-48-21.49-48-48V112c0-26.51 21.49-48 48-48h480c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48zM128 180v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm-336 96v-40c0-6.627-5.373-12-12-12H76c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12zm288 0v-40c0-6.627-5.373-12-12-12H172c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h232c6.627 0 12-5.373 12-12zm96 0v-40c0-6.627-5.373-12-12-12h-40c-6.627 0-12 5.373-12 12v40c0 6.627 5.373 12 12 12h40c6.627 0 12-5.373 12-12z" />
</svg>
);
export const HelpIcon = (props: HelpIconProps) => (
<label title={`${props.title} — ?`} className="help-icon">
<div onClick={props.onClick}>{ICON}</div>
<div onClick={props.onClick}>{questionCircle}</div>
</label>
);
+1
View File
@@ -102,6 +102,7 @@
position: absolute;
bottom: 2px;
font-size: 0.7em;
color: var(--keybinding-color);
:root[dir="ltr"] & {
right: 2px;
+32 -56
View File
@@ -1,56 +1,46 @@
import clsx from "clsx";
import React, {
RefObject,
useCallback,
useEffect,
useRef,
useState,
RefObject,
useEffect,
useCallback,
} from "react";
import { showSelectedShapeActions } from "../element";
import { calculateScrollCenter, getSelectedElements } from "../scene";
import { exportCanvas } from "../data";
import { AppState, LibraryItems, LibraryItem } from "../types";
import { NonDeletedExcalidrawElement } from "../element/types";
import { ActionManager } from "../actions/manager";
import { Island } from "./Island";
import Stack from "./Stack";
import { FixedSideContainer } from "./FixedSideContainer";
import { UserList } from "./UserList";
import { LockIcon } from "./LockIcon";
import { ExportDialog, ExportCB } from "./ExportDialog";
import { CLASSES } from "../constants";
import { exportCanvas } from "../data";
import { importLibraryFromJSON, saveLibraryAsJSON } from "../data/json";
import { Library } from "../data/library";
import { showSelectedShapeActions } from "../element";
import { NonDeletedExcalidrawElement } from "../element/types";
import { Language, t } from "../i18n";
import { HintViewer } from "./HintViewer";
import useIsMobile from "../is-mobile";
import { calculateScrollCenter, getSelectedElements } from "../scene";
import { ExportType } from "../scene/types";
import { MobileMenu } from "./MobileMenu";
import { ZoomActions, SelectedShapeActions, ShapesSwitcher } from "./Actions";
import { Section } from "./Section";
import { AppState, LibraryItem, LibraryItems } from "../types";
import { muteFSAbortError } from "../utils";
import { SelectedShapeActions, ShapesSwitcher, ZoomActions } from "./Actions";
import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle";
import CollabButton from "./CollabButton";
import { ErrorDialog } from "./ErrorDialog";
import { ShortcutsDialog } from "./ShortcutsDialog";
import { LoadingMessage } from "./LoadingMessage";
import { CLASSES } from "../constants";
import { shield, exportFile, load } from "./icons";
import { ExportCB, ExportDialog } from "./ExportDialog";
import { FixedSideContainer } from "./FixedSideContainer";
import { GitHubCorner } from "./GitHubCorner";
import { Tooltip } from "./Tooltip";
import { HintViewer } from "./HintViewer";
import { exportFile, load, shield } from "./icons";
import { Island } from "./Island";
import "./LayerUI.scss";
import { LibraryUnit } from "./LibraryUnit";
import { ToolButton } from "./ToolButton";
import { saveLibraryAsJSON, importLibraryFromJSON } from "../data/json";
import { muteFSAbortError } from "../utils";
import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle";
import clsx from "clsx";
import { Library } from "../data/library";
import {
EVENT_ACTION,
EVENT_EXIT,
EVENT_LIBRARY,
trackEvent,
} from "../analytics";
import { LoadingMessage } from "./LoadingMessage";
import { LockIcon } from "./LockIcon";
import { MobileMenu } from "./MobileMenu";
import { PasteChartDialog } from "./PasteChartDialog";
import { Section } from "./Section";
import { HelpDialog } from "./HelpDialog";
import Stack from "./Stack";
import { ToolButton } from "./ToolButton";
import { Tooltip } from "./Tooltip";
import { UserList } from "./UserList";
interface LayerUIProps {
actionManager: ActionManager;
@@ -159,13 +149,7 @@ const LibraryMenuItems = ({
}}
/>
<a
href="https://libraries.excalidraw.com"
target="_excalidraw_libraries"
onClick={() => {
trackEvent(EVENT_EXIT, "libraries");
}}
>
<a href="https://libraries.excalidraw.com" target="_excalidraw_libraries">
{t("labels.libraries")}
</a>
</div>,
@@ -267,7 +251,6 @@ const LibraryMenu = ({
const items = await Library.loadLibrary();
const nextItems = items.filter((_, index) => index !== indexToRemove);
Library.saveLibrary(nextItems);
trackEvent(EVENT_LIBRARY, "remove");
setLibraryItems(nextItems);
}, []);
@@ -276,7 +259,6 @@ const LibraryMenu = ({
const items = await Library.loadLibrary();
const nextItems = [...items, elements];
onAddToLibrary();
trackEvent(EVENT_LIBRARY, "add");
Library.saveLibrary(nextItems);
setLibraryItems(nextItems);
},
@@ -328,9 +310,6 @@ const LayerUI = ({
href="https://blog.excalidraw.com/end-to-end-encryption/"
target="_blank"
rel="noopener noreferrer"
onClick={() => {
trackEvent(EVENT_EXIT, "e2ee shield");
}}
>
<Tooltip label={t("encrypted.tooltip")} position="above" long={true}>
{shield}
@@ -567,7 +546,6 @@ const LayerUI = ({
<button
className="scroll-back-to-content"
onClick={() => {
trackEvent(EVENT_ACTION, "scroll to content");
setAppState({
...calculateScrollCenter(elements, appState, canvas),
});
@@ -588,10 +566,8 @@ const LayerUI = ({
onClose={() => setAppState({ errorMessage: null })}
/>
)}
{appState.showShortcutsDialog && (
<ShortcutsDialog
onClose={() => setAppState({ showShortcutsDialog: false })}
/>
{appState.showHelpDialog && (
<HelpDialog onClose={() => setAppState({ showHelpDialog: false })} />
)}
{appState.pasteDialog.shown && (
<PasteChartDialog
-2
View File
@@ -16,7 +16,6 @@ import { SCROLLBAR_WIDTH, SCROLLBAR_MARGIN } from "../scene/scrollbars";
import { LockIcon } from "./LockIcon";
import { UserList } from "./UserList";
import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle";
import { EVENT_ACTION, trackEvent } from "../analytics";
type MobileMenuProps = {
appState: AppState;
@@ -149,7 +148,6 @@ export const MobileMenu = ({
<button
className="scroll-back-to-content"
onClick={() => {
trackEvent(EVENT_ACTION, "scroll to content");
setAppState({
...calculateScrollCenter(elements, appState, canvas),
});
+2
View File
@@ -1,5 +1,6 @@
import oc from "open-color";
import React, { useLayoutEffect, useRef, useState } from "react";
import { trackEvent } from "../analytics";
import { ChartElements, renderSpreadsheet, Spreadsheet } from "../charts";
import { ChartType } from "../element/types";
import { t } from "../i18n";
@@ -86,6 +87,7 @@ export const PasteChartDialog = ({
const handleChartClick = (chartType: ChartType, elements: ChartElements) => {
onInsertChart(elements);
trackEvent("magic", "chart", chartType);
setAppState({
currentChartType: chartType,
pasteDialog: {
-338
View File
@@ -1,338 +0,0 @@
import React from "react";
import { t } from "../i18n";
import { isDarwin } from "../keys";
import { Dialog } from "./Dialog";
import { getShortcutKey } from "../utils";
import "./ShortcutsDialog.scss";
import { EVENT_EXIT, trackEvent } from "../analytics";
const Columns = (props: { children: React.ReactNode }) => (
<div
style={{
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
justifyContent: "space-between",
}}
>
{props.children}
</div>
);
const Column = (props: { children: React.ReactNode }) => (
<div style={{ width: "49%" }}>{props.children}</div>
);
const ShortcutIsland = (props: {
caption: string;
children: React.ReactNode;
}) => (
<div className="ShortcutsDialog-island">
<h3 className="ShortcutsDialog-island-title">{props.caption}</h3>
{props.children}
</div>
);
const Shortcut = (props: {
label: string;
shortcuts: string[];
isOr: boolean;
}) => {
return (
<div className="ShorcutsDialog-shortcut">
<div
style={{
display: "flex",
margin: "0",
padding: "4px 8px",
alignItems: "center",
}}
>
<div
style={{
lineHeight: 1.4,
}}
>
{props.label}
</div>
<div
style={{
display: "flex",
flex: "0 0 auto",
justifyContent: "flex-end",
marginInlineStart: "auto",
minWidth: "30%",
}}
>
{props.shortcuts.map((shortcut, index) => (
<React.Fragment key={index}>
<ShortcutKey>{shortcut}</ShortcutKey>
{props.isOr &&
index !== props.shortcuts.length - 1 &&
t("shortcutsDialog.or")}
</React.Fragment>
))}
</div>
</div>
</div>
);
};
Shortcut.defaultProps = {
isOr: true,
};
const ShortcutKey = (props: { children: React.ReactNode }) => (
<span className="ShorcutsDialog-key" {...props} />
);
const Footer = () => (
<div className="ShortcutsDialog-footer">
<a
href="https://blog.excalidraw.com"
target="_blank"
rel="noopener noreferrer"
onClick={() => {
trackEvent(EVENT_EXIT, "blog");
}}
>
{t("shortcutsDialog.blog")}
</a>
<a
href="https://howto.excalidraw.com"
target="_blank"
rel="noopener noreferrer"
onClick={() => {
trackEvent(EVENT_EXIT, "guides");
}}
>
{t("shortcutsDialog.howto")}
</a>
<a
href="https://github.com/excalidraw/excalidraw/issues"
target="_blank"
rel="noopener noreferrer"
onClick={() => {
trackEvent(EVENT_EXIT, "issues");
}}
>
{t("shortcutsDialog.github")}
</a>
</div>
);
export const ShortcutsDialog = ({ onClose }: { onClose?: () => void }) => {
const handleClose = React.useCallback(() => {
if (onClose) {
onClose();
}
}, [onClose]);
return (
<>
<Dialog onCloseRequest={handleClose} title={t("shortcutsDialog.title")}>
<Columns>
<Column>
<ShortcutIsland caption={t("shortcutsDialog.shapes")}>
<Shortcut label={t("toolBar.selection")} shortcuts={["V", "1"]} />
<Shortcut label={t("toolBar.rectangle")} shortcuts={["R", "2"]} />
<Shortcut label={t("toolBar.diamond")} shortcuts={["D", "3"]} />
<Shortcut label={t("toolBar.ellipse")} shortcuts={["E", "4"]} />
<Shortcut label={t("toolBar.arrow")} shortcuts={["A", "5"]} />
<Shortcut label={t("toolBar.line")} shortcuts={["P", "6"]} />
<Shortcut
label={t("toolBar.draw")}
shortcuts={["Shift+P", "7"]}
/>
<Shortcut label={t("toolBar.text")} shortcuts={["T", "8"]} />
<Shortcut
label={t("shortcutsDialog.textNewLine")}
shortcuts={[
getShortcutKey("Enter"),
getShortcutKey("Shift+Enter"),
]}
/>
<Shortcut
label={t("shortcutsDialog.textFinish")}
shortcuts={[
getShortcutKey("Esc"),
getShortcutKey("CtrlOrCmd+Enter"),
]}
/>
<Shortcut
label={t("shortcutsDialog.curvedArrow")}
shortcuts={[
"A",
t("shortcutsDialog.click"),
t("shortcutsDialog.click"),
t("shortcutsDialog.click"),
]}
isOr={false}
/>
<Shortcut
label={t("shortcutsDialog.curvedLine")}
shortcuts={[
"L",
t("shortcutsDialog.click"),
t("shortcutsDialog.click"),
t("shortcutsDialog.click"),
]}
isOr={false}
/>
<Shortcut label={t("toolBar.lock")} shortcuts={["Q"]} />
<Shortcut
label={t("shortcutsDialog.preventBinding")}
shortcuts={[getShortcutKey("CtrlOrCmd")]}
/>
</ShortcutIsland>
<ShortcutIsland caption={t("shortcutsDialog.view")}>
<Shortcut
label={t("buttons.zoomIn")}
shortcuts={[getShortcutKey("CtrlOrCmd++")]}
/>
<Shortcut
label={t("buttons.zoomOut")}
shortcuts={[getShortcutKey("CtrlOrCmd+-")]}
/>
<Shortcut
label={t("buttons.resetZoom")}
shortcuts={[getShortcutKey("CtrlOrCmd+0")]}
/>
<Shortcut
label={t("shortcutsDialog.zoomToFit")}
shortcuts={["Shift+1"]}
/>
<Shortcut
label={t("shortcutsDialog.zoomToSelection")}
shortcuts={["Shift+2"]}
/>
<Shortcut label={t("buttons.fullScreen")} shortcuts={["F"]} />
<Shortcut
label={t("buttons.zenMode")}
shortcuts={[getShortcutKey("Alt+Z")]}
/>
<Shortcut
label={t("labels.gridMode")}
shortcuts={[getShortcutKey("CtrlOrCmd+'")]}
/>
</ShortcutIsland>
</Column>
<Column>
<ShortcutIsland caption={t("shortcutsDialog.editor")}>
<Shortcut
label={t("labels.selectAll")}
shortcuts={[getShortcutKey("CtrlOrCmd+A")]}
/>
<Shortcut
label={t("labels.multiSelect")}
shortcuts={[
getShortcutKey(`Shift+${t("shortcutsDialog.click")}`),
]}
/>
<Shortcut
label={t("labels.moveCanvas")}
shortcuts={[
getShortcutKey(`Space+${t("shortcutsDialog.drag")}`),
getShortcutKey(`Wheel+${t("shortcutsDialog.drag")}`),
]}
isOr={true}
/>
<Shortcut
label={t("labels.cut")}
shortcuts={[getShortcutKey("CtrlOrCmd+X")]}
/>
<Shortcut
label={t("labels.copy")}
shortcuts={[getShortcutKey("CtrlOrCmd+C")]}
/>
<Shortcut
label={t("labels.paste")}
shortcuts={[getShortcutKey("CtrlOrCmd+V")]}
/>
<Shortcut
label={t("labels.copyAsPng")}
shortcuts={[getShortcutKey("Shift+Alt+C")]}
/>
<Shortcut
label={t("labels.copyStyles")}
shortcuts={[getShortcutKey("CtrlOrCmd+Alt+C")]}
/>
<Shortcut
label={t("labels.pasteStyles")}
shortcuts={[getShortcutKey("CtrlOrCmd+Alt+V")]}
/>
<Shortcut
label={t("labels.delete")}
shortcuts={[getShortcutKey("Del")]}
/>
<Shortcut
label={t("labels.sendToBack")}
shortcuts={[
isDarwin
? getShortcutKey("CtrlOrCmd+Alt+[")
: getShortcutKey("CtrlOrCmd+Shift+["),
]}
/>
<Shortcut
label={t("labels.bringToFront")}
shortcuts={[
isDarwin
? getShortcutKey("CtrlOrCmd+Alt+]")
: getShortcutKey("CtrlOrCmd+Shift+]"),
]}
/>
<Shortcut
label={t("labels.sendBackward")}
shortcuts={[getShortcutKey("CtrlOrCmd+[")]}
/>
<Shortcut
label={t("labels.bringForward")}
shortcuts={[getShortcutKey("CtrlOrCmd+]")]}
/>
<Shortcut
label={t("labels.alignTop")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Up")]}
/>
<Shortcut
label={t("labels.alignBottom")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Down")]}
/>
<Shortcut
label={t("labels.alignLeft")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Left")]}
/>
<Shortcut
label={t("labels.alignRight")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Right")]}
/>
<Shortcut
label={t("labels.duplicateSelection")}
shortcuts={[
getShortcutKey("CtrlOrCmd+D"),
getShortcutKey(`Alt+${t("shortcutsDialog.drag")}`),
]}
/>
<Shortcut
label={t("buttons.undo")}
shortcuts={[getShortcutKey("CtrlOrCmd+Z")]}
/>
<Shortcut
label={t("buttons.redo")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+Z")]}
/>
<Shortcut
label={t("labels.group")}
shortcuts={[getShortcutKey("CtrlOrCmd+G")]}
/>
<Shortcut
label={t("labels.ungroup")}
shortcuts={[getShortcutKey("CtrlOrCmd+Shift+G")]}
/>
</ShortcutIsland>
</Column>
</Columns>
<Footer />
</Dialog>
</>
);
};
+32
View File
@@ -0,0 +1,32 @@
@import "../css/_variables";
.excalidraw {
.Toast {
animation: fade-in 0.5s;
background-color: var(--button-gray-1);
border-radius: 4px;
bottom: 10px;
box-sizing: border-box;
cursor: default;
left: 50%;
margin-left: -150px;
padding: 4px 0;
position: fixed;
text-align: center;
width: 300px;
z-index: 999999;
}
.Toast__message {
color: var(--popup-text-color);
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
+34
View File
@@ -0,0 +1,34 @@
import React, { useCallback, useEffect, useRef } from "react";
import { TOAST_TIMEOUT } from "../constants";
import "./Toast.scss";
export const Toast = ({
message,
clearToast,
}: {
message: string;
clearToast: () => void;
}) => {
const timerRef = useRef<number>(0);
const scheduleTimeout = useCallback(
() =>
(timerRef.current = window.setTimeout(() => clearToast(), TOAST_TIMEOUT)),
[clearToast],
);
useEffect(() => {
scheduleTimeout();
return () => clearTimeout(timerRef.current);
}, [scheduleTimeout, message]);
return (
<div
className="Toast"
onMouseEnter={() => clearTimeout(timerRef?.current)}
onMouseLeave={scheduleTimeout}
>
<p className="Toast__message">{message}</p>
</div>
);
};
+3
View File
@@ -70,6 +70,7 @@ export const DEFAULT_FONT_SIZE = 20;
export const DEFAULT_FONT_FAMILY: FontFamily = 1;
export const DEFAULT_TEXT_ALIGN = "left";
export const DEFAULT_VERTICAL_ALIGN = "top";
export const DEFAULT_VERSION = "{version}";
export const CANVAS_ONLY_ACTIONS = ["selectAll"];
@@ -88,3 +89,5 @@ export const STORAGE_KEYS = {
export const TAP_TWICE_TIMEOUT = 300;
export const TOUCH_CTX_MENU_TIMEOUT = 500;
export const TITLE_TIMEOUT = 10000;
export const TOAST_TIMEOUT = 5000;
export const VERSION_TIMEOUT = 15000;
+2 -1
View File
@@ -13,7 +13,7 @@
a {
font-weight: 500;
text-decoration: none;
color: $oc-blue-7; /* OC Blue 7 */
color: var(--link-color);
&:hover {
text-decoration: underline;
@@ -431,6 +431,7 @@
cursor: pointer;
fill: $oc-gray-6;
bottom: 14px;
width: 1.5rem;
:root[dir="ltr"] & {
right: 14px;
+1
View File
@@ -32,6 +32,7 @@
--popup-text-color: #{$oc-black};
--popup-text-inverted-color: #{$oc-white};
--dialog-border: #{$oc-gray-6};
--link-color: #{$oc-blue-7};
}
.excalidraw {
-2
View File
@@ -1,4 +1,3 @@
import { EVENT_IO, trackEvent } from "../analytics";
import { cleanAppStateForExport } from "../appState";
import { MIME_TYPES } from "../constants";
import { clearElementsForExport } from "../element";
@@ -111,7 +110,6 @@ export const loadFromBlob = async (
localAppState,
);
trackEvent(EVENT_IO, "load", getMimeType(blob));
return result;
} catch (error) {
console.error(error.message);
+2 -7
View File
@@ -1,5 +1,4 @@
import { fileSave } from "browser-nativefs";
import { EVENT_IO, trackEvent } from "../analytics";
import {
copyCanvasToClipboardAsPng,
copyTextToSystemClipboard,
@@ -8,8 +7,8 @@ import { NonDeletedExcalidrawElement } from "../element/types";
import { t } from "../i18n";
import { exportToCanvas, exportToSvg } from "../scene/export";
import { ExportType } from "../scene/types";
import { canvasToBlob } from "./blob";
import { AppState } from "../types";
import { canvasToBlob } from "./blob";
import { serializeAsJSON } from "./json";
export { loadFromBlob } from "./blob";
@@ -37,7 +36,7 @@ export const exportCanvas = async (
},
) => {
if (elements.length === 0) {
return window.alert(t("alerts.cannotExportEmptyCanvas"));
throw new Error(t("alerts.cannotExportEmptyCanvas"));
}
if (type === "svg" || type === "clipboard-svg") {
const tempSvg = exportToSvg(elements, {
@@ -60,10 +59,8 @@ export const exportCanvas = async (
fileName: `${name}.svg`,
extensions: [".svg"],
});
trackEvent(EVENT_IO, "export", "svg");
return;
} else if (type === "clipboard-svg") {
trackEvent(EVENT_IO, "export", "clipboard-svg");
copyTextToSystemClipboard(tempSvg.outerHTML);
return;
}
@@ -95,11 +92,9 @@ export const exportCanvas = async (
fileName,
extensions: [".png"],
});
trackEvent(EVENT_IO, "export", "png");
} else if (type === "clipboard") {
try {
await copyCanvasToClipboardAsPng(tempCanvas);
trackEvent(EVENT_IO, "export", "clipboard-png");
} catch (error) {
if (error.name === "CANVAS_POSSIBLY_TOO_BIG") {
throw error;
+5 -9
View File
@@ -1,13 +1,11 @@
import { ExcalidrawElement } from "../element/types";
import { AppState } from "../types";
import { cleanAppStateForExport } from "../appState";
import { fileOpen, fileSave } from "browser-nativefs";
import { loadFromBlob } from "./blob";
import { Library } from "./library";
import { cleanAppStateForExport } from "../appState";
import { MIME_TYPES } from "../constants";
import { clearElementsForExport } from "../element";
import { EVENT_LIBRARY, trackEvent } from "../analytics";
import { ExcalidrawElement } from "../element/types";
import { AppState } from "../types";
import { loadFromBlob } from "./blob";
import { Library } from "./library";
export const serializeAsJSON = (
elements: readonly ExcalidrawElement[],
@@ -84,7 +82,6 @@ export const saveLibraryAsJSON = async () => {
description: "Excalidraw library file",
extensions: [".excalidrawlib"],
});
trackEvent(EVENT_LIBRARY, "save");
};
export const importLibraryFromJSON = async () => {
@@ -93,6 +90,5 @@ export const importLibraryFromJSON = async () => {
extensions: [".json", ".excalidrawlib"],
mimeTypes: ["application/json"],
});
trackEvent(EVENT_LIBRARY, "load");
Library.importLibrary(blob);
};
-1
View File
@@ -34,7 +34,6 @@ export {
export {
resizeTest,
getCursorForResizingElement,
normalizeTransformHandleType,
getElementWithTransformHandleType,
getTransformHandleTypeFromCoords,
} from "./resizeTest";
+111 -206
View File
@@ -4,7 +4,6 @@ import { rescalePoints } from "../points";
import {
rotate,
adjustXYWithRotation,
getFlipAdjustment,
centerPoint,
rotatePoint,
} from "../math";
@@ -13,21 +12,16 @@ import {
ExcalidrawTextElement,
NonDeletedExcalidrawElement,
NonDeleted,
ExcalidrawGenericElement,
ExcalidrawElement,
} from "./types";
import {
getElementAbsoluteCoords,
getCommonBounds,
getResizedElementAbsoluteCoords,
} from "./bounds";
import { isGenericElement, isLinearElement, isTextElement } from "./typeChecks";
import { isLinearElement, isTextElement } from "./typeChecks";
import { mutateElement } from "./mutateElement";
import { getPerfectElementSize } from "./sizeHelpers";
import {
getCursorForResizingElement,
normalizeTransformHandleType,
} from "./resizeTest";
import { getCursorForResizingElement } from "./resizeTest";
import { measureText, getFontString } from "../utils";
import { updateBoundElements } from "./binding";
import {
@@ -49,7 +43,6 @@ const normalizeAngle = (angle: number): number => {
export const transformElements = (
pointerDownState: PointerDownState,
transformHandleType: MaybeTransformHandleType,
setTransformHandle: (nextTransformHandle: MaybeTransformHandleType) => void,
selectedElements: readonly NonDeletedExcalidrawElement[],
resizeArrowDirection: "origin" | "end",
isRotateWithDiscreteAngle: boolean,
@@ -101,36 +94,15 @@ export const transformElements = (
);
updateBoundElements(element);
} else if (transformHandleType) {
if (isGenericElement(element)) {
resizeSingleGenericElement(
pointerDownState.originalElements.get(element.id) as typeof element,
shouldKeepSidesRatio,
element,
transformHandleType,
isResizeCenterPoint,
pointerX,
pointerY,
);
} else {
const keepSquareAspectRatio = shouldKeepSidesRatio;
resizeSingleNonGenericElement(
element,
transformHandleType,
isResizeCenterPoint,
keepSquareAspectRatio,
pointerX,
pointerY,
);
setTransformHandle(
normalizeTransformHandleType(element, transformHandleType),
);
if (element.width < 0) {
mutateElement(element, { width: -element.width });
}
if (element.height < 0) {
mutateElement(element, { height: -element.height });
}
}
resizeSingleElement(
pointerDownState.originalElements.get(element.id) as typeof element,
shouldKeepSidesRatio,
element,
transformHandleType,
isResizeCenterPoint,
pointerX,
pointerY,
);
}
// update cursor
@@ -414,8 +386,8 @@ const resizeSingleTextElement = (
}
};
const resizeSingleGenericElement = (
stateAtResizeStart: NonDeleted<ExcalidrawGenericElement>,
const resizeSingleElement = (
stateAtResizeStart: NonDeletedExcalidrawElement,
shouldKeepSidesRatio: boolean,
element: NonDeletedExcalidrawElement,
transformHandleDirection: TransformHandleDirection,
@@ -423,251 +395,184 @@ const resizeSingleGenericElement = (
pointerX: number,
pointerY: number,
) => {
const [x1, y1, x2, y2] = getElementAbsoluteCoords(stateAtResizeStart);
// Gets bounds corners
const [x1, y1, x2, y2] = getResizedElementAbsoluteCoords(
stateAtResizeStart,
stateAtResizeStart.width,
stateAtResizeStart.height,
);
const startTopLeft: Point = [x1, y1];
const startBottomRight: Point = [x2, y2];
const startCenter: Point = centerPoint(startTopLeft, startBottomRight);
// Calculate new dimensions based on cursor position
let newWidth = stateAtResizeStart.width;
let newHeight = stateAtResizeStart.height;
const rotatedPointer = rotatePoint(
[pointerX, pointerY],
startCenter,
-stateAtResizeStart.angle,
);
//Get bounds corners rendered on screen
const [esx1, esy1, esx2, esy2] = getResizedElementAbsoluteCoords(
element,
element.width,
element.height,
);
const boundsCurrentWidth = esx2 - esx1;
const boundsCurrentHeight = esy2 - esy1;
// It's important we set the initial scale value based on the width and height at resize start,
// otherwise previous dimensions affected by modifiers will be taken into account.
const atStartBoundsWidth = startBottomRight[0] - startTopLeft[0];
const atStartBoundsHeight = startBottomRight[1] - startTopLeft[1];
let scaleX = atStartBoundsWidth / boundsCurrentWidth;
let scaleY = atStartBoundsHeight / boundsCurrentHeight;
if (transformHandleDirection.includes("e")) {
newWidth = rotatedPointer[0] - startTopLeft[0];
scaleX = (rotatedPointer[0] - startTopLeft[0]) / boundsCurrentWidth;
}
if (transformHandleDirection.includes("s")) {
newHeight = rotatedPointer[1] - startTopLeft[1];
scaleY = (rotatedPointer[1] - startTopLeft[1]) / boundsCurrentHeight;
}
if (transformHandleDirection.includes("w")) {
newWidth = startBottomRight[0] - rotatedPointer[0];
scaleX = (startBottomRight[0] - rotatedPointer[0]) / boundsCurrentWidth;
}
if (transformHandleDirection.includes("n")) {
newHeight = startBottomRight[1] - rotatedPointer[1];
scaleY = (startBottomRight[1] - rotatedPointer[1]) / boundsCurrentHeight;
}
// Linear elements dimensions differ from bounds dimensions
const eleInitialWidth = stateAtResizeStart.width;
const eleInitialHeight = stateAtResizeStart.height;
// We have to use dimensions of element on screen, otherwise the scaling of the
// dimensions won't match the cursor for linear elements.
let eleNewWidth = element.width * scaleX;
let eleNewHeight = element.height * scaleY;
// adjust dimensions for resizing from center
if (isResizeFromCenter) {
newWidth = 2 * newWidth - stateAtResizeStart.width;
newHeight = 2 * newHeight - stateAtResizeStart.height;
eleNewWidth = 2 * eleNewWidth - eleInitialWidth;
eleNewHeight = 2 * eleNewHeight - eleInitialHeight;
}
// adjust dimensions to keep sides ratio
if (shouldKeepSidesRatio) {
const widthRatio = Math.abs(newWidth) / stateAtResizeStart.width;
const heightRatio = Math.abs(newHeight) / stateAtResizeStart.height;
const widthRatio = Math.abs(eleNewWidth) / eleInitialWidth;
const heightRatio = Math.abs(eleNewHeight) / eleInitialHeight;
if (transformHandleDirection.length === 1) {
newHeight *= widthRatio;
newWidth *= heightRatio;
eleNewHeight *= widthRatio;
eleNewWidth *= heightRatio;
}
if (transformHandleDirection.length === 2) {
const ratio = Math.max(widthRatio, heightRatio);
newWidth = stateAtResizeStart.width * ratio * Math.sign(newWidth);
newHeight = stateAtResizeStart.height * ratio * Math.sign(newHeight);
eleNewWidth = eleInitialWidth * ratio * Math.sign(eleNewWidth);
eleNewHeight = eleInitialHeight * ratio * Math.sign(eleNewHeight);
}
}
const [
newBoundsX1,
newBoundsY1,
newBoundsX2,
newBoundsY2,
] = getResizedElementAbsoluteCoords(
stateAtResizeStart,
eleNewWidth,
eleNewHeight,
);
const newBoundsWidth = newBoundsX2 - newBoundsX1;
const newBoundsHeight = newBoundsY2 - newBoundsY1;
// Calculate new topLeft based on fixed corner during resize
let newTopLeft = startTopLeft as [number, number];
let newTopLeft = [...startTopLeft] as [number, number];
if (["n", "w", "nw"].includes(transformHandleDirection)) {
newTopLeft = [
startBottomRight[0] - Math.abs(newWidth),
startBottomRight[1] - Math.abs(newHeight),
startBottomRight[0] - Math.abs(newBoundsWidth),
startBottomRight[1] - Math.abs(newBoundsHeight),
];
}
if (transformHandleDirection === "ne") {
const bottomLeft = [
stateAtResizeStart.x,
stateAtResizeStart.y + stateAtResizeStart.height,
];
newTopLeft = [bottomLeft[0], bottomLeft[1] - Math.abs(newHeight)];
const bottomLeft = [startTopLeft[0], startBottomRight[1]];
newTopLeft = [bottomLeft[0], bottomLeft[1] - Math.abs(newBoundsHeight)];
}
if (transformHandleDirection === "sw") {
const topRight = [
stateAtResizeStart.x + stateAtResizeStart.width,
stateAtResizeStart.y,
];
newTopLeft = [topRight[0] - Math.abs(newWidth), topRight[1]];
const topRight = [startBottomRight[0], startTopLeft[1]];
newTopLeft = [topRight[0] - Math.abs(newBoundsWidth), topRight[1]];
}
// Keeps opposite handle fixed during resize
if (shouldKeepSidesRatio) {
if (["s", "n"].includes(transformHandleDirection)) {
newTopLeft[0] = startCenter[0] - newWidth / 2;
newTopLeft[0] = startCenter[0] - newBoundsWidth / 2;
}
if (["e", "w"].includes(transformHandleDirection)) {
newTopLeft[1] = startCenter[1] - newHeight / 2;
newTopLeft[1] = startCenter[1] - newBoundsHeight / 2;
}
}
// Flip horizontally
if (newWidth < 0) {
if (eleNewWidth < 0) {
if (transformHandleDirection.includes("e")) {
newTopLeft[0] -= Math.abs(newWidth);
newTopLeft[0] -= Math.abs(newBoundsWidth);
}
if (transformHandleDirection.includes("w")) {
newTopLeft[0] += Math.abs(newWidth);
newTopLeft[0] += Math.abs(newBoundsWidth);
}
}
// Flip vertically
if (newHeight < 0) {
if (eleNewHeight < 0) {
if (transformHandleDirection.includes("s")) {
newTopLeft[1] -= Math.abs(newHeight);
newTopLeft[1] -= Math.abs(newBoundsHeight);
}
if (transformHandleDirection.includes("n")) {
newTopLeft[1] += Math.abs(newHeight);
newTopLeft[1] += Math.abs(newBoundsHeight);
}
}
if (isResizeFromCenter) {
newTopLeft[0] = startCenter[0] - Math.abs(newWidth) / 2;
newTopLeft[1] = startCenter[1] - Math.abs(newHeight) / 2;
newTopLeft[0] = startCenter[0] - Math.abs(newBoundsWidth) / 2;
newTopLeft[1] = startCenter[1] - Math.abs(newBoundsHeight) / 2;
}
// adjust topLeft to new rotation point
const angle = stateAtResizeStart.angle;
const rotatedTopLeft = rotatePoint(newTopLeft, startCenter, angle);
const newCenter: Point = [
newTopLeft[0] + Math.abs(newWidth) / 2,
newTopLeft[1] + Math.abs(newHeight) / 2,
newTopLeft[0] + Math.abs(newBoundsWidth) / 2,
newTopLeft[1] + Math.abs(newBoundsHeight) / 2,
];
const rotatedNewCenter = rotatePoint(newCenter, startCenter, angle);
newTopLeft = rotatePoint(rotatedTopLeft, rotatedNewCenter, -angle);
// Readjust points for linear elements
const rescaledPoints = rescalePointsInElement(
stateAtResizeStart,
eleNewWidth,
eleNewHeight,
);
// For linear elements (x,y) are the coordinates of the first drawn point not the top-left corner
// So we need to readjust (x,y) to be where the first point should be
const newOrigin = [...newTopLeft];
newOrigin[0] += stateAtResizeStart.x - newBoundsX1;
newOrigin[1] += stateAtResizeStart.y - newBoundsY1;
const resizedElement = {
width: Math.abs(newWidth),
height: Math.abs(newHeight),
x: newTopLeft[0],
y: newTopLeft[1],
width: Math.abs(eleNewWidth),
height: Math.abs(eleNewHeight),
x: newOrigin[0],
y: newOrigin[1],
...rescaledPoints,
};
updateBoundElements(element, {
newSize: { width: resizedElement.width, height: resizedElement.height },
});
mutateElement(element, resizedElement);
};
const resizeSingleNonGenericElement = (
element: NonDeleted<Exclude<ExcalidrawElement, ExcalidrawGenericElement>>,
transformHandleType: "n" | "s" | "w" | "e" | "nw" | "ne" | "sw" | "se",
isResizeFromCenter: boolean,
keepSquareAspectRatio: boolean,
pointerX: number,
pointerY: number,
) => {
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
const cx = (x1 + x2) / 2;
const cy = (y1 + y2) / 2;
// rotation pointer with reverse angle
const [rotatedX, rotatedY] = rotate(
pointerX,
pointerY,
cx,
cy,
-element.angle,
);
let scaleX = 1;
let scaleY = 1;
if (
transformHandleType === "e" ||
transformHandleType === "ne" ||
transformHandleType === "se"
) {
scaleX = (rotatedX - x1) / (x2 - x1);
}
if (
transformHandleType === "s" ||
transformHandleType === "sw" ||
transformHandleType === "se"
) {
scaleY = (rotatedY - y1) / (y2 - y1);
}
if (
transformHandleType === "w" ||
transformHandleType === "nw" ||
transformHandleType === "sw"
) {
scaleX = (x2 - rotatedX) / (x2 - x1);
}
if (
transformHandleType === "n" ||
transformHandleType === "nw" ||
transformHandleType === "ne"
) {
scaleY = (y2 - rotatedY) / (y2 - y1);
}
let nextWidth = element.width * scaleX;
let nextHeight = element.height * scaleY;
if (keepSquareAspectRatio) {
nextWidth = nextHeight = Math.max(nextWidth, nextHeight);
}
const [nextX1, nextY1, nextX2, nextY2] = getResizedElementAbsoluteCoords(
element,
nextWidth,
nextHeight,
);
const deltaX1 = (x1 - nextX1) / 2;
const deltaY1 = (y1 - nextY1) / 2;
const deltaX2 = (x2 - nextX2) / 2;
const deltaY2 = (y2 - nextY2) / 2;
const rescaledPoints = rescalePointsInElement(element, nextWidth, nextHeight);
updateBoundElements(element, {
newSize: { width: nextWidth, height: nextHeight },
});
const [finalX1, finalY1, finalX2, finalY2] = getResizedElementAbsoluteCoords(
{
...element,
...rescaledPoints,
},
Math.abs(nextWidth),
Math.abs(nextHeight),
);
const [flipDiffX, flipDiffY] = getFlipAdjustment(
transformHandleType,
nextWidth,
nextHeight,
nextX1,
nextY1,
nextX2,
nextY2,
finalX1,
finalY1,
finalX2,
finalY2,
isLinearElement(element),
element.angle,
);
const [nextElementX, nextElementY] = adjustXYWithRotation(
getSidesForTransformHandle(transformHandleType, isResizeFromCenter),
element.x - flipDiffX,
element.y - flipDiffY,
element.angle,
deltaX1,
deltaY1,
deltaX2,
deltaY2,
);
if (
nextWidth !== 0 &&
nextHeight !== 0 &&
Number.isFinite(nextElementX) &&
Number.isFinite(nextElementY)
resizedElement.width !== 0 &&
resizedElement.height !== 0 &&
Number.isFinite(resizedElement.x) &&
Number.isFinite(resizedElement.y)
) {
mutateElement(element, {
width: nextWidth,
height: nextHeight,
x: nextElementX,
y: nextElementY,
...rescaledPoints,
updateBoundElements(element, {
newSize: { width: resizedElement.width, height: resizedElement.height },
});
mutateElement(element, resizedElement);
}
};
-54
View File
@@ -173,57 +173,3 @@ export const getCursorForResizingElement = (resizingElement: {
return cursor ? `${cursor}-resize` : "";
};
export const normalizeTransformHandleType = (
element: ExcalidrawElement,
transformHandleType: TransformHandleType,
): TransformHandleType => {
if (element.width >= 0 && element.height >= 0) {
return transformHandleType;
}
if (element.width < 0 && element.height < 0) {
switch (transformHandleType) {
case "nw":
return "se";
case "ne":
return "sw";
case "se":
return "nw";
case "sw":
return "ne";
}
} else if (element.width < 0) {
switch (transformHandleType) {
case "nw":
return "ne";
case "ne":
return "nw";
case "se":
return "sw";
case "sw":
return "se";
case "e":
return "w";
case "w":
return "e";
}
} else {
switch (transformHandleType) {
case "nw":
return "sw";
case "ne":
return "se";
case "se":
return "ne";
case "sw":
return "nw";
case "n":
return "s";
case "s":
return "n";
}
}
return transformHandleType;
};
+21 -27
View File
@@ -1,40 +1,36 @@
import React, { PureComponent } from "react";
import throttle from "lodash.throttle";
import React, { PureComponent } from "react";
import { ExcalidrawImperativeAPI } from "../../components/App";
import { ErrorDialog } from "../../components/ErrorDialog";
import { APP_NAME, ENV, EVENT } from "../../constants";
import {
decryptAESGEM,
SocketUpdateDataSource,
getCollaborationLinkData,
generateCollaborationLink,
SOCKET_SERVER,
} from "../data";
import { isSavedToFirebase, saveToFirebase } from "../data/firebase";
import Portal from "./Portal";
import { AppState, Collaborator, Gesture } from "../../types";
import { ImportedDataState } from "../../data/types";
import { ExcalidrawElement } from "../../element/types";
import {
importUsernameFromLocalStorage,
saveUsernameToLocalStorage,
STORAGE_KEYS,
} from "../data/localStorage";
import { resolvablePromise, withBatchedUpdates } from "../../utils";
import {
getSceneVersion,
getSyncableElements,
} from "../../packages/excalidraw/index";
import RoomDialog from "./RoomDialog";
import { ErrorDialog } from "../../components/ErrorDialog";
import { ImportedDataState } from "../../data/types";
import { ExcalidrawImperativeAPI } from "../../components/App";
import { AppState, Collaborator, Gesture } from "../../types";
import { resolvablePromise, withBatchedUpdates } from "../../utils";
import {
INITIAL_SCENE_UPDATE_TIMEOUT,
SCENE,
SYNC_FULL_SCENE_INTERVAL_MS,
} from "../app_constants";
import { EVENT_SHARE, trackEvent } from "../../analytics";
import {
decryptAESGEM,
generateCollaborationLink,
getCollaborationLinkData,
SocketUpdateDataSource,
SOCKET_SERVER,
} from "../data";
import { isSavedToFirebase, saveToFirebase } from "../data/firebase";
import {
importUsernameFromLocalStorage,
saveUsernameToLocalStorage,
STORAGE_KEYS,
} from "../data/localStorage";
import Portal from "./Portal";
import RoomDialog from "./RoomDialog";
interface CollabState {
isCollaborating: boolean;
@@ -168,7 +164,6 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
elements,
commitToHistory: true,
});
trackEvent(EVENT_SHARE, "session start");
return this.initializeSocketClient();
};
@@ -176,7 +171,6 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
this.saveCollabRoomToFirebase();
window.history.pushState({}, APP_NAME, window.location.origin);
this.destroySocketClient();
trackEvent(EVENT_SHARE, "session end");
};
private destroySocketClient = () => {
+3 -7
View File
@@ -1,12 +1,10 @@
import React, { useRef } from "react";
import { t } from "../../i18n";
import { Dialog } from "../../components/Dialog";
import { copyTextToSystemClipboard } from "../../clipboard";
import { ToolButton } from "../../components/ToolButton";
import { Dialog } from "../../components/Dialog";
import { clipboard, start, stop } from "../../components/icons";
import { ToolButton } from "../../components/ToolButton";
import { t } from "../../i18n";
import "./RoomDialog.scss";
import { EVENT_SHARE, trackEvent } from "../../analytics";
const RoomDialog = ({
handleClose,
@@ -30,7 +28,6 @@ const RoomDialog = ({
const copyRoomLink = async () => {
try {
await copyTextToSystemClipboard(activeRoomLink);
trackEvent(EVENT_SHARE, "copy link");
} catch (error) {
setErrorMessage(error.message);
}
@@ -95,7 +92,6 @@ const RoomDialog = ({
value={username || ""}
className="RoomDialog-username TextInput"
onChange={(event) => onUsernameChange(event.target.value)}
onBlur={() => trackEvent(EVENT_SHARE, "name")}
onKeyPress={(event) => event.key === "Enter" && handleClose()}
/>
</div>
@@ -22,6 +22,9 @@ export const LanguageList = ({
value={currentLangCode}
aria-label={i18n.t("buttons.selectLanguage")}
>
<option key={i18n.defaultLang.code} value={i18n.defaultLang.code}>
{i18n.defaultLang.label}
</option>
{languages.map((lang) => (
<option key={lang.code} value={lang.code}>
{lang.label}
+5 -8
View File
@@ -1,10 +1,9 @@
import { t } from "../../i18n";
import { ExcalidrawElement } from "../../element/types";
import { AppState } from "../../types";
import { ImportedDataState } from "../../data/types";
import { restore } from "../../data/restore";
import { EVENT_ACTION, EVENT_IO, trackEvent } from "../../analytics";
import { serializeAsJSON } from "../../data/json";
import { restore } from "../../data/restore";
import { ImportedDataState } from "../../data/types";
import { ExcalidrawElement } from "../../element/types";
import { t } from "../../i18n";
import { AppState } from "../../types";
const byteToHex = (byte: number): string => `0${byte.toString(16)}`.slice(-2);
@@ -192,7 +191,6 @@ const importFromBackend = async (
data = await response.json();
}
trackEvent(EVENT_ACTION, "import");
return {
elements: data.elements || null,
appState: data.appState || null,
@@ -276,7 +274,6 @@ export const exportToBackend = async (
url.hash = `json=${json.id},${exportedKey.k!}`;
const urlString = url.toString();
window.prompt(`🔒${t("alerts.uploadedSecurly")}`, urlString);
trackEvent(EVENT_IO, "export", "backend");
} else if (json.error_class === "RequestTooLargeError") {
window.alert(t("alerts.couldNotCreateShareableLinkTooBig"));
} else {
+38 -41
View File
@@ -1,45 +1,44 @@
import React, {
useState,
useLayoutEffect,
useEffect,
useRef,
useCallback,
} from "react";
import LanguageDetector from "i18next-browser-languagedetector";
import Excalidraw, {
languages,
defaultLang,
} from "../packages/excalidraw/index";
import {
getTotalStorageSize,
importFromLocalStorage,
saveToLocalStorage,
STORAGE_KEYS,
} from "./data/localStorage";
import { ImportedDataState } from "../data/types";
import CollabWrapper, { CollabAPI } from "./collab/CollabWrapper";
import { TopErrorBoundary } from "../components/TopErrorBoundary";
import { Language, t } from "../i18n";
import { exportToBackend, loadScene } from "./data";
import { getCollaborationLinkData } from "./data";
import { EVENT } from "../constants";
import { loadFromFirebase } from "./data/firebase";
import React, {
useCallback,
useEffect,
useLayoutEffect,
useRef,
useState,
} from "react";
import { trackEvent } from "../analytics";
import { getDefaultAppState } from "../appState";
import { ExcalidrawImperativeAPI } from "../components/App";
import { debounce, ResolvablePromise, resolvablePromise } from "../utils";
import { AppState, ExcalidrawAPIRefValue } from "../types";
import { ErrorDialog } from "../components/ErrorDialog";
import { TopErrorBoundary } from "../components/TopErrorBoundary";
import { APP_NAME, EVENT, TITLE_TIMEOUT, VERSION_TIMEOUT } from "../constants";
import { ImportedDataState } from "../data/types";
import {
ExcalidrawElement,
NonDeletedExcalidrawElement,
} from "../element/types";
import { Language, t } from "../i18n";
import Excalidraw, {
defaultLang,
languages,
} from "../packages/excalidraw/index";
import { AppState, ExcalidrawAPIRefValue } from "../types";
import {
debounce,
getVersion,
ResolvablePromise,
resolvablePromise,
} from "../utils";
import { SAVE_TO_LOCAL_STORAGE_TIMEOUT } from "./app_constants";
import { EVENT_LOAD, EVENT_SHARE, trackEvent } from "../analytics";
import { ErrorDialog } from "../components/ErrorDialog";
import { getDefaultAppState } from "../appState";
import { APP_NAME, TITLE_TIMEOUT } from "../constants";
import CollabWrapper, { CollabAPI } from "./collab/CollabWrapper";
import { LanguageList } from "./components/LanguageList";
import { exportToBackend, getCollaborationLinkData, loadScene } from "./data";
import { loadFromFirebase } from "./data/firebase";
import {
importFromLocalStorage,
saveToLocalStorage,
STORAGE_KEYS,
} from "./data/localStorage";
const languageDetector = new LanguageDetector();
languageDetector.init({
@@ -163,7 +162,6 @@ const initializeScene = async (opts: {
// into the remote scene
opts.resetScene();
const scenePromise = opts.initializeSocketClient();
trackEvent(EVENT_SHARE, "session join");
try {
const [, roomId, roomKey] = getCollaborationLinkData(
@@ -231,12 +229,11 @@ function ExcalidrawWrapper(props: { collab: CollabAPI }) {
const { collab } = props;
useEffect(() => {
const storageSize = getTotalStorageSize();
if (storageSize) {
trackEvent(EVENT_LOAD, "storage", "size", storageSize);
} else {
trackEvent(EVENT_LOAD, "first time");
}
// Delayed so that the app has a time to load the latest SW
setTimeout(() => {
trackEvent("load", "version", getVersion());
}, VERSION_TIMEOUT);
excalidrawRef.current!.readyPromise.then((excalidrawApi) => {
initializeScene({
resetScene: excalidrawApi.resetScene,
+7 -11
View File
@@ -1,5 +1,3 @@
import { EVENT_CHANGE, trackEvent } from "./analytics";
import fallbackLangData from "./locales/en.json";
import percentages from "./locales/percentages.json";
@@ -11,10 +9,12 @@ export interface Language {
rtl?: boolean;
}
export const defaultLang = { code: "en", label: "English" };
const allLanguages: Language[] = [
{ code: "ar-SA", label: "العربية", rtl: true },
{ code: "bg-BG", label: "Български" },
{ code: "ca-ES", label: "Catalan" },
{ code: "ca-ES", label: "Català" },
{ code: "de-DE", label: "Deutsch" },
{ code: "el-GR", label: "Ελληνικά" },
{ code: "es-ES", label: "Español" },
@@ -32,6 +32,7 @@ const allLanguages: Language[] = [
{ code: "nb-NO", label: "Norsk bokmål" },
{ code: "nl-NL", label: "Nederlands" },
{ code: "nn-NO", label: "Norsk nynorsk" },
{ code: "pa-IN", label: "ਪੰਜਾਬੀ" },
{ code: "pl-PL", label: "Polski" },
{ code: "pt-BR", label: "Português Brasileiro" },
{ code: "pt-PT", label: "Português" },
@@ -43,14 +44,10 @@ const allLanguages: Language[] = [
{ code: "uk-UA", label: "Українська" },
{ code: "zh-CN", label: "简体中文" },
{ code: "zh-TW", label: "繁體中文" },
];
].concat([defaultLang]);
export const defaultLang = { code: "en", label: "English" };
export const languages: Language[] = [defaultLang]
.concat(
allLanguages.sort((left, right) => (left.label > right.label ? 1 : -1)),
)
export const languages: Language[] = allLanguages
.sort((left, right) => (left.label > right.label ? 1 : -1))
.filter(
(lang) =>
(percentages as Record<string, number>)[lang.code] >=
@@ -67,7 +64,6 @@ export const setLanguage = async (lang: Language) => {
currentLangData = await import(
/* webpackChunkName: "i18n-[request]" */ `./locales/${currentLang.code}.json`
);
trackEvent(EVENT_CHANGE, "language", currentLang.code);
};
export const setLanguageFirstTime = async (lang: Language) => {
+1
View File
@@ -40,6 +40,7 @@ export const KEYS = {
D: "d",
E: "e",
L: "l",
O: "o",
P: "p",
Q: "q",
R: "r",
+2 -4
View File
@@ -3,12 +3,10 @@
Please do not contribute changes directly to these files, as we manage them with Crowdin. Instead:
- to request a new translation, [open an issue](https://github.com/excalidraw/excalidraw/issues/new/choose).
- to update existing translations, [edit them on Crowdin](https://crowdin.com/translate/excalidraw/10)
and we should have them included in the app soon!
- to update existing translations, [edit them on Crowdin](https://crowdin.com/translate/excalidraw/10) and we should have them included in the app soon!
## Completion of translation
[percentages.json](./percentages.json) holds a percentage of completion for each language. We generate these
automatically [on build time](./../../.github/workflows/locales-coverage.yml) when a new translation PR appears.
[percentages.json](./percentages.json) holds a percentage of completion for each language. We generate these automatically [on build time](./../../.github/workflows/locales-coverage.yml) when a new translation PR appears.
We only make a language available on the app if it exceeds a certain threshold of completion.
+55 -48
View File
@@ -1,17 +1,18 @@
{
"labels": {
"paste": "لصق",
"pasteCharts": "لصق الرسوم البيانية",
"selectAll": "تحديد الكل",
"multiSelect": "إضافة عنصر للتحديد",
"moveCanvas": "نقل لوح رسم",
"cut": "",
"cut": "قص",
"copy": "نسخ",
"copyAsPng": "نسخ إلى الحافظة بصيغة PNG",
"copyAsSvg": "نسخ بصيغة SVG",
"bringForward": "ارقع للأمام",
"copyAsSvg": "نسخ إلى الحافظة بصيغة SVG",
"bringForward": "جلب للأمام",
"sendToBack": "أرسل للخلف",
"bringToFront": "أحضر للأمام",
"sendBackward": نزل للوراء",
"sendBackward": رسل للخلف",
"delete": "حذف",
"copyStyles": "نسخ النمط",
"pasteStyles": "لصق النمط",
@@ -29,15 +30,15 @@
"edges": "الحواف",
"sharp": "حادة",
"round": "دائرية",
"arrowheads": "",
"arrowhead_none": "",
"arrowhead_arrow": "",
"arrowhead_bar": "",
"arrowhead_dot": "",
"arrowheads": "رؤوس الأسهم",
"arrowhead_none": "لا شيء",
"arrowhead_arrow": "سهم",
"arrowhead_bar": "شريط",
"arrowhead_dot": "نقطة",
"fontSize": "حجم الخط",
"fontFamily": "نوع الخط",
"onlySelected": "المحدد فقط",
"withBackground": "",
"withBackground": "مع الخلفية",
"exportEmbedScene": "تضمين المشهد في ملف التصدير",
"exportEmbedScene_details": "سيتم حفظ بيانات المشهد في ملف PNG/SVG المصدّر بحيث يمكن استعادة المشهد منه.\nسيزيد حجم الملف المصدر.",
"addWatermark": "إضافة \"مصنوعة بواسطة Excalidraw\"",
@@ -60,7 +61,7 @@
"architect": "معماري",
"artist": "رسام",
"cartoonist": "كرتوني",
"fileTitle": "",
"fileTitle": "عنوان الملف",
"colorPicker": "اختيار الألوان",
"canvasBackground": "خلفية اللوحة",
"drawingCanvas": "لوحة الرسم",
@@ -69,18 +70,18 @@
"language": "اللغة",
"createRoom": "مشاركة الجلسة مباشرة",
"duplicateSelection": "تكرار",
"untitled": "",
"untitled": "غير معنون",
"name": "الاسم",
"yourName": "اسمك",
"madeWithExcalidraw": "مصنوعة بواسطة Excalidraw",
"group": "تحديد مجموعة",
"ungroup": "إلغاء تحديد مجموعة",
"collaborators": "المتعاونون",
"gridMode": "",
"gridMode": "وضع الشبكة",
"addToLibrary": "أضف إلى المكتبة",
"removeFromLibrary": "حذف من المكتبة",
"libraryLoadingMessage": "جارٍ تحميل المكتبة...",
"libraries": "",
"libraries": "تصفح المكتبات",
"loadingScene": "جاري تحميل المشهد...",
"align": "محاذاة",
"alignTop": "محاذاة إلى اﻷعلى",
@@ -117,10 +118,10 @@
"redo": "إعادة تنفيذ",
"roomDialog": "بدء المشاركة الحية",
"createNewRoom": "إنشاء غرفة جديدة",
"fullScreen": "",
"darkMode": "",
"lightMode": "",
"zenMode": "",
"fullScreen": "شاشة كاملة",
"darkMode": "الوضع المظلم",
"lightMode": "الوضع المضيء",
"zenMode": "وضع التأمل",
"exitZenMode": "إلغاء الوضع الليلى"
},
"alerts": {
@@ -136,7 +137,7 @@
"loadSceneOverridePrompt": "تحميل الرسم الخارجي سيحل محل المحتوى الموجود لديك. هل ترغب في المتابعة؟",
"errorLoadingLibrary": "حصل خطأ أثناء تحميل مكتبة الطرف الثالث.",
"confirmAddLibrary": "هذا سيضيف {{numShapes}} شكل إلى مكتبتك. هل أنت متأكد؟",
"imageDoesNotContainScene": "",
"imageDoesNotContainScene": "استيراد الصور غير مدعوم في الوقت الراهن.\n\nهل تريد استيراد مشهد؟ لا يبدو أن هذه الصورة تحتوي على أي بيانات مشهد. هل قمت بسماح هذا أثناء التصدير؟",
"cannotRestoreFromImage": "تعذر استعادة المشهد من ملف الصورة"
},
"toolBar": {
@@ -161,7 +162,7 @@
"freeDraw": "انقر واسحب، افرج عند الانتهاء",
"text": "نصيحة: يمكنك أيضًا إضافة نص بالنقر المزدوج في أي مكان بأداة الاختيار",
"linearElementMulti": "انقر فوق النقطة الأخيرة أو اضغط على Esc أو Enter للإنهاء",
"lockAngle": "",
"lockAngle": "يمكنك تقييد الزاوية بالضغط على SHIFT",
"resize": "يمكنك تقييد النسب بالضغط على SHIFT أثناء تغيير الحجم،\nاضغط على ALT لتغيير الحجم من المركز",
"rotate": "يمكنك تقييد الزوايا من خلال الضغط على SHIFT أثناء الدوران",
"lineEditor_info": "انقر نقراً مزدوجاً أو اضغط Enter لتعديل النقاط",
@@ -198,38 +199,44 @@
"errorDialog": {
"title": "خطأ"
},
"shortcutsDialog": {
"title": "اختصارات لوحة المفاتيح",
"shapes": "الأشكال",
"or": "أو",
"click": "انقر فوق",
"drag": "اسحب",
"curvedArrow": "سهم منحنى",
"curvedLine": "خط منحنى",
"editor": "المحرر",
"view": "المشهد",
"blog": "اقرأ مدونتنا",
"howto": "اتبع دليلنا",
"github": "عثرت على مشكلة؟ إرسال",
"textNewLine": "إضافة سطر جديد (نص)",
"textFinish": "الانتهاء من تحرير (النص)",
"zoomToFit": "تكبير لتلائم جميع العناصر",
"zoomToSelection": "",
"preventBinding": "منع ربط السهم"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "رسوماتك مشفرة من النهاية إلى النهاية حتى أن خوادم Excalidraw لن تراها أبدا."
},
"stats": {
"angle": "",
"element": "",
"elements": "",
"height": "",
"scene": "",
"selected": "",
"storage": "",
"title": "",
"total": "",
"width": ""
"angle": "الزاوية",
"element": "عنصر",
"elements": "العناصر",
"height": "الارتفاع",
"scene": "المشهد",
"selected": "المحدد",
"storage": "التخزين",
"title": "إحصائيات للمهووسين",
"total": "المجموع",
"width": "العرض"
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+102 -95
View File
@@ -1,10 +1,11 @@
{
"labels": {
"paste": "Постави",
"pasteCharts": "Постави графики",
"selectAll": "Маркирай всичко",
"multiSelect": "",
"moveCanvas": "",
"cut": "",
"multiSelect": "Добави елемент към селекция",
"moveCanvas": "Премести платно",
"cut": "Изрежи",
"copy": "Копирай",
"copyAsPng": "Копиране в клипборда",
"copyAsSvg": "Копиране в клипборда",
@@ -19,28 +20,28 @@
"background": "Фон",
"fill": "Наситеност",
"strokeWidth": "Ширина на щриха",
"strokeStyle": "",
"strokeStyle_solid": "",
"strokeStyle_dashed": "",
"strokeStyle_dotted": "",
"strokeStyle": "Стил на линия",
"strokeStyle_solid": "Плътен",
"strokeStyle_dashed": "Пунктир",
"strokeStyle_dotted": "Пунктирано",
"sloppiness": "Небрежност",
"opacity": "Непрозрачност",
"opacity": "Прозрачност",
"textAlign": "Подравняване на текста",
"edges": "",
"sharp": "",
"round": "",
"arrowheads": "",
"arrowhead_none": "",
"edges": "Крайща",
"sharp": "Остър",
"round": "Закръглено",
"arrowheads": "Стрелки",
"arrowhead_none": "Без",
"arrowhead_arrow": "Стрелка",
"arrowhead_bar": "",
"arrowhead_dot": "",
"arrowhead_bar": "Връх на стрелката",
"arrowhead_dot": "Точка",
"fontSize": "Размер на шрифта",
"fontFamily": "Семейство шрифтове",
"onlySelected": "Само избраното",
"withBackground": "",
"exportEmbedScene": "",
"exportEmbedScene_details": "",
"addWatermark": "",
"withBackground": "С фон",
"exportEmbedScene": "Вгради сцената във файл",
"exportEmbedScene_details": "Данните от сцената ще бъдат екпортирани в PNG/SVG файл, за да може сцената да бъде възстановена от него.\nТова ще увеличи размера на файла.",
"addWatermark": "Добави \"Направено с Excalidraw\"",
"handDrawn": "Нарисувано на ръка",
"normal": "Нормален",
"code": "Код",
@@ -50,7 +51,7 @@
"veryLarge": "Много голям",
"solid": "Солиден",
"hachure": "Хералдика",
"crossHatch": "",
"crossHatch": "Двойно-пресечено",
"thin": "Тънък",
"bold": "Ясно очертан",
"left": "Ляво",
@@ -60,7 +61,7 @@
"architect": "Архитект",
"artist": "Художник",
"cartoonist": "Карикатурист",
"fileTitle": "",
"fileTitle": "Заглавие на файл",
"colorPicker": "Избор на цвят",
"canvasBackground": "Фон на платно",
"drawingCanvas": "Платно за рисуване",
@@ -69,28 +70,28 @@
"language": "Език",
"createRoom": "Споделете сесия за сътрудничество на живо",
"duplicateSelection": "Дублирай",
"untitled": "",
"untitled": "Неозаглавено",
"name": "Име",
"yourName": "",
"madeWithExcalidraw": "",
"group": "",
"ungroup": "",
"collaborators": "",
"gridMode": "",
"addToLibrary": "",
"removeFromLibrary": "",
"libraryLoadingMessage": "",
"libraries": "",
"loadingScene": "",
"align": "",
"alignTop": "",
"alignBottom": "",
"alignLeft": "",
"alignRight": "",
"centerVertically": "",
"centerHorizontally": "",
"distributeHorizontally": "",
"distributeVertically": ""
"yourName": "Вашето име",
"madeWithExcalidraw": "Направено с Excalidraw",
"group": "Групирай селекцията",
"ungroup": "Спри групирането на селекцията",
"collaborators": "Сътрудници",
"gridMode": "Решетъчен режим",
"addToLibrary": "Добавяне към библиотеката",
"removeFromLibrary": "Премахване от библиотеката",
"libraryLoadingMessage": "Зареждане на библиотеката...",
"libraries": "Разглеждане на библиотеките",
"loadingScene": "Зареждане на сцена...",
"align": "Подравняване",
"alignTop": "Подравняване отгоре",
"alignBottom": "Подравняване отдолу",
"alignLeft": "Подравняване отляво",
"alignRight": "Подравняване отдясно",
"centerVertically": "Центрирай вертикално",
"centerHorizontally": "Центрирай хоризонтално",
"distributeHorizontally": "Разпредели хоризонтално",
"distributeVertically": "Разпредели вертикално"
},
"buttons": {
"clearReset": "Нулиране на платно",
@@ -99,7 +100,7 @@
"exportToSvg": "Изнасяне в SVG",
"copyToClipboard": "Копиране в клипборда",
"copyPngToClipboard": "Копирай PNG в клипборда",
"scale": "",
"scale": "Мащаб",
"save": "Запази",
"saveAs": "Запиши като",
"load": "Зареждане",
@@ -117,38 +118,38 @@
"redo": "Повтори",
"roomDialog": "Започнете сътрудничество на живо",
"createNewRoom": "Създай нова стая",
"fullScreen": "",
"darkMode": "",
"lightMode": "",
"zenMode": "",
"exitZenMode": ""
"fullScreen": "На цял екран",
"darkMode": "Тъмен режим",
"lightMode": "Светъл режим",
"zenMode": "Режим Zen",
"exitZenMode": "Спиране на Zen режим"
},
"alerts": {
"clearReset": "Това ще изчисти цялото платно. Сигурни ли сте?",
"couldNotCreateShareableLink": "Връзката не може да бъде създадена.",
"couldNotCreateShareableLinkTooBig": "",
"couldNotCreateShareableLinkTooBig": "Не може да се създаде връзка за споделяне: сцената е твърде голяма",
"couldNotLoadInvalidFile": "Невалиден файл не може да се зареди",
"importBackendFailed": "Импортирането от бекенд не беше успешно.",
"cannotExportEmptyCanvas": "Не може да се експортира празно платно.",
"couldNotCopyToClipboard": "Неуспешно копиране в клипборда. Опитайте да използвате браузъра Chrome.",
"decryptFailed": "Данните не можаха да се дешифрират.",
"uploadedSecurly": "Качването е защитено с криптиране от край до край, което означава, че сървърът Excalidraw и трети страни не могат да четат съдържанието.",
"loadSceneOverridePrompt": "",
"errorLoadingLibrary": "",
"confirmAddLibrary": "",
"imageDoesNotContainScene": "",
"cannotRestoreFromImage": ""
"loadSceneOverridePrompt": "Зареждането на външна рисунка ще презапише настоящото ви съдържание. Желаете ли да продължите?",
"errorLoadingLibrary": "Възникна грешка при зареждането на външна библиотека.",
"confirmAddLibrary": "Ще се добавят {{numShapes}} фигура(и) във вашата библиотека. Сигурни ли сте?",
"imageDoesNotContainScene": "Импортирането на картинки не се поддържва в момента.\n\nИскате да импортнете сцена? Тази картинка не съдържа данни от сцена. Разрешили ли сте последното при експортирането?",
"cannotRestoreFromImage": "Не може да бъде възстановена сцена от този файл"
},
"toolBar": {
"selection": "Селекция",
"draw": "",
"draw": "Рисуване",
"rectangle": "Правоъгълник",
"diamond": "Диамант",
"ellipse": "Елипс",
"arrow": "Стрелка",
"line": "Линия",
"text": "Текст",
"library": "",
"library": "Библиотека",
"lock": "Поддържайте избрания инструмент активен след рисуване"
},
"headings": {
@@ -158,20 +159,20 @@
},
"hints": {
"linearElement": "Кликнете, за да стартирате няколко точки, плъзнете за една линия",
"freeDraw": "",
"text": "",
"freeDraw": "Натиснете и влачете, пуснете като сте готови",
"text": "Подсказка: Можете също да добавите текст като натиснете някъде два път с инструмента за селекция",
"linearElementMulti": "Кликнете върху последната точка или натиснете Escape или Enter, за да завършите",
"lockAngle": "",
"resize": "",
"lockAngle": "Можете да ограничите ъгъла, като задържите SHIFT",
"resize": "Може да ограничите при преоразмеряване като задържите SHIFT,\nзадръжте ALT за преоразмерите през центъра",
"rotate": "Можете да ограничите ъглите, като държите SHIFT, докато се въртите",
"lineEditor_info": "",
"lineEditor_pointSelected": "",
"lineEditor_nothingSelected": ""
"lineEditor_info": "Кликнете два пъти или натиснете Enter за да промените точките",
"lineEditor_pointSelected": "Натиснете Delete за да изтриете точка, CtrlOrCmd+D за дуплициране, или извлачете за да преместите",
"lineEditor_nothingSelected": "Изберете точка за местене или изтриване, или пък задръжте Alt и натиснете за да добавите нови точки"
},
"canvasError": {
"cannotShowPreview": "",
"canvasTooBig": "",
"canvasTooBigTip": ""
"cannotShowPreview": "Невъзможност за показване на preview",
"canvasTooBig": "Платното е твърде голямо.",
"canvasTooBigTip": "Подсказка: пробвайте да приближите далечните елементи по-близко."
},
"errorSplash": {
"headingMain_pre": "Среща грешка. Опитайте ",
@@ -193,43 +194,49 @@
"button_stopSession": "Стоп на сесията",
"desc_inProgressIntro": "Сесията за сътрудничество на живо е в ход.",
"desc_shareLink": "Споделете тази връзка с всеки, с когото искате да си сътрудничите:",
"desc_exitSession": ""
"desc_exitSession": "Спирането на сесията ще ви изключи от стаята, но ще можете да продължите да работите със сцената, локално. Имайте предвид, че това няма да засегне други хора и те все още ще могат да си сътрудничат с тяхната версия."
},
"errorDialog": {
"title": "Грешка"
},
"shortcutsDialog": {
"title": "Клавиши за бърз достъп",
"shapes": "Фигури",
"or": "или",
"click": "клик",
"drag": "плъзнете",
"curvedArrow": "Извита стрелка",
"curvedLine": "Извита линия",
"editor": "Редактор",
"view": "Преглед",
"blog": "Прочетете нашия блог",
"howto": "Следвайте нашите ръководства",
"github": "Намерихте проблем? Изпратете",
"textNewLine": "Добавяне на нов ред (текст)",
"textFinish": "Завършете редактиране (текст)",
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": "",
"preventBinding": ""
"zoomToSelection": ""
},
"encrypted": {
"tooltip": ""
"tooltip": "Вашите рисунки са криптирани от край до край, така че сървърите на Excalidraw няма да могат да ги виждат."
},
"stats": {
"angle": "",
"element": "",
"elements": "",
"height": "",
"scene": "",
"selected": "",
"storage": "",
"title": "",
"total": "",
"width": ""
"angle": "Ъгъл",
"element": "Елемент",
"elements": "Елементи",
"height": "Височина",
"scene": "Сцена",
"selected": "Селектирано",
"storage": "Съхранение на данни",
"title": "Статистика за хакери",
"total": "Общо",
"width": "Широчина"
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+71 -64
View File
@@ -1,10 +1,11 @@
{
"labels": {
"paste": "Enganxar",
"pasteCharts": "Enganxar diagrames",
"selectAll": "Seleccionar tot",
"multiSelect": "Afegir element a la selecció",
"moveCanvas": "Moure el llenç",
"cut": "",
"cut": "Tallar",
"copy": "Copiar",
"copyAsPng": "Copiar al porta-retalls com a PNG",
"copyAsSvg": "Copiar al porta-retalls com a SVG",
@@ -29,17 +30,17 @@
"edges": "Vores",
"sharp": "Agut",
"round": "Arrodonit",
"arrowheads": "",
"arrowhead_none": "",
"arrowhead_arrow": "",
"arrowhead_bar": "",
"arrowhead_dot": "",
"arrowheads": "Puntes de fletxa",
"arrowhead_none": "Cap",
"arrowhead_arrow": "Fletxa",
"arrowhead_bar": "Barra",
"arrowhead_dot": "Punt",
"fontSize": "Mida de lletra",
"fontFamily": "Tipus de lletra",
"onlySelected": "Només seleccionats",
"withBackground": "",
"exportEmbedScene": "",
"exportEmbedScene_details": "",
"withBackground": "Amb fons",
"exportEmbedScene": "Incrustar escena al fitxer exportat",
"exportEmbedScene_details": "Les dades de lescena es desaran al fitxer PNG/SVG de manera que es pugui restaurar lescena.\nAugmentarà la mida del fitxer exportat.",
"addWatermark": "Afegir \"Fet amb Excalidraw\"",
"handDrawn": "Dibuixat a mà",
"normal": "Normal",
@@ -60,37 +61,37 @@
"architect": "Arquitecte",
"artist": "Artista",
"cartoonist": "Dibuixant",
"fileTitle": "",
"fileTitle": "Títol del fitxer",
"colorPicker": "Selector de colors",
"canvasBackground": "Fons de la tela",
"drawingCanvas": "Tela de dibuix",
"canvasBackground": "Fons del llenç",
"drawingCanvas": "Llenç de dibuix",
"layers": "Capes",
"actions": "Accions",
"language": "Llengua",
"createRoom": "Compartir una sessió de col·laboració en directe",
"duplicateSelection": "Duplicar",
"untitled": "",
"untitled": "Sense títol",
"name": "Nom",
"yourName": "El teu nom",
"madeWithExcalidraw": "Fet amb Excalidraw",
"group": "Agrupar la selecció",
"ungroup": "Desagrupar la selecció",
"collaborators": "Col·laboradors",
"gridMode": "",
"gridMode": "Mode quadrícula",
"addToLibrary": "Afegir a la biblioteca",
"removeFromLibrary": "Eliminar de la biblioteca",
"libraryLoadingMessage": "Carregant la biblioteca...",
"libraries": "",
"loadingScene": "Carregant escena ...",
"align": "",
"alignTop": "",
"alignBottom": "",
"alignLeft": "",
"alignRight": "",
"centerVertically": "",
"centerHorizontally": "",
"distributeHorizontally": "",
"distributeVertically": ""
"libraries": "Explorar biblioteques",
"loadingScene": "Carregant escena...",
"align": "Alinear",
"alignTop": "Alinear a dalt",
"alignBottom": "Alinear a baix",
"alignLeft": "Alinear a lesquerra",
"alignRight": "Alinear a la dreta",
"centerVertically": "Centrar verticalment",
"centerHorizontally": "Centrar horitzontalment",
"distributeHorizontally": "Distribuir horitzontalment",
"distributeVertically": "Distribuir verticalment"
},
"buttons": {
"clearReset": "Netejar el llenç",
@@ -117,16 +118,16 @@
"redo": "Refer",
"roomDialog": "Començar col·laboració en directe",
"createNewRoom": "Crear sala nova",
"fullScreen": "",
"darkMode": "",
"lightMode": "",
"zenMode": "",
"fullScreen": "Pantalla completa",
"darkMode": "Mode fosc",
"lightMode": "Mode clar",
"zenMode": "Mode Zen",
"exitZenMode": "Sortir de modo zen"
},
"alerts": {
"clearReset": "Tot el llenç s'esborrarà. Estàs segur?",
"couldNotCreateShareableLink": "No s'ha pogut crear un enllaç per compartir.",
"couldNotCreateShareableLinkTooBig": "",
"couldNotCreateShareableLinkTooBig": "No sha pogut crear un enllaç per compartir: lescena és massa gran",
"couldNotLoadInvalidFile": "No s'ha pogut carregar un fitxer no vàlid",
"importBackendFailed": "Importació fallida.",
"cannotExportEmptyCanvas": "No es pot exportar un llenç buit.",
@@ -136,8 +137,8 @@
"loadSceneOverridePrompt": "Si carregas aquest dibuix extern, substituirá el que tens. Vols continuar?",
"errorLoadingLibrary": "S'ha produït un error en carregar la biblioteca de tercers.",
"confirmAddLibrary": "Això afegirà {{numShapes}} forma(es) a la vostra biblioteca. Estàs segur?",
"imageDoesNotContainScene": "",
"cannotRestoreFromImage": ""
"imageDoesNotContainScene": "En aquest moment no sadmet la importació dimatges.\n\nVolies importar una escena? Sembla que aquesta imatge no conté cap dada descena. Ho has activat durant l'exportació?",
"cannotRestoreFromImage": "Lescena no sha pogut restaurar des daquest fitxer dimatge"
},
"toolBar": {
"selection": "Selecció",
@@ -161,7 +162,7 @@
"freeDraw": "Fer clic i arrosegar, deixar anar al punt final",
"text": "Consell: també pots afegir text fent doble clic a qualsevol lloc amb l'eina de selecció",
"linearElementMulti": "Fer clic a l'ultim punt, o polsar Escape o Enter per acabar",
"lockAngle": "",
"lockAngle": "Per restringir els angles, mantenir premut el majúscul (SHIFT)",
"resize": "Per restringir les proporcions mentres es canvia la mida, mantenir premut el majúscul (SHIFT); per canviar la mida des del centre, mantenir premut ALT",
"rotate": "Per restringir els angles mentre gira, mantenir premut el majúscul (SHIFT)",
"lineEditor_info": "Fes doble clic o premi Enter per editar punts",
@@ -169,9 +170,9 @@
"lineEditor_nothingSelected": "Selecciona un punt per moure o eliminar, o manté premut Alt i fes clic per afegir punts nous"
},
"canvasError": {
"cannotShowPreview": "",
"canvasTooBig": "",
"canvasTooBigTip": ""
"cannotShowPreview": "No es pot mostrar la vista prèvia",
"canvasTooBig": "Pot ser que el llenç sigui massa gran.",
"canvasTooBigTip": "Consell: prova dacostar una mica els elements més allunyats."
},
"errorSplash": {
"headingMain_pre": "S'ha produït un error. Intentar ",
@@ -198,38 +199,44 @@
"errorDialog": {
"title": "Error"
},
"shortcutsDialog": {
"title": "Dreceres de teclat",
"shapes": "Formes",
"or": "o",
"click": "fer clic",
"drag": "arrosegar",
"curvedArrow": "Fletxa curva",
"curvedLine": "Línea curva",
"editor": "Editor",
"view": "Vista",
"blog": "Llegir el nostre blog",
"howto": "Seguir els nostres guies",
"github": "Has trobat un problema? Enviar-ho",
"textNewLine": "Afegir línea nova (text)",
"textFinish": "Acabar d'editar (text)",
"zoomToFit": "Zoom per veure tots els elements",
"zoomToSelection": "",
"preventBinding": "Prevenir vinculació de la fletxa"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "Els vostres dibuixos estan xifrats de punta a punta de manera que els servidors dExcalidraw no els veuran mai."
},
"stats": {
"angle": "",
"element": "",
"elements": "",
"height": "",
"scene": "",
"selected": "",
"storage": "",
"title": "",
"total": "",
"width": ""
"angle": "Angle",
"element": "Element",
"elements": "Elements",
"height": "Altura",
"scene": "Escena",
"selected": "Seleccionat",
"storage": "Emmagatzematge",
"title": "Estadístiques per nerds",
"total": "Total",
"width": "Amplada"
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+18 -11
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Einfügen",
"pasteCharts": "Diagramme einfügen",
"selectAll": "Alle auswählen",
"multiSelect": "Element zur Auswahl hinzufügen",
"moveCanvas": "Leinwand verschieben",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Fehler"
},
"shortcutsDialog": {
"title": "Tastaturkürzel",
"shapes": "Formen",
"or": "oder",
"helpDialog": {
"blog": "Lies unseren Blog",
"click": "klicken",
"drag": "ziehen",
"curvedArrow": "Gebogener Pfeil",
"curvedLine": "Gebogene Linie",
"documentation": "Dokumentation",
"drag": "ziehen",
"editor": "Editor",
"view": "Ansicht",
"blog": "Unseren Blog lesen",
"howto": "Folge unseren Anleitungen",
"github": "Ein Problem gefunden? Informiere uns",
"textNewLine": "Neue Zeile hinzufügen (Text)",
"howto": "Folge unseren Anleitungen",
"or": "oder",
"preventBinding": "Pfeil-Bindung verhindern",
"shapes": "Formen",
"shortcuts": "Tastaturkürzel",
"textFinish": "Bearbeiten beenden (Text)",
"textNewLine": "Neue Zeile hinzufügen (Text)",
"title": "Hilfe",
"view": "Ansicht",
"zoomToFit": "Zoomen um alle Elemente einzupassen",
"zoomToSelection": "Zoomauswahl",
"preventBinding": "Pfeil-Bindung verhindern"
"zoomToSelection": "Auf Auswahl zoomen"
},
"encrypted": {
"tooltip": "Da deine Zeichnungen Ende-zu-Ende verschlüsselt werden, sehen auch unsere Excalidraw-Server sie niemals."
@@ -231,5 +234,9 @@
"title": "Statistiken für Nerds",
"total": "Gesamt",
"width": "Breite"
},
"toast": {
"copyStyles": "Formatierung kopiert.",
"copyToClipboardAsPng": "In die Zwischenablage als PNG kopiert."
}
}
+25 -18
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Επικόλληση",
"pasteCharts": "Επικόλληση γραφημάτων",
"selectAll": "Επιλογή όλων",
"multiSelect": "Προσθέστε το στοιχείο στην επιλογή",
"moveCanvas": "Μετακίνηση καμβά",
@@ -89,8 +90,8 @@
"alignRight": "Στοίχιση δεξιά",
"centerVertically": "Κέντρο κάθετα",
"centerHorizontally": "Κέντρο οριζόντια",
"distributeHorizontally": "",
"distributeVertically": ""
"distributeHorizontally": "Οριζόντια κατανομή",
"distributeVertically": "Κατακόρυφη κατανομή"
},
"buttons": {
"clearReset": "Επαναφορά του καμβά",
@@ -126,7 +127,7 @@
"alerts": {
"clearReset": "Αυτό θα σβήσει ολόκληρο τον καμβά. Είσαι σίγουρος;",
"couldNotCreateShareableLink": "Δεν ήταν δυνατή η δημιουργία συνδέσμου κοινής χρήσης.",
"couldNotCreateShareableLinkTooBig": "",
"couldNotCreateShareableLinkTooBig": "Δεν ήταν δυνατή η δημιουργία κοινόχρηστου συνδέσμου: η σκηνή είναι πολύ μεγάλη",
"couldNotLoadInvalidFile": "Δεν μπόρεσε να ανοίξει εσφαλμένο αρχείο",
"importBackendFailed": "Η εισαγωγή από το backend απέτυχε.",
"cannotExportEmptyCanvas": "Δεν είναι δυνατή η εξαγωγή κενού καμβά.",
@@ -136,7 +137,7 @@
"loadSceneOverridePrompt": "Η φόρτωση εξωτερικού σχεδίου θα αντικαταστήσει το υπάρχον περιεχόμενο. Επιθυμείτε να συνεχίσετε;",
"errorLoadingLibrary": "Υπήρξε ένα σφάλμα κατά τη φόρτωση της βιβλιοθήκης τρίτου μέρους.",
"confirmAddLibrary": "Αυτό θα προσθέσει {{numShapes}} σχήμα(τα) στη βιβιλιοθήκη σας. Είστε σίγουροι;",
"imageDoesNotContainScene": "",
"imageDoesNotContainScene": "Η εισαγωγή εικόνων δεν υποστηρίζεται αυτή τη στιγμή.\n\nΜήπως θέλετε να εισαγάγετε μια σκηνή; Αυτή η εικόνα δεν φαίνεται να περιέχει δεδομένα σκηνής. Έχετε ενεργοποιήσει αυτό κατά την εξαγωγή;",
"cannotRestoreFromImage": "Η σκηνή δεν ήταν δυνατό να αποκατασταθεί από αυτό το αρχείο εικόνας"
},
"toolBar": {
@@ -161,7 +162,7 @@
"freeDraw": "Κάντε κλικ και σύρατε, απελευθερώσατε όταν έχετε τελειώσει",
"text": "Tip: μπορείτε επίσης να προσθέστε κείμενο με διπλό-κλικ οπουδήποτε με το εργαλείο επιλογών",
"linearElementMulti": "Κάνε κλικ στο τελευταίο σημείο ή πάτησε Escape ή Enter για να τελειώσεις",
"lockAngle": "",
"lockAngle": "Μπορείτε να περιορίσετε τη γωνία κρατώντας πατημένο το SHIFT",
"resize": "Μπορείς να περιορίσεις τις αναλογίες κρατώντας το SHIFT ενώ αλλάζεις μέγεθος,\nκράτησε πατημένο το ALT για αλλαγή μεγέθους από το κέντρο",
"rotate": "Μπορείς να περιορίσεις τις γωνίες κρατώντας πατημένο το πλήκτρο SHIFT κατά την περιστροφή",
"lineEditor_info": "Διπλό-κλικ ή πιέστε Enter για να επεξεργαστείτε τα σημεία",
@@ -169,9 +170,9 @@
"lineEditor_nothingSelected": "Επιλέξτε ένα σημείο για μετακίνηση ή αφαίρεση, ή κρατήστε παρατεταμένα το Alt και κάντε κλικ για να προσθέσετε νέα σημεία"
},
"canvasError": {
"cannotShowPreview": "",
"cannotShowPreview": "Αδυναμία εμφάνισης προεπισκόπησης",
"canvasTooBig": "Ο καμβάς μπορεί να είναι μεγάλος.",
"canvasTooBigTip": ""
"canvasTooBigTip": "Συμβουλή: προσπαθήστε να μετακινήσετε τα πιο απομακρυσμένα στοιχεία λίγο πιο κοντά μαζί."
},
"errorSplash": {
"headingMain_pre": "Συνέβη κάποιο σφάλμα. Προσπάθησε ",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Σφάλμα"
},
"shortcutsDialog": {
"title": "Συντομεύσεις πληκτρολογίου",
"shapes": "Σχήματα",
"or": "ή",
"helpDialog": {
"blog": "Διαβάστε το Blog μας",
"click": "κλικ",
"drag": "σύρε",
"curvedArrow": "Κυρτό βέλος",
"curvedLine": "Κυρτή γραμμή",
"documentation": "Εγχειρίδιο",
"drag": "σύρε",
"editor": "Επεξεργαστής",
"view": "Προβολή",
"blog": "Διαβάστε το ιστολόγιο μας",
"howto": "Ακολουθήστε τους οδηγούς μας",
"github": "Βρήκατε πρόβλημα; Υποβάλετε το",
"textNewLine": "Προσθήκη νέας γραμμής (κείμενο)",
"howto": "Ακολουθήστε τους οδηγούς μας",
"or": "ή",
"preventBinding": "Αποτροπή δέσμευσης βέλων",
"shapes": "Σχήματα",
"shortcuts": "Συντομεύσεις πληκτρολογίου",
"textFinish": "Ολοκλήρωση επεξεργασίας (κείμενο)",
"textNewLine": "Προσθήκη νέας γραμμής (κείμενο)",
"title": "Βοήθεια",
"view": "Προβολή",
"zoomToFit": "Zoom ώστε να χωρέσουν όλα τα στοιχεία",
"zoomToSelection": "",
"preventBinding": "Αποτροπή δέσμευσης βέλων"
"zoomToSelection": "Ζουμ στην επιλογή"
},
"encrypted": {
"tooltip": "Τα σχέδιά σου είναι κρυπτογραφημένα από άκρο σε άκρο, έτσι δεν θα έιναι ποτέ ορατά μέσα από τους διακομιστές του Excalidraw."
@@ -231,5 +234,9 @@
"title": "Στατιστικά για σπασίκλες",
"total": "Σύνολο ",
"width": "Πλάτος"
},
"toast": {
"copyStyles": "Αντιγράφηκαν στυλ.",
"copyToClipboardAsPng": "Αντιγράφτηκε στο πρόχειρο ως PNG."
}
}
+17 -11
View File
@@ -199,24 +199,26 @@
"errorDialog": {
"title": "Error"
},
"shortcutsDialog": {
"title": "Keyboard shortcuts",
"shapes": "Shapes",
"or": "or",
"helpDialog": {
"blog": "Read our blog",
"click": "click",
"drag": "drag",
"curvedArrow": "Curved arrow",
"curvedLine": "Curved line",
"documentation": "Documentation",
"drag": "drag",
"editor": "Editor",
"view": "View",
"blog": "Read our blog",
"howto": "Follow our guides",
"github": "Found an issue? Submit",
"textNewLine": "Add new line (text)",
"howto": "Follow our guides",
"or": "or",
"preventBinding": "Prevent arrow binding",
"shapes": "Shapes",
"shortcuts": "Keyboard shortcuts",
"textFinish": "Finish editing (text)",
"textNewLine": "Add new line (text)",
"title": "Help",
"view": "View",
"zoomToFit": "Zoom to fit all elements",
"zoomToSelection": "Zoom to selection",
"preventBinding": "Prevent arrow binding"
"zoomToSelection": "Zoom to selection"
},
"encrypted": {
"tooltip": "Your drawings are end-to-end encrypted so Excalidraw's servers will never see them."
@@ -232,5 +234,9 @@
"title": "Stats for nerds",
"total": "Total",
"width": "Width"
},
"toast": {
"copyStyles": "Copied styles.",
"copyToClipboardAsPng": "Copied to clipboard as PNG."
}
}
+50 -43
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Pegar",
"pasteCharts": "Pegar gráficos",
"selectAll": "Seleccionar todo",
"multiSelect": "Añadir elemento a la selección",
"moveCanvas": "Mover el lienzo",
@@ -21,7 +22,7 @@
"strokeWidth": "Grosor del trazo",
"strokeStyle": "Estilo del trazo",
"strokeStyle_solid": "Sólido",
"strokeStyle_dashed": "Linea discontinua",
"strokeStyle_dashed": "Discontinua",
"strokeStyle_dotted": "Punteado",
"sloppiness": "Estilo de trazo",
"opacity": "Opacidad",
@@ -30,7 +31,7 @@
"sharp": "Afilado",
"round": "Redondo",
"arrowheads": "Puntas de flecha",
"arrowhead_none": "Vacía",
"arrowhead_none": "Ninguna",
"arrowhead_arrow": "Flecha",
"arrowhead_bar": "Barra",
"arrowhead_dot": "Punto",
@@ -39,7 +40,7 @@
"onlySelected": "Sólo seleccionados",
"withBackground": "Con fondo",
"exportEmbedScene": "Insertar escena en el archivo exportado",
"exportEmbedScene_details": "Los datos de escena se guardarán en el archivo PNG/SVG exportado para que la escena pueda ser restaurada de ella.\nIncrementará el tamaño del archivo exportado.",
"exportEmbedScene_details": "Los datos de escena se guardarán en el archivo PNG/SVG exportado, así la escena puede ser restaurada de la misma.\nEsto aumentará el tamaño del archivo exportado.",
"addWatermark": "Agregar \"Hecho con Excalidraw\"",
"handDrawn": "Dibujado a mano",
"normal": "Normal",
@@ -73,18 +74,18 @@
"name": "Nombre",
"yourName": "Tu nombre",
"madeWithExcalidraw": "Hecho con Excalidraw",
"group": "Selección de grupo",
"ungroup": "Desagrupar",
"group": "Agrupar selección",
"ungroup": "Desagrupar selección",
"collaborators": "Colaboradores",
"gridMode": "Modo cuadrícula",
"addToLibrary": "Añadir a la biblioteca",
"removeFromLibrary": "Eliminar de la biblioteca",
"libraryLoadingMessage": "Cargando biblioteca...",
"libraries": "Explorar librerías",
"libraries": "Explorar bibliotecas",
"loadingScene": "Cargando escena...",
"align": "Alinear",
"alignTop": "Alinear arriba",
"alignBottom": "Alinear abajo",
"alignTop": "Alineación superior",
"alignBottom": "Alineación inferior",
"alignLeft": "Alinear a la izquierda",
"alignRight": "Alinear a la derecha",
"centerVertically": "Centrar verticalmente",
@@ -99,7 +100,7 @@
"exportToSvg": "Exportar a SVG",
"copyToClipboard": "Copiar al portapapeles",
"copyPngToClipboard": "Copiar PNG al portapapeles",
"scale": "Escala",
"scale": "Escalar",
"save": "Guardar",
"saveAs": "Guardar como",
"load": "Cargar",
@@ -109,7 +110,7 @@
"scrollBackToContent": "Volver al contenido",
"zoomIn": "Acercarse",
"zoomOut": "Alejarse",
"resetZoom": "Restablecer zoom",
"resetZoom": "Restablecer acercamiento",
"menu": "Menú",
"done": "Hecho",
"edit": "Editar",
@@ -127,16 +128,16 @@
"clearReset": "Esto limpiará todo el lienzo. Estás seguro?",
"couldNotCreateShareableLink": "No se pudo crear un enlace para compartir.",
"couldNotCreateShareableLinkTooBig": "No se pudo crear el enlace para compartir: la escena es demasiado grande",
"couldNotLoadInvalidFile": "No se pudo cargar el archivo inválido",
"couldNotLoadInvalidFile": "No se pudo cargar el archivo no válido",
"importBackendFailed": "La importación falló.",
"cannotExportEmptyCanvas": "No se puede exportar un lienzo vació",
"couldNotCopyToClipboard": "No se ha podido copiar al portapapeles, intente usar Chrome como navegador.",
"decryptFailed": "No se pudieron descifrar los datos.",
"uploadedSecurly": "La carga ha sido asegurada con cifrado de extremo a extremo, lo que significa que el servidor de Excalidraw y terceros no pueden leer el contenido.",
"uploadedSecurly": "La carga ha sido asegurada con cifrado de principio a fin, lo que significa que el servidor de Excalidraw y terceros no pueden leer el contenido.",
"loadSceneOverridePrompt": "Si carga este dibujo externo, reemplazará el que tiene. ¿Desea continuar?",
"errorLoadingLibrary": "Se ha producido un error al cargar la biblioteca de terceros.",
"confirmAddLibrary": "Esto añadirá {{numShapes}} forma(s) a tu biblioteca. ¿Estás seguro?",
"imageDoesNotContainScene": "La importación de imágenes no está soportada en este momento.\n\n¿Querías importar una escena? Esta imagen no parece contener ningún dato de escena. ¿Lo ha activado durante la exportación?",
"imageDoesNotContainScene": "La importación de imágenes no está homologada en este momento.\n\n¿Deseas importar una escena? Esta imagen no parece contener ningún dato de escena. ¿Lo has activado durante la exportación?",
"cannotRestoreFromImage": "No se pudo restaurar la escena desde este archivo de imagen"
},
"toolBar": {
@@ -157,65 +158,67 @@
"shapes": "Formas"
},
"hints": {
"linearElement": "Haga clic para dibujar multiples puntos o arrastre para una sola línea",
"linearElement": "Haz clic para dibujar múltiples puntos, arrastrar para solo una línea",
"freeDraw": "Haz clic y arrastra, suelta al terminar",
"text": "Consejo: también puedes añadir texto haciendo doble clic en cualquier lugar con la herramienta de selección",
"linearElementMulti": "Haga clic en el último punto o pulse Escape o Enter para finalizar",
"lockAngle": "",
"linearElementMulti": "Haz clic en el último punto o presiona Escape o Enter para finalizar",
"lockAngle": "Puedes restringir el ángulo manteniendo presionado el botón SHIFT",
"resize": "Para mantener las proporciones mantén SHIFT presionado mientras modificas el tamaño, \nmantén presionado ALT para modificar el tamaño desde el centro",
"rotate": "Puede restringir los ángulos manteniendo presionado SHIFT mientras gira",
"lineEditor_info": "haga doble clic o pulse Enter para editar puntos",
"rotate": "Puedes restringir los ángulos manteniendo presionado SHIFT mientras giras",
"lineEditor_info": "Doble clic o pulse Enter para editar puntos",
"lineEditor_pointSelected": "Presione Suprimir para eliminar el punto, CtrlOrCmd+D para duplicarlo, o arrástrelo para moverlo",
"lineEditor_nothingSelected": "Seleccione un punto para mover o eliminar, o mantenga pulsado Alt y haga clic para añadir nuevos puntos"
"lineEditor_nothingSelected": "Selecciona un punto sea para mover o eliminar, o mantén pulsado Alt y haz clic para añadir nuevos puntos"
},
"canvasError": {
"cannotShowPreview": "No se puede mostrar la vista previa",
"canvasTooBig": "El lienzo podría ser demasiado grande.",
"canvasTooBigTip": "Sugerencia: intenta acercar un poco los elementos más lejanos."
"canvasTooBigTip": "Sugerencia: intenta acercar un poco más los elementos más lejanos."
},
"errorSplash": {
"headingMain_pre": "Se encontró un error. Intente ",
"headingMain_button": "recargando la página.",
"clearCanvasMessage": "Si la recarga no funciona, intente ",
"clearCanvasMessage_button": "limpiando el lienzo.",
"clearCanvasCaveat": " Esto resultará en la pérdida del trabajo ",
"clearCanvasCaveat": " Esto provocará la pérdida de su trabajo ",
"trackedToSentry_pre": "El error con el identificador ",
"trackedToSentry_post": " fue rastreado en nuestro sistema.",
"openIssueMessage_pre": "Fuimos muy cautelosos para no incluir la información de tu escena en el error. Si tu escena no es privada, por favor considera seguir nuestro ",
"openIssueMessage_button": "seguimiento de errores.",
"openIssueMessage_pre": "Fuimos muy cautelosos de no incluir la información de tu escena en el error. Si tu escena no es privada, por favor considera seguir nuestro ",
"openIssueMessage_button": "rastreador de errores.",
"openIssueMessage_post": " Por favor, incluya la siguiente información copiándola y pegándola en el issue de GitHub.",
"sceneContent": "Contenido de la escena:"
},
"roomDialog": {
"desc_intro": "Puedes invitar a gente a tu escena actual para colaborar contigo.",
"desc_privacy": "No te preocupes, la sesión usa encriptación de extremo a extremo, por lo que todo lo que se dibuje se mantendrá privado. Ni siquiera nuestro servidor podrá ver lo que haces.",
"desc_intro": "Puede invitar a otras personas a tu actual escena para que colaboren contigo.",
"desc_privacy": "No te preocupes, la sesión usa encriptación de punta a punta, por lo que todo lo que se dibuje se mantendrá privadamente. Ni siquiera nuestro servidor podrá ver lo que haces.",
"button_startSession": "Iniciar sesión",
"button_stopSession": "Detener sesión",
"desc_inProgressIntro": "La sesión de colaboración en vivo está ahora en progreso.",
"desc_shareLink": "Comparte este enlace con tus colaboradores:",
"desc_exitSession": "Detener la sesión te desconectará de la sala, pero podrás seguir trabajando con la escena localmente. Ten en cuenta que esto no afectará a otras personas, y que seguirán siendo capaces de colaborar en su versión."
"desc_shareLink": "Comparte este enlace con cualquier persona con quien quieras colaborar:",
"desc_exitSession": "Detener la sesión te desconectará de la sala, pero podrás seguir trabajando con la escena en su computadora, esto es de modo local. Ten en cuenta que esto no afectará a otras personas, y que las mismas seguirán siendo capaces de colaborar en tu escena."
},
"errorDialog": {
"title": "Error"
},
"shortcutsDialog": {
"title": "Atajos del teclado",
"shapes": "Formas",
"or": "o",
"click": "hacer clic",
"drag": "arrastrar",
"curvedArrow": "Flecha curva",
"curvedLine": "Línea curva",
"editor": "Editor",
"view": "Vista",
"helpDialog": {
"blog": "Lee nuestro blog",
"howto": "Sigue nuestras guías",
"click": "click",
"curvedArrow": "Flecha curvada",
"curvedLine": "Línea curva",
"documentation": "Documentación",
"drag": "arrastrar",
"editor": "Editor",
"github": "¿Has encontrado un problema? Envíalo",
"textNewLine": "Añadir nueva línea (texto)",
"howto": "Siga nuestras guías",
"or": "o",
"preventBinding": "Evitar yuxtaposición de flechas",
"shapes": "Formas",
"shortcuts": "Atajos del teclado",
"textFinish": "Finalizar edición (texto)",
"zoomToFit": "Ajustar para mostrar todos los elementos",
"zoomToSelection": "Hacer zoom a la selección",
"preventBinding": "Evitar enlace de flecha"
"textNewLine": "Añadir nueva línea (texto)",
"title": "Ayuda",
"view": "Vista",
"zoomToFit": "Ajustar la vista para mostrar todos los elementos",
"zoomToSelection": "Hacer zoom a la selección"
},
"encrypted": {
"tooltip": "Tus dibujos están cifrados de punto a punto, por lo que los servidores de Excalidraw nunca los verán."
@@ -228,8 +231,12 @@
"scene": "Escena",
"selected": "Seleccionado",
"storage": "Almacenamiento",
"title": "",
"title": "Estadísticas para nerds",
"total": "Total",
"width": "Ancho"
},
"toast": {
"copyStyles": "Estilos copiados.",
"copyToClipboardAsPng": "Copiado al portapapeles como PNG."
}
}
+55 -48
View File
@@ -1,10 +1,11 @@
{
"labels": {
"paste": "جای گذاری",
"pasteCharts": "قراردادن نمودار",
"selectAll": "انتخاب همه",
"multiSelect": "یک ایتم به انتخاب شده ها اضافه کنید.",
"moveCanvas": "بوم را حرکت بدهید",
"cut": "",
"cut": "جابجایی",
"copy": "کپی",
"copyAsPng": "کپی در حافطه موقت به صورت PNG",
"copyAsSvg": "کپی در حافطه موقت به صورت SVG",
@@ -13,8 +14,8 @@
"bringToFront": "جلو آوردن",
"sendBackward": "پس فرستادن",
"delete": "حذف",
"copyStyles": "کپی استایل",
"pasteStyles": "چسباندن استایل",
"copyStyles": "کپی سبک",
"pasteStyles": "جای گذاری سبک",
"stroke": "خط",
"background": "پس زمینه",
"fill": "رنگ آمیزی",
@@ -29,15 +30,15 @@
"edges": "لبه ها",
"sharp": "تیز",
"round": "دور",
"arrowheads": "",
"arrowhead_none": "",
"arrowhead_arrow": "",
"arrowhead_bar": "",
"arrowhead_dot": "",
"arrowheads": "سر پیکان",
"arrowhead_none": "هیچ کدام",
"arrowhead_arrow": "فلش",
"arrowhead_bar": "میله ای",
"arrowhead_dot": "نقطه",
"fontSize": "اندازه قلم",
"fontFamily": "نوع قلم",
"onlySelected": "فقط انتخاب شده ها",
"withBackground": "",
"withBackground": "با پس زمینه",
"exportEmbedScene": "قرار دادن صحنه در فایل خروجی",
"exportEmbedScene_details": "متحوای صحنه به فایل خروجی SVG/PNG اضافه خواهد شد برای بازیابی صحنه به آن اضافه خواهد شد.\nباعث افزایش حجم فایل خروجی میشود.",
"addWatermark": "\"ساخته شده با Excalidraw\" را اضافه کن",
@@ -60,7 +61,7 @@
"architect": "معمار",
"artist": "هنرمند",
"cartoonist": "کارتونیست",
"fileTitle": "",
"fileTitle": "عنوان فایل",
"colorPicker": "انتخابگر رنگ",
"canvasBackground": "بوم",
"drawingCanvas": "بوم نقاشی",
@@ -69,18 +70,18 @@
"language": "زبان",
"createRoom": "اشتراک گذاری جلسه همکاری زنده",
"duplicateSelection": "تکرار",
"untitled": "",
"untitled": "بدون عنوان",
"name": "نام",
"yourName": "نام شما",
"madeWithExcalidraw": "ساخته شده با Excalidraw",
"group": "گروهبندی انتخابها",
"ungroup": "حذف گروهبندی انتخابها",
"collaborators": "همکاران",
"gridMode": "",
"gridMode": "حالت شبکه ای",
"addToLibrary": "افزودن به کتابخانه",
"removeFromLibrary": "حذف از کتابخانه",
"libraryLoadingMessage": "بارگذاری کتابخانه...",
"libraries": "",
"libraries": "مرور کردن کتابخانه ها",
"loadingScene": "باگذاری صحنه...",
"align": "تراز",
"alignTop": "تراز به بالا",
@@ -117,10 +118,10 @@
"redo": "از سر",
"roomDialog": "همکاری آنلاین را شروع کنید",
"createNewRoom": "ایجاد یک اتاق جدید",
"fullScreen": "",
"darkMode": "",
"lightMode": "",
"zenMode": "",
"fullScreen": "تمام‌صفحه",
"darkMode": "حالت تیره",
"lightMode": "حالت روشن",
"zenMode": "حالت ذن",
"exitZenMode": "خروج از حالت تمرکز"
},
"alerts": {
@@ -136,7 +137,7 @@
"loadSceneOverridePrompt": "بارگزاری یک طرح خارجی محتوای فعلی رو از بین میبرد. آیا میخواهید ادامه دهید؟",
"errorLoadingLibrary": "خطایی در بارگذاری کتابخانه ثالث وجود داشت.",
"confirmAddLibrary": "{{numShapes}} از اشکال به کتابخانه شما اضافه خواهد شد. مطمئن هستید؟",
"imageDoesNotContainScene": "",
"imageDoesNotContainScene": "وارد کردن تصویر در این لحظه امکان پذیر نمی باشد.\nآیا مایل به وارد کردن یک صحنه هستید؟ این تصویر به نظر می رسد که فاقد هرگونه اطلاعاتی مربوط به صحنه باشد. آیا این گزینه را در زمان وارد کردن تصویر فعال کرده اید؟",
"cannotRestoreFromImage": "صحنه را نمی توان از این فایل تصویری بازیابی کرد"
},
"toolBar": {
@@ -161,7 +162,7 @@
"freeDraw": "کلیک کنید و بکشید و وقتی کار تمام شد رها کنید",
"text": "نکته: با برنامه انتخاب شده شما میتوانید با دوبار کلیک کردن هرکجا میخواید متن اظاف کنید",
"linearElementMulti": "روی آخرین نقطه کلیک کنید یا کلید ESC را بزنید یا کلید Enter را بزنید برای اتمام کار",
"lockAngle": "",
"lockAngle": "با نگه داشتن SHIFT هنگام چرخش می توانید زاویه ها را محدود کنید",
"resize": "می توانید با نگه داشتن SHIFT در هنگام تغییر اندازه، نسبت ها را محدود کنید،ALT را برای تغییر اندازه از مرکز نگه دارید",
"rotate": "با نگه داشتن SHIFT هنگام چرخش می توانید زاویه ها را محدود کنید",
"lineEditor_info": "دوبار کلیک کنید یا Enter را فشار دهید تا نقاط را ویرایش کنید",
@@ -178,7 +179,7 @@
"headingMain_button": "در حال بازنشانی صفحه.",
"clearCanvasMessage": "اگر بازنشانی صفحه مشکل را حل نکرد این را امتحان کنید ",
"clearCanvasMessage_button": "در حال تمیز کردن بوم",
"clearCanvasCaveat": " این باعث میشود کارهای شما از بین برود ",
"clearCanvasCaveat": " این باعث میشود کارهای شما ذخیره نشود ",
"trackedToSentry_pre": "خطا در شناسه ",
"trackedToSentry_post": " در سیستم ما رهگیری شد.",
"openIssueMessage_pre": "ما خیلی محتاط هستیم که اطلاعات شما را در خطا قرار ندهیم. با این حال اگر اطلاعات شما خصوصی نیست لطفا پیگیری کنید ",
@@ -198,38 +199,44 @@
"errorDialog": {
"title": "خطا"
},
"shortcutsDialog": {
"title": "میانبرهای صفحه کلید",
"shapes": "شکل‌ها",
"or": "یا",
"click": "کلیک",
"drag": "کشیدن",
"curvedArrow": "فلش خمیده",
"curvedLine": "منحنی",
"editor": "ویرایشگر",
"view": "نمایش",
"blog": "بلاگ ما را بخوانید",
"howto": "راهنمای ما را دنبال کنید",
"github": "اشکالی می بینید؟ گزارش دهید",
"textNewLine": "یک خط جدید اضافه کنید (متن)",
"textFinish": "پایان ویرایش (متن)",
"zoomToFit": "بزرگنمایی برای دیدن تمام آیتم ها",
"zoomToSelection": "",
"preventBinding": "مانع شدن از چسبیدن فلش ها"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "شما در یک محیط رمزگزاری شده دو طرفه در حال طراحی هستید پس Excalidraw هرگز طرح های شما را نمیبند."
},
"stats": {
"angle": "",
"element": "",
"elements": "",
"height": "",
"scene": "",
"selected": "",
"storage": "",
"title": "",
"total": "",
"width": ""
"angle": "زاویه",
"element": "اِلمان",
"elements": "اِلمان ها",
"height": "ارتفاع",
"scene": "صحنه",
"selected": "انتخاب شده",
"storage": "حافظه",
"title": "آمار برای نردها",
"total": "مجموع",
"width": "عرض"
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+20 -13
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Liitä",
"pasteCharts": "Liitä kaaviot",
"selectAll": "Valitse kaikki",
"multiSelect": "Lisää kohde valintaan",
"moveCanvas": "Siirrä piirtoaluetta",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Virhe"
},
"shortcutsDialog": {
"title": "Pikanäppäimet",
"shapes": "Muodot",
"or": "tai",
"helpDialog": {
"blog": "Lue blogiamme",
"click": "klikkaa",
"drag": "vedä",
"curvedArrow": "Kaareva nuoli",
"curvedLine": "Kaareva viiva",
"editor": "Editori",
"view": "Näkymä",
"blog": "Lue blogiamme",
"howto": "Seuraa oppaitamme",
"documentation": "Käyttöohjeet",
"drag": "vedä",
"editor": "Muokkausohjelma",
"github": "Löysitkö ongelman? Kerro meille",
"textNewLine": "Lisää uusi rivi (teksti)",
"howto": "Seuraa oppaitamme",
"or": "tai",
"preventBinding": "Estä nuolten kiinnitys",
"shapes": "Muodot",
"shortcuts": "Pikanäppäimet",
"textFinish": "Lopeta muokkaus (teksti)",
"zoomToFit": "Zoomaa kaikki elementit näkyviin",
"zoomToSelection": "Zoomaa valintaan",
"preventBinding": "Estä nuolten sitominen"
"textNewLine": "Lisää uusi rivi (teksti)",
"title": "Ohjeet",
"view": "Näkymä",
"zoomToFit": "Näytä kaikki elementit",
"zoomToSelection": "Näytä valinta"
},
"encrypted": {
"tooltip": "Piirroksesi ovat päästä päähän salattuja, joten Excalidrawin palvelimet eivät koskaan näe niitä."
@@ -231,5 +234,9 @@
"title": "Nörttien tilastot",
"total": "Yhteensä",
"width": "Leveys"
},
"toast": {
"copyStyles": "Tyylit kopioitu.",
"copyToClipboardAsPng": "Kopioitu leikepöydälle PNG-tiedostona."
}
}
+58 -51
View File
@@ -1,9 +1,10 @@
{
"labels": {
"paste": "Coller",
"pasteCharts": "Coller les graphiques",
"selectAll": "Tout sélectionner",
"multiSelect": "Ajouter l'élément à la sélection",
"moveCanvas": "Déplacer le canvas",
"moveCanvas": "Déplacer le canevas",
"cut": "Couper",
"copy": "Copier",
"copyAsPng": "Copier dans le presse-papier en PNG",
@@ -18,7 +19,7 @@
"stroke": "Contour",
"background": "Arrière-plan",
"fill": "Remplissage",
"strokeWidth": "Largeur du contour",
"strokeWidth": "Largeur du trait",
"strokeStyle": "Style du trait",
"strokeStyle_solid": "Plein",
"strokeStyle_dashed": "Tirets",
@@ -27,10 +28,10 @@
"opacity": "Opacité",
"textAlign": "Alignement du texte",
"edges": "Angles",
"sharp": "Aigu",
"round": "Rond",
"arrowheads": "Extrémités de ligne",
"arrowhead_none": "Aucun",
"sharp": "Pointus",
"round": "Arrondis",
"arrowheads": "Extrémités de flèche",
"arrowhead_none": "Aucune",
"arrowhead_arrow": "Flèche",
"arrowhead_bar": "Barre",
"arrowhead_dot": "Point",
@@ -40,8 +41,8 @@
"withBackground": "Avec arrière-plan",
"exportEmbedScene": "Intégrer la scène au fichier exporté",
"exportEmbedScene_details": "Les données de scène seront enregistrées dans le fichier PNG/SVG exporté, afin que la scène puisse être restaurée à partir de celui-ci.\nCela augmentera la taille du fichier exporté.",
"addWatermark": "Ajouter \"Fabriqué avec Excalidraw\"",
"handDrawn": "Manuscrite",
"addWatermark": "Ajouter \"Fait avec Excalidraw\"",
"handDrawn": "À main levée",
"normal": "Normale",
"code": "Code",
"small": "Petit",
@@ -62,8 +63,8 @@
"cartoonist": "Caricaturiste",
"fileTitle": "Titre du fichier",
"colorPicker": "Sélecteur de couleur",
"canvasBackground": "Fond du canevas",
"drawingCanvas": "Canvas de dessin",
"canvasBackground": "Arrière-plan du canevas",
"drawingCanvas": "Zone de dessin",
"layers": "Calques",
"actions": "Actions",
"language": "Langue",
@@ -72,7 +73,7 @@
"untitled": "Sans-titre",
"name": "Nom",
"yourName": "Votre nom",
"madeWithExcalidraw": "Fabriqué avec Excalidraw",
"madeWithExcalidraw": "Fait avec Excalidraw",
"group": "Grouper la sélection",
"ungroup": "Dégrouper la sélection",
"collaborators": "Collaborateurs",
@@ -80,9 +81,9 @@
"addToLibrary": "Ajouter à la bibliothèque",
"removeFromLibrary": "Supprimer de la bibliothèque",
"libraryLoadingMessage": "Chargement de la bibliothèque...",
"libraries": "Explorer les bibliothèques",
"libraries": "Parcourir les bibliothèques",
"loadingScene": "Chargement de la scène...",
"align": "Alignement",
"align": "Aligner",
"alignTop": "Aligner en haut",
"alignBottom": "Aligner en bas",
"alignLeft": "Aligner à gauche",
@@ -93,12 +94,12 @@
"distributeVertically": "Distribuer verticalement"
},
"buttons": {
"clearReset": "Effacer le canvas & réinitialiser la couleur d'arrière-plan",
"clearReset": "Réinitialiser le canevas",
"export": "Exporter",
"exportToPng": "Exporter en PNG",
"exportToSvg": "Exporter en SVG",
"copyToClipboard": "Copier dans le presse-papier",
"copyPngToClipboard": "Copier le PNG dans le presse-papier",
"copyPngToClipboard": "Copier le PNG vers le presse-papier",
"scale": "Échelle",
"save": "Sauvegarder",
"saveAs": "Enregistrer sous",
@@ -115,28 +116,28 @@
"edit": "Modifier",
"undo": "Annuler",
"redo": "Rétablir",
"roomDialog": "Démarrer le collaboration en temps réel",
"createNewRoom": "Créer un nouveau salon",
"roomDialog": "Démarrer la collaboration en direct",
"createNewRoom": "Créer une nouvelle salle",
"fullScreen": "Plein écran",
"darkMode": "Mode sombre",
"lightMode": "Mode Clair",
"zenMode": "Mode Zen",
"lightMode": "Mode clair",
"zenMode": "Mode zen",
"exitZenMode": "Quitter le mode zen"
},
"alerts": {
"clearReset": "L'intégralité du canvas va être effacé. Êtes-vous sur ?",
"clearReset": "L'intégralité du canevas va être effacée. Êtes-vous sûr ?",
"couldNotCreateShareableLink": "Impossible de créer un lien de partage.",
"couldNotCreateShareableLinkTooBig": "Impossible de créer un lien partageable : la scène est trop volumineuse",
"couldNotLoadInvalidFile": "Impossible de charger un fichier invalide",
"importBackendFailed": "L'import depuis le backend a échoué.",
"cannotExportEmptyCanvas": "Impossible d'exporter un canvas vide.",
"importBackendFailed": "L'importation depuis le backend a échoué.",
"cannotExportEmptyCanvas": "Impossible d'exporter un canevas vide.",
"couldNotCopyToClipboard": "Impossible de copier dans le presse-papier. Essayez d'utiliser le navigateur Chrome.",
"decryptFailed": "Les données n'ont pas pu être déchiffrées.",
"uploadedSecurly": "Le téléchargement a été sécurisé avec un chiffrement de bout en bout, ce qui signifie que ni Excalidraw ni personne d'autre ne peut en lire le contenu.",
"loadSceneOverridePrompt": "Le chargement d'un dessin externe remplacera votre contenu actuel. Souhaitez-vous continuer ?",
"errorLoadingLibrary": "Une erreur s'est produite lors du chargement de la bibliothèque tierce.",
"confirmAddLibrary": "Cela va ajouter {{numShapes}} forme(s) à votre bibliothèque. Êtes-vous sûr(e) ?",
"imageDoesNotContainScene": "L'importation des images n'est pas prise en charge pour le moment.\n\nVoulez-vous importer une scène ? Cette image ne semble pas contenir de données de scène. Avez-vous activé cette option lors de l'exportation ?",
"confirmAddLibrary": "Cela va ajouter {{numShapes}} forme(s) à votre bibliothèque. Êtes-vous sûr·e ?",
"imageDoesNotContainScene": "L'importation d'images n'est pas prise en charge pour le moment.\n\nVouliez-vous importer une scène ? Cette image ne semble pas contenir de données de scène. Avez-vous activé cette option lors de l'exportation ?",
"cannotRestoreFromImage": "Impossible de restaurer la scène depuis ce fichier image"
},
"toolBar": {
@@ -159,63 +160,65 @@
"hints": {
"linearElement": "Cliquez pour démarrer plusieurs points, faites glisser pour une seule ligne",
"freeDraw": "Cliquez et faites glissez, relâchez quand vous avez terminé",
"text": "Astuce : vous pouvez également ajouter du texte en double-cliquant n'importe où avec l'outil de sélection",
"text": "Astuce : vous pouvez aussi ajouter du texte en double-cliquant n'importe où avec l'outil de sélection",
"linearElementMulti": "Cliquez sur le dernier point ou appuyez sur Échap ou Entrée pour terminer",
"lockAngle": "Vous pouvez contraindre l'angle en maintenant SHIFT",
"resize": "Vous pouvez conserver les proportions en maintenant la touche SHIFT pendant le redimensionnement,\nen maintenant la touche ALT pour redimensionner par rapport au centre",
"rotate": "Vous pouvez contraindre les angles en maintenant MAJ enfoncé pendant la rotation",
"lockAngle": "Vous pouvez restreindre l'angle en maintenant MAJ",
"resize": "Vous pouvez conserver les proportions en maintenant la touche MAJ pendant le redimensionnement,\nmaintenez la touche ALT pour redimensionner par rapport au centre",
"rotate": "Vous pouvez restreindre les angles en maintenant MAJ pendant la rotation",
"lineEditor_info": "Double-cliquez ou appuyez sur Entrée pour éditer les points",
"lineEditor_pointSelected": "Appuyez sur Supprimer pour supprimer le point, Ctrl ou Cmd+D pour le dupliquer, ou faites-le glisser pour le déplacer",
"lineEditor_nothingSelected": "Sélectionnez un point à déplacer ou à supprimer, ou maintenez Alt enfoncé et cliquez pour ajouter de nouveaux points"
"lineEditor_nothingSelected": "Sélectionnez un point à déplacer ou supprimer, ou maintenez Alt et cliquez pour ajouter de nouveaux points"
},
"canvasError": {
"cannotShowPreview": "Impossible dafficher laperçu",
"canvasTooBig": "Le dessin est peut-être trop grand.",
"canvasTooBigTip": "Conseil : essayez de rapprocher un peu plus les éléments les plus éloignés."
"canvasTooBig": "Le canevas est peut-être trop grand.",
"canvasTooBigTip": "Astuce : essayez de rapprocher un peu les éléments les plus éloignés."
},
"errorSplash": {
"headingMain_pre": "Une erreur est survenue. Essayez ",
"headingMain_button": "rechargement de la page.",
"headingMain_button": "de recharger la page.",
"clearCanvasMessage": "Si le rechargement ne résout pas l'erreur, essayez ",
"clearCanvasMessage_button": "effacement du canvas.",
"clearCanvasMessage_button": "effacement du canevas.",
"clearCanvasCaveat": " Cela entraînera une perte du travail ",
"trackedToSentry_pre": "L'erreur avec l'identifiant ",
"trackedToSentry_post": " a été enregistrée dans notre système.",
"openIssueMessage_pre": "Nous avons été très prudents de ne pas inclure les informations de votre scène dans l'erreur. Si votre scène n'est pas privée, veuillez envisager de poursuivre sur notre ",
"openIssueMessage_pre": "Nous avons fait très attention à ne pas inclure les informations de votre scène dans l'erreur. Si votre scène n'est pas privée, veuillez envisager de poursuivre sur notre ",
"openIssueMessage_button": "outil de suivi des bugs.",
"openIssueMessage_post": " Veuillez inclure les informations ci-dessous en les copiant-collant dans le ticket GitHub.",
"sceneContent": "Contenu de la scène :"
},
"roomDialog": {
"desc_intro": "Vous pouvez inviter des personnes dans votre scène actuelle à collaborer avec vous.",
"desc_privacy": "Ne vous inquiétez pas, la session utilise le chiffrement de bout en bout, donc tout ce que vous dessinez restera privé. Même notre serveur ne sera pas en mesure de voir ce que vous faites.",
"desc_intro": "Vous pouvez inviter des personnes à collaborer avec vous sur votre scène actuelle.",
"desc_privacy": "Pas d'inquiétude, la session utilise le chiffrement de bout en bout, donc tout ce que vous dessinez restera privé. Même notre serveur ne pourra voir ce que vous faites.",
"button_startSession": "Démarrer la session",
"button_stopSession": "Arrêter la session",
"desc_inProgressIntro": "La session de collaboration en direct est maintenant en cours.",
"desc_shareLink": "Partagez ce lien avec ceux avec qui vous souhaitez collaborer :",
"desc_exitSession": "Arrêter la session vous déconnectera du salon, mais vous pourrez continuer à travailler avec la scène, localement. Notez que cela n'affectera pas les autres personnes, et ils seront toujours en mesure de collaborer sur leur version."
"desc_shareLink": "Partagez ce lien avec les personnes avec lesquelles vous souhaitez collaborer :",
"desc_exitSession": "Arrêter la session vous déconnectera de la salle, mais vous pourrez continuer à travailler avec la scène, localement. Notez que cela n'affectera pas les autres personnes, et ils pourront toujours collaborer sur leur version."
},
"errorDialog": {
"title": "Erreur"
},
"shortcutsDialog": {
"title": "Raccourcis clavier",
"shapes": "Formes",
"or": "ou",
"click": "cliquer",
"drag": "glisser",
"helpDialog": {
"blog": "Lire notre blog",
"click": "clic",
"curvedArrow": "Flèche courbée",
"curvedLine": "Ligne courbée",
"documentation": "Documentation",
"drag": "glisser",
"editor": "Éditeur",
"view": "Afficher",
"blog": "Lisez notre blog",
"github": "Problème trouvé ? Soumettre",
"howto": "Suivez nos guides",
"github": "Vous avez trouvé un problème ? Envoyer",
"textNewLine": "Ajouter une nouvelle ligne (texte)",
"or": "ou",
"preventBinding": "Empêcher la liaison de flèche",
"shapes": "Formes",
"shortcuts": "Raccourcis clavier",
"textFinish": "Terminer l'édition (texte)",
"zoomToFit": "Zoomer pour visualiser tous les éléments",
"zoomToSelection": "Zoom sur la sélection",
"preventBinding": "Empêcher la liaison de la flèche"
"textNewLine": "Ajouter une nouvelle ligne (texte)",
"title": "Aide",
"view": "Affichage",
"zoomToFit": "Zoomer pour voir tous les éléments",
"zoomToSelection": "Zoomer sur la sélection"
},
"encrypted": {
"tooltip": "Vos dessins sont chiffrés de bout en bout, les serveurs d'Excalidraw ne les verront jamais."
@@ -231,5 +234,9 @@
"title": "Stats pour les nerds",
"total": "Total",
"width": "Largeur"
},
"toast": {
"copyStyles": "Styles copiés.",
"copyToClipboardAsPng": "Copié vers le presse-papier en PNG."
}
}
+32 -25
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "הדבק",
"pasteCharts": "הדבק גרפים",
"selectAll": "בחר הכל",
"multiSelect": "הוסף אובייקט לבחירה",
"moveCanvas": "הזז את הקנבס",
@@ -76,7 +77,7 @@
"group": "אחד לקבוצה",
"ungroup": "פרק קבוצה",
"collaborators": "שותפים",
"gridMode": "",
"gridMode": "מצב רשת",
"addToLibrary": "הוסף לספריה",
"removeFromLibrary": "הסר מספריה",
"libraryLoadingMessage": "טוען ספריה...",
@@ -117,10 +118,10 @@
"redo": "בצע מחדש",
"roomDialog": "התחל שיתוף חי",
"createNewRoom": "צור חדר",
"fullScreen": "",
"darkMode": "",
"lightMode": "",
"zenMode": "",
"fullScreen": "מסך מלא",
"darkMode": "מצב כהה",
"lightMode": "מצב בהיר",
"zenMode": "מצב זן",
"exitZenMode": "צא ממצב תפריט מרחף"
},
"alerts": {
@@ -136,7 +137,7 @@
"loadSceneOverridePrompt": "טעינה של ציור חיצוני תחליף את התוכן הקיים שלך. האם תרצה להמשיך?",
"errorLoadingLibrary": "קרתה שגיאה בטעינת הספריה החיצונית.",
"confirmAddLibrary": "הפעולה תוסיף {{numShapes}} צורה(ות) לספריה שלך. האם אתה בטוח?",
"imageDoesNotContainScene": "",
"imageDoesNotContainScene": "אין תמיכה בייבוא תמונות כעת.\n\nהאם אתה רוצה לייבא תצוגה? התמונה הזאת אינה מכילה מידע על תצוגה. האם הפעלת את האפשרות הזאת בזמן הוצאת המידע?",
"cannotRestoreFromImage": "לא הצלחנו לשחזר את התצוגה מקובץ התמונה"
},
"toolBar": {
@@ -161,7 +162,7 @@
"freeDraw": "לחץ וגרור, שחרר כשסיימת",
"text": "טיפ: אפשר להוסיף טקסט על ידי לחיצה כפולה בכל מקום עם כלי הבחירה",
"linearElementMulti": "הקלק על הנקודה האחרונה או הקש Escape או Enter לסיום",
"lockAngle": "",
"lockAngle": "אתה יכול להגביל זווית ע״י לחיצה על SHIFT",
"resize": "ניתן להגביל פרופורציות על ידי לחיצה על SHIFT תוך כדי שינוי גודל,\nהחזק ALT בשביל לשנות גודל ביחס למרכז",
"rotate": "ניתן להגביל זוויות על ידי לחיצה על SHIFT תוך כדי סיבוב",
"lineEditor_info": "לחץ לחיצה כפולה או אנטר לעריכת הנקודות",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "שגיאה"
},
"shortcutsDialog": {
"title": "קיצורי מקלדת",
"shapes": "צורות",
"or": "או",
"click": "לחץ",
"drag": "גרור",
"curvedArrow": "חץ מעוקל",
"curvedLine": "קו מעוקל",
"editor": "עורך",
"view": "תצוגה",
"blog": "קרא את הבלוג שלנו",
"howto": "עקוב אחר המדריכים שלנו",
"github": "מצאת בעיה? דווח",
"textNewLine": "הוסף שורה חדשה (טקסט)",
"textFinish": "סיים עריכה (טקסט)",
"zoomToFit": "זום להתאמת כל האלמנטים למסך",
"zoomToSelection": "התמקד בבחירה",
"preventBinding": "מנע השתלבות חצים"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "הרישומים שלך מוצפנים מקצה לקצה כך שהשרתים של Excalidraw לא יראו אותם לעולם."
@@ -231,5 +234,9 @@
"title": "סטטיסטיקות לחנונים",
"total": "סה״כ",
"width": "רוחב"
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+58 -51
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "चिपकाएँ",
"pasteCharts": "चार्ट चिपकाएँ",
"selectAll": "सभी चुनें",
"multiSelect": "आकार को चयन में जोड़ें",
"moveCanvas": "कैनवास को स्थानांतरित करें",
@@ -38,8 +39,8 @@
"fontFamily": "फ़ॉन्ट का परिवार",
"onlySelected": "केवल चयनित",
"withBackground": "बैकग्राउंड के साथ",
"exportEmbedScene": "",
"exportEmbedScene_details": "",
"exportEmbedScene": "निर्यात एम्बेड दृश्य",
"exportEmbedScene_details": "निर्यात एम्बेड दृश्य विवरण",
"addWatermark": "ऐड \"मेड विथ एक्सकैलिडराव\"",
"handDrawn": "हाथ से बनाया हुआ",
"normal": "साधारण",
@@ -60,7 +61,7 @@
"architect": "वास्तुकार",
"artist": "कलाकार",
"cartoonist": "व्यंग्य चित्रकार",
"fileTitle": "",
"fileTitle": "फ़ाइल का शीर्षक",
"colorPicker": "रंग चयन",
"canvasBackground": "कैनवास बैकग्राउंड",
"drawingCanvas": "कैनवास बना रहे हैं",
@@ -76,21 +77,21 @@
"group": "समूह चयन",
"ungroup": "समूह चयन असमूहीकृत करें",
"collaborators": "सहयोगी",
"gridMode": "",
"gridMode": "ग्रिड मॉड",
"addToLibrary": "लाइब्रेरी से जोड़ें",
"removeFromLibrary": "लाइब्रेरी से निकालें",
"libraryLoadingMessage": "लाइब्रेरी खुल रही है",
"libraries": "",
"libraries": "लाइब्रेरी ब्राउज़ करें",
"loadingScene": "दृश्य खुल रहा है",
"align": "",
"alignTop": "",
"alignBottom": "",
"alignLeft": "",
"alignRight": "",
"centerVertically": "",
"centerHorizontally": "",
"distributeHorizontally": "",
"distributeVertically": ""
"align": "संरेखित करें",
"alignTop": "ऊपर संरेखित करें",
"alignBottom": "नीचे संरेखित करें",
"alignLeft": "बायें संरेखित करें",
"alignRight": "दायें संरेखित करें",
"centerVertically": "लंबवत केन्द्रित",
"centerHorizontally": "क्षैतिज केन्द्रित",
"distributeHorizontally": "क्षैतिज रूप से वितरित करें",
"distributeVertically": "खड़ी रूप से वितरित करें"
},
"buttons": {
"clearReset": "कैनवास रीसेट करें",
@@ -99,7 +100,7 @@
"exportToSvg": "Svg के रूप में निर्यात करे",
"copyToClipboard": "क्लिपबोर्ड पर प्रतिलिपि बनाएँ",
"copyPngToClipboard": "क्लिपबोर्ड पर कॉपी करें,पीएनजी के रूप में",
"scale": "",
"scale": "पैमाना",
"save": "सहेजें",
"saveAs": "सेव करे इस तरह",
"load": "लोड करें",
@@ -117,16 +118,16 @@
"redo": "फिर से करें",
"roomDialog": "लाइव सहयोग शुरू करें",
"createNewRoom": "एक नया कमरा बनाएं",
"fullScreen": "",
"darkMode": "",
"lightMode": "",
"zenMode": "",
"fullScreen": "पूरी स्क्रीन",
"darkMode": "डार्क मोड",
"lightMode": "लाइट मोड",
"zenMode": "ज़ेन मोड",
"exitZenMode": "जेन मोड से बाहर निकलें"
},
"alerts": {
"clearReset": "इससे पूरा कैनवास साफ हो जाएगा। क्या आपको यकीन है?",
"couldNotCreateShareableLink": "साझा करने योग्य लिंक नहीं बनाया जा सका।",
"couldNotCreateShareableLinkTooBig": "",
"couldNotCreateShareableLinkTooBig": "लिंक शेयर नहीं कर सकता: दृश्य बहुत बड़ा",
"couldNotLoadInvalidFile": "अमान्य फ़ाइल लोड नहीं की जा सकी",
"importBackendFailed": "बैकएंड से आयात करना विफल रहा।",
"cannotExportEmptyCanvas": "खाली कैनवास निर्यात नहीं कर सकता।",
@@ -134,10 +135,10 @@
"decryptFailed": "डेटा को डिक्रिप्ट नहीं किया जा सका।",
"uploadedSecurly": "अपलोड को एंड-टू-एंड एन्क्रिप्शन के साथ सुरक्षित किया गया है, जिसका मतलब है कि एक्सक्लूसिव सर्वर और थर्ड पार्टी कंटेंट नहीं पढ़ सकते हैं।",
"loadSceneOverridePrompt": "लोड हो रहा है बाहरी ड्राइंग आपके मौजूदा सामग्री को बदल देगा। क्या आप जारी रखना चाहते हैं?",
"errorLoadingLibrary": "",
"confirmAddLibrary": "",
"imageDoesNotContainScene": "",
"cannotRestoreFromImage": ""
"errorLoadingLibrary": "लाइब्रेरी लोड करने में त्रुटि",
"confirmAddLibrary": "लाइब्रेरी जोड़ें पुष्‍टि करें आकार संख्या",
"imageDoesNotContainScene": "दृश्य में छवि नहीं है",
"cannotRestoreFromImage": "छवि फ़ाइल बहाल दृश्य नहीं है"
},
"toolBar": {
"selection": "चयन",
@@ -148,7 +149,7 @@
"arrow": "तीर",
"line": "रेखा",
"text": "पाठ",
"library": "",
"library": "लाइब्रेरी",
"lock": "ड्राइंग के बाद चयनित टूल को सक्रिय रखें"
},
"headings": {
@@ -159,9 +160,9 @@
"hints": {
"linearElement": "कई बिंदुओं को शुरू करने के लिए क्लिक करें, सिंगल लाइन के लिए खींचें",
"freeDraw": "क्लिक करें और खींचें। समाप्त करने के लिए, छोड़ो",
"text": "",
"text": "आप चयन टूल से कहीं भी डबल-क्लिक करके टेक्स्ट जोड़ सकते हैं",
"linearElementMulti": "अंतिम बिंदु पर क्लिक करें या समाप्त होने के लिए एस्केप या एंटर दबाएं",
"lockAngle": "",
"lockAngle": "आप घूर्णन करते समय SHIFT पकड़कर कोणों को मोड़ सकते हैं",
"resize": "आकार बदलते समय आप SHIFT को पकड़ कर अनुपात में कमी कर सकते हैं,\nकेंद्र से आकार बदलने के लिए ALT दबाए रखें",
"rotate": "आप घूर्णन करते समय SHIFT पकड़कर कोणों को विवश कर सकते हैं",
"lineEditor_info": "बिंदुओं को संपादित करने के लिए Enter पर डबल-क्लिक करें या दबाएँ",
@@ -169,9 +170,9 @@
"lineEditor_nothingSelected": "स्थानांतरित करने या हटाने के लिए एक बिंदु का चयन करें, या Alt दबाए रखें और नए बिंदुओं को जोड़ने के लिए क्लिक करें"
},
"canvasError": {
"cannotShowPreview": "",
"canvasTooBig": "",
"canvasTooBigTip": ""
"cannotShowPreview": "पूर्वावलोकन नहीं दिखा सकते हैं",
"canvasTooBig": "कैनवास बहुत बड़ा",
"canvasTooBigTip": "कैनवास बहुत बड़ा टिप"
},
"errorSplash": {
"headingMain_pre": "एक त्रुटि का सामना करना पड़ा। प्रयत्न ",
@@ -198,38 +199,44 @@
"errorDialog": {
"title": "गलती"
},
"shortcutsDialog": {
"title": "कीबोर्ड के शॉर्टकट्स",
"shapes": "आकृतियाँ",
"or": "या",
"click": "क्लिक करें",
"drag": "खींचें",
"curvedArrow": "घुमावदार तीर",
"curvedLine": "घुमावदार रेखा",
"editor": "संपादक",
"view": "दृश्य",
"blog": "हमारा ब्लॉग पढे",
"howto": "हमारे गाइड का पालन करें",
"github": "एक मुद्दा मिला? प्रस्तुत करे",
"textNewLine": "नई पंक्ति (पाठ) जोड़ें",
"textFinish": "संपादन समाप्त करें (पाठ)",
"zoomToFit": "सभी तत्वों को फिट करने के लिए ज़ूम करें",
"zoomToSelection": "",
"preventBinding": ""
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "आपके चित्र अंत-से-अंत एन्क्रिप्टेड हैं, इसलिए एक्सक्लूसिव्रॉव के सर्वर उन्हें कभी नहीं देखेंगे।"
},
"stats": {
"angle": "कोण",
"element": "",
"elements": "",
"element": "एलिमेंट",
"elements": "एलिमेंट",
"height": "ऊंचाई",
"scene": "दृश्य",
"selected": "चयनित",
"storage": "संग्रह",
"title": "",
"title": "बेवकूफ के लिए आँकड़े",
"total": "कुल",
"width": "चौड़ाई"
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+62 -55
View File
@@ -1,8 +1,9 @@
{
"labels": {
"paste": "Beillesztés",
"pasteCharts": "Grafikon beillesztése",
"selectAll": "Összes kijelölése",
"multiSelect": "Elem hozzáadása a kiválasztáshoz",
"multiSelect": "Elem hozzáadása a kijelöléshez",
"moveCanvas": "Vászon mozgatása",
"cut": "Kivágás",
"copy": "Másolás",
@@ -36,14 +37,14 @@
"arrowhead_dot": "Pont",
"fontSize": "Betűméret",
"fontFamily": "Betűkészlet család",
"onlySelected": "Csak a kiválasztott",
"withBackground": "",
"onlySelected": "Csak a kijelölt",
"withBackground": "Háttérrel",
"exportEmbedScene": "Jelenet beágyazása az exportált fájlba",
"exportEmbedScene_details": "",
"exportEmbedScene_details": "A jelenetet leíró adatok hozzá lesznek adva a PNG/SVG fájlhoz, így a jelenetet vissza lehet majd tölteni belőle. Ez megnöveli a fájl méretét.",
"addWatermark": "Add hozzá, hogy \"Excalidraw-val készült\"",
"handDrawn": "Kézzel rajzolt",
"normal": "Normál",
"code": "Code",
"code": "Kód",
"small": "Kicsi",
"medium": "Közepes",
"large": "Nagy",
@@ -76,7 +77,7 @@
"group": "Csoportosítás",
"ungroup": "Csoportbontás",
"collaborators": "Közreműködők",
"gridMode": "",
"gridMode": "Hálómód",
"addToLibrary": "Hozzáadás a könyvtárhoz",
"removeFromLibrary": "Eltávólítás a könyvtárból",
"libraryLoadingMessage": "Könyvtár betöltése...",
@@ -113,15 +114,15 @@
"menu": "Menü",
"done": "Kész",
"edit": "Szerkesztés",
"undo": "Visszavonás",
"redo": "Újra végrehajtás",
"undo": "Vissza",
"redo": "Újra",
"roomDialog": "Élő együttműködés indítása",
"createNewRoom": "Új szoba létrehozása",
"fullScreen": "",
"darkMode": "",
"lightMode": "",
"zenMode": "",
"exitZenMode": "Zen mód elhagyása"
"fullScreen": "Teljes képernyő",
"darkMode": "Sötét mód",
"lightMode": "Világos mód",
"zenMode": "Letisztult mód",
"exitZenMode": "Kilépés a letisztult módból"
},
"alerts": {
"clearReset": "Ez a művelet törli a vászont. Biztos benne?",
@@ -130,17 +131,17 @@
"couldNotLoadInvalidFile": "Nem sikerült betölteni a helytelen fájlt",
"importBackendFailed": "Nem sikerült betölteni a szerverről.",
"cannotExportEmptyCanvas": "Üres vászont nem lehet exportálni.",
"couldNotCopyToClipboard": "Nem sikerült vágólapra menteni. Próbálja meg Chrome böngészővel.",
"couldNotCopyToClipboard": "Nem sikerült vágólapra menteni. Próbáld meg Chrome böngészővel.",
"decryptFailed": "Nem sikerült visszafejteni a titkosított adatot.",
"uploadedSecurly": "A feltöltést végpontok közötti titkosítással biztosítottuk, ami azt jelenti, hogy az Excalidraw szerver és harmadik felek nem tudják elolvasni a feltöltés tartalmát.",
"uploadedSecurly": "A feltöltést végpontok közötti titkosítással biztosítottuk, ami azt jelenti, hogy egy harmadik fél nem tudja megnézni a tartalmát, beleértve az Excalidraw szervereit is.",
"loadSceneOverridePrompt": "A betöltött külső rajz felül fogja írnia meglévőt. Szeretnéd folytatni?",
"errorLoadingLibrary": "Hibába ütközött a harmarmadik féltől származó könyvtár betöltése.",
"confirmAddLibrary": "Ez a művelet {{numShapes}} formát fog hozzáadni a könyvtáradhoz. Biztos vagy benne?",
"imageDoesNotContainScene": "",
"cannotRestoreFromImage": ""
"imageDoesNotContainScene": "Képek importálása egyelőre nem támogatott.\n\nEgy jelenetet szeretnél betölteni? Úgy tűnik ez a kép fájl nem tartalmazza a szükséges adatokat. Exportáláskor ezt egy külön opcióval lehet beállítani.",
"cannotRestoreFromImage": "A jelenet visszaállítása nem sikerült ebből a kép fájlból"
},
"toolBar": {
"selection": "Kiválasztás",
"selection": "Kijelölés",
"draw": "Szabadkézi rajz",
"rectangle": "Téglalap",
"diamond": "Rombusz",
@@ -149,20 +150,20 @@
"line": "Vonal",
"text": "Szöveg",
"library": "Könyvtár",
"lock": "Rajzolás után az aktív eszközt tartsa kiválasztva"
"lock": "Rajzolás után az aktív eszközt tartsa kijelölve"
},
"headings": {
"canvasActions": "Vászon műveletek",
"selectedShapeActions": "Kiválasztott forma műveletei",
"shapes": "Formák"
"selectedShapeActions": "Kijelölt forma műveletei",
"shapes": "Alakzatok"
},
"hints": {
"linearElement": "Kattintson a több pont elindításához, húzza az egyenes vonalhoz",
"linearElement": "Kattintással görbe, az eger húzásával pedig egyenes nyilat rajzolhatsz",
"freeDraw": "Kattints és húzd, majd engedd el, amikor végeztél",
"text": "Tipp: A kiválasztó eszközzel bárhol létrehozhatsz szöveget dupla kattintással",
"linearElementMulti": "Kattintson az utolsó pontra, vagy nyomja meg az Escape vagy az Enter billentyűt a befejezéshez",
"lockAngle": "",
"resize": "",
"text": "Tipp: A kijelölés eszközzel a dupla kattintás új szöveget hoz létre",
"linearElementMulti": "Kattints a következő ív pozíciójára, vagy fejezd be a nyilat az Escape vagy Enter megnyomásával",
"lockAngle": "A SHIFT billentyű lenyomva tartásával korlátozhatja forgatás szögét",
"resize": "A SHIFT billentyű lenyomva tartásával az átméretezés megtartja az arányokat,\naz ALT lenyomva tartásával pedig a középpont egy helyben marad",
"rotate": "A SHIFT billentyű lenyomva tartásával korlátozhatja a szögek illesztését",
"lineEditor_info": "Kattints duplán, vagy nyomj entert a pontok szerkesztéséhez",
"lineEditor_pointSelected": "Nyomd meg a delete gombot a pont eltávolításához, Ctrl vagy Cmd + D-t a duplikáláshoz, vagy húzva mozgasd",
@@ -171,24 +172,24 @@
"canvasError": {
"cannotShowPreview": "Előnézet nem jeleníthető meg",
"canvasTooBig": "A vászon talán túl nagy.",
"canvasTooBigTip": "Tipp: próbáld meg a legtávolabbi elemeket közelebb mozgazni egy máshoz."
"canvasTooBigTip": "Tipp: próbáld meg a legtávolabbi elemeket közelebb hozni egy máshoz."
},
"errorSplash": {
"headingMain_pre": "Hiba történt. Próbálja ",
"headingMain_pre": "Hiba történt. Próbáld ",
"headingMain_button": "újratölteni az oldalt.",
"clearCanvasMessage": "Ha az újratöltés nem működik, próbálja ",
"clearCanvasMessage_button": "törölni a vászont.",
"clearCanvasCaveat": " Ezzel elveszik minden eddigi munkája ",
"clearCanvasMessage": "Ha az újratöltés nem működik, próbáld ",
"clearCanvasMessage_button": "letörölni a vászont.",
"clearCanvasCaveat": " Ezzel az eddigi munka elveszik ",
"trackedToSentry_pre": "A hibakód azonosítóval ",
"trackedToSentry_post": " nyomon van követve a rendszerünkben.",
"openIssueMessage_pre": "Nagyon vigyáztunk, hogy ne adjunk meg a jelenetre vonatkozó információkat a hibában. Ha a jeleneted nem bizalmas, kérjük fontolja meg a jelenet hozzáadását a hibakövető rendszerünkben ",
"openIssueMessage_button": "hibabejelentő.",
"openIssueMessage_pre": "Vigyáztunk arra, hogy a jelenthez tartozó információ ne jelenjen meg a hibaüzenetben. Ha a jeleneted nem bizalmas, kérjük add hozzá a ",
"openIssueMessage_button": "hibakövető rendszerünkhöz.",
"openIssueMessage_post": " Kérjük, másolja be az alábbi információkat a GitHub problémába.",
"sceneContent": "Jelenet tartalma:"
},
"roomDialog": {
"desc_intro": "Meghívhat embereket a jelenlegi jelenetbe, hogy együttműködjenek önnel.",
"desc_privacy": "Ne aggódjon, a munkamenet végpontok közötti titkosítást használ, tehát bármit rajzol, privát marad. Még a szerverünk sem fogja látni, hogy mit rajzolt.",
"desc_privacy": "Ne aggódj, a munkamenet végpontok közötti titkosítást használ, tehát bármit rajzolsz, privát marad. Még a szerverünkről se lehet belenézni.",
"button_startSession": "Munkamenet indítása",
"button_stopSession": "Munkamenet leállítása",
"desc_inProgressIntro": "Az élő együttműködési munkamenet folyamatban van.",
@@ -198,38 +199,44 @@
"errorDialog": {
"title": "Hiba"
},
"shortcutsDialog": {
"title": "Gyorsbillentyűk",
"shapes": "Formák",
"or": "vagy",
"click": "klikk",
"drag": "húzd",
"curvedArrow": "Ívelt nyíl",
"curvedLine": "Ívelt vonal",
"editor": "Szerkesztő",
"view": "Nézet",
"blog": "Olvasd a blogunkat",
"howto": "Kövesd az útmutatóinkat",
"github": "Hibát találtál? Küld be",
"textNewLine": "Új sor hozzáadása (szöveg)",
"textFinish": "Szerkesztés befejezése (szöveg)",
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": "Kijelölésre nagyítás",
"preventBinding": ""
"zoomToSelection": ""
},
"encrypted": {
"tooltip": ""
"tooltip": "A rajzaidat végpontok közötti titkosítással tároljuk, tehát az Excalidraw szervereiről se tud más belenézni."
},
"stats": {
"angle": "Szög",
"element": "Elem",
"elements": "Elemek",
"height": "Magasság",
"scene": "",
"selected": "Kiválasztott",
"scene": "Jelenet",
"selected": "Kijelölt",
"storage": "Tárhely",
"title": "",
"title": "Statisztikák",
"total": "Összesen",
"width": "Szélesség"
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+25 -18
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Tempel",
"pasteCharts": "Tempel diagram",
"selectAll": "Pilih semua",
"multiSelect": "Tambahkan elemen ke pilihan",
"moveCanvas": "Pindahkan kanvas",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Kesalahan"
},
"shortcutsDialog": {
"title": "Pintasan keyboard",
"shapes": "Bentuk",
"or": "atau",
"click": "klik",
"drag": "seret",
"curvedArrow": "Panah lengkung",
"curvedLine": "Garis lengkung",
"editor": "Editor",
"view": "Tampilan",
"blog": "Baca blog kami",
"howto": "Ikuti panduan kami",
"github": "Menemukan sebuah masalah? Kirimkan",
"textNewLine": "Tambahkan baris baru (teks)",
"textFinish": "Selesai mengedit (teks)",
"zoomToFit": "Perbesar agar sesuai dengan semua elemen",
"zoomToSelection": "Perbesar ke seleksi",
"preventBinding": "Cegah pengikatan panah"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "Gambar anda terenkripsi end-to-end sehingga server Excalidraw tidak akan pernah dapat melihatnya."
@@ -231,5 +234,9 @@
"title": "Statistik untuk nerd",
"total": "Total",
"width": "Lebar"
},
"toast": {
"copyStyles": "Gaya tersalin.",
"copyToClipboardAsPng": "Tersalin ke clipboard sebagai PNG."
}
}
+30 -23
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Incolla",
"pasteCharts": "Incolla grafici",
"selectAll": "Seleziona tutto",
"multiSelect": "Aggiungi elemento alla selezione",
"moveCanvas": "Sposta tela",
@@ -77,8 +78,8 @@
"ungroup": "Dividi gruppo da selezione",
"collaborators": "Collaboratori",
"gridMode": "Modalità griglia",
"addToLibrary": "Aggiungi alla biblioteca",
"removeFromLibrary": "Rimuovi dalla biblioteca",
"addToLibrary": "Aggiungi alla libreria",
"removeFromLibrary": "Rimuovi dalla libreria",
"libraryLoadingMessage": "Caricamento della biblioteca...",
"libraries": "Sfoglia librerie",
"loadingScene": "Caricamento della scena...",
@@ -135,7 +136,7 @@
"uploadedSecurly": "L'upload è stato protetto con la crittografia end-to-end, il che significa che il server Excalidraw e terze parti non possono leggere il contenuto.",
"loadSceneOverridePrompt": "Se carichi questo disegno esterno, sostituirà quello che hai. Vuoi continuare?",
"errorLoadingLibrary": "Si è verificato un errore nel caricamento della libreria di terze parti.",
"confirmAddLibrary": "Questo aggiungerà {{numShapes}} forma(e) alla tua biblioteca. Sei sicuro?",
"confirmAddLibrary": "Questo aggiungerà {{numShapes}} forma(e) alla tua libreria. Sei sicuro?",
"imageDoesNotContainScene": "L'importazione di immagini al momento non è supportata.\n\nVuoi importare una scena? Questa immagine non sembra contenere alcun dato di scena. Hai abilitato questa opzione durante l'esportazione?",
"cannotRestoreFromImage": "Impossibile ripristinare la scena da questo file immagine"
},
@@ -148,7 +149,7 @@
"arrow": "Freccia",
"line": "Linea",
"text": "Testo",
"library": "Biblioteca",
"library": "Libreria",
"lock": "Mantieni lo strumento selezionato attivo dopo aver disegnato"
},
"headings": {
@@ -162,7 +163,7 @@
"text": "Suggerimento: puoi anche aggiungere del testo facendo doppio clic ovunque con lo strumento di selezione",
"linearElementMulti": "Clicca sull'ultimo punto o premi Esc o Invio per finire",
"lockAngle": "Puoi limitare l'angolo tenendo premuto SHIFT",
"resize": "Per vincolare le proporzioni, tenir premuto MAIUSC durante il ridimensionamento;\nper ridimensionare dal centro, tenir premuto ALT",
"resize": "Per vincolare le proporzioni, tieni premuto MAIUSC durante il ridimensionamento;\nper ridimensionare dal centro, tieni premuto ALT",
"rotate": "Puoi mantenere gli angoli tenendo premuto SHIFT durante la rotazione",
"lineEditor_info": "Fai doppio click o premi invio per modificare i punti",
"lineEditor_pointSelected": "Premere Elimina per rimuovere il punto, CtrlOrCmd+D per duplicare o trascinare per spostare",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Errore"
},
"shortcutsDialog": {
"title": "Scorciatoie da tastiera",
"shapes": "Forme",
"or": "oppure",
"click": "click",
"drag": "trascina",
"curvedArrow": "Freccia curva",
"curvedLine": "Linea curva",
"editor": "Editor",
"view": "Vista",
"blog": "Leggi il nostro blog",
"howto": "Segui le nostre guide",
"github": "Hai trovato un problema? Segnalalo",
"textNewLine": "Aggiungi nuova riga (testo)",
"textFinish": "Completa la modifica (testo)",
"zoomToFit": "Adatta zoom per mostrare tutti gli elementi",
"zoomToSelection": "Zoom alla selezione",
"preventBinding": "Prevenire l'associazione freccia"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "I tuoi disegni sono crittografati end-to-end in modo che i server di Excalidraw non li possano mai vedere."
@@ -231,5 +234,9 @@
"title": "Statistiche per nerd",
"total": "Totale",
"width": "Larghezza"
},
"toast": {
"copyStyles": "Stili copiati.",
"copyToClipboardAsPng": "Copiato negli appunti come PNG."
}
}
+36 -29
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "貼り付け",
"pasteCharts": "",
"selectAll": "すべて選択",
"multiSelect": "複数選択",
"moveCanvas": "キャンバスを移動",
@@ -29,11 +30,11 @@
"edges": "角",
"sharp": "四角",
"round": "丸",
"arrowheads": "",
"arrowhead_none": "",
"arrowhead_arrow": "",
"arrowhead_bar": "",
"arrowhead_dot": "",
"arrowheads": "線の終点",
"arrowhead_none": "なし",
"arrowhead_arrow": "矢印",
"arrowhead_bar": "バー",
"arrowhead_dot": "ドット",
"fontSize": "フォントの大きさ",
"fontFamily": "フォントの種類",
"onlySelected": "選択中のみ",
@@ -117,9 +118,9 @@
"redo": "やり直し",
"roomDialog": "共同編集を開始する",
"createNewRoom": "新しい部屋を作成する",
"fullScreen": "",
"darkMode": "",
"lightMode": "",
"fullScreen": "全画面表示",
"darkMode": "ダークモード",
"lightMode": "ライトモード",
"zenMode": "",
"exitZenMode": "集中モードをやめる"
},
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "エラー"
},
"shortcutsDialog": {
"title": "キーボードショートカット",
"shapes": "図形",
"or": "または",
"click": "クリック",
"drag": "ドラッグ",
"curvedArrow": "曲がった矢印",
"curvedLine": "曲線",
"editor": "エディタ",
"view": "表示",
"blog": "公式ブログを読む",
"howto": "ヘルプ・マニュアル",
"github": "不具合報告はこちら",
"textNewLine": "テキストの改行",
"textFinish": "テキストの編集を終える",
"zoomToFit": "すべての図形が収まるよう拡大/縮小",
"zoomToSelection": "",
"preventBinding": "矢印を結合しない"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "描画内容はエンドツーエンド暗号化が施されており、Excalidrawサーバーが内容を見ることはできません。"
@@ -224,12 +227,16 @@
"angle": "",
"element": "",
"elements": "",
"height": "",
"height": "高さ",
"scene": "",
"selected": "",
"storage": "",
"title": "",
"total": "",
"width": ""
"total": "合計",
"width": ""
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+105 -98
View File
@@ -1,11 +1,12 @@
{
"labels": {
"paste": "붙여넣기",
"pasteCharts": "차트 붙여넣기",
"selectAll": "전체 선택",
"multiSelect": "선택 영역에 추가하기",
"moveCanvas": "캔버스 이동",
"cut": "잘라내기",
"copy": "복사하기",
"copy": "복사",
"copyAsPng": "클립보드로 PNG 이미지 복사",
"copyAsSvg": "클립보드로 SVG 이미지 복사",
"bringForward": "앞으로 가져오기",
@@ -17,31 +18,31 @@
"pasteStyles": "스타일 붙여넣기",
"stroke": "선 색상",
"background": "배경색",
"fill": "채우기 스타일",
"strokeWidth": "선 두께",
"strokeStyle": "선 스타일",
"fill": "채우기",
"strokeWidth": "선 굵기",
"strokeStyle": "선",
"strokeStyle_solid": "실선",
"strokeStyle_dashed": "파선",
"strokeStyle_dotted": "점선",
"sloppiness": "선 스타일",
"sloppiness": "대충 긋기",
"opacity": "불투명도",
"textAlign": "텍스트 정렬",
"edges": "가장자리",
"sharp": "선명하게",
"sharp": "뾰족하게",
"round": "둥글게",
"arrowheads": "화살표 모양",
"arrowheads": "화살",
"arrowhead_none": "없음",
"arrowhead_arrow": "화살표",
"arrowhead_bar": "",
"arrowhead_dot": "",
"fontSize": "폰트 크기",
"fontFamily": "폰트 스타일",
"arrowhead_bar": "막대",
"arrowhead_dot": "",
"fontSize": "글자 크기",
"fontFamily": "글꼴",
"onlySelected": "선택한 항목만",
"withBackground": "",
"exportEmbedScene": "",
"exportEmbedScene_details": "",
"withBackground": "배경 포함",
"exportEmbedScene": "화면을 내보낸 파일에 담기",
"exportEmbedScene_details": "화면 정보가 내보내는 PNG/SVG 파일에 저장되어 이후에 파일에서 화면을 복구할 수 있습니다. 파일 크기가 증가합니다.",
"addWatermark": "\"Made with Excalidraw\" 추가",
"handDrawn": "필기체",
"handDrawn": "손글씨",
"normal": "일반",
"code": "코드",
"small": "작게",
@@ -57,40 +58,40 @@
"center": "가운데",
"right": "오른쪽",
"extraBold": "매우 굵게",
"architect": "",
"artist": "",
"cartoonist": "",
"fileTitle": "",
"architect": "건축가",
"artist": "예술가",
"cartoonist": "만화가",
"fileTitle": "파일명",
"colorPicker": "색상 선택기",
"canvasBackground": "캔버스 배경",
"drawingCanvas": "캔버스 그리기",
"layers": "레이어",
"actions": "",
"actions": "동작",
"language": "언어",
"createRoom": "실시간 협업 세션 공유",
"duplicateSelection": "복제",
"untitled": "",
"name": "",
"untitled": "제목 없음",
"name": "이름",
"yourName": "이름 입력",
"madeWithExcalidraw": "Made with Excalidraw",
"group": "그룹 생성",
"ungroup": "그룹 해제",
"collaborators": "공동 작업자",
"gridMode": "",
"gridMode": "격자 방식",
"addToLibrary": "라이브러리에 추가",
"removeFromLibrary": "라이브러리에서 제거",
"libraryLoadingMessage": "라이브러리 불러오는 중...",
"libraries": "",
"libraries": "라이브러리 찾기",
"loadingScene": "화면 불러오는 중...",
"align": "",
"alignTop": "",
"alignBottom": "",
"alignLeft": "",
"alignRight": "",
"centerVertically": "",
"centerHorizontally": "",
"distributeHorizontally": "",
"distributeVertically": ""
"align": "정렬",
"alignTop": "상단 정렬",
"alignBottom": "하단 정렬",
"alignLeft": "왼쪽 정렬",
"alignRight": "오른쪽 정렬",
"centerVertically": "수직으로 중앙 정렬",
"centerHorizontally": "수평으로 중앙 정렬",
"distributeHorizontally": "수평으로 분배",
"distributeVertically": "수직으로 분배"
},
"buttons": {
"clearReset": "캔버스 초기화",
@@ -99,17 +100,17 @@
"exportToSvg": "SVG로 내보내기",
"copyToClipboard": "클립보드로 복사",
"copyPngToClipboard": "클립보드로 PNG 이미지 복사",
"scale": "",
"scale": "크기",
"save": "저장",
"saveAs": "다른 이름으로 저장",
"load": "불러오기",
"getShareableLink": "공유 가능한 링크 생성",
"close": "닫기",
"selectLanguage": "언어 선택",
"scrollBackToContent": "콘텐츠 영역으로 스크롤 이동하기",
"scrollBackToContent": "콘텐츠 영역으로 스크롤하기",
"zoomIn": "확대",
"zoomOut": "축소",
"resetZoom": " 초기화",
"resetZoom": "확대/축소 초기화",
"menu": "메뉴",
"done": "완료",
"edit": "수정",
@@ -117,27 +118,27 @@
"redo": "다시 실행",
"roomDialog": "실시간 협업 시작하기",
"createNewRoom": "방 만들기",
"fullScreen": "",
"darkMode": "",
"lightMode": "",
"zenMode": "",
"fullScreen": "전체화면",
"darkMode": "다크 모드",
"lightMode": "밝은 모드",
"zenMode": "젠 모드",
"exitZenMode": "젠 모드 종료하기"
},
"alerts": {
"clearReset": "모든 작업 내용 초기화니다. 계속 진행할까요?",
"clearReset": "모든 작업 내용 초기화니다. 계속하시겠습니까?",
"couldNotCreateShareableLink": "공유 가능한 링크를 생성할 수 없습니다.",
"couldNotCreateShareableLinkTooBig": "",
"couldNotCreateShareableLinkTooBig": "공유 가능한 링크를 생성할 수 없습니다: 화면이 너무 큽니다.",
"couldNotLoadInvalidFile": "유효하지 않은 파일입니다.",
"importBackendFailed": "서버로부터 불러 오지 못했습니다.",
"cannotExportEmptyCanvas": "빈 캔버스를 내보낼 수 없습니다.",
"couldNotCopyToClipboard": "클립 보드에 복사 할 수 없습니다. Chrome 브라우저에서 시도해 주세요.",
"couldNotCopyToClipboard": "클립 보드에 복사할 수 없습니다. Chrome 브라우저에서 시도해 주세요.",
"decryptFailed": "데이터를 복호화하지 못했습니다.",
"uploadedSecurly": "업로드는 종단 간 암호화로 보호되므로 Excalidraw 서버 및 타사가 콘텐츠를 읽을 수 없습니다.",
"loadSceneOverridePrompt": "외부 파일을 불러 오면 기존 콘텐츠가 대체됩니다. 계속 진행할까요?",
"errorLoadingLibrary": "",
"confirmAddLibrary": "",
"imageDoesNotContainScene": "",
"cannotRestoreFromImage": ""
"errorLoadingLibrary": "외부 라이브러리를 불러오는 중에 문제가 발생했습니다.",
"confirmAddLibrary": "{{numShapes}}개의 모양이 라이브러리에 추가됩니다. 계속하시겠어요?",
"imageDoesNotContainScene": "이미지에서 불러오기는 현재 지원되지 않습니다.\n\n화면을 불러오려고 하셨나요? 이미지에 화면 정보가 없는 것 같습니다. 내보낼 때 화면을 포함했나요?",
"cannotRestoreFromImage": "이미지 파일에서 화면을 복구할 수 없었습니다"
},
"toolBar": {
"selection": "선택",
@@ -146,45 +147,45 @@
"diamond": "다이아몬드",
"ellipse": "타원",
"arrow": "화살표",
"line": "라인",
"line": "",
"text": "텍스트",
"library": "라이브러리",
"lock": "선택된 도구 유지하기"
},
"headings": {
"canvasActions": "",
"selectedShapeActions": "",
"shapes": ""
"canvasActions": "캔버스 동작",
"selectedShapeActions": "선택된 모양 동작",
"shapes": "모양"
},
"hints": {
"linearElement": "여러 점을 연결하려면 클릭하고, 직선을 그리려면 바로 드래그하세요.",
"freeDraw": "클릭 후 드래그하세요. 완료되면 놓으세요.",
"text": "",
"text": "팁: 선택 툴로 아무 곳이나 더블 클릭해 텍스트를 추가할 수도 있습니다.",
"linearElementMulti": "마지막 지점을 클릭하거나 Esc 또는 Enter 키를 눌러 완료하세요.",
"lockAngle": "",
"resize": "",
"lockAngle": "SHIFT 키를 누르면서 회전하면 각도를 제한할 수 있습니다.",
"resize": "SHIFT 키를 누르면서 조정하면 크기의 비율이 제한됩니다.\nALT를 누르면서 조정하면 중앙을 기준으로 크기를 조정합니다.",
"rotate": "SHIFT 키를 누르면서 회전하면 각도를 제한할 수 있습니다.",
"lineEditor_info": "포인트를 수정하려면 두 번 클릭하거나 엔터 키를 누르세요.",
"lineEditor_info": "지점을 수정하려면 두 번 클릭하거나 Enter 키를 누르세요.",
"lineEditor_pointSelected": "제거하려면 Delete 키, 복제하려면 CtrlOrCmd+D, 이동하려면 드래그하세요.",
"lineEditor_nothingSelected": ""
"lineEditor_nothingSelected": "옮기거나 지울 지점을 선택하거나, Alt를 누른 상태로 클릭해 새 지점을 만드세요"
},
"canvasError": {
"cannotShowPreview": "",
"canvasTooBig": "",
"canvasTooBigTip": ""
"cannotShowPreview": "미리보기를 볼 수 없습니다",
"canvasTooBig": "캔버스가 너무 큽니다.",
"canvasTooBigTip": "팁: 멀리 있는 요소들을 좀 더 가까이로 붙여 보세요."
},
"errorSplash": {
"headingMain_pre": "",
"headingMain_pre": "오류가 발생했습니다. ",
"headingMain_button": "페이지 새로고침",
"clearCanvasMessage": "",
"clearCanvasMessage_button": "캔버스를 초기화 중입니다.",
"clearCanvasCaveat": "",
"trackedToSentry_pre": "",
"trackedToSentry_post": "",
"openIssueMessage_pre": "",
"openIssueMessage_button": "",
"clearCanvasMessage": "새로고침으로 해결되지 않을 경우, ",
"clearCanvasMessage_button": "캔버스 비우기",
"clearCanvasCaveat": " 작업 내용을 잃게 됩니다 ",
"trackedToSentry_pre": "오류 ",
"trackedToSentry_post": " 가 시스템에서 발견되었습니다.",
"openIssueMessage_pre": "저희는 화면 정보를 오류에 포함하지 않도록 매우 주의하고 있습니다. 혹시 화면에 민감한 내용이 없다면 이곳에 업로드를 고려해주세요.",
"openIssueMessage_button": "버그 트래커",
"openIssueMessage_post": " 아래 정보를 GitHub 이슈에 복사 및 붙여넣기해 주세요.",
"sceneContent": ""
"sceneContent": "화면 내용:"
},
"roomDialog": {
"desc_intro": "현재 화면에 공동 작업자를 초대해 협업할 수 있습니다.",
@@ -193,43 +194,49 @@
"button_stopSession": "세션 중단",
"desc_inProgressIntro": "실시간 협업 세션이 진행 중입니다.",
"desc_shareLink": "공동 작업자에게 이 링크를 공유하세요.",
"desc_exitSession": ""
"desc_exitSession": "세션을 중단하면 연결은 끊어지나 작업을 이어갈 수 있습니다. 이 작업은 다른 작업자에게 영향을 미치지 않으며 각자의 공동 작업은 계속 유지됩니다."
},
"errorDialog": {
"title": "에러"
"title": "오류"
},
"shortcutsDialog": {
"title": "키보드 단축키",
"shapes": "그리기",
"or": "또는",
"click": "클릭",
"drag": "드래그",
"curvedArrow": "곡선 화살표",
"curvedLine": "곡선",
"editor": "편집",
"view": "보기",
"blog": "블로그 읽어보기",
"howto": "가이드 참고하기",
"github": "이슈 제보하기",
"textNewLine": "줄바꾸기",
"textFinish": "편집 완료",
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": "",
"preventBinding": ""
"zoomToSelection": ""
},
"encrypted": {
"tooltip": ""
"tooltip": "그림은 종단 간 암호화되므로 Excalidraw의 서버는 절대로 내용을 알 수 없습니다."
},
"stats": {
"angle": "",
"element": "",
"elements": "",
"height": "",
"scene": "",
"selected": "",
"storage": "",
"title": "",
"total": "",
"width": ""
"angle": "각도",
"element": "요소",
"elements": "요소",
"height": "높이",
"scene": "화면",
"selected": "선택됨",
"storage": "저장공간",
"title": "덕후들을 위한 통계",
"total": "합계",
"width": "너비"
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+26 -19
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "ထား",
"pasteCharts": "",
"selectAll": "အကုန်ရွေး",
"multiSelect": "ရွေးထားသည့်ထဲပုံထည့်",
"moveCanvas": "ကားချပ်ရွှေ့",
@@ -33,7 +34,7 @@
"arrowhead_none": "ဘာမျှမရှိ",
"arrowhead_arrow": "မြှား",
"arrowhead_bar": "",
"arrowhead_dot": "",
"arrowhead_dot": "အစက်",
"fontSize": "စာလုံးအရွယ်",
"fontFamily": "စာလုံးပုံစံ",
"onlySelected": "ရွေးထားသလောက်",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "ချို့ယွင်းချက်"
},
"shortcutsDialog": {
"title": "ကီးဘုတ်ရှော့ကတ်များ",
"shapes": "ပုံသဏ္ဌာန်",
"or": "(သို့)",
"click": "ကလစ်နှိပ်",
"drag": "တရွတ်ဆွဲ",
"curvedArrow": "မြှားကွေး",
"curvedLine": "မျဉ်းကွေး",
"editor": "တည်းဖြတ်",
"view": "မြင်ကွင်း",
"blog": "ဘလော့ဂ်တွင်လေ့လာပါ",
"howto": "အညွှန်း",
"github": "ချို့ယွင်းမှုအတွက်အသိပေးရန်",
"textNewLine": "စာသားဖြည့်သွင်း",
"textFinish": "စာသားဖြည့်သွင်းပြီး",
"zoomToFit": "ကားချပ်အပြည့်ဖေါ်",
"zoomToSelection": "",
"preventBinding": "မြှားများမပေါင်းစေရန်"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "ရေးဆွဲထားသောပုံများအား နှစ်ဘက်စွန်းတိုင်လျှို့ဝှက်ထားသဖြင့် Excalidraw ၏ဆာဗာများပင်လျှင်မြင်တွေ့ရမည်မဟုတ်ပါ။"
@@ -231,5 +234,9 @@
"title": "အက္ခရာများအတွက်အချက်အလက်များ",
"total": "စုစုပေါင်း",
"width": "အကျယ်"
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+20 -13
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Lim inn",
"pasteCharts": "Lim inn diagrammer",
"selectAll": "Velg alt",
"multiSelect": "Legg til element i utvalg",
"moveCanvas": "Flytt lerretet",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Feil"
},
"shortcutsDialog": {
"title": "Tastatursnarveier",
"shapes": "Figurer",
"or": "eller",
"helpDialog": {
"blog": "Les bloggen vår",
"click": "klikk",
"drag": "dra",
"curvedArrow": "Buet pil",
"curvedLine": "Buet linje",
"editor": "Redigering",
"view": "Visning",
"blog": "Les bloggen vår",
"howto": "Følg våre veiledninger",
"documentation": "Dokumentasjon",
"drag": "dra",
"editor": "Redigeringsvisning",
"github": "Funnet et problem? Send inn",
"textNewLine": "Legg til ny linje (tekst)",
"howto": "Følg våre veiledninger",
"or": "eller",
"preventBinding": "Forhindre pilbinding",
"shapes": "Former",
"shortcuts": "Tastatursnarveier",
"textFinish": "Fullfør redigering (tekst)",
"zoomToFit": "Zoom for å passe alle elementene",
"zoomToSelection": "Zoom til utvalg",
"preventBinding": "Forhindre pilbinding"
"textNewLine": "Legg til ny linje (tekst)",
"title": "Hjelp",
"view": "Vis",
"zoomToFit": "Zoom for å se alle elementer",
"zoomToSelection": "Zoom til utvalg"
},
"encrypted": {
"tooltip": "Dine tegninger er ende-til-ende-krypterte slik at Excalidraw sine servere aldri vil se dem."
@@ -231,5 +234,9 @@
"title": "Statistikk for nerder",
"total": "Totalt",
"width": "Bredde"
},
"toast": {
"copyStyles": "Kopierte stiler.",
"copyToClipboardAsPng": "Kopiert til utklippstavlen som PNG."
}
}
+21 -14
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Plakken",
"pasteCharts": "Plak grafieken",
"selectAll": "Alles selecteren",
"multiSelect": "Voeg element toe aan selectie",
"moveCanvas": "Canvas verplaatsen",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Fout"
},
"shortcutsDialog": {
"title": "Sneltoetsen",
"shapes": "Vormen",
"or": "of",
"click": "klik",
"drag": "slepen",
"curvedArrow": "Gebogen pijl",
"curvedLine": "Gebogen lijn",
"editor": "Editor",
"view": "Weergave",
"helpDialog": {
"blog": "Lees onze blog",
"click": "klik",
"curvedArrow": "Gebogen pijl",
"curvedLine": "Kromme lijn",
"documentation": "Documentatie",
"drag": "slepen",
"editor": "Editor",
"github": "Probleem gevonden? Verzenden",
"howto": "Volg onze handleidingen",
"github": "Probleem gevonden? Stuur een nieuwe issue",
"textNewLine": "Nieuwe regel toevoegen (tekst)",
"or": "of",
"preventBinding": "Pijlbinding voorkomen",
"shapes": "Vormen",
"shortcuts": "Sneltoetsen",
"textFinish": "Voltooi bewerken (tekst)",
"textNewLine": "Nieuwe regel toevoegen (tekst)",
"title": "Help",
"view": "Weergave",
"zoomToFit": "Zoom in op alle elementen",
"zoomToSelection": "Inzoomen op selectie",
"preventBinding": "Pijlbinding voorkomen"
"zoomToSelection": "Inzoomen op selectie"
},
"encrypted": {
"tooltip": "Je tekeningen zijn beveiligd met end-to-end encryptie, dus Excalidraw's servers zullen nooit zien wat je tekent."
@@ -231,5 +234,9 @@
"title": "Statistieken voor nerds",
"total": "Totaal",
"width": "Breedte"
},
"toast": {
"copyStyles": "Stijlen gekopieerd.",
"copyToClipboardAsPng": "Gekopieerd naar klembord als PNG."
}
}
+33 -26
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Lim inn",
"pasteCharts": "Lim inn diagram",
"selectAll": "Vel alt",
"multiSelect": "Legg til element i utval",
"moveCanvas": "Flytt lerretet",
@@ -39,7 +40,7 @@
"onlySelected": "Kun valde",
"withBackground": "Med bakgrunn",
"exportEmbedScene": "Bygg scena inn i eksportert fil",
"exportEmbedScene_details": "Scenedataa vert lagra i den eksporterte PNG- eller SVG-fila slik at scena kan bli gjenopprettast frå den. Dette vil auke eksportert filstorleik.",
"exportEmbedScene_details": "Scenedata vert lagra i den eksporterte PNG- eller SVG-fila slik at scena kan bli gjenopprettast frå den. Dette vil auke eksportert filstorleik.",
"addWatermark": "Legg til «Laga med Excalidraw»",
"handDrawn": "Handteikna",
"normal": "Normal",
@@ -76,7 +77,7 @@
"group": "Grupper utval",
"ungroup": "Avgrupper utval",
"collaborators": "Samarbeidarar",
"gridMode": "",
"gridMode": "Rutevisning",
"addToLibrary": "Legg til i bibliotek",
"removeFromLibrary": "Fjern frå bibliotek",
"libraryLoadingMessage": "Laster bibliotek...",
@@ -117,10 +118,10 @@
"redo": "Gjer om",
"roomDialog": "Start sanntids-samarbeid",
"createNewRoom": "Lag nytt rom",
"fullScreen": "",
"darkMode": "",
"lightMode": "",
"zenMode": "",
"fullScreen": "Fullskjerm",
"darkMode": "Mørk modus",
"lightMode": "Lys modus",
"zenMode": "Zen-modus",
"exitZenMode": "Avslutt zen-modus"
},
"alerts": {
@@ -136,7 +137,7 @@
"loadSceneOverridePrompt": "Innlasting av ekstern teikning erstattar ditt eksisterande innhald. Ynskjer du å fortsette?",
"errorLoadingLibrary": "Det oppstod ein feil under lastinga av tredjepartsbibliotek.",
"confirmAddLibrary": "Dette vil legge til {{numShapes}} form(er) i biblioteket ditt. Er du sikker?",
"imageDoesNotContainScene": "",
"imageDoesNotContainScene": "Importering av bilder støttes ikkje for p. t.\n\nVil du importere ein scene? Dette bildet ser ikkje ut til å inneholde noen scene-data. Har du aktivert dette under eksporten?",
"cannotRestoreFromImage": "Scena kunne ikkje gjenopprettast frå denne biletfila"
},
"toolBar": {
@@ -161,7 +162,7 @@
"freeDraw": "Klikk og drag, slepp når du er ferdig",
"text": "Tips: du kan òg leggje til tekst ved å dobbeltklikke kor som helst med utvalgsverktyet",
"linearElementMulti": "Klikk på siste punkt eller trykk Escape eller Enter for å fullføre",
"lockAngle": "",
"lockAngle": "Du kan begrense vinkelen ved å holde nede SKIFT",
"resize": "Du kan halde fram med forholdet ved å trykke SHIFT medan du endrar storleik,\ntrykk ALT for å endre storleiken frå midten",
"rotate": "Du kan låse vinklane ved å halde SHIFT medan du roterer",
"lineEditor_info": "Dobbeltklikk eller trykk Enter for å redigere punkt",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Feil"
},
"shortcutsDialog": {
"title": "Tastatursnarvegar",
"shapes": "Figurar",
"or": "eller",
"click": "klikk",
"drag": "drag",
"curvedArrow": "Boga pil",
"curvedLine": "Boga linje",
"editor": "Redigering",
"view": "Vising",
"blog": "Les bloggen vår",
"howto": "Følg vegleiinga vår",
"github": "Funne eit problem? Send inn",
"textNewLine": "Legg til ny linje (tekst)",
"textFinish": "Fullfør redigering (tekst)",
"zoomToFit": "Zoom for å sjå alle elementa",
"zoomToSelection": "Zoom til utval",
"preventBinding": "Hindre pilkobling"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "Teikningane dine er ende-til-ende-krypterte slik at Excalidraw sine serverar aldri får sjå dei."
@@ -231,5 +234,9 @@
"title": "Statistikk for nerdar",
"total": "Totalt",
"width": "Breidde"
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+242
View File
@@ -0,0 +1,242 @@
{
"labels": {
"paste": "ਪੇਸਟ ਕਰੋ",
"pasteCharts": "ਚਾਰਟ ਪੇਸਟ ਕਰੋ",
"selectAll": "ਸਾਰੇ ਚੁਣੋ",
"multiSelect": "ਐਲੀਮੈਂਟ ਨੂੰ ਚੋਣ ਵਿੱਚ ਜੋੜੋ",
"moveCanvas": "ਕੈਨਵਸ ਹਿਲਾਓ",
"cut": "ਕੱਟੋ",
"copy": "ਕਾਪੀ ਕਰੋ",
"copyAsPng": "ਕਲਿੱਪਬੋਰਡ 'ਤੇ PNG ਵਜੋਂ ਕਾਪੀ ਕਰੋ",
"copyAsSvg": "ਕਲਿੱਪਬੋਰਡ 'ਤੇ SVG ਵਜੋਂ ਕਾਪੀ ਕਰੋ",
"bringForward": "ਅੱਗੇ ਲਿਆਓ",
"sendToBack": "ਸਭ ਤੋਂ ਪਿੱਛੇ ਭੇਜੋ",
"bringToFront": "ਸਭ ਤੋਂ ਅੱਗੇ ਲਿਆਓ",
"sendBackward": "ਪਿੱਛੇ ਭੇਜੋ",
"delete": "ਮਿਟਾਓ",
"copyStyles": "ਸਟਾਇਲ ਕਾਪੀ ਕਰੋ",
"pasteStyles": "ਸਟਾਇਲ ਪੇਸਟ ਕਰੋ",
"stroke": "ਰੇਖਾ",
"background": "ਬੈਕਗਰਾਉਂਡ",
"fill": "ਭਰਨਾ",
"strokeWidth": "ਰੇਖਾ ਦੀ ਚੌੜਾਈ",
"strokeStyle": "ਰੇਖਾ ਦਾ ਸਟਾਇਲ",
"strokeStyle_solid": "ਠੋਸ",
"strokeStyle_dashed": "ਡੈਸ਼ ਵਾਲੀ",
"strokeStyle_dotted": "ਬਿੰਦੀਆਂ ਵਾਲੀ",
"sloppiness": "ਬੇਤਰਤੀਬੀ",
"opacity": "ਅਪਾਰਦਰਸ਼ਤਾ",
"textAlign": "ਲਿਖਤ ਇਕਸਾਰਤਾ",
"edges": "ਕਿਨਾਰੇ",
"sharp": "ਤਿੱਖੇ",
"round": "ਗੋਲ",
"arrowheads": "ਤੀਰ ਦੇ ਸਿਰੇ",
"arrowhead_none": "ਕੋਈ ਨਹੀਂ",
"arrowhead_arrow": "ਤੀਰ",
"arrowhead_bar": "ਡੰਡੀ",
"arrowhead_dot": "ਬਿੰਦੀ",
"fontSize": "ਫੌਂਟ ਅਕਾਰ",
"fontFamily": "ਫੌਂਟ ਪਰਿਵਾਰ",
"onlySelected": "ਸਿਰਫ ਚੁਣੇ ਹੋਏ ਹੀ",
"withBackground": "ਬੈਕਗਰਾਉਂਂਡ ਨਾਲ",
"exportEmbedScene": "ਦ੍ਰਿਸ਼ ਨੂੰ ਨਿਰਯਾਤ ਕੀਤੀ ਫਾਈਲ ਵਿੱਚ ਮੜ੍ਹੋ",
"exportEmbedScene_details": "ਦ੍ਰਿਸ਼ ਦਾ ਡਾਟਾ ਨਿਰਯਾਤ ਕੀਤੀ PNG/SVG ਫਾਈਲ ਵਿੱਚ ਸਾਂਭ ਦਿੱਤਾ ਜਾਵੇਗਾ ਤਾਂ ਜੋ ਇਸ ਵਿੱਚੋਂ ਦ੍ਰਿਸ਼ ਨੂੰ ਬਹਾਲ ਕੀਤਾ ਜਾ ਸਕੇ। ਇਹ ਨਿਰਯਾਤ ਕੀਤੀ ਜਾਣ ਵਾਲੀ ਫਾਈਲ ਦਾ ਅਕਾਰ ਵਧਾ ਦੇਵੇਗਾ।",
"addWatermark": "\"Excalidraw ਨਾਲ ਬਣਾਇਆ\" ਜੋੜੋ",
"handDrawn": "ਹੱਥਲਿਖਤ",
"normal": "ਆਮ",
"code": "ਕੋਡ",
"small": "ਛੋਟਾ",
"medium": "ਮੱਧਮ",
"large": "ਵੱਡਾ",
"veryLarge": "ਬਹੁਤ ਵੱਡਾ",
"solid": "ਠੋਸ",
"hachure": "ਤਿਰਛੀਆਂ ਗਰਿੱਲਾਂ",
"crossHatch": "ਜਾਲੀ",
"thin": "ਪਤਲੀ",
"bold": "ਮੋਟੀ",
"left": "ਖੱਬੇ",
"center": "ਵਿਚਕਾਰ",
"right": "ਸੱਜੇ",
"extraBold": "ਬਹੁਤ ਮੋਟੀ",
"architect": "ਭਵਨ ਨਿਰਮਾਣਕਾਰੀ",
"artist": "ਕਲਾਕਾਰ",
"cartoonist": "ਕਾਰਟੂਨਿਸਟ",
"fileTitle": "ਫਾਈਲ ਦਾ ਸਿਰਨਾਵਾਂ",
"colorPicker": "ਰੰਗ ਚੋਣਕਾਰ",
"canvasBackground": "ਕੈਨਵਸ ਦਾ ਬੈਕਗਰਾਉਂਡ",
"drawingCanvas": "ਡਰਾਇੰਗ ਕੈਨਵਸ",
"layers": "ਪਰਤਾਂ",
"actions": "ਕਾਰਵਾਈਆਂ",
"language": "ਭਾਸ਼ਾ",
"createRoom": "ਲਾਇਵ ਸਹਿਯੋਗ ਇਜਲਾਸ ਸਾਂਝਾ ਕਰੋ",
"duplicateSelection": "ਡੁਪਲੀਕੇਟ ਬਣਾਓ",
"untitled": "ਬੇ-ਸਿਰਨਾਵਾਂ",
"name": "ਨਾਂ",
"yourName": "ਤੁਹਾਡਾ ਨਾਂ",
"madeWithExcalidraw": "Excalidraw ਨਾਲ ਬਣਾਇਆ",
"group": "ਚੋਣ ਦਾ ਗਰੁੱਪ ਬਣਾਓ",
"ungroup": "ਚੋਣ ਦਾ ਗਰੁੱਪ ਤੋੜੋ",
"collaborators": "ਸਹਿਯੋਗੀ",
"gridMode": "ਜਾਲੀਦਾਰ ਮੋਡ",
"addToLibrary": "ਲਾਇਬ੍ਰੇਰੀ ਵਿੱਚ ਜੋੜੋ",
"removeFromLibrary": "ਲਾਇਬ੍ਰੇਰੀ 'ਚੋਂ ਹਟਾਓ",
"libraryLoadingMessage": "ਲਾਇਬ੍ਰੇਰੀ ਲੋਡ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ...",
"libraries": "ਲਾਇਬ੍ਰੇਰੀਆਂ ਬਰਾਉਜ਼ ਕਰੋ",
"loadingScene": "ਦ੍ਰਿਸ਼ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ...",
"align": "ਇਕਸਾਰ",
"alignTop": "ਉੱਪਰ ਇਕਸਾਰ ਕਰੋ",
"alignBottom": "ਹੇਠਾਂ ਇਕਸਾਰ ਕਰੋ",
"alignLeft": "ਖੱਬੇ ਇਕਸਾਰ ਕਰੋ",
"alignRight": "ਸੱਜੇ ਇਕਸਾਰ ਕਰੋ",
"centerVertically": "ਲੇਟਵੇਂ ਵਿਚਕਾਰ ਕਰੋ",
"centerHorizontally": "ਖੜ੍ਹਵੇਂ ਵਿਚਕਾਰ ਕਰੋ",
"distributeHorizontally": "ਖੜ੍ਹਵੇਂ ਇਕਸਾਰ ਵੰਡੋ",
"distributeVertically": "ਲੇਟਵੇਂ ਇਕਸਾਰ ਵੰਡੋ"
},
"buttons": {
"clearReset": "ਕੈਨਵਸ ਰੀਸੈੱਟ ਕਰੋ",
"export": "ਨਿਰਯਾਤ",
"exportToPng": "PNG ਵਿੱਚ ਨਿਰਯਾਤ ਕਰੋ",
"exportToSvg": "SVG ਵਿੱਚ ਨਿਰਯਾਤ ਕਰੋ",
"copyToClipboard": "ਕਲਿੱਪਬੋਰਡ 'ਤੇ ਕਾਪੀ ਕਰੋ",
"copyPngToClipboard": "PNG ਨੂੰ ਕਲਿੱਪਬੋਰਡ 'ਤੇ ਕਾਪੀ ਕਰੋ",
"scale": "ਪੈਮਾਇਸ਼",
"save": "ਸਾਂਭੋ",
"saveAs": "ਇਸ ਵਜੋਂ ਸਾਂਭੋ",
"load": "ਲੋਡ ਕਰੋ",
"getShareableLink": "ਸਾਂਝੀ ਕਰਨ ਵਾਲੀ ਲਿੰਕ ਲਵੋ",
"close": "ਬੰਦ ਕਰੋ",
"selectLanguage": "ਭਾਸ਼ਾ ਚੁਣੋ",
"scrollBackToContent": "ਸਮੱਗਰੀ 'ਤੇ ਵਾਪਸ ਸਕਰੋਲ ਕਰੋ",
"zoomIn": "ਜ਼ੂਮ ਵਧਾਓ",
"zoomOut": "ਜ਼ੂਮ ਘਟਾਓ",
"resetZoom": "ਜ਼ੂਮ ਰੀਸੈੱਟ ਕਰੋ",
"menu": "ਮੇਨੂ",
"done": "ਹੋ ਗਿਆ",
"edit": "ਸੋਧੋ",
"undo": "ਅਣਕੀਤਾ ਕਰੋ",
"redo": "ਮੁੜ-ਕਰੋ",
"roomDialog": "ਲਾਇਵ ਸਹਿਯੋਗ ਸ਼ੁਰੂ ਕਰੋ",
"createNewRoom": "ਨਵਾਂ ਕਮਰਾ ਬਣਾਓ",
"fullScreen": "ਪੂਰੀ ਸਕਰੀਨ",
"darkMode": "ਡਾਰਕ ਮੋਡ",
"lightMode": "ਲਾਇਟ ਮੋਡ",
"zenMode": "ਜ਼ੈੱਨ ਮੋਡ",
"exitZenMode": "ਜ਼ੈੱਨ ਮੋਡ 'ਚੋਂ ਬਾਹਰ ਨਿਕਲੋ"
},
"alerts": {
"clearReset": "ਇਹ ਸਾਰਾ ਕੈਨਵਸ ਸਾਫ ਕਰ ਦੇਵੇਗਾ। ਕੀ ਤੁਸੀਂ ਪੱਕਾ ਇੰਝ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?",
"couldNotCreateShareableLink": "ਸਾਂਝੀ ਕਰਨ ਵਾਲੀ ਲਿੰਕ ਨਹੀਂ ਬਣਾ ਸਕੇ।",
"couldNotCreateShareableLinkTooBig": "ਸਾਂਝੀ ਕਰਨ ਵਾਲੀ ਲਿੰਕ ਨਹੀਂ ਬਣਾ ਸਕੇ: ਦ੍ਰਿਸ਼ ਬਹੁਤ ਵੱਡਾ ਹੈ",
"couldNotLoadInvalidFile": "ਨਜਾਇਜ਼ ਫਾਈਲ ਲੋਡ ਨਹੀਂ ਕਰ ਸਕੇ",
"importBackendFailed": "ਬੈਕਐੱਨਡ ਤੋਂ ਆਯਾਤ ਕਰਨ ਵਿੱਚ ਅਸਫਲ ਰਹੇ।",
"cannotExportEmptyCanvas": "ਖਾਲੀ ਕੈਨਵਸ ਨਿਰਯਾਤ ਨਹੀਂ ਕਰ ਸਕਦੇ।",
"couldNotCopyToClipboard": "ਕਲਿੱਪਬੋਰਡ 'ਤੇ ਕਾਪੀ ਨਹੀਂ ਕਰ ਸਕੇ। ਕਰੋਮ ਬਰਾਉਜ਼ਰ ਵਰਤ ਕੇ ਦੇਖੋ।",
"decryptFailed": "ਡਾਟਾ ਡੀਕਰਿਪਟ ਨਹੀਂ ਕਰ ਸਕੇ।",
"uploadedSecurly": "ਅੱਪਲੋਡ ਸਿਰੇ-ਤੋਂ-ਸਿਰੇ ਤੱਕ ਇਨਕਰਿਪਸ਼ਨ ਨਾਲ ਸੁਰੱਖਿਅਤ ਕੀਤੀ ਹੋਈ ਹੈ, ਜਿਸਦਾ ਮਤਲਬ ਇਹ ਹੈ ਕਿ Excalidraw ਸਰਵਰ ਅਤੇ ਤੀਜੀ ਧਿਰ ਦੇ ਬੰਦੇ ਸਮੱਗਰੀ ਨੂੰ ਪੜ੍ਹ ਨਹੀਂ ਸਕਦੇ।",
"loadSceneOverridePrompt": "ਬਾਹਰੀ ਡਰਾਇੰਗ ਨੂੰ ਲੋਡ ਕਰਨਾ ਤੁਹਾਡੀ ਮੌਜੂਦਾ ਸਮੱਗਰੀ ਦੀ ਥਾਂ ਲੈ ਲਵੇਗਾ। ਕੀ ਤੁਸੀਂ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?",
"errorLoadingLibrary": "ਤੀਜੀ ਧਿਰ ਦੀ ਲਾਇਬ੍ਰੇਰੀ ਨੂੰ ਲੋਡ ਕਰਨ ਵਿੱਚ ਗਲਤੀ ਹੋਈ ਸੀ।",
"confirmAddLibrary": "ਇਹ ਤੁਹਾਡੀ ਲਾਇਬ੍ਰੇਰੀ ਵਿੱਚ {{numShapes}} ਆਕ੍ਰਿਤੀ(ਆਂ) ਨੂੰ ਜੋੜ ਦੇਵੇਗਾ। ਕੀ ਤੁਸੀਂ ਪੱਕਾ ਇੰਝ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?",
"imageDoesNotContainScene": "ਫਿਲਹਾਲ ਤਸਵੀਰਾਂ ਨੂੰ ਆਯਾਤ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ।\n\nਕੀ ਤੁਸੀਂ ਦ੍ਰਿਸ਼ ਨੂੰ ਆਯਾਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਸੀ? ਇਸ ਤਸਵੀਰ ਵਿੱਚ ਦ੍ਰਿਸ਼ ਦਾ ਕੋਈ ਵੀ ਡਾਟਾ ਨਜ਼ਰ ਨਹੀਂ ਆ ਰਿਹਾ। ਕੀ ਨਿਰਯਾਤ ਦੌਰਾਨ ਤੁਸੀਂ ਇਹ ਸਮਰੱਥ ਕੀਤਾ ਸੀ?",
"cannotRestoreFromImage": "ਇਸ ਤਸਵੀਰ ਫਾਈਲ ਤੋਂ ਦ੍ਰਿਸ਼ ਬਹਾਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"
},
"toolBar": {
"selection": "ਚੋਣਕਾਰ",
"draw": "ਖੁੱਲ੍ਹੀ ਵਾਹੀ",
"rectangle": "ਆਇਤ",
"diamond": "ਹੀਰਾ",
"ellipse": "ਅੰਡਾਕਾਰ",
"arrow": "ਤੀਰ",
"line": "ਲਕੀਰ",
"text": "ਪਾਠ",
"library": "ਲਾਇਬ੍ਰੇਰੀ",
"lock": "ਡਰਾਇੰਗ ਤੋਂ ਬਾਅਦ ਵੀ ਚੁਣੇ ਹੋਏ ਸੰਦ ਨੂੰ ਸਰਗਰਮ ਰੱਖੋ "
},
"headings": {
"canvasActions": "ਕੈਨਵਸ ਦੀਆਂ ਕਾਰਵਾਈਆਂ",
"selectedShapeActions": "ਚੁਣੀ ਆਕ੍ਰਿਤੀ ਦੀਆਂ ਕਾਰਵਾਈਆਂ",
"shapes": "ਆਕ੍ਰਿਤੀਆਂ"
},
"hints": {
"linearElement": "ਇੱਕ ਤੋਂ ਜ਼ਿਆਦਾ ਬਿੰਦੂਆਂ ਲਈ ਕਲਿੱਕ ਕਰਕੇ ਸ਼ੁਰੂਆਤ ਕਰੋ, ਇਕਹਿਰੀ ਲਕੀਰ ਲਈ ਘਸੀਟੋ",
"freeDraw": "ਕਲਿੱਕ ਕਰਕੇ ਘਸੀਟੋ, ਪੂਰਾ ਹੋਣ 'ਤੇ ਛੱਡ ਦਿਉ",
"text": "ਨੁਸਖਾ: ਤੁਸੀਂ ਚੋਣਕਾਰ ਸੰਦ ਰਾਹੀਂ ਕਿਤੇ ਵੀ ਡਬਲ-ਕਲਿੱਕ ਕਰਕੇ ਵੀ ਪਾਠ ਜੋੜ ਸਕਦੇ ਹੋ",
"linearElementMulti": "ਮੁਕੰਮਲ ਕਰਨ ਲਈ ਆਖਰੀ ਬਿੰਦੂ 'ਤੇ ਕਲਿੱਕ ਕਰੋ ਜਾਂ ਇਸਕੇਪ ਜਾਂ ਐਂਟਰ ਦਬਾਓ",
"lockAngle": "ਤੁਸੀਂ SHIFT ਦਬਾਈ ਰੱਖ ਕੇ ਕੋਣਾਂ ਨੂੰ ਕਾਬੂ ਕਰ ਸਕਦੇ ਹੋ",
"resize": "ਤੁਸੀਂ ਅਕਾਰ ਬਦਲਦੇ ਸਮੇਂ SHIFT ਦਬਾਈ ਰੱਖ ਕੇ ਅਨੁਪਾਤ ਨੂੰ ਕਾਬੂ ਕਰ ਸਕਦੇ ਹੋ, ਵਿਚਕਾਰ ਤੋਂ ਅਕਾਰ ਬਦਲਣ ਲਈ ALT ਦਬਾਓ",
"rotate": "ਤੁਸੀਂ ਘੁਮਾਉਂਦੇ ਹੋਏ SHIFT ਦਬਾਈ ਰੱਖ ਕੇ ਕੋਣਾਂ ਨੂੰ ਕਾਬੂ ਕਰ ਸਕਦੇ ਹੋ",
"lineEditor_info": "ਬਿੰਦੂਆਂ ਨੂੰ ਸੋਧਣ ਲਈ ਡਬਲ-ਕਲਿੱਕ ਜਾਂ ਐਂਟਰ ਦਬਾਓ",
"lineEditor_pointSelected": "ਬਿੰਦੀ ਹਟਾਉਣ ਲਈ ਡਲੀਟ ਦਬਾਓ, ਡੁਪਲੀਕੇਟ ਬਣਾਉਣ ਲਈ CtrlOrCmd+D, ਜਾਂ ਹਿਲਾਉਣ ਲਈ ਘਸੀਟੋ",
"lineEditor_nothingSelected": "ਹਿਲਾਉਣ ਜਾਂ ਹਟਾਉਣ ਲਈ ਬਿੰਦੂ ਚੁਣੋ, ਜਾਂ ਨਵਾਂ ਬਿੰਦੂ ਜੋੜਨ ਲਈ Alt ਦਬਾਕੇ ਕਲਿੱਕ ਕਰੋ"
},
"canvasError": {
"cannotShowPreview": "ਝਲਕ ਨਹੀਂ ਦਿਖਾ ਸਕਦੇ",
"canvasTooBig": "ਸ਼ਾਇਦ ਕੈਨਵਸ ਬਹੁਤ ਜ਼ਿਆਦਾ ਵੱਡਾ ਹੈ।",
"canvasTooBigTip": "ਨੁਸਖਾ: ਸਭ ਤੋਂ ਦੂਰ ਸਥਿੱਤ ਐਲੀਮੈਂਟਾਂ ਨੂੰ ਥੋੜ੍ਹਾ ਜਿਹਾ ਨੇੜੇ ਲਿਆ ਕੇ ਦੇਖੋ।"
},
"errorSplash": {
"headingMain_pre": "ਗਲਤੀ ਹੋਈ। ਇਹ ਕਰਕੇ ਦੇਖੋ ",
"headingMain_button": "ਪੰਨਾ ਮੁੜ-ਲੋਡ ਕਰੋ।",
"clearCanvasMessage": "ਜੇ ਮੁੜ-ਲੋਡ ਕਰਨਾ ਕੰਮ ਨਾ ਕਰੇ, ਤਾਂ ਇਹ ਕਰਕੇ ਦੇਖੋ ",
"clearCanvasMessage_button": "ਕੈਨਵਸ ਸਾਫ ਕਰੋ।",
"clearCanvasCaveat": " ਇਹ ਸਾਰਾ ਕੰਮ ਗਵਾ ਦੇਵੇਗਾ ",
"trackedToSentry_pre": "ਗਲਤੀ ਸੂਚਕ ",
"trackedToSentry_post": " ਸਾਡੇ ਸਿਸਟਮ 'ਤੇ ਟਰੈਕ ਕੀਤਾ ਗਿਆ ਸੀ।",
"openIssueMessage_pre": "ਅਸੀਂ ਬੜੇ ਸਾਵਧਾਨ ਸੀ ਕਿ ਗਲਤੀ ਵਿੱਚ ਤੁਹਾਡੇ ਦ੍ਰਿਸ਼ ਦੀ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਨਾ ਕਰੀਏ। ਜੇ ਤੁਹਾਡਾ ਦ੍ਰਿਸ਼ ਨਿੱਜੀ ਨਹੀਂ ਹੈ ਤਾਂ ਇਸ 'ਤੇ ਸਾਡੇ ਨਾਲ ਸੰਪਰਕ ਕਰੋ ਜੀ ",
"openIssueMessage_button": "ਬੱਗ ਟਰੈਕਰ।",
"openIssueMessage_post": "ਹੇਠਾਂ ਦਿੱਤੀ ਜਾਣਕਾਰੀ ਨੂੰ ਕਾਪੀ ਕਰਕੇ ਗਿੱਟਹੱਬ ਮੁੱਦੇ ਵਿੱਚ ਪੇਸਟ ਕਰਕੇ ਸ਼ਾਮਲ ਕਰੋ ਜੀ।",
"sceneContent": "ਦ੍ਰਿਸ਼ ਦੀ ਸਮੱਗਰੀ:"
},
"roomDialog": {
"desc_intro": "ਤੁਸੀਂ ਲੋਕਾਂ ਨੂੰ ਆਪਣੇ ਨਾਲ ਮੌਜੂਦਾ ਦ੍ਰਿਸ਼ 'ਤੇ ਸਹਿਯੋਗ ਕਰਨ ਲਈ ਸੱਦਾ ਭੇਜ ਸਕਦੇ ਹੋ।",
"desc_privacy": "ਫਿਕਰ ਨਾ ਕਰੋ, ਇਜਲਾਸ ਸਿਰੇ-ਤੋਂ-ਸਿਰੇ ਤੱਕ ਇਨਕਰਿਪਸ਼ਨ ਵਰਤਦਾ ਹੈ, ਸੋ ਜੋ ਕੁਝ ਵੀ ਤੁਸੀਂ ਵਾਹੁੰਦੇ ਹੋ ਉਹ ਨਿੱਜੀ ਹੀ ਰਹਿੰਦਾ ਹੈ। ਇੱਥੋਂ ਤੱਕ ਕਿ ਸਾਡੇ ਸਰਵਰ ਵੀ ਨਹੀਂ ਜਾਣ ਸਕਣਗੇ ਕਿ ਤੁਸੀਂ ਕੀ ਬਣਾਇਆ ਹੈ।",
"button_startSession": "ਇਜਲਾਸ ਸ਼ੁਰੂ ਕਰੋ",
"button_stopSession": "ਇਜਲਾਸ ਰੋਕੋ",
"desc_inProgressIntro": "ਲਾਇਵ ਸਹਿਯੋਗ ਹੁਣ ਚੱਲ ਰਿਹਾ ਹੈ।",
"desc_shareLink": "ਇਸ ਲਿੰਕ ਨੂੰ ਉਹਨਾਂ ਨਾਲ ਸਾਂਝਾ ਕਰੋ ਜਿਹਨਾਂ ਨਾਲ ਤੁਸੀਂ ਸਹਿਯੋਗ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ:",
"desc_exitSession": "ਇਜਲਾਸ ਨੂੰ ਰੋਕਣਾ ਤੁਹਾਡਾ ਕਮਰੇ ਨਾਲੋਂ ਨਾਤਾ ਤੋੜ ਦੇਵੇਗਾ, ਪਰ ਤੁਸੀਂ ਸਥਾਨਕ ਪੱਧਰ 'ਤੇ ਦ੍ਰਿਸ਼ ਨਾਲ ਕੰਮ ਕਰਨਾ ਜਾਰੀ ਰੱਖ ਸਕੋਗੇ। ਇਹ ਧਿਆਨ 'ਚ ਰੱਖੋ ਕਿ ਇਹ ਬਾਕੀ ਲੋਕਾਂ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਨਹੀਂ ਕਰੇਗਾ , ਅਤੇ ਉਹ ਹਾਲੇ ਵੀ ਆਪਣੇ ਸੰਸਕਰਨ 'ਤੇ ਸਹਿਯੋਗ ਕਰਨ ਦੇ ਕਾਬਲ ਹੋਣਗੇ।"
},
"errorDialog": {
"title": "ਗਲਤੀ"
},
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "ਤੁਹਾਡੀ ਡਰਾਇੰਗਾਂ ਸਿਰੇ-ਤੋਂ-ਸਿਰੇ ਤੱਕ ਇਨਕਰਿਪਟ ਕੀਤੀਆਂ ਹੋਈਆਂ ਹਨ, ਇਸ ਲਈ Excalidraw ਦੇ ਸਰਵਰ ਉਹਨਾਂ ਨੂੰ ਕਦੇ ਵੀ ਨਹੀਂ ਦੇਖਣਗੇ।"
},
"stats": {
"angle": "ਕੋਣ",
"element": "ਐਲੀਮੈਂਟ",
"elements": "ਐਲੀਮੈਂਟ",
"height": "ਉਚਾਈ",
"scene": "ਦ੍ਰਿਸ਼",
"selected": "ਚੁਣੇ",
"storage": "ਸਟੋਰੇਜ",
"title": "ਪੜਾਕੂਆਂ ਲਈ ਅੰਕੜੇ",
"total": "ਕੁੱਲ",
"width": "ਚੌੜਾਈ"
},
"toast": {
"copyStyles": "ਕਾਪੀ ਕੀਤੇ ਸਟਾਇਲ।",
"copyToClipboardAsPng": "ਕਲਿੱਪਬੋਰਡ 'ਤੇ PNG ਵਜੋਂ ਕਾਪੀ ਕੀਤਾ।"
}
}
+23 -22
View File
@@ -1,34 +1,35 @@
{
"ar-SA": 86,
"bg-BG": 60,
"ca-ES": 78,
"ar-SA": 90,
"bg-BG": 90,
"ca-ES": 90,
"de-DE": 100,
"el-GR": 96,
"el-GR": 100,
"en": 100,
"es-ES": 99,
"fa-IR": 86,
"es-ES": 100,
"fa-IR": 90,
"fi-FI": 100,
"fr-FR": 100,
"he-IL": 96,
"hi-IN": 82,
"hu-HU": 92,
"id-ID": 100,
"it-IT": 100,
"ja-JP": 85,
"ko-KR": 67,
"my-MM": 93,
"he-IL": 90,
"hi-IN": 90,
"hu-HU": 90,
"id-ID": 91,
"it-IT": 91,
"ja-JP": 81,
"ko-KR": 90,
"my-MM": 83,
"nb-NO": 100,
"nl-NL": 100,
"nn-NO": 96,
"pl-PL": 95,
"nn-NO": 90,
"pa-IN": 91,
"pl-PL": 90,
"pt-BR": 100,
"pt-PT": 100,
"ro-RO": 100,
"ru-RU": 97,
"sk-SK": 100,
"ru-RU": 91,
"sk-SK": 91,
"sv-SE": 100,
"tr-TR": 87,
"uk-UA": 99,
"zh-CN": 100,
"zh-TW": 99
"tr-TR": 90,
"uk-UA": 100,
"zh-CN": 90,
"zh-TW": 100
}
+39 -32
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Wklej",
"pasteCharts": "Wklej wykresy",
"selectAll": "Zaznacz wszystko",
"multiSelect": "Dodaj element do zaznaczenia",
"moveCanvas": "Przesuń obszar roboczy",
@@ -32,12 +33,12 @@
"arrowheads": "Groty",
"arrowhead_none": "Brak",
"arrowhead_arrow": "Strzałka",
"arrowhead_bar": "",
"arrowhead_bar": "Kreska",
"arrowhead_dot": "Kropka",
"fontSize": "Rozmiar tekstu",
"fontFamily": "Krój pisma",
"onlySelected": "Tylko wybrane",
"withBackground": "",
"withBackground": "Z tłem",
"exportEmbedScene": "Osadź scenę w eksportowanym pliku",
"exportEmbedScene_details": "Dane sceny zostaną zapisane w eksportowanym pliku PNG/SVG tak, aby scena mogła zostać z niego przywrócona.\nZwiększy to rozmiar eksportowanego pliku.",
"addWatermark": "Dodaj \"Zrobione w Excalidraw\"",
@@ -99,7 +100,7 @@
"exportToSvg": "Zapisz jako SVG",
"copyToClipboard": "Skopiuj do schowka",
"copyPngToClipboard": "Skopiuj do schowka jako plik PNG",
"scale": "",
"scale": "Skala",
"save": "Zapisz",
"saveAs": "Zapisz jako",
"load": "Otwórz",
@@ -117,16 +118,16 @@
"redo": "Przywróć",
"roomDialog": "Utwórz nową sesję współpracy na żywo",
"createNewRoom": "Utwórz nowy pokój",
"fullScreen": "",
"darkMode": "",
"lightMode": "",
"zenMode": "",
"fullScreen": "Pełny ekran",
"darkMode": "Ciemny motyw",
"lightMode": "Jasny motyw",
"zenMode": "Tryb Zen",
"exitZenMode": "Wyjdź z trybu Zen"
},
"alerts": {
"clearReset": "To spowoduje usunięcie wszystkiego z dokumentu. Czy chcesz kontynuować?",
"couldNotCreateShareableLink": "Wystąpił błąd przy generowaniu linka do udostępniania.",
"couldNotCreateShareableLinkTooBig": "Nie można utworzyć udostępnialnego linku: scena jest za duża",
"couldNotCreateShareableLinkTooBig": "Nie można utworzyć linku do udostępnienia: scena jest za duża",
"couldNotLoadInvalidFile": "Nie udało się otworzyć pliku. Wybrany plik jest nieprawidłowy.",
"importBackendFailed": "Wystąpił błąd podczas importowania pliku.",
"cannotExportEmptyCanvas": "Najpierw musisz coś narysować, aby zapisać dokument.",
@@ -134,9 +135,9 @@
"decryptFailed": "Nie udało się odszyfrować danych.",
"uploadedSecurly": "By zapewnić Ci prywatność, udostępnianie projektu jest zabezpieczone szyfrowaniem end-to-end, co oznacza, że poza tobą i osobą z którą podzielisz się linkiem, nikt nie ma dostępu do tego co udostępniasz.",
"loadSceneOverridePrompt": "Wczytanie zewnętrznego rysunku zastąpi istniejącą zawartość. Czy chcesz kontynuować?",
"errorLoadingLibrary": "Wystąpił błąd podczas ładowania biblioteki stron trzecich.",
"errorLoadingLibrary": "Wystąpił błąd podczas ładowania zewnętrznej biblioteki.",
"confirmAddLibrary": "To doda {{numShapes}} kształtów do twojej biblioteki. Jesteś pewien?",
"imageDoesNotContainScene": "",
"imageDoesNotContainScene": "Importowanie zdjęć nie jest obecnie obsługiwane.\n\nCzy chciałeś zaimportować scenę? Ten obraz nie zawiera żadnych danych sceny. Czy włączyłeś to podczas eksportowania?",
"cannotRestoreFromImage": "Scena nie mogła zostać przywrócona z pliku obrazu"
},
"toolBar": {
@@ -161,7 +162,7 @@
"freeDraw": "Naciśnij i przeciągnij by rysować, puść kiedy skończysz",
"text": "Wskazówka: możesz również dodać tekst klikając dwukrotnie gdziekolwiek za pomocą narzędzia zaznaczania",
"linearElementMulti": "Aby zakończyć krzywą, ponownie kliknij w ostatni punkt, bądź naciśnij Esc albo Enter",
"lockAngle": "",
"lockAngle": "Możesz ograniczyć kąt trzymając SHIFT",
"resize": "Możesz zachować proporcję trzymająć wcisnięty SHIFT, przytrzymaj ALT by zmienić rozmiar względem środka",
"rotate": "Możesz obracać element w równych odstępach trzymając wciśnięty SHIFT",
"lineEditor_info": "Kliknij dwukrotnie lub naciśnij Enter, aby edytować punkty",
@@ -169,8 +170,8 @@
"lineEditor_nothingSelected": "Naciśnij w punkt by go edytować, przytrzymaj Alt i naciśnij by dodać nowy punkt"
},
"canvasError": {
"cannotShowPreview": "Nie można pokazać podglądu",
"canvasTooBig": "Płótno może być za duże.",
"cannotShowPreview": "Nie można wyświetlić podglądu",
"canvasTooBig": "Obszar roboczy może być za duży.",
"canvasTooBigTip": "Wskazówka: spróbuj nieco zbliżyć najdalej wysunięte elementy."
},
"errorSplash": {
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Wystąpił błąd"
},
"shortcutsDialog": {
"title": "Skróty klawiszowe",
"shapes": "Kształty",
"or": "lub",
"click": "klik",
"drag": "przeciągnij",
"curvedArrow": "Zakrzywiona strzałka",
"curvedLine": "Zakrzywiona linia",
"editor": "Edytor",
"view": "Widok",
"blog": "Przeczytaj naszego bloga",
"howto": "Skorzystaj z instrukcji",
"github": "Znalazłeś problem? Zgłoś go",
"textNewLine": "Dodaj nową linię (tekst)",
"textFinish": "Zakończ edycję (tekst)",
"zoomToFit": "Powiększ, aby wyświetlić wszystkie elementy",
"zoomToSelection": "Przybliż zaznaczenie",
"preventBinding": "Zablokuj przywiązanie strzałek do obiektu"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "Twoje rysunki są zabezpieczone szyfrowaniem end-to-end, tak więc nawet w Excalidraw nie jesteśmy w stanie zobaczyć tego co tworzysz."
@@ -229,7 +232,11 @@
"selected": "Zaznaczenie",
"storage": "Pamięć",
"title": "Statystyki dla nerdów",
"total": "Suma",
"total": "Łącznie",
"width": "Szerokość"
},
"toast": {
"copyStyles": "",
"copyToClipboardAsPng": ""
}
}
+19 -12
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Colar",
"pasteCharts": "Colar gráficos",
"selectAll": "Selecionar tudo",
"multiSelect": "Adicionar elemento à seleção",
"moveCanvas": "Mover tela",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Erro"
},
"shortcutsDialog": {
"title": "Atalhos de teclado",
"shapes": "Formas",
"or": "ou",
"helpDialog": {
"blog": "Leia o nosso blog",
"click": "clicar",
"drag": "arrastar",
"curvedArrow": "Seta curva",
"curvedLine": "Linha curva",
"documentation": "Documentação",
"drag": "arrastar",
"editor": "Editor",
"view": "Visualizar",
"blog": "Leia o nosso blog",
"howto": "Siga os nossos guias",
"github": "Encontrou algum problema? Nos informe",
"textNewLine": "Adicionar nova linha (texto)",
"howto": "Siga nossos guias",
"or": "ou",
"preventBinding": "Evitar fixação de seta",
"shapes": "Formas",
"shortcuts": "Atalhos de teclado",
"textFinish": "Finalizar edição (texto)",
"zoomToFit": "Ajustar para caber todos os elementos",
"zoomToSelection": "Ampliar a seleção",
"preventBinding": "Prevenir fixação de seta"
"textNewLine": "Adicionar nova linha (texto)",
"title": "Ajudar",
"view": "Visualizar",
"zoomToFit": "Ampliar para encaixar todos os elementos",
"zoomToSelection": "Ampliar a seleção"
},
"encrypted": {
"tooltip": "Seus desenhos são criptografados de ponta a ponta, então os servidores do Excalidraw nunca os verão."
@@ -231,5 +234,9 @@
"title": "Estatísticas para nerds",
"total": "Total",
"width": "Largura"
},
"toast": {
"copyStyles": "Estilos copiados.",
"copyToClipboardAsPng": "Copiado para a área de transferência como PNG."
}
}
+18 -11
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Colar",
"pasteCharts": "Colar gráficos",
"selectAll": "Selecionar tudo",
"multiSelect": "Adicionar elemento à seleção",
"moveCanvas": "Mover tela",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Erro"
},
"shortcutsDialog": {
"title": "Atalhos de teclado",
"shapes": "Formas",
"or": "ou",
"helpDialog": {
"blog": "Leia o nosso blog",
"click": "clicar",
"drag": "arrastar",
"curvedArrow": "Seta curva",
"curvedLine": "Linha curva",
"documentation": "Documentação",
"drag": "arrastar",
"editor": "Editor",
"view": "Visualizar",
"blog": "Leia o nosso blog",
"howto": "Siga os nossos guias",
"github": "Encontrou algum problema? Nos informe",
"textNewLine": "Adicionar nova linha (texto)",
"howto": "Siga os nossos guias",
"or": "ou",
"preventBinding": "Prevenir fixação de seta",
"shapes": "Formas",
"shortcuts": "Atalhos de teclado",
"textFinish": "Finalizar edição (texto)",
"textNewLine": "Adicionar nova linha (texto)",
"title": "Ajuda",
"view": "Visualizar",
"zoomToFit": "Ajustar para caber todos os elementos",
"zoomToSelection": "Ampliar a seleção",
"preventBinding": "Prevenir fixação de seta"
"zoomToSelection": "Ampliar a seleção"
},
"encrypted": {
"tooltip": "Seus desenhos são criptografados de ponta a ponta, então os servidores do Excalidraw nunca os verão."
@@ -231,5 +234,9 @@
"title": "Estatísticas para nerds",
"total": "Total",
"width": "Largura"
},
"toast": {
"copyStyles": "Estilos copiados.",
"copyToClipboardAsPng": "Copiado para o clipboard como PNG."
}
}
+19 -12
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Lipire",
"pasteCharts": "Lipire diagrame",
"selectAll": "Selectare totală",
"multiSelect": "Adaugă element la selecție",
"moveCanvas": "Mutare pânză",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Eroare"
},
"shortcutsDialog": {
"title": "Comenzi rapide de la tastatură",
"shapes": "Forme",
"or": "sau",
"helpDialog": {
"blog": "Citește blogul nostru",
"click": "clic",
"drag": "glisare",
"curvedArrow": "Săgeată curbată",
"curvedLine": "Linie curbată",
"documentation": "Documentație",
"drag": "glisare",
"editor": "Editor",
"view": "Vizualizare",
"blog": "Citește blogul nostru",
"howto": "Urmărește ghidurile noastre",
"github": "Ai întâmpinat o problemă? Trimite un raport",
"textNewLine": "Adaugă o linie nouă (text)",
"howto": "Urmărește ghidurile noastre",
"or": "sau",
"preventBinding": "Împiedică legarea săgeții",
"shapes": "Forme",
"shortcuts": "Comenzi rapide de la tastatură",
"textFinish": "Finalizează editarea (text)",
"zoomToFit": "Apropiere/depărtare pentru a cuprinde totul",
"zoomToSelection": "Panoramare la selecție",
"preventBinding": "Împiedică legarea săgeții"
"textNewLine": "Adaugă o linie nouă (text)",
"title": "Ajutor",
"view": "Vizualizare",
"zoomToFit": "Panoramare pentru a cuprinde totul",
"zoomToSelection": "Panoramare la selecție"
},
"encrypted": {
"tooltip": "Desenele tale sunt criptate integral, astfel că serverele Excalidraw nu le vor vedea niciodată."
@@ -231,5 +234,9 @@
"title": "Statistici pentru pasionați",
"total": "Total",
"width": "Lățime"
},
"toast": {
"copyStyles": "Stiluri copiate.",
"copyToClipboardAsPng": "Copiat în memoria temporară ca PNG."
}
}
+42 -35
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Вставить",
"pasteCharts": "Вставить диаграммы",
"selectAll": "Выбрать все",
"multiSelect": "Добавить элемент в выделенный фрагмент",
"moveCanvas": "Переместить холст",
@@ -21,8 +22,8 @@
"strokeWidth": "Толщина штриха",
"strokeStyle": "Стиль обводки",
"strokeStyle_solid": "Сплошная",
"strokeStyle_dashed": "Штриховая",
"strokeStyle_dotted": "Пунктирная",
"strokeStyle_dashed": "Пунктирная",
"strokeStyle_dotted": "Точечная",
"sloppiness": "Стиль обводки",
"opacity": "Непрозрачность",
"textAlign": "Выравнивание текста",
@@ -30,9 +31,9 @@
"sharp": "Острые",
"round": "Скругленные",
"arrowheads": "Стрелка",
"arrowhead_none": "Без стрелки",
"arrowhead_none": "Нет",
"arrowhead_arrow": "Cтрелка",
"arrowhead_bar": "Столбец",
"arrowhead_bar": "Черта",
"arrowhead_dot": "Точка",
"fontSize": "Размер шрифта",
"fontFamily": "Семейство шрифтов",
@@ -40,8 +41,8 @@
"withBackground": "С фоном",
"exportEmbedScene": "Встроить информацию о сцене в экспортируемый файл",
"exportEmbedScene_details": "Сцена будет сохранена в PNG/SVG файл так, чтобы всю сцену можно будет восстановить из этого файла. Это увеличит размер файла.",
"addWatermark": "Добавить \"Сделано с Excalidraw\"",
"handDrawn": "Нарисованный от руки",
"addWatermark": "Добавить «Создано в Excalidraw»",
"handDrawn": "От руки",
"normal": "Обычный",
"code": "Код",
"small": "Малый",
@@ -63,20 +64,20 @@
"fileTitle": "Название файла",
"colorPicker": "Выбор цвета",
"canvasBackground": "Фон холста",
"drawingCanvas": "Холст для рисования",
"drawingCanvas": "Полотно",
"layers": "Слои",
"actions": "Действия",
"language": "Язык",
"createRoom": "Создать многопользовательскую сессию",
"createRoom": "Начать сеанс совместной работы",
"duplicateSelection": "Дубликат",
"untitled": "Без названия",
"untitled": "Безымянный",
"name": "Имя",
"yourName": "Ваше имя",
"madeWithExcalidraw": "Сделано в Excalidraw",
"group": "Сгруппировать выделение",
"ungroup": "Разделить выделение",
"collaborators": "Участники",
"gridMode": "",
"gridMode": "Сетка",
"addToLibrary": "Добавить в библиотеку",
"removeFromLibrary": "Удалить из библиотеки",
"libraryLoadingMessage": "Загрузка библиотеки...",
@@ -118,9 +119,9 @@
"roomDialog": "Начать совместную работу",
"createNewRoom": "Создать новую комнату",
"fullScreen": "Полный экран",
"darkMode": "",
"lightMode": "",
"zenMode": "",
"darkMode": "Темная тема",
"lightMode": "Светлая тема",
"zenMode": "Режим Дзен",
"exitZenMode": "Выключить режим концентрации внимания"
},
"alerts": {
@@ -136,7 +137,7 @@
"loadSceneOverridePrompt": "Загрузка рисунка приведёт к замене имеющегося содержимого. Вы хотите продолжить?",
"errorLoadingLibrary": "Произошла ошибка при загрузке сторонней библиотеки.",
"confirmAddLibrary": "Будет добавлено {{numShapes}} фигур в вашу библиотеку. Продолжить?",
"imageDoesNotContainScene": "",
"imageDoesNotContainScene": "Импорт изображений не поддерживается в данный момент.\n\nХотите импортировать сцену? Данное изображение не содержит данных о сцене. Было ли включено это во время экспорта?",
"cannotRestoreFromImage": "Сцена не может быть восстановлена из этого изображения"
},
"toolBar": {
@@ -161,7 +162,7 @@
"freeDraw": "Нажмите и перетаскивайте, отпустите по завершении",
"text": "Совет: при выбранном инструменте выделения дважды щёлкните в любом месте, чтобы добавить текст",
"linearElementMulti": "Кликните на последней точке или нажмите Escape или Enter чтобы закончить",
"lockAngle": "",
"lockAngle": "Вы можете ограничить угол удерживая SHIFT",
"resize": "Вы можете ограничить пропорции, удерживая SHIFT во время изменения размеров,\nудерживайте ALT чтобы изменить размер из центра",
"rotate": "Вы можете ограничить углы, удерживая SHIFT во время вращения",
"lineEditor_info": "Дважды кликните или нажмите Enter, чтобы редактировать точки",
@@ -188,34 +189,36 @@
},
"roomDialog": {
"desc_intro": "Вы можете пригласить людей в текущую сцену для совместной работы.",
"desc_privacy": "Не беспокойтесь, сессия использует сквозное шифрование, поэтому всё что вы нарисуете останется приватным. Ваша информация не будет доступна даже на наших серверах.",
"desc_privacy": "Не беспокойтесь — во время сеанса используется сквозное шифрование. Всё, что вы нарисуете, останется конфиденциальным и не будет доступно даже нашему серверу.",
"button_startSession": "Начать сеанс",
"button_stopSession": "Завершить сеанс",
"desc_inProgressIntro": "Совместная сессия теперь активна.",
"desc_inProgressIntro": "Сеанс совместной работы запущен.",
"desc_shareLink": "Поделитесь этой ссылкой со всеми участниками:",
"desc_exitSession": "Завершив сеанс, вы выйдете из комнаты, но сможете продолжить работать с документом локально. Это не повлияет на работу других пользователей — они смогут продолжить совместную работу с их версией документа."
},
"errorDialog": {
"title": "Ошибка"
},
"shortcutsDialog": {
"title": "Сочетания клавиш",
"shapes": "Фигуры",
"or": "или",
"click": "нажать",
"drag": "перетащить",
"curvedArrow": "Изогнутая стрелка",
"curvedLine": "Изогнутая линия",
"editor": "Редактор",
"view": "Просмотр",
"blog": "Прочитайте наш блог",
"howto": "Следуйте нашим инструкциям",
"github": "Нашли проблему? Отправьте",
"textNewLine": "Добавить новую строку (текст)",
"textFinish": "Закончить редактирование (текст)",
"zoomToFit": "Отмастштабировать, чтобы поместились все элементы",
"zoomToSelection": "Перейти к выделенному",
"preventBinding": "Предотвратить привязку стрелок"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "Ваши данные защищены сквозным (End-to-end) шифрованием. Серверы Excalidraw никогда не получат доступ к ним."
@@ -231,5 +234,9 @@
"title": "Статистика для ботаников",
"total": "Всего",
"width": "Ширина"
},
"toast": {
"copyStyles": "Скопированы стили.",
"copyToClipboardAsPng": "Скопировано в буфер обмена в формате PNG."
}
}
+26 -19
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Vložiť",
"pasteCharts": "Vložiť grafy",
"selectAll": "Vybrať všetko",
"multiSelect": "Pridať prvok do výberu",
"moveCanvas": "Pohyb plátna",
@@ -14,7 +15,7 @@
"sendBackward": "Presunúť o úroveň dozadu",
"delete": "Vymazať",
"copyStyles": "Kopírovať štýly",
"pasteStyles": "Prilepiť štýly",
"pasteStyles": "Vložiť štýly",
"stroke": "Obrys",
"background": "Pozadie",
"fill": "Výplň",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Chyba"
},
"shortcutsDialog": {
"title": "Klávesové skratky",
"shapes": "Tvary",
"or": "alebo",
"click": "kliknutie",
"drag": "potiahnutie",
"curvedArrow": "Zakrivená šípka",
"curvedLine": "Zakrivená čiara",
"editor": "Editovanie",
"view": "Zobrazenie",
"blog": "Prečítajte si náš blog",
"howto": "Postupujte podľa naších návodov",
"github": "Objavili ste problém? Nahláste ho",
"textNewLine": "Vložiť nový riadok (text)",
"textFinish": "Ukončenie editovania (text)",
"zoomToFit": "Priblížiť aby boli zahrnuté všetky prvky",
"zoomToSelection": "Priblížiť na výber",
"preventBinding": "Zakázať pripájanie šípky"
"helpDialog": {
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "",
"editor": "",
"github": "",
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "Vaše kresby používajú end-to-end šifrovanie, takže ich Excalidraw server nedokáže prečítať."
@@ -231,5 +234,9 @@
"title": "Štatistiky",
"total": "Celkom",
"width": "Šírka"
},
"toast": {
"copyStyles": "Štýly skopírované.",
"copyToClipboardAsPng": "Skopírované do schránky ako PNG."
}
}
+18 -11
View File
@@ -1,6 +1,7 @@
{
"labels": {
"paste": "Klistra in",
"pasteCharts": "Klistra in diagram",
"selectAll": "Markera alla",
"multiSelect": "Lägg till element till markering",
"moveCanvas": "Flytta canvas",
@@ -198,24 +199,26 @@
"errorDialog": {
"title": "Fel"
},
"shortcutsDialog": {
"title": "Tangentbordsgenvägar",
"shapes": "Former",
"or": "eller",
"helpDialog": {
"blog": "Läs vår blogg",
"click": "klicka",
"drag": "dra",
"curvedArrow": "Böjd pil",
"curvedLine": "Böjd linje",
"documentation": "Dokumentation",
"drag": "dra",
"editor": "Redigerare",
"view": "Visa",
"blog": "Läs vår blogg",
"howto": "Följ våra guider",
"github": "Hittat ett problem? Rapportera",
"textNewLine": "Lägg till ny rad (text)",
"howto": "Följ våra guider",
"or": "eller",
"preventBinding": "Förhindra pilbindning",
"shapes": "Former",
"shortcuts": "Tangentbordsgenvägar",
"textFinish": "Slutför redigering (text)",
"textNewLine": "Lägg till ny rad (text)",
"title": "Hjälp",
"view": "Visa",
"zoomToFit": "Zooma för att rymma alla element",
"zoomToSelection": "Zooma till markering",
"preventBinding": "Förhindra pilbindning"
"zoomToSelection": "Zooma till markering"
},
"encrypted": {
"tooltip": "Dina skisser är krypterade från ände till ände så Excalidraws servrar kommer aldrig att se dem."
@@ -231,5 +234,9 @@
"title": "Statistik för nördar",
"total": "Totalt",
"width": "Bredd"
},
"toast": {
"copyStyles": "Kopierade stilar.",
"copyToClipboardAsPng": "Kopierat till urklipp som PNG."
}
}

Some files were not shown because too many files have changed in this diff Show More