Compare commits

..
Author SHA1 Message Date
Zsolt Viczian e4b17e77f8 publish handleLinkNavigation to app props 2022-02-03 19:18:09 +01:00
88 changed files with 780 additions and 2110 deletions
@@ -23,5 +23,4 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Auto release - name: Auto release
run: | run: |
yarn add @actions/core
yarn autorelease yarn autorelease
-55
View File
@@ -1,55 +0,0 @@
name: Auto release preview @excalidraw/excalidraw-preview
on:
issue_comment:
types: [created, edited]
jobs:
Auto-release-excalidraw-preview:
name: Auto release preview
if: github.event.comment.body == '@excalibot release package' && github.event.issue.pull_request
runs-on: ubuntu-latest
steps:
- name: React to release comment
uses: peter-evans/create-or-update-comment@v1
with:
token: ${{ secrets.PUSH_TRANSLATIONS_COVERAGE_PAT }}
comment-id: ${{ github.event.comment.id }}
reactions: "+1"
- name: Get PR SHA
id: sha
uses: actions/github-script@v4
with:
result-encoding: string
script: |
const { owner, repo, number } = context.issue;
const pr = await github.pulls.get({
owner,
repo,
pull_number: number,
});
return pr.data.head.sha
- uses: actions/checkout@v2
with:
ref: ${{ steps.sha.outputs.result }}
fetch-depth: 2
- name: Setup Node.js 14.x
uses: actions/setup-node@v2
with:
node-version: 14.x
- name: Set up publish access
run: |
npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Auto release preview
id: "autorelease"
run: |
yarn add @actions/core
yarn autorelease preview ${{ github.event.issue.number }}
- name: Post comment post release
if: always()
uses: peter-evans/create-or-update-comment@v1
with:
token: ${{ secrets.PUSH_TRANSLATIONS_COVERAGE_PAT }}
issue-number: ${{ github.event.issue.number }}
body: "@${{ github.event.comment.user.login }} ${{ steps.autorelease.outputs.result }}"
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
- name: Setup Node.js 14.x - name: Setup Node.js 14.x
uses: actions/setup-node@v2 uses: actions/setup-node@v2
with: with:
node-version: 14.x node-version: 16.x
- name: Install and test - name: Install and test
run: | run: |
yarn --frozen-lockfile yarn --frozen-lockfile
-4
View File
@@ -23,7 +23,3 @@ static
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
src/packages/excalidraw/types src/packages/excalidraw/types
src/packages/excalidraw/example/public/bundle.js
src/packages/excalidraw/example/public/excalidraw-assets-dev
src/packages/excalidraw/example/public/excalidraw.development.js
+7 -7
View File
@@ -21,12 +21,12 @@
"dependencies": { "dependencies": {
"@sentry/browser": "6.2.5", "@sentry/browser": "6.2.5",
"@sentry/integrations": "6.2.5", "@sentry/integrations": "6.2.5",
"@testing-library/jest-dom": "5.16.2", "@testing-library/jest-dom": "5.16.1",
"@testing-library/react": "12.1.2", "@testing-library/react": "12.1.2",
"@tldraw/vec": "1.4.3", "@tldraw/vec": "1.4.3",
"@types/jest": "27.4.0", "@types/jest": "27.4.0",
"@types/pica": "5.1.3", "@types/pica": "5.1.3",
"@types/react": "17.0.39", "@types/react": "17.0.38",
"@types/react-dom": "17.0.11", "@types/react-dom": "17.0.11",
"@types/socket.io-client": "1.4.36", "@types/socket.io-client": "1.4.36",
"browser-fs-access": "0.23.0", "browser-fs-access": "0.23.0",
@@ -50,9 +50,9 @@
"react-dom": "17.0.2", "react-dom": "17.0.2",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
"roughjs": "4.5.2", "roughjs": "4.5.2",
"sass": "1.49.7", "sass": "1.47.0",
"socket.io-client": "2.3.1", "socket.io-client": "2.3.1",
"typescript": "4.5.5" "typescript": "4.5.4"
}, },
"devDependencies": { "devDependencies": {
"@excalidraw/eslint-config": "1.0.0", "@excalidraw/eslint-config": "1.0.0",
@@ -61,20 +61,20 @@
"@types/lodash.throttle": "4.1.6", "@types/lodash.throttle": "4.1.6",
"@types/pako": "1.0.3", "@types/pako": "1.0.3",
"@types/resize-observer-browser": "0.1.6", "@types/resize-observer-browser": "0.1.6",
"chai": "4.3.6", "chai": "4.3.4",
"dotenv": "10.0.0", "dotenv": "10.0.0",
"eslint-config-prettier": "8.3.0", "eslint-config-prettier": "8.3.0",
"eslint-plugin-prettier": "3.3.1", "eslint-plugin-prettier": "3.3.1",
"firebase-tools": "9.23.0", "firebase-tools": "9.23.0",
"husky": "7.0.4", "husky": "7.0.4",
"jest-canvas-mock": "2.3.1", "jest-canvas-mock": "2.3.1",
"lint-staged": "12.3.3", "lint-staged": "12.1.7",
"pepjs": "0.5.3", "pepjs": "0.5.3",
"prettier": "2.5.1", "prettier": "2.5.1",
"rewire": "5.0.0" "rewire": "5.0.0"
}, },
"resolutions": { "resolutions": {
"@typescript-eslint/typescript-estree": "5.10.2" "@typescript-eslint/typescript-estree": "5.3.0"
}, },
"engines": { "engines": {
"node": ">=14.0.0" "node": ">=14.0.0"
+5 -30
View File
@@ -1,6 +1,5 @@
const fs = require("fs"); const fs = require("fs");
const { exec, execSync } = require("child_process"); const { exec, execSync } = require("child_process");
const core = require("@actions/core");
const excalidrawDir = `${__dirname}/../src/packages/excalidraw`; const excalidrawDir = `${__dirname}/../src/packages/excalidraw`;
const excalidrawPackage = `${excalidrawDir}/package.json`; const excalidrawPackage = `${excalidrawDir}/package.json`;
@@ -16,25 +15,18 @@ const publish = () => {
execSync(`yarn --frozen-lockfile`, { cwd: excalidrawDir }); execSync(`yarn --frozen-lockfile`, { cwd: excalidrawDir });
execSync(`yarn run build:umd`, { cwd: excalidrawDir }); execSync(`yarn run build:umd`, { cwd: excalidrawDir });
execSync(`yarn --cwd ${excalidrawDir} publish`); execSync(`yarn --cwd ${excalidrawDir} publish`);
console.info("Published 🎉");
core.setOutput(
"result",
`**Preview version has been shipped** :rocket:
You can use [@excalidraw/excalidraw-preview@${pkg.version}](https://www.npmjs.com/package/@excalidraw/excalidraw-preview/v/${pkg.version}) for testing!`,
);
} catch (error) { } catch (error) {
core.setOutput("result", "package couldn't be published :warning:!");
console.error(error); console.error(error);
process.exit(1);
} }
}; };
// get files changed between prev and head commit // get files changed between prev and head commit
exec(`git diff --name-only HEAD^ HEAD`, async (error, stdout, stderr) => { exec(`git diff --name-only HEAD^ HEAD`, async (error, stdout, stderr) => {
if (error || stderr) { if (error || stderr) {
console.error(error); console.error(error);
core.setOutput("result", ":warning: Package couldn't be published!");
process.exit(1); process.exit(1);
} }
const changedFiles = stdout.trim().split("\n"); const changedFiles = stdout.trim().split("\n");
const filesToIgnoreRegex = /src\/excalidraw-app|packages\/utils/; const filesToIgnoreRegex = /src\/excalidraw-app|packages\/utils/;
@@ -45,33 +37,16 @@ exec(`git diff --name-only HEAD^ HEAD`, async (error, stdout, stderr) => {
); );
}); });
if (!excalidrawPackageFiles.length) { if (!excalidrawPackageFiles.length) {
console.info("Skipping release as no valid diff found");
core.setOutput("result", "Skipping release as no valid diff found");
process.exit(0); process.exit(0);
} }
// update package.json // update package.json
pkg.version = `${pkg.version}-${getShortCommitHash()}`;
pkg.name = "@excalidraw/excalidraw-next"; pkg.name = "@excalidraw/excalidraw-next";
let version = `${pkg.version}-${getShortCommitHash()}`;
// update readme
let data = fs.readFileSync(`${excalidrawDir}/README_NEXT.md`, "utf8");
const isPreview = process.argv.slice(2)[0] === "preview";
if (isPreview) {
// use pullNumber-commithash as the version for preview
const pullRequestNumber = process.argv.slice(3)[0];
version = `${pkg.version}-${pullRequestNumber}-${getShortCommitHash()}`;
// replace "excalidraw-next" with "excalidraw-preview"
pkg.name = "@excalidraw/excalidraw-preview";
data = data.replace(/excalidraw-next/g, "excalidraw-preview");
data = data.trim();
}
pkg.version = version;
fs.writeFileSync(excalidrawPackage, JSON.stringify(pkg, null, 2), "utf8"); fs.writeFileSync(excalidrawPackage, JSON.stringify(pkg, null, 2), "utf8");
// update readme
const data = fs.readFileSync(`${excalidrawDir}/README_NEXT.md`, "utf8");
fs.writeFileSync(`${excalidrawDir}/README.md`, data, "utf8"); fs.writeFileSync(`${excalidrawDir}/README.md`, data, "utf8");
console.info("Publish in progress...");
publish(); publish();
}); });
+11 -18
View File
@@ -20,7 +20,7 @@ const headerForType = {
perf: "Performance", perf: "Performance",
build: "Build", build: "Build",
}; };
const badCommits = [];
const getCommitHashForLastVersion = async () => { const getCommitHashForLastVersion = async () => {
try { try {
const commitMessage = `"release @excalidraw/excalidraw@${lastVersion}"`; const commitMessage = `"release @excalidraw/excalidraw@${lastVersion}"`;
@@ -53,26 +53,19 @@ const getLibraryCommitsSinceLastRelease = async () => {
const messageWithoutType = commit.slice(indexOfColon + 1).trim(); const messageWithoutType = commit.slice(indexOfColon + 1).trim();
const messageWithCapitalizeFirst = const messageWithCapitalizeFirst =
messageWithoutType.charAt(0).toUpperCase() + messageWithoutType.slice(1); messageWithoutType.charAt(0).toUpperCase() + messageWithoutType.slice(1);
const prMatch = commit.match(/\(#([0-9]*)\)/); const prNumber = commit.match(/\(#([0-9]*)\)/)[1];
if (prMatch) {
const prNumber = prMatch[1];
// return if the changelog already contains the pr number which would happen for package updates // return if the changelog already contains the pr number which would happen for package updates
if (existingChangeLog.includes(prNumber)) { if (existingChangeLog.includes(prNumber)) {
return; return;
}
const prMarkdown = `[#${prNumber}](https://github.com/excalidraw/excalidraw/pull/${prNumber})`;
const messageWithPRLink = messageWithCapitalizeFirst.replace(
/\(#[0-9]*\)/,
prMarkdown,
);
commitList[type].push(messageWithPRLink);
} else {
badCommits.push(commit);
commitList[type].push(messageWithCapitalizeFirst);
} }
const prMarkdown = `[#${prNumber}](https://github.com/excalidraw/excalidraw/pull/${prNumber})`;
const messageWithPRLink = messageWithCapitalizeFirst.replace(
/\(#[0-9]*\)/,
prMarkdown,
);
commitList[type].push(messageWithPRLink);
}); });
console.info("Bad commits:", badCommits);
return commitList; return commitList;
}; };
-2
View File
@@ -65,8 +65,6 @@ export const actionClearCanvas = register({
gridSize: appState.gridSize, gridSize: appState.gridSize,
showStats: appState.showStats, showStats: appState.showStats,
pasteDialog: appState.pasteDialog, pasteDialog: appState.pasteDialog,
elementType:
appState.elementType === "image" ? "selection" : appState.elementType,
}, },
commitToHistory: true, commitToHistory: true,
}; };
+2 -7
View File
@@ -145,7 +145,6 @@ const changeFontSize = (
elements: readonly ExcalidrawElement[], elements: readonly ExcalidrawElement[],
appState: AppState, appState: AppState,
getNewFontSize: (element: ExcalidrawTextElement) => number, getNewFontSize: (element: ExcalidrawTextElement) => number,
fallbackValue?: ExcalidrawTextElement["fontSize"],
) => { ) => {
const newFontSizes = new Set<number>(); const newFontSizes = new Set<number>();
@@ -183,7 +182,7 @@ const changeFontSize = (
currentItemFontSize: currentItemFontSize:
newFontSizes.size === 1 newFontSizes.size === 1
? [...newFontSizes][0] ? [...newFontSizes][0]
: fallbackValue ?? appState.currentItemFontSize, : appState.currentItemFontSize,
}, },
commitToHistory: true, commitToHistory: true,
}; };
@@ -521,7 +520,7 @@ export const actionChangeOpacity = register({
export const actionChangeFontSize = register({ export const actionChangeFontSize = register({
name: "changeFontSize", name: "changeFontSize",
perform: (elements, appState, value) => { perform: (elements, appState, value) => {
return changeFontSize(elements, appState, () => value, value); return changeFontSize(elements, appState, () => value);
}, },
PanelComponent: ({ elements, appState, updateData }) => ( PanelComponent: ({ elements, appState, updateData }) => (
<fieldset> <fieldset>
@@ -533,25 +532,21 @@ export const actionChangeFontSize = register({
value: 16, value: 16,
text: t("labels.small"), text: t("labels.small"),
icon: <FontSizeSmallIcon theme={appState.theme} />, icon: <FontSizeSmallIcon theme={appState.theme} />,
testId: "fontSize-small",
}, },
{ {
value: 20, value: 20,
text: t("labels.medium"), text: t("labels.medium"),
icon: <FontSizeMediumIcon theme={appState.theme} />, icon: <FontSizeMediumIcon theme={appState.theme} />,
testId: "fontSize-medium",
}, },
{ {
value: 28, value: 28,
text: t("labels.large"), text: t("labels.large"),
icon: <FontSizeLargeIcon theme={appState.theme} />, icon: <FontSizeLargeIcon theme={appState.theme} />,
testId: "fontSize-large",
}, },
{ {
value: 36, value: 36,
text: t("labels.veryLarge"), text: t("labels.veryLarge"),
icon: <FontSizeExtraLargeIcon theme={appState.theme} />, icon: <FontSizeExtraLargeIcon theme={appState.theme} />,
testId: "fontSize-veryLarge",
}, },
]} ]}
value={getFormValue( value={getFormValue(
+3 -3
View File
@@ -150,12 +150,12 @@ export const SelectedShapeActions = ({
</div> </div>
</fieldset> </fieldset>
)} )}
{!isEditing && targetElements.length > 0 && ( {!isMobile && !isEditing && targetElements.length > 0 && (
<fieldset> <fieldset>
<legend>{t("labels.actions")}</legend> <legend>{t("labels.actions")}</legend>
<div className="buttonList"> <div className="buttonList">
{!isMobile && renderAction("duplicateSelection")} {renderAction("duplicateSelection")}
{!isMobile && renderAction("deleteSelectedElements")} {renderAction("deleteSelectedElements")}
{renderAction("group")} {renderAction("group")}
{renderAction("ungroup")} {renderAction("ungroup")}
{targetElements.length === 1 && renderAction("link")} {targetElements.length === 1 && renderAction("link")}
+63 -138
View File
@@ -115,7 +115,11 @@ import {
updateBoundElements, updateBoundElements,
} from "../element/binding"; } from "../element/binding";
import { LinearElementEditor } from "../element/linearElementEditor"; import { LinearElementEditor } from "../element/linearElementEditor";
import { mutateElement, newElementWith } from "../element/mutateElement"; import {
bumpVersion,
mutateElement,
newElementWith,
} from "../element/mutateElement";
import { deepCopyElement, newFreeDrawElement } from "../element/newElement"; import { deepCopyElement, newFreeDrawElement } from "../element/newElement";
import { import {
hasBoundTextElement, hasBoundTextElement,
@@ -159,7 +163,6 @@ import {
shouldRotateWithDiscreteAngle, shouldRotateWithDiscreteAngle,
isArrowKey, isArrowKey,
KEYS, KEYS,
isAndroid,
} from "../keys"; } from "../keys";
import { distance2d, getGridPoint, isPathALoop } from "../math"; import { distance2d, getGridPoint, isPathALoop } from "../math";
import { renderScene } from "../renderer"; import { renderScene } from "../renderer";
@@ -209,8 +212,6 @@ import {
tupleToCoors, tupleToCoors,
viewportCoordsToSceneCoords, viewportCoordsToSceneCoords,
withBatchedUpdates, withBatchedUpdates,
wrapEvent,
withBatchedUpdatesThrottled,
} from "../utils"; } from "../utils";
import ContextMenu, { ContextMenuOption } from "./ContextMenu"; import ContextMenu, { ContextMenuOption } from "./ContextMenu";
import LayerUI from "./LayerUI"; import LayerUI from "./LayerUI";
@@ -414,7 +415,7 @@ class App extends React.Component<AppProps, AppState> {
ref={this.handleCanvasRef} ref={this.handleCanvasRef}
onContextMenu={this.handleCanvasContextMenu} onContextMenu={this.handleCanvasContextMenu}
onPointerMove={this.handleCanvasPointerMove} onPointerMove={this.handleCanvasPointerMove}
onPointerUp={this.handleCanvasPointerUp} onPointerUp={this.removePointer}
onPointerCancel={this.removePointer} onPointerCancel={this.removePointer}
onTouchMove={this.handleTouchMove} onTouchMove={this.handleTouchMove}
onPointerDown={this.handleCanvasPointerDown} onPointerDown={this.handleCanvasPointerDown}
@@ -437,7 +438,7 @@ class App extends React.Component<AppProps, AppState> {
onPointerDown={this.handleCanvasPointerDown} onPointerDown={this.handleCanvasPointerDown}
onDoubleClick={this.handleCanvasDoubleClick} onDoubleClick={this.handleCanvasDoubleClick}
onPointerMove={this.handleCanvasPointerMove} onPointerMove={this.handleCanvasPointerMove}
onPointerUp={this.handleCanvasPointerUp} onPointerUp={this.removePointer}
onPointerCancel={this.removePointer} onPointerCancel={this.removePointer}
onTouchMove={this.handleTouchMove} onTouchMove={this.handleTouchMove}
> >
@@ -523,7 +524,6 @@ class App extends React.Component<AppProps, AppState> {
element={selectedElement[0]} element={selectedElement[0]}
appState={this.state} appState={this.state}
setAppState={this.setAppState} setAppState={this.setAppState}
onLinkOpen={this.props.onLinkOpen}
/> />
)} )}
{this.state.showStats && ( {this.state.showStats && (
@@ -1272,12 +1272,6 @@ class App extends React.Component<AppProps, AppState> {
} }
private onTapStart = (event: TouchEvent) => { private onTapStart = (event: TouchEvent) => {
// fix for Apple Pencil Scribble
// On Android, preventing the event would disable contextMenu on tap-hold
if (!isAndroid) {
event.preventDefault();
}
if (!didTapTwice) { if (!didTapTwice) {
didTapTwice = true; didTapTwice = true;
clearTimeout(tappedTwiceTimer); clearTimeout(tappedTwiceTimer);
@@ -1299,10 +1293,7 @@ class App extends React.Component<AppProps, AppState> {
didTapTwice = false; didTapTwice = false;
clearTimeout(tappedTwiceTimer); clearTimeout(tappedTwiceTimer);
} }
if (isAndroid) { event.preventDefault();
event.preventDefault();
}
if (event.touches.length === 2) { if (event.touches.length === 2) {
this.setState({ this.setState({
selectedElementIds: {}, selectedElementIds: {},
@@ -1311,14 +1302,11 @@ class App extends React.Component<AppProps, AppState> {
}; };
private onTapEnd = (event: TouchEvent) => { private onTapEnd = (event: TouchEvent) => {
this.resetContextMenuTimer();
if (event.touches.length > 0) { if (event.touches.length > 0) {
this.setState({ this.setState({
previousSelectedElementIds: {}, previousSelectedElementIds: {},
selectedElementIds: this.state.previousSelectedElementIds, selectedElementIds: this.state.previousSelectedElementIds,
}); });
} else {
gesture.pointers.clear();
} }
}; };
@@ -1531,8 +1519,12 @@ class App extends React.Component<AppProps, AppState> {
}; };
removePointer = (event: React.PointerEvent<HTMLElement> | PointerEvent) => { removePointer = (event: React.PointerEvent<HTMLElement> | PointerEvent) => {
if (touchTimeout) { this.lastPointerUp = event;
this.resetContextMenuTimer(); // remove touch handler for context menu on touch devices
if (event.pointerType === "touch" && touchTimeout) {
clearTimeout(touchTimeout);
touchTimeout = 0;
invalidateContextMenu = false;
} }
gesture.pointers.delete(event.pointerId); gesture.pointers.delete(event.pointerId);
@@ -1616,6 +1608,9 @@ class App extends React.Component<AppProps, AppState> {
this.files = { ...this.files, ...Object.fromEntries(filesMap) }; this.files = { ...this.files, ...Object.fromEntries(filesMap) };
// bump versions for elements that reference added files so that
// we/host apps can detect the change, and invalidate the image & shape
// cache
this.scene.getElements().forEach((element) => { this.scene.getElements().forEach((element) => {
if ( if (
isInitializedImageElement(element) && isInitializedImageElement(element) &&
@@ -1623,6 +1618,7 @@ class App extends React.Component<AppProps, AppState> {
) { ) {
this.imageCache.delete(element.fileId); this.imageCache.delete(element.fileId);
invalidateShapeForElement(element); invalidateShapeForElement(element);
bumpVersion(element);
} }
}); });
this.scene.informMutation(); this.scene.informMutation();
@@ -1928,7 +1924,7 @@ class App extends React.Component<AppProps, AppState> {
// zoom in at the right location on the touchMove handler already. // zoom in at the right location on the touchMove handler already.
// On Macbook, we don't have those events so will zoom in at the // On Macbook, we don't have those events so will zoom in at the
// current location instead. // current location instead.
if (gesture.pointers.size >= 2) { if (gesture.pointers.size === 2) {
return; return;
} }
@@ -2367,35 +2363,16 @@ class App extends React.Component<AppProps, AppState> {
} }
return ( return (
element.link && element.link &&
isPointHittingLinkIcon( isPointHittingLinkIcon(element, this.state, [
element, scenePointer.x,
this.state, scenePointer.y,
[scenePointer.x, scenePointer.y], ]) &&
this.isMobile,
) &&
index <= hitElementIndex index <= hitElementIndex
); );
}); });
}; };
private redirectToLink = ( private redirectToLink = () => {
event: React.PointerEvent<HTMLCanvasElement>,
isTouchScreen: boolean,
) => {
const draggedDistance = distance2d(
this.lastPointerDown!.clientX,
this.lastPointerDown!.clientY,
this.lastPointerUp!.clientX,
this.lastPointerUp!.clientY,
);
if (
!this.hitLinkElement ||
// For touch screen allow dragging threshold else strict check
(isTouchScreen && draggedDistance > DRAGGING_THRESHOLD) ||
(!isTouchScreen && draggedDistance !== 0)
) {
return;
}
const lastPointerDownCoords = viewportCoordsToSceneCoords( const lastPointerDownCoords = viewportCoordsToSceneCoords(
this.lastPointerDown!, this.lastPointerDown!,
this.state, this.state,
@@ -2404,38 +2381,43 @@ class App extends React.Component<AppProps, AppState> {
this.hitLinkElement!, this.hitLinkElement!,
this.state, this.state,
[lastPointerDownCoords.x, lastPointerDownCoords.y], [lastPointerDownCoords.x, lastPointerDownCoords.y],
this.isMobile,
); );
const lastPointerUpCoords = viewportCoordsToSceneCoords( const lastPointerUpCoords = viewportCoordsToSceneCoords(
this.lastPointerUp!, this.lastPointerUp!,
this.state, this.state,
); );
const lastPointerUpHittingLinkIcon = isPointHittingLinkIcon( const LastPointerUpHittingLinkIcon = isPointHittingLinkIcon(
this.hitLinkElement!, this.hitLinkElement!,
this.state, this.state,
[lastPointerUpCoords.x, lastPointerUpCoords.y], [lastPointerUpCoords.x, lastPointerUpCoords.y],
this.isMobile,
); );
if (lastPointerDownHittingLinkIcon && lastPointerUpHittingLinkIcon) { if (lastPointerDownHittingLinkIcon && LastPointerUpHittingLinkIcon) {
const url = this.hitLinkElement.link; const url = this.hitLinkElement?.link;
if (url) { if (url) {
let customEvent; if (this.props.handleLinkNavigation) {
if (this.props.onLinkOpen) { try {
customEvent = wrapEvent(EVENT.EXCALIDRAW_LINK, event.nativeEvent); this.props.handleLinkNavigation(url);
this.props.onLinkOpen(this.hitLinkElement, customEvent); return;
} } catch (error: any) {
if (!customEvent?.defaultPrevented) { console.error(error);
const target = isLocalLink(url) ? "_self" : "_blank";
const newWindow = window.open(undefined, target);
// https://mathiasbynens.github.io/rel-noopener/
if (newWindow) {
newWindow.opener = null;
newWindow.location = normalizeLink(url);
} }
} }
const target = isLocalLink(url) ? "_self" : "_blank";
const newWindow = window.open(undefined, target);
// https://mathiasbynens.github.io/rel-noopener/
if (newWindow) {
newWindow.opener = null;
newWindow.location = normalizeLink(url);
}
} }
} }
}; };
private attachLinkListener = () => {
this.canvas?.addEventListener("click", this.redirectToLink);
};
private detachLinkListener = () => {
this.canvas?.removeEventListener("click", this.redirectToLink);
};
private handleCanvasPointerMove = ( private handleCanvasPointerMove = (
event: React.PointerEvent<HTMLCanvasElement>, event: React.PointerEvent<HTMLCanvasElement>,
@@ -2680,8 +2662,10 @@ class App extends React.Component<AppProps, AppState> {
) { ) {
setCursor(this.canvas, CURSOR_TYPE.POINTER); setCursor(this.canvas, CURSOR_TYPE.POINTER);
showHyperlinkTooltip(this.hitLinkElement, this.state); showHyperlinkTooltip(this.hitLinkElement, this.state);
this.attachLinkListener();
} else { } else {
hideHyperlinkToolip(); hideHyperlinkToolip();
this.detachLinkListener();
if ( if (
hitElement && hitElement &&
hitElement.link && hitElement.link &&
@@ -2886,35 +2870,6 @@ class App extends React.Component<AppProps, AppState> {
} }
}; };
private handleCanvasPointerUp = (
event: React.PointerEvent<HTMLCanvasElement>,
) => {
this.lastPointerUp = event;
const isTouchScreen = ["pen", "touch"].includes(event.pointerType);
if (isTouchScreen) {
const scenePointer = viewportCoordsToSceneCoords(
{ clientX: event.clientX, clientY: event.clientY },
this.state,
);
const hitElement = this.getElementAtPosition(
scenePointer.x,
scenePointer.y,
);
this.hitLinkElement = this.getElementLinkAtPosition(
scenePointer,
hitElement,
);
}
if (
this.hitLinkElement &&
!this.state.selectedElementIds[this.hitLinkElement.id]
) {
this.redirectToLink(event, isTouchScreen);
}
this.removePointer(event);
};
private maybeOpenContextMenuAfterPointerDownOnTouchDevices = ( private maybeOpenContextMenuAfterPointerDownOnTouchDevices = (
event: React.PointerEvent<HTMLCanvasElement>, event: React.PointerEvent<HTMLCanvasElement>,
): void => { ): void => {
@@ -2940,12 +2895,6 @@ class App extends React.Component<AppProps, AppState> {
} }
}; };
private resetContextMenuTimer = () => {
clearTimeout(touchTimeout);
touchTimeout = 0;
invalidateContextMenu = false;
};
private maybeCleanupAfterMissingPointerUp( private maybeCleanupAfterMissingPointerUp(
event: React.PointerEvent<HTMLCanvasElement>, event: React.PointerEvent<HTMLCanvasElement>,
): void { ): void {
@@ -2980,7 +2929,7 @@ class App extends React.Component<AppProps, AppState> {
setCursor(this.canvas, CURSOR_TYPE.GRABBING); setCursor(this.canvas, CURSOR_TYPE.GRABBING);
let { clientX: lastX, clientY: lastY } = event; let { clientX: lastX, clientY: lastY } = event;
const onPointerMove = withBatchedUpdatesThrottled((event: PointerEvent) => { const onPointerMove = withBatchedUpdates((event: PointerEvent) => {
const deltaX = lastX - event.clientX; const deltaX = lastX - event.clientX;
const deltaY = lastY - event.clientY; const deltaY = lastY - event.clientY;
lastX = event.clientX; lastX = event.clientX;
@@ -3043,7 +2992,6 @@ class App extends React.Component<AppProps, AppState> {
window.removeEventListener(EVENT.POINTER_MOVE, onPointerMove); window.removeEventListener(EVENT.POINTER_MOVE, onPointerMove);
window.removeEventListener(EVENT.POINTER_UP, teardown); window.removeEventListener(EVENT.POINTER_UP, teardown);
window.removeEventListener(EVENT.BLUR, teardown); window.removeEventListener(EVENT.BLUR, teardown);
onPointerMove.flush();
}), }),
); );
window.addEventListener(EVENT.BLUR, teardown); window.addEventListener(EVENT.BLUR, teardown);
@@ -3146,7 +3094,7 @@ class App extends React.Component<AppProps, AppState> {
isDraggingScrollBar = true; isDraggingScrollBar = true;
pointerDownState.lastCoords.x = event.clientX; pointerDownState.lastCoords.x = event.clientX;
pointerDownState.lastCoords.y = event.clientY; pointerDownState.lastCoords.y = event.clientY;
const onPointerMove = withBatchedUpdatesThrottled((event: PointerEvent) => { const onPointerMove = withBatchedUpdates((event: PointerEvent) => {
const target = event.target; const target = event.target;
if (!(target instanceof HTMLElement)) { if (!(target instanceof HTMLElement)) {
return; return;
@@ -3165,7 +3113,6 @@ class App extends React.Component<AppProps, AppState> {
this.savePointer(event.clientX, event.clientY, "up"); this.savePointer(event.clientX, event.clientY, "up");
window.removeEventListener(EVENT.POINTER_MOVE, onPointerMove); window.removeEventListener(EVENT.POINTER_MOVE, onPointerMove);
window.removeEventListener(EVENT.POINTER_UP, onPointerUp); window.removeEventListener(EVENT.POINTER_UP, onPointerUp);
onPointerMove.flush();
}); });
lastPointerUp = onPointerUp; lastPointerUp = onPointerUp;
@@ -3274,12 +3221,10 @@ class App extends React.Component<AppProps, AppState> {
if (pointerDownState.hit.element) { if (pointerDownState.hit.element) {
// Early return if pointer is hitting link icon // Early return if pointer is hitting link icon
if ( if (
isPointHittingLinkIcon( isPointHittingLinkIcon(pointerDownState.hit.element, this.state, [
pointerDownState.hit.element, pointerDownState.origin.x,
this.state, pointerDownState.origin.y,
[pointerDownState.origin.x, pointerDownState.origin.y], ])
this.isMobile,
)
) { ) {
return false; return false;
} }
@@ -3703,8 +3648,8 @@ class App extends React.Component<AppProps, AppState> {
private onPointerMoveFromPointerDownHandler( private onPointerMoveFromPointerDownHandler(
pointerDownState: PointerDownState, pointerDownState: PointerDownState,
) { ): (event: PointerEvent) => void {
return withBatchedUpdatesThrottled((event: PointerEvent) => { return withBatchedUpdates((event: PointerEvent) => {
// We need to initialize dragOffsetXY only after we've updated // We need to initialize dragOffsetXY only after we've updated
// `state.selectedElementIds` on pointerDown. Doing it here in pointerMove // `state.selectedElementIds` on pointerDown. Doing it here in pointerMove
// event handler should hopefully ensure we're already working with // event handler should hopefully ensure we're already working with
@@ -3915,20 +3860,14 @@ class App extends React.Component<AppProps, AppState> {
const dx = pointerCoords.x - draggingElement.x; const dx = pointerCoords.x - draggingElement.x;
const dy = pointerCoords.y - draggingElement.y; const dy = pointerCoords.y - draggingElement.y;
const lastPoint = points.length > 0 && points[points.length - 1]; const pressures = draggingElement.simulatePressure
const discardPoint = ? draggingElement.pressures
lastPoint && lastPoint[0] === dx && lastPoint[1] === dy; : [...draggingElement.pressures, event.pressure];
if (!discardPoint) { mutateElement(draggingElement, {
const pressures = draggingElement.simulatePressure points: [...points, [dx, dy]],
? draggingElement.pressures pressures,
: [...draggingElement.pressures, event.pressure]; });
mutateElement(draggingElement, {
points: [...points, [dx, dy]],
pressures,
});
}
} else if (isLinearElement(draggingElement)) { } else if (isLinearElement(draggingElement)) {
pointerDownState.drag.hasOccurred = true; pointerDownState.drag.hasOccurred = true;
const points = draggingElement.points; const points = draggingElement.points;
@@ -4125,10 +4064,6 @@ class App extends React.Component<AppProps, AppState> {
lastPointerUp = null; lastPointerUp = null;
if (pointerDownState.eventListeners.onMove) {
pointerDownState.eventListeners.onMove.flush();
}
window.removeEventListener( window.removeEventListener(
EVENT.POINTER_MOVE, EVENT.POINTER_MOVE,
pointerDownState.eventListeners.onMove!, pointerDownState.eventListeners.onMove!,
@@ -5054,16 +4989,6 @@ class App extends React.Component<AppProps, AppState> {
) => { ) => {
event.preventDefault(); event.preventDefault();
if (
(event.nativeEvent.pointerType === "touch" ||
(event.nativeEvent.pointerType === "pen" &&
// always allow if user uses a pen secondary button
event.button !== POINTER_BUTTON.SECONDARY)) &&
this.state.elementType !== "selection"
) {
return;
}
const { x, y } = viewportCoordsToSceneCoords(event, this.state); const { x, y } = viewportCoordsToSceneCoords(event, this.state);
const element = this.getElementAtPosition(x, y, { preferSelected: true }); const element = this.getElementAtPosition(x, y, { preferSelected: true });
+1 -2
View File
@@ -7,7 +7,7 @@ export const ButtonIconSelect = <T extends Object>({
onChange, onChange,
group, group,
}: { }: {
options: { value: T; text: string; icon: JSX.Element; testId?: string }[]; options: { value: T; text: string; icon: JSX.Element }[];
value: T | null; value: T | null;
onChange: (value: T) => void; onChange: (value: T) => void;
group: string; group: string;
@@ -24,7 +24,6 @@ export const ButtonIconSelect = <T extends Object>({
name={group} name={group}
onChange={() => onChange(option.value)} onChange={() => onChange(option.value)}
checked={value === option.value} checked={value === option.value}
data-testid={option.testId}
/> />
{option.icon} {option.icon}
</label> </label>
+2 -9
View File
@@ -49,7 +49,6 @@
.ToolIcon__hidden { .ToolIcon__hidden {
box-shadow: none !important; box-shadow: none !important;
background-color: transparent !important; background-color: transparent !important;
pointer-events: none !important;
} }
.ToolIcon.ToolIcon__lock { .ToolIcon.ToolIcon__lock {
@@ -87,14 +86,8 @@
.ToolIcon { .ToolIcon {
&:hover { &:hover {
--icon-fill-color: var( --icon-fill-color: var(--color-primary-chubb);
--color-primary-contrast-offset, --keybinding-color: var(--color-primary-chubb);
var(--color-primary)
);
--keybinding-color: var(
--color-primary-contrast-offset,
var(--color-primary)
);
} }
&:active { &:active {
--icon-fill-color: #{$oc-gray-9}; --icon-fill-color: #{$oc-gray-9};
+1 -3
View File
@@ -24,7 +24,7 @@ export const POINTER_BUTTON = {
WHEEL: 1, WHEEL: 1,
SECONDARY: 2, SECONDARY: 2,
TOUCH: -1, TOUCH: -1,
} as const; };
export enum EVENT { export enum EVENT {
COPY = "copy", COPY = "copy",
@@ -52,8 +52,6 @@ export enum EVENT {
HASHCHANGE = "hashchange", HASHCHANGE = "hashchange",
VISIBILITY_CHANGE = "visibilitychange", VISIBILITY_CHANGE = "visibilitychange",
SCROLL = "scroll", SCROLL = "scroll",
// custom events
EXCALIDRAW_LINK = "excalidraw-link",
} }
export const ENV = { export const ENV = {
+2
View File
@@ -38,6 +38,7 @@
--text-primary-color: #{$oc-gray-8}; --text-primary-color: #{$oc-gray-8};
--color-primary: #6965db; --color-primary: #6965db;
--color-primary-chubb: #625ee0; // to offset Chubb illusion
--color-primary-darker: #5b57d1; --color-primary-darker: #5b57d1;
--color-primary-darkest: #4a47b1; --color-primary-darkest: #4a47b1;
--color-primary-light: #e2e1fc; --color-primary-light: #e2e1fc;
@@ -84,6 +85,7 @@
--text-primary-color: #{$oc-gray-4}; --text-primary-color: #{$oc-gray-4};
--color-primary: #5650f0; --color-primary: #5650f0;
--color-primary-chubb: #726dff; // to offset Chubb illusion
--color-primary-darker: #4b46d8; --color-primary-darker: #4b46d8;
--color-primary-darkest: #3e39be; --color-primary-darkest: #3e39be;
--color-primary-light: #3f3d64; --color-primary-light: #3f3d64;
+10 -34
View File
@@ -1,9 +1,8 @@
import { AppState, ExcalidrawProps, Point } from "../types"; import { AppState, Point } from "../types";
import { import {
getShortcutKey, getShortcutKey,
sceneCoordsToViewportCoords, sceneCoordsToViewportCoords,
viewportCoordsToSceneCoords, viewportCoordsToSceneCoords,
wrapEvent,
} from "../utils"; } from "../utils";
import { mutateElement } from "./mutateElement"; import { mutateElement } from "./mutateElement";
import { NonDeletedExcalidrawElement } from "./types"; import { NonDeletedExcalidrawElement } from "./types";
@@ -49,12 +48,10 @@ export const Hyperlink = ({
element, element,
appState, appState,
setAppState, setAppState,
onLinkOpen,
}: { }: {
element: NonDeletedExcalidrawElement; element: NonDeletedExcalidrawElement;
appState: AppState; appState: AppState;
setAppState: React.Component<any, AppState>["setState"]; setAppState: React.Component<any, AppState>["setState"];
onLinkOpen: ExcalidrawProps["onLinkOpen"];
}) => { }) => {
const linkVal = element.link || ""; const linkVal = element.link || "";
@@ -122,8 +119,7 @@ export const Hyperlink = ({
if ( if (
appState.draggingElement || appState.draggingElement ||
appState.resizingElement || appState.resizingElement ||
appState.isRotating || appState.isRotating
appState.openMenu
) { ) {
return null; return null;
} }
@@ -163,18 +159,6 @@ export const Hyperlink = ({
"d-none": isEditing, "d-none": isEditing,
})} })}
target={isLocalLink(element.link) ? "_self" : "_blank"} target={isLocalLink(element.link) ? "_self" : "_blank"}
onClick={(event) => {
if (element.link && onLinkOpen) {
const customEvent = wrapEvent(
EVENT.EXCALIDRAW_LINK,
event.nativeEvent,
);
onLinkOpen(element, customEvent);
if (customEvent.defaultPrevented) {
event.preventDefault();
}
}
}}
rel="noopener noreferrer" rel="noopener noreferrer"
> >
{element.link} {element.link}
@@ -213,9 +197,8 @@ const getCoordsForPopover = (
element: NonDeletedExcalidrawElement, element: NonDeletedExcalidrawElement,
appState: AppState, appState: AppState,
) => { ) => {
const [x1, y1] = getElementAbsoluteCoords(element);
const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords( const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords(
{ sceneX: x1 + element.width / 2, sceneY: y1 }, { sceneX: element.x + element.width / 2, sceneY: element.y },
appState, appState,
); );
const x = viewportX - appState.offsetLeft - CONTAINER_WIDTH / 2; const x = viewportX - appState.offsetLeft - CONTAINER_WIDTH / 2;
@@ -249,7 +232,6 @@ export const actionLink = register({
appState: { appState: {
...appState, ...appState,
showHyperlinkPopup: "editor", showHyperlinkPopup: "editor",
openMenu: null,
}, },
commitToHistory: true, commitToHistory: true,
}; };
@@ -324,16 +306,9 @@ export const isPointHittingLinkIcon = (
element: NonDeletedExcalidrawElement, element: NonDeletedExcalidrawElement,
appState: AppState, appState: AppState,
[x, y]: Point, [x, y]: Point,
isMobile: boolean,
) => { ) => {
const threshold = 4 / appState.zoom.value; const threshold = 4 / appState.zoom.value;
if (
!isMobile &&
appState.viewModeEnabled &&
isPointHittingElementBoundingBox(element, [x, y], threshold)
) {
return true;
}
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
const [linkX, linkY, linkWidth, linkHeight] = getLinkHandleFromCoords( const [linkX, linkY, linkWidth, linkHeight] = getLinkHandleFromCoords(
@@ -346,6 +321,7 @@ export const isPointHittingLinkIcon = (
x < linkX + threshold + linkWidth && x < linkX + threshold + linkWidth &&
y > linkY - threshold && y > linkY - threshold &&
y < linkY + linkHeight + threshold; y < linkY + linkHeight + threshold;
return hitLink; return hitLink;
}; };
@@ -428,13 +404,13 @@ export const shouldHideLinkPopup = (
if (isPointHittingElementBoundingBox(element, [sceneX, sceneY], threshold)) { if (isPointHittingElementBoundingBox(element, [sceneX, sceneY], threshold)) {
return false; return false;
} }
const [x1, y1, x2] = getElementAbsoluteCoords(element);
// hit box to prevent hiding when hovered in the vertical area between element and popover // hit box to prevent hiding when hovered in the vertical area between element and popover
if ( if (
sceneX >= x1 && sceneX >= element.x &&
sceneX <= x2 && sceneX <= element.x + element.width &&
sceneY >= y1 - SPACE_BOTTOM && sceneY <= element.y &&
sceneY <= y1 sceneY >= element.y - SPACE_BOTTOM
) { ) {
return false; return false;
} }
+2 -2
View File
@@ -185,7 +185,7 @@ const getLinearElementAbsoluteCoords = (
maxY + element.y, maxY + element.y,
]; ];
} else { } else {
const shape = getShapeForElement(element)!; const shape = getShapeForElement(element) as Drawable[];
// first element is always the curve // first element is always the curve
const ops = getCurvePathOps(shape[0]); const ops = getCurvePathOps(shape[0]);
@@ -326,7 +326,7 @@ const getLinearElementRotatedBounds = (
return [minX, minY, maxX, maxY]; return [minX, minY, maxX, maxY];
} }
const shape = getShapeForElement(element)!; const shape = getShapeForElement(element) as Drawable[];
// first element is always the curve // first element is always the curve
const ops = getCurvePathOps(shape[0]); const ops = getCurvePathOps(shape[0]);
+4 -22
View File
@@ -24,7 +24,6 @@ import {
NonDeleted, NonDeleted,
ExcalidrawFreeDrawElement, ExcalidrawFreeDrawElement,
ExcalidrawImageElement, ExcalidrawImageElement,
ExcalidrawLinearElement,
} from "./types"; } from "./types";
import { getElementAbsoluteCoords, getCurvePathOps, Bounds } from "./bounds"; import { getElementAbsoluteCoords, getCurvePathOps, Bounds } from "./bounds";
@@ -362,14 +361,6 @@ const hitTestFreeDrawElement = (
B = element.points[i + 1]; B = element.points[i + 1];
} }
const shape = getShapeForElement(element);
// for filled freedraw shapes, support
// selecting from inside
if (shape && shape.sets.length) {
return hitTestRoughShape(shape, x, y, threshold);
}
return false; return false;
}; };
@@ -392,11 +383,7 @@ const hitTestLinear = (args: HitTestArgs): boolean => {
} }
const [relX, relY] = GAPoint.toTuple(point); const [relX, relY] = GAPoint.toTuple(point);
const shape = getShapeForElement(element as ExcalidrawLinearElement); const shape = getShapeForElement(element) as Drawable[];
if (!shape) {
return false;
}
if (args.check === isInsideCheck) { if (args.check === isInsideCheck) {
const hit = shape.some((subshape) => const hit = shape.some((subshape) =>
@@ -834,7 +821,7 @@ const hitTestCurveInside = (
sharpness: ExcalidrawElement["strokeSharpness"], sharpness: ExcalidrawElement["strokeSharpness"],
) => { ) => {
const ops = getCurvePathOps(drawable); const ops = getCurvePathOps(drawable);
const points: Mutable<Point>[] = []; const points: Point[] = [];
let odd = false; // select one line out of double lines let odd = false; // select one line out of double lines
for (const operation of ops) { for (const operation of ops) {
if (operation.op === "move") { if (operation.op === "move") {
@@ -848,17 +835,13 @@ const hitTestCurveInside = (
points.push([operation.data[2], operation.data[3]]); points.push([operation.data[2], operation.data[3]]);
points.push([operation.data[4], operation.data[5]]); points.push([operation.data[4], operation.data[5]]);
} }
} else if (operation.op === "lineTo") {
if (odd) {
points.push([operation.data[0], operation.data[1]]);
}
} }
} }
if (points.length >= 4) { if (points.length >= 4) {
if (sharpness === "sharp") { if (sharpness === "sharp") {
return isPointInPolygon(points, x, y); return isPointInPolygon(points, x, y);
} }
const polygonPoints = pointsOnBezierCurves(points, 10, 5); const polygonPoints = pointsOnBezierCurves(points as any, 10, 5);
return isPointInPolygon(polygonPoints, x, y); return isPointInPolygon(polygonPoints, x, y);
} }
return false; return false;
@@ -913,10 +896,9 @@ const hitTestRoughShape = (
// position of the previous operation // position of the previous operation
return retVal; return retVal;
} else if (op === "lineTo") { } else if (op === "lineTo") {
return hitTestCurveInside(drawable, x, y, "sharp"); // TODO: Implement this
} else if (op === "qcurveTo") { } else if (op === "qcurveTo") {
// TODO: Implement this // TODO: Implement this
console.warn("qcurveTo is not implemented yet");
} }
return false; return false;
+1 -1
View File
@@ -86,7 +86,7 @@ export const textWysiwyg = ({
updatedElement: ExcalidrawTextElement, updatedElement: ExcalidrawTextElement,
editable: HTMLTextAreaElement, editable: HTMLTextAreaElement,
) => { ) => {
const currentFont = editable.style.fontFamily.replace(/"/g, ""); const currentFont = editable.style.fontFamily.replaceAll('"', "");
if ( if (
getFontFamilyString({ fontFamily: updatedElement.fontFamily }) !== getFontFamilyString({ fontFamily: updatedElement.fontFamily }) !==
currentFont currentFont
-5
View File
@@ -1,9 +1,4 @@
.excalidraw { .excalidraw {
--color-primary-contrast-offset: #625ee0; // to offset Chubb illusion
&.theme--dark {
--color-primary-contrast-offset: #726dff; // to offset Chubb illusion
}
.layer-ui__wrapper__footer-center { .layer-ui__wrapper__footer-center {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
-1
View File
@@ -1,6 +1,5 @@
export const isDarwin = /Mac|iPod|iPhone|iPad/.test(window.navigator.platform); export const isDarwin = /Mac|iPod|iPhone|iPad/.test(window.navigator.platform);
export const isWindows = /^Win/.test(window.navigator.platform); export const isWindows = /^Win/.test(window.navigator.platform);
export const isAndroid = /\b(android)\b/i.test(navigator.userAgent);
export const CODES = { export const CODES = {
EQUAL: "Equal", EQUAL: "Equal",
+6 -14
View File
@@ -103,14 +103,8 @@
"toggleTheme": "غير النمط", "toggleTheme": "غير النمط",
"personalLib": "المكتبة الشخصية", "personalLib": "المكتبة الشخصية",
"excalidrawLib": "مكتبتنا", "excalidrawLib": "مكتبتنا",
"decreaseFontSize": "تصغير حجم الخط", "decreaseFontSize": "",
"increaseFontSize": "تكبير حجم الخط", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "إعادة تعيين اللوحة", "clearReset": "إعادة تعيين اللوحة",
@@ -179,7 +173,7 @@
"imageInsertError": "تعذر إدراج الصورة. حاول مرة أخرى لاحقاً...", "imageInsertError": "تعذر إدراج الصورة. حاول مرة أخرى لاحقاً...",
"fileTooBig": "الملف كبير جداً. الحد الأقصى المسموح به للحجم هو {{maxSize}}.", "fileTooBig": "الملف كبير جداً. الحد الأقصى المسموح به للحجم هو {{maxSize}}.",
"svgImageInsertError": "تعذر إدراج صورة SVG. يبدو أن ترميز SVG غير صحيح.", "svgImageInsertError": "تعذر إدراج صورة SVG. يبدو أن ترميز SVG غير صحيح.",
"invalidSVGString": "SVG غير صالح." "invalidSVGString": ""
}, },
"toolBar": { "toolBar": {
"selection": "تحديد", "selection": "تحديد",
@@ -192,9 +186,7 @@
"freedraw": "رسم", "freedraw": "رسم",
"text": "نص", "text": "نص",
"library": "مكتبة", "library": "مكتبة",
"lock": "الحفاظ على أداة التحديد نشطة بعد الرسم", "lock": "الحفاظ على أداة التحديد نشطة بعد الرسم"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "إجراءات اللوحة", "canvasActions": "إجراءات اللوحة",
@@ -202,7 +194,7 @@
"shapes": "الأشكال" "shapes": "الأشكال"
}, },
"hints": { "hints": {
"canvasPanning": "لتحريك لوحة الرسم ، استمر في الضغط على عجلة الماوس أو مفتاح المسافة أثناء السحب", "canvasPanning": "",
"linearElement": "انقر لبدء نقاط متعددة، اسحب لخط واحد", "linearElement": "انقر لبدء نقاط متعددة، اسحب لخط واحد",
"freeDraw": "انقر واسحب، افرج عند الانتهاء", "freeDraw": "انقر واسحب، افرج عند الانتهاء",
"text": "نصيحة: يمكنك أيضًا إضافة نص بالنقر المزدوج في أي مكان بأداة الاختيار", "text": "نصيحة: يمكنك أيضًا إضافة نص بالنقر المزدوج في أي مكان بأداة الاختيار",
@@ -309,7 +301,7 @@
"website": "" "website": ""
}, },
"errors": { "errors": {
"required": "مطلوب", "required": "",
"website": "" "website": ""
}, },
"noteDescription": { "noteDescription": {
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Нулиране на платно", "clearReset": "Нулиране на платно",
@@ -192,9 +186,7 @@
"freedraw": "Рисуване", "freedraw": "Рисуване",
"text": "Текст", "text": "Текст",
"library": "Библиотека", "library": "Библиотека",
"lock": "Поддържайте избрания инструмент активен след рисуване", "lock": "Поддържайте избрания инструмент активен след рисуване"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Действия по платното", "canvasActions": "Действия по платното",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "", "clearReset": "",
@@ -192,9 +186,7 @@
"freedraw": "", "freedraw": "",
"text": "", "text": "",
"library": "", "library": "",
"lock": "", "lock": ""
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "", "canvasActions": "",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Biblioteca personal", "personalLib": "Biblioteca personal",
"excalidrawLib": "Biblioteca d'Excalidraw", "excalidrawLib": "Biblioteca d'Excalidraw",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Neteja el llenç", "clearReset": "Neteja el llenç",
@@ -192,9 +186,7 @@
"freedraw": "Dibuix", "freedraw": "Dibuix",
"text": "Text", "text": "Text",
"library": "Biblioteca", "library": "Biblioteca",
"lock": "Mantenir activa l'eina seleccionada desprès de dibuixar", "lock": "Mantenir activa l'eina seleccionada desprès de dibuixar"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Accions del llenç", "canvasActions": "Accions del llenç",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "", "clearReset": "",
@@ -192,9 +186,7 @@
"freedraw": "Kreslení", "freedraw": "Kreslení",
"text": "Text", "text": "Text",
"library": "", "library": "",
"lock": "", "lock": ""
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "", "canvasActions": "",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "", "clearReset": "",
@@ -192,9 +186,7 @@
"freedraw": "", "freedraw": "",
"text": "", "text": "",
"library": "", "library": "",
"lock": "", "lock": ""
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "", "canvasActions": "",
+4 -12
View File
@@ -100,17 +100,11 @@
"share": "Teilen", "share": "Teilen",
"showStroke": "Auswahl für Strichfarbe anzeigen", "showStroke": "Auswahl für Strichfarbe anzeigen",
"showBackground": "Hintergrundfarbe auswählen", "showBackground": "Hintergrundfarbe auswählen",
"toggleTheme": "Thema umschalten", "toggleTheme": "Design umschalten",
"personalLib": "Persönliche Bibliothek", "personalLib": "Persönliche Bibliothek",
"excalidrawLib": "Excalidraw-Bibliothek", "excalidrawLib": "Excalidraw-Bibliothek",
"decreaseFontSize": "Schrift verkleinern", "decreaseFontSize": "Schrift verkleinern",
"increaseFontSize": "Schrift vergrößern", "increaseFontSize": "Schrift vergrößern"
"unbindText": "Text lösen",
"link": {
"edit": "Link bearbeiten",
"create": "Link erstellen",
"label": "Link"
}
}, },
"buttons": { "buttons": {
"clearReset": "Zeichenfläche löschen & Hintergrundfarbe zurücksetzen", "clearReset": "Zeichenfläche löschen & Hintergrundfarbe zurücksetzen",
@@ -192,9 +186,7 @@
"freedraw": "Zeichnen", "freedraw": "Zeichnen",
"text": "Text", "text": "Text",
"library": "Bibliothek", "library": "Bibliothek",
"lock": "Ausgewähltes Werkzeug nach Zeichnen aktiv lassen", "lock": "Ausgewähltes Werkzeug nach Zeichnen aktiv lassen"
"penMode": "",
"link": "Link für ausgewählte Form hinzufügen / aktualisieren"
}, },
"headings": { "headings": {
"canvasActions": "Aktionen für Zeichenfläche", "canvasActions": "Aktionen für Zeichenfläche",
@@ -255,7 +247,7 @@
"exportDialog": { "exportDialog": {
"disk_title": "Auf Festplatte speichern", "disk_title": "Auf Festplatte speichern",
"disk_details": "Exportiere die Zeichnungsdaten in eine Datei, die Du später importieren kannst.", "disk_details": "Exportiere die Zeichnungsdaten in eine Datei, die Du später importieren kannst.",
"disk_button": "Als Datei speichern", "disk_button": "In Datei speichern",
"link_title": "Teilbarer Link", "link_title": "Teilbarer Link",
"link_details": "Als schreibgeschützten Link exportieren.", "link_details": "Als schreibgeschützten Link exportieren.",
"link_button": "Als Link exportieren", "link_button": "Als Link exportieren",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Προσωπική Βιβλιοθήκη", "personalLib": "Προσωπική Βιβλιοθήκη",
"excalidrawLib": "Βιβλιοθήκη Excalidraw", "excalidrawLib": "Βιβλιοθήκη Excalidraw",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Επαναφορά του καμβά", "clearReset": "Επαναφορά του καμβά",
@@ -192,9 +186,7 @@
"freedraw": "Σχεδίαση", "freedraw": "Σχεδίαση",
"text": "Κείμενο", "text": "Κείμενο",
"library": "Βιβλιοθήκη", "library": "Βιβλιοθήκη",
"lock": "Κράτησε επιλεγμένο το εργαλείο μετά το σχέδιο", "lock": "Κράτησε επιλεγμένο το εργαλείο μετά το σχέδιο"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Ενέργειες καμβά", "canvasActions": "Ενέργειες καμβά",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Limpiar lienzo y reiniciar el color de fondo", "clearReset": "Limpiar lienzo y reiniciar el color de fondo",
@@ -192,9 +186,7 @@
"freedraw": "Dibujar", "freedraw": "Dibujar",
"text": "Texto", "text": "Texto",
"library": "Biblioteca", "library": "Biblioteca",
"lock": "Mantener la herramienta seleccionada activa después de dibujar", "lock": "Mantener la herramienta seleccionada activa después de dibujar"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Acciones del lienzo", "canvasActions": "Acciones del lienzo",
+49 -57
View File
@@ -103,14 +103,8 @@
"toggleTheme": "Aldatu gaia", "toggleTheme": "Aldatu gaia",
"personalLib": "Liburutegi pertsonala", "personalLib": "Liburutegi pertsonala",
"excalidrawLib": "Excalidraw liburutegia", "excalidrawLib": "Excalidraw liburutegia",
"decreaseFontSize": "Txikitu letra tamaina", "decreaseFontSize": "",
"increaseFontSize": "Handitu letra tamaina", "increaseFontSize": ""
"unbindText": "Askatu testua",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Garbitu oihala", "clearReset": "Garbitu oihala",
@@ -162,63 +156,61 @@
"decryptFailed": "Ezin izan da deszifratu.", "decryptFailed": "Ezin izan da deszifratu.",
"uploadedSecurly": "Kargatzea muturretik muturrerako zifratze bidez ziurtatu da, hau da, Excalidraw zerbitzariak eta hirugarrenek ezin dutela edukia irakurri.", "uploadedSecurly": "Kargatzea muturretik muturrerako zifratze bidez ziurtatu da, hau da, Excalidraw zerbitzariak eta hirugarrenek ezin dutela edukia irakurri.",
"loadSceneOverridePrompt": "Kanpoko marrazkia kargatzeak lehendik duzun edukia ordezkatuko du. Jarraitu nahi duzu?", "loadSceneOverridePrompt": "Kanpoko marrazkia kargatzeak lehendik duzun edukia ordezkatuko du. Jarraitu nahi duzu?",
"collabStopOverridePrompt": "Saioa gelditzeak lokalean gordetako zure aurreko marrazkia gainidatziko du. Ziur zaude?\n\n(Zure marrazki lokala mantendu nahi baduzu, itxi arakatzailearen fitxa.)", "collabStopOverridePrompt": "",
"errorLoadingLibrary": "Errore bat gertatu da hirugarrenen liburutegia kargatzean.", "errorLoadingLibrary": "",
"errorAddingToLibrary": "Ezin izan da elementua liburutegian gehitu", "errorAddingToLibrary": "",
"errorRemovingFromLibrary": "Ezin izan da elementua liburutegitik kendu", "errorRemovingFromLibrary": "",
"confirmAddLibrary": "Honek {{numShapes}} forma gehituko ditu zure liburutegian. Ziur zaude?", "confirmAddLibrary": "",
"imageDoesNotContainScene": "Irudi honek ez dirudi eszena daturik duenik. Eszena kapsulatzea gaitu al duzu esportazioan?", "imageDoesNotContainScene": "",
"cannotRestoreFromImage": "Ezin izan da eszena leheneratu irudi fitxategi honetatik", "cannotRestoreFromImage": "",
"invalidSceneUrl": "Ezin izan da eszena inportatu emandako URLtik. Gaizki eratuta dago edo ez du baliozko Excalidraw JSON daturik.", "invalidSceneUrl": "",
"resetLibrary": "Honek zure liburutegia garbituko du. Ziur zaude?", "resetLibrary": "",
"removeItemsFromsLibrary": "Liburutegitik {{count}} elementu ezabatu?", "removeItemsFromsLibrary": "",
"invalidEncryptionKey": "Enkriptazio-gakoak 22 karaktere izan behar ditu. Zuzeneko lankidetza desgaituta dago." "invalidEncryptionKey": ""
}, },
"errors": { "errors": {
"unsupportedFileType": "Onartu gabeko fitxategi mota.", "unsupportedFileType": "",
"imageInsertError": "Ezin izan da irudia txertatu. Saiatu berriro geroago...", "imageInsertError": "",
"fileTooBig": "Fitxategia handiegia da. Onartutako gehienezko tamaina {{maxSize}} da.", "fileTooBig": "",
"svgImageInsertError": "Ezin izan da SVG irudia txertatu. SVG markak baliogabea dirudi.", "svgImageInsertError": "",
"invalidSVGString": "SVG baliogabea." "invalidSVGString": ""
}, },
"toolBar": { "toolBar": {
"selection": "Hautapena", "selection": "",
"image": "Txertatu irudia", "image": "",
"rectangle": "Laukizuzena", "rectangle": "",
"diamond": "Diamantea", "diamond": "",
"ellipse": "Elipsea", "ellipse": "",
"arrow": "Gezia", "arrow": "",
"line": "Lerroa", "line": "",
"freedraw": "Marraztu", "freedraw": "",
"text": "Testua", "text": "",
"library": "Liburutegia", "library": "",
"lock": "Mantendu aktibo hautatutako tresna marraztu ondoren", "lock": ""
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Canvas ekintzak", "canvasActions": "",
"selectedShapeActions": "Hautatutako formaren ekintzak", "selectedShapeActions": "",
"shapes": "Formak" "shapes": ""
}, },
"hints": { "hints": {
"canvasPanning": "Oihala mugitzeko, sakatu saguaren gurpila edo zuriune-barra arrastatzean", "canvasPanning": "",
"linearElement": "Egin klik hainbat puntu hasteko, arrastatu lerro bakarrerako", "linearElement": "",
"freeDraw": "Egin klik eta arrastatu, askatu amaitutakoan", "freeDraw": "",
"text": "Aholkua: testua gehitu dezakezu edozein lekutan klik bikoitza eginez hautapen tresnarekin", "text": "",
"text_selected": "Egin klik bikoitza edo sakatu SARTU testua editatzeko", "text_selected": "",
"text_editing": "Sakatu Esc edo Ctrl+SARTU editatzen amaitzeko", "text_editing": "",
"linearElementMulti": "Egin klik azken puntuan edo sakatu Esc edo Sartu amaitzeko", "linearElementMulti": "",
"lockAngle": "SHIFT sakatuta angelua mantendu dezakezu", "lockAngle": "",
"resize": "Proportzioak mantendu ditzakezu SHIFT sakatuta tamaina aldatzen duzun bitartean.\nsakatu ALT erditik tamaina aldatzeko", "resize": "",
"resizeImage": "Tamaina libreki alda dezakezu SHIFT sakatuta,\nsakatu ALT erditik tamaina aldatzeko", "resizeImage": "",
"rotate": "Angeluak mantendu ditzakezu SHIFT sakatuta biratzen duzun bitartean", "rotate": "",
"lineEditor_info": "Egin klik bikoitza edo sakatu Sartu puntuak editatzeko", "lineEditor_info": "",
"lineEditor_pointSelected": "Sakatu Ezabatu puntuak kentzeko,\nKtrl+D bikoizteko, edo arrastatu mugitzeko", "lineEditor_pointSelected": "",
"lineEditor_nothingSelected": "Hautatu editatzeko puntu bat (SHIFT sakatuta anitz hautatzeko),\nedo eduki Alt sakatuta eta egin klik puntu berriak gehitzeko", "lineEditor_nothingSelected": "",
"placeImage": "Egin klik irudia kokatzeko, edo egin klik eta arrastatu bere tamaina eskuz ezartzeko", "placeImage": "",
"publishLibrary": "Argitaratu zure liburutegia", "publishLibrary": "",
"bindTextToElement": "Sakatu Sartu testua gehitzeko", "bindTextToElement": "",
"deepBoxSelect": "" "deepBoxSelect": ""
}, },
"canvasError": { "canvasError": {
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "پاکسازی بوم نقاشی", "clearReset": "پاکسازی بوم نقاشی",
@@ -192,9 +186,7 @@
"freedraw": "کشیدن", "freedraw": "کشیدن",
"text": "متن", "text": "متن",
"library": "کتابخانه", "library": "کتابخانه",
"lock": "ابزار انتخاب شده را بعد از کشیدن نگه دار", "lock": "ابزار انتخاب شده را بعد از کشیدن نگه دار"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "عملیات روی بوم", "canvasActions": "عملیات روی بوم",
+6 -14
View File
@@ -103,14 +103,8 @@
"toggleTheme": "Vaihda teema", "toggleTheme": "Vaihda teema",
"personalLib": "Oma kirjasto", "personalLib": "Oma kirjasto",
"excalidrawLib": "Excalidraw kirjasto", "excalidrawLib": "Excalidraw kirjasto",
"decreaseFontSize": "Pienennä kirjasinkokoa", "decreaseFontSize": "",
"increaseFontSize": "Kasvata kirjasinkokoa", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "Muokkaa linkkiä",
"create": "Luo linkki",
"label": "Linkki"
}
}, },
"buttons": { "buttons": {
"clearReset": "Tyhjennä piirtoalue", "clearReset": "Tyhjennä piirtoalue",
@@ -192,9 +186,7 @@
"freedraw": "Piirrä", "freedraw": "Piirrä",
"text": "Teksti", "text": "Teksti",
"library": "Kirjasto", "library": "Kirjasto",
"lock": "Pidä valittu työkalu aktiivisena piirron jälkeen", "lock": "Pidä valittu työkalu aktiivisena piirron jälkeen"
"penMode": "Estä nipistyszoomaus ja vastaanota ainoastaan kynällä piirretty",
"link": "Lisää/päivitä linkki valitulle muodolle"
}, },
"headings": { "headings": {
"canvasActions": "Piirtoalueen toiminnot", "canvasActions": "Piirtoalueen toiminnot",
@@ -214,11 +206,11 @@
"resizeImage": "Voit muuttaa kokoa vapaasti pitämällä SHIFTiä pohjassa, pidä ALT pohjassa muuttaaksesi kokoa keskipisteen ympäri", "resizeImage": "Voit muuttaa kokoa vapaasti pitämällä SHIFTiä pohjassa, pidä ALT pohjassa muuttaaksesi kokoa keskipisteen ympäri",
"rotate": "Voit rajoittaa kulman pitämällä SHIFT pohjassa pyörittäessäsi", "rotate": "Voit rajoittaa kulman pitämällä SHIFT pohjassa pyörittäessäsi",
"lineEditor_info": "Kaksoisnapauta tai paina Enter muokataksesi pisteitä", "lineEditor_info": "Kaksoisnapauta tai paina Enter muokataksesi pisteitä",
"lineEditor_pointSelected": "Poista piste(et) painamalla delete, monista painamalla CtrlOrCmd+D, tai liikuta raahaamalla", "lineEditor_pointSelected": "",
"lineEditor_nothingSelected": "Valitse muokattava piste (monivalinta pitämällä SHIFT pohjassa), tai paina Alt ja klikkaa lisätäksesi uusia pisteitä", "lineEditor_nothingSelected": "",
"placeImage": "Klikkaa asettaaksesi kuvan, tai klikkaa ja raahaa asettaaksesi sen koon manuaalisesti", "placeImage": "Klikkaa asettaaksesi kuvan, tai klikkaa ja raahaa asettaaksesi sen koon manuaalisesti",
"publishLibrary": "Julkaise oma kirjasto", "publishLibrary": "Julkaise oma kirjasto",
"bindTextToElement": "Lisää tekstiä painamalla enter", "bindTextToElement": "",
"deepBoxSelect": "" "deepBoxSelect": ""
}, },
"canvasError": { "canvasError": {
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Bibliothèque personnelle", "personalLib": "Bibliothèque personnelle",
"excalidrawLib": "Bibliothèque Excalidraw", "excalidrawLib": "Bibliothèque Excalidraw",
"decreaseFontSize": "Réduire la taille de police", "decreaseFontSize": "Réduire la taille de police",
"increaseFontSize": "Augmenter la taille de police", "increaseFontSize": "Augmenter la taille de police"
"unbindText": "Délier le texte",
"link": {
"edit": "Modifier le lien",
"create": "Créer un lien",
"label": "Lien"
}
}, },
"buttons": { "buttons": {
"clearReset": "Réinitialiser le canevas", "clearReset": "Réinitialiser le canevas",
@@ -192,9 +186,7 @@
"freedraw": "Dessiner", "freedraw": "Dessiner",
"text": "Texte", "text": "Texte",
"library": "Bibliothèque", "library": "Bibliothèque",
"lock": "Garder l'outil sélectionné actif après le dessin", "lock": "Garder l'outil sélectionné actif après le dessin"
"penMode": "Empêcher le zoom tactile et accepter la saisie libre uniquement à partir du stylet",
"link": "Ajouter/mettre à jour le lien pour une forme sélectionnée"
}, },
"headings": { "headings": {
"canvasActions": "Actions du canevas", "canvasActions": "Actions du canevas",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "אפס את הלוח", "clearReset": "אפס את הלוח",
@@ -192,9 +186,7 @@
"freedraw": "צייר", "freedraw": "צייר",
"text": "טקסט", "text": "טקסט",
"library": "ספריה", "library": "ספריה",
"lock": "השאר את הכלי הנבחר פעיל גם לאחר סיום הציור", "lock": "השאר את הכלי הנבחר פעיל גם לאחר סיום הציור"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "פעולות הלוח", "canvasActions": "פעולות הלוח",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "कैनवास रीसेट करें", "clearReset": "कैनवास रीसेट करें",
@@ -192,9 +186,7 @@
"freedraw": "", "freedraw": "",
"text": "पाठ", "text": "पाठ",
"library": "लाइब्रेरी", "library": "लाइब्रेरी",
"lock": "ड्राइंग के बाद चयनित टूल को सक्रिय रखें", "lock": "ड्राइंग के बाद चयनित टूल को सक्रिय रखें"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "कैनवास क्रिया", "canvasActions": "कैनवास क्रिया",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Vászon törlése", "clearReset": "Vászon törlése",
@@ -192,9 +186,7 @@
"freedraw": "", "freedraw": "",
"text": "Szöveg", "text": "Szöveg",
"library": "Könyvtár", "library": "Könyvtár",
"lock": "Rajzolás után az aktív eszközt tartsa kijelölve", "lock": "Rajzolás után az aktív eszközt tartsa kijelölve"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Vászon műveletek", "canvasActions": "Vászon műveletek",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Pustaka Pribadi", "personalLib": "Pustaka Pribadi",
"excalidrawLib": "Pustaka Excalidraw", "excalidrawLib": "Pustaka Excalidraw",
"decreaseFontSize": "Kecilkan ukuran font", "decreaseFontSize": "Kecilkan ukuran font",
"increaseFontSize": "Besarkan ukuran font", "increaseFontSize": "Besarkan ukuran font"
"unbindText": "Lepas teks",
"link": {
"edit": "Edit tautan",
"create": "Buat tautan",
"label": "Tautan"
}
}, },
"buttons": { "buttons": {
"clearReset": "Setel Ulang Kanvas", "clearReset": "Setel Ulang Kanvas",
@@ -192,9 +186,7 @@
"freedraw": "Gambar", "freedraw": "Gambar",
"text": "Teks", "text": "Teks",
"library": "Pustaka", "library": "Pustaka",
"lock": "Biarkan alat yang dipilih aktif setelah menggambar", "lock": "Biarkan alat yang dipilih aktif setelah menggambar"
"penMode": "Cegah jepit perbesar dan terima hanya input freedraw dari pena",
"link": "Tambah/Perbarui tautan untuk bentuk yang dipilih"
}, },
"headings": { "headings": {
"canvasActions": "Opsi Kanvas", "canvasActions": "Opsi Kanvas",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Libreria Personale", "personalLib": "Libreria Personale",
"excalidrawLib": "Libreria di Excalidraw", "excalidrawLib": "Libreria di Excalidraw",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Svuota la tela", "clearReset": "Svuota la tela",
@@ -192,9 +186,7 @@
"freedraw": "Disegno", "freedraw": "Disegno",
"text": "Testo", "text": "Testo",
"library": "Libreria", "library": "Libreria",
"lock": "Mantieni lo strumento selezionato attivo dopo aver disegnato", "lock": "Mantieni lo strumento selezionato attivo dopo aver disegnato"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Azioni sulla Tela", "canvasActions": "Azioni sulla Tela",
+3 -11
View File
@@ -103,14 +103,8 @@
"toggleTheme": "テーマの切り替え", "toggleTheme": "テーマの切り替え",
"personalLib": "個人ライブラリ", "personalLib": "個人ライブラリ",
"excalidrawLib": "Excalidrawライブラリ", "excalidrawLib": "Excalidrawライブラリ",
"decreaseFontSize": "フォントサイズを縮小", "decreaseFontSize": "",
"increaseFontSize": "フォントサイズを拡大", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "リンクを編集",
"create": "リンクを作成",
"label": "リンク"
}
}, },
"buttons": { "buttons": {
"clearReset": "キャンバスのリセット", "clearReset": "キャンバスのリセット",
@@ -192,9 +186,7 @@
"freedraw": "描画", "freedraw": "描画",
"text": "テキスト", "text": "テキスト",
"library": "ライブラリ", "library": "ライブラリ",
"lock": "描画後も使用中のツールを選択したままにする", "lock": "描画後も使用中のツールを選択したままにする"
"penMode": "ピンチとズームを抑止し、ペンからのみ自由な入力を受け付けます",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "キャンバス操作", "canvasActions": "キャンバス操作",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Tamkarḍit tudmawant", "personalLib": "Tamkarḍit tudmawant",
"excalidrawLib": "Tamkarḍit n Excalidraw", "excalidrawLib": "Tamkarḍit n Excalidraw",
"decreaseFontSize": "Senqes tiddi n tsefsit", "decreaseFontSize": "Senqes tiddi n tsefsit",
"increaseFontSize": "Sali tiddi n tsefsit", "increaseFontSize": "Sali tiddi n tsefsit"
"unbindText": "",
"link": {
"edit": "Ẓreg aseɣwen",
"create": "Snulfu-d aseɣwen",
"label": "Aseɣwen"
}
}, },
"buttons": { "buttons": {
"clearReset": "Ales awennez n teɣzut n usuneɣ", "clearReset": "Ales awennez n teɣzut n usuneɣ",
@@ -192,9 +186,7 @@
"freedraw": "Suneɣ", "freedraw": "Suneɣ",
"text": "Aḍris", "text": "Aḍris",
"library": "Tamkarḍit", "library": "Tamkarḍit",
"lock": "Eǧǧ afecku n tefrayt yermed mbaɛd asuneɣ", "lock": "Eǧǧ afecku n tefrayt yermed mbaɛd asuneɣ"
"penMode": "",
"link": "Rnu/leqqem aseɣwen i talɣa yettwafernen"
}, },
"headings": { "headings": {
"canvasActions": "Tigawin n teɣzut n usuneɣ", "canvasActions": "Tigawin n teɣzut n usuneɣ",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "", "clearReset": "",
@@ -192,9 +186,7 @@
"freedraw": "", "freedraw": "",
"text": "Мәтін", "text": "Мәтін",
"library": "", "library": "",
"lock": "", "lock": ""
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "", "canvasActions": "",
+60 -68
View File
@@ -35,11 +35,11 @@
"arrowhead_arrow": "화살표", "arrowhead_arrow": "화살표",
"arrowhead_bar": "막대", "arrowhead_bar": "막대",
"arrowhead_dot": "점", "arrowhead_dot": "점",
"arrowhead_triangle": "삼각형", "arrowhead_triangle": "",
"fontSize": "글자 크기", "fontSize": "글자 크기",
"fontFamily": "글꼴", "fontFamily": "글꼴",
"onlySelected": "선택한 항목만", "onlySelected": "선택한 항목만",
"withBackground": "배경", "withBackground": "",
"exportEmbedScene": "", "exportEmbedScene": "",
"exportEmbedScene_details": "화면 정보가 내보내는 PNG/SVG 파일에 저장되어 이후에 파일에서 화면을 복구할 수 있습니다. 파일 크기가 증가합니다.", "exportEmbedScene_details": "화면 정보가 내보내는 PNG/SVG 파일에 저장되어 이후에 파일에서 화면을 복구할 수 있습니다. 파일 크기가 증가합니다.",
"addWatermark": "\"Made with Excalidraw\" 추가", "addWatermark": "\"Made with Excalidraw\" 추가",
@@ -62,14 +62,14 @@
"architect": "건축가", "architect": "건축가",
"artist": "예술가", "artist": "예술가",
"cartoonist": "만화가", "cartoonist": "만화가",
"fileTitle": "파일 이름", "fileTitle": "",
"colorPicker": "색상 선택기", "colorPicker": "색상 선택기",
"canvasBackground": "캔버스 배경", "canvasBackground": "캔버스 배경",
"drawingCanvas": "캔버스 그리기", "drawingCanvas": "캔버스 그리기",
"layers": "레이어", "layers": "레이어",
"actions": "동작", "actions": "동작",
"language": "언어", "language": "언어",
"liveCollaboration": "라이브 협력", "liveCollaboration": "",
"duplicateSelection": "복제", "duplicateSelection": "복제",
"untitled": "제목 없음", "untitled": "제목 없음",
"name": "이름", "name": "이름",
@@ -78,7 +78,7 @@
"group": "그룹 생성", "group": "그룹 생성",
"ungroup": "그룹 해제", "ungroup": "그룹 해제",
"collaborators": "공동 작업자", "collaborators": "공동 작업자",
"showGrid": "그리드 보기", "showGrid": "",
"addToLibrary": "라이브러리에 추가", "addToLibrary": "라이브러리에 추가",
"removeFromLibrary": "라이브러리에서 제거", "removeFromLibrary": "라이브러리에서 제거",
"libraryLoadingMessage": "라이브러리 불러오는 중…", "libraryLoadingMessage": "라이브러리 불러오는 중…",
@@ -93,36 +93,30 @@
"centerHorizontally": "수평으로 중앙 정렬", "centerHorizontally": "수평으로 중앙 정렬",
"distributeHorizontally": "수평으로 분배", "distributeHorizontally": "수평으로 분배",
"distributeVertically": "수직으로 분배", "distributeVertically": "수직으로 분배",
"flipHorizontal": "좌우반전", "flipHorizontal": "",
"flipVertical": "상하반전", "flipVertical": "",
"viewMode": "보기 모드", "viewMode": "보기 모드",
"toggleExportColorScheme": "", "toggleExportColorScheme": "",
"share": "공유", "share": "",
"showStroke": "", "showStroke": "",
"showBackground": "", "showBackground": "",
"toggleTheme": "", "toggleTheme": "",
"personalLib": "개인 라이브러리", "personalLib": "",
"excalidrawLib": "Excalidraw 라이브러리", "excalidrawLib": "",
"decreaseFontSize": "폰트 사이즈 줄이기", "decreaseFontSize": "",
"increaseFontSize": "폰트 사이즈 키우기", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "캔버스 초기화", "clearReset": "캔버스 초기화",
"exportJSON": "파일로 익스포트", "exportJSON": "",
"exportImage": "이미지로 저장", "exportImage": "",
"export": "내보내기", "export": "내보내기",
"exportToPng": "PNG로 내보내기", "exportToPng": "PNG로 내보내기",
"exportToSvg": "SVG로 내보내기", "exportToSvg": "SVG로 내보내기",
"copyToClipboard": "클립보드로 복사", "copyToClipboard": "클립보드로 복사",
"copyPngToClipboard": "클립보드로 PNG 이미지 복사", "copyPngToClipboard": "클립보드로 PNG 이미지 복사",
"scale": "크기", "scale": "크기",
"save": "현재 파일에 저장", "save": "",
"saveAs": "다른 이름으로 저장", "saveAs": "다른 이름으로 저장",
"load": "불러오기", "load": "불러오기",
"getShareableLink": "공유 가능한 링크 생성", "getShareableLink": "공유 가능한 링크 생성",
@@ -137,19 +131,19 @@
"edit": "수정", "edit": "수정",
"undo": "실행 취소", "undo": "실행 취소",
"redo": "다시 실행", "redo": "다시 실행",
"resetLibrary": "라이브러리 리셋", "resetLibrary": "",
"createNewRoom": "방 만들기", "createNewRoom": "방 만들기",
"fullScreen": "전체화면", "fullScreen": "전체화면",
"darkMode": "다크 모드", "darkMode": "다크 모드",
"lightMode": "밝은 모드", "lightMode": "밝은 모드",
"zenMode": "젠 모드", "zenMode": "젠 모드",
"exitZenMode": "젠 모드 종료하기", "exitZenMode": "젠 모드 종료하기",
"cancel": "취소", "cancel": "",
"clear": "지우기", "clear": "",
"remove": "삭제", "remove": "",
"publishLibrary": "게시하기", "publishLibrary": "",
"submit": "제출", "submit": "",
"confirm": "확인" "confirm": ""
}, },
"alerts": { "alerts": {
"clearReset": "모든 작업 내용이 초기화됩니다. 계속하시겠습니까?", "clearReset": "모든 작업 내용이 초기화됩니다. 계속하시겠습니까?",
@@ -164,8 +158,8 @@
"loadSceneOverridePrompt": "외부 파일을 불러 오면 기존 콘텐츠가 대체됩니다. 계속 진행할까요?", "loadSceneOverridePrompt": "외부 파일을 불러 오면 기존 콘텐츠가 대체됩니다. 계속 진행할까요?",
"collabStopOverridePrompt": "협업 세션을 종료하면 로컬 저장소에 있는 그림이 협업 세션의 그림으로 대체됩니다. 진행하겠습니까?\n\n(로컬 저장소에 있는 그림을 유지하려면 현재 브라우저 탭을 닫아주세요.)", "collabStopOverridePrompt": "협업 세션을 종료하면 로컬 저장소에 있는 그림이 협업 세션의 그림으로 대체됩니다. 진행하겠습니까?\n\n(로컬 저장소에 있는 그림을 유지하려면 현재 브라우저 탭을 닫아주세요.)",
"errorLoadingLibrary": "외부 라이브러리를 불러오는 중에 문제가 발생했습니다.", "errorLoadingLibrary": "외부 라이브러리를 불러오는 중에 문제가 발생했습니다.",
"errorAddingToLibrary": "아이템을 라이브러리에 추가 할수 없습니다", "errorAddingToLibrary": "",
"errorRemovingFromLibrary": "라이브러리에서 아이템을 삭제할수 없습니다", "errorRemovingFromLibrary": "",
"confirmAddLibrary": "{{numShapes}}개의 모양이 라이브러리에 추가됩니다. 계속하시겠어요?", "confirmAddLibrary": "{{numShapes}}개의 모양이 라이브러리에 추가됩니다. 계속하시겠어요?",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "",
"cannotRestoreFromImage": "이미지 파일에서 화면을 복구할 수 없었습니다", "cannotRestoreFromImage": "이미지 파일에서 화면을 복구할 수 없었습니다",
@@ -175,26 +169,24 @@
"invalidEncryptionKey": "" "invalidEncryptionKey": ""
}, },
"errors": { "errors": {
"unsupportedFileType": "지원하지 않는 파일 형식 입니다.", "unsupportedFileType": "",
"imageInsertError": "이미지를 삽입할 수 없습니다. 나중에 다시 시도 하십시오", "imageInsertError": "",
"fileTooBig": "", "fileTooBig": "",
"svgImageInsertError": "", "svgImageInsertError": "",
"invalidSVGString": "" "invalidSVGString": ""
}, },
"toolBar": { "toolBar": {
"selection": "선택", "selection": "선택",
"image": "이미지 삽입", "image": "",
"rectangle": "사각형", "rectangle": "사각형",
"diamond": "다이아몬드", "diamond": "다이아몬드",
"ellipse": "타원", "ellipse": "타원",
"arrow": "화살표", "arrow": "화살표",
"line": "선", "line": "선",
"freedraw": "그리기", "freedraw": "",
"text": "텍스트", "text": "텍스트",
"library": "라이브러리", "library": "라이브러리",
"lock": "선택된 도구 유지하기", "lock": "선택된 도구 유지하기"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "캔버스 동작", "canvasActions": "캔버스 동작",
@@ -253,14 +245,14 @@
"title": "오류" "title": "오류"
}, },
"exportDialog": { "exportDialog": {
"disk_title": "디스크에 저장", "disk_title": "",
"disk_details": "", "disk_details": "",
"disk_button": "파일로 저장", "disk_button": "",
"link_title": "공유 가능한 링크 생성", "link_title": "",
"link_details": "", "link_details": "",
"link_button": "링크로 내보내기", "link_button": "",
"excalidrawplus_description": "", "excalidrawplus_description": "",
"excalidrawplus_button": "내보내기", "excalidrawplus_button": "",
"excalidrawplus_exportError": "" "excalidrawplus_exportError": ""
}, },
"helpDialog": { "helpDialog": {
@@ -271,35 +263,35 @@
"curvedArrow": "곡선 화살표", "curvedArrow": "곡선 화살표",
"curvedLine": "곡선", "curvedLine": "곡선",
"documentation": "설명서", "documentation": "설명서",
"doubleClick": "더블 클릭", "doubleClick": "",
"drag": "드래그", "drag": "드래그",
"editor": "에디터", "editor": "에디터",
"editSelectedShape": "선택한 도형 편집하기(텍스트/화살표/라인)", "editSelectedShape": "",
"github": "문제 제보하기", "github": "문제 제보하기",
"howto": "가이드 참고하기", "howto": "가이드 참고하기",
"or": "또는", "or": "또는",
"preventBinding": "화살표가 붙지 않게 하기", "preventBinding": "화살표가 붙지 않게 하기",
"shapes": "도형", "shapes": "도형",
"shortcuts": "키보드 단축키", "shortcuts": "키보드 단축키",
"textFinish": "편집 완료 (텍스트 에디터)", "textFinish": "",
"textNewLine": "줄바꿈(텍스트 에디터)", "textNewLine": "",
"title": "도움말", "title": "도움말",
"view": "보기", "view": "보기",
"zoomToFit": "모든 요소가 보이도록 확대/축소", "zoomToFit": "모든 요소가 보이도록 확대/축소",
"zoomToSelection": "선택 영역으로 확대/축소" "zoomToSelection": "선택 영역으로 확대/축소"
}, },
"clearCanvasDialog": { "clearCanvasDialog": {
"title": "캔버스 지우기" "title": ""
}, },
"publishDialog": { "publishDialog": {
"title": "", "title": "",
"itemName": "아이템 이름", "itemName": "",
"authorName": "저자명", "authorName": "",
"githubUsername": "깃허브 사용자이름", "githubUsername": "",
"twitterUsername": "트위터 사용자이름", "twitterUsername": "",
"libraryName": "라이브러리 이름", "libraryName": "",
"libraryDesc": "", "libraryDesc": "",
"website": "웹사이트", "website": "",
"placeholder": { "placeholder": {
"authorName": "", "authorName": "",
"libraryName": "", "libraryName": "",
@@ -309,7 +301,7 @@
"website": "" "website": ""
}, },
"errors": { "errors": {
"required": "필수사항", "required": "",
"website": "" "website": ""
}, },
"noteDescription": { "noteDescription": {
@@ -319,12 +311,12 @@
}, },
"noteGuidelines": { "noteGuidelines": {
"pre": "", "pre": "",
"link": "가이드라인", "link": "",
"post": "" "post": ""
}, },
"noteLicense": { "noteLicense": {
"pre": "", "pre": "",
"link": "MIT 라이선스, ", "link": "",
"post": "" "post": ""
}, },
"noteItems": "", "noteItems": "",
@@ -333,10 +325,10 @@
"publishSuccessDialog": { "publishSuccessDialog": {
"title": "", "title": "",
"content": "", "content": "",
"link": "여기" "link": ""
}, },
"confirmDialog": { "confirmDialog": {
"resetLibrary": "라이브러리 리셋", "resetLibrary": "",
"removeItemsFromLib": "" "removeItemsFromLib": ""
}, },
"encrypted": { "encrypted": {
@@ -359,21 +351,21 @@
"width": "너비" "width": "너비"
}, },
"toast": { "toast": {
"addedToLibrary": "라이브러리에 추가되었습니다", "addedToLibrary": "",
"copyStyles": "스타일 복사.", "copyStyles": "스타일 복사.",
"copyToClipboard": "클립보드로 복사.", "copyToClipboard": "클립보드로 복사.",
"copyToClipboardAsPng": "", "copyToClipboardAsPng": "",
"fileSaved": "파일이 저장되었습니다.", "fileSaved": "",
"fileSavedToFilename": "{filename} 로 저장되었습니다", "fileSavedToFilename": "",
"canvas": "캔버스", "canvas": "",
"selection": "선택" "selection": ""
}, },
"colors": { "colors": {
"ffffff": "화이트", "ffffff": "",
"f8f9fa": "그레이 0", "f8f9fa": "",
"f1f3f5": "그레이 1", "f1f3f5": "",
"fff5f5": "레드 0", "fff5f5": "",
"fff0f6": "핑크 0", "fff0f6": "",
"f8f0fc": "", "f8f0fc": "",
"f3f0ff": "", "f3f0ff": "",
"edf2ff": "", "edf2ff": "",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Asmeninė biblioteka", "personalLib": "Asmeninė biblioteka",
"excalidrawLib": "Exaclidraw biblioteka", "excalidrawLib": "Exaclidraw biblioteka",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "", "clearReset": "",
@@ -192,9 +186,7 @@
"freedraw": "Piešti", "freedraw": "Piešti",
"text": "Tekstas", "text": "Tekstas",
"library": "Biblioteka", "library": "Biblioteka",
"lock": "", "lock": ""
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "", "canvasActions": "",
+5 -13
View File
@@ -104,13 +104,7 @@
"personalLib": "Personīgā bibliotēka", "personalLib": "Personīgā bibliotēka",
"excalidrawLib": "Excalidraw bibliotēka", "excalidrawLib": "Excalidraw bibliotēka",
"decreaseFontSize": "Samazināt fonta izmēru", "decreaseFontSize": "Samazināt fonta izmēru",
"increaseFontSize": "Palielināt fonta izmēru", "increaseFontSize": "Palielināt fonta izmēru"
"unbindText": "Atdalīt tekstu",
"link": {
"edit": "Rediģēt saiti",
"create": "Izveidot saiti",
"label": "Saite"
}
}, },
"buttons": { "buttons": {
"clearReset": "Atiestatīt tāfeli", "clearReset": "Atiestatīt tāfeli",
@@ -157,7 +151,7 @@
"couldNotCreateShareableLinkTooBig": "Nevarēja izveidot kopīgojamo saiti – aina ir par lielu", "couldNotCreateShareableLinkTooBig": "Nevarēja izveidot kopīgojamo saiti – aina ir par lielu",
"couldNotLoadInvalidFile": "Nevarēja ielādēt nederīgu datni", "couldNotLoadInvalidFile": "Nevarēja ielādēt nederīgu datni",
"importBackendFailed": "Ielāde no krātuves neizdevās.", "importBackendFailed": "Ielāde no krātuves neizdevās.",
"cannotExportEmptyCanvas": "Nevar eksportēt tukšu tāfeli.", "cannotExportEmptyCanvas": "Nevar eksportēt tukšu zīmējumu.",
"couldNotCopyToClipboard": "Neizdevās kopēt starpliktuvē. Mēģiniet vēlreiz, izmantojot pārlūku Chrome.", "couldNotCopyToClipboard": "Neizdevās kopēt starpliktuvē. Mēģiniet vēlreiz, izmantojot pārlūku Chrome.",
"decryptFailed": "Nevarēja atšifrēt datus.", "decryptFailed": "Nevarēja atšifrēt datus.",
"uploadedSecurly": "Augšuplāde nodrošināta ar šifrēšanu no gala līdz galam, kas nozīmē, ka Excalidraw serveri un trešās puses nevar lasīt saturu.", "uploadedSecurly": "Augšuplāde nodrošināta ar šifrēšanu no gala līdz galam, kas nozīmē, ka Excalidraw serveri un trešās puses nevar lasīt saturu.",
@@ -192,9 +186,7 @@
"freedraw": "Zīmēt", "freedraw": "Zīmēt",
"text": "Teksts", "text": "Teksts",
"library": "Bibliotēka", "library": "Bibliotēka",
"lock": "Paturēt izvēlēto rīku pēc darbības", "lock": "Paturēt izvēlēto rīku pēc darbības"
"penMode": "Lietojot pildspalvu, bloķēt tuvināšanu un atļaut tikai zīmēšanu",
"link": "Pievienot/rediģēt atlasītās figūras saiti"
}, },
"headings": { "headings": {
"canvasActions": "Tāfeles darbības", "canvasActions": "Tāfeles darbības",
@@ -274,12 +266,12 @@
"doubleClick": "dubultklikšķis", "doubleClick": "dubultklikšķis",
"drag": "vilkt", "drag": "vilkt",
"editor": "Redaktors", "editor": "Redaktors",
"editSelectedShape": "Rediģēt atlasīto figūru (tekstu/bultu/līniju)", "editSelectedShape": "Rediģēt atlasīto formu (tekstu/bultu/līniju)",
"github": "Sastapāt kļūdu? Ziņot", "github": "Sastapāt kļūdu? Ziņot",
"howto": "Sekojiet mūsu instrukcijām", "howto": "Sekojiet mūsu instrukcijām",
"or": "vai", "or": "vai",
"preventBinding": "Novērst bultu piesaistīšanos", "preventBinding": "Novērst bultu piesaistīšanos",
"shapes": "Figūras", "shapes": "Formas",
"shortcuts": "Tastatūras saīsnes", "shortcuts": "Tastatūras saīsnes",
"textFinish": "Pabeigt rediģēšanu (teksta redaktorā)", "textFinish": "Pabeigt rediģēšanu (teksta redaktorā)",
"textNewLine": "Nākamā rindiņa (teksta redaktorā)", "textNewLine": "Nākamā rindiņa (teksta redaktorā)",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "ကားချပ်ရှင်းလင်း", "clearReset": "ကားချပ်ရှင်းလင်း",
@@ -192,9 +186,7 @@
"freedraw": "", "freedraw": "",
"text": "စာသား", "text": "စာသား",
"library": "မှတ်တမ်း", "library": "မှတ်တမ်း",
"lock": "ရွေးချယ်ထားသောကိရိယာကိုသာဆက်သုံး", "lock": "ရွေးချယ်ထားသောကိရိယာကိုသာဆက်သုံး"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "ကားချပ်လုပ်ဆောင်ချက်", "canvasActions": "ကားချပ်လုပ်ဆောင်ချက်",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Personlig bibliotek", "personalLib": "Personlig bibliotek",
"excalidrawLib": "Excalidraw-bibliotek", "excalidrawLib": "Excalidraw-bibliotek",
"decreaseFontSize": "Reduser skriftstørrelse", "decreaseFontSize": "Reduser skriftstørrelse",
"increaseFontSize": "Øk skriftstørrelse", "increaseFontSize": "Øk skriftstørrelse"
"unbindText": "Avbind tekst",
"link": {
"edit": "Rediger lenke",
"create": "Opprett lenke",
"label": "Lenke"
}
}, },
"buttons": { "buttons": {
"clearReset": "Tøm lerretet og tilbakestill bakgrunnsfargen", "clearReset": "Tøm lerretet og tilbakestill bakgrunnsfargen",
@@ -192,9 +186,7 @@
"freedraw": "Tegn", "freedraw": "Tegn",
"text": "Tekst", "text": "Tekst",
"library": "Bibliotek", "library": "Bibliotek",
"lock": "Behold merket verktøy som aktivt", "lock": "Behold merket verktøy som aktivt"
"penMode": "Forhindre zoom ved kniping og godta frihåndstegning kun fra penn",
"link": "Legg til / oppdater link for en valgt figur"
}, },
"headings": { "headings": {
"canvasActions": "Handlinger: lerret", "canvasActions": "Handlinger: lerret",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Persoonlijke bibliotheek", "personalLib": "Persoonlijke bibliotheek",
"excalidrawLib": "Excalidraw bibliotheek", "excalidrawLib": "Excalidraw bibliotheek",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "Ontkoppel tekst",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Canvas opnieuw instellen", "clearReset": "Canvas opnieuw instellen",
@@ -192,9 +186,7 @@
"freedraw": "Tekenen", "freedraw": "Tekenen",
"text": "Tekst", "text": "Tekst",
"library": "Bibliotheek", "library": "Bibliotheek",
"lock": "Geselecteerde tool actief houden na tekenen", "lock": "Geselecteerde tool actief houden na tekenen"
"penMode": "Voorkom pinch-zoom en accepteer freedraw invoer alleen van pen",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Canvasacties", "canvasActions": "Canvasacties",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Tilbakestill lerretet", "clearReset": "Tilbakestill lerretet",
@@ -192,9 +186,7 @@
"freedraw": "Teikn", "freedraw": "Teikn",
"text": "Tekst", "text": "Tekst",
"library": "Bibliotek", "library": "Bibliotek",
"lock": "Hald fram med valt verktøy", "lock": "Hald fram med valt verktøy"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Handlingar: lerret", "canvasActions": "Handlingar: lerret",
+4 -12
View File
@@ -103,14 +103,8 @@
"toggleTheme": "Alternar tèma", "toggleTheme": "Alternar tèma",
"personalLib": "Bibliotèca personala", "personalLib": "Bibliotèca personala",
"excalidrawLib": "Bibliotèca Excalidraw", "excalidrawLib": "Bibliotèca Excalidraw",
"decreaseFontSize": "Reduire talha poliça", "decreaseFontSize": "",
"increaseFontSize": "Aumentar talha poliça", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Reïnicializar lo canabàs", "clearReset": "Reïnicializar lo canabàs",
@@ -192,9 +186,7 @@
"freedraw": "Dessenhar", "freedraw": "Dessenhar",
"text": "Tèxt", "text": "Tèxt",
"library": "Bibliotèca", "library": "Bibliotèca",
"lock": "Mantenir activa l’aisina aprèp dessenhar", "lock": "Mantenir activa l’aisina aprèp dessenhar"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Accions del canabàs", "canvasActions": "Accions del canabàs",
@@ -310,7 +302,7 @@
}, },
"errors": { "errors": {
"required": "Requerit", "required": "Requerit",
"website": "Picatz una URL valida" "website": ""
}, },
"noteDescription": { "noteDescription": {
"pre": "Enviatz vòstra bibliotèca per èsser compresa al ", "pre": "Enviatz vòstra bibliotèca per èsser compresa al ",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "ਨਿੱਜੀ ਲਾਇਬ੍ਰੇਰੀ", "personalLib": "ਨਿੱਜੀ ਲਾਇਬ੍ਰੇਰੀ",
"excalidrawLib": "ਐਕਸਕਲੀਡਰਾਅ ਲਾਇਬ੍ਰੇਰੀ", "excalidrawLib": "ਐਕਸਕਲੀਡਰਾਅ ਲਾਇਬ੍ਰੇਰੀ",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "ਕੈਨਵਸ ਰੀਸੈੱਟ ਕਰੋ", "clearReset": "ਕੈਨਵਸ ਰੀਸੈੱਟ ਕਰੋ",
@@ -192,9 +186,7 @@
"freedraw": "ਵਾਹੋ", "freedraw": "ਵਾਹੋ",
"text": "ਪਾਠ", "text": "ਪਾਠ",
"library": "ਲਾਇਬ੍ਰੇਰੀ", "library": "ਲਾਇਬ੍ਰੇਰੀ",
"lock": "ਡਰਾਇੰਗ ਤੋਂ ਬਾਅਦ ਵੀ ਚੁਣੇ ਹੋਏ ਸੰਦ ਨੂੰ ਸਰਗਰਮ ਰੱਖੋ ", "lock": "ਡਰਾਇੰਗ ਤੋਂ ਬਾਅਦ ਵੀ ਚੁਣੇ ਹੋਏ ਸੰਦ ਨੂੰ ਸਰਗਰਮ ਰੱਖੋ "
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "ਕੈਨਵਸ ਦੀਆਂ ਕਾਰਵਾਈਆਂ", "canvasActions": "ਕੈਨਵਸ ਦੀਆਂ ਕਾਰਵਾਈਆਂ",
+30 -30
View File
@@ -1,47 +1,47 @@
{ {
"ar-SA": 88, "ar-SA": 88,
"bg-BG": 61, "bg-BG": 62,
"bn-BD": 0, "bn-BD": 0,
"ca-ES": 95, "ca-ES": 97,
"cs-CZ": 24, "cs-CZ": 24,
"da-DK": 16, "da-DK": 17,
"de-DE": 99, "de-DE": 100,
"el-GR": 87, "el-GR": 88,
"en": 100, "en": 100,
"es-ES": 84, "es-ES": 86,
"eu-ES": 96, "eu-ES": 84,
"fa-IR": 63, "fa-IR": 64,
"fi-FI": 98, "fi-FI": 97,
"fr-FR": 100, "fr-FR": 100,
"he-IL": 80, "he-IL": 82,
"hi-IN": 55, "hi-IN": 56,
"hu-HU": 49, "hu-HU": 50,
"id-ID": 100, "id-ID": 100,
"it-IT": 96, "it-IT": 98,
"ja-JP": 98, "ja-JP": 98,
"kab-KAB": 95, "kab-KAB": 96,
"kk-KZ": 23, "kk-KZ": 23,
"ko-KR": 72, "ko-KR": 57,
"lt-LT": 24, "lt-LT": 24,
"lv-LV": 100, "lv-LV": 100,
"my-MM": 46, "my-MM": 47,
"nb-NO": 100, "nb-NO": 100,
"nl-NL": 90, "nl-NL": 91,
"nn-NO": 83, "nn-NO": 85,
"oc-FR": 97, "oc-FR": 98,
"pa-IN": 87, "pa-IN": 88,
"pl-PL": 93, "pl-PL": 95,
"pt-BR": 98, "pt-BR": 100,
"pt-PT": 83, "pt-PT": 85,
"ro-RO": 100, "ro-RO": 100,
"ru-RU": 99, "ru-RU": 100,
"si-LK": 9, "si-LK": 9,
"sk-SK": 100, "sk-SK": 99,
"sv-SE": 100, "sv-SE": 99,
"ta-IN": 99, "ta-IN": 97,
"tr-TR": 85, "tr-TR": 86,
"uk-UA": 82, "uk-UA": 83,
"zh-CN": 100, "zh-CN": 100,
"zh-HK": 28, "zh-HK": 29,
"zh-TW": 100 "zh-TW": 100
} }
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Biblioteka prywatna", "personalLib": "Biblioteka prywatna",
"excalidrawLib": "Biblioteka Excalidraw", "excalidrawLib": "Biblioteka Excalidraw",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Wyczyść dokument i zresetuj kolor dokumentu", "clearReset": "Wyczyść dokument i zresetuj kolor dokumentu",
@@ -192,9 +186,7 @@
"freedraw": "Rysuj", "freedraw": "Rysuj",
"text": "Tekst", "text": "Tekst",
"library": "Biblioteka", "library": "Biblioteka",
"lock": "Zablokuj wybrane narzędzie", "lock": "Zablokuj wybrane narzędzie"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Narzędzia", "canvasActions": "Narzędzia",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Biblioteca Pessoal", "personalLib": "Biblioteca Pessoal",
"excalidrawLib": "Biblioteca do Excalidraw", "excalidrawLib": "Biblioteca do Excalidraw",
"decreaseFontSize": "Diminuir o tamanho da fonte", "decreaseFontSize": "Diminuir o tamanho da fonte",
"increaseFontSize": "Aumentar o tamanho da fonte", "increaseFontSize": "Aumentar o tamanho da fonte"
"unbindText": "Desvincular texto",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Limpar o canvas e redefinir a cor de fundo", "clearReset": "Limpar o canvas e redefinir a cor de fundo",
@@ -192,9 +186,7 @@
"freedraw": "Desenhar", "freedraw": "Desenhar",
"text": "Texto", "text": "Texto",
"library": "Biblioteca", "library": "Biblioteca",
"lock": "Manter ativa a ferramenta selecionada após desenhar", "lock": "Manter ativa a ferramenta selecionada após desenhar"
"penMode": "Prevenir a ação de tocar-ampliar e permitir apenas interações da caneta",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Ações da tela", "canvasActions": "Ações da tela",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Limpar a área de desenho e redefinir a cor de fundo", "clearReset": "Limpar a área de desenho e redefinir a cor de fundo",
@@ -192,9 +186,7 @@
"freedraw": "Desenhar", "freedraw": "Desenhar",
"text": "Texto", "text": "Texto",
"library": "Biblioteca", "library": "Biblioteca",
"lock": "Manter a ferramenta selecionada ativa após desenhar", "lock": "Manter a ferramenta selecionada ativa após desenhar"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Ações da área de desenho", "canvasActions": "Ações da área de desenho",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Biblioteca personală", "personalLib": "Biblioteca personală",
"excalidrawLib": "Biblioteca Excalidraw", "excalidrawLib": "Biblioteca Excalidraw",
"decreaseFontSize": "Micșorează dimensiunea fontului", "decreaseFontSize": "Micșorează dimensiunea fontului",
"increaseFontSize": "Mărește dimensiunea fontului", "increaseFontSize": "Mărește dimensiunea fontului"
"unbindText": "Deconectare text",
"link": {
"edit": "Editare URL",
"create": "Creare URL",
"label": "URL"
}
}, },
"buttons": { "buttons": {
"clearReset": "Resetare pânză", "clearReset": "Resetare pânză",
@@ -192,9 +186,7 @@
"freedraw": "Desenare", "freedraw": "Desenare",
"text": "Text", "text": "Text",
"library": "Bibliotecă", "library": "Bibliotecă",
"lock": "Menține activ instrumentul selectat după desenare", "lock": "Menține activ instrumentul selectat după desenare"
"penMode": "Împiedică mărirea prin ciupire și acceptă desenarea liberă doar de la stilou",
"link": "Adăugare/actualizare URL pentru forma selectată"
}, },
"headings": { "headings": {
"canvasActions": "Acțiuni pentru pânză", "canvasActions": "Acțiuni pentru pânză",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Личная библиотека", "personalLib": "Личная библиотека",
"excalidrawLib": "Библиотека Excalidraw", "excalidrawLib": "Библиотека Excalidraw",
"decreaseFontSize": "Уменьшить шрифт", "decreaseFontSize": "Уменьшить шрифт",
"increaseFontSize": "Увеличить шрифт", "increaseFontSize": "Увеличить шрифт"
"unbindText": "Отвязать текст",
"link": {
"edit": "Редактировать ссылку",
"create": "Создать ссылку",
"label": "Ссылка"
}
}, },
"buttons": { "buttons": {
"clearReset": "Очистить холст и сбросить цвет фона", "clearReset": "Очистить холст и сбросить цвет фона",
@@ -192,9 +186,7 @@
"freedraw": "Чертить", "freedraw": "Чертить",
"text": "Текст", "text": "Текст",
"library": "Библиотека", "library": "Библиотека",
"lock": "Сохранять выбранный инструмент активным после рисования", "lock": "Сохранять выбранный инструмент активным после рисования"
"penMode": "",
"link": "Добавить/обновить ссылку для выбранной фигуры"
}, },
"headings": { "headings": {
"canvasActions": "Операции холста", "canvasActions": "Операции холста",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "", "clearReset": "",
@@ -192,9 +186,7 @@
"freedraw": "", "freedraw": "",
"text": "", "text": "",
"library": "", "library": "",
"lock": "", "lock": ""
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "", "canvasActions": "",
+4 -12
View File
@@ -103,14 +103,8 @@
"toggleTheme": "Prepnúť tému", "toggleTheme": "Prepnúť tému",
"personalLib": "Moja knižnica", "personalLib": "Moja knižnica",
"excalidrawLib": "Excalidraw knižnica", "excalidrawLib": "Excalidraw knižnica",
"decreaseFontSize": "Zmenšiť veľkosť písma", "decreaseFontSize": "",
"increaseFontSize": "Zväčšiť veľkosť písma", "increaseFontSize": ""
"unbindText": "Zrušiť previazanie textu",
"link": {
"edit": "Upraviť odkaz",
"create": "Vytvoriť odkaz",
"label": "Odkaz"
}
}, },
"buttons": { "buttons": {
"clearReset": "Obnoviť plátno", "clearReset": "Obnoviť plátno",
@@ -192,9 +186,7 @@
"freedraw": "Kresliť", "freedraw": "Kresliť",
"text": "Text", "text": "Text",
"library": "Knižnica", "library": "Knižnica",
"lock": "Nechať zvolený nástroj aktívny po skončení kreslenia", "lock": "Nechať zvolený nástroj aktívny po skončení kreslenia"
"penMode": "Zabrániť priblíženiu potiahnutím a povoliť vstup voľnou rokou iba z pera",
"link": "Pridať/ Upraviť odkaz pre vybraný tvar"
}, },
"headings": { "headings": {
"canvasActions": "Akcie plátna", "canvasActions": "Akcie plátna",
@@ -303,7 +295,7 @@
"placeholder": { "placeholder": {
"authorName": "Vaše meno alebo užívateľské meno", "authorName": "Vaše meno alebo užívateľské meno",
"libraryName": "Názov vašej knižnice", "libraryName": "Názov vašej knižnice",
"libraryDesc": "Popis vašej knižnice, ktorý ostatným pomôže porozumieť jej vhodnému použitiu", "libraryDesc": "",
"githubHandle": "GitHub užívateľské meno (nepovinné), aby ste mohli robiť úpravy po tom, čo bude knižnica uverejnená na schválenie", "githubHandle": "GitHub užívateľské meno (nepovinné), aby ste mohli robiť úpravy po tom, čo bude knižnica uverejnená na schválenie",
"twitterHandle": "Twitter užívateľské meno (nepovinné), aby sme vedeli komu pripísať zásluhu pri propagovaní cez Twitter", "twitterHandle": "Twitter užívateľské meno (nepovinné), aby sme vedeli komu pripísať zásluhu pri propagovaní cez Twitter",
"website": "Odkaz na vašu osobnú webovú stránku alebo niekam inam (nepovinné)" "website": "Odkaz na vašu osobnú webovú stránku alebo niekam inam (nepovinné)"
+3 -11
View File
@@ -103,14 +103,8 @@
"toggleTheme": "Växla tema", "toggleTheme": "Växla tema",
"personalLib": "Personligt bibliotek", "personalLib": "Personligt bibliotek",
"excalidrawLib": "Excalidraw bibliotek", "excalidrawLib": "Excalidraw bibliotek",
"decreaseFontSize": "Minska fontstorleken", "decreaseFontSize": "",
"increaseFontSize": "Öka fontstorleken", "increaseFontSize": ""
"unbindText": "Koppla bort text",
"link": {
"edit": "Redigera länk",
"create": "Skapa länk",
"label": "Länk"
}
}, },
"buttons": { "buttons": {
"clearReset": "Återställ canvasen", "clearReset": "Återställ canvasen",
@@ -192,9 +186,7 @@
"freedraw": "Rita", "freedraw": "Rita",
"text": "Text", "text": "Text",
"library": "Bibliotek", "library": "Bibliotek",
"lock": "Håll valt verktyg aktivt efter ritande", "lock": "Håll valt verktyg aktivt efter ritande"
"penMode": "Förhindra nypzoom och acceptera endast frihandsteckning från penna",
"link": "Lägg till / Uppdatera länk för en vald form"
}, },
"headings": { "headings": {
"canvasActions": "Canvas-åtgärder", "canvasActions": "Canvas-åtgärder",
+9 -17
View File
@@ -40,7 +40,7 @@
"fontFamily": "எழுத்துரு குடும்பம்", "fontFamily": "எழுத்துரு குடும்பம்",
"onlySelected": "தேர்ந்ததை மட்டும்", "onlySelected": "தேர்ந்ததை மட்டும்",
"withBackground": "பின்புலம்", "withBackground": "பின்புலம்",
"exportEmbedScene": "காட்சியை உட்பொதி", "exportEmbedScene": "கட்சியை உட்பொதி",
"exportEmbedScene_details": "காட்சி தரவு ஏற்றுமதி செய்யப்பட்ட PNG/SVG கோப்பினுள் சேமிக்கப்படும் இதனால் காட்சியை அதிலிருந்து மீட்டெடுக்க முடியும். ஏற்றுமதி செய்யப்பட்ட கோப்பின் அளவை அதிகரிக்கும்.", "exportEmbedScene_details": "காட்சி தரவு ஏற்றுமதி செய்யப்பட்ட PNG/SVG கோப்பினுள் சேமிக்கப்படும் இதனால் காட்சியை அதிலிருந்து மீட்டெடுக்க முடியும். ஏற்றுமதி செய்யப்பட்ட கோப்பின் அளவை அதிகரிக்கும்.",
"addWatermark": "\"எக்ஸ்கேலிட்ரா கொண்டு ஆனது\"-ஐச் சேர்", "addWatermark": "\"எக்ஸ்கேலிட்ரா கொண்டு ஆனது\"-ஐச் சேர்",
"handDrawn": "கையால்-வரைந்த", "handDrawn": "கையால்-வரைந்த",
@@ -103,14 +103,8 @@
"toggleTheme": "தோற்றத்தை நிலைமாற்று", "toggleTheme": "தோற்றத்தை நிலைமாற்று",
"personalLib": "தனக்குரிய நூலகம்", "personalLib": "தனக்குரிய நூலகம்",
"excalidrawLib": "எக்ஸ்கேலிட்ரா நூலகம்", "excalidrawLib": "எக்ஸ்கேலிட்ரா நூலகம்",
"decreaseFontSize": "எழுத்துரு அளவைக் குறை", "decreaseFontSize": "",
"increaseFontSize": "எழுத்துரு அளவை அதிகரி", "increaseFontSize": ""
"unbindText": "உரையைப் பிணைவவிழ்",
"link": {
"edit": "தொடுப்பைத் திருத்து",
"create": "தொடுப்பைப் படை",
"label": "தொடுப்பு"
}
}, },
"buttons": { "buttons": {
"clearReset": "கித்தானை அகரமாக்கு", "clearReset": "கித்தானை அகரமாக்கு",
@@ -162,7 +156,7 @@
"decryptFailed": "தரவை மறைநீக்க முடியவில்லை.", "decryptFailed": "தரவை மறைநீக்க முடியவில்லை.",
"uploadedSecurly": "பதிவேற்றம் இருமுனை மறையாகத்தால் பாதுகாக்கப்பட்டுள்ளது, எனவே எக்ஸ்கேலிட்ரா சேவையகமும் மூன்றாம் தரப்பினரும் உள்ளடக்கத்தை வாசிக்கமுடியாது.", "uploadedSecurly": "பதிவேற்றம் இருமுனை மறையாகத்தால் பாதுகாக்கப்பட்டுள்ளது, எனவே எக்ஸ்கேலிட்ரா சேவையகமும் மூன்றாம் தரப்பினரும் உள்ளடக்கத்தை வாசிக்கமுடியாது.",
"loadSceneOverridePrompt": "வெளிப்புறச்சித்திரமேற்றல் இருக்கிற உள்ளடக்கத்தை இடங்கொள்ளும். தொடர விருப்பமா?", "loadSceneOverridePrompt": "வெளிப்புறச்சித்திரமேற்றல் இருக்கிற உள்ளடக்கத்தை இடங்கொள்ளும். தொடர விருப்பமா?",
"collabStopOverridePrompt": "அமர்வை நிறுத்துதல் முன்னர் அகமாக தேக்கிய உம் சித்திரத்தை மேலெழுதும். நீங்கள் உறுதியா?\n\n(உம் அக சித்திரத்தை வைக்கவேண்டுமெனில், சும்மா உலாவி தாவலை மூடுக அதற்குபதிலாக.)", "collabStopOverridePrompt": "",
"errorLoadingLibrary": "மூன்றாம் தரப்பு நூலகத்தை ஏற்றுவதில் பிழை.", "errorLoadingLibrary": "மூன்றாம் தரப்பு நூலகத்தை ஏற்றுவதில் பிழை.",
"errorAddingToLibrary": "உருப்படியை நூலகத்தில் சேர்க்க இயலா", "errorAddingToLibrary": "உருப்படியை நூலகத்தில் சேர்க்க இயலா",
"errorRemovingFromLibrary": "உருப்படியை நூலகத்திலிருந்து நீக்க இயலா", "errorRemovingFromLibrary": "உருப்படியை நூலகத்திலிருந்து நீக்க இயலா",
@@ -192,9 +186,7 @@
"freedraw": "வரை", "freedraw": "வரை",
"text": "உரை", "text": "உரை",
"library": "நூலகம்", "library": "நூலகம்",
"lock": "தேர்ந்த கருவியை வரைந்த பின்பும் வைத்திரு", "lock": "தேர்ந்த கருவியை வரைந்த பின்பும் வைத்திரு"
"penMode": "கிள்ளிப்பெரிதாக்குவதைத் தவிர் மற்றும் பேனாவிலிருந்து மட்டும் கட்டற்றவரைவை ஏல்",
"link": "தேர்தெடுத்த வடிவத்திற்குத் தொடுப்பைச் சேர்/ புதுப்பி"
}, },
"headings": { "headings": {
"canvasActions": "கித்தான் செயல்கள்", "canvasActions": "கித்தான் செயல்கள்",
@@ -209,17 +201,17 @@
"text_selected": "உரையைத் திருத்த இரு-சொடுக்கு அ ENTERஐ அழுத்து", "text_selected": "உரையைத் திருத்த இரு-சொடுக்கு அ ENTERஐ அழுத்து",
"text_editing": "திருத்துவதை முடிக்க Escape அ CtrlOrCmd+ENTERஐ அழுத்து", "text_editing": "திருத்துவதை முடிக்க Escape அ CtrlOrCmd+ENTERஐ அழுத்து",
"linearElementMulti": "கடைசி புள்ளியில் சொடுக்கு அ முடிக்க Escape அ Enter அழுத்து", "linearElementMulti": "கடைசி புள்ளியில் சொடுக்கு அ முடிக்க Escape அ Enter அழுத்து",
"lockAngle": "SHIFTஐ அழுத்திப்பிடித்து கோணத்தை வற்புறுத்தலாம்", "lockAngle": "",
"resize": "மறுஅளவிடுகையில் SHIFTஐ அழுத்திப்பிடித்து விகிதசமத்தை வற்புறுத்தலாம்,\nமையத்திலிருந்து மறுஅளவிட ALTஐ அழுத்திப்பிடி", "resize": "",
"resizeImage": "SHIFTஐ நீண்டழுத்தி கட்டற்று அளவுமாற்றலாம்,\nமையத்திலிருந்து அளவுமாற்ற ALTஐ நீண்டழுத்துக", "resizeImage": "SHIFTஐ நீண்டழுத்தி கட்டற்று அளவுமாற்றலாம்,\nமையத்திலிருந்து அளவுமாற்ற ALTஐ நீண்டழுத்துக",
"rotate": "சுழற்றுகையில் SHIFTஐ அழுத்திப்பிடித்து கோணங்களை வற்புறுத்தலாம்", "rotate": "",
"lineEditor_info": "புள்ளிகளைத் திருத்த இரு-சொடுக்கு அ Enterஐ அழுத்து", "lineEditor_info": "புள்ளிகளைத் திருத்த இரு-சொடுக்கு அ Enterஐ அழுத்து",
"lineEditor_pointSelected": "புள்ளி(கள்)ஐ நீக்க Deleteஐ அழுத்து,\nநகலாக்க CtrlOrCmd+D, அ நகர்த்த பிடித்திழு", "lineEditor_pointSelected": "புள்ளி(கள்)ஐ நீக்க Deleteஐ அழுத்து,\nநகலாக்க CtrlOrCmd+D, அ நகர்த்த பிடித்திழு",
"lineEditor_nothingSelected": "திருத்த புள்ளியைத் தேர்ந்தெடு (பலவற்றை தேர SHIFTஐ அழுத்திப்பிடி),\nஅ புதிய புள்ளிகளைச் சேர்க்க Altஐ அழுத்திப்பிடித்துச் சொடுக்கு", "lineEditor_nothingSelected": "திருத்த புள்ளியைத் தேர்ந்தெடு (பலவற்றை தேர SHIFTஐ அழுத்திப்பிடி),\nஅ புதிய புள்ளிகளைச் சேர்க்க Altஐ அழுத்திப்பிடித்துச் சொடுக்கு",
"placeImage": "படத்தை வைக்கச் சொடுக்கு, அ கைமுறையாக அளவு அமைக்க சொடுக்கி பிடித்திழு", "placeImage": "படத்தை வைக்கச் சொடுக்கு, அ கைமுறையாக அளவு அமைக்க சொடுக்கி பிடித்திழு",
"publishLibrary": "உம் சொந்த நூலகத்தைப் பிரசுரி", "publishLibrary": "உம் சொந்த நூலகத்தைப் பிரசுரி",
"bindTextToElement": "உரையைச் சேர்க்க enterஐ அழுத்து", "bindTextToElement": "உரையைச் சேர்க்க enterஐ அழுத்து",
"deepBoxSelect": "ஆழ்ந்துத் தேரவும் பிடித்திழுத்தலைத் தவிர்க்கவும் CtrlOrCmdஐ அழுத்திப்பிடி" "deepBoxSelect": ""
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "முன்னோட்டம் காட்ட இயலவில்லை", "cannotShowPreview": "முன்னோட்டம் காட்ட இயலவில்லை",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "Kişisel Kitaplık", "personalLib": "Kişisel Kitaplık",
"excalidrawLib": "Excalidraw Kitaplığı", "excalidrawLib": "Excalidraw Kitaplığı",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Tuvali sıfırla", "clearReset": "Tuvali sıfırla",
@@ -192,9 +186,7 @@
"freedraw": "Çiz", "freedraw": "Çiz",
"text": "Yazı", "text": "Yazı",
"library": "Kütüphane", "library": "Kütüphane",
"lock": "Seçilen aracı çizimden sonra aktif tut", "lock": "Seçilen aracı çizimden sonra aktif tut"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Tuval eylemleri", "canvasActions": "Tuval eylemleri",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "Очистити полотно", "clearReset": "Очистити полотно",
@@ -192,9 +186,7 @@
"freedraw": "Малювати", "freedraw": "Малювати",
"text": "Текст", "text": "Текст",
"library": "Бібліотека", "library": "Бібліотека",
"lock": "Залишити обраний інструмент після креслення", "lock": "Залишити обраний інструмент після креслення"
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "Дії з полотном", "canvasActions": "Дії з полотном",
+3 -11
View File
@@ -104,13 +104,7 @@
"personalLib": "个人素材库", "personalLib": "个人素材库",
"excalidrawLib": "Excalidraw 素材库", "excalidrawLib": "Excalidraw 素材库",
"decreaseFontSize": "缩小字体大小", "decreaseFontSize": "缩小字体大小",
"increaseFontSize": "放大字体大小", "increaseFontSize": "放大字体大小"
"unbindText": "取消文本绑定",
"link": {
"edit": "编辑链接",
"create": "新建链接",
"label": "链接"
}
}, },
"buttons": { "buttons": {
"clearReset": "重置画布", "clearReset": "重置画布",
@@ -192,9 +186,7 @@
"freedraw": "自由书写", "freedraw": "自由书写",
"text": "文字", "text": "文字",
"library": "素材库", "library": "素材库",
"lock": "绘制后保持所选的工具栏状态", "lock": "绘制后保持所选的工具栏状态"
"penMode": "禁用手势缩放并只接收来自触控笔的输入",
"link": "为选中的形状添加/更新链接"
}, },
"headings": { "headings": {
"canvasActions": "画布动作", "canvasActions": "画布动作",
@@ -320,7 +312,7 @@
"noteGuidelines": { "noteGuidelines": {
"pre": "提交的素材库需先经人工审核。在提交之前,请先阅读 ", "pre": "提交的素材库需先经人工审核。在提交之前,请先阅读 ",
"link": "指南", "link": "指南",
"post": " 。后续沟通和对库的修改需要 GitHub 账号,但这不是必须的。" "post": " 后续沟通和对库的修改需要 GitHub 帐号,但这不是必须的。"
}, },
"noteLicense": { "noteLicense": {
"pre": "提交即表明您已同意素材库将遵循 ", "pre": "提交即表明您已同意素材库将遵循 ",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "", "personalLib": "",
"excalidrawLib": "", "excalidrawLib": "",
"decreaseFontSize": "", "decreaseFontSize": "",
"increaseFontSize": "", "increaseFontSize": ""
"unbindText": "",
"link": {
"edit": "",
"create": "",
"label": ""
}
}, },
"buttons": { "buttons": {
"clearReset": "清空畫布", "clearReset": "清空畫布",
@@ -192,9 +186,7 @@
"freedraw": "", "freedraw": "",
"text": "", "text": "",
"library": "", "library": "",
"lock": "", "lock": ""
"penMode": "",
"link": ""
}, },
"headings": { "headings": {
"canvasActions": "畫布動作", "canvasActions": "畫布動作",
+2 -10
View File
@@ -104,13 +104,7 @@
"personalLib": "個人資料庫", "personalLib": "個人資料庫",
"excalidrawLib": "Excalidraw 資料庫", "excalidrawLib": "Excalidraw 資料庫",
"decreaseFontSize": "縮小文字", "decreaseFontSize": "縮小文字",
"increaseFontSize": "放大文字", "increaseFontSize": "放大文字"
"unbindText": "取消綁定文字",
"link": {
"edit": "編輯連結",
"create": "建立連結",
"label": "連結"
}
}, },
"buttons": { "buttons": {
"clearReset": "重置 canvas", "clearReset": "重置 canvas",
@@ -192,9 +186,7 @@
"freedraw": "繪圖", "freedraw": "繪圖",
"text": "文字", "text": "文字",
"library": "資料庫", "library": "資料庫",
"lock": "可連續使用選取的工具", "lock": "可連續使用選取的工具"
"penMode": "停止使用手勢縮放並接受以繪圖筆繪圖輸入",
"link": "為所選的形狀增加\b/更新連結"
}, },
"headings": { "headings": {
"canvasActions": "canvas 動作", "canvasActions": "canvas 動作",
+23 -288
View File
@@ -11,29 +11,34 @@ The change should be grouped under one of the below section and must contain PR
Please add the latest change on the top under the correct section. Please add the latest change on the top under the correct section.
--> -->
## 0.11.0 (2022-02-17) ## Unreleased
## Excalidraw API ## Excalidraw API
- [`exportToBlob`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#exportToBlob) now automatically sets `appState.exportBackground` to `true` if exporting to `image/jpeg` MIME type (to ensure that alpha channel is not compressed to black color).
## Excalidraw App Props
- `handleLinkNavigation (url: string) => void`. If provided Excalidraw will call this function to open element hyperlinks.
### Features ### Features
- Add `onLinkOpen` prop which will be triggered when clicked on element hyperlink if present [#4694](https://github.com/excalidraw/excalidraw/pull/4694).
- Support updating library using [`updateScene`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#updateScene) API [#4546](https://github.com/excalidraw/excalidraw/pull/4546). - Support updating library using [`updateScene`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#updateScene) API [#4546](https://github.com/excalidraw/excalidraw/pull/4546).
- Introduced primary colors to the app. The colors can be overriden. Check [readme](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#customizing-styles) on how to do so [#4387](https://github.com/excalidraw/excalidraw/pull/4387). - Introduced primary colors to the app. The colors can be overriden. Check [readme](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#customizing-styles) on how to do so.
- [`exportToBlob`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#exportToBlob) now automatically sets `appState.exportBackground` to `true` if exporting to `image/jpeg` MIME type (to ensure that alpha channel is not compressed to black color) [#4342](https://github.com/excalidraw/excalidraw/pull/4342). - #### BREAKING CHANGE
#### BREAKING CHANGE Removed `getElementMap` util method.
Remove `getElementMap` util [#4306](https://github.com/excalidraw/excalidraw/pull/4306). - Changes to [`exportToCanvas`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#exportToCanvas) util function:
- Changes to [`exportToCanvas`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#exportToCanvas) util function [#4321](https://github.com/excalidraw/excalidraw/pull/4321):
- Add `maxWidthOrHeight?: number` attribute. - Add `maxWidthOrHeight?: number` attribute.
- `scale` returned from `getDimensions()` is now optional (default to `1`). - `scale` returned from `getDimensions()` is now optional (default to `1`).
- Image support added for host [PR](https://github.com/excalidraw/excalidraw/pull/4011) - Image support.
NOTE: the unreleased API is highly unstable and may change significantly before the next stable release. As such it's largely undocumented at this point. You are encouraged to read through the [PR](https://github.com/excalidraw/excalidraw/pull/4011) description if you want to know more about the internals.
General notes: General notes:
@@ -53,13 +58,13 @@ Please add the latest change on the top under the correct section.
Other notes: Other notes:
- `.excalidraw` files may now contain top-level `files` key in format of `Record<FileId, BinaryFileData>` when exporting any (image) elements. - `.excalidraw` files may now contain top-level `files` key in format of `Record<FileId, BinaryFileData>` when exporting any (image) elements.
- Changes were made to various export utilities exported from the package so that they take `files`, you can refer to the docs for the same. - Changes were made to various export utilityies exported from the package so that they take `files`. For now, TypeScript should help you figure the changes out.
- Export [`isLinearElement`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#isLinearElement) and [`getNonDeletedElements`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#getNonDeletedElements) [#4072](https://github.com/excalidraw/excalidraw/pull/4072). - Export [`isLinearElement`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#isLinearElement) and [`getNonDeletedElements`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#getNonDeletedElements).
- Support [`renderTopRightUI`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#renderTopRightUI) in mobile UI [#4065](https://github.com/excalidraw/excalidraw/pull/4065). - Support [`renderTopRightUI`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#renderTopRightUI) in mobile UI.
- Export `THEME` constant from the package so host can use this when passing the theme [#4055](https://github.com/excalidraw/excalidraw/pull/4055). - Export `THEME` constant from the package so host can use this when passing the theme.
#### BREAKING CHANGE #### BREAKING CHANGE
@@ -69,285 +74,15 @@ Please add the latest change on the top under the correct section.
- Reset `unmounted` state on the component once component mounts to fix the mounting/unmounting repeatedly when used with `useEffect` [#4682](https://github.com/excalidraw/excalidraw/pull/4682). - Reset `unmounted` state on the component once component mounts to fix the mounting/unmounting repeatedly when used with `useEffect` [#4682](https://github.com/excalidraw/excalidraw/pull/4682).
- Panning the canvas using `mousewheel-drag` and `space-drag` now prevents the browser from scrolling the container/page [#4489](https://github.com/excalidraw/excalidraw/pull/4489). - Panning the canvas using `mousewheel-drag` and `space-drag` now prevents the browser from scrolling the container/page [#4489](https://github.com/excalidraw/excalidraw/pull/4489).
- Scope drag and drop events to Excalidraw container to prevent overriding host application drag and drop events [#4445](https://github.com/excalidraw/excalidraw/pull/4445). - Scope drag and drop events to Excalidraw container to prevent overriding host application drag and drop events.
### Build ### Build
- Release preview package [@excalidraw/excalidraw-preview](https://www.npmjs.com/package/@excalidraw/excalidraw-preview) when triggered via comment - Added an example to test and develop the package [locally](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#Development) using `yarn start`
``` - Remove `file-loader` so font assets are not duplicated by webpack and use webpack asset modules for font generation [#4380](https://github.com/excalidraw/excalidraw/pull/4380)
@excalibot trigger release
```
[#4750](https://github.com/excalidraw/excalidraw/pull/4750). - We're now compiling to `es2017` target. Notably, `async/await` is not compiled down to generators. [#4341](https://github.com/excalidraw/excalidraw/pull/4341)
- Added an example to test and develop the package [locally](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#Development) using `yarn start` [#4488](https://github.com/excalidraw/excalidraw/pull/4488)
- Remove `file-loader` so font assets are not duplicated by webpack and use webpack asset modules for font generation [#4380](https://github.com/excalidraw/excalidraw/pull/4380).
- We're now compiling to `es2017` target. Notably, `async/await` is not compiled down to generators. [#4341](https://github.com/excalidraw/excalidraw/pull/4341).
---
## Excalidraw Library
**_This section lists the updates made to the excalidraw library and will not affect the integration._**
### Features
- Show group/group and link action in mobile [#4795](https://github.com/excalidraw/excalidraw/pull/4795)
- Support background fill for freedraw shapes [#4610](https://github.com/excalidraw/excalidraw/pull/4610)
- Keep selected tool on canvas reset [#4728](https://github.com/excalidraw/excalidraw/pull/4728)
- Make whole element clickable in view mode when it has hyperlink [#4735](https://github.com/excalidraw/excalidraw/pull/4735)
- Allow any precision when zooming [#4730](https://github.com/excalidraw/excalidraw/pull/4730)
- Throttle `pointermove` events per framerate [#4727](https://github.com/excalidraw/excalidraw/pull/4727)
- Support hyperlinks 🔥 [#4620](https://github.com/excalidraw/excalidraw/pull/4620)
- Added penMode for palm rejection [#4657](https://github.com/excalidraw/excalidraw/pull/4657)
- Support unbinding bound text [#4686](https://github.com/excalidraw/excalidraw/pull/4686)
- Sync local storage state across tabs when out of sync [#4545](https://github.com/excalidraw/excalidraw/pull/4545)
- Support contextMenuLabel to be of function type to support dynmaic labels [#4654](https://github.com/excalidraw/excalidraw/pull/4654)
- Support decreasing/increasing `fontSize` via keyboard [#4553](https://github.com/excalidraw/excalidraw/pull/4553)
- Link to new LP for excalidraw plus [#4549](https://github.com/excalidraw/excalidraw/pull/4549)
- Update stroke color of bounded text along with container [#4541](https://github.com/excalidraw/excalidraw/pull/4541)
- Hints and shortcuts help around deep selection [#4502](https://github.com/excalidraw/excalidraw/pull/4502)
- Support updating text properties by clicking on container [#4499](https://github.com/excalidraw/excalidraw/pull/4499)
- Bind text to shapes when pressing enter and support sticky notes 🎉 [#4343](https://github.com/excalidraw/excalidraw/pull/4343)
- Change `boundElementIds` → `boundElements` [#4404](https://github.com/excalidraw/excalidraw/pull/4404)
- Support selecting multiple points when editing line [#4373](https://github.com/excalidraw/excalidraw/pull/4373)
- Horizontally center toolbar menu [commit link](https://github.com/excalidraw/excalidraw/commit/9b8ee3cacfec239617c357693cf2a3ca9972d2cb)
- Add support for rounded corners in diamond [#4369](https://github.com/excalidraw/excalidraw/pull/4369)
- Allow zooming up to 3000% [#4358](https://github.com/excalidraw/excalidraw/pull/4358)
- Stop discarding precision when rendering [#4357](https://github.com/excalidraw/excalidraw/pull/4357)
- Support Image binding [#4347](https://github.com/excalidraw/excalidraw/pull/4347)
- Add `element.updated` [#4070](https://github.com/excalidraw/excalidraw/pull/4070)
- Compress shareLink data when uploading to json server [#4225](https://github.com/excalidraw/excalidraw/pull/4225)
- Supply `version` param when installing libraries [#4305](https://github.com/excalidraw/excalidraw/pull/4305)
- Log FS abortError to console [#4279](https://github.com/excalidraw/excalidraw/pull/4279)
- Add validation for website and remove validation for library item name [#4269](https://github.com/excalidraw/excalidraw/pull/4269)
- Allow publishing libraries from UI [#4115](https://github.com/excalidraw/excalidraw/pull/4115)
- Create confirm dialog to use instead of window.confirm [#4256](https://github.com/excalidraw/excalidraw/pull/4256)
- Allow letters in IDs for storing files in backend [#4224](https://github.com/excalidraw/excalidraw/pull/4224)
- Remove support for V1 unencrypted backend [#4189](https://github.com/excalidraw/excalidraw/pull/4189)
- Use separate backend for local storage [#4187](https://github.com/excalidraw/excalidraw/pull/4187)
- Add hint around canvas panning [#4159](https://github.com/excalidraw/excalidraw/pull/4159)
- Stop using production services for development [#4113](https://github.com/excalidraw/excalidraw/pull/4113)
- Add triangle arrowhead [#4024](https://github.com/excalidraw/excalidraw/pull/4024)
- Add rewrite to webex landing page [#4102](https://github.com/excalidraw/excalidraw/pull/4102)
- Switch collab server [#4092](https://github.com/excalidraw/excalidraw/pull/4092)
- Use dialog component for clear canvas instead of window confirm [#4075](https://github.com/excalidraw/excalidraw/pull/4075)
### Fixes
- Rename --color-primary-chubb to --color-primary-contrast-offset and fallback to primary color if not present [#4803](https://github.com/excalidraw/excalidraw/pull/4803)
- Add commits directly pushed to master in changelog [#4798](https://github.com/excalidraw/excalidraw/pull/4798)
- Don't bump element version when adding files data [#4794](https://github.com/excalidraw/excalidraw/pull/4794)
- Mobile link click [#4742](https://github.com/excalidraw/excalidraw/pull/4742)
- ContextMenu timer & pointers not correctly reset on iOS [#4765](https://github.com/excalidraw/excalidraw/pull/4765)
- Use absolute coords when rendering link popover [#4753](https://github.com/excalidraw/excalidraw/pull/4753)
- Changing font size when text is not selected or edited [#4751](https://github.com/excalidraw/excalidraw/pull/4751)
- Disable contextmenu on non-secondary `pen` events or `touch` [#4675](https://github.com/excalidraw/excalidraw/pull/4675)
- Mobile context menu won't show on long press [#4741](https://github.com/excalidraw/excalidraw/pull/4741)
- Do not open links twice [#4738](https://github.com/excalidraw/excalidraw/pull/4738)
- Make link icon clickable in mobile [#4736](https://github.com/excalidraw/excalidraw/pull/4736)
- Apple Pen missing strokes [#4705](https://github.com/excalidraw/excalidraw/pull/4705)
- Freedraw slow movement jittery lines [#4726](https://github.com/excalidraw/excalidraw/pull/4726)
- Disable three finger pinch zoom in penMode [#4725](https://github.com/excalidraw/excalidraw/pull/4725)
- Remove click listener for opening popup [#4700](https://github.com/excalidraw/excalidraw/pull/4700)
- Link popup position not accounting for offsets [#4695](https://github.com/excalidraw/excalidraw/pull/4695)
- PenMode darkmode style [#4692](https://github.com/excalidraw/excalidraw/pull/4692)
- Typing `_+` in wysiwyg not working [#4681](https://github.com/excalidraw/excalidraw/pull/4681)
- Keyboard-zooming in wysiwyg should zoom canvas [#4676](https://github.com/excalidraw/excalidraw/pull/4676)
- SceneCoordsToViewportCoords, jumping text when there is an offset [#4413](https://github.com/excalidraw/excalidraw/pull/4413) (#4630)
- Right-click object menu displays partially off-screen [#4572](https://github.com/excalidraw/excalidraw/pull/4572) (#4631)
- Support collaboration in bound text [#4573](https://github.com/excalidraw/excalidraw/pull/4573)
- Cmd/ctrl native browser behavior blocked in inputs [#4589](https://github.com/excalidraw/excalidraw/pull/4589)
- Use cached width when calculating min width during resize [#4585](https://github.com/excalidraw/excalidraw/pull/4585)
- Support collaboration in bounded text [#4580](https://github.com/excalidraw/excalidraw/pull/4580)
- Port for collab server and update docs [#4569](https://github.com/excalidraw/excalidraw/pull/4569)
- Don't mutate the bounded text if not updated when submitted [#4543](https://github.com/excalidraw/excalidraw/pull/4543)
- Prevent canvas drag while editing text [#4552](https://github.com/excalidraw/excalidraw/pull/4552)
- Support shift+P for freedraw [#4550](https://github.com/excalidraw/excalidraw/pull/4550)
- Prefer spreadsheet data over image [#4533](https://github.com/excalidraw/excalidraw/pull/4533)
- Show text properties button states correctly for bounded text [#4542](https://github.com/excalidraw/excalidraw/pull/4542)
- Rotate bounded text when container is rotated before typing [#4535](https://github.com/excalidraw/excalidraw/pull/4535)
- Undo should work when selecting bounded textr [#4537](https://github.com/excalidraw/excalidraw/pull/4537)
- Reduce padding to 5px for bounded text [#4530](https://github.com/excalidraw/excalidraw/pull/4530)
- Bound text doesn't inherit container [#4521](https://github.com/excalidraw/excalidraw/pull/4521)
- Text wrapping with grid [#4505](https://github.com/excalidraw/excalidraw/pull/4505) (#4506)
- Check if process is defined before using so it works in browser [#4497](https://github.com/excalidraw/excalidraw/pull/4497)
- Pending review fixes for sticky notes [#4493](https://github.com/excalidraw/excalidraw/pull/4493)
- Pasted elements except binded text once paste action is complete [#4472](https://github.com/excalidraw/excalidraw/pull/4472)
- Don't select binded text when ungrouping [#4470](https://github.com/excalidraw/excalidraw/pull/4470)
- Set height correctly when text properties updated while editing in container until first submit [#4469](https://github.com/excalidraw/excalidraw/pull/4469)
- Align and distribute binded text in container and cleanup [#4468](https://github.com/excalidraw/excalidraw/pull/4468)
- Move binded text when moving container using keyboard [#4466](https://github.com/excalidraw/excalidraw/pull/4466)
- Support dragging binded text in container selected in a group [#4462](https://github.com/excalidraw/excalidraw/pull/4462)
- Vertically align single line when deleting text in bounded container [#4460](https://github.com/excalidraw/excalidraw/pull/4460)
- Update height correctly when updating text properties in binded text [#4459](https://github.com/excalidraw/excalidraw/pull/4459)
- Align library item previews to center [#4447](https://github.com/excalidraw/excalidraw/pull/4447)
- Vertically center align text when text deleted [#4457](https://github.com/excalidraw/excalidraw/pull/4457)
- Vertically center the first line as user starts typing in container [#4454](https://github.com/excalidraw/excalidraw/pull/4454)
- Switch cursor to center of container when adding text when dimensions are too small [#4452](https://github.com/excalidraw/excalidraw/pull/4452)
- Vertically center align the bounded text correctly when zoomed [#4444](https://github.com/excalidraw/excalidraw/pull/4444)
- Support updating stroke color for text by typing in color picker input [#4415](https://github.com/excalidraw/excalidraw/pull/4415)
- Bound text not atomic with container when changing z-index [#4414](https://github.com/excalidraw/excalidraw/pull/4414)
- Update viewport coords correctly when editing text [#4416](https://github.com/excalidraw/excalidraw/pull/4416)
- Use word-break break-word only and update text editor height only when binded to container [#4410](https://github.com/excalidraw/excalidraw/pull/4410)
- Husky not able to execute pre-commit on windows [#4370](https://github.com/excalidraw/excalidraw/pull/4370)
- Make firebase config parsing not fail on undefined env [#4381](https://github.com/excalidraw/excalidraw/pull/4381)
- Adding to library via contextmenu when no image is selected [#4356](https://github.com/excalidraw/excalidraw/pull/4356)
- Export scale quality regression [#4316](https://github.com/excalidraw/excalidraw/pull/4316)
- Remove `100%` height from tooltip container to fix layout issues [#3980](https://github.com/excalidraw/excalidraw/pull/3980)
- Inline ENV variables when building excalidraw package [#4311](https://github.com/excalidraw/excalidraw/pull/4311)
- SVG export in dark mode with embedded bitmap image [#4285](https://github.com/excalidraw/excalidraw/pull/4285)
- New FS API not working on Linux [#4280](https://github.com/excalidraw/excalidraw/pull/4280)
- Url -> URL for consistency [#4277](https://github.com/excalidraw/excalidraw/pull/4277)
- Prevent adding images to library via contextMenu [#4264](https://github.com/excalidraw/excalidraw/pull/4264)
- Account for libraries v2 when prompting [#4263](https://github.com/excalidraw/excalidraw/pull/4263)
- Skia rendering issues [#4200](https://github.com/excalidraw/excalidraw/pull/4200)
- Ellipse roughness when `0` [#4194](https://github.com/excalidraw/excalidraw/pull/4194)
- Proper string for invalid SVG [#4191](https://github.com/excalidraw/excalidraw/pull/4191)
- Images not initialized correctly [#4157](https://github.com/excalidraw/excalidraw/pull/4157)
- Image-related fixes [#4147](https://github.com/excalidraw/excalidraw/pull/4147)
- Rewrite collab element reconciliation to fix z-index issues [#4076](https://github.com/excalidraw/excalidraw/pull/4076)
- Redirect excalidraw.com/about to for-webex.excalidraw.com [#4104](https://github.com/excalidraw/excalidraw/pull/4104)
- Redirect to webex LP instead of rewrite to fix SW [#4103](https://github.com/excalidraw/excalidraw/pull/4103)
- Clear image/shape cache of affected elements when adding files [#4089](https://github.com/excalidraw/excalidraw/pull/4089)
- Clear `LibraryUnit` DOM on unmount [#4084](https://github.com/excalidraw/excalidraw/pull/4084)
- Pasting images on firefox [#4085](https://github.com/excalidraw/excalidraw/pull/4085)
### Refactor
- Simplify zoom by removing `zoom.translation` [#4477](https://github.com/excalidraw/excalidraw/pull/4477)
- Deduplicate encryption helpers [#4146](https://github.com/excalidraw/excalidraw/pull/4146)
### Performance
- Cache approx line height in textwysiwg [#4651](https://github.com/excalidraw/excalidraw/pull/4651)
### Build
- Rename release command to 'release package' [#4783](https://github.com/excalidraw/excalidraw/pull/4783)
- Deploy excalidraw package example [#4762](https://github.com/excalidraw/excalidraw/pull/4762)
- Allow package.json changes when autoreleasing next [#4068](https://github.com/excalidraw/excalidraw/pull/4068)
--- ---
@@ -357,7 +92,7 @@ Please add the latest change on the top under the correct section.
### Fixes ### Fixes
- Don't show save file to disk button in export dialog when `saveFileToDisk` passed as `false` in [`UIOptions.canvasActions.export`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#exportOpts) [#4073](https://github.com/excalidraw/excalidraw/pull/4073). - Don't show save file to disk button in export dialog when `saveFileToDisk` passed as `false` in [`UIOptions.canvasActions.export`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#exportOpts).
- [`onPaste`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#onPaste) prop should return false to prevent the native excalidraw paste action [#3974](https://github.com/excalidraw/excalidraw/pull/3974). - [`onPaste`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#onPaste) prop should return false to prevent the native excalidraw paste action [#3974](https://github.com/excalidraw/excalidraw/pull/3974).
+109 -255
View File
@@ -347,31 +347,6 @@ To view the full example visit :point_down:
</details> </details>
### Customizing styles
Excalidraw is using CSS variables to style certain components. To override them, you should set your own on the `.excalidraw` and `.excalidraw.theme--dark` (for dark mode variables) selectors.
Make sure the selector has higher specificity, e.g. by prefixing it with your app's selector:
```css
.your-app .excalidraw {
--color-primary: red;
}
.your-app .excalidraw.theme--dark {
--color-primary: pink;
}
```
Most notably, you can customize the primary colors, by overriding these variables:
- `--color-primary`
- `--color-primary-darker`
- `--color-primary-darkest`
- `--color-primary-light`
- `--color-primary-contrast-offset` — a slightly darker (in light mode), or lighter (in dark mode) `--color-primary` color to fix contrast issues (see [Chubb illusion](https://en.wikipedia.org/wiki/Chubb_illusion)). It will fall back to `--color-primary` if not present.
For a complete list of variables, check [theme.scss](https://github.com/excalidraw/excalidraw/blob/master/src/css/theme.scss), though most of them will not make sense to override.
### Props ### Props
| Name | Type | Default | Description | | Name | Type | Default | Description |
@@ -390,16 +365,14 @@ For a complete list of variables, check [theme.scss](https://github.com/excalidr
| [`zenModeEnabled`](#zenModeEnabled) | boolean | | This implies if the zen mode is enabled | | [`zenModeEnabled`](#zenModeEnabled) | boolean | | This implies if the zen mode is enabled |
| [`gridModeEnabled`](#gridModeEnabled) | boolean | | This implies if the grid mode is enabled | | [`gridModeEnabled`](#gridModeEnabled) | boolean | | This implies if the grid mode is enabled |
| [`libraryReturnUrl`](#libraryReturnUrl) | string | | What URL should [libraries.excalidraw.com](https://libraries.excalidraw.com) be installed to | | [`libraryReturnUrl`](#libraryReturnUrl) | string | | What URL should [libraries.excalidraw.com](https://libraries.excalidraw.com) be installed to |
| [`theme`](#theme) | [THEME.LIGHT](#THEME-1) &#124; [THEME.LIGHT](#THEME-1) | [THEME.LIGHT](#THEME-1) | The theme of the Excalidraw component | | [`theme`](#theme) | `light` or `dark` | | The theme of the Excalidraw component |
| [`name`](#name) | string | | Name of the drawing | | [`name`](#name) | string | | Name of the drawing |
| [`UIOptions`](#UIOptions) | <pre>{ canvasActions: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L208"> CanvasActions<a/> }</pre> | [DEFAULT UI OPTIONS](https://github.com/excalidraw/excalidraw/blob/master/src/constants.ts#L129) | To customise UI options. Currently we support customising [`canvas actions`](#canvasActions) | | [`UIOptions`](#UIOptions) | <pre>{ canvasActions: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L208"> CanvasActions<a/> }</pre> | [DEFAULT UI OPTIONS](https://github.com/excalidraw/excalidraw/blob/master/src/constants.ts#L129) | To customise UI options. Currently we support customising [`canvas actions`](#canvasActions) |
| [`onPaste`](#onPaste) | <pre>(data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/clipboard.ts#L21">ClipboardData</a>, event: ClipboardEvent &#124; null) => boolean</pre> | | Callback to be triggered if passed when the something is pasted in to the scene | | [`onPaste`](#onPaste) | <pre>(data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/clipboard.ts#L17">ClipboardData</a>, event: ClipboardEvent &#124; null) => boolean</pre> | | Callback to be triggered if passed when the something is pasted in to the scene |
| [`detectScroll`](#detectScroll) | boolean | true | Indicates whether to update the offsets when nearest ancestor is scrolled. | | [`detectScroll`](#detectScroll) | boolean | true | Indicates whether to update the offsets when nearest ancestor is scrolled. |
| [`handleKeyboardGlobally`](#handleKeyboardGlobally) | boolean | false | Indicates whether to bind the keyboard events to document. | | [`handleKeyboardGlobally`](#handleKeyboardGlobally) | boolean | false | Indicates whether to bind the keyboard events to document. |
| [`onLibraryChange`](#onLibraryChange) | <pre>(items: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200">LibraryItems</a>) => void &#124; Promise&lt;any&gt; </pre> | | The callback if supplied is triggered when the library is updated and receives the library items. | | [`onLibraryChange`](#onLibraryChange) | <pre>(items: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200">LibraryItems</a>) => void &#124; Promise&lt;any&gt; </pre> | | The callback if supplied is triggered when the library is updated and receives the library items. |
| [`autoFocus`](#autoFocus) | boolean | false | Implies whether to focus the Excalidraw component on page load | | [`autoFocus`](#autoFocus) | boolean | false | Implies whether to focus the Excalidraw component on page load |
| [`generateIdForFile`](#generateIdForFile) | `(file: File) => string | Promise<string>` | Allows you to override `id` generation for files added on canvas |
| [`onLinkOpen`](#onLinkOpen) | <pre>(element: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">NonDeletedExcalidrawElement</a>, event: CustomEvent) </pre> | | This prop if passed will be triggered when link of an element is clicked |
### Dimensions of Excalidraw ### Dimensions of Excalidraw
@@ -410,14 +383,12 @@ Excalidraw takes `100%` of `width` and `height` of the containing block so make
Every time component updates, this callback if passed will get triggered and has the below signature. Every time component updates, this callback if passed will get triggered and has the below signature.
```js ```js
(excalidrawElements, appState, files) => void; (excalidrawElements, appState) => void;
``` ```
1.`excalidrawElements`: Array of [excalidrawElements](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78) in the scene. 1.`excalidrawElements`: Array of [excalidrawElements](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78) in the scene.
2.`appState`: [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) of the scene. 2.`appState`: [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) of the scene
3. `files`: The [`BinaryFiles`]([BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64) which are added to the scene.
Here you can try saving the data to your backend or local storage for example. Here you can try saving the data to your backend or local storage for example.
@@ -431,7 +402,6 @@ This helps to load Excalidraw with `initialData`. It must be an object or a [pro
| `appState` | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) | The App state with which Excalidraw should be mounted. | | `appState` | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) | The App state with which Excalidraw should be mounted. |
| `scrollToContent` | boolean | This attribute implies whether to scroll to the nearest element to center once Excalidraw is mounted. By default, it will not scroll the nearest element to the center. Make sure you pass `initialData.appState.scrollX` and `initialData.appState.scrollY` when `scrollToContent` is false so that scroll positions are retained | | `scrollToContent` | boolean | This attribute implies whether to scroll to the nearest element to center once Excalidraw is mounted. By default, it will not scroll the nearest element to the center. Make sure you pass `initialData.appState.scrollX` and `initialData.appState.scrollY` when `scrollToContent` is false so that scroll positions are retained |
| `libraryItems` | [LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L151) | This library items with which Excalidraw should be mounted. | | `libraryItems` | [LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L151) | This library items with which Excalidraw should be mounted. |
| `files` | [BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64) | The files added to the scene. |
```json ```json
{ {
@@ -472,8 +442,7 @@ You can pass a `ref` when you want to access some excalidraw APIs. We expose the
| --- | --- | --- | | --- | --- | --- |
| ready | `boolean` | This is set to true once Excalidraw is rendered | | ready | `boolean` | This is set to true once Excalidraw is rendered |
| readyPromise | [resolvablePromise](https://github.com/excalidraw/excalidraw/blob/master/src/utils.ts#L317) | This promise will be resolved with the api once excalidraw has rendered. This will be helpful when you want do some action on the host app once this promise resolves. For this to work you will have to pass ref as shown [here](#readyPromise) | | readyPromise | [resolvablePromise](https://github.com/excalidraw/excalidraw/blob/master/src/utils.ts#L317) | This promise will be resolved with the api once excalidraw has rendered. This will be helpful when you want do some action on the host app once this promise resolves. For this to work you will have to pass ref as shown [here](#readyPromise) |
| [updateScene](#updateScene) | <pre>(scene: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L207">sceneData</a>) => void </pre> | updates the scene with the sceneData | | [updateScene](#updateScene) | <pre>(<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L207">sceneData</a>)) => void </pre> | updates the scene with the sceneData |
| [addFiles](#addFiles) | <pre>(files: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts">BinaryFileData</a>) => void </pre> | add files data to the appState |
| resetScene | `({ resetLoadingState: boolean }) => void` | Resets the scene. If `resetLoadingState` is passed as true then it will also force set the loading state to false. | | resetScene | `({ resetLoadingState: boolean }) => void` | Resets the scene. If `resetLoadingState` is passed as true then it will also force set the loading state to false. |
| getSceneElementsIncludingDeleted | <pre> () => <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a></pre> | Returns all the elements including the deleted in the scene | | getSceneElementsIncludingDeleted | <pre> () => <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a></pre> | Returns all the elements including the deleted in the scene |
| getSceneElements | <pre> () => <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a></pre> | Returns all the elements excluding the deleted in the scene | | getSceneElements | <pre> () => <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a></pre> | Returns all the elements excluding the deleted in the scene |
@@ -484,7 +453,6 @@ You can pass a `ref` when you want to access some excalidraw APIs. We expose the
| [importLibrary](#importlibrary) | `(url: string, token?: string) => void` | Imports library from given URL | | [importLibrary](#importlibrary) | `(url: string, token?: string) => void` | Imports library from given URL |
| setToastMessage | `(message: string) => void` | This API can be used to show the toast with custom message. | | setToastMessage | `(message: string) => void` | This API can be used to show the toast with custom message. |
| [id](#id) | string | Unique ID for the excalidraw component. | | [id](#id) | string | Unique ID for the excalidraw component. |
| [getFiles](#getFiles) | <pre>() => <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64">files</a> </pre> | This API can be used to get the files present in the scene. It may contain files that aren't referenced by any element, so if you're persisting the files to a storage, you should compare them against stored elements. |
#### `readyPromise` #### `readyPromise`
@@ -497,7 +465,7 @@ Since plain object is passed as a `ref`, the `readyPromise` is resolved as soon
### `updateScene` ### `updateScene`
<pre> <pre>
(scene: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L207">sceneData</a>) => void (<a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L207">sceneData</a>)) => void
</pre> </pre>
You can use this function to update the scene with the sceneData. It accepts the below attributes. You can use this function to update the scene with the sceneData. It accepts the below attributes.
@@ -508,13 +476,6 @@ You can use this function to update the scene with the sceneData. It accepts the
| `appState` | [`ImportedDataState["appState"]`](https://github.com/excalidraw/excalidraw/blob/master/src/data/types.ts#L18) | The `appState` to be updated in the scene. | | `appState` | [`ImportedDataState["appState"]`](https://github.com/excalidraw/excalidraw/blob/master/src/data/types.ts#L18) | The `appState` to be updated in the scene. |
| `collaborators` | <pre>Map<string, <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L29">Collaborator></a></pre> | The list of collaborators to be updated in the scene. | | `collaborators` | <pre>Map<string, <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L29">Collaborator></a></pre> | The list of collaborators to be updated in the scene. |
| `commitToHistory` | `boolean` | Implies if the `history (undo/redo)` should be recorded. Defaults to `false`. | | `commitToHistory` | `boolean` | Implies if the `history (undo/redo)` should be recorded. Defaults to `false`. |
| `libraryItems` | [LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L258) | The `libraryItems` to be update in the scene. |
### `addFiles`
<pre>(files: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts">BinaryFileData</a>) => void </pre>
Adds supplied files data to the `appState.files` cache on top of existing files present in the cache.
#### `onCollabButtonClick` #### `onCollabButtonClick`
@@ -597,7 +558,7 @@ If supplied, this URL will be used when user tries to install a library from [li
#### `theme` #### `theme`
This prop controls Excalidraw's theme. When supplied, the value takes precedence over `intialData.appState.theme`, the theme will be fully controlled by the host app, and users won't be able to toggle it from within the app. You can use [`THEME`](#THEME-1) to specify the theme. This prop controls Excalidraw's theme. When supplied, the value takes precedence over `intialData.appState.theme`, the theme will be fully controlled by the host app, and users won't be able to toggle it from within the app.
#### `name` #### `name`
@@ -638,14 +599,18 @@ The below attributes can be set in `UIOptions.canvasActions.export` to customize
This callback is triggered if passed when something is pasted into the scene. You can use this callback in case you want to do something additional when the paste event occurs. This callback is triggered if passed when something is pasted into the scene. You can use this callback in case you want to do something additional when the paste event occurs.
<pre> <pre>
(data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/clipboard.ts#L21">ClipboardData</a>, event: ClipboardEvent &#124; null) => boolean (data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/clipboard.ts#L17">ClipboardData</a>, event: ClipboardEvent &#124; null) => boolean
</pre> </pre>
This callback must return a `boolean` value or a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise) which resolves to a boolean value. This callback must return a `boolean` value or a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise) which resolves to a boolean value.
In case you want to prevent the excalidraw paste action you must return `false`, it will stop the native excalidraw clipboard management flow (nothing will be pasted into the scene). In case you want to prevent the excalidraw paste action you must return `false`, it will stop the native excalidraw clipboard management flow (nothing will be pasted into the scene).
#### `importLibrary` ### Does it support collaboration ?
No, Excalidraw package doesn't come with collaboration built in, since the implementation is specific to each host app. We expose APIs which you can use to communicate with Excalidraw which you can use to implement it. You can check our own implementation [here](https://github.com/excalidraw/excalidraw/blob/master/src/excalidraw-app/index.tsx).
### importLibrary
Imports library from given URL. You should call this on `hashchange`, passing the `addLibrary` value if you detect it as shown below. Optionally pass a CSRF `token` to skip prompting during installation (retrievable via `token` key from the url coming from [https://libraries.excalidraw.com](https://libraries.excalidraw.com/)). Imports library from given URL. You should call this on `hashchange`, passing the `addLibrary` value if you detect it as shown below. Optionally pass a CSRF `token` to skip prompting during installation (retrievable via `token` key from the url coming from [https://libraries.excalidraw.com](https://libraries.excalidraw.com/)).
@@ -667,17 +632,17 @@ useEffect(() => {
Try out the [Demo](#Demo) to see it in action. Try out the [Demo](#Demo) to see it in action.
#### `detectScroll` ### detectScroll
Indicates whether Excalidraw should listen for `scroll` event on the nearest scrollable container in the DOM tree and recompute the coordinates (e.g. to correctly handle the cursor) when the component's position changes. You can disable this when you either know this doesn't affect your app or you want to take care of it yourself (calling the [`refresh()`](#ref) method). Indicates whether Excalidraw should listen for `scroll` event on the nearest scrollable container in the DOM tree and recompute the coordinates (e.g. to correctly handle the cursor) when the component's position changes. You can disable this when you either know this doesn't affect your app or you want to take care of it yourself (calling the [`refresh()`](#ref) method).
#### `handleKeyboardGlobally` ### handleKeyboardGlobally
Indicates whether to bind keyboard events to `document`. Disabled by default, meaning the keyboard events are bound to the Excalidraw component. This allows for multiple Excalidraw components to live on the same page, and ensures that Excalidraw keyboard handling doesn't collide with your app's (or the browser) when the component isn't focused. Indicates whether to bind keyboard events to `document`. Disabled by default, meaning the keyboard events are bound to the Excalidraw component. This allows for multiple Excalidraw components to live on the same page, and ensures that Excalidraw keyboard handling doesn't collide with your app's (or the browser) when the component isn't focused.
Enable this if you want Excalidraw to handle keyboard even if the component isn't focused (e.g. a user is interacting with the navbar, sidebar, or similar). Enable this if you want Excalidraw to handle keyboard even if the component isn't focused (e.g. a user is interacting with the navbar, sidebar, or similar).
#### `onLibraryChange` ### onLibraryChange
Ths callback if supplied will get triggered when the library is updated and has the below signature. Ths callback if supplied will get triggered when the library is updated and has the below signature.
@@ -687,58 +652,58 @@ Ths callback if supplied will get triggered when the library is updated and has
It is invoked with empty items when user clears the library. You can use this callback when you want to do something additional when library is updated for example persisting it to local storage. It is invoked with empty items when user clears the library. You can use this callback when you want to do something additional when library is updated for example persisting it to local storage.
#### `id` ### id
The unique id of the excalidraw component. This can be used to identify the excalidraw component, for example importing the library items to the excalidraw component from where it was initiated when you have multiple excalidraw components rendered on the same page as shown in [multiple excalidraw demo](https://codesandbox.io/s/multiple-excalidraw-k1xx5). The unique id of the excalidraw component. This can be used to identify the excalidraw component, for example importing the library items to the excalidraw component from where it was initiated when you have multiple excalidraw components rendered on the same page as shown in [multiple excalidraw demo](https://codesandbox.io/s/multiple-excalidraw-k1xx5).
#### `autoFocus` ### autoFocus
This prop implies whether to focus the Excalidraw component on page load. Defaults to false. This prop implies whether to focus the Excalidraw component on page load. Defaults to false.
#### `generateIdForFile` ### Extra API's
Allows you to override `id` generation for files added on canvas (images). By default, an SHA-1 digest of the file is used. #### `getSceneVersion`
``` **How to use**
(file: File) => string | Promise<string>
<pre>
import { getSceneVersion } from "@excalidraw/excalidraw";
getSceneVersion(elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a>)
</pre>
This function returns the current scene version.
#### `isInvisiblySmallElement`
**_Signature_**
<pre>
isInvisiblySmallElement(element: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement</a>): boolean
</pre>
**How to use**
```js
import { isInvisiblySmallElement } from "@excalidraw/excalidraw";
``` ```
#### `onLinkOpen` Returns `true` if element is invisibly small (e.g. width & height are zero).
This prop if passed will be triggered when clicked on link. To handle the redirect yourself (such as when using your own router for internal links), you must call `event.preventDefault()`. #### `getElementMap`
``` **_Signature_**
(element: ExcalidrawElement, event: CustomEvent<{ nativeEvent: MouseEvent }>) => void
<pre>
getElementsMap(elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a>): {[id: string]: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement</a>}
</pre>
**How to use**
```js
import { getElementsMap } from "@excalidraw/excalidraw";
``` ```
Example: This function returns an object where each element is mapped to its id.
```ts
const history = useHistory();
// open internal links using the app's router, but opens external links in
// a new tab/window
const onLinkOpen: ExcalidrawProps["onLinkOpen"] = useCallback(
(element, event) => {
const link = element.link;
const { nativeEvent } = event.detail;
const isNewTab = nativeEvent.ctrlKey || nativeEvent.metaKey;
const isNewWindow = nativeEvent.shiftKey;
const isInternalLink =
link.startsWith("/") || link.includes(window.location.origin);
if (isInternalLink && !isNewTab && !isNewWindow) {
history.push(link.replace(window.location.origin, ""));
// signal that we're handling the redirect ourselves
event.preventDefault();
}
},
[history],
);
```
### Does it support collaboration ?
No, Excalidraw package doesn't come with collaboration built in, since the implementation is specific to each host app. We expose APIs which you can use to communicate with Excalidraw which you can use to implement it. You can check our own implementation [here](https://github.com/excalidraw/excalidraw/blob/master/src/excalidraw-app/index.tsx).
### Restore utilities ### Restore utilities
@@ -796,6 +761,19 @@ import { restore } from "@excalidraw/excalidraw";
This function makes sure elements and state is set to appropriate values and set to default value if not present. It is a combination of [restoreElements](#restoreElements) and [restoreAppState](#restoreAppState). This function makes sure elements and state is set to appropriate values and set to default value if not present. It is a combination of [restoreElements](#restoreElements) and [restoreAppState](#restoreAppState).
#### `serializeAsJSON`
**_Signature_**
<pre>
serializeAsJSON({
elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a>,
appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42">AppState</a>,
}): string
</pre>
Takes the scene elements and state and returns a JSON string. Deleted `elements`as well as most properties from `AppState` are removed from the resulting JSON. (see [`serializeAsJSON()`](https://github.com/excalidraw/excalidraw/blob/master/src/data/json.ts#L16) source for details).
### Export utilities ### Export utilities
#### `exportToCanvas` #### `exportToCanvas`
@@ -807,17 +785,14 @@ This function makes sure elements and state is set to appropriate values and set
elements, elements,
appState appState
getDimensions, getDimensions,
files }: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L10">ExportOpts</a>
}: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L12">ExportOpts</a>
</pre> </pre>
| Name | Type | Default | Description | | Name | Type | Default | Description |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| elements | [Excalidraw Element []](https://github.com/excalidraw/excalidraw/blob/master/src/element/types) | | The elements to be exported to canvas | | elements | [Excalidraw Element []](https://github.com/excalidraw/excalidraw/blob/master/src/element/types) | | The elements to be exported to canvas |
| appState | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L12) | [defaultAppState](https://github.com/excalidraw/excalidraw/blob/master/src/appState.ts#L11) | The app state of the scene | | appState | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L12) | [defaultAppState](https://github.com/excalidraw/excalidraw/blob/master/src/appState.ts#L11) | The app state of the scene |
| getDimensions | `(width: number, height: number) => { width: number, height: number, scale?: number }` | undefined | A function which returns the `width`, `height`, and optionally `scale` (defaults `1`), with which canvas is to be exported. | | getDimensions | `(width: number, height: number) => {width: number, height: number, scale: number)` | `(width, height) => ({ width, height, scale: 1 })` | A function which returns the width, height and scale with which canvas is to be exported. |
| maxWidthOrHeight | `number` | undefined | The maximum width or height of the exported image. If provided, `getDimensions` is ignored. |
| files | [BinaryFiles](The [`BinaryFiles`](<[BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64)>) | undefined | The files added to the scene. |
**How to use** **How to use**
@@ -853,6 +828,8 @@ import { exportToBlob } from "@excalidraw/excalidraw";
Returns a promise which resolves with a [blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob). It internally uses [canvas.ToBlob](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob). Returns a promise which resolves with a [blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob). It internally uses [canvas.ToBlob](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob).
Note: `appState.exportBackground` is always set to `true` if exporting to `image/jpeg` to ensure the alpha channel isn't compressed to black.
#### `exportToSvg` #### `exportToSvg`
**_Signature_** **_Signature_**
@@ -863,7 +840,6 @@ exportToSvg({
appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42">AppState</a>, appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42">AppState</a>,
exportPadding?: number, exportPadding?: number,
metadata?: string, metadata?: string,
files?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64">BinaryFiles</a>
}) })
</pre> </pre>
@@ -872,7 +848,6 @@ exportToSvg({
| elements | [Excalidraw Element []](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78) | | The elements to exported as svg | | elements | [Excalidraw Element []](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78) | | The elements to exported as svg |
| appState | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) | [defaultAppState](https://github.com/excalidraw/excalidraw/blob/master/src/appState.ts#L11) | The app state of the scene | | appState | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) | [defaultAppState](https://github.com/excalidraw/excalidraw/blob/master/src/appState.ts#L11) | The app state of the scene |
| exportPadding | number | 10 | The padding to be added on canvas | | exportPadding | number | 10 | The padding to be added on canvas |
| files | [BinaryFiles](The [`BinaryFiles`](<[BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64)>) | undefined | The files added to the scene. |
This function returns a promise which resolves to svg of the exported drawing. This function returns a promise which resolves to svg of the exported drawing.
@@ -885,129 +860,7 @@ This function returns a promise which resolves to svg of the exported drawing.
| exportWithDarkMode | boolean | false | Indicates whether to export with dark mode | | exportWithDarkMode | boolean | false | Indicates whether to export with dark mode |
| exportEmbedScene | boolean | false | Indicates whether scene data should be embedded in svg. This will increase the svg size. | | exportEmbedScene | boolean | false | Indicates whether scene data should be embedded in svg. This will increase the svg size. |
### Extra API's ### FONT_FAMILY
#### `serializeAsJSON`
**_Signature_**
<pre>
serializeAsJSON({
elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a>,
appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42">AppState</a>,
}): string
</pre>
Takes the scene elements and state and returns a JSON string. Deleted `elements`as well as most properties from `AppState` are removed from the resulting JSON. (see [`serializeAsJSON()`](https://github.com/excalidraw/excalidraw/blob/master/src/data/json.ts#L16) source for details).
#### `getSceneVersion`
**How to use**
<pre>
import { getSceneVersion } from "@excalidraw/excalidraw";
getSceneVersion(elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a>)
</pre>
This function returns the current scene version.
#### `isInvisiblySmallElement`
**_Signature_**
<pre>
isInvisiblySmallElement(element: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement</a>): boolean
</pre>
**How to use**
```js
import { isInvisiblySmallElement } from "@excalidraw/excalidraw";
```
Returns `true` if element is invisibly small (e.g. width & height are zero).
#### `loadLibraryFromBlob`
```js
import { loadLibraryFromBlob } from "@excalidraw/excalidraw";
```
**_Signature_**
<pre>
loadLibraryFromBlob(blob: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">Blob</a>)
</pre>
This function loads the library from the blob.
#### `loadFromBlob`
**How to use**
```js
import { loadFromBlob } from "@excalidraw/excalidraw";
```
**Signature**
<pre>
loadFromBlob(blob: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">Blob</a>, localAppState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42">AppState</a> | null)
</pre>
This function loads the scene data from the blob. If you pass `localAppState`, `localAppState` value will be preferred over the `appState` derived from `blob`
#### `getFreeDrawSvgPath`
**How to use**
```js
import { getFreeDrawSvgPath } from "@excalidraw/excalidraw";
```
**Signature**
<pre>
getFreeDrawSvgPath(element: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L127">ExcalidrawFreeDrawElement</a>
</pre>
This function returns the free draw svg path for the element.
#### `isLinearElement`
**How to use**
```js
import { isLinearElement } from "@excalidraw/excalidraw";
```
**Signature**
<pre>
isLinearElement(elementType?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L80">ExcalidrawElement</a>): boolean
</pre>
This function returns true if the element is linear type (`arrow` |`line`) else returns false.
#### `getNonDeletedElements`
**How to use**
```js
import { getNonDeletedElements } from "@excalidraw/excalidraw";
```
**Signature**
<pre>
getNonDeletedElements(elements: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L80"> readonly ExcalidrawElement[]</a>): as readonly <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L90">NonDeletedExcalidrawElement[]</a>
</pre>
This function returns an array of deleted elements.
### Exported constants
#### `FONT_FAMILY`
**How to use** **How to use**
@@ -1025,51 +878,52 @@ import { FONT_FAMILY } from "@excalidraw/excalidraw";
Defaults to `FONT_FAMILY.Virgil` unless passed in `initialData.appState.currentItemFontFamily`. Defaults to `FONT_FAMILY.Virgil` unless passed in `initialData.appState.currentItemFontFamily`.
#### `THEME` ### loadLibraryFromBlob
```js
import { loadLibraryFromBlob } from "@excalidraw/excalidraw";
```
**_Signature_**
<pre>
loadLibraryFromBlob(blob: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">Blob</a>)
</pre>
This function loads the library from the blob.
### loadFromBlob
**How to use** **How to use**
```js ```js
import { THEME } from "@excalidraw/excalidraw"; import { loadFromBlob } from "@excalidraw/excalidraw";
``` ```
`THEME` contains all the themes supported by `Excalidraw` as explained below **Signature**
| Theme | Description | <pre>
| ----- | --------------- | loadFromBlob(blob: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">Blob</a>, localAppState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42">AppState</a> | null)
| LIGHT | The light theme | </pre>
| DARK | The Dark theme |
Defaults to `THEME.LIGHT` unless passed in `initialData.appState.theme` This function loads the scene data from the blob. If you pass `localAppState`, `localAppState` value will be preferred over the `appState` derived from `blob`
### getFreeDrawSvgPath
**How to use**
```js
import { getFreeDrawSvgPath } from "@excalidraw/excalidraw";
```
**Signature**
<pre>
getFreeDrawSvgPath(element: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L127">ExcalidrawFreeDrawElement</a>
</pre>
This function returns the free draw svg path for the element.
## Need help? ## Need help?
Check out the existing [Q&A](https://github.com/excalidraw/excalidraw/discussions?discussions_q=label%3Apackage%3Aexcalidraw). If you have any queries or need help, ask us [here](https://github.com/excalidraw/excalidraw/discussions?discussions_q=label%3Apackage%3Aexcalidraw). Check out the existing [Q&A](https://github.com/excalidraw/excalidraw/discussions?discussions_q=label%3Apackage%3Aexcalidraw). If you have any queries or need help, ask us [here](https://github.com/excalidraw/excalidraw/discussions?discussions_q=label%3Apackage%3Aexcalidraw).
### Development
#### Install the dependencies
```bash
yarn
```
#### Start the server
```bash
yarn start
```
[http://localhost:3001](http://localhost:3001) will open in your default browser.
The example is same as the [codesandbox example](https://ehlz3.csb.app/)
#### Create a test release
You can create a test release by posting the below comment in your pull request
```
@excalibot release package
```
Once the version is released `@excalibot` will post a comment with the release version.
+8 -59
View File
@@ -374,7 +374,7 @@ Most notably, you can customize the primary colors, by overriding these variable
- `--color-primary-darker` - `--color-primary-darker`
- `--color-primary-darkest` - `--color-primary-darkest`
- `--color-primary-light` - `--color-primary-light`
- `--color-primary-contrast-offset` — a slightly darker (in light mode), or lighter (in dark mode) `--color-primary` color to fix contrast issues (see [Chubb illusion](https://en.wikipedia.org/wiki/Chubb_illusion)). It will fall back to `--color-primary` if not present. - `--color-primary-chubb` — a slightly darker (in light mode), or lighter (in dark mode) `--color-primary` color to account for [Chubb illusion](https://en.wikipedia.org/wiki/Chubb_illusion).
For a complete list of variables, check [theme.scss](https://github.com/excalidraw/excalidraw/blob/master/src/css/theme.scss), though most of them will not make sense to override. For a complete list of variables, check [theme.scss](https://github.com/excalidraw/excalidraw/blob/master/src/css/theme.scss), though most of them will not make sense to override.
@@ -399,13 +399,13 @@ For a complete list of variables, check [theme.scss](https://github.com/excalidr
| [`theme`](#theme) | [THEME.LIGHT](#THEME-1) &#124; [THEME.LIGHT](#THEME-1) | [THEME.LIGHT](#THEME-1) | The theme of the Excalidraw component | | [`theme`](#theme) | [THEME.LIGHT](#THEME-1) &#124; [THEME.LIGHT](#THEME-1) | [THEME.LIGHT](#THEME-1) | The theme of the Excalidraw component |
| [`name`](#name) | string | | Name of the drawing | | [`name`](#name) | string | | Name of the drawing |
| [`UIOptions`](#UIOptions) | <pre>{ canvasActions: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L208"> CanvasActions<a/> }</pre> | [DEFAULT UI OPTIONS](https://github.com/excalidraw/excalidraw/blob/master/src/constants.ts#L129) | To customise UI options. Currently we support customising [`canvas actions`](#canvasActions) | | [`UIOptions`](#UIOptions) | <pre>{ canvasActions: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L208"> CanvasActions<a/> }</pre> | [DEFAULT UI OPTIONS](https://github.com/excalidraw/excalidraw/blob/master/src/constants.ts#L129) | To customise UI options. Currently we support customising [`canvas actions`](#canvasActions) |
| [`onPaste`](#onPaste) | <pre>(data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/clipboard.ts#L21">ClipboardData</a>, event: ClipboardEvent &#124; null) => boolean</pre> | | Callback to be triggered if passed when the something is pasted in to the scene | | [`onPaste`](#onPaste) | <pre>(data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/clipboard.ts#L17">ClipboardData</a>, event: ClipboardEvent &#124; null) => boolean</pre> | | Callback to be triggered if passed when the something is pasted in to the scene |
| [`detectScroll`](#detectScroll) | boolean | true | Indicates whether to update the offsets when nearest ancestor is scrolled. | | [`detectScroll`](#detectScroll) | boolean | true | Indicates whether to update the offsets when nearest ancestor is scrolled. |
| [`handleKeyboardGlobally`](#handleKeyboardGlobally) | boolean | false | Indicates whether to bind the keyboard events to document. | | [`handleKeyboardGlobally`](#handleKeyboardGlobally) | boolean | false | Indicates whether to bind the keyboard events to document. |
| [`onLibraryChange`](#onLibraryChange) | <pre>(items: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200">LibraryItems</a>) => void &#124; Promise&lt;any&gt; </pre> | | The callback if supplied is triggered when the library is updated and receives the library items. | | [`onLibraryChange`](#onLibraryChange) | <pre>(items: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200">LibraryItems</a>) => void &#124; Promise&lt;any&gt; </pre> | | The callback if supplied is triggered when the library is updated and receives the library items. |
| [`autoFocus`](#autoFocus) | boolean | false | Implies whether to focus the Excalidraw component on page load | | [`autoFocus`](#autoFocus) | boolean | false | Implies whether to focus the Excalidraw component on page load |
| [`generateIdForFile`](#generateIdForFile) | `(file: File) => string | Promise<string>` | Allows you to override `id` generation for files added on canvas | | [`generateIdForFile`](#generateIdForFile) | `(file: File) => string | Promise<string>` | Allows you to override `id` generation for files added on canvas |
| [`onLinkOpen`](#onLinkOpen) | <pre>(element: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">NonDeletedExcalidrawElement</a>, event: CustomEvent) </pre> | | This prop if passed will be triggered when link of an element is clicked | | [`handleLinkNavigation`](#handleLinkNavigation) | `(url: string) => void` | If provided Excalidraw will call this function to open element hyperlinks |
### Dimensions of Excalidraw ### Dimensions of Excalidraw
@@ -416,14 +416,12 @@ Excalidraw takes `100%` of `width` and `height` of the containing block so make
Every time component updates, this callback if passed will get triggered and has the below signature. Every time component updates, this callback if passed will get triggered and has the below signature.
```js ```js
(excalidrawElements, appState, files) => void; (excalidrawElements, appState) => void;
``` ```
1.`excalidrawElements`: Array of [excalidrawElements](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78) in the scene. 1.`excalidrawElements`: Array of [excalidrawElements](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78) in the scene.
2.`appState`: [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) of the scene. 2.`appState`: [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) of the scene
3. `files`: The [`BinaryFiles`]([BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64) which are added to the scene.
Here you can try saving the data to your backend or local storage for example. Here you can try saving the data to your backend or local storage for example.
@@ -437,7 +435,6 @@ This helps to load Excalidraw with `initialData`. It must be an object or a [pro
| `appState` | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) | The App state with which Excalidraw should be mounted. | | `appState` | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) | The App state with which Excalidraw should be mounted. |
| `scrollToContent` | boolean | This attribute implies whether to scroll to the nearest element to center once Excalidraw is mounted. By default, it will not scroll the nearest element to the center. Make sure you pass `initialData.appState.scrollX` and `initialData.appState.scrollY` when `scrollToContent` is false so that scroll positions are retained | | `scrollToContent` | boolean | This attribute implies whether to scroll to the nearest element to center once Excalidraw is mounted. By default, it will not scroll the nearest element to the center. Make sure you pass `initialData.appState.scrollX` and `initialData.appState.scrollY` when `scrollToContent` is false so that scroll positions are retained |
| `libraryItems` | [LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L151) | This library items with which Excalidraw should be mounted. | | `libraryItems` | [LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L151) | This library items with which Excalidraw should be mounted. |
| `files` | [BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64) | The files added to the scene. |
```json ```json
{ {
@@ -490,7 +487,6 @@ You can pass a `ref` when you want to access some excalidraw APIs. We expose the
| [importLibrary](#importlibrary) | `(url: string, token?: string) => void` | Imports library from given URL | | [importLibrary](#importlibrary) | `(url: string, token?: string) => void` | Imports library from given URL |
| setToastMessage | `(message: string) => void` | This API can be used to show the toast with custom message. | | setToastMessage | `(message: string) => void` | This API can be used to show the toast with custom message. |
| [id](#id) | string | Unique ID for the excalidraw component. | | [id](#id) | string | Unique ID for the excalidraw component. |
| [getFiles](#getFiles) | <pre>() => <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64">files</a> </pre> | This API can be used to get the files present in the scene. It may contain files that aren't referenced by any element, so if you're persisting the files to a storage, you should compare them against stored elements. |
#### `readyPromise` #### `readyPromise`
@@ -520,7 +516,7 @@ You can use this function to update the scene with the sceneData. It accepts the
<pre>(files: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts">BinaryFileData</a>) => void </pre> <pre>(files: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts">BinaryFileData</a>) => void </pre>
Adds supplied files data to the `appState.files` cache on top of existing files present in the cache. Adds supplied files data to the `appState.files` cache, on top of existing files present in the cache.
#### `onCollabButtonClick` #### `onCollabButtonClick`
@@ -644,7 +640,7 @@ The below attributes can be set in `UIOptions.canvasActions.export` to customize
This callback is triggered if passed when something is pasted into the scene. You can use this callback in case you want to do something additional when the paste event occurs. This callback is triggered if passed when something is pasted into the scene. You can use this callback in case you want to do something additional when the paste event occurs.
<pre> <pre>
(data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/clipboard.ts#L21">ClipboardData</a>, event: ClipboardEvent &#124; null) => boolean (data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/clipboard.ts#L17">ClipboardData</a>, event: ClipboardEvent &#124; null) => boolean
</pre> </pre>
This callback must return a `boolean` value or a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise) which resolves to a boolean value. This callback must return a `boolean` value or a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise) which resolves to a boolean value.
@@ -709,39 +705,6 @@ Allows you to override `id` generation for files added on canvas (images). By de
(file: File) => string | Promise<string> (file: File) => string | Promise<string>
``` ```
#### `onLinkOpen`
This prop if passed will be triggered when clicked on link. To handle the redirect yourself (such as when using your own router for internal links), you must call `event.preventDefault()`.
```
(element: ExcalidrawElement, event: CustomEvent<{ nativeEvent: MouseEvent }>) => void
```
Example:
```ts
const history = useHistory();
// open internal links using the app's router, but opens external links in
// a new tab/window
const onLinkOpen: ExcalidrawProps["onLinkOpen"] = useCallback(
(element, event) => {
const link = element.link;
const { nativeEvent } = event.detail;
const isNewTab = nativeEvent.ctrlKey || nativeEvent.metaKey;
const isNewWindow = nativeEvent.shiftKey;
const isInternalLink =
link.startsWith("/") || link.includes(window.location.origin);
if (isInternalLink && !isNewTab && !isNewWindow) {
history.push(link.replace(window.location.origin, ""));
// signal that we're handling the redirect ourselves
event.preventDefault();
}
},
[history],
);
```
### Does it support collaboration ? ### Does it support collaboration ?
No, Excalidraw package doesn't come with collaboration built in, since the implementation is specific to each host app. We expose APIs which you can use to communicate with Excalidraw which you can use to implement it. You can check our own implementation [here](https://github.com/excalidraw/excalidraw/blob/master/src/excalidraw-app/index.tsx). No, Excalidraw package doesn't come with collaboration built in, since the implementation is specific to each host app. We expose APIs which you can use to communicate with Excalidraw which you can use to implement it. You can check our own implementation [here](https://github.com/excalidraw/excalidraw/blob/master/src/excalidraw-app/index.tsx).
@@ -813,8 +776,7 @@ This function makes sure elements and state is set to appropriate values and set
elements, elements,
appState appState
getDimensions, getDimensions,
files }: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L10">ExportOpts</a>
}: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L12">ExportOpts</a>
</pre> </pre>
| Name | Type | Default | Description | | Name | Type | Default | Description |
@@ -823,7 +785,6 @@ This function makes sure elements and state is set to appropriate values and set
| appState | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L12) | [defaultAppState](https://github.com/excalidraw/excalidraw/blob/master/src/appState.ts#L11) | The app state of the scene | | appState | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/packages/utils.ts#L12) | [defaultAppState](https://github.com/excalidraw/excalidraw/blob/master/src/appState.ts#L11) | The app state of the scene |
| getDimensions | `(width: number, height: number) => { width: number, height: number, scale?: number }` | undefined | A function which returns the `width`, `height`, and optionally `scale` (defaults `1`), with which canvas is to be exported. | | getDimensions | `(width: number, height: number) => { width: number, height: number, scale?: number }` | undefined | A function which returns the `width`, `height`, and optionally `scale` (defaults `1`), with which canvas is to be exported. |
| maxWidthOrHeight | `number` | undefined | The maximum width or height of the exported image. If provided, `getDimensions` is ignored. | | maxWidthOrHeight | `number` | undefined | The maximum width or height of the exported image. If provided, `getDimensions` is ignored. |
| files | [BinaryFiles](The [`BinaryFiles`](<[BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64)>) | undefined | The files added to the scene. |
**How to use** **How to use**
@@ -869,7 +830,6 @@ exportToSvg({
appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42">AppState</a>, appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42">AppState</a>,
exportPadding?: number, exportPadding?: number,
metadata?: string, metadata?: string,
files?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64">BinaryFiles</a>
}) })
</pre> </pre>
@@ -878,7 +838,6 @@ exportToSvg({
| elements | [Excalidraw Element []](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78) | | The elements to exported as svg | | elements | [Excalidraw Element []](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78) | | The elements to exported as svg |
| appState | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) | [defaultAppState](https://github.com/excalidraw/excalidraw/blob/master/src/appState.ts#L11) | The app state of the scene | | appState | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) | [defaultAppState](https://github.com/excalidraw/excalidraw/blob/master/src/appState.ts#L11) | The app state of the scene |
| exportPadding | number | 10 | The padding to be added on canvas | | exportPadding | number | 10 | The padding to be added on canvas |
| files | [BinaryFiles](The [`BinaryFiles`](<[BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L64)>) | undefined | The files added to the scene. |
This function returns a promise which resolves to svg of the exported drawing. This function returns a promise which resolves to svg of the exported drawing.
@@ -1069,13 +1028,3 @@ yarn start
[http://localhost:3001](http://localhost:3001) will open in your default browser. [http://localhost:3001](http://localhost:3001) will open in your default browser.
The example is same as the [codesandbox example](https://ehlz3.csb.app/) The example is same as the [codesandbox example](https://ehlz3.csb.app/)
#### Create a test release
You can create a test release by posting the below comment in your pull request
```
@excalibot release package
```
Once the version is released `@excalibot` will post a comment with the release version.
+16 -62
View File
@@ -1,29 +1,16 @@
import { useEffect, useState, useRef, useCallback } from "react"; import { useEffect, useState, useRef } from "react";
import InitialData from "./initialData"; import InitialData from "./initialData";
import Sidebar from "./sidebar/Sidebar"; import Sidebar from "./sidebar/Sidebar";
import "./App.scss"; import "./App.scss";
import initialData from "./initialData"; import initialData from "./initialData";
import { MIME_TYPES } from "../../../constants";
// This is so that we use the bundled excalidraw.developement.js file instead // This is so that we use the bundled excalidraw.developement.js file instead
// of the actual source code // of the actual source code
const { exportToCanvas, exportToSvg, exportToBlob } = window.Excalidraw; const { exportToCanvas, exportToSvg, exportToBlob } = window.Excalidraw;
const Excalidraw = window.Excalidraw.default; const Excalidraw = window.Excalidraw.default;
const resolvablePromise = () => {
let resolve;
let reject;
const promise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
});
promise.resolve = resolve;
promise.reject = reject;
return promise;
};
const renderTopRightUI = () => { const renderTopRightUI = () => {
return ( return (
<button onClick={() => alert("This is dummy top right UI")}> <button onClick={() => alert("This is dummy top right UI")}>
@@ -51,35 +38,10 @@ export default function App() {
const [blobUrl, setBlobUrl] = useState(null); const [blobUrl, setBlobUrl] = useState(null);
const [canvasUrl, setCanvasUrl] = useState(null); const [canvasUrl, setCanvasUrl] = useState(null);
const [exportWithDarkMode, setExportWithDarkMode] = useState(false); const [exportWithDarkMode, setExportWithDarkMode] = useState(false);
const [shouldAddWatermark, setShouldAddWatermark] = useState(false);
const [theme, setTheme] = useState("light"); const [theme, setTheme] = useState("light");
const initialStatePromiseRef = useRef({ promise: null });
if (!initialStatePromiseRef.current.promise) {
initialStatePromiseRef.current.promise = resolvablePromise();
}
useEffect(() => { useEffect(() => {
const fetchData = async () => {
const res = await fetch("/rocket.jpeg");
const imageData = await res.blob();
const reader = new FileReader();
reader.readAsDataURL(imageData);
reader.onload = function () {
const imagesArray = [
{
id: "rocket",
dataURL: reader.result,
mimeType: MIME_TYPES.jpg,
created: 1644915140367,
},
];
initialStatePromiseRef.current.promise.resolve(InitialData);
excalidrawRef.current.addFiles(imagesArray);
};
};
fetchData();
const onHashChange = () => { const onHashChange = () => {
const hash = new URLSearchParams(window.location.hash.slice(1)); const hash = new URLSearchParams(window.location.hash.slice(1));
const libraryUrl = hash.get("addLibrary"); const libraryUrl = hash.get("addLibrary");
@@ -125,21 +87,6 @@ export default function App() {
excalidrawRef.current.updateScene(sceneData); excalidrawRef.current.updateScene(sceneData);
}; };
const onLinkOpen = useCallback((element, event) => {
const link = element.link;
const { nativeEvent } = event.detail;
const isNewTab = nativeEvent.ctrlKey || nativeEvent.metaKey;
const isNewWindow = nativeEvent.shiftKey;
const isInternalLink =
link.startsWith("/") || link.includes(window.location.origin);
if (isInternalLink && !isNewTab && !isNewWindow) {
// signal that we're handling the redirect ourselves
event.preventDefault();
// do a custom redirect, such as passing to react-router
// ...
}
}, []);
return ( return (
<div className="App"> <div className="App">
<h1> Excalidraw Example</h1> <h1> Excalidraw Example</h1>
@@ -216,7 +163,7 @@ export default function App() {
<div className="excalidraw-wrapper"> <div className="excalidraw-wrapper">
<Excalidraw <Excalidraw
ref={excalidrawRef} ref={excalidrawRef}
initialData={initialStatePromiseRef.current.promise} initialData={InitialData}
onChange={(elements, state) => onChange={(elements, state) =>
console.info("Elements :", elements, "State : ", state) console.info("Elements :", elements, "State : ", state)
} }
@@ -232,7 +179,6 @@ export default function App() {
UIOptions={{ canvasActions: { loadScene: false } }} UIOptions={{ canvasActions: { loadScene: false } }}
renderTopRightUI={renderTopRightUI} renderTopRightUI={renderTopRightUI}
renderFooter={renderFooter} renderFooter={renderFooter}
onLinkOpen={onLinkOpen}
/> />
</div> </div>
@@ -245,6 +191,14 @@ export default function App() {
/> />
Export with dark mode Export with dark mode
</label> </label>
<label className="export-wrapper__checkbox">
<input
type="checkbox"
checked={shouldAddWatermark}
onChange={() => setShouldAddWatermark(!shouldAddWatermark)}
/>
Add Watermark
</label>
<button <button
onClick={async () => { onClick={async () => {
const svg = await exportToSvg({ const svg = await exportToSvg({
@@ -252,11 +206,11 @@ export default function App() {
appState: { appState: {
...initialData.appState, ...initialData.appState,
exportWithDarkMode, exportWithDarkMode,
shouldAddWatermark,
width: 300, width: 300,
height: 100, height: 100,
}, },
embedScene: true, embedScene: true,
files: excalidrawRef.current.getFiles(),
}); });
document.querySelector(".export-svg").innerHTML = svg.outerHTML; document.querySelector(".export-svg").innerHTML = svg.outerHTML;
}} }}
@@ -273,8 +227,8 @@ export default function App() {
appState: { appState: {
...initialData.appState, ...initialData.appState,
exportWithDarkMode, exportWithDarkMode,
shouldAddWatermark,
}, },
files: excalidrawRef.current.getFiles(),
}); });
setBlobUrl(window.URL.createObjectURL(blob)); setBlobUrl(window.URL.createObjectURL(blob));
}} }}
@@ -286,14 +240,14 @@ export default function App() {
</div> </div>
<button <button
onClick={async () => { onClick={() => {
const canvas = await exportToCanvas({ const canvas = exportToCanvas({
elements: excalidrawRef.current.getSceneElements(), elements: excalidrawRef.current.getSceneElements(),
appState: { appState: {
...initialData.appState, ...initialData.appState,
exportWithDarkMode, exportWithDarkMode,
shouldAddWatermark,
}, },
files: excalidrawRef.current.getFiles(),
}); });
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
ctx.font = "30px Virgil"; ctx.font = "30px Virgil";
-7
View File
@@ -40,10 +40,3 @@
display: flex; display: flex;
} }
} }
.excalidraw {
--color-primary: #faa2c1;
--color-primary-darker: #f783ac;
--color-primary-darkest: #e64980;
--color-primary-light: #fcc2d7;
}
@@ -42,33 +42,6 @@ export default {
versionNonce: 1128618623, versionNonce: 1128618623,
isDeleted: false, isDeleted: false,
}, },
{
fileId: "rocket",
type: "image",
x: 606.1042326312408,
y: 153.57729779411773,
width: 231.30325348751828,
height: 231.64340533088227,
angle: 0,
strokeColor: "transparent",
backgroundColor: "transparent",
fillStyle: "hachure",
strokeWidth: 1,
strokeStyle: "solid",
roughness: 1,
opacity: 100,
groupIds: [],
strokeSharpness: "round",
seed: 707269846,
version: 143,
versionNonce: 2028982666,
isDeleted: false,
boundElements: null,
updated: 1644914782403,
link: null,
status: "pending",
scale: [1, 1],
},
], ],
appState: { viewBackgroundColor: "#AFEEEE", currentItemFontFamily: 1 }, appState: { viewBackgroundColor: "#AFEEEE", currentItemFontFamily: 1 },
scrollToContent: true, scrollToContent: true,
Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

+2 -2
View File
@@ -35,7 +35,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
onLibraryChange, onLibraryChange,
autoFocus = false, autoFocus = false,
generateIdForFile, generateIdForFile,
onLinkOpen, handleLinkNavigation,
} = props; } = props;
const canvasActions = props.UIOptions?.canvasActions; const canvasActions = props.UIOptions?.canvasActions;
@@ -97,7 +97,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
onLibraryChange={onLibraryChange} onLibraryChange={onLibraryChange}
autoFocus={autoFocus} autoFocus={autoFocus}
generateIdForFile={generateIdForFile} generateIdForFile={generateIdForFile}
onLinkOpen={onLinkOpen} handleLinkNavigation={handleLinkNavigation}
/> />
</InitializeApp> </InitializeApp>
); );
+7 -9
View File
@@ -1,6 +1,6 @@
{ {
"name": "@excalidraw/excalidraw", "name": "@excalidraw/excalidraw",
"version": "0.11.0", "version": "0.10.0",
"main": "main.js", "main": "main.js",
"types": "types/packages/excalidraw/index.d.ts", "types": "types/packages/excalidraw/index.d.ts",
"files": [ "files": [
@@ -44,7 +44,7 @@
"react-dom": "^17.0.2" "react-dom": "^17.0.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.17.0", "@babel/core": "7.16.7",
"@babel/plugin-transform-arrow-functions": "7.16.7", "@babel/plugin-transform-arrow-functions": "7.16.7",
"@babel/plugin-transform-async-to-generator": "7.16.0", "@babel/plugin-transform-async-to-generator": "7.16.0",
"@babel/plugin-transform-runtime": "7.16.8", "@babel/plugin-transform-runtime": "7.16.8",
@@ -56,17 +56,17 @@
"babel-loader": "8.2.3", "babel-loader": "8.2.3",
"babel-plugin-transform-class-properties": "6.24.1", "babel-plugin-transform-class-properties": "6.24.1",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"css-loader": "6.6.0", "css-loader": "6.5.1",
"mini-css-extract-plugin": "2.4.6", "mini-css-extract-plugin": "2.4.6",
"postcss-loader": "6.2.1", "postcss-loader": "6.2.1",
"sass-loader": "12.4.0", "sass-loader": "12.4.0",
"terser-webpack-plugin": "5.3.1", "terser-webpack-plugin": "5.3.0",
"ts-loader": "9.2.6", "ts-loader": "9.2.6",
"typescript": "4.5.4", "typescript": "4.5.4",
"webpack": "5.65.0", "webpack": "5.65.0",
"webpack-bundle-analyzer": "4.5.0", "webpack-bundle-analyzer": "4.5.0",
"webpack-cli": "4.9.2", "webpack-cli": "4.9.1",
"webpack-dev-server": "4.7.4", "webpack-dev-server": "4.7.3",
"webpack-merge": "5.8.0" "webpack-merge": "5.8.0"
}, },
"bugs": "https://github.com/excalidraw/excalidraw/issues", "bugs": "https://github.com/excalidraw/excalidraw/issues",
@@ -76,9 +76,7 @@
"build:umd": "rm -rf dist && cross-env NODE_ENV=production webpack --config webpack.prod.config.js && cross-env NODE_ENV=development webpack --config webpack.dev.config.js && yarn gen:types", "build:umd": "rm -rf dist && cross-env NODE_ENV=production webpack --config webpack.prod.config.js && cross-env NODE_ENV=development webpack --config webpack.dev.config.js && yarn gen:types",
"build:umd:withAnalyzer": "cross-env NODE_ENV=production ANALYZER=true webpack --config webpack.prod.config.js", "build:umd:withAnalyzer": "cross-env NODE_ENV=production ANALYZER=true webpack --config webpack.prod.config.js",
"pack": "yarn build:umd && yarn pack", "pack": "yarn build:umd && yarn pack",
"start": "webpack serve --config webpack.dev-server.config.js", "start": "webpack serve --config webpack.dev-server.config.js "
"install:deps": "yarn install --frozen-lockfile && yarn --cwd ../../../",
"build:example": "EXAMPLE=true webpack --config webpack.dev-server.config.js"
}, },
"dependencies": { "dependencies": {
"dotenv": "10.0.0" "dotenv": "10.0.0"
@@ -14,7 +14,7 @@ const devServerConfig = {
hot: true, hot: true,
compress: true, compress: true,
static: { static: {
directory: path.join(__dirname, "./example/public"), directory: path.join(__dirname, "example"),
}, },
client: { client: {
progress: true, progress: true,
@@ -3,7 +3,6 @@ const webpack = require("webpack");
const autoprefixer = require("autoprefixer"); const autoprefixer = require("autoprefixer");
const { parseEnvVariables } = require("./env"); const { parseEnvVariables } = require("./env");
const outputDir = process.env.EXAMPLE === "true" ? "example/public" : "dist";
module.exports = { module.exports = {
mode: "development", mode: "development",
devtool: false, devtool: false,
@@ -11,7 +10,7 @@ module.exports = {
"excalidraw.development": "./entry.js", "excalidraw.development": "./entry.js",
}, },
output: { output: {
path: path.resolve(__dirname, outputDir), path: path.resolve(__dirname, "dist"),
library: "Excalidraw", library: "Excalidraw",
libraryTarget: "umd", libraryTarget: "umd",
filename: "[name].js", filename: "[name].js",
+124 -138
View File
@@ -2,14 +2,6 @@
# yarn lockfile v1 # yarn lockfile v1
"@ampproject/remapping@^2.0.0":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.0.3.tgz#899999b5b7a5ce570d6d9bafdcc1e62cea466cf3"
integrity sha512-DmIAguV77yFP0MGVFWknCMgSLAtsLR3VlRTteR6xgMpIfYtwaZuMvjGv5YlpiqN7S/5q87DHyuIx8oa15kiyag==
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.9"
"@jridgewell/trace-mapping" "^0.2.7"
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7": "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7":
version "7.16.7" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
@@ -22,33 +14,33 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e"
integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==
"@babel/core@7.17.0": "@babel/core@7.16.7":
version "7.17.0" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.0.tgz#16b8772b0a567f215839f689c5ded6bb20e864d5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.7.tgz#db990f931f6d40cb9b87a0dc7d2adc749f1dcbcf"
integrity sha512-x/5Ea+RO5MvF9ize5DeVICJoVrNv0Mi2RnIABrZEKYvPEpldXwauPkgvYA17cKa6WpU3LoYvYbuEMFtSNFsarA== integrity sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==
dependencies: dependencies:
"@ampproject/remapping" "^2.0.0"
"@babel/code-frame" "^7.16.7" "@babel/code-frame" "^7.16.7"
"@babel/generator" "^7.17.0" "@babel/generator" "^7.16.7"
"@babel/helper-compilation-targets" "^7.16.7" "@babel/helper-compilation-targets" "^7.16.7"
"@babel/helper-module-transforms" "^7.16.7" "@babel/helper-module-transforms" "^7.16.7"
"@babel/helpers" "^7.17.0" "@babel/helpers" "^7.16.7"
"@babel/parser" "^7.17.0" "@babel/parser" "^7.16.7"
"@babel/template" "^7.16.7" "@babel/template" "^7.16.7"
"@babel/traverse" "^7.17.0" "@babel/traverse" "^7.16.7"
"@babel/types" "^7.17.0" "@babel/types" "^7.16.7"
convert-source-map "^1.7.0" convert-source-map "^1.7.0"
debug "^4.1.0" debug "^4.1.0"
gensync "^1.0.0-beta.2" gensync "^1.0.0-beta.2"
json5 "^2.1.2" json5 "^2.1.2"
semver "^6.3.0" semver "^6.3.0"
source-map "^0.5.0"
"@babel/generator@^7.17.0": "@babel/generator@^7.16.7":
version "7.17.0" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.0.tgz#7bd890ba706cd86d3e2f727322346ffdbf98f65e" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.7.tgz#b42bf46a3079fa65e1544135f32e7958f048adbb"
integrity sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw== integrity sha512-/ST3Sg8MLGY5HVYmrjOgL60ENux/HfO/CsUh7y4MalThufhE/Ff/6EibFDHi4jiDCaWfJKoqbE6oTh21c5hrRg==
dependencies: dependencies:
"@babel/types" "^7.17.0" "@babel/types" "^7.16.7"
jsesc "^2.5.1" jsesc "^2.5.1"
source-map "^0.5.0" source-map "^0.5.0"
@@ -335,14 +327,14 @@
"@babel/traverse" "^7.16.7" "@babel/traverse" "^7.16.7"
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/helpers@^7.17.0": "@babel/helpers@^7.16.7":
version "7.17.0" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.0.tgz#79cdf6c66a579f3a7b5e739371bc63ca0306886b" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc"
integrity sha512-Xe/9NFxjPwELUvW2dsukcMZIp6XwPSbI4ojFBJuX5ramHuVE22SVcZIwqzdWo5uCgeTXW8qV97lMvSOjq+1+nQ== integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==
dependencies: dependencies:
"@babel/template" "^7.16.7" "@babel/template" "^7.16.7"
"@babel/traverse" "^7.17.0" "@babel/traverse" "^7.16.7"
"@babel/types" "^7.17.0" "@babel/types" "^7.16.7"
"@babel/highlight@^7.16.7": "@babel/highlight@^7.16.7":
version "7.16.7" version "7.16.7"
@@ -353,10 +345,10 @@
chalk "^2.0.0" chalk "^2.0.0"
js-tokens "^4.0.0" js-tokens "^4.0.0"
"@babel/parser@^7.16.7", "@babel/parser@^7.17.0": "@babel/parser@^7.16.7":
version "7.17.0" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.0.tgz#f0ac33eddbe214e4105363bb17c3341c5ffcc43c" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.7.tgz#d372dda9c89fcec340a82630a9f533f2fe15877e"
integrity sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw== integrity sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA==
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7":
version "7.16.7" version "7.16.7"
@@ -1071,26 +1063,26 @@
"@babel/parser" "^7.16.7" "@babel/parser" "^7.16.7"
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.17.0": "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.7":
version "7.17.0" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.0.tgz#3143e5066796408ccc880a33ecd3184f3e75cd30" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.7.tgz#dac01236a72c2560073658dd1a285fe4e0865d76"
integrity sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg== integrity sha512-8KWJPIb8c2VvY8AJrydh6+fVRo2ODx1wYBU2398xJVq0JomuLBZmVQzLPBblJgHIGYG4znCpUZUZ0Pt2vdmVYQ==
dependencies: dependencies:
"@babel/code-frame" "^7.16.7" "@babel/code-frame" "^7.16.7"
"@babel/generator" "^7.17.0" "@babel/generator" "^7.16.7"
"@babel/helper-environment-visitor" "^7.16.7" "@babel/helper-environment-visitor" "^7.16.7"
"@babel/helper-function-name" "^7.16.7" "@babel/helper-function-name" "^7.16.7"
"@babel/helper-hoist-variables" "^7.16.7" "@babel/helper-hoist-variables" "^7.16.7"
"@babel/helper-split-export-declaration" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7"
"@babel/parser" "^7.17.0" "@babel/parser" "^7.16.7"
"@babel/types" "^7.17.0" "@babel/types" "^7.16.7"
debug "^4.1.0" debug "^4.1.0"
globals "^11.1.0" globals "^11.1.0"
"@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.4.4": "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.4.4":
version "7.17.0" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.7.tgz#4ed19d51f840ed4bd5645be6ce40775fecf03159"
integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== integrity sha512-E8HuV7FO9qLpx6OtoGfUQ2cjIYnbFwvZWYBS+87EwtdMvmUPJSwykpovFB+8insbpF0uJcpr8KMUi64XZntZcg==
dependencies: dependencies:
"@babel/helper-validator-identifier" "^7.16.7" "@babel/helper-validator-identifier" "^7.16.7"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
@@ -1100,24 +1092,6 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752"
integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg== integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==
"@jridgewell/resolve-uri@^3.0.3":
version "3.0.4"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz#b876e3feefb9c8d3aa84014da28b5e52a0640d72"
integrity sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==
"@jridgewell/sourcemap-codec@^1.4.9":
version "1.4.10"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz#baf57b4e2a690d4f38560171f91783656b7f8186"
integrity sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==
"@jridgewell/trace-mapping@^0.2.7":
version "0.2.7"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.2.7.tgz#d45be64544788e32c7ea5c8faa16a7000d840b5b"
integrity sha512-ZKfRhw6eK2vvdWqpU7DQq49+BZESqh5rmkYpNhuzkz01tapssl2sNNy6uMUIgrTtUWQDijomWJzJRCoevVrfgw==
dependencies:
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.9"
"@nodelib/fs.scandir@2.1.5": "@nodelib/fs.scandir@2.1.5":
version "2.1.5" version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@@ -1204,7 +1178,7 @@
"@types/qs" "*" "@types/qs" "*"
"@types/range-parser" "*" "@types/range-parser" "*"
"@types/express@*", "@types/express@^4.17.13": "@types/express@*":
version "4.17.13" version "4.17.13"
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034"
integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==
@@ -1416,22 +1390,22 @@
"@webassemblyjs/ast" "1.11.1" "@webassemblyjs/ast" "1.11.1"
"@xtuc/long" "4.2.2" "@xtuc/long" "4.2.2"
"@webpack-cli/configtest@^1.1.1": "@webpack-cli/configtest@^1.1.0":
version "1.1.1" version "1.1.0"
resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.1.tgz#9f53b1b7946a6efc2a749095a4f450e2932e8356" resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043"
integrity sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg== integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==
"@webpack-cli/info@^1.4.1": "@webpack-cli/info@^1.4.0":
version "1.4.1" version "1.4.0"
resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.1.tgz#2360ea1710cbbb97ff156a3f0f24556e0fc1ebea" resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223"
integrity sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA== integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==
dependencies: dependencies:
envinfo "^7.7.3" envinfo "^7.7.3"
"@webpack-cli/serve@^1.6.1": "@webpack-cli/serve@^1.6.0":
version "1.6.1" version "1.6.0"
resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe" resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2"
integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw== integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==
"@xtuc/ieee754@^1.2.0": "@xtuc/ieee754@^1.2.0":
version "1.2.0" version "1.2.0"
@@ -1877,10 +1851,10 @@ chalk@^4.1.0:
ansi-styles "^4.1.0" ansi-styles "^4.1.0"
supports-color "^7.1.0" supports-color "^7.1.0"
chokidar@^3.5.3: chokidar@^3.5.2:
version "3.5.3" version "3.5.2"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
dependencies: dependencies:
anymatch "~3.1.2" anymatch "~3.1.2"
braces "~3.0.2" braces "~3.0.2"
@@ -1937,6 +1911,11 @@ color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
colorette@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
colorette@^2.0.10, colorette@^2.0.14: colorette@^2.0.10, colorette@^2.0.14:
version "2.0.16" version "2.0.16"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da"
@@ -2069,18 +2048,18 @@ cross-spawn@^7.0.1, cross-spawn@^7.0.3:
shebang-command "^2.0.0" shebang-command "^2.0.0"
which "^2.0.1" which "^2.0.1"
css-loader@6.6.0: css-loader@6.5.1:
version "6.6.0" version "6.5.1"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.6.0.tgz#c792ad5510bd1712618b49381bd0310574fafbd3" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.1.tgz#0c43d4fbe0d97f699c91e9818cb585759091d1b1"
integrity sha512-FK7H2lisOixPT406s5gZM1S3l8GrfhEBT3ZiL2UX1Ng1XWs0y2GPllz/OTyvbaHe12VgQrIXIzuEGVlbUhodqg== integrity sha512-gEy2w9AnJNnD9Kuo4XAP9VflW/ujKoS9c/syO+uWMlm5igc7LysKzPXaDoR2vroROkSwsTS2tGr1yGGEbZOYZQ==
dependencies: dependencies:
icss-utils "^5.1.0" icss-utils "^5.1.0"
postcss "^8.4.5" postcss "^8.2.15"
postcss-modules-extract-imports "^3.0.0" postcss-modules-extract-imports "^3.0.0"
postcss-modules-local-by-default "^4.0.0" postcss-modules-local-by-default "^4.0.0"
postcss-modules-scope "^3.0.0" postcss-modules-scope "^3.0.0"
postcss-modules-values "^4.0.0" postcss-modules-values "^4.0.0"
postcss-value-parser "^4.2.0" postcss-value-parser "^4.1.0"
semver "^7.3.5" semver "^7.3.5"
cssesc@^3.0.0: cssesc@^3.0.0:
@@ -2440,9 +2419,9 @@ find-up@^4.0.0:
path-exists "^4.0.0" path-exists "^4.0.0"
follow-redirects@^1.0.0: follow-redirects@^1.0.0:
version "1.14.8" version "1.14.7"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
forwarded@0.2.0: forwarded@0.2.0:
version "0.2.0" version "0.2.0"
@@ -2874,10 +2853,10 @@ isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
jest-worker@^27.4.5: jest-worker@^27.4.1:
version "27.5.0" version "27.4.5"
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.0.tgz#99ee77e4d06168107c27328bd7f54e74c3a48d59" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.5.tgz#d696e3e46ae0f24cff3fa7195ffba22889262242"
integrity sha512-8OEHiPNOPTfaWnJ2SUHM8fmgeGq37uuGsQBvGKQJl1f+6WIy6g7G3fE2ruI5294bUKUI9FaCWt5hDvO8HSwsSg== integrity sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
merge-stream "^2.0.0" merge-stream "^2.0.0"
@@ -3009,10 +2988,10 @@ media-typer@0.3.0:
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
memfs@^3.4.1: memfs@^3.2.2:
version "3.4.1" version "3.4.0"
resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305" resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.0.tgz#8bc12062b973be6b295d4340595736a656f0a257"
integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw== integrity sha512-o/RfP0J1d03YwsAxyHxAYs2kyJp55AFkMazlFAZFR2I2IXkxiUTXRabJ6RmNNCQ83LAD2jy52Khj0m3OffpNdA==
dependencies: dependencies:
fs-monkey "1.0.3" fs-monkey "1.0.3"
@@ -3150,7 +3129,7 @@ multicast-dns@^6.0.1:
dns-packet "^1.3.1" dns-packet "^1.3.1"
thunky "^1.0.2" thunky "^1.0.2"
nanoid@^3.2.0: nanoid@^3.1.23:
version "3.2.0" version "3.2.0"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
@@ -3429,14 +3408,14 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^8.4.5: postcss@^8.2.15:
version "8.4.6" version "8.3.0"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.6.tgz#c5ff3c3c457a23864f32cb45ac9b741498a09ae1" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f"
integrity sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA== integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==
dependencies: dependencies:
nanoid "^3.2.0" colorette "^1.2.2"
picocolors "^1.0.0" nanoid "^3.1.23"
source-map-js "^1.0.2" source-map-js "^0.6.2"
process-nextick-args@~2.0.0: process-nextick-args@~2.0.0:
version "2.0.1" version "2.0.1"
@@ -3830,10 +3809,10 @@ sockjs@^0.3.21:
uuid "^8.3.2" uuid "^8.3.2"
websocket-driver "^0.7.4" websocket-driver "^0.7.4"
source-map-js@^1.0.2: source-map-js@^0.6.2:
version "1.0.2" version "0.6.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
source-map-support@~0.5.20: source-map-support@~0.5.20:
version "0.5.20" version "0.5.20"
@@ -3950,12 +3929,12 @@ tapable@^2.1.1, tapable@^2.2.0:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==
terser-webpack-plugin@5.3.1, terser-webpack-plugin@^5.1.3: terser-webpack-plugin@5.3.0, terser-webpack-plugin@^5.1.3:
version "5.3.1" version "5.3.0"
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz#0320dcc270ad5372c1e8993fabbd927929773e54" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz#21641326486ecf91d8054161c816e464435bae9f"
integrity sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g== integrity sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ==
dependencies: dependencies:
jest-worker "^27.4.5" jest-worker "^27.4.1"
schema-utils "^3.1.1" schema-utils "^3.1.1"
serialize-javascript "^6.0.0" serialize-javascript "^6.0.0"
source-map "^0.6.1" source-map "^0.6.1"
@@ -4120,15 +4099,15 @@ webpack-bundle-analyzer@4.5.0:
sirv "^1.0.7" sirv "^1.0.7"
ws "^7.3.1" ws "^7.3.1"
webpack-cli@4.9.2: webpack-cli@4.9.1:
version "4.9.2" version "4.9.1"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.2.tgz#77c1adaea020c3f9e2db8aad8ea78d235c83659d" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3"
integrity sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ== integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==
dependencies: dependencies:
"@discoveryjs/json-ext" "^0.5.0" "@discoveryjs/json-ext" "^0.5.0"
"@webpack-cli/configtest" "^1.1.1" "@webpack-cli/configtest" "^1.1.0"
"@webpack-cli/info" "^1.4.1" "@webpack-cli/info" "^1.4.0"
"@webpack-cli/serve" "^1.6.1" "@webpack-cli/serve" "^1.6.0"
colorette "^2.0.14" colorette "^2.0.14"
commander "^7.0.0" commander "^7.0.0"
execa "^5.0.0" execa "^5.0.0"
@@ -4138,31 +4117,30 @@ webpack-cli@4.9.2:
rechoir "^0.7.0" rechoir "^0.7.0"
webpack-merge "^5.7.3" webpack-merge "^5.7.3"
webpack-dev-middleware@^5.3.1: webpack-dev-middleware@^5.3.0:
version "5.3.1" version "5.3.0"
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.0.tgz#8fc02dba6e72e1d373eca361623d84610f27be7c"
integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== integrity sha512-MouJz+rXAm9B1OTOYaJnn6rtD/lWZPy2ufQCH3BPs8Rloh/Du6Jze4p7AeLYHkVi0giJnYLaSGDC7S+GM9arhg==
dependencies: dependencies:
colorette "^2.0.10" colorette "^2.0.10"
memfs "^3.4.1" memfs "^3.2.2"
mime-types "^2.1.31" mime-types "^2.1.31"
range-parser "^1.2.1" range-parser "^1.2.1"
schema-utils "^4.0.0" schema-utils "^4.0.0"
webpack-dev-server@4.7.4: webpack-dev-server@4.7.3:
version "4.7.4" version "4.7.3"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.4.tgz#d0ef7da78224578384e795ac228d8efb63d5f945" resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.3.tgz#4e995b141ff51fa499906eebc7906f6925d0beaa"
integrity sha512-nfdsb02Zi2qzkNmgtZjkrMOcXnYZ6FLKcQwpxT7MvmHKc+oTtDsBju8j+NMyAygZ9GW1jMEUpy3itHtqgEhe1A== integrity sha512-mlxq2AsIw2ag016nixkzUkdyOE8ST2GTy34uKSABp1c4nhjZvH90D5ZRR+UOLSsG4Z3TFahAi72a3ymRtfRm+Q==
dependencies: dependencies:
"@types/bonjour" "^3.5.9" "@types/bonjour" "^3.5.9"
"@types/connect-history-api-fallback" "^1.3.5" "@types/connect-history-api-fallback" "^1.3.5"
"@types/express" "^4.17.13"
"@types/serve-index" "^1.9.1" "@types/serve-index" "^1.9.1"
"@types/sockjs" "^0.3.33" "@types/sockjs" "^0.3.33"
"@types/ws" "^8.2.2" "@types/ws" "^8.2.2"
ansi-html-community "^0.0.8" ansi-html-community "^0.0.8"
bonjour "^3.5.0" bonjour "^3.5.0"
chokidar "^3.5.3" chokidar "^3.5.2"
colorette "^2.0.10" colorette "^2.0.10"
compression "^1.7.4" compression "^1.7.4"
connect-history-api-fallback "^1.6.0" connect-history-api-fallback "^1.6.0"
@@ -4182,10 +4160,10 @@ webpack-dev-server@4.7.4:
sockjs "^0.3.21" sockjs "^0.3.21"
spdy "^4.0.2" spdy "^4.0.2"
strip-ansi "^7.0.0" strip-ansi "^7.0.0"
webpack-dev-middleware "^5.3.1" webpack-dev-middleware "^5.3.0"
ws "^8.4.2" ws "^8.1.0"
webpack-merge@5.8.0, webpack-merge@^5.7.3: webpack-merge@5.8.0:
version "5.8.0" version "5.8.0"
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61"
integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==
@@ -4193,6 +4171,14 @@ webpack-merge@5.8.0, webpack-merge@^5.7.3:
clone-deep "^4.0.1" clone-deep "^4.0.1"
wildcard "^2.0.0" wildcard "^2.0.0"
webpack-merge@^5.7.3:
version "5.7.3"
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.7.3.tgz#2a0754e1877a25a8bbab3d2475ca70a052708213"
integrity sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==
dependencies:
clone-deep "^4.0.1"
wildcard "^2.0.0"
webpack-sources@^3.2.2: webpack-sources@^3.2.2:
version "3.2.2" version "3.2.2"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260"
@@ -4264,10 +4250,10 @@ ws@^7.3.1:
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
ws@^8.4.2: ws@^8.1.0:
version "8.4.2" version "8.4.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.2.tgz#18e749868d8439f2268368829042894b6907aa0b" resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.0.tgz#f05e982a0a88c604080e8581576e2a063802bed6"
integrity sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA== integrity sha512-IHVsKe2pjajSUIl4KYMQOdlyliovpEPquKkqbwswulszzI7r0SfQrxnXdWAEqOlDCLrVSJzo+O1hAwdog2sKSQ==
yallist@^4.0.0: yallist@^4.0.0:
version "4.0.0" version "4.0.0"
+1 -1
View File
@@ -34,7 +34,7 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.17.2", "@babel/core": "7.16.7",
"@babel/plugin-transform-arrow-functions": "7.16.0", "@babel/plugin-transform-arrow-functions": "7.16.0",
"@babel/plugin-transform-async-to-generator": "7.16.5", "@babel/plugin-transform-async-to-generator": "7.16.5",
"@babel/plugin-transform-runtime": "^7.14.5", "@babel/plugin-transform-runtime": "^7.14.5",
+36 -61
View File
@@ -2,13 +2,6 @@
# yarn lockfile v1 # yarn lockfile v1
"@ampproject/remapping@^2.0.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.0.tgz#72becdf17ee44b2d1ac5651fb12f1952c336fe23"
integrity sha512-d5RysTlJ7hmw5Tw4UxgxcY3lkMe92n8sXCcuLPAyIAHK6j8DefDwtGnVVDgOnv+RnEosulDJ9NPKQL27bDId0g==
dependencies:
"@jridgewell/trace-mapping" "^0.3.0"
"@babel/code-frame@^7.16.7": "@babel/code-frame@^7.16.7":
version "7.16.7" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
@@ -21,33 +14,33 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e"
integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==
"@babel/core@7.17.2": "@babel/core@7.16.7":
version "7.17.2" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.2.tgz#2c77fc430e95139d816d39b113b31bf40fb22337" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.7.tgz#db990f931f6d40cb9b87a0dc7d2adc749f1dcbcf"
integrity sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw== integrity sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==
dependencies: dependencies:
"@ampproject/remapping" "^2.0.0"
"@babel/code-frame" "^7.16.7" "@babel/code-frame" "^7.16.7"
"@babel/generator" "^7.17.0" "@babel/generator" "^7.16.7"
"@babel/helper-compilation-targets" "^7.16.7" "@babel/helper-compilation-targets" "^7.16.7"
"@babel/helper-module-transforms" "^7.16.7" "@babel/helper-module-transforms" "^7.16.7"
"@babel/helpers" "^7.17.2" "@babel/helpers" "^7.16.7"
"@babel/parser" "^7.17.0" "@babel/parser" "^7.16.7"
"@babel/template" "^7.16.7" "@babel/template" "^7.16.7"
"@babel/traverse" "^7.17.0" "@babel/traverse" "^7.16.7"
"@babel/types" "^7.17.0" "@babel/types" "^7.16.7"
convert-source-map "^1.7.0" convert-source-map "^1.7.0"
debug "^4.1.0" debug "^4.1.0"
gensync "^1.0.0-beta.2" gensync "^1.0.0-beta.2"
json5 "^2.1.2" json5 "^2.1.2"
semver "^6.3.0" semver "^6.3.0"
source-map "^0.5.0"
"@babel/generator@^7.17.0": "@babel/generator@^7.16.7":
version "7.17.0" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.0.tgz#7bd890ba706cd86d3e2f727322346ffdbf98f65e" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.7.tgz#b42bf46a3079fa65e1544135f32e7958f048adbb"
integrity sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw== integrity sha512-/ST3Sg8MLGY5HVYmrjOgL60ENux/HfO/CsUh7y4MalThufhE/Ff/6EibFDHi4jiDCaWfJKoqbE6oTh21c5hrRg==
dependencies: dependencies:
"@babel/types" "^7.17.0" "@babel/types" "^7.16.7"
jsesc "^2.5.1" jsesc "^2.5.1"
source-map "^0.5.0" source-map "^0.5.0"
@@ -291,14 +284,14 @@
"@babel/traverse" "^7.16.7" "@babel/traverse" "^7.16.7"
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/helpers@^7.17.2": "@babel/helpers@^7.16.7":
version "7.17.2" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.2.tgz#23f0a0746c8e287773ccd27c14be428891f63417" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc"
integrity sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ== integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==
dependencies: dependencies:
"@babel/template" "^7.16.7" "@babel/template" "^7.16.7"
"@babel/traverse" "^7.17.0" "@babel/traverse" "^7.16.7"
"@babel/types" "^7.17.0" "@babel/types" "^7.16.7"
"@babel/highlight@^7.16.7": "@babel/highlight@^7.16.7":
version "7.16.7" version "7.16.7"
@@ -309,10 +302,10 @@
chalk "^2.0.0" chalk "^2.0.0"
js-tokens "^4.0.0" js-tokens "^4.0.0"
"@babel/parser@^7.16.7", "@babel/parser@^7.17.0": "@babel/parser@^7.16.7":
version "7.17.0" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.0.tgz#f0ac33eddbe214e4105363bb17c3341c5ffcc43c" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.7.tgz#d372dda9c89fcec340a82630a9f533f2fe15877e"
integrity sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw== integrity sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA==
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7":
version "7.16.7" version "7.16.7"
@@ -966,26 +959,26 @@
"@babel/parser" "^7.16.7" "@babel/parser" "^7.16.7"
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.5", "@babel/traverse@^7.16.7", "@babel/traverse@^7.17.0": "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.5", "@babel/traverse@^7.16.7":
version "7.17.0" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.0.tgz#3143e5066796408ccc880a33ecd3184f3e75cd30" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.7.tgz#dac01236a72c2560073658dd1a285fe4e0865d76"
integrity sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg== integrity sha512-8KWJPIb8c2VvY8AJrydh6+fVRo2ODx1wYBU2398xJVq0JomuLBZmVQzLPBblJgHIGYG4znCpUZUZ0Pt2vdmVYQ==
dependencies: dependencies:
"@babel/code-frame" "^7.16.7" "@babel/code-frame" "^7.16.7"
"@babel/generator" "^7.17.0" "@babel/generator" "^7.16.7"
"@babel/helper-environment-visitor" "^7.16.7" "@babel/helper-environment-visitor" "^7.16.7"
"@babel/helper-function-name" "^7.16.7" "@babel/helper-function-name" "^7.16.7"
"@babel/helper-hoist-variables" "^7.16.7" "@babel/helper-hoist-variables" "^7.16.7"
"@babel/helper-split-export-declaration" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7"
"@babel/parser" "^7.17.0" "@babel/parser" "^7.16.7"
"@babel/types" "^7.17.0" "@babel/types" "^7.16.7"
debug "^4.1.0" debug "^4.1.0"
globals "^11.1.0" globals "^11.1.0"
"@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.4.4": "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.4.4":
version "7.17.0" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.7.tgz#4ed19d51f840ed4bd5645be6ce40775fecf03159"
integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== integrity sha512-E8HuV7FO9qLpx6OtoGfUQ2cjIYnbFwvZWYBS+87EwtdMvmUPJSwykpovFB+8insbpF0uJcpr8KMUi64XZntZcg==
dependencies: dependencies:
"@babel/helper-validator-identifier" "^7.16.7" "@babel/helper-validator-identifier" "^7.16.7"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
@@ -995,24 +988,6 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752"
integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg== integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==
"@jridgewell/resolve-uri@^3.0.3":
version "3.0.4"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz#b876e3feefb9c8d3aa84014da28b5e52a0640d72"
integrity sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==
"@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.10"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz#baf57b4e2a690d4f38560171f91783656b7f8186"
integrity sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==
"@jridgewell/trace-mapping@^0.3.0":
version "0.3.4"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3"
integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==
dependencies:
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@polka/url@^1.0.0-next.9": "@polka/url@^1.0.0-next.9":
version "1.0.0-next.11" version "1.0.0-next.11"
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71"
+20 -63
View File
@@ -196,7 +196,7 @@ const drawElementOnCanvas = (
case "ellipse": { case "ellipse": {
context.lineJoin = "round"; context.lineJoin = "round";
context.lineCap = "round"; context.lineCap = "round";
rc.draw(getShapeForElement(element)!); rc.draw(getShapeForElement(element) as Drawable);
break; break;
} }
case "arrow": case "arrow":
@@ -204,7 +204,7 @@ const drawElementOnCanvas = (
context.lineJoin = "round"; context.lineJoin = "round";
context.lineCap = "round"; context.lineCap = "round";
getShapeForElement(element)!.forEach((shape) => { (getShapeForElement(element) as Drawable[]).forEach((shape) => {
rc.draw(shape); rc.draw(shape);
}); });
break; break;
@@ -215,11 +215,6 @@ const drawElementOnCanvas = (
context.fillStyle = element.strokeColor; context.fillStyle = element.strokeColor;
const path = getFreeDrawPath2D(element) as Path2D; const path = getFreeDrawPath2D(element) as Path2D;
const fillShape = getShapeForElement(element);
if (fillShape) {
rc.draw(fillShape);
}
context.fillStyle = element.strokeColor; context.fillStyle = element.strokeColor;
context.fill(path); context.fill(path);
@@ -295,29 +290,13 @@ const elementWithCanvasCache = new WeakMap<
ExcalidrawElementWithCanvas ExcalidrawElementWithCanvas
>(); >();
const shapeCache = new WeakMap<ExcalidrawElement, ElementShape>(); const shapeCache = new WeakMap<
ExcalidrawElement,
Drawable | Drawable[] | null
>();
type ElementShape = Drawable | Drawable[] | null; export const getShapeForElement = (element: ExcalidrawElement) =>
shapeCache.get(element);
type ElementShapes = {
freedraw: Drawable | null;
arrow: Drawable[];
line: Drawable[];
text: null;
image: null;
};
export const getShapeForElement = <T extends ExcalidrawElement>(element: T) =>
shapeCache.get(element) as T["type"] extends keyof ElementShapes
? ElementShapes[T["type"]] | undefined
: Drawable | null | undefined;
export const setShapeForElement = <T extends ExcalidrawElement>(
element: T,
shape: T["type"] extends keyof ElementShapes
? ElementShapes[T["type"]]
: Drawable,
) => shapeCache.set(element, shape);
export const invalidateShapeForElement = (element: ExcalidrawElement) => export const invalidateShapeForElement = (element: ExcalidrawElement) =>
shapeCache.delete(element); shapeCache.delete(element);
@@ -367,8 +346,7 @@ export const generateRoughOptions = (
} }
return options; return options;
} }
case "line": case "line": {
case "freedraw": {
if (isPathALoop(element.points)) { if (isPathALoop(element.points)) {
options.fillStyle = element.fillStyle; options.fillStyle = element.fillStyle;
options.fill = options.fill =
@@ -378,6 +356,7 @@ export const generateRoughOptions = (
} }
return options; return options;
} }
case "freedraw":
case "arrow": case "arrow":
return options; return options;
default: { default: {
@@ -395,11 +374,9 @@ const generateElementShape = (
element: NonDeletedExcalidrawElement, element: NonDeletedExcalidrawElement,
generator: RoughGenerator, generator: RoughGenerator,
) => { ) => {
let shape = shapeCache.get(element); let shape = shapeCache.get(element) || null;
// `null` indicates no rc shape applicable for this element type if (!shape) {
// (= do not generate anything)
if (shape === undefined) {
elementWithCanvasCache.delete(element); elementWithCanvasCache.delete(element);
switch (element.type) { switch (element.type) {
@@ -425,8 +402,6 @@ const generateElementShape = (
generateRoughOptions(element), generateRoughOptions(element),
); );
} }
setShapeForElement(element, shape);
break; break;
case "diamond": { case "diamond": {
const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] = const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] =
@@ -470,8 +445,6 @@ const generateElementShape = (
generateRoughOptions(element), generateRoughOptions(element),
); );
} }
setShapeForElement(element, shape);
break; break;
} }
case "ellipse": case "ellipse":
@@ -482,8 +455,6 @@ const generateElementShape = (
element.height, element.height,
generateRoughOptions(element), generateRoughOptions(element),
); );
setShapeForElement(element, shape);
break; break;
case "line": case "line":
case "arrow": { case "arrow": {
@@ -607,32 +578,21 @@ const generateElementShape = (
} }
} }
setShapeForElement(element, shape);
break; break;
} }
case "freedraw": { case "freedraw": {
generateFreeDrawShape(element); generateFreeDrawShape(element);
shape = [];
if (isPathALoop(element.points)) {
// generate rough polygon to fill freedraw shape
shape = generator.polygon(element.points as [number, number][], {
...generateRoughOptions(element),
stroke: "none",
});
} else {
shape = null;
}
setShapeForElement(element, shape);
break; break;
} }
case "text": case "text":
case "image": { case "image": {
// just to ensure we don't regenerate element.canvas on rerenders // just to ensure we don't regenerate element.canvas on rerenders
setShapeForElement(element, null); shape = [];
break; break;
} }
} }
shapeCache.set(element, shape);
} }
}; };
@@ -848,7 +808,7 @@ export const renderElementToSvg = (
generateElementShape(element, generator); generateElementShape(element, generator);
const node = roughSVGDrawWithPrecision( const node = roughSVGDrawWithPrecision(
rsvg, rsvg,
getShapeForElement(element)!, getShapeForElement(element) as Drawable,
MAX_DECIMALS_FOR_SVG_EXPORT, MAX_DECIMALS_FOR_SVG_EXPORT,
); );
const opacity = element.opacity / 100; const opacity = element.opacity / 100;
@@ -873,7 +833,7 @@ export const renderElementToSvg = (
const opacity = element.opacity / 100; const opacity = element.opacity / 100;
group.setAttribute("stroke-linecap", "round"); group.setAttribute("stroke-linecap", "round");
getShapeForElement(element)!.forEach((shape) => { (getShapeForElement(element) as Drawable[]).forEach((shape) => {
const node = roughSVGDrawWithPrecision( const node = roughSVGDrawWithPrecision(
rsvg, rsvg,
shape, shape,
@@ -904,10 +864,7 @@ export const renderElementToSvg = (
case "freedraw": { case "freedraw": {
generateFreeDrawShape(element); generateFreeDrawShape(element);
const opacity = element.opacity / 100; const opacity = element.opacity / 100;
const shape = getShapeForElement(element); const node = svgRoot.ownerDocument!.createElementNS(SVG_NS, "g");
const node = shape
? roughSVGDrawWithPrecision(rsvg, shape, MAX_DECIMALS_FOR_SVG_EXPORT)
: svgRoot.ownerDocument!.createElementNS(SVG_NS, "g");
if (opacity !== 1) { if (opacity !== 1) {
node.setAttribute("stroke-opacity", `${opacity}`); node.setAttribute("stroke-opacity", `${opacity}`);
node.setAttribute("fill-opacity", `${opacity}`); node.setAttribute("fill-opacity", `${opacity}`);
@@ -918,9 +875,9 @@ export const renderElementToSvg = (
offsetY || 0 offsetY || 0
}) rotate(${degree} ${cx} ${cy})`, }) rotate(${degree} ${cx} ${cy})`,
); );
node.setAttribute("stroke", "none");
const path = svgRoot.ownerDocument!.createElementNS(SVG_NS, "path"); const path = svgRoot.ownerDocument!.createElementNS(SVG_NS, "path");
path.setAttribute("fill", element.strokeColor); node.setAttribute("stroke", "none");
node.setAttribute("fill", element.strokeColor);
path.setAttribute("d", getFreeDrawSvgPath(element)); path.setAttribute("d", getFreeDrawSvgPath(element));
node.appendChild(path); node.appendChild(path);
svgRoot.appendChild(node); svgRoot.appendChild(node);
+1 -2
View File
@@ -9,8 +9,7 @@ export const hasBackground = (type: string) =>
type === "rectangle" || type === "rectangle" ||
type === "ellipse" || type === "ellipse" ||
type === "diamond" || type === "diamond" ||
type === "line" || type === "line";
type === "freedraw";
export const hasStrokeColor = (type: string) => type !== "image"; export const hasStrokeColor = (type: string) => type !== "image";
+3 -1
View File
@@ -1,7 +1,9 @@
import { AppState, NormalizedZoomValue } from "../types"; import { AppState, NormalizedZoomValue } from "../types";
export const getNormalizedZoom = (zoom: number): NormalizedZoomValue => { export const getNormalizedZoom = (zoom: number): NormalizedZoomValue => {
return Math.max(0.1, Math.min(zoom, 30)) as NormalizedZoomValue; const normalizedZoom = parseFloat(zoom.toFixed(2));
const clampedZoom = Math.max(0.1, Math.min(normalizedZoom, 30));
return clampedZoom as NormalizedZoomValue;
}; };
export const getStateForZoom = ( export const getStateForZoom = (
+1 -25
View File
@@ -1,10 +1,8 @@
import { queryByTestId, render, waitFor } from "./test-utils"; import { render, waitFor } from "./test-utils";
import ExcalidrawApp from "../excalidraw-app"; import ExcalidrawApp from "../excalidraw-app";
import { API } from "./helpers/api"; import { API } from "./helpers/api";
import { getDefaultAppState } from "../appState"; import { getDefaultAppState } from "../appState";
import { EXPORT_DATA_TYPES, MIME_TYPES } from "../constants"; import { EXPORT_DATA_TYPES, MIME_TYPES } from "../constants";
import { Pointer, UI } from "./helpers/ui";
import { ExcalidrawTextElement } from "../element/types";
const { h } = window; const { h } = window;
@@ -50,26 +48,4 @@ describe("appState", () => {
expect(h.state.viewBackgroundColor).toBe("#000"); expect(h.state.viewBackgroundColor).toBe("#000");
}); });
}); });
it("changing fontSize with text tool selected (no element created yet)", async () => {
const { container } = await render(<ExcalidrawApp />, {
localStorageData: {
appState: {
currentItemFontSize: 30,
},
},
});
UI.clickTool("text");
expect(h.state.currentItemFontSize).toBe(30);
queryByTestId(container, "fontSize-small")!.click();
expect(h.state.currentItemFontSize).toBe(16);
const mouse = new Pointer("mouse");
mouse.clickAt(100, 100);
expect((h.elements[0] as ExcalidrawTextElement).fontSize).toBe(16);
});
}); });
+3 -8
View File
@@ -20,7 +20,7 @@ import { LinearElementEditor } from "./element/linearElementEditor";
import { SuggestedBinding } from "./element/binding"; import { SuggestedBinding } from "./element/binding";
import { ImportedDataState } from "./data/types"; import { ImportedDataState } from "./data/types";
import type App from "./components/App"; import type App from "./components/App";
import type { ResolvablePromise, throttleRAF } from "./utils"; import type { ResolvablePromise } from "./utils";
import { Spreadsheet } from "./charts"; import { Spreadsheet } from "./charts";
import { Language } from "./i18n"; import { Language } from "./i18n";
import { ClipboardData } from "./clipboard"; import { ClipboardData } from "./clipboard";
@@ -247,12 +247,7 @@ export interface ExcalidrawProps {
onLibraryChange?: (libraryItems: LibraryItems) => void | Promise<any>; onLibraryChange?: (libraryItems: LibraryItems) => void | Promise<any>;
autoFocus?: boolean; autoFocus?: boolean;
generateIdForFile?: (file: File) => string | Promise<string>; generateIdForFile?: (file: File) => string | Promise<string>;
onLinkOpen?: ( handleLinkNavigation?: (url: string) => void;
element: NonDeletedExcalidrawElement,
event: CustomEvent<{
nativeEvent: MouseEvent | React.PointerEvent<HTMLCanvasElement>;
}>,
) => void;
} }
export type SceneData = { export type SceneData = {
@@ -373,7 +368,7 @@ export type PointerDownState = Readonly<{
// We need to have these in the state so that we can unsubscribe them // We need to have these in the state so that we can unsubscribe them
eventListeners: { eventListeners: {
// It's defined on the initial pointer down event // It's defined on the initial pointer down event
onMove: null | ReturnType<typeof throttleRAF>; onMove: null | ((event: PointerEvent) => void);
// It's defined on the initial pointer down event // It's defined on the initial pointer down event
onUp: null | ((event: PointerEvent) => void); onUp: null | ((event: PointerEvent) => void);
// It's defined on the initial pointer down event // It's defined on the initial pointer down event
-72
View File
@@ -2,7 +2,6 @@ import colors from "./colors";
import { import {
CURSOR_TYPE, CURSOR_TYPE,
DEFAULT_VERSION, DEFAULT_VERSION,
EVENT,
FONT_FAMILY, FONT_FAMILY,
WINDOWS_EMOJI_FALLBACK_FONT, WINDOWS_EMOJI_FALLBACK_FONT,
} from "./constants"; } from "./constants";
@@ -120,53 +119,6 @@ export const debounce = <T extends any[]>(
return ret; return ret;
}; };
// throttle callback to execute once per animation frame
export const throttleRAF = <T extends any[]>(fn: (...args: T) => void) => {
let handle: number | null = null;
let lastArgs: T | null = null;
let callback: ((...args: T) => void) | null = null;
const ret = (...args: T) => {
if (process.env.NODE_ENV === "test") {
fn(...args);
return;
}
lastArgs = args;
callback = fn;
if (handle === null) {
handle = window.requestAnimationFrame(() => {
handle = null;
lastArgs = null;
callback = null;
fn(...args);
});
}
};
ret.flush = () => {
if (handle !== null) {
cancelAnimationFrame(handle);
handle = null;
}
if (lastArgs) {
const _lastArgs = lastArgs;
const _callback = callback;
lastArgs = null;
callback = null;
if (_callback !== null) {
_callback(..._lastArgs);
}
}
};
ret.cancel = () => {
lastArgs = null;
callback = null;
if (handle !== null) {
cancelAnimationFrame(handle);
handle = null;
}
};
return ret;
};
// https://github.com/lodash/lodash/blob/es/chunk.js // https://github.com/lodash/lodash/blob/es/chunk.js
export const chunk = <T extends any>( export const chunk = <T extends any>(
array: readonly T[], array: readonly T[],
@@ -404,21 +356,6 @@ export const withBatchedUpdates = <
unstable_batchedUpdates(func as TFunction, event); unstable_batchedUpdates(func as TFunction, event);
}) as TFunction; }) as TFunction;
/**
* barches React state updates and throttles the calls to a single call per
* animation frame
*/
export const withBatchedUpdatesThrottled = <
TFunction extends ((event: any) => void) | (() => void),
>(
func: Parameters<TFunction>["length"] extends 0 | 1 ? TFunction : never,
) => {
// @ts-ignore
return throttleRAF<Parameters<TFunction>>(((event) => {
unstable_batchedUpdates(func, event);
}) as TFunction);
};
//https://stackoverflow.com/a/9462382/8418 //https://stackoverflow.com/a/9462382/8418
export const nFormatter = (num: number, digits: number): string => { export const nFormatter = (num: number, digits: number): string => {
const si = [ const si = [
@@ -524,12 +461,3 @@ export const arrayToMap = <T extends { id: string } | string>(
export const isTestEnv = () => export const isTestEnv = () =>
typeof process !== "undefined" && process.env?.NODE_ENV === "test"; typeof process !== "undefined" && process.env?.NODE_ENV === "test";
export const wrapEvent = <T extends Event>(name: EVENT, nativeEvent: T) => {
return new CustomEvent(name, {
detail: {
nativeEvent,
},
cancelable: true,
});
};
+59 -80
View File
@@ -2136,10 +2136,10 @@
lz-string "^1.4.4" lz-string "^1.4.4"
pretty-format "^27.0.2" pretty-format "^27.0.2"
"@testing-library/jest-dom@5.16.2": "@testing-library/jest-dom@5.16.1":
version "5.16.2" version "5.16.1"
resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz#f329b36b44aa6149cd6ced9adf567f8b6aa1c959" resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.1.tgz#3db7df5ae97596264a7da9696fe14695ba02e51f"
integrity sha512-6ewxs1MXWwsBFZXIk4nKKskWANelkdUehchEOokHsN8X7c2eKXGw+77aRV63UU8f/DTSVUPLaGxdrj4lN7D/ug== integrity sha512-ajUJdfDIuTCadB79ukO+0l8O+QwN0LiSxDaYUTI4LndbbUsGi6rWU1SCexXzBA2NSjlVB9/vbkasQIL3tmPBjw==
dependencies: dependencies:
"@babel/runtime" "^7.9.2" "@babel/runtime" "^7.9.2"
"@types/testing-library__jest-dom" "^5.9.1" "@types/testing-library__jest-dom" "^5.9.1"
@@ -2375,10 +2375,10 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react@*", "@types/react@17.0.39": "@types/react@*", "@types/react@17.0.38":
version "17.0.39" version "17.0.38"
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.39.tgz#d0f4cde092502a6db00a1cded6e6bf2abb7633ce" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.38.tgz#f24249fefd89357d5fa71f739a686b8d7c7202bd"
integrity sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug== integrity sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==
dependencies: dependencies:
"@types/prop-types" "*" "@types/prop-types" "*"
"@types/scheduler" "*" "@types/scheduler" "*"
@@ -2540,18 +2540,18 @@
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.19.0.tgz" resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.19.0.tgz"
integrity sha512-A4iAlexVvd4IBsSTNxdvdepW0D4uR/fwxDrKUa+iEY9UWvGREu2ZyB8ylTENM1SH8F7bVC9ac9+si3LWNxcBuA== integrity sha512-A4iAlexVvd4IBsSTNxdvdepW0D4uR/fwxDrKUa+iEY9UWvGREu2ZyB8ylTENM1SH8F7bVC9ac9+si3LWNxcBuA==
"@typescript-eslint/types@5.10.2": "@typescript-eslint/types@5.3.0":
version "5.10.2" version "5.3.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.2.tgz#604d15d795c4601fffba6ecb4587ff9fdec68ce8" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.3.0.tgz#af29fd53867c2df0028c57c36a655bd7e9e05416"
integrity sha512-Qfp0qk/5j2Rz3p3/WhWgu4S1JtMcPgFLnmAKAW061uXxKSa7VWKZsDXVaMXh2N60CX9h6YLaBoy9PJAfCOjk3w== integrity sha512-fce5pG41/w8O6ahQEhXmMV+xuh4+GayzqEogN24EK+vECA3I6pUwKuLi5QbXO721EMitpQne5VKXofPonYlAQg==
"@typescript-eslint/typescript-estree@3.10.1", "@typescript-eslint/typescript-estree@4.19.0", "@typescript-eslint/typescript-estree@5.10.2": "@typescript-eslint/typescript-estree@3.10.1", "@typescript-eslint/typescript-estree@4.19.0", "@typescript-eslint/typescript-estree@5.3.0":
version "5.10.2" version "5.3.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.2.tgz#810906056cd3ddcb35aa333fdbbef3713b0fe4a7" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.0.tgz#4f68ddd46dc2983182402d2ab21fb44ad94988cf"
integrity sha512-WHHw6a9vvZls6JkTgGljwCsMkv8wu8XU8WaYKeYhxhWXH/atZeiMW6uDFPLZOvzNOGmuSMvHtZKd6AuC8PrwKQ== integrity sha512-FJ0nqcaUOpn/6Z4Jwbtf+o0valjBLkqc3MWkMvrhA2TvzFXtcclIM8F4MBEmYa2kgcI8EZeSAzwoSrIC8JYkug==
dependencies: dependencies:
"@typescript-eslint/types" "5.10.2" "@typescript-eslint/types" "5.3.0"
"@typescript-eslint/visitor-keys" "5.10.2" "@typescript-eslint/visitor-keys" "5.3.0"
debug "^4.3.2" debug "^4.3.2"
globby "^11.0.4" globby "^11.0.4"
is-glob "^4.0.3" is-glob "^4.0.3"
@@ -2566,12 +2566,12 @@
"@typescript-eslint/types" "4.19.0" "@typescript-eslint/types" "4.19.0"
eslint-visitor-keys "^2.0.0" eslint-visitor-keys "^2.0.0"
"@typescript-eslint/visitor-keys@5.10.2": "@typescript-eslint/visitor-keys@5.3.0":
version "5.10.2" version "5.3.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.2.tgz#fdbf272d8e61c045d865bd6c8b41bea73d222f3d" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.0.tgz#a6258790f3b7b2547f70ed8d4a1e0c3499994523"
integrity sha512-zHIhYGGGrFJvvyfwHk5M08C5B5K4bewkm+rrvNTKk1/S15YHR+SA/QUF8ZWscXSfEaB8Nn2puZj+iHcoxVOD/Q== integrity sha512-oVIAfIQuq0x2TFDNLVavUn548WL+7hdhxYn+9j3YdJJXB7mH9dAmZNJsPDa7Jc+B9WGqoiex7GUDbyMxV0a/aw==
dependencies: dependencies:
"@typescript-eslint/types" "5.10.2" "@typescript-eslint/types" "5.3.0"
eslint-visitor-keys "^3.0.0" eslint-visitor-keys "^3.0.0"
"@webassemblyjs/ast@1.9.0": "@webassemblyjs/ast@1.9.0":
@@ -2780,11 +2780,6 @@ acorn-walk@^7.1.1:
resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz" resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz"
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
acorn-walk@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
acorn@^6.4.1: acorn@^6.4.1:
version "6.4.2" version "6.4.2"
resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz" resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz"
@@ -2795,11 +2790,6 @@ acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0:
resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
acorn@^8.7.0:
version "8.7.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
address@1.1.2, address@^1.0.1: address@1.1.2, address@^1.0.1:
version "1.1.2" version "1.1.2"
resolved "https://registry.npmjs.org/address/-/address-1.1.2.tgz" resolved "https://registry.npmjs.org/address/-/address-1.1.2.tgz"
@@ -4116,16 +4106,15 @@ caseless@~0.12.0:
resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
chai@4.3.6: chai@4.3.4:
version "4.3.6" version "4.3.4"
resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49"
integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==
dependencies: dependencies:
assertion-error "^1.1.0" assertion-error "^1.1.0"
check-error "^1.0.2" check-error "^1.0.2"
deep-eql "^3.0.1" deep-eql "^3.0.1"
get-func-name "^2.0.0" get-func-name "^2.0.0"
loupe "^2.3.1"
pathval "^1.1.1" pathval "^1.1.1"
type-detect "^4.0.5" type-detect "^4.0.5"
@@ -6805,9 +6794,9 @@ fn.name@1.x.x:
integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
follow-redirects@^1.0.0: follow-redirects@^1.0.0:
version "1.14.8" version "1.14.7"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
for-in@^1.0.2: for-in@^1.0.2:
version "1.0.2" version "1.0.2"
@@ -9287,10 +9276,10 @@ lines-and-columns@^1.1.6:
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz" resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz"
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
lint-staged@12.3.3: lint-staged@12.1.7:
version "12.3.3" version "12.1.7"
resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-12.3.3.tgz#0a465962fe53baa2b4b9da50801ead49a910e03b" resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-12.1.7.tgz#fe9137992ac18a456422bb8484dd30be0140629f"
integrity sha512-OqcLsqcPOqzvsfkxjeBpZylgJ3SRG1RYqc9LxC6tkt6tNsq1bNVkAixBwX09f6CobcHswzqVOCBpFR1Fck0+ag== integrity sha512-bltv/ejiLWtowExpjU+s5z8j1Byjg9AlmaAjMmqNbIicY69u6sYIwXGg0dCn0TlkrrY2CphtHIXAkbZ+1VoWQQ==
dependencies: dependencies:
cli-truncate "^3.1.0" cli-truncate "^3.1.0"
colorette "^2.0.16" colorette "^2.0.16"
@@ -9298,10 +9287,10 @@ lint-staged@12.3.3:
debug "^4.3.3" debug "^4.3.3"
execa "^5.1.1" execa "^5.1.1"
lilconfig "2.0.4" lilconfig "2.0.4"
listr2 "^4.0.1" listr2 "^3.13.5"
micromatch "^4.0.4" micromatch "^4.0.4"
normalize-path "^3.0.0" normalize-path "^3.0.0"
object-inspect "^1.12.0" object-inspect "^1.11.1"
string-argv "^0.3.1" string-argv "^0.3.1"
supports-color "^9.2.1" supports-color "^9.2.1"
yaml "^1.10.2" yaml "^1.10.2"
@@ -9311,17 +9300,17 @@ listenercount@~1.0.1:
resolved "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz" resolved "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz"
integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc= integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=
listr2@^4.0.1: listr2@^3.13.5:
version "4.0.2" version "3.13.5"
resolved "https://registry.yarnpkg.com/listr2/-/listr2-4.0.2.tgz#04d66f8c8694a14920d7df08ebe01568948fb500" resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.13.5.tgz#105a813f2eb2329c4aae27373a281d610ee4985f"
integrity sha512-YcgwfCWpvPbj9FLUGqvdFvd3hrFWKpOeuXznRgfWEJ7RNr8b/IKKIKZABHx3aU+4CWN/iSAFFSReziQG6vTeIA== integrity sha512-3n8heFQDSk+NcwBn3CgxEibZGaRzx+pC64n3YjpMD1qguV4nWus3Al+Oo3KooqFKTQEJ1v7MmnbnyyNspgx3NA==
dependencies: dependencies:
cli-truncate "^2.1.0" cli-truncate "^2.1.0"
colorette "^2.0.16" colorette "^2.0.16"
log-update "^4.0.0" log-update "^4.0.0"
p-map "^4.0.0" p-map "^4.0.0"
rfdc "^1.3.0" rfdc "^1.3.0"
rxjs "^7.5.2" rxjs "^7.4.0"
through "^2.3.8" through "^2.3.8"
wrap-ansi "^7.0.0" wrap-ansi "^7.0.0"
@@ -9612,13 +9601,6 @@ loose-envify@^1.1.0, loose-envify@^1.4.0:
dependencies: dependencies:
js-tokens "^3.0.0 || ^4.0.0" js-tokens "^3.0.0 || ^4.0.0"
loupe@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.1.tgz#a2e1192c9f452e4e85089766da10ac8288383947"
integrity sha512-EN1D3jyVmaX4tnajVlfbREU4axL647hLec1h/PXAb8CPDMJiYitcWF2UeLVNttRqaIqQs4x+mRvXf+d+TlDrCA==
dependencies:
get-func-name "^2.0.0"
lower-case@^2.0.2: lower-case@^2.0.2:
version "2.0.2" version "2.0.2"
resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz" resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz"
@@ -10421,7 +10403,7 @@ object-copy@^0.1.0:
define-property "^0.2.5" define-property "^0.2.5"
kind-of "^3.0.3" kind-of "^3.0.3"
object-inspect@^1.12.0, object-inspect@^1.9.0: object-inspect@^1.11.1, object-inspect@^1.9.0:
version "1.12.0" version "1.12.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
@@ -12868,12 +12850,12 @@ rxjs@^6.4.0, rxjs@^6.6.0:
dependencies: dependencies:
tslib "^1.9.0" tslib "^1.9.0"
rxjs@^7.5.2: rxjs@^7.4.0:
version "7.5.2" version "7.4.0"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.2.tgz#11e4a3a1dfad85dbf7fb6e33cbba17668497490b" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.4.0.tgz#a12a44d7eebf016f5ff2441b87f28c9a51cebc68"
integrity sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w== integrity sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==
dependencies: dependencies:
tslib "^2.1.0" tslib "~2.1.0"
safari-14-idb-fix@^3.0.0: safari-14-idb-fix@^3.0.0:
version "3.0.0" version "3.0.0"
@@ -12933,10 +12915,10 @@ sass-loader@^10.0.5:
schema-utils "^3.0.0" schema-utils "^3.0.0"
semver "^7.3.2" semver "^7.3.2"
sass@1.49.7: sass@1.47.0:
version "1.49.7" version "1.47.0"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.7.tgz#22a86a50552b9b11f71404dfad1b9ff44c6b0c49" resolved "https://registry.yarnpkg.com/sass/-/sass-1.47.0.tgz#c22dd0eed2e4a991430dae0b03c8e694bc41c2b4"
integrity sha512-13dml55EMIR2rS4d/RDHHP0sXMY3+30e1TKsyXaSz3iLWVoDWEoboY8WzJd5JMnxrRHffKO3wq2mpJ0jxRJiEQ== integrity sha512-GtXwvwgD7/6MLUZPnlA5/8cdRgC9SzT5kAnnJMRmEZQFRE3J56Foswig4NyyyQGsnmNvg6EUM/FP0Pe9Y2zywQ==
dependencies: dependencies:
chokidar ">=3.0.0 <4.0.0" chokidar ">=3.0.0 <4.0.0"
immutable "^4.0.0" immutable "^4.0.0"
@@ -14284,7 +14266,7 @@ tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0: tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@~2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz" resolved "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz"
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
@@ -14410,10 +14392,10 @@ typedarray@^0.0.6:
resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
typescript@4.5.5: typescript@4.5.4:
version "4.5.5" version "4.5.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8"
integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==
typeson-registry@^1.0.0-alpha.20: typeson-registry@^1.0.0-alpha.20:
version "1.0.0-alpha.39" version "1.0.0-alpha.39"
@@ -14760,12 +14742,9 @@ vm-browserify@^1.0.1:
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
vm2@^3.9.3: vm2@^3.9.3:
version "3.9.7" version "3.9.5"
resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.7.tgz#bb87aa677c97c61e23a6cb6547e44e990517a6f6" resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.5.tgz#5288044860b4bbace443101fcd3bddb2a0aa2496"
integrity sha512-g/GZ7V0Mlmch3eDVOATvAXr1GsJNg6kQ5PjvYy3HbJMCRn5slNbo/u73Uy7r5yUej1cRa3ZjtoVwcWSQuQ/fow== integrity sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==
dependencies:
acorn "^8.7.0"
acorn-walk "^8.2.0"
w3c-hr-time@^1.0.2: w3c-hr-time@^1.0.2:
version "1.0.2" version "1.0.2"